pax_global_header00006660000000000000000000000064131246645550014525gustar00rootroot0000000000000052 comment=3bc91fa2ba75468223fb948accf9fd7a57a0fc83 iotjs-1.0/000077500000000000000000000000001312466455500125155ustar00rootroot00000000000000iotjs-1.0/.clang-format000066400000000000000000000055101312466455500150710ustar00rootroot00000000000000# This file is generated by below command, # $ clang-format-3.8 -style=google -dump-config > .clang-format # then modified according to IoT.js style guide. --- Language: Cpp # BasedOnStyle: Google AccessModifierOffset: -1 AlignAfterOpenBracket: Align AlignConsecutiveAssignments: false AlignConsecutiveDeclarations: false AlignEscapedNewlinesLeft: true AlignOperands: true AlignTrailingComments: true AllowAllParametersOfDeclarationOnNextLine: true AllowShortBlocksOnASingleLine: false AllowShortCaseLabelsOnASingleLine: false AllowShortFunctionsOnASingleLine: None AllowShortIfStatementsOnASingleLine: false AllowShortLoopsOnASingleLine: false AlwaysBreakAfterDefinitionReturnType: None AlwaysBreakAfterReturnType: None AlwaysBreakBeforeMultilineStrings: true AlwaysBreakTemplateDeclarations: true BinPackArguments: true BinPackParameters: true BraceWrapping: AfterClass: false AfterControlStatement: false AfterEnum: false AfterFunction: false AfterNamespace: false AfterObjCDeclaration: false AfterStruct: false AfterUnion: false BeforeCatch: false BeforeElse: false IndentBraces: false BreakBeforeBinaryOperators: None BreakBeforeBraces: Attach BreakBeforeTernaryOperators: true BreakConstructorInitializersBeforeComma: false ColumnLimit: 80 CommentPragmas: '^ IWYU pragma:' ConstructorInitializerAllOnOneLineOrOnePerLine: true ConstructorInitializerIndentWidth: 4 ContinuationIndentWidth: 4 Cpp11BracedListStyle: false DerivePointerAlignment: true DisableFormat: false ExperimentalAutoDetectBinPacking: false ForEachMacros: [ ] IncludeCategories: - Regex: '^"(iotjs_def)' Priority: -1 - Regex: '^.iotjs' Priority: 1 - Regex: '^.jerry' Priority: 2 - Regex: '^.uv' Priority: 2 - Regex: '^.http' Priority: 2 - Regex: '^(<)' Priority: 3 IndentCaseLabels: true IndentWidth: 2 IndentWrappedFunctionNames: false KeepEmptyLinesAtTheStartOfBlocks: false MacroBlockBegin: '' MacroBlockEnd: '' MaxEmptyLinesToKeep: 2 NamespaceIndentation: None ObjCBlockIndentWidth: 2 ObjCSpaceAfterProperty: false ObjCSpaceBeforeProtocolList: false PenaltyBreakBeforeFirstCallParameter: 500 PenaltyBreakComment: 300 PenaltyBreakFirstLessLess: 120 PenaltyBreakString: 1000 PenaltyExcessCharacter: 1000000 PenaltyReturnTypeOnItsOwnLine: 200 PointerAlignment: Left ReflowComments: true SortIncludes: true SpaceAfterCStyleCast: false SpaceBeforeAssignmentOperators: true SpaceBeforeParens: ControlStatements SpaceInEmptyParentheses: false SpacesBeforeTrailingComments: 1 SpacesInAngles: false SpacesInContainerLiterals: true SpacesInCStyleCastParentheses: false SpacesInParentheses: false SpacesInSquareBrackets: false Standard: Auto TabWidth: 8 UseTab: Never ... iotjs-1.0/.gitignore000066400000000000000000000005451312466455500145110ustar00rootroot00000000000000# Produced files /build /build/* /src/iotjs_js.h /src/iotjs_js.c /src/iotjs_string_ext.inl.h /test/tmp/* # IDE related files nbproject **.sublime-project **.sublime-workspace .idea # Random Trash *.swp *.swo *~ core vgcore.* **.orig **.directory **.patch .tags* cscope.* *.pyc # ctags and ID database tags ID TAGS # config files *.config !build.config iotjs-1.0/.gitmodules000066400000000000000000000004571312466455500147000ustar00rootroot00000000000000[submodule "deps/jerry"] path = deps/jerry url = https://github.com/jerryscript-project/jerryscript.git [submodule "deps/http-parser"] path = deps/http-parser url = https://github.com/Samsung/http-parser.git [submodule "deps/libtuv"] path = deps/libtuv url = https://github.com/Samsung/libtuv.git iotjs-1.0/.travis.yml000066400000000000000000000065311312466455500146330ustar00rootroot00000000000000language: c os: linux dist: trusty sudo: required before_install: - if [[ "$INSTALL_ARM_DEPS" == "yes" ]]; then tools/apt-get-install-arm.sh; fi - if [[ "$INSTALL_NUTTX_DEPS" == "yes" ]]; then tools/apt-get-install-nuttx.sh; fi - if [[ "$INSTALL_TIZEN_DEPS" == "yes" ]]; then . tools/apt-get-install-tizen.sh; fi - if [[ "$INSTALL_TRAVIS_I686_DEPS" == "yes" ]]; then tools/apt-get-install-travis-i686.sh; fi - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then tools/apt-get-install-deps.sh; fi - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then tools/brew-install-deps.sh; fi install: script: "tools/precommit.py $OPTS" env: global: - secure: "lUGzoKK/Yn4/OmpqLQALrIgfY9mQWE51deUawPrCO87UQ2GknfQ4BvwY3UT5QY0XnztPBP1+vRQ2qxbiAU7VWicp280sXDnh0FeuZD14FcE9l0FczraL12reoLu+gY5HWFfbkZncmcBsZkxDEYxhkM14FJU8fxyqGQW2ypJNz+gUGP+8r40Re5J3WjcddCQNe5IG8U+M9B4YeDHhN2QspLdN5pkgn56XtdGa3+qbecO2NpjJG5ltM9j1tTuo/Dg22DxrIFVfeFSFKUj4nfMrgPo5LevRsC/lfaBSCsj751eqrxRcQRh2hkpiIJ7mEBs2LL1EH9O6Mbj+eRh8BvIYqTB85VPNFc43sLWk14apcSVBrxJE5j3kP9sAsOD9Y5JynnkeuxYyISrkywwoX2uxsmCzIfGbwsv5VLToQzrqWlGYrHOAmVXNi8561dLfsWwxxFUjdqkZr1Kgc8UfnBEcBUtSiKCHS86/YUUbBJGkEkjDUS0GiqhFY4bXLQCR7EX4qDX3m6p7Mnh4NVUolpnSmyeYE/MjmqQ+7PJsPLL3EcIYmJ7dtW3mZ3yE2NyaFD0Pym9+TiuCCXRtrNVK1M3Kya64KNv+HbhjT/fTCgXLSeyDmJOKVAqugRlDo3b1KGR1LI0AfegzSA6mEC4e9JLjYiSnHPMUahzgLt8oU0hNFRY=" matrix: - OPTS="--test=host-linux" - OPTS="--test=rpi2" INSTALL_ARM_DEPS=yes - OPTS="--test=nuttx" INSTALL_NUTTX_DEPS=yes - OPTS="--test=artik10" INSTALL_TIZEN_DEPS=yes - OPTS="--test=misc" matrix: include: - os: osx env: OPTS="--test=host-darwin" - os: linux before_install: - tools/apt-get-install-deps.sh - echo -n | openssl s_client -connect scan.coverity.com:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' | sudo tee -a /etc/ssl/certs/ca- addons: coverity_scan: project: name: "Samsung/iotjs" description: "Platform for Internet of Things with JavaScript" notification_email: duddlf.choi@samsung.com build_command: "tools/precommit.py --test=coverity" branch_pattern: master env: OPTS="--test=coverity" - compiler: gcc-4.9 addons: apt: sources: - ubuntu-toolchain-r-test packages: - gcc-4.9 - gcc-4.9-multilib env: OPTS="--test=host-linux --buildtype=debug --buildoptions=--target-arch=i686,--compile-flag=-fsanitize=address,--compile-flag=-fno-omit-frame-pointer,--compile-flag=-fno-common,--compile-flag=-O2,--jerry-cmake-param=-DJERRY_LIBC=OFF,--jerry-cmake-param=-DFEATURE_SYSTEM_ALLOCATOR=ON,--no-snapshot,--no-check-valgrind" INSTALL_TRAVIS_I686_DEPS=yes ASAN_OPTIONS=detect_stack_use_after_return=1:check_initialization_order=true:strict_init_order=true - compiler: gcc-4.9 addons: apt: sources: - ubuntu-toolchain-r-test packages: - gcc-4.9 - gcc-4.9-multilib env: OPTS="--test=host-linux --buildtype=debug --buildoptions=--target-arch=i686,--compile-flag=-fsanitize=undefined,--compile-flag=-fno-omit-frame-pointer,--compile-flag=-fno-common,--jerry-cmake-param=-DJERRY_LIBC=OFF,--jerry-cmake-param=-DFEATURE_SYSTEM_ALLOCATOR=ON,--no-snapshot,--no-check-valgrind" INSTALL_TRAVIS_I686_DEPS=yes UBSAN_OPTIONS=print_stacktrace=1 fast_finish: true iotjs-1.0/CMakeLists.txt000066400000000000000000000037721312466455500152660ustar00rootroot00000000000000# Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. cmake_minimum_required(VERSION 2.8) project(IOTJS C) set(IOTJS_VERSION_MAJOR 0) set(IOTJS_VERSION_MINOR 1) # Do a few default checks if(NOT DEFINED PLATFORM_DESCRIPTOR) message(FATAL_ERROR "No PLATFORM_DESCRIPTOR specified (format: -)") endif() string(REPLACE "-" ";" PLATFORM_ARGS ${PLATFORM_DESCRIPTOR}) if(NOT DEFINED TARGET_OS) list(GET PLATFORM_ARGS 1 TARGET_OS) message( "TARGET_OS not specified, using '${TARGET_OS}' from PLATFORM_DESCRIPTOR") endif() string(TOUPPER "${TARGET_OS}" TARGET_OS) if(NOT CMAKE_BUILD_TYPE) message("CMAKE_BUILD_TYPE was not set! Configuring for Debug build!") set(CMAKE_BUILD_TYPE Debug) elseif("${CMAKE_BUILD_TYPE}" STREQUAL "Release") message("CMAKE_BUILD_TYPE was set to Release, switching to MinSizeRel") set(CMAKE_BUILD_TYPE MinSizeRel) endif() if(NOT DEFINED BUILD_LIB_ONLY) set(BUILD_LIB_ONLY OFF) endif() if(NOT DEFINED ENABLE_SNAPSHOT) message("Snapshot mode force enabled") set(ENABLE_SNAPSHOT ON) endif() if(NOT DEFINED ENABLE_LTO) message("LTO force disabled") set(ENABLE_LTO OFF) endif() set(ROOT_DIR ${CMAKE_SOURCE_DIR}) # Common compile flags set(CFLAGS_COMMON -Wall -Wextra -Werror -Wno-unused-parameter -Wsign-conversion -std=gnu99 ) include(ExternalProject) # Include external projects include(cmake/jerry.cmake) include(cmake/http-parser.cmake) include(cmake/libtuv.cmake) include(cmake/iotjs.cmake) iotjs-1.0/LICENSE000066400000000000000000000274601312466455500135330ustar00rootroot00000000000000Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS -------- Copyright Node.js contributors. All rights reserved. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. This license applies to parts of '*.js' files in '/src/js', implementing node.js compatible API, originating from the https://github.com/node/node repository: iotjs-1.0/README.md000066400000000000000000000074701312466455500140040ustar00rootroot00000000000000# IoT.js: Platform for Internet of Things with JavaScript [![Join the chat at https://gitter.im/Samsung/iotjs](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/Samsung/iotjs?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![License](https://img.shields.io/badge/licence-Apache%202.0-brightgreen.svg?style=flat)](LICENSE) [![Build Status](https://travis-ci.org/Samsung/iotjs.svg?branch=master)](https://travis-ci.org/Samsung/iotjs) [![Coverity Scan Build Status](https://img.shields.io/coverity/scan/12140.svg)](https://scan.coverity.com/projects/samsung-iotjs) [![FOSSA Status](https://app.fossa.io/api/projects/git%2Bhttps%3A%2F%2Fgithub.com%2FSamsung%2Fiotjs.svg?type=shield)](https://app.fossa.io/projects/git%2Bhttps%3A%2F%2Fgithub.com%2FSamsung%2Fiotjs?ref=badge_shield) You can find project details on our [project page](http://samsung.github.io/iotjs/) and [wiki](https://github.com/Samsung/iotjs/wiki). IRC channel: #iotjs on [freenode](https://freenode.net) Mailing list: iotjs-dev@groups.io, you can subscribe [here](https://groups.io/g/iotjs-dev) and access the mailing list archive [here](https://groups.io/g/iotjs-dev/topics). ## Quick Start ### Getting the sources ```bash git clone https://github.com/Samsung/iotjs.git cd iotjs ``` ### How to Build ```bash tools/build.py ``` ### How to Test ```bash build/x86_64-linux/debug/bin/iotjs tools/check_test.js ``` For Additional information see [Getting Started](docs/help/Getting-Started.md). ## Documentation - [Getting Started](docs/help/Getting-Started.md) - [API Reference](docs/api/IoT.js-API-reference.md) ## License IoT.js is Open Source software under the [Apache 2.0 license](https://www.apache.org/licenses/LICENSE-2.0). Complete license and copyright information can be found within the code. [![FOSSA Status](https://app.fossa.io/api/projects/git%2Bhttps%3A%2F%2Fgithub.com%2FSamsung%2Fiotjs.svg?type=large)](https://app.fossa.io/projects/git%2Bhttps%3A%2F%2Fgithub.com%2FSamsung%2Fiotjs?ref=badge_large) > Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors > Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. > Copyright Node.js contributors. All rights reserved. > Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: > The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. > THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. > This license applies to parts of '*.js' files in '/src/js', implementing node.js compatible API, originating from the https://github.com/nodejs/node repository: iotjs-1.0/build.config000066400000000000000000000061121312466455500150030ustar00rootroot00000000000000{ "build_option" : { "buildtype": "debug", "buildlib": false, "builddir": "", "clean": false, "config": "", "target-arch": "", "target-os": "", "target-board":"", "cmake-param": [], "compile-flag": [], "link-flag": [], "external-include-dir": [], "external-static-lib": [], "external-shared-lib": [], "jerry-cmake-param": [], "jerry-compile-flag": [], "jerry-link-flag": [], "jerry-lto": false, "jerry-heaplimit": 256, "jerry-memstat": false, "no-init-submodule": false, "no-check-tidy": false, "no-check-test": false, "no-parallel-build": false, "sysroot": "", "no-snapshot": false }, "compile_flags": { "os": { "linux": ["-D__LINUX__", "-fno-builtin"], "darwin": ["-D__DARWIN__", "-fno-builtin"], "nuttx": ["-D__NUTTX__", "-Os", "-fno-strict-aliasing", "-fno-strength-reduce", "-fomit-frame-pointer"], "tizen": ["-D__LINUX__", "-fno-builtin"], "tizenrt": ["-D__TIZENRT__", "-Os", "-fno-strict-aliasing", "-fno-strength-reduce", "-fomit-frame-pointer"] }, "arch": { "i686": ["-D__i686__", "-D__x86__", "-D__I686__", "-D__X86__", "-march=i686", "-m32"], "x86_64": ["-D__x86_64__", "-D__X86_64__"], "arm": ["-D__ARM__", "-D__arm__", "-mthumb", "-fno-short-enums", "-mlittle-endian"] }, "board": { "stm32f4dis": ["-mcpu=cortex-m4", "-march=armv7e-m", "-mfpu=fpv4-sp-d16", "-mfloat-abi=hard", "-DTARGET_BOARD=STM32F4DIS"], "rpi2": ["-mcpu=cortex-a7", "-mfpu=neon-vfpv4", "-DTARGET_BOARD=RP2"], "artik05x": ["-mcpu=cortex-r4", "-mfpu=vfp3", "-DTARGET_BOARD=artik05x"], "artik10": ["-mcpu=cortex-a7", "-mfpu=neon-vfpv4", "-mfloat-abi=softfp", "-DTARGET_BOARD=artik10"] }, "buildtype": { "release": [], "debug": ["-DDEBUG", "-DENABLE_DEBUG_LOG"] } }, "link_flags": { "os": { "linux": ["-pthread"], "darwin": [], "nuttx": [], "tizen": ["-pthread"], "tizenrt": [] } }, "shared_libs": { "os": { "linux": ["m", "rt"], "darwin": [], "nuttx": [], "tizen": ["m", "rt"], "tizenrt": [] } }, "module": { "always": ["buffer", "console", "events", "fs", "module", "timers"], "include": ["assert", "dns", "http", "net", "stream", "testdriver"], "exclude": { "all": [], "linux": ["adc", "ble", "dgram", "gpio", "i2c", "pwm", "spi", "uart"], "nuttx": ["adc", "dgram", "gpio", "i2c", "pwm", "stm32f4dis", "uart"], "darwin": [], "tizenrt": ["gpio", "pwm"] } } } iotjs-1.0/cmake/000077500000000000000000000000001312466455500135755ustar00rootroot00000000000000iotjs-1.0/cmake/config/000077500000000000000000000000001312466455500150425ustar00rootroot00000000000000iotjs-1.0/cmake/config/arm-linux.cmake000066400000000000000000000014771312466455500177710ustar00rootroot00000000000000# Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. include(CMakeForceCompiler) set(CMAKE_SYSTEM_NAME Linux) set(CMAKE_SYSTEM_PROCESSOR armv7l) set(EXTERNAL_CMAKE_C_COMPILER arm-linux-gnueabihf-gcc) CMAKE_FORCE_C_COMPILER(${EXTERNAL_CMAKE_C_COMPILER} GNU) iotjs-1.0/cmake/config/arm-nuttx.cmake000066400000000000000000000014711312466455500200060ustar00rootroot00000000000000# Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. include(CMakeForceCompiler) set(CMAKE_SYSTEM_NAME Nuttx) set(CMAKE_SYSTEM_PROCESSOR armv7l) set(EXTERNAL_CMAKE_C_COMPILER arm-none-eabi-gcc) CMAKE_FORCE_C_COMPILER(${EXTERNAL_CMAKE_C_COMPILER} GNU) iotjs-1.0/cmake/config/arm-tizen.cmake000066400000000000000000000021311312466455500177470ustar00rootroot00000000000000# Copyright 2017-present Samsung Electronics Co., Ltd. and other contributors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. include(CMakeForceCompiler) set(CMAKE_SYSTEM_NAME Linux) set(CMAKE_SYSTEM_PROCESSOR armv7l) # Only set the compiler if not provided already if(NOT "${CMAKE_C_COMPILER}" STREQUAL "") find_program(COMPILER_PATH ${CMAKE_C_COMPILER}) if(COMPILER_PATH STREQUAL "") message(WARNING "Command ${CMAKE_C_COMPILER} not found") unset(CMAKE_C_COMPILER) endif() unset(COMPILER_PATH) endif() if("${CMAKE_C_COMPILER}" STREQUAL "") set(CMAKE_C_COMPILER arm-linux-gnueabi-gcc) endif() iotjs-1.0/cmake/config/arm-tizenrt.cmake000066400000000000000000000014731312466455500203250ustar00rootroot00000000000000# Copyright 2017-present Samsung Electronics Co., Ltd. and other contributors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. include(CMakeForceCompiler) set(CMAKE_SYSTEM_NAME Tizenrt) set(CMAKE_SYSTEM_PROCESSOR armv7l) set(EXTERNAL_CMAKE_C_COMPILER arm-none-eabi-gcc) CMAKE_FORCE_C_COMPILER(${EXTERNAL_CMAKE_C_COMPILER} GNU) iotjs-1.0/cmake/config/i686-linux.cmake000066400000000000000000000013131312466455500176730ustar00rootroot00000000000000# Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. include(CMakeForceCompiler) set(CMAKE_SYSTEM_NAME Linux) set(CMAKE_SYSTEM_PROCESSOR i686) iotjs-1.0/cmake/config/x86_64-darwin.cmake000066400000000000000000000013161312466455500202650ustar00rootroot00000000000000# Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. include(CMakeForceCompiler) set(CMAKE_SYSTEM_NAME Darwin) set(CMAKE_SYSTEM_PROCESSOR x86_64) iotjs-1.0/cmake/config/x86_64-linux.cmake000066400000000000000000000013151312466455500201370ustar00rootroot00000000000000# Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. include(CMakeForceCompiler) set(CMAKE_SYSTEM_NAME Linux) set(CMAKE_SYSTEM_PROCESSOR x86_64) iotjs-1.0/cmake/http-parser.cmake000066400000000000000000000032511312466455500170510ustar00rootroot00000000000000# Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. cmake_minimum_required(VERSION 2.8) if("${TARGET_OS}" MATCHES "NUTTX|TIZENRT") set(HTTPPARSER_NUTTX_ARG -DNUTTX_HOME=${TARGET_SYSTEMROOT}) endif() set(DEPS_HTTPPARSER deps/http-parser) set(DEPS_HTTPPARSER_SRC ${ROOT_DIR}/${DEPS_HTTPPARSER}/) ExternalProject_Add(http-parser PREFIX ${DEPS_HTTPPARSER} SOURCE_DIR ${DEPS_HTTPPARSER_SRC} BUILD_IN_SOURCE 0 BINARY_DIR ${DEPS_HTTPPARSER} INSTALL_COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/${DEPS_HTTPPARSER}/libhttpparser.a ${CMAKE_BINARY_DIR}/lib/ CMAKE_ARGS -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE} -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_C_FLAGS=${CMAKE_C_FLAGS} -DOS=${TARGET_OS} ${HTTPPARSER_NUTTX_ARG} ) add_library(libhttp-parser STATIC IMPORTED) add_dependencies(libhttp-parser http-parser) set_property(TARGET libhttp-parser PROPERTY IMPORTED_LOCATION ${CMAKE_BINARY_DIR}/lib/libhttpparser.a) set_property(DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES ${CMAKE_BINARY_DIR}/lib/libhttpparser.a) set(HTTPPARSER_INCLUDE_DIR ${DEPS_HTTPPARSER_SRC}) iotjs-1.0/cmake/iotjs.cmake000066400000000000000000000227621312466455500157400ustar00rootroot00000000000000# Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. cmake_minimum_required(VERSION 2.8) set(IOTJS_SOURCE_DIR ${ROOT_DIR}/src) function(find_value RESULT VALUE VALUE_TRUE VALUE_FALSE) list(FIND ARGN ${VALUE} idx) if(${idx} GREATER -1) set(${RESULT} ${VALUE_TRUE} PARENT_SCOPE) else() set(${RESULT} ${VALUE_FALSE} PARENT_SCOPE) endif() endfunction(find_value) # System Configuration (not module) string(TOLOWER ${CMAKE_SYSTEM_NAME} IOTJS_SYSTEM_OS) set(PLATFORM_OS_DIR ${IOTJS_SOURCE_DIR}/platform/${IOTJS_SYSTEM_OS}) file(GLOB IOTJS_PLATFORM_SRC ${PLATFORM_OS_DIR}/iotjs_*.c) file(GLOB PLATFORM_MODULE_SRC ${PLATFORM_OS_DIR}/iotjs_module_*.c) if (IOTJS_PLATFORM_SRC AND PLATFORM_MODULE_SRC) list(REMOVE_ITEM IOTJS_PLATFORM_SRC ${PLATFORM_MODULE_SRC}) endif() # Board Configuration (not module) if(NOT "${TARGET_BOARD}" STREQUAL "None") set(PLATFORM_BOARD_DIR ${PLATFORM_OS_DIR}/${TARGET_BOARD}) file(GLOB IOTJS_BOARD_SRC ${PLATFORM_BOARD_DIR}/iotjs_*.c) file(GLOB PLATFORM_MODULE_SRC ${PLATFORM_BOARD_DIR}/iotjs_module_*.c) if (IOTJS_BOARD_SRC AND PLATFORM_MODULE_SRC) list(REMOVE_ITEM IOTJS_BOARD_SRC ${PLATFORM_MODULE_SRC}) endif() list(APPEND IOTJS_PLATFORM_SRC ${IOTJS_BOARD_SRC}) endif() # Run js/native module analyzer if(ENABLE_MINIMAL) set(MODULE_ANALYZER_ARGS --iotjs-minimal-profile) endif() execute_process( COMMAND python ${ROOT_DIR}/tools/module_analyzer.py --mode cmake-dump --target-os ${TARGET_OS} --iotjs-include-module "${IOTJS_INCLUDE_MODULE}" --iotjs-exclude-module "${IOTJS_EXCLUDE_MODULE}" ${MODULE_ANALYZER_ARGS} RESULT_VARIABLE MODULE_ANALYZER_RETURN_CODE ERROR_VARIABLE MODULE_ANALYZER_OUTPUT_ERR OUTPUT_VARIABLE MODULE_ANALYZER_OUTPUT ) if(MODULE_ANALYZER_RETURN_CODE) message(FATAL_ERROR "Error during module analyzer execution (${MODULE_ANALYZER_RETURN_CODE}): " "${MODULE_ANALYZER_OUTPUT}" "${MODULE_ANALYZER_OUTPUT_ERR}") endif() if(VERBOSE) message("Module analyzer:\n${MODULE_ANALYZER_OUTPUT}") endif() function(get_variable_value OUTPUT_VAR VAR_NAME STRING_DATA) string(REGEX MATCHALL "${VAR_NAME}=[a-zA-Z;_0-9-]+" LINE "${STRING_DATA}") string(REPLACE "${VAR_NAME}=" "" VAR_VALUE "${LINE}") string(STRIP "${VAR_VALUE}" VAR_VALUE) separate_arguments(VAR_VALUE) set(${OUTPUT_VAR} ${VAR_VALUE} PARENT_SCOPE) endfunction(get_variable_value) get_variable_value(IOTJS_NATIVE_MODULES "IOTJS_NATIVE_MODULES" "${MODULE_ANALYZER_OUTPUT}") get_variable_value(IOTJS_JS_MODULES "IOTJS_JS_MODULES" "${MODULE_ANALYZER_OUTPUT}") # Run js2c set(JS2C_RUN_MODE "release") if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug") set(JS2C_RUN_MODE "debug") endif() if(ENABLE_SNAPSHOT) set(JS2C_SNAPSHOT_ARG --snapshot-generator=${JERRY_HOST}) set(IOTJS_CFLAGS ${IOTJS_CFLAGS} -DENABLE_SNAPSHOT) endif() add_custom_command( OUTPUT ${IOTJS_SOURCE_DIR}/iotjs_js.c ${IOTJS_SOURCE_DIR}/iotjs_js.h COMMAND python ${ROOT_DIR}/tools/js2c.py ARGS --buildtype=${JS2C_RUN_MODE} --modules '${IOTJS_JS_MODULES}' ${JS2C_SNAPSHOT_ARG} DEPENDS ${ROOT_DIR}/tools/js2c.py jerry ${IOTJS_SOURCE_DIR}/js/*.js ) # Module Configuration - listup all possible native C modules set(IOTJS_MODULES_ENABLED) set(IOTJS_MODULES_DISABLED) # List all modules and mark them as disabled by default file(GLOB IOTJS_MODULES_ALL_SRC ${IOTJS_SOURCE_DIR}/modules/*.c) foreach(module ${IOTJS_MODULES_ALL_SRC}) ## iotjs_module_adc.c -> ADC get_filename_component(IOTJS_MODULENAME ${module} NAME_WE) string(SUBSTRING ${IOTJS_MODULENAME} 13 -1 IOTJS_MODULENAME) string(TOUPPER ${IOTJS_MODULENAME} IOTJS_MODULENAME) list(APPEND IOTJS_MODULES_DISABLED ${IOTJS_MODULENAME}) endforeach() # Module Configuration - enable only selected modules and add board support set(IOTJS_PLATFORM_SUPPORT) set(IOTJS_BOARD_SUPPORT) set(IOTJS_MODULES_SRC) set(PLATFORM_SRC ${IOTJS_SOURCE_DIR}/platform/${PLATFORM_DESCRIPTOR}/iotjs_module) foreach(module ${IOTJS_NATIVE_MODULES}) string(TOUPPER ${module} MODULE) # check if there is a native file for the module set(BASE_MODULE_SRC ${IOTJS_SOURCE_DIR}/modules/iotjs_module_${module}.c) if(EXISTS "${BASE_MODULE_SRC}") list(APPEND IOTJS_MODULE_SRC ${BASE_MODULE_SRC}) endif() # first, check if there is the module in / set(ADD_MODULE_RESULT FALSE) if(NOT "${TARGET_BOARD}" STREQUAL "None") set(PLATFORM_MODULE_SRC ${PLATFORM_BOARD_DIR}/iotjs_module_${module}) set(PLATFORM_MODULE_SRC ${PLATFORM_MODULE_SRC}-${IOTJS_SYSTEM_OS}-${TARGET_BOARD}.c) if(EXISTS "${PLATFORM_MODULE_SRC}") list(APPEND IOTJS_MODULE_SRC ${PLATFORM_MODULE_SRC}) list(APPEND IOTJS_BOARD_SUPPORT ${MODULE}) set(${ADD_MODULE_RESULT} TRUE) else() set(${ADD_MODULE_RESULT} FALSE) endif() endif() # if the module is not in /, look in if(NOT ${ADD_MODULE_RESULT}) set(PLATFORM_MODULE_SRC ${PLATFORM_OS_DIR}/iotjs_module_${module}-${IOTJS_SYSTEM_OS}.c) if(EXISTS "${PLATFORM_MODULE_SRC}") list(APPEND IOTJS_MODULE_SRC ${PLATFORM_MODULE_SRC}) list(APPEND IOTJS_PLATFORM_SUPPORT ${MODULE}) endif() endif() list(APPEND IOTJS_MODULES_ENABLED ${MODULE}) list(REMOVE_ITEM IOTJS_MODULES_DISABLED ${MODULE}) endforeach() # Build the module enable defines and print out the module configurations message("Native module configuration:") set(IOTJS_MODULES_ALL ${IOTJS_MODULES_ENABLED} ${IOTJS_MODULES_DISABLED}) list(SORT IOTJS_MODULES_ALL) foreach(module ${IOTJS_MODULES_ALL}) find_value(MODULE_ENABLED "${module}" 1 0 ${IOTJS_MODULES_ENABLED}) list(APPEND IOTJS_CFLAGS "-DENABLE_MODULE_${module}=${MODULE_ENABLED}") if(MODULE_ENABLED) find_value(PLATFORM_SUPPORT "${module}" "found" "NOT found" ${IOTJS_PLATFORM_SUPPORT}) if(DEFINED TARGET_BOARD) find_value(BOARD_SUPPORT "${module}" "found" "NOT found" ${IOTJS_BOARD_SUPPORT}) set(BOARD_SUPPORT_STR "[Board support: ${BOARD_SUPPORT}]") else() set(BOARD_SUPPORT_STR "") endif() message(STATUS "${module}: ON " "[Platform support: ${PLATFORM_SUPPORT}]" "${BOARD_SUPPORT_STR}") else() message(STATUS "${module}: OFF") endif() endforeach() # List the enabled js modules message("Enabled JS modules:") foreach(module ${IOTJS_JS_MODULES}) message(STATUS "${module}") endforeach() # Print out some configs message("IoT.js configured with:") message(STATUS "CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE}") message(STATUS "CMAKE_C_FLAGS ${CMAKE_C_FLAGS}") message(STATUS "PLATFORM_DESCRIPTOR ${PLATFORM_DESCRIPTOR}") message(STATUS "TARGET_OS ${TARGET_OS}") message(STATUS "TARGET_SYSTEMROOT ${TARGET_SYSTEMROOT}") message(STATUS "TARGET_BOARD ${TARGET_BOARD}") message(STATUS "BUILD_LIB_ONLY ${BUILD_LIB_ONLY}") message(STATUS "ENABLE_LTO ${ENABLE_LTO}") message(STATUS "ENABLE_SNAPSHOT ${ENABLE_SNAPSHOT}") message(STATUS "ENABLE_MINIMAL ${ENABLE_MINIMAL}") message(STATUS "IOTJS_INCLUDE_MODULE ${IOTJS_INCLUDE_MODULE}") message(STATUS "IOTJS_EXCLUDE_MODULE ${IOTJS_EXCLUDE_MODULE}") message(STATUS "IOTJS_C_FLAGS ${IOTJS_C_FLAGS}") message(STATUS "IOTJS_LINK_FLAGS ${IOTJS_LINK_FLAGS}") # Collect all sources into LIB_IOTJS_SRC file(GLOB LIB_IOTJS_SRC ${IOTJS_SOURCE_DIR}/*.c) list(APPEND LIB_IOTJS_SRC ${IOTJS_SOURCE_DIR}/iotjs_js.c ${IOTJS_SOURCE_DIR}/iotjs_js.h ${IOTJS_MODULE_SRC} ${IOTJS_PLATFORM_SRC} ) separate_arguments(EXTERNAL_INCLUDE_DIR) separate_arguments(EXTERNAL_STATIC_LIB) separate_arguments(EXTERNAL_SHARED_LIB) set(IOTJS_INCLUDE_DIRS ${EXTERNAL_INCLUDE_DIR} ${ROOT_DIR}/include ${IOTJS_SOURCE_DIR} ${JERRY_PORT_DIR}/include ${JERRY_INCLUDE_DIR} ${HTTPPARSER_INCLUDE_DIR} ${TUV_INCLUDE_DIR} ) set(IOTJS_CFLAGS ${IOTJS_CFLAGS} ${CFLAGS_COMMON}) # Configure the libiotjs.a set(TARGET_LIB_IOTJS libiotjs) add_library(${TARGET_LIB_IOTJS} STATIC ${LIB_IOTJS_SRC}) set_target_properties(${TARGET_LIB_IOTJS} PROPERTIES COMPILE_OPTIONS "${IOTJS_CFLAGS}" OUTPUT_NAME iotjs ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib" ) target_include_directories(${TARGET_LIB_IOTJS} PRIVATE ${IOTJS_INCLUDE_DIRS}) target_link_libraries(${TARGET_LIB_IOTJS} ${JERRY_LIBS} ${TUV_LIBS} libhttp-parser ${EXTERNAL_STATIC_LIB} ${EXTERNAL_SHARED_LIB} ) if(NOT BUILD_LIB_ONLY) if("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin") set(IOTJS_LINK_FLAGS "-Xlinker -map -Xlinker iotjs.map") else() set(IOTJS_LINK_FLAGS "-Xlinker -Map -Xlinker iotjs.map") endif() # Configure the iotjs executable set(TARGET_IOTJS iotjs) add_executable(${TARGET_IOTJS} ${ROOT_DIR}/iotjs_linux.c) set_target_properties(${TARGET_IOTJS} PROPERTIES COMPILE_OPTIONS "${IOTJS_CFLAGS}" LINK_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${IOTJS_LINK_FLAGS}" RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin" ) target_include_directories(${TARGET_IOTJS} PRIVATE ${IOTJS_INCLUDE_DIRS}) target_link_libraries(${TARGET_IOTJS} ${TARGET_LIB_IOTJS}) endif() iotjs-1.0/cmake/jerry.cmake000066400000000000000000000127621312466455500157420ustar00rootroot00000000000000# Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. cmake_minimum_required(VERSION 2.8) # Host jerry for snapshot generation set(DEPS_HOST_JERRY deps/jerry-host) ExternalProject_Add(hostjerry PREFIX ${DEPS_HOST_JERRY} SOURCE_DIR ${ROOT_DIR}/deps/jerry/ BUILD_IN_SOURCE 0 BINARY_DIR ${DEPS_HOST_JERRY} INSTALL_COMMAND "" CMAKE_ARGS -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DJERRY_LIBC=OFF -DJERRY_CMDLINE=ON -DJERRY_CMDLINE_MINIMAL=OFF -DFEATURE_SNAPSHOT_SAVE=${ENABLE_SNAPSHOT} -DFEATURE_PROFILE=es5.1 ) add_executable(jerry IMPORTED) add_dependencies(jerry hostjerry) set_property(TARGET jerry PROPERTY IMPORTED_LOCATION ${CMAKE_BINARY_DIR}/${DEPS_HOST_JERRY}/bin/jerry) set(JERRY_HOST ${CMAKE_BINARY_DIR}/${DEPS_HOST_JERRY}/bin/jerry) # Utility method to add -D= macro(add_cmake_arg TARGET_ARG KEY) if(${KEY}) list(APPEND ${TARGET_ARG} -D${KEY}=${${KEY}}) endif() endmacro(add_cmake_arg) # Target libjerry set(JERRY_LIBS jerry-core jerry-port-default) set(DEPS_LIB_JERRY_ARGS) # Configure the MinSizeRel as the default build type # for target jerry in release mode. if("${CMAKE_BUILD_TYPE}" STREQUAL "Release") set(JERRY_CMAKE_BUILD_TYPE MinSizeRel) else() set(JERRY_CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE}) endif() # use system libc/libm on Unix like targets if("${TARGET_OS}" MATCHES "TIZENRT|NUTTX") list(APPEND JERRY_LIBS jerry-libm) list(APPEND DEPS_LIB_JERRY_ARGS -DJERRY_LIBC=OFF -DJERRY_LIBM=ON -DEXTERNAL_LIBC_INTERFACE=${EXTERNAL_LIBC_INTERFACE} -DEXTERNAL_CMAKE_SYSTEM_PROCESSOR=${EXTERNAL_CMAKE_SYSTEM_PROCESSOR} ) elseif("${TARGET_OS}" MATCHES "LINUX|TIZEN|DARWIN") list(APPEND JERRY_LIBS m) list(APPEND DEPS_LIB_JERRY_ARGS -DJERRY_LIBC=OFF -DJERRY_LIBM=OFF) else() list(APPEND JERRY_LIBS jerry-libm jerry-libc) list(APPEND DEPS_LIB_JERRY_ARGS -DEXTERNAL_LIBC_INTERFACE=${EXTERNAL_LIBC_INTERFACE} -DEXTERNAL_CMAKE_SYSTEM_PROCESSOR=${EXTERNAL_CMAKE_SYSTEM_PROCESSOR} ) endif() # Add a few cmake options based on buildtype/external cmake defines if("${CMAKE_BUILD_TYPE}" STREQUAL "Debug") list(APPEND DEPS_LIB_JERRY_ARGS -DFEATURE_ERROR_MESSAGES=ON) endif() # NuttX is not using the default port implementation of JerryScript if("${TARGET_OS}" MATCHES "NUTTX") list(APPEND DEPS_LIB_JERRY_ARGS -DJERRY_PORT_DEFAULT=OFF) else() list(APPEND DEPS_LIB_JERRY_ARGS -DJERRY_PORT_DEFAULT=ON) endif() add_cmake_arg(DEPS_LIB_JERRY_ARGS ENABLE_LTO) add_cmake_arg(DEPS_LIB_JERRY_ARGS FEATURE_MEM_STATS) add_cmake_arg(DEPS_LIB_JERRY_ARGS FEATURE_ERROR_MESSAGES) add_cmake_arg(DEPS_LIB_JERRY_ARGS FEATURE_DEBUGGER) add_cmake_arg(DEPS_LIB_JERRY_ARGS FEATURE_DEBUGGER_PORT) add_cmake_arg(DEPS_LIB_JERRY_ARGS MEM_HEAP_SIZE_KB) add_cmake_arg(DEPS_LIB_JERRY_ARGS JERRY_HEAP_SECTION_ATTR) separate_arguments(EXTRA_JERRY_CMAKE_PARAMS) set(DEPS_LIB_JERRY deps/jerry) set(DEPS_LIB_JERRY_SRC ${ROOT_DIR}/${DEPS_LIB_JERRY}) ExternalProject_Add(libjerry PREFIX ${DEPS_LIB_JERRY} SOURCE_DIR ${ROOT_DIR}/deps/jerry/ BUILD_IN_SOURCE 0 BINARY_DIR ${DEPS_LIB_JERRY} INSTALL_COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_BINARY_DIR}/${DEPS_LIB_JERRY}/lib/ ${CMAKE_BINARY_DIR}/lib/ CMAKE_ARGS -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE} -DCMAKE_BUILD_TYPE=${JERRY_CMAKE_BUILD_TYPE} -DCMAKE_C_FLAGS=${CMAKE_C_FLAGS} -DJERRY_CMDLINE=OFF -DJERRY_CMDLINE_MINIMAL=OFF -DFEATURE_SNAPSHOT_EXEC=${ENABLE_SNAPSHOT} -DFEATURE_SNAPSHOT_SAVE=OFF -DFEATURE_PROFILE=${FEATURE_PROFILE} -DENABLE_LTO=${ENABLE_LTO} ${DEPS_LIB_JERRY_ARGS} ${EXTRA_JERRY_CMAKE_PARAMS} ) set_property(DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES ${CMAKE_BINARY_DIR}/lib/libjerry-core.a ${CMAKE_BINARY_DIR}/lib/libjerry-libm.a ${CMAKE_BINARY_DIR}/lib/libjerry-libc.a ) # define external jerry-core target add_library(jerry-core STATIC IMPORTED) add_dependencies(jerry-core libjerry) set_property(TARGET jerry-core PROPERTY IMPORTED_LOCATION ${CMAKE_BINARY_DIR}/lib/libjerry-core.a) # define external jerry-libc target add_library(jerry-libc STATIC IMPORTED) add_dependencies(jerry-libc libjerry) set_property(TARGET jerry-libc PROPERTY IMPORTED_LOCATION ${CMAKE_BINARY_DIR}/lib/libjerry-libc.a) # define external jerry-libm target add_library(jerry-libm STATIC IMPORTED) add_dependencies(jerry-libm libjerry) set_property(TARGET jerry-libm PROPERTY IMPORTED_LOCATION ${CMAKE_BINARY_DIR}/lib/libjerry-libm.a) if(NOT "${TARGET_OS}" MATCHES "NUTTX") set_property(DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES ${CMAKE_BINARY_DIR}/lib/libjerry-port.a ) # define external jerry-port-default target add_library(jerry-port-default STATIC IMPORTED) add_dependencies(jerry-port-default libjerry) set_property(TARGET jerry-port-default PROPERTY IMPORTED_LOCATION ${CMAKE_BINARY_DIR}/lib/libjerry-port-default.a) set(JERRY_PORT_DIR ${DEPS_LIB_JERRY_SRC}/jerry-port/default) endif() set(JERRY_INCLUDE_DIR ${DEPS_LIB_JERRY}/jerry-core/include) iotjs-1.0/cmake/libtuv.cmake000066400000000000000000000035551312466455500161140ustar00rootroot00000000000000# Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. cmake_minimum_required(VERSION 2.8) # Configure external libtuv set(DEPS_TUV deps/libtuv) set(DEPS_TUV_SRC ${ROOT_DIR}/${DEPS_TUV}) set(DEPS_TUV_TOOLCHAIN ${DEPS_TUV_SRC}/cmake/config/config_${PLATFORM_DESCRIPTOR}.cmake) message(STATUS "libtuv toolchain file: ${DEPS_TUV_TOOLCHAIN}") ExternalProject_Add(libtuv PREFIX ${DEPS_TUV} SOURCE_DIR ${DEPS_TUV_SRC} BUILD_IN_SOURCE 0 BINARY_DIR ${DEPS_TUV} INSTALL_COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/${DEPS_TUV}/lib/libtuv.a ${CMAKE_BINARY_DIR}/lib/ CMAKE_ARGS -DCMAKE_TOOLCHAIN_FILE=${DEPS_TUV_TOOLCHAIN} -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_C_FLAGS=${CMAKE_C_FLAGS} -DTARGET_PLATFORM=${PLATFORM_DESCRIPTOR} -DLIBTUV_CUSTOM_LIB_OUT=lib -DBUILDTESTER=NO -DBUILDAPIEMULTESTER=NO -DTARGET_SYSTEMROOT=${TARGET_SYSTEMROOT} -DTARGET_BOARD=${TARGET_BOARD} ) add_library(tuv STATIC IMPORTED) add_dependencies(tuv libtuv) set_property(TARGET tuv PROPERTY IMPORTED_LOCATION ${CMAKE_BINARY_DIR}/lib/libtuv.a) set_property(DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES ${CMAKE_BINARY_DIR}/lib/libtuv.a) set(TUV_INCLUDE_DIR ${DEPS_TUV_SRC}/include) set(TUV_LIBS tuv) if("${TARGET_OS}" STREQUAL "LINUX") list(APPEND TUV_LIBS pthread) endif() iotjs-1.0/config/000077500000000000000000000000001312466455500137625ustar00rootroot00000000000000iotjs-1.0/config/nuttx/000077500000000000000000000000001312466455500151445ustar00rootroot00000000000000iotjs-1.0/config/nuttx/stm32f4dis/000077500000000000000000000000001312466455500170465ustar00rootroot00000000000000iotjs-1.0/config/nuttx/stm32f4dis/.config.default000066400000000000000000001123461312466455500217460ustar00rootroot00000000000000# # Automatically generated file; DO NOT EDIT. # Nuttx/ Configuration # # # Build Setup # # CONFIG_EXPERIMENTAL is not set # CONFIG_DEFAULT_SMALL is not set CONFIG_HOST_LINUX=y # CONFIG_HOST_OSX is not set # CONFIG_HOST_WINDOWS is not set # CONFIG_HOST_OTHER is not set # # Build Configuration # CONFIG_APPS_DIR="../apps" CONFIG_BUILD_FLAT=y # CONFIG_BUILD_2PASS is not set # # Binary Output Formats # # CONFIG_RRLOAD_BINARY is not set CONFIG_INTELHEX_BINARY=y # CONFIG_MOTOROLA_SREC is not set CONFIG_RAW_BINARY=y # CONFIG_UBOOT_UIMAGE is not set # # Customize Header Files # # CONFIG_ARCH_STDINT_H is not set # CONFIG_ARCH_STDBOOL_H is not set # CONFIG_ARCH_MATH_H is not set # CONFIG_ARCH_FLOAT_H is not set # CONFIG_ARCH_STDARG_H is not set # CONFIG_ARCH_DEBUG_H is not set # # Debug Options # CONFIG_DEBUG_ALERT=y # CONFIG_DEBUG_FEATURES is not set CONFIG_ARCH_HAVE_STACKCHECK=y # CONFIG_STACK_COLORATION is not set CONFIG_ARCH_HAVE_HEAPCHECK=y # CONFIG_HEAP_COLORATION is not set # CONFIG_DEBUG_SYMBOLS is not set CONFIG_ARCH_HAVE_CUSTOMOPT=y # CONFIG_DEBUG_NOOPT is not set # CONFIG_DEBUG_CUSTOMOPT is not set CONFIG_DEBUG_FULLOPT=y # # System Type # CONFIG_ARCH_ARM=y # CONFIG_ARCH_AVR is not set # CONFIG_ARCH_HC is not set # CONFIG_ARCH_MIPS is not set # CONFIG_ARCH_RGMP is not set # CONFIG_ARCH_RENESAS is not set # CONFIG_ARCH_SIM is not set # CONFIG_ARCH_X86 is not set # CONFIG_ARCH_Z16 is not set # CONFIG_ARCH_Z80 is not set CONFIG_ARCH="arm" # # ARM Options # # CONFIG_ARCH_CHIP_A1X is not set # CONFIG_ARCH_CHIP_C5471 is not set # CONFIG_ARCH_CHIP_CALYPSO is not set # CONFIG_ARCH_CHIP_DM320 is not set # CONFIG_ARCH_CHIP_EFM32 is not set # CONFIG_ARCH_CHIP_IMX1 is not set # CONFIG_ARCH_CHIP_IMX6 is not set # CONFIG_ARCH_CHIP_KINETIS is not set # CONFIG_ARCH_CHIP_KL is not set # CONFIG_ARCH_CHIP_LM is not set # CONFIG_ARCH_CHIP_TIVA is not set # CONFIG_ARCH_CHIP_LPC11XX is not set # CONFIG_ARCH_CHIP_LPC17XX is not set # CONFIG_ARCH_CHIP_LPC214X is not set # CONFIG_ARCH_CHIP_LPC2378 is not set # CONFIG_ARCH_CHIP_LPC31XX is not set # CONFIG_ARCH_CHIP_LPC43XX is not set # CONFIG_ARCH_CHIP_NUC1XX is not set # CONFIG_ARCH_CHIP_SAMA5 is not set # CONFIG_ARCH_CHIP_SAMD is not set # CONFIG_ARCH_CHIP_SAML is not set # CONFIG_ARCH_CHIP_SAM34 is not set # CONFIG_ARCH_CHIP_SAMV7 is not set CONFIG_ARCH_CHIP_STM32=y # CONFIG_ARCH_CHIP_STM32F7 is not set # CONFIG_ARCH_CHIP_STM32L4 is not set # CONFIG_ARCH_CHIP_STR71X is not set # CONFIG_ARCH_CHIP_TMS570 is not set # CONFIG_ARCH_CHIP_MOXART is not set # CONFIG_ARCH_ARM7TDMI is not set # CONFIG_ARCH_ARM926EJS is not set # CONFIG_ARCH_ARM920T is not set # CONFIG_ARCH_CORTEXM0 is not set # CONFIG_ARCH_CORTEXM3 is not set CONFIG_ARCH_CORTEXM4=y # CONFIG_ARCH_CORTEXM7 is not set # CONFIG_ARCH_CORTEXA5 is not set # CONFIG_ARCH_CORTEXA8 is not set # CONFIG_ARCH_CORTEXA9 is not set # CONFIG_ARCH_CORTEXR4 is not set # CONFIG_ARCH_CORTEXR4F is not set # CONFIG_ARCH_CORTEXR5 is not set # CONFIG_ARCH_CORTEX5F is not set # CONFIG_ARCH_CORTEXR7 is not set # CONFIG_ARCH_CORTEXR7F is not set CONFIG_ARCH_FAMILY="armv7-m" CONFIG_ARCH_CHIP="stm32" # CONFIG_ARM_TOOLCHAIN_IAR is not set CONFIG_ARM_TOOLCHAIN_GNU=y # CONFIG_ARMV7M_USEBASEPRI is not set CONFIG_ARCH_HAVE_CMNVECTOR=y # CONFIG_ARMV7M_CMNVECTOR is not set # CONFIG_ARMV7M_LAZYFPU is not set CONFIG_ARCH_HAVE_FPU=y # CONFIG_ARCH_HAVE_DPFPU is not set CONFIG_ARCH_FPU=y # CONFIG_ARCH_HAVE_TRUSTZONE is not set CONFIG_ARM_HAVE_MPU_UNIFIED=y # CONFIG_ARM_MPU is not set # # ARMV7M Configuration Options # # CONFIG_ARMV7M_HAVE_ICACHE is not set # CONFIG_ARMV7M_HAVE_DCACHE is not set # CONFIG_ARMV7M_HAVE_ITCM is not set # CONFIG_ARMV7M_HAVE_DTCM is not set # CONFIG_ARMV7M_TOOLCHAIN_IARL is not set # CONFIG_ARMV7M_TOOLCHAIN_BUILDROOT is not set # CONFIG_ARMV7M_TOOLCHAIN_CODEREDL is not set # CONFIG_ARMV7M_TOOLCHAIN_CODESOURCERYL is not set CONFIG_ARMV7M_TOOLCHAIN_GNU_EABIL=y CONFIG_ARMV7M_HAVE_STACKCHECK=y # CONFIG_ARMV7M_STACKCHECK is not set # CONFIG_ARMV7M_ITMSYSLOG is not set # CONFIG_SERIAL_TERMIOS is not set # CONFIG_SDIO_DMA is not set # CONFIG_SDIO_WIDTH_D1_ONLY is not set # # STM32 Configuration Options # # CONFIG_ARCH_CHIP_STM32L151C6 is not set # CONFIG_ARCH_CHIP_STM32L151C8 is not set # CONFIG_ARCH_CHIP_STM32L151CB is not set # CONFIG_ARCH_CHIP_STM32L151R6 is not set # CONFIG_ARCH_CHIP_STM32L151R8 is not set # CONFIG_ARCH_CHIP_STM32L151RB is not set # CONFIG_ARCH_CHIP_STM32L151V6 is not set # CONFIG_ARCH_CHIP_STM32L151V8 is not set # CONFIG_ARCH_CHIP_STM32L151VB is not set # CONFIG_ARCH_CHIP_STM32L152C6 is not set # CONFIG_ARCH_CHIP_STM32L152C8 is not set # CONFIG_ARCH_CHIP_STM32L152CB is not set # CONFIG_ARCH_CHIP_STM32L152R6 is not set # CONFIG_ARCH_CHIP_STM32L152R8 is not set # CONFIG_ARCH_CHIP_STM32L152RB is not set # CONFIG_ARCH_CHIP_STM32L152V6 is not set # CONFIG_ARCH_CHIP_STM32L152V8 is not set # CONFIG_ARCH_CHIP_STM32L152VB is not set # CONFIG_ARCH_CHIP_STM32L162ZD is not set # CONFIG_ARCH_CHIP_STM32L162VE is not set # CONFIG_ARCH_CHIP_STM32F100C8 is not set # CONFIG_ARCH_CHIP_STM32F100CB is not set # CONFIG_ARCH_CHIP_STM32F100R8 is not set # CONFIG_ARCH_CHIP_STM32F100RB is not set # CONFIG_ARCH_CHIP_STM32F100RC is not set # CONFIG_ARCH_CHIP_STM32F100RD is not set # CONFIG_ARCH_CHIP_STM32F100RE is not set # CONFIG_ARCH_CHIP_STM32F100V8 is not set # CONFIG_ARCH_CHIP_STM32F100VB is not set # CONFIG_ARCH_CHIP_STM32F100VC is not set # CONFIG_ARCH_CHIP_STM32F100VD is not set # CONFIG_ARCH_CHIP_STM32F100VE is not set # CONFIG_ARCH_CHIP_STM32F102CB is not set # CONFIG_ARCH_CHIP_STM32F103T8 is not set # CONFIG_ARCH_CHIP_STM32F103TB is not set # CONFIG_ARCH_CHIP_STM32F103C4 is not set # CONFIG_ARCH_CHIP_STM32F103C8 is not set # CONFIG_ARCH_CHIP_STM32F103CB is not set # CONFIG_ARCH_CHIP_STM32F103R8 is not set # CONFIG_ARCH_CHIP_STM32F103RB is not set # CONFIG_ARCH_CHIP_STM32F103RC is not set # CONFIG_ARCH_CHIP_STM32F103RD is not set # CONFIG_ARCH_CHIP_STM32F103RE is not set # CONFIG_ARCH_CHIP_STM32F103RG is not set # CONFIG_ARCH_CHIP_STM32F103V8 is not set # CONFIG_ARCH_CHIP_STM32F103VB is not set # CONFIG_ARCH_CHIP_STM32F103VC is not set # CONFIG_ARCH_CHIP_STM32F103VE is not set # CONFIG_ARCH_CHIP_STM32F103ZE is not set # CONFIG_ARCH_CHIP_STM32F105VB is not set # CONFIG_ARCH_CHIP_STM32F105RB is not set # CONFIG_ARCH_CHIP_STM32F107VC is not set # CONFIG_ARCH_CHIP_STM32F205RG is not set # CONFIG_ARCH_CHIP_STM32F207IG is not set # CONFIG_ARCH_CHIP_STM32F207ZE is not set # CONFIG_ARCH_CHIP_STM32F302K6 is not set # CONFIG_ARCH_CHIP_STM32F302K8 is not set # CONFIG_ARCH_CHIP_STM32F302CB is not set # CONFIG_ARCH_CHIP_STM32F302CC is not set # CONFIG_ARCH_CHIP_STM32F302RB is not set # CONFIG_ARCH_CHIP_STM32F302RC is not set # CONFIG_ARCH_CHIP_STM32F302VB is not set # CONFIG_ARCH_CHIP_STM32F302VC is not set # CONFIG_ARCH_CHIP_STM32F303K6 is not set # CONFIG_ARCH_CHIP_STM32F303K8 is not set # CONFIG_ARCH_CHIP_STM32F303C6 is not set # CONFIG_ARCH_CHIP_STM32F303C8 is not set # CONFIG_ARCH_CHIP_STM32F303CB is not set # CONFIG_ARCH_CHIP_STM32F303CC is not set # CONFIG_ARCH_CHIP_STM32F303RB is not set # CONFIG_ARCH_CHIP_STM32F303RC is not set # CONFIG_ARCH_CHIP_STM32F303RD is not set # CONFIG_ARCH_CHIP_STM32F303RE is not set # CONFIG_ARCH_CHIP_STM32F303VB is not set # CONFIG_ARCH_CHIP_STM32F303VC is not set # CONFIG_ARCH_CHIP_STM32F372C8 is not set # CONFIG_ARCH_CHIP_STM32F372R8 is not set # CONFIG_ARCH_CHIP_STM32F372V8 is not set # CONFIG_ARCH_CHIP_STM32F372CB is not set # CONFIG_ARCH_CHIP_STM32F372RB is not set # CONFIG_ARCH_CHIP_STM32F372VB is not set # CONFIG_ARCH_CHIP_STM32F372CC is not set # CONFIG_ARCH_CHIP_STM32F372RC is not set # CONFIG_ARCH_CHIP_STM32F372VC is not set # CONFIG_ARCH_CHIP_STM32F373C8 is not set # CONFIG_ARCH_CHIP_STM32F373R8 is not set # CONFIG_ARCH_CHIP_STM32F373V8 is not set # CONFIG_ARCH_CHIP_STM32F373CB is not set # CONFIG_ARCH_CHIP_STM32F373RB is not set # CONFIG_ARCH_CHIP_STM32F373VB is not set # CONFIG_ARCH_CHIP_STM32F373CC is not set # CONFIG_ARCH_CHIP_STM32F373RC is not set # CONFIG_ARCH_CHIP_STM32F373VC is not set # CONFIG_ARCH_CHIP_STM32F401RE is not set # CONFIG_ARCH_CHIP_STM32F411RE is not set # CONFIG_ARCH_CHIP_STM32F411VE is not set # CONFIG_ARCH_CHIP_STM32F405RG is not set # CONFIG_ARCH_CHIP_STM32F405VG is not set # CONFIG_ARCH_CHIP_STM32F405ZG is not set # CONFIG_ARCH_CHIP_STM32F407VE is not set CONFIG_ARCH_CHIP_STM32F407VG=y # CONFIG_ARCH_CHIP_STM32F407ZE is not set # CONFIG_ARCH_CHIP_STM32F407ZG is not set # CONFIG_ARCH_CHIP_STM32F407IE is not set # CONFIG_ARCH_CHIP_STM32F407IG is not set # CONFIG_ARCH_CHIP_STM32F427V is not set # CONFIG_ARCH_CHIP_STM32F427Z is not set # CONFIG_ARCH_CHIP_STM32F427I is not set # CONFIG_ARCH_CHIP_STM32F429V is not set # CONFIG_ARCH_CHIP_STM32F429Z is not set # CONFIG_ARCH_CHIP_STM32F429I is not set # CONFIG_ARCH_CHIP_STM32F429B is not set # CONFIG_ARCH_CHIP_STM32F429N is not set # CONFIG_ARCH_CHIP_STM32F446M is not set # CONFIG_ARCH_CHIP_STM32F446R is not set # CONFIG_ARCH_CHIP_STM32F446V is not set # CONFIG_ARCH_CHIP_STM32F446Z is not set # CONFIG_ARCH_CHIP_STM32F469A is not set # CONFIG_ARCH_CHIP_STM32F469I is not set # CONFIG_ARCH_CHIP_STM32F469B is not set # CONFIG_ARCH_CHIP_STM32F469N is not set CONFIG_STM32_FLASH_CONFIG_DEFAULT=y # CONFIG_STM32_FLASH_CONFIG_4 is not set # CONFIG_STM32_FLASH_CONFIG_6 is not set # CONFIG_STM32_FLASH_CONFIG_8 is not set # CONFIG_STM32_FLASH_CONFIG_B is not set # CONFIG_STM32_FLASH_CONFIG_C is not set # CONFIG_STM32_FLASH_CONFIG_D is not set # CONFIG_STM32_FLASH_CONFIG_E is not set # CONFIG_STM32_FLASH_CONFIG_F is not set # CONFIG_STM32_FLASH_CONFIG_G is not set # CONFIG_STM32_FLASH_CONFIG_I is not set # CONFIG_STM32_STM32L15XX is not set # CONFIG_STM32_ENERGYLITE is not set # CONFIG_STM32_STM32F10XX is not set # CONFIG_STM32_VALUELINE is not set # CONFIG_STM32_CONNECTIVITYLINE is not set # CONFIG_STM32_PERFORMANCELINE is not set # CONFIG_STM32_USBACCESSLINE is not set # CONFIG_STM32_HIGHDENSITY is not set # CONFIG_STM32_MEDIUMDENSITY is not set # CONFIG_STM32_LOWDENSITY is not set # CONFIG_STM32_STM32F20XX is not set # CONFIG_STM32_STM32F205 is not set # CONFIG_STM32_STM32F207 is not set # CONFIG_STM32_STM32F30XX is not set # CONFIG_STM32_STM32F302 is not set # CONFIG_STM32_STM32F303 is not set # CONFIG_STM32_STM32F37XX is not set CONFIG_STM32_STM32F40XX=y # CONFIG_STM32_STM32F401 is not set # CONFIG_STM32_STM32F411 is not set # CONFIG_STM32_STM32F405 is not set CONFIG_STM32_STM32F407=y # CONFIG_STM32_STM32F427 is not set # CONFIG_STM32_STM32F429 is not set # CONFIG_STM32_STM32F446 is not set # CONFIG_STM32_STM32F469 is not set # CONFIG_STM32_DFU is not set # # STM32 Peripheral Support # CONFIG_STM32_HAVE_CCM=y # CONFIG_STM32_HAVE_USBDEV is not set CONFIG_STM32_HAVE_OTGFS=y CONFIG_STM32_HAVE_FSMC=y # CONFIG_STM32_HAVE_LTDC is not set CONFIG_STM32_HAVE_USART3=y CONFIG_STM32_HAVE_UART4=y CONFIG_STM32_HAVE_UART5=y CONFIG_STM32_HAVE_USART6=y # CONFIG_STM32_HAVE_UART7 is not set # CONFIG_STM32_HAVE_UART8 is not set CONFIG_STM32_HAVE_TIM1=y CONFIG_STM32_HAVE_TIM2=y CONFIG_STM32_HAVE_TIM3=y CONFIG_STM32_HAVE_TIM4=y CONFIG_STM32_HAVE_TIM5=y CONFIG_STM32_HAVE_TIM6=y CONFIG_STM32_HAVE_TIM7=y CONFIG_STM32_HAVE_TIM8=y CONFIG_STM32_HAVE_TIM9=y CONFIG_STM32_HAVE_TIM10=y CONFIG_STM32_HAVE_TIM11=y CONFIG_STM32_HAVE_TIM12=y CONFIG_STM32_HAVE_TIM13=y CONFIG_STM32_HAVE_TIM14=y # CONFIG_STM32_HAVE_TIM15 is not set # CONFIG_STM32_HAVE_TIM16 is not set # CONFIG_STM32_HAVE_TIM17 is not set CONFIG_STM32_HAVE_ADC2=y CONFIG_STM32_HAVE_ADC3=y # CONFIG_STM32_HAVE_ADC4 is not set # CONFIG_STM32_HAVE_ADC1_DMA is not set # CONFIG_STM32_HAVE_ADC2_DMA is not set # CONFIG_STM32_HAVE_ADC3_DMA is not set # CONFIG_STM32_HAVE_ADC4_DMA is not set CONFIG_STM32_HAVE_CAN1=y CONFIG_STM32_HAVE_CAN2=y CONFIG_STM32_HAVE_DAC1=y CONFIG_STM32_HAVE_DAC2=y CONFIG_STM32_HAVE_RNG=y CONFIG_STM32_HAVE_ETHMAC=y CONFIG_STM32_HAVE_I2C2=y CONFIG_STM32_HAVE_I2C3=y CONFIG_STM32_HAVE_SPI2=y CONFIG_STM32_HAVE_SPI3=y # CONFIG_STM32_HAVE_SPI4 is not set # CONFIG_STM32_HAVE_SPI5 is not set # CONFIG_STM32_HAVE_SPI6 is not set # CONFIG_STM32_HAVE_SAIPLL is not set # CONFIG_STM32_HAVE_I2SPLL is not set # CONFIG_STM32_ADC1 is not set # CONFIG_STM32_ADC2 is not set # CONFIG_STM32_ADC3 is not set # CONFIG_STM32_BKPSRAM is not set # CONFIG_STM32_CAN1 is not set # CONFIG_STM32_CAN2 is not set # CONFIG_STM32_CCMDATARAM is not set # CONFIG_STM32_CRC is not set # CONFIG_STM32_CRYP is not set # CONFIG_STM32_DMA1 is not set # CONFIG_STM32_DMA2 is not set # CONFIG_STM32_DAC1 is not set # CONFIG_STM32_DAC2 is not set # CONFIG_STM32_DCMI is not set # CONFIG_STM32_ETHMAC is not set # CONFIG_STM32_FSMC is not set # CONFIG_STM32_HASH is not set # CONFIG_STM32_I2C1 is not set # CONFIG_STM32_I2C2 is not set # CONFIG_STM32_I2C3 is not set CONFIG_STM32_OTGFS=y # CONFIG_STM32_OTGHS is not set CONFIG_STM32_PWR=y # CONFIG_STM32_RNG is not set CONFIG_STM32_SDIO=y CONFIG_STM32_SPI1=y # CONFIG_STM32_SPI2 is not set # CONFIG_STM32_SPI3 is not set CONFIG_STM32_SYSCFG=y # CONFIG_STM32_TIM1 is not set # CONFIG_STM32_TIM2 is not set # CONFIG_STM32_TIM3 is not set # CONFIG_STM32_TIM4 is not set # CONFIG_STM32_TIM5 is not set # CONFIG_STM32_TIM6 is not set # CONFIG_STM32_TIM7 is not set # CONFIG_STM32_TIM8 is not set # CONFIG_STM32_TIM9 is not set # CONFIG_STM32_TIM10 is not set # CONFIG_STM32_TIM11 is not set # CONFIG_STM32_TIM12 is not set # CONFIG_STM32_TIM13 is not set # CONFIG_STM32_TIM14 is not set # CONFIG_STM32_USART1 is not set CONFIG_STM32_USART2=y # CONFIG_STM32_USART3 is not set # CONFIG_STM32_UART4 is not set # CONFIG_STM32_UART5 is not set # CONFIG_STM32_USART6 is not set # CONFIG_STM32_IWDG is not set # CONFIG_STM32_WWDG is not set CONFIG_STM32_SPI=y # CONFIG_STM32_NOEXT_VECTORS is not set # # Alternate Pin Mapping # # CONFIG_STM32_FLASH_PREFETCH is not set # CONFIG_STM32_JTAG_DISABLE is not set # CONFIG_STM32_JTAG_FULL_ENABLE is not set # CONFIG_STM32_JTAG_NOJNTRST_ENABLE is not set CONFIG_STM32_JTAG_SW_ENABLE=y # CONFIG_STM32_DISABLE_IDLE_SLEEP_DURING_DEBUG is not set # CONFIG_STM32_FORCEPOWER is not set # CONFIG_ARCH_BOARD_STM32_CUSTOM_CLOCKCONFIG is not set # CONFIG_STM32_CCMEXCLUDE is not set # # Timer Configuration # # CONFIG_STM32_ONESHOT is not set # CONFIG_STM32_FREERUN is not set # CONFIG_STM32_TIM1_CAP is not set # CONFIG_STM32_TIM2_CAP is not set # CONFIG_STM32_TIM3_CAP is not set # CONFIG_STM32_TIM4_CAP is not set # CONFIG_STM32_TIM5_CAP is not set # CONFIG_STM32_TIM8_CAP is not set # CONFIG_STM32_TIM9_CAP is not set # CONFIG_STM32_TIM10_CAP is not set # CONFIG_STM32_TIM11_CAP is not set # CONFIG_STM32_TIM12_CAP is not set # CONFIG_STM32_TIM13_CAP is not set # CONFIG_STM32_TIM14_CAP is not set CONFIG_STM32_USART=y CONFIG_STM32_SERIALDRIVER=y # # U[S]ART Configuration # # # U[S]ART Device Configuration # CONFIG_STM32_USART2_SERIALDRIVER=y # CONFIG_STM32_USART2_1WIREDRIVER is not set # CONFIG_USART2_RS485 is not set # # Serial Driver Configuration # # CONFIG_SERIAL_DISABLE_REORDERING is not set # CONFIG_STM32_FLOWCONTROL_BROKEN is not set # CONFIG_STM32_USART_BREAKS is not set # CONFIG_STM32_USART_SINGLEWIRE is not set # # SPI Configuration # # CONFIG_STM32_SPI_INTERRUPTS is not set # CONFIG_STM32_SPI_DMA is not set # # SDIO Configuration # CONFIG_SDIO_DMAPRIO=0x00010000 # CONFIG_STM32_HAVE_RTC_COUNTER is not set # CONFIG_STM32_HAVE_RTC_SUBSECONDS is not set # # USB FS Host Configuration # # # USB HS Host Configuration # # # USB Host Debug Configuration # # # USB Device Configuration # # # Architecture Options # # CONFIG_ARCH_NOINTC is not set # CONFIG_ARCH_VECNOTIRQ is not set # CONFIG_ARCH_DMA is not set CONFIG_ARCH_HAVE_IRQPRIO=y # CONFIG_ARCH_L2CACHE is not set # CONFIG_ARCH_HAVE_COHERENT_DCACHE is not set # CONFIG_ARCH_HAVE_ADDRENV is not set # CONFIG_ARCH_NEED_ADDRENV_MAPPING is not set # CONFIG_ARCH_HAVE_MULTICPU is not set CONFIG_ARCH_HAVE_VFORK=y # CONFIG_ARCH_HAVE_MMU is not set CONFIG_ARCH_HAVE_MPU=y # CONFIG_ARCH_NAND_HWECC is not set # CONFIG_ARCH_HAVE_EXTCLK is not set # CONFIG_ARCH_HAVE_POWEROFF is not set CONFIG_ARCH_HAVE_RESET=y # CONFIG_ARCH_USE_MPU is not set # CONFIG_ARCH_IRQPRIO is not set CONFIG_ARCH_STACKDUMP=y # CONFIG_ENDIAN_BIG is not set # CONFIG_ARCH_IDLE_CUSTOM is not set # CONFIG_ARCH_HAVE_RAMFUNCS is not set CONFIG_ARCH_HAVE_RAMVECTORS=y # CONFIG_ARCH_RAMVECTORS is not set # # Board Settings # CONFIG_BOARD_LOOPSPERMSEC=16717 # CONFIG_ARCH_CALIBRATION is not set # # Interrupt options # CONFIG_ARCH_HAVE_INTERRUPTSTACK=y CONFIG_ARCH_INTERRUPTSTACK=0 CONFIG_ARCH_HAVE_HIPRI_INTERRUPT=y # CONFIG_ARCH_HIPRI_INTERRUPT is not set # # Boot options # # CONFIG_BOOT_RUNFROMEXTSRAM is not set CONFIG_BOOT_RUNFROMFLASH=y # CONFIG_BOOT_RUNFROMISRAM is not set # CONFIG_BOOT_RUNFROMSDRAM is not set # CONFIG_BOOT_COPYTORAM is not set # # Boot Memory Configuration # CONFIG_RAM_START=0x20000000 CONFIG_RAM_SIZE=114688 # CONFIG_ARCH_HAVE_SDRAM is not set # # Board Selection # CONFIG_ARCH_BOARD_STM32F4_DISCOVERY=y # CONFIG_ARCH_BOARD_MIKROE_STM32F4 is not set # CONFIG_ARCH_BOARD_CUSTOM is not set CONFIG_ARCH_BOARD="stm32f4discovery" # # Common Board Options # CONFIG_ARCH_HAVE_LEDS=y CONFIG_ARCH_LEDS=y CONFIG_ARCH_HAVE_BUTTONS=y CONFIG_ARCH_BUTTONS=y CONFIG_ARCH_HAVE_IRQBUTTONS=y # CONFIG_ARCH_IRQBUTTONS is not set # # Board-Specific Options # # CONFIG_STM32F4DISBB is not set # CONFIG_BOARD_CRASHDUMP is not set CONFIG_LIB_BOARDCTL=y # CONFIG_BOARDCTL_RESET is not set # CONFIG_BOARDCTL_UNIQUEID is not set CONFIG_BOARDCTL_USBDEVCTRL=y # CONFIG_BOARDCTL_TSCTEST is not set # CONFIG_BOARDCTL_ADCTEST is not set # CONFIG_BOARDCTL_PWMTEST is not set # CONFIG_BOARDCTL_GRAPHICS is not set # CONFIG_BOARDCTL_IOCTL is not set # # RTOS Features # CONFIG_DISABLE_OS_API=y # CONFIG_DISABLE_POSIX_TIMERS is not set # CONFIG_DISABLE_PTHREAD is not set # CONFIG_DISABLE_SIGNALS is not set # CONFIG_DISABLE_MQUEUE is not set # CONFIG_DISABLE_ENVIRON is not set # # Clocks and Timers # CONFIG_ARCH_HAVE_TICKLESS=y # CONFIG_SCHED_TICKLESS is not set CONFIG_USEC_PER_TICK=10000 # CONFIG_SYSTEM_TIME64 is not set CONFIG_CLOCK_MONOTONIC=y CONFIG_ARCH_HAVE_TIMEKEEPING=y # CONFIG_JULIAN_TIME is not set CONFIG_START_YEAR=2013 CONFIG_START_MONTH=1 CONFIG_START_DAY=27 CONFIG_MAX_WDOGPARMS=2 CONFIG_PREALLOC_WDOGS=8 CONFIG_WDOG_INTRESERVE=1 CONFIG_PREALLOC_TIMERS=4 # # Tasks and Scheduling # # CONFIG_INIT_NONE is not set CONFIG_INIT_ENTRYPOINT=y # CONFIG_INIT_FILEPATH is not set CONFIG_USER_ENTRYPOINT="nsh_main" CONFIG_RR_INTERVAL=200 # CONFIG_SCHED_SPORADIC is not set CONFIG_TASK_NAME_SIZE=31 CONFIG_MAX_TASKS=16 # CONFIG_SCHED_HAVE_PARENT is not set CONFIG_SCHED_WAITPID=y # # Pthread Options # CONFIG_MUTEX_TYPES=y CONFIG_NPTHREAD_KEYS=4 # # Performance Monitoring # # CONFIG_SCHED_CPULOAD is not set # CONFIG_SCHED_INSTRUMENTATION is not set # # Files and I/O # CONFIG_DEV_CONSOLE=y # CONFIG_FDCLONE_DISABLE is not set # CONFIG_FDCLONE_STDIO is not set CONFIG_SDCLONE_DISABLE=y CONFIG_NFILE_DESCRIPTORS=8 CONFIG_NFILE_STREAMS=8 CONFIG_NAME_MAX=32 # CONFIG_PRIORITY_INHERITANCE is not set # # RTOS hooks # # CONFIG_BOARD_INITIALIZE is not set # CONFIG_SCHED_STARTHOOK is not set # CONFIG_SCHED_ATEXIT is not set # CONFIG_SCHED_ONEXIT is not set # CONFIG_SIG_EVTHREAD is not set # # Signal Numbers # CONFIG_SIG_SIGUSR1=1 CONFIG_SIG_SIGUSR2=2 CONFIG_SIG_SIGALARM=3 CONFIG_SIG_SIGCONDTIMEDOUT=16 CONFIG_SIG_SIGWORK=17 # # POSIX Message Queue Options # CONFIG_PREALLOC_MQ_MSGS=4 CONFIG_MQ_MAXMSGSIZE=32 # CONFIG_MODULE is not set # # Work queue support # CONFIG_SCHED_WORKQUEUE=y CONFIG_SCHED_HPWORK=y CONFIG_SCHED_HPWORKPRIORITY=224 CONFIG_SCHED_HPWORKPERIOD=50000 CONFIG_SCHED_HPWORKSTACKSIZE=2048 # CONFIG_SCHED_LPWORK is not set # # Stack and heap information # CONFIG_IDLETHREAD_STACKSIZE=2048 CONFIG_USERMAIN_STACKSIZE=2048 CONFIG_PTHREAD_STACK_MIN=256 CONFIG_PTHREAD_STACK_DEFAULT=2048 # CONFIG_LIB_SYSCALL is not set # # Device Drivers # # CONFIG_DISABLE_POLL is not set CONFIG_DEV_NULL=y # CONFIG_DEV_ZERO is not set # CONFIG_DEV_URANDOM is not set # CONFIG_DEV_LOOP is not set # # Buffering # # CONFIG_DRVR_WRITEBUFFER is not set # CONFIG_DRVR_READAHEAD is not set # CONFIG_RAMDISK is not set # CONFIG_CAN is not set # CONFIG_ARCH_HAVE_PWM_PULSECOUNT is not set # CONFIG_ARCH_HAVE_PWM_MULTICHAN is not set # CONFIG_PWM is not set CONFIG_ARCH_HAVE_I2CRESET=y # CONFIG_I2C is not set CONFIG_SPI=y # CONFIG_SPI_SLAVE is not set CONFIG_SPI_EXCHANGE=y # CONFIG_SPI_CMDDATA is not set # CONFIG_SPI_CALLBACK is not set # CONFIG_SPI_HWFEATURES is not set # CONFIG_ARCH_HAVE_SPI_CRCGENERATION is not set # CONFIG_ARCH_HAVE_SPI_CS_CONTROL is not set CONFIG_ARCH_HAVE_SPI_BITORDER=y # CONFIG_SPI_BITORDER is not set # CONFIG_SPI_CS_DELAY_CONTROL is not set # CONFIG_SPI_DRIVER is not set # CONFIG_SPI_BITBANG is not set # CONFIG_I2S is not set # # Timer Driver Support # # CONFIG_TIMER is not set # CONFIG_ONESHOT is not set # CONFIG_RTC is not set # CONFIG_WATCHDOG is not set # CONFIG_ANALOG is not set # CONFIG_AUDIO_DEVICES is not set # CONFIG_VIDEO_DEVICES is not set # CONFIG_BCH is not set # CONFIG_INPUT is not set # # IO Expander/GPIO Support # # CONFIG_IOEXPANDER is not set # CONFIG_DEV_GPIO is not set # # LCD Driver Support # # CONFIG_LCD is not set # CONFIG_SLCD is not set # # LED Support # # CONFIG_USERLED is not set # CONFIG_RGBLED is not set # CONFIG_PCA9635PW is not set # CONFIG_NCP5623C is not set CONFIG_MMCSD=y CONFIG_MMCSD_NSLOTS=1 # CONFIG_MMCSD_READONLY is not set # CONFIG_MMCSD_MULTIBLOCK_DISABLE is not set CONFIG_MMCSD_MMCSUPPORT=y CONFIG_MMCSD_HAVECARDDETECT=y CONFIG_MMCSD_SPI=y CONFIG_MMCSD_SPICLOCK=20000000 CONFIG_MMCSD_SPIMODE=0 CONFIG_ARCH_HAVE_SDIO=y CONFIG_ARCH_HAVE_SDIOWAIT_WRCOMPLETE=y CONFIG_MMCSD_SDIO=y CONFIG_SDIO_PREFLIGHT=y # CONFIG_SDIO_MUXBUS is not set # CONFIG_MMCSD_SDIOWAIT_WRCOMPLETE is not set # CONFIG_SDIO_BLOCKSETUP is not set # CONFIG_MODEM is not set # CONFIG_MTD is not set # CONFIG_EEPROM is not set CONFIG_NETDEVICES=y # # General Ethernet MAC Driver Options # # CONFIG_NETDEV_LOOPBACK is not set # CONFIG_NETDEV_TELNET is not set # CONFIG_NETDEV_MULTINIC is not set # CONFIG_ARCH_HAVE_NETDEV_STATISTICS is not set CONFIG_NETDEV_LATEINIT=y # # External Ethernet MAC Device Support # # CONFIG_NET_DM90x0 is not set # CONFIG_ENC28J60 is not set # CONFIG_ENCX24J600 is not set # CONFIG_NET_E1000 is not set # CONFIG_NET_SLIP is not set # CONFIG_NET_FTMAC100 is not set # CONFIG_NET_VNET is not set CONFIG_PIPES=y CONFIG_DEV_PIPE_MAXSIZE=1024 CONFIG_DEV_PIPE_SIZE=1024 CONFIG_DEV_FIFO_SIZE=1024 # CONFIG_PM is not set # CONFIG_POWER is not set # CONFIG_SENSORS is not set # CONFIG_SERCOMM_CONSOLE is not set CONFIG_SERIAL=y # CONFIG_DEV_LOWCONSOLE is not set CONFIG_SERIAL_REMOVABLE=y # CONFIG_SERIAL_CONSOLE is not set # CONFIG_16550_UART is not set # CONFIG_UART_SERIALDRIVER is not set # CONFIG_UART0_SERIALDRIVER is not set # CONFIG_UART1_SERIALDRIVER is not set # CONFIG_UART2_SERIALDRIVER is not set # CONFIG_UART3_SERIALDRIVER is not set # CONFIG_UART4_SERIALDRIVER is not set # CONFIG_UART5_SERIALDRIVER is not set # CONFIG_UART6_SERIALDRIVER is not set # CONFIG_UART7_SERIALDRIVER is not set # CONFIG_UART8_SERIALDRIVER is not set # CONFIG_SCI0_SERIALDRIVER is not set # CONFIG_SCI1_SERIALDRIVER is not set # CONFIG_USART0_SERIALDRIVER is not set # CONFIG_USART1_SERIALDRIVER is not set CONFIG_USART2_SERIALDRIVER=y # CONFIG_USART3_SERIALDRIVER is not set # CONFIG_USART4_SERIALDRIVER is not set # CONFIG_USART5_SERIALDRIVER is not set # CONFIG_USART6_SERIALDRIVER is not set # CONFIG_USART7_SERIALDRIVER is not set # CONFIG_USART8_SERIALDRIVER is not set # CONFIG_OTHER_UART_SERIALDRIVER is not set CONFIG_MCU_SERIAL=y CONFIG_STANDARD_SERIAL=y CONFIG_SERIAL_NPOLLWAITERS=2 # CONFIG_SERIAL_IFLOWCONTROL is not set # CONFIG_SERIAL_OFLOWCONTROL is not set # CONFIG_SERIAL_DMA is not set CONFIG_ARCH_HAVE_SERIAL_TERMIOS=y # CONFIG_USART2_SERIAL_CONSOLE is not set # CONFIG_OTHER_SERIAL_CONSOLE is not set CONFIG_NO_SERIAL_CONSOLE=y # # USART2 Configuration # CONFIG_USART2_RXBUFSIZE=256 CONFIG_USART2_TXBUFSIZE=256 CONFIG_USART2_BAUD=115200 CONFIG_USART2_BITS=8 CONFIG_USART2_PARITY=0 CONFIG_USART2_2STOP=0 # CONFIG_USART2_IFLOWCONTROL is not set # CONFIG_USART2_OFLOWCONTROL is not set # CONFIG_USART2_DMA is not set # CONFIG_PSEUDOTERM is not set CONFIG_USBDEV=y # # USB Device Controller Driver Options # # CONFIG_USBDEV_ISOCHRONOUS is not set # CONFIG_USBDEV_DUALSPEED is not set CONFIG_USBDEV_SELFPOWERED=y # CONFIG_USBDEV_BUSPOWERED is not set CONFIG_USBDEV_MAXPOWER=100 # CONFIG_USBDEV_DMA is not set # CONFIG_ARCH_USBDEV_STALLQUEUE is not set # CONFIG_USBDEV_TRACE is not set # # USB Device Class Driver Options # # CONFIG_USBDEV_COMPOSITE is not set # CONFIG_PL2303 is not set CONFIG_CDCACM=y CONFIG_CDCACM_CONSOLE=y CONFIG_CDCACM_EP0MAXPACKET=64 CONFIG_CDCACM_EPINTIN=1 CONFIG_CDCACM_EPINTIN_FSSIZE=64 CONFIG_CDCACM_EPINTIN_HSSIZE=64 CONFIG_CDCACM_EPBULKOUT=3 CONFIG_CDCACM_EPBULKOUT_FSSIZE=64 CONFIG_CDCACM_EPBULKOUT_HSSIZE=512 CONFIG_CDCACM_EPBULKIN=2 CONFIG_CDCACM_EPBULKIN_FSSIZE=64 CONFIG_CDCACM_EPBULKIN_HSSIZE=512 CONFIG_CDCACM_NRDREQS=4 CONFIG_CDCACM_NWRREQS=4 CONFIG_CDCACM_BULKIN_REQLEN=96 CONFIG_CDCACM_RXBUFSIZE=256 CONFIG_CDCACM_TXBUFSIZE=256 CONFIG_CDCACM_VENDORID=0x0525 CONFIG_CDCACM_PRODUCTID=0xa4a7 CONFIG_CDCACM_VENDORSTR="NuttX" CONFIG_CDCACM_PRODUCTSTR="CDC/ACM Serial" # CONFIG_USBMSC is not set # CONFIG_USBHOST is not set # CONFIG_HAVE_USBTRACE is not set # CONFIG_DRIVERS_WIRELESS is not set # CONFIG_DRIVERS_CONTACTLESS is not set # # System Logging # # CONFIG_ARCH_SYSLOG is not set # CONFIG_RAMLOG is not set # CONFIG_SYSLOG_INTBUFFER is not set # CONFIG_SYSLOG_TIMESTAMP is not set # CONFIG_SYSLOG_SERIAL_CONSOLE is not set CONFIG_SYSLOG_CHAR=y # CONFIG_SYSLOG_CONSOLE is not set # CONFIG_SYSLOG_NONE is not set # CONFIG_SYSLOG_FILE is not set # CONFIG_CONSOLE_SYSLOG is not set CONFIG_SYSLOG_CHAR_CRLF=y CONFIG_SYSLOG_DEVPATH="/dev/ttyS0" # CONFIG_SYSLOG_CHARDEV is not set # # Networking Support # CONFIG_ARCH_HAVE_NET=y # CONFIG_ARCH_HAVE_PHY is not set CONFIG_NET=y # CONFIG_NET_NOINTS is not set # CONFIG_NET_PROMISCUOUS is not set # # Driver buffer configuration # # CONFIG_NET_MULTIBUFFER is not set CONFIG_NET_ETH_MTU=590 CONFIG_NET_ETH_TCP_RECVWNDO=536 CONFIG_NET_GUARDSIZE=2 # # Data link support # # CONFIG_NET_MULTILINK is not set CONFIG_NET_ETHERNET=y # CONFIG_NET_LOOPBACK is not set # CONFIG_NET_TUN is not set # # Network Device Operations # # CONFIG_NETDEV_PHY_IOCTL is not set # # Internet Protocol Selection # CONFIG_NET_IPv4=y # CONFIG_NET_IPv6 is not set # # Socket Support # CONFIG_NSOCKET_DESCRIPTORS=8 CONFIG_NET_NACTIVESOCKETS=16 CONFIG_NET_SOCKOPTS=y # CONFIG_NET_SOLINGER is not set # # Raw Socket Support # # CONFIG_NET_PKT is not set # # Unix Domain Socket Support # CONFIG_NET_LOCAL=y CONFIG_NET_LOCAL_STREAM=y CONFIG_NET_LOCAL_DGRAM=y # # TCP/IP Networking # CONFIG_NET_TCP=y # CONFIG_NET_TCPURGDATA is not set CONFIG_NET_TCP_CONNS=8 CONFIG_NET_MAX_LISTENPORTS=20 CONFIG_NET_TCP_READAHEAD=y CONFIG_NET_TCP_WRITE_BUFFERS=y CONFIG_NET_TCP_NWRBCHAINS=8 CONFIG_NET_TCP_RECVDELAY=0 # CONFIG_NET_TCPBACKLOG is not set # CONFIG_NET_SENDFILE is not set # # UDP Networking # # CONFIG_NET_UDP is not set # # ICMP Networking Support # # CONFIG_NET_ICMP is not set # # IGMPv2 Client Support # # CONFIG_NET_IGMP is not set # # ARP Configuration # CONFIG_NET_ARP=y CONFIG_NET_ARPTAB_SIZE=16 CONFIG_NET_ARP_MAXAGE=120 # CONFIG_NET_ARP_IPIN is not set # CONFIG_NET_ARP_SEND is not set # # Network I/O Buffer Support # CONFIG_NET_IOB=y CONFIG_IOB_NBUFFERS=36 CONFIG_IOB_BUFSIZE=196 CONFIG_IOB_NCHAINS=8 CONFIG_IOB_THROTTLE=8 # CONFIG_NET_ARCH_INCR32 is not set # CONFIG_NET_ARCH_CHKSUM is not set # CONFIG_NET_STATISTICS is not set # # Routing Table Configuration # # CONFIG_NET_ROUTE is not set CONFIG_NET_HOSTNAME="" # # Crypto API # # CONFIG_CRYPTO is not set # # File Systems # # # File system configuration # # CONFIG_DISABLE_MOUNTPOINT is not set # CONFIG_FS_AUTOMOUNTER is not set # CONFIG_DISABLE_PSEUDOFS_OPERATIONS is not set CONFIG_FS_READABLE=y CONFIG_FS_WRITABLE=y # CONFIG_FS_NAMED_SEMAPHORES is not set CONFIG_FS_MQUEUE_MPATH="/var/mqueue" # CONFIG_FS_RAMMAP is not set CONFIG_FS_FAT=y CONFIG_FAT_LCNAMES=y CONFIG_FAT_LFN=y CONFIG_FAT_MAXFNAME=32 # CONFIG_FS_FATTIME is not set # CONFIG_FAT_FORCE_INDIRECT is not set # CONFIG_FAT_DMAMEMORY is not set # CONFIG_FAT_DIRECT_RETRY is not set # CONFIG_FS_NXFFS is not set # CONFIG_FS_ROMFS is not set # CONFIG_FS_TMPFS is not set # CONFIG_FS_SMARTFS is not set # CONFIG_FS_BINFS is not set CONFIG_FS_PROCFS=y # CONFIG_FS_PROCFS_REGISTER is not set # # Exclude individual procfs entries # # CONFIG_FS_PROCFS_EXCLUDE_PROCESS is not set # CONFIG_FS_PROCFS_EXCLUDE_UPTIME is not set # CONFIG_FS_PROCFS_EXCLUDE_MOUNTS is not set # CONFIG_FS_PROCFS_EXCLUDE_NET is not set # CONFIG_FS_UNIONFS is not set # # Graphics Support # # CONFIG_NX is not set # # Memory Management # # CONFIG_MM_SMALL is not set CONFIG_MM_REGIONS=2 # CONFIG_ARCH_HAVE_HEAP2 is not set # CONFIG_GRAN is not set # # Audio Support # # CONFIG_AUDIO is not set # # Wireless Support # # # Binary Loader # # CONFIG_BINFMT_DISABLE is not set # CONFIG_BINFMT_EXEPATH is not set # CONFIG_NXFLAT is not set # CONFIG_ELF is not set CONFIG_BUILTIN=y # CONFIG_PIC is not set # CONFIG_SYMTAB_ORDEREDBYNAME is not set # # Library Routines # # # Standard C Library Options # CONFIG_STDIO_BUFFER_SIZE=64 CONFIG_STDIO_LINEBUFFER=y CONFIG_NUNGET_CHARS=2 CONFIG_LIB_HOMEDIR="/" CONFIG_LIBM=y # CONFIG_NOPRINTF_FIELDWIDTH is not set # CONFIG_LIBC_FLOATINGPOINT is not set CONFIG_LIBC_LONG_LONG=y # CONFIG_LIBC_IOCTL_VARIADIC is not set CONFIG_LIB_RAND_ORDER=1 # CONFIG_EOL_IS_CR is not set # CONFIG_EOL_IS_LF is not set # CONFIG_EOL_IS_BOTH_CRLF is not set CONFIG_EOL_IS_EITHER_CRLF=y # CONFIG_LIBC_EXECFUNCS is not set CONFIG_POSIX_SPAWN_PROXY_STACKSIZE=1024 CONFIG_TASK_SPAWN_DEFAULT_STACKSIZE=2048 # CONFIG_LIBC_STRERROR is not set # CONFIG_LIBC_PERROR_STDOUT is not set CONFIG_LIBC_TMPDIR="/tmp" CONFIG_LIBC_MAX_TMPFILE=32 CONFIG_ARCH_LOWPUTC=y # CONFIG_LIBC_LOCALTIME is not set # CONFIG_TIME_EXTENDED is not set CONFIG_LIB_SENDFILE_BUFSIZE=512 # CONFIG_ARCH_ROMGETC is not set # CONFIG_ARCH_OPTIMIZED_FUNCTIONS is not set CONFIG_ARCH_HAVE_TLS=y # CONFIG_TLS is not set CONFIG_LIBC_NETDB=y # CONFIG_NETDB_HOSTFILE is not set # # Non-standard Library Support # # CONFIG_LIB_CRC64_FAST is not set # CONFIG_LIB_KBDCODEC is not set # CONFIG_LIB_SLCDCODEC is not set # CONFIG_LIB_HEX2BIN is not set # # Basic CXX Support # # CONFIG_C99_BOOL8 is not set CONFIG_HAVE_CXX=y CONFIG_HAVE_CXXINITIALIZE=y # CONFIG_CXX_NEWLONG is not set # # uClibc++ Standard C++ Library # # CONFIG_UCLIBCXX is not set # # Application Configuration # # # Built-In Applications # CONFIG_BUILTIN_PROXY_STACKSIZE=1024 # # CAN Utilities # # # Examples # # CONFIG_EXAMPLES_BUTTONS is not set # CONFIG_EXAMPLES_CHAT is not set # CONFIG_EXAMPLES_CONFIGDATA is not set # CONFIG_EXAMPLES_CPUHOG is not set # CONFIG_EXAMPLES_CXXTEST is not set # CONFIG_EXAMPLES_DHCPD is not set # CONFIG_EXAMPLES_ELF is not set # CONFIG_EXAMPLES_FSTEST is not set # CONFIG_EXAMPLES_FTPC is not set # CONFIG_EXAMPLES_FTPD is not set # CONFIG_EXAMPLES_HELLO is not set # CONFIG_EXAMPLES_HELLOXX is not set # CONFIG_EXAMPLES_HIDKBD is not set # CONFIG_EXAMPLES_IGMP is not set # CONFIG_EXAMPLES_JSON is not set # CONFIG_EXAMPLES_KEYPADTEST is not set # CONFIG_EXAMPLES_MEDIA is not set # CONFIG_EXAMPLES_MM is not set # CONFIG_EXAMPLES_MODBUS is not set # CONFIG_EXAMPLES_MOUNT is not set # CONFIG_EXAMPLES_NETTEST is not set # CONFIG_EXAMPLES_NRF24L01TERM is not set CONFIG_EXAMPLES_NSH=y CONFIG_EXAMPLES_NSH_CXXINITIALIZE=y # CONFIG_EXAMPLES_NULL is not set # CONFIG_EXAMPLES_NXFFS is not set # CONFIG_EXAMPLES_NXHELLO is not set # CONFIG_EXAMPLES_NXIMAGE is not set # CONFIG_EXAMPLES_NX is not set # CONFIG_EXAMPLES_NXLINES is not set # CONFIG_EXAMPLES_NXTERM is not set # CONFIG_EXAMPLES_NXTEXT is not set # CONFIG_EXAMPLES_OSTEST is not set # CONFIG_EXAMPLES_PCA9635 is not set # CONFIG_EXAMPLES_PIPE is not set # CONFIG_EXAMPLES_POSIXSPAWN is not set # CONFIG_EXAMPLES_PPPD is not set # CONFIG_EXAMPLES_RFID_READUID is not set # CONFIG_EXAMPLES_RGBLED is not set # CONFIG_EXAMPLES_RGMP is not set # CONFIG_EXAMPLES_SENDMAIL is not set # CONFIG_EXAMPLES_SERIALBLASTER is not set # CONFIG_EXAMPLES_SERIALRX is not set # CONFIG_EXAMPLES_SERLOOP is not set # CONFIG_EXAMPLES_SLCD is not set # CONFIG_EXAMPLES_SMART is not set # CONFIG_EXAMPLES_SMART_TEST is not set # CONFIG_EXAMPLES_SMP is not set # CONFIG_EXAMPLES_TCPECHO is not set # CONFIG_EXAMPLES_TELNETD is not set # CONFIG_EXAMPLES_TIFF is not set # CONFIG_EXAMPLES_TOUCHSCREEN is not set # CONFIG_EXAMPLES_UDGRAM is not set # CONFIG_EXAMPLES_USBSERIAL is not set # CONFIG_EXAMPLES_USBTERM is not set # CONFIG_EXAMPLES_USTREAM is not set # CONFIG_EXAMPLES_WATCHDOG is not set # CONFIG_EXAMPLES_WEBSERVER is not set # CONFIG_EXAMPLES_XMLRPC is not set # # File System Utilities # # CONFIG_FSUTILS_INIFILE is not set # CONFIG_FSUTILS_PASSWD is not set # # GPS Utilities # # CONFIG_GPSUTILS_MINMEA_LIB is not set # # Graphics Support # # CONFIG_TIFF is not set # CONFIG_GRAPHICS_TRAVELER is not set # # Interpreters # # CONFIG_INTERPRETERS_BAS is not set # CONFIG_INTERPRETERS_FICL is not set # CONFIG_INTERPRETERS_MICROPYTHON is not set # CONFIG_INTERPRETERS_MINIBASIC is not set # CONFIG_INTERPRETERS_PCODE is not set # # FreeModBus # # CONFIG_MODBUS is not set # # Network Utilities # # CONFIG_NETUTILS_CHAT is not set # CONFIG_NETUTILS_CODECS is not set # CONFIG_NETUTILS_ESP8266 is not set # CONFIG_NETUTILS_FTPC is not set # CONFIG_NETUTILS_FTPD is not set # CONFIG_NETUTILS_JSON is not set CONFIG_NETUTILS_NETLIB=y # CONFIG_NETUTILS_SMTP is not set # CONFIG_NETUTILS_TELNETD is not set # CONFIG_NETUTILS_WEBCLIENT is not set # CONFIG_NETUTILS_WEBSERVER is not set # CONFIG_NETUTILS_XMLRPC is not set # # NSH Library # CONFIG_NSH_LIBRARY=y # CONFIG_NSH_MOTD is not set # # Command Line Configuration # CONFIG_NSH_READLINE=y # CONFIG_NSH_CLE is not set CONFIG_NSH_LINELEN=64 # CONFIG_NSH_DISABLE_SEMICOLON is not set CONFIG_NSH_CMDPARMS=y CONFIG_NSH_MAXARGUMENTS=6 CONFIG_NSH_ARGCAT=y CONFIG_NSH_NESTDEPTH=3 # CONFIG_NSH_DISABLEBG is not set CONFIG_NSH_BUILTIN_APPS=y # # Disable Individual commands # # CONFIG_NSH_DISABLE_ADDROUTE is not set # CONFIG_NSH_DISABLE_ARP is not set # CONFIG_NSH_DISABLE_BASENAME is not set # CONFIG_NSH_DISABLE_CAT is not set # CONFIG_NSH_DISABLE_CD is not set # CONFIG_NSH_DISABLE_CP is not set # CONFIG_NSH_DISABLE_CMP is not set CONFIG_NSH_DISABLE_DATE=y # CONFIG_NSH_DISABLE_DD is not set # CONFIG_NSH_DISABLE_DF is not set # CONFIG_NSH_DISABLE_DELROUTE is not set # CONFIG_NSH_DISABLE_DIRNAME is not set # CONFIG_NSH_DISABLE_ECHO is not set # CONFIG_NSH_DISABLE_EXEC is not set # CONFIG_NSH_DISABLE_EXIT is not set # CONFIG_NSH_DISABLE_FREE is not set # CONFIG_NSH_DISABLE_GET is not set # CONFIG_NSH_DISABLE_HELP is not set # CONFIG_NSH_DISABLE_HEXDUMP is not set # CONFIG_NSH_DISABLE_IFCONFIG is not set # CONFIG_NSH_DISABLE_IFUPDOWN is not set # CONFIG_NSH_DISABLE_KILL is not set # CONFIG_NSH_DISABLE_LOSETUP is not set CONFIG_NSH_DISABLE_LOSMART=y # CONFIG_NSH_DISABLE_LS is not set # CONFIG_NSH_DISABLE_MB is not set # CONFIG_NSH_DISABLE_MKDIR is not set # CONFIG_NSH_DISABLE_MKFATFS is not set # CONFIG_NSH_DISABLE_MKFIFO is not set # CONFIG_NSH_DISABLE_MKRD is not set # CONFIG_NSH_DISABLE_MH is not set # CONFIG_NSH_DISABLE_MOUNT is not set # CONFIG_NSH_DISABLE_MV is not set # CONFIG_NSH_DISABLE_MW is not set CONFIG_NSH_DISABLE_PRINTF=y # CONFIG_NSH_DISABLE_PS is not set # CONFIG_NSH_DISABLE_PUT is not set # CONFIG_NSH_DISABLE_PWD is not set # CONFIG_NSH_DISABLE_RM is not set # CONFIG_NSH_DISABLE_RMDIR is not set # CONFIG_NSH_DISABLE_SET is not set # CONFIG_NSH_DISABLE_SH is not set # CONFIG_NSH_DISABLE_SLEEP is not set # CONFIG_NSH_DISABLE_TIME is not set # CONFIG_NSH_DISABLE_TEST is not set # CONFIG_NSH_DISABLE_UMOUNT is not set # CONFIG_NSH_DISABLE_UNAME is not set # CONFIG_NSH_DISABLE_UNSET is not set # CONFIG_NSH_DISABLE_USLEEP is not set # CONFIG_NSH_DISABLE_WGET is not set # CONFIG_NSH_DISABLE_XD is not set CONFIG_NSH_MMCSDMINOR=0 CONFIG_NSH_MMCSDSLOTNO=0 CONFIG_NSH_MMCSDSPIPORTNO=0 # # Configure Command Options # CONFIG_NSH_CMDOPT_DF_H=y CONFIG_NSH_CODECS_BUFSIZE=128 CONFIG_NSH_CMDOPT_HEXDUMP=y CONFIG_NSH_PROC_MOUNTPOINT="/proc" CONFIG_NSH_FILEIOSIZE=512 # # Scripting Support # # CONFIG_NSH_DISABLESCRIPT is not set # CONFIG_NSH_DISABLE_ITEF is not set # CONFIG_NSH_DISABLE_LOOPS is not set # # Console Configuration # CONFIG_NSH_CONSOLE=y # CONFIG_NSH_USBCONSOLE is not set # CONFIG_NSH_ALTCONDEV is not set CONFIG_NSH_ARCHINIT=y # # Networking Configuration # CONFIG_NSH_NETINIT=y # CONFIG_NSH_NETINIT_THREAD is not set # # IP Address Configuration # # # IPv4 Addresses # CONFIG_NSH_IPADDR=0x0a000002 CONFIG_NSH_DRIPADDR=0x0a000001 CONFIG_NSH_NETMASK=0xffffff00 # CONFIG_NSH_NOMAC is not set CONFIG_NSH_MAX_ROUNDTRIP=20 # CONFIG_NSH_LOGIN is not set # CONFIG_NSH_CONSOLE_LOGIN is not set # # NxWidgets/NxWM # # # Platform-specific Support # # CONFIG_PLATFORM_CONFIGDATA is not set # # System Libraries and NSH Add-Ons # # CONFIG_SYSTEM_CDCACM is not set # CONFIG_SYSTEM_CLE is not set # CONFIG_SYSTEM_CUTERM is not set # CONFIG_SYSTEM_FREE is not set # CONFIG_SYSTEM_HEX2BIN is not set # CONFIG_SYSTEM_HEXED is not set # CONFIG_SYSTEM_INSTALL is not set CONFIG_IOTJS=y CONFIG_IOTJS_PRIORITY=100 CONFIG_IOTJS_STACKSIZE=16384 CONFIG_IOTJS_HEAPSIZE=107520 # CONFIG_SYSTEM_NETDB is not set # CONFIG_SYSTEM_RAMTEST is not set CONFIG_READLINE_HAVE_EXTMATCH=y CONFIG_SYSTEM_READLINE=y CONFIG_READLINE_ECHO=y CONFIG_READLINE_TABCOMPLETION=y CONFIG_READLINE_MAX_BUILTINS=64 CONFIG_READLINE_MAX_EXTCMDS=64 CONFIG_READLINE_CMD_HISTORY=y CONFIG_READLINE_CMD_HISTORY_LINELEN=80 CONFIG_READLINE_CMD_HISTORY_LEN=16 # CONFIG_SYSTEM_SUDOKU is not set # CONFIG_SYSTEM_SYSTEM is not set # CONFIG_SYSTEM_TEE is not set # CONFIG_SYSTEM_UBLOXMODEM is not set # CONFIG_SYSTEM_VI is not set # CONFIG_SYSTEM_ZMODEM is not set iotjs-1.0/config/nuttx/stm32f4dis/.config.travis000066400000000000000000001150171312466455500216300ustar00rootroot00000000000000# # Automatically generated file; DO NOT EDIT. # Nuttx/ Configuration # # # Build Setup # # CONFIG_EXPERIMENTAL is not set # CONFIG_DEFAULT_SMALL is not set CONFIG_HOST_LINUX=y # CONFIG_HOST_OSX is not set # CONFIG_HOST_WINDOWS is not set # CONFIG_HOST_OTHER is not set # # Build Configuration # CONFIG_APPS_DIR="../apps" CONFIG_BUILD_FLAT=y # CONFIG_BUILD_2PASS is not set # # Binary Output Formats # # CONFIG_RRLOAD_BINARY is not set CONFIG_INTELHEX_BINARY=y # CONFIG_MOTOROLA_SREC is not set CONFIG_RAW_BINARY=y # CONFIG_UBOOT_UIMAGE is not set # # Customize Header Files # # CONFIG_ARCH_STDINT_H is not set # CONFIG_ARCH_STDBOOL_H is not set # CONFIG_ARCH_MATH_H is not set # CONFIG_ARCH_FLOAT_H is not set # CONFIG_ARCH_STDARG_H is not set # CONFIG_ARCH_DEBUG_H is not set # # Debug Options # CONFIG_DEBUG_ALERT=y # CONFIG_DEBUG_FEATURES is not set CONFIG_ARCH_HAVE_STACKCHECK=y # CONFIG_STACK_COLORATION is not set CONFIG_ARCH_HAVE_HEAPCHECK=y # CONFIG_HEAP_COLORATION is not set # CONFIG_DEBUG_SYMBOLS is not set CONFIG_ARCH_HAVE_CUSTOMOPT=y # CONFIG_DEBUG_NOOPT is not set # CONFIG_DEBUG_CUSTOMOPT is not set CONFIG_DEBUG_FULLOPT=y # # System Type # CONFIG_ARCH_ARM=y # CONFIG_ARCH_AVR is not set # CONFIG_ARCH_HC is not set # CONFIG_ARCH_MIPS is not set # CONFIG_ARCH_MISOC is not set # CONFIG_ARCH_RENESAS is not set # CONFIG_ARCH_RISCV is not set # CONFIG_ARCH_SIM is not set # CONFIG_ARCH_X86 is not set # CONFIG_ARCH_XTENSA is not set # CONFIG_ARCH_Z16 is not set # CONFIG_ARCH_Z80 is not set CONFIG_ARCH="arm" # # ARM Options # # CONFIG_ARCH_CHIP_A1X is not set # CONFIG_ARCH_CHIP_C5471 is not set # CONFIG_ARCH_CHIP_DM320 is not set # CONFIG_ARCH_CHIP_EFM32 is not set # CONFIG_ARCH_CHIP_IMX1 is not set # CONFIG_ARCH_CHIP_IMX6 is not set # CONFIG_ARCH_CHIP_KINETIS is not set # CONFIG_ARCH_CHIP_KL is not set # CONFIG_ARCH_CHIP_LM is not set # CONFIG_ARCH_CHIP_TIVA is not set # CONFIG_ARCH_CHIP_LPC11XX is not set # CONFIG_ARCH_CHIP_LPC17XX is not set # CONFIG_ARCH_CHIP_LPC214X is not set # CONFIG_ARCH_CHIP_LPC2378 is not set # CONFIG_ARCH_CHIP_LPC31XX is not set # CONFIG_ARCH_CHIP_LPC43XX is not set # CONFIG_ARCH_CHIP_NUC1XX is not set # CONFIG_ARCH_CHIP_SAMA5 is not set # CONFIG_ARCH_CHIP_SAMD is not set # CONFIG_ARCH_CHIP_SAML is not set # CONFIG_ARCH_CHIP_SAM34 is not set # CONFIG_ARCH_CHIP_SAMV7 is not set CONFIG_ARCH_CHIP_STM32=y # CONFIG_ARCH_CHIP_STM32F7 is not set # CONFIG_ARCH_CHIP_STM32L4 is not set # CONFIG_ARCH_CHIP_STR71X is not set # CONFIG_ARCH_CHIP_TMS570 is not set # CONFIG_ARCH_CHIP_MOXART is not set # CONFIG_ARCH_ARM7TDMI is not set # CONFIG_ARCH_ARM926EJS is not set # CONFIG_ARCH_ARM920T is not set # CONFIG_ARCH_CORTEXM0 is not set # CONFIG_ARCH_CORTEXM3 is not set CONFIG_ARCH_CORTEXM4=y # CONFIG_ARCH_CORTEXM7 is not set # CONFIG_ARCH_CORTEXA5 is not set # CONFIG_ARCH_CORTEXA8 is not set # CONFIG_ARCH_CORTEXA9 is not set # CONFIG_ARCH_CORTEXR4 is not set # CONFIG_ARCH_CORTEXR4F is not set # CONFIG_ARCH_CORTEXR5 is not set # CONFIG_ARCH_CORTEX5F is not set # CONFIG_ARCH_CORTEXR7 is not set # CONFIG_ARCH_CORTEXR7F is not set CONFIG_ARCH_FAMILY="armv7-m" CONFIG_ARCH_CHIP="stm32" # CONFIG_ARM_TOOLCHAIN_IAR is not set CONFIG_ARM_TOOLCHAIN_GNU=y # CONFIG_ARMV7M_USEBASEPRI is not set CONFIG_ARCH_HAVE_CMNVECTOR=y # CONFIG_ARMV7M_CMNVECTOR is not set # CONFIG_ARMV7M_LAZYFPU is not set CONFIG_ARCH_HAVE_FPU=y # CONFIG_ARCH_HAVE_DPFPU is not set CONFIG_ARCH_FPU=y # CONFIG_ARCH_HAVE_TRUSTZONE is not set CONFIG_ARM_HAVE_MPU_UNIFIED=y # CONFIG_ARM_MPU is not set # # ARMV7M Configuration Options # # CONFIG_ARMV7M_HAVE_ICACHE is not set # CONFIG_ARMV7M_HAVE_DCACHE is not set # CONFIG_ARMV7M_HAVE_ITCM is not set # CONFIG_ARMV7M_HAVE_DTCM is not set # CONFIG_ARMV7M_TOOLCHAIN_IARL is not set # CONFIG_ARMV7M_TOOLCHAIN_BUILDROOT is not set # CONFIG_ARMV7M_TOOLCHAIN_CODEREDL is not set # CONFIG_ARMV7M_TOOLCHAIN_CODESOURCERYL is not set CONFIG_ARMV7M_TOOLCHAIN_GNU_EABIL=y CONFIG_ARMV7M_HAVE_STACKCHECK=y # CONFIG_ARMV7M_STACKCHECK is not set # CONFIG_ARMV7M_ITMSYSLOG is not set # CONFIG_SERIAL_TERMIOS is not set # CONFIG_SDIO_DMA is not set # CONFIG_SDIO_WIDTH_D1_ONLY is not set # # STM32 Configuration Options # # CONFIG_ARCH_CHIP_STM32L151C6 is not set # CONFIG_ARCH_CHIP_STM32L151C8 is not set # CONFIG_ARCH_CHIP_STM32L151CB is not set # CONFIG_ARCH_CHIP_STM32L151R6 is not set # CONFIG_ARCH_CHIP_STM32L151R8 is not set # CONFIG_ARCH_CHIP_STM32L151RB is not set # CONFIG_ARCH_CHIP_STM32L151V6 is not set # CONFIG_ARCH_CHIP_STM32L151V8 is not set # CONFIG_ARCH_CHIP_STM32L151VB is not set # CONFIG_ARCH_CHIP_STM32L152C6 is not set # CONFIG_ARCH_CHIP_STM32L152C8 is not set # CONFIG_ARCH_CHIP_STM32L152CB is not set # CONFIG_ARCH_CHIP_STM32L152R6 is not set # CONFIG_ARCH_CHIP_STM32L152R8 is not set # CONFIG_ARCH_CHIP_STM32L152RB is not set # CONFIG_ARCH_CHIP_STM32L152V6 is not set # CONFIG_ARCH_CHIP_STM32L152V8 is not set # CONFIG_ARCH_CHIP_STM32L152VB is not set # CONFIG_ARCH_CHIP_STM32L162ZD is not set # CONFIG_ARCH_CHIP_STM32L162VE is not set # CONFIG_ARCH_CHIP_STM32F100C8 is not set # CONFIG_ARCH_CHIP_STM32F100CB is not set # CONFIG_ARCH_CHIP_STM32F100R8 is not set # CONFIG_ARCH_CHIP_STM32F100RB is not set # CONFIG_ARCH_CHIP_STM32F100RC is not set # CONFIG_ARCH_CHIP_STM32F100RD is not set # CONFIG_ARCH_CHIP_STM32F100RE is not set # CONFIG_ARCH_CHIP_STM32F100V8 is not set # CONFIG_ARCH_CHIP_STM32F100VB is not set # CONFIG_ARCH_CHIP_STM32F100VC is not set # CONFIG_ARCH_CHIP_STM32F100VD is not set # CONFIG_ARCH_CHIP_STM32F100VE is not set # CONFIG_ARCH_CHIP_STM32F102CB is not set # CONFIG_ARCH_CHIP_STM32F103T8 is not set # CONFIG_ARCH_CHIP_STM32F103TB is not set # CONFIG_ARCH_CHIP_STM32F103C4 is not set # CONFIG_ARCH_CHIP_STM32F103C8 is not set # CONFIG_ARCH_CHIP_STM32F103CB is not set # CONFIG_ARCH_CHIP_STM32F103R8 is not set # CONFIG_ARCH_CHIP_STM32F103RB is not set # CONFIG_ARCH_CHIP_STM32F103RC is not set # CONFIG_ARCH_CHIP_STM32F103RD is not set # CONFIG_ARCH_CHIP_STM32F103RE is not set # CONFIG_ARCH_CHIP_STM32F103RG is not set # CONFIG_ARCH_CHIP_STM32F103V8 is not set # CONFIG_ARCH_CHIP_STM32F103VB is not set # CONFIG_ARCH_CHIP_STM32F103VC is not set # CONFIG_ARCH_CHIP_STM32F103VE is not set # CONFIG_ARCH_CHIP_STM32F103ZE is not set # CONFIG_ARCH_CHIP_STM32F105VB is not set # CONFIG_ARCH_CHIP_STM32F105RB is not set # CONFIG_ARCH_CHIP_STM32F107VC is not set # CONFIG_ARCH_CHIP_STM32F205RG is not set # CONFIG_ARCH_CHIP_STM32F207IG is not set # CONFIG_ARCH_CHIP_STM32F207ZE is not set # CONFIG_ARCH_CHIP_STM32F302K6 is not set # CONFIG_ARCH_CHIP_STM32F302K8 is not set # CONFIG_ARCH_CHIP_STM32F302CB is not set # CONFIG_ARCH_CHIP_STM32F302CC is not set # CONFIG_ARCH_CHIP_STM32F302RB is not set # CONFIG_ARCH_CHIP_STM32F302RC is not set # CONFIG_ARCH_CHIP_STM32F302VB is not set # CONFIG_ARCH_CHIP_STM32F302VC is not set # CONFIG_ARCH_CHIP_STM32F303K6 is not set # CONFIG_ARCH_CHIP_STM32F303K8 is not set # CONFIG_ARCH_CHIP_STM32F303C6 is not set # CONFIG_ARCH_CHIP_STM32F303C8 is not set # CONFIG_ARCH_CHIP_STM32F303CB is not set # CONFIG_ARCH_CHIP_STM32F303CC is not set # CONFIG_ARCH_CHIP_STM32F303RB is not set # CONFIG_ARCH_CHIP_STM32F303RC is not set # CONFIG_ARCH_CHIP_STM32F303RD is not set # CONFIG_ARCH_CHIP_STM32F303RE is not set # CONFIG_ARCH_CHIP_STM32F303VB is not set # CONFIG_ARCH_CHIP_STM32F303VC is not set # CONFIG_ARCH_CHIP_STM32F372C8 is not set # CONFIG_ARCH_CHIP_STM32F372R8 is not set # CONFIG_ARCH_CHIP_STM32F372V8 is not set # CONFIG_ARCH_CHIP_STM32F372CB is not set # CONFIG_ARCH_CHIP_STM32F372RB is not set # CONFIG_ARCH_CHIP_STM32F372VB is not set # CONFIG_ARCH_CHIP_STM32F372CC is not set # CONFIG_ARCH_CHIP_STM32F372RC is not set # CONFIG_ARCH_CHIP_STM32F372VC is not set # CONFIG_ARCH_CHIP_STM32F373C8 is not set # CONFIG_ARCH_CHIP_STM32F373R8 is not set # CONFIG_ARCH_CHIP_STM32F373V8 is not set # CONFIG_ARCH_CHIP_STM32F373CB is not set # CONFIG_ARCH_CHIP_STM32F373RB is not set # CONFIG_ARCH_CHIP_STM32F373VB is not set # CONFIG_ARCH_CHIP_STM32F373CC is not set # CONFIG_ARCH_CHIP_STM32F373RC is not set # CONFIG_ARCH_CHIP_STM32F373VC is not set # CONFIG_ARCH_CHIP_STM32F401RE is not set # CONFIG_ARCH_CHIP_STM32F411RE is not set # CONFIG_ARCH_CHIP_STM32F411VE is not set # CONFIG_ARCH_CHIP_STM32F405RG is not set # CONFIG_ARCH_CHIP_STM32F405VG is not set # CONFIG_ARCH_CHIP_STM32F405ZG is not set # CONFIG_ARCH_CHIP_STM32F407VE is not set CONFIG_ARCH_CHIP_STM32F407VG=y # CONFIG_ARCH_CHIP_STM32F407ZE is not set # CONFIG_ARCH_CHIP_STM32F407ZG is not set # CONFIG_ARCH_CHIP_STM32F407IE is not set # CONFIG_ARCH_CHIP_STM32F407IG is not set # CONFIG_ARCH_CHIP_STM32F427V is not set # CONFIG_ARCH_CHIP_STM32F427Z is not set # CONFIG_ARCH_CHIP_STM32F427I is not set # CONFIG_ARCH_CHIP_STM32F429V is not set # CONFIG_ARCH_CHIP_STM32F429Z is not set # CONFIG_ARCH_CHIP_STM32F429I is not set # CONFIG_ARCH_CHIP_STM32F429B is not set # CONFIG_ARCH_CHIP_STM32F429N is not set # CONFIG_ARCH_CHIP_STM32F446M is not set # CONFIG_ARCH_CHIP_STM32F446R is not set # CONFIG_ARCH_CHIP_STM32F446V is not set # CONFIG_ARCH_CHIP_STM32F446Z is not set # CONFIG_ARCH_CHIP_STM32F469A is not set # CONFIG_ARCH_CHIP_STM32F469I is not set # CONFIG_ARCH_CHIP_STM32F469B is not set # CONFIG_ARCH_CHIP_STM32F469N is not set CONFIG_STM32_FLASH_CONFIG_DEFAULT=y # CONFIG_STM32_FLASH_CONFIG_4 is not set # CONFIG_STM32_FLASH_CONFIG_6 is not set # CONFIG_STM32_FLASH_CONFIG_8 is not set # CONFIG_STM32_FLASH_CONFIG_B is not set # CONFIG_STM32_FLASH_CONFIG_C is not set # CONFIG_STM32_FLASH_CONFIG_D is not set # CONFIG_STM32_FLASH_CONFIG_E is not set # CONFIG_STM32_FLASH_CONFIG_F is not set # CONFIG_STM32_FLASH_CONFIG_G is not set # CONFIG_STM32_FLASH_CONFIG_I is not set # CONFIG_STM32_STM32L15XX is not set # CONFIG_STM32_ENERGYLITE is not set # CONFIG_STM32_STM32F10XX is not set # CONFIG_STM32_VALUELINE is not set # CONFIG_STM32_CONNECTIVITYLINE is not set # CONFIG_STM32_PERFORMANCELINE is not set # CONFIG_STM32_USBACCESSLINE is not set # CONFIG_STM32_HIGHDENSITY is not set # CONFIG_STM32_MEDIUMDENSITY is not set # CONFIG_STM32_LOWDENSITY is not set # CONFIG_STM32_STM32F20XX is not set # CONFIG_STM32_STM32F205 is not set # CONFIG_STM32_STM32F207 is not set # CONFIG_STM32_STM32F30XX is not set # CONFIG_STM32_STM32F302 is not set # CONFIG_STM32_STM32F303 is not set # CONFIG_STM32_STM32F37XX is not set CONFIG_STM32_STM32F40XX=y # CONFIG_STM32_STM32F401 is not set # CONFIG_STM32_STM32F411 is not set # CONFIG_STM32_STM32F405 is not set CONFIG_STM32_STM32F407=y # CONFIG_STM32_STM32F427 is not set # CONFIG_STM32_STM32F429 is not set # CONFIG_STM32_STM32F446 is not set # CONFIG_STM32_STM32F469 is not set # CONFIG_STM32_DFU is not set # # STM32 Peripheral Support # CONFIG_STM32_HAVE_CCM=y # CONFIG_STM32_HAVE_USBDEV is not set CONFIG_STM32_HAVE_OTGFS=y CONFIG_STM32_HAVE_FSMC=y # CONFIG_STM32_HAVE_LTDC is not set CONFIG_STM32_HAVE_USART3=y CONFIG_STM32_HAVE_UART4=y CONFIG_STM32_HAVE_UART5=y CONFIG_STM32_HAVE_USART6=y # CONFIG_STM32_HAVE_UART7 is not set # CONFIG_STM32_HAVE_UART8 is not set CONFIG_STM32_HAVE_TIM1=y CONFIG_STM32_HAVE_TIM2=y CONFIG_STM32_HAVE_TIM3=y CONFIG_STM32_HAVE_TIM4=y CONFIG_STM32_HAVE_TIM5=y CONFIG_STM32_HAVE_TIM6=y CONFIG_STM32_HAVE_TIM7=y CONFIG_STM32_HAVE_TIM8=y CONFIG_STM32_HAVE_TIM9=y CONFIG_STM32_HAVE_TIM10=y CONFIG_STM32_HAVE_TIM11=y CONFIG_STM32_HAVE_TIM12=y CONFIG_STM32_HAVE_TIM13=y CONFIG_STM32_HAVE_TIM14=y # CONFIG_STM32_HAVE_TIM15 is not set # CONFIG_STM32_HAVE_TIM16 is not set # CONFIG_STM32_HAVE_TIM17 is not set CONFIG_STM32_HAVE_ADC2=y CONFIG_STM32_HAVE_ADC3=y # CONFIG_STM32_HAVE_ADC4 is not set # CONFIG_STM32_HAVE_ADC1_DMA is not set # CONFIG_STM32_HAVE_ADC2_DMA is not set # CONFIG_STM32_HAVE_ADC3_DMA is not set # CONFIG_STM32_HAVE_ADC4_DMA is not set # CONFIG_STM32_HAVE_SDADC1 is not set # CONFIG_STM32_HAVE_SDADC2 is not set # CONFIG_STM32_HAVE_SDADC3 is not set # CONFIG_STM32_HAVE_SDADC1_DMA is not set # CONFIG_STM32_HAVE_SDADC2_DMA is not set # CONFIG_STM32_HAVE_SDADC3_DMA is not set CONFIG_STM32_HAVE_CAN1=y CONFIG_STM32_HAVE_CAN2=y CONFIG_STM32_HAVE_DAC1=y CONFIG_STM32_HAVE_DAC2=y CONFIG_STM32_HAVE_RNG=y CONFIG_STM32_HAVE_ETHMAC=y CONFIG_STM32_HAVE_I2C2=y CONFIG_STM32_HAVE_I2C3=y CONFIG_STM32_HAVE_SPI2=y CONFIG_STM32_HAVE_SPI3=y # CONFIG_STM32_HAVE_SPI4 is not set # CONFIG_STM32_HAVE_SPI5 is not set # CONFIG_STM32_HAVE_SPI6 is not set # CONFIG_STM32_HAVE_SAIPLL is not set # CONFIG_STM32_HAVE_I2SPLL is not set CONFIG_STM32_ADC1=y # CONFIG_STM32_ADC2 is not set # CONFIG_STM32_ADC3 is not set # CONFIG_STM32_BKPSRAM is not set # CONFIG_STM32_CAN1 is not set # CONFIG_STM32_CAN2 is not set # CONFIG_STM32_CCMDATARAM is not set # CONFIG_STM32_CRC is not set # CONFIG_STM32_CRYP is not set # CONFIG_STM32_DMA1 is not set # CONFIG_STM32_DMA2 is not set # CONFIG_STM32_DAC1 is not set # CONFIG_STM32_DAC2 is not set # CONFIG_STM32_DCMI is not set # CONFIG_STM32_ETHMAC is not set # CONFIG_STM32_FSMC is not set # CONFIG_STM32_HASH is not set CONFIG_STM32_I2C1=y # CONFIG_STM32_I2C2 is not set # CONFIG_STM32_I2C3 is not set CONFIG_STM32_OTGFS=y # CONFIG_STM32_OTGHS is not set CONFIG_STM32_PWR=y # CONFIG_STM32_RNG is not set CONFIG_STM32_SDIO=y CONFIG_STM32_SPI1=y # CONFIG_STM32_SPI2 is not set # CONFIG_STM32_SPI3 is not set CONFIG_STM32_SYSCFG=y CONFIG_STM32_TIM1=y # CONFIG_STM32_TIM2 is not set CONFIG_STM32_TIM3=y # CONFIG_STM32_TIM4 is not set # CONFIG_STM32_TIM5 is not set # CONFIG_STM32_TIM6 is not set # CONFIG_STM32_TIM7 is not set # CONFIG_STM32_TIM8 is not set # CONFIG_STM32_TIM9 is not set # CONFIG_STM32_TIM10 is not set # CONFIG_STM32_TIM11 is not set # CONFIG_STM32_TIM12 is not set # CONFIG_STM32_TIM13 is not set # CONFIG_STM32_TIM14 is not set # CONFIG_STM32_USART1 is not set CONFIG_STM32_USART2=y # CONFIG_STM32_USART3 is not set # CONFIG_STM32_UART4 is not set # CONFIG_STM32_UART5 is not set # CONFIG_STM32_USART6 is not set # CONFIG_STM32_IWDG is not set # CONFIG_STM32_WWDG is not set CONFIG_STM32_ADC=y CONFIG_STM32_SPI=y CONFIG_STM32_I2C=y # CONFIG_STM32_NOEXT_VECTORS is not set # # Alternate Pin Mapping # # CONFIG_STM32_FLASH_PREFETCH is not set # CONFIG_STM32_JTAG_DISABLE is not set # CONFIG_STM32_JTAG_FULL_ENABLE is not set # CONFIG_STM32_JTAG_NOJNTRST_ENABLE is not set CONFIG_STM32_JTAG_SW_ENABLE=y # CONFIG_STM32_DISABLE_IDLE_SLEEP_DURING_DEBUG is not set # CONFIG_STM32_FORCEPOWER is not set # CONFIG_ARCH_BOARD_STM32_CUSTOM_CLOCKCONFIG is not set # CONFIG_STM32_CCMEXCLUDE is not set # # Timer Configuration # # CONFIG_STM32_ONESHOT is not set # CONFIG_STM32_FREERUN is not set CONFIG_STM32_TIM1_PWM=y CONFIG_STM32_TIM1_MODE=0 CONFIG_STM32_TIM1_CHANNEL=1 CONFIG_STM32_TIM1_CHMODE=0 # CONFIG_STM32_TIM3_PWM is not set # CONFIG_STM32_PWM_MULTICHAN is not set # CONFIG_STM32_TIM1_ADC is not set CONFIG_STM32_TIM3_ADC=y CONFIG_STM32_TIM3_ADC1=y CONFIG_HAVE_ADC1_TIMER=y CONFIG_STM32_ADC1_SAMPLE_FREQUENCY=100 CONFIG_STM32_ADC1_TIMTRIG=0 # CONFIG_STM32_TIM1_CAP is not set # CONFIG_STM32_TIM2_CAP is not set # CONFIG_STM32_TIM3_CAP is not set # CONFIG_STM32_TIM4_CAP is not set # CONFIG_STM32_TIM5_CAP is not set # CONFIG_STM32_TIM8_CAP is not set # CONFIG_STM32_TIM9_CAP is not set # CONFIG_STM32_TIM10_CAP is not set # CONFIG_STM32_TIM11_CAP is not set # CONFIG_STM32_TIM12_CAP is not set # CONFIG_STM32_TIM13_CAP is not set # CONFIG_STM32_TIM14_CAP is not set # # ADC Configuration # CONFIG_STM32_USART=y CONFIG_STM32_SERIALDRIVER=y # # U[S]ART Configuration # # # U[S]ART Device Configuration # CONFIG_STM32_USART2_SERIALDRIVER=y # CONFIG_STM32_USART2_1WIREDRIVER is not set # CONFIG_USART2_RS485 is not set # # Serial Driver Configuration # # CONFIG_SERIAL_DISABLE_REORDERING is not set # CONFIG_STM32_FLOWCONTROL_BROKEN is not set # CONFIG_STM32_USART_BREAKS is not set # CONFIG_STM32_USART_SINGLEWIRE is not set # # SPI Configuration # # CONFIG_STM32_SPI_INTERRUPTS is not set # CONFIG_STM32_SPI_DMA is not set # # I2C Configuration # # CONFIG_STM32_I2C_ALT is not set # CONFIG_STM32_I2C_DYNTIMEO is not set CONFIG_STM32_I2CTIMEOSEC=0 CONFIG_STM32_I2CTIMEOMS=500 CONFIG_STM32_I2CTIMEOTICKS=500 # CONFIG_STM32_I2C_DUTY16_9 is not set # # SDIO Configuration # CONFIG_SDIO_DMAPRIO=0x00010000 # CONFIG_STM32_HAVE_RTC_COUNTER is not set # CONFIG_STM32_HAVE_RTC_SUBSECONDS is not set # # USB FS Host Configuration # # # USB HS Host Configuration # # # USB Host Debug Configuration # # # USB Device Configuration # # # Architecture Options # # CONFIG_ARCH_NOINTC is not set # CONFIG_ARCH_VECNOTIRQ is not set # CONFIG_ARCH_DMA is not set CONFIG_ARCH_HAVE_IRQPRIO=y # CONFIG_ARCH_L2CACHE is not set # CONFIG_ARCH_HAVE_COHERENT_DCACHE is not set # CONFIG_ARCH_HAVE_ADDRENV is not set # CONFIG_ARCH_NEED_ADDRENV_MAPPING is not set # CONFIG_ARCH_HAVE_MULTICPU is not set CONFIG_ARCH_HAVE_VFORK=y # CONFIG_ARCH_HAVE_MMU is not set CONFIG_ARCH_HAVE_MPU=y # CONFIG_ARCH_NAND_HWECC is not set # CONFIG_ARCH_HAVE_EXTCLK is not set # CONFIG_ARCH_HAVE_POWEROFF is not set CONFIG_ARCH_HAVE_RESET=y # CONFIG_ARCH_USE_MPU is not set # CONFIG_ARCH_IRQPRIO is not set CONFIG_ARCH_STACKDUMP=y # CONFIG_ENDIAN_BIG is not set # CONFIG_ARCH_IDLE_CUSTOM is not set # CONFIG_ARCH_HAVE_RAMFUNCS is not set CONFIG_ARCH_HAVE_RAMVECTORS=y # CONFIG_ARCH_RAMVECTORS is not set # # Board Settings # CONFIG_BOARD_LOOPSPERMSEC=16717 # CONFIG_ARCH_CALIBRATION is not set # # Interrupt options # CONFIG_ARCH_HAVE_INTERRUPTSTACK=y CONFIG_ARCH_INTERRUPTSTACK=0 CONFIG_ARCH_HAVE_HIPRI_INTERRUPT=y # CONFIG_ARCH_HIPRI_INTERRUPT is not set # # Boot options # # CONFIG_BOOT_RUNFROMEXTSRAM is not set CONFIG_BOOT_RUNFROMFLASH=y # CONFIG_BOOT_RUNFROMISRAM is not set # CONFIG_BOOT_RUNFROMSDRAM is not set # CONFIG_BOOT_COPYTORAM is not set # # Boot Memory Configuration # CONFIG_RAM_START=0x20000000 CONFIG_RAM_SIZE=114688 # CONFIG_ARCH_HAVE_SDRAM is not set # # Board Selection # CONFIG_ARCH_BOARD_STM32F4_DISCOVERY=y # CONFIG_ARCH_BOARD_MIKROE_STM32F4 is not set # CONFIG_ARCH_BOARD_CUSTOM is not set CONFIG_ARCH_BOARD="stm32f4discovery" # # Common Board Options # CONFIG_ARCH_HAVE_LEDS=y CONFIG_ARCH_LEDS=y CONFIG_ARCH_HAVE_BUTTONS=y CONFIG_ARCH_BUTTONS=y CONFIG_ARCH_HAVE_IRQBUTTONS=y # CONFIG_ARCH_IRQBUTTONS is not set # # Board-Specific Options # # CONFIG_STM32F4DISBB is not set # CONFIG_BOARD_CRASHDUMP is not set CONFIG_LIB_BOARDCTL=y # CONFIG_BOARDCTL_RESET is not set # CONFIG_BOARDCTL_UNIQUEID is not set CONFIG_BOARDCTL_USBDEVCTRL=y # CONFIG_BOARDCTL_TSCTEST is not set # CONFIG_BOARDCTL_GRAPHICS is not set # CONFIG_BOARDCTL_IOCTL is not set # # RTOS Features # CONFIG_DISABLE_OS_API=y # CONFIG_DISABLE_POSIX_TIMERS is not set # CONFIG_DISABLE_PTHREAD is not set # CONFIG_DISABLE_SIGNALS is not set # CONFIG_DISABLE_MQUEUE is not set # CONFIG_DISABLE_ENVIRON is not set # # Clocks and Timers # CONFIG_ARCH_HAVE_TICKLESS=y # CONFIG_SCHED_TICKLESS is not set CONFIG_USEC_PER_TICK=10000 # CONFIG_SYSTEM_TIME64 is not set CONFIG_CLOCK_MONOTONIC=y CONFIG_ARCH_HAVE_TIMEKEEPING=y # CONFIG_JULIAN_TIME is not set CONFIG_START_YEAR=2013 CONFIG_START_MONTH=1 CONFIG_START_DAY=27 CONFIG_MAX_WDOGPARMS=2 CONFIG_PREALLOC_WDOGS=8 CONFIG_WDOG_INTRESERVE=1 CONFIG_PREALLOC_TIMERS=4 # # Tasks and Scheduling # # CONFIG_SPINLOCK is not set # CONFIG_INIT_NONE is not set CONFIG_INIT_ENTRYPOINT=y # CONFIG_INIT_FILEPATH is not set CONFIG_USER_ENTRYPOINT="nsh_main" CONFIG_RR_INTERVAL=200 # CONFIG_SCHED_SPORADIC is not set CONFIG_TASK_NAME_SIZE=31 CONFIG_MAX_TASKS=16 # CONFIG_SCHED_HAVE_PARENT is not set CONFIG_SCHED_WAITPID=y # # Pthread Options # CONFIG_MUTEX_TYPES=y CONFIG_NPTHREAD_KEYS=4 # CONFIG_PTHREAD_CLEANUP is not set # CONFIG_CANCELLATION_POINTS is not set # # Performance Monitoring # # CONFIG_SCHED_CPULOAD is not set # CONFIG_SCHED_INSTRUMENTATION is not set # # Files and I/O # CONFIG_DEV_CONSOLE=y # CONFIG_FDCLONE_DISABLE is not set # CONFIG_FDCLONE_STDIO is not set CONFIG_SDCLONE_DISABLE=y CONFIG_NFILE_DESCRIPTORS=8 CONFIG_NFILE_STREAMS=8 CONFIG_NAME_MAX=32 # CONFIG_PRIORITY_INHERITANCE is not set # # RTOS hooks # # CONFIG_BOARD_INITIALIZE is not set # CONFIG_SCHED_STARTHOOK is not set # CONFIG_SCHED_ATEXIT is not set # CONFIG_SCHED_ONEXIT is not set # CONFIG_SIG_EVTHREAD is not set # # Signal Numbers # CONFIG_SIG_SIGUSR1=1 CONFIG_SIG_SIGUSR2=2 CONFIG_SIG_SIGALARM=3 CONFIG_SIG_SIGCONDTIMEDOUT=16 CONFIG_SIG_SIGWORK=17 # # POSIX Message Queue Options # CONFIG_PREALLOC_MQ_MSGS=4 CONFIG_MQ_MAXMSGSIZE=32 # CONFIG_MODULE is not set # # Work queue support # CONFIG_SCHED_WORKQUEUE=y CONFIG_SCHED_HPWORK=y CONFIG_SCHED_HPWORKPRIORITY=224 CONFIG_SCHED_HPWORKPERIOD=50000 CONFIG_SCHED_HPWORKSTACKSIZE=2048 # CONFIG_SCHED_LPWORK is not set # # Stack and heap information # CONFIG_IDLETHREAD_STACKSIZE=2048 CONFIG_USERMAIN_STACKSIZE=2048 CONFIG_PTHREAD_STACK_MIN=256 CONFIG_PTHREAD_STACK_DEFAULT=2048 # CONFIG_LIB_SYSCALL is not set # # Device Drivers # # CONFIG_DISABLE_POLL is not set CONFIG_DEV_NULL=y # CONFIG_DEV_ZERO is not set # CONFIG_DEV_URANDOM is not set # CONFIG_DEV_LOOP is not set # # Buffering # # CONFIG_DRVR_WRITEBUFFER is not set # CONFIG_DRVR_READAHEAD is not set # CONFIG_RAMDISK is not set # CONFIG_CAN is not set CONFIG_ARCH_HAVE_PWM_PULSECOUNT=y # CONFIG_ARCH_HAVE_PWM_MULTICHAN is not set CONFIG_PWM=y # CONFIG_PWM_PULSECOUNT is not set CONFIG_ARCH_HAVE_I2CRESET=y CONFIG_I2C=y # CONFIG_I2C_SLAVE is not set # CONFIG_I2C_POLLED is not set # CONFIG_I2C_RESET is not set # CONFIG_I2C_TRACE is not set # CONFIG_I2C_DRIVER is not set CONFIG_SPI=y # CONFIG_ARCH_HAVE_SPI_CRCGENERATION is not set # CONFIG_ARCH_HAVE_SPI_CS_CONTROL is not set CONFIG_ARCH_HAVE_SPI_BITORDER=y # CONFIG_SPI_SLAVE is not set CONFIG_SPI_EXCHANGE=y # CONFIG_SPI_CMDDATA is not set # CONFIG_SPI_CALLBACK is not set # CONFIG_SPI_HWFEATURES is not set # CONFIG_SPI_BITORDER is not set # CONFIG_SPI_CS_DELAY_CONTROL is not set # CONFIG_SPI_DRIVER is not set # CONFIG_SPI_BITBANG is not set # CONFIG_I2S is not set # # Timer Driver Support # # CONFIG_TIMER is not set # CONFIG_ONESHOT is not set # CONFIG_RTC is not set # CONFIG_WATCHDOG is not set # CONFIG_TIMERS_CS2100CP is not set CONFIG_ANALOG=y CONFIG_ADC=y CONFIG_ADC_FIFOSIZE=8 # CONFIG_ADC_NO_STARTUP_CONV is not set # CONFIG_ADC_ADS1242 is not set # CONFIG_ADC_ADS125X is not set # CONFIG_ADC_PGA11X is not set # CONFIG_DAC is not set # CONFIG_AUDIO_DEVICES is not set # CONFIG_VIDEO_DEVICES is not set # CONFIG_BCH is not set # CONFIG_INPUT is not set # # IO Expander/GPIO Support # # CONFIG_IOEXPANDER is not set # CONFIG_DEV_GPIO is not set # # LCD Driver Support # # CONFIG_LCD is not set # CONFIG_SLCD is not set # # LED Support # # CONFIG_USERLED is not set # CONFIG_RGBLED is not set # CONFIG_PCA9635PW is not set # CONFIG_NCP5623C is not set CONFIG_MMCSD=y CONFIG_MMCSD_NSLOTS=1 # CONFIG_MMCSD_READONLY is not set # CONFIG_MMCSD_MULTIBLOCK_DISABLE is not set CONFIG_MMCSD_MMCSUPPORT=y CONFIG_MMCSD_HAVECARDDETECT=y CONFIG_MMCSD_SPI=y CONFIG_MMCSD_SPICLOCK=20000000 CONFIG_MMCSD_SPIMODE=0 CONFIG_ARCH_HAVE_SDIO=y CONFIG_ARCH_HAVE_SDIOWAIT_WRCOMPLETE=y CONFIG_MMCSD_SDIO=y CONFIG_SDIO_PREFLIGHT=y # CONFIG_SDIO_MUXBUS is not set # CONFIG_MMCSD_SDIOWAIT_WRCOMPLETE is not set # CONFIG_SDIO_BLOCKSETUP is not set # CONFIG_MODEM is not set # CONFIG_MTD is not set # CONFIG_EEPROM is not set CONFIG_NETDEVICES=y # # General Ethernet MAC Driver Options # # CONFIG_NETDEV_LOOPBACK is not set # CONFIG_NETDEV_TELNET is not set # CONFIG_NETDEV_MULTINIC is not set # CONFIG_ARCH_HAVE_NETDEV_STATISTICS is not set CONFIG_NETDEV_LATEINIT=y # # External Ethernet MAC Device Support # # CONFIG_NET_DM90x0 is not set # CONFIG_ENC28J60 is not set # CONFIG_ENCX24J600 is not set # CONFIG_NET_SLIP is not set # CONFIG_NET_FTMAC100 is not set CONFIG_PIPES=y CONFIG_DEV_PIPE_MAXSIZE=1024 CONFIG_DEV_PIPE_SIZE=1024 CONFIG_DEV_FIFO_SIZE=1024 # CONFIG_PM is not set # CONFIG_POWER is not set # CONFIG_SENSORS is not set CONFIG_SERIAL=y # CONFIG_DEV_LOWCONSOLE is not set CONFIG_SERIAL_REMOVABLE=y # CONFIG_SERIAL_CONSOLE is not set # CONFIG_16550_UART is not set # CONFIG_UART_SERIALDRIVER is not set # CONFIG_UART0_SERIALDRIVER is not set # CONFIG_UART1_SERIALDRIVER is not set # CONFIG_UART2_SERIALDRIVER is not set # CONFIG_UART3_SERIALDRIVER is not set # CONFIG_UART4_SERIALDRIVER is not set # CONFIG_UART5_SERIALDRIVER is not set # CONFIG_UART6_SERIALDRIVER is not set # CONFIG_UART7_SERIALDRIVER is not set # CONFIG_UART8_SERIALDRIVER is not set # CONFIG_SCI0_SERIALDRIVER is not set # CONFIG_SCI1_SERIALDRIVER is not set # CONFIG_USART0_SERIALDRIVER is not set # CONFIG_USART1_SERIALDRIVER is not set CONFIG_USART2_SERIALDRIVER=y # CONFIG_USART3_SERIALDRIVER is not set # CONFIG_USART4_SERIALDRIVER is not set # CONFIG_USART5_SERIALDRIVER is not set # CONFIG_USART6_SERIALDRIVER is not set # CONFIG_USART7_SERIALDRIVER is not set # CONFIG_USART8_SERIALDRIVER is not set # CONFIG_OTHER_UART_SERIALDRIVER is not set CONFIG_MCU_SERIAL=y CONFIG_STANDARD_SERIAL=y CONFIG_SERIAL_NPOLLWAITERS=2 # CONFIG_SERIAL_IFLOWCONTROL is not set # CONFIG_SERIAL_OFLOWCONTROL is not set # CONFIG_SERIAL_DMA is not set CONFIG_ARCH_HAVE_SERIAL_TERMIOS=y # CONFIG_USART2_SERIAL_CONSOLE is not set # CONFIG_OTHER_SERIAL_CONSOLE is not set CONFIG_NO_SERIAL_CONSOLE=y # # USART2 Configuration # CONFIG_USART2_RXBUFSIZE=256 CONFIG_USART2_TXBUFSIZE=256 CONFIG_USART2_BAUD=115200 CONFIG_USART2_BITS=8 CONFIG_USART2_PARITY=0 CONFIG_USART2_2STOP=0 # CONFIG_USART2_IFLOWCONTROL is not set # CONFIG_USART2_OFLOWCONTROL is not set # CONFIG_USART2_DMA is not set # CONFIG_PSEUDOTERM is not set CONFIG_USBDEV=y # # USB Device Controller Driver Options # # CONFIG_USBDEV_ISOCHRONOUS is not set # CONFIG_USBDEV_DUALSPEED is not set CONFIG_USBDEV_SELFPOWERED=y # CONFIG_USBDEV_BUSPOWERED is not set CONFIG_USBDEV_MAXPOWER=100 # CONFIG_USBDEV_DMA is not set # CONFIG_ARCH_USBDEV_STALLQUEUE is not set # CONFIG_USBDEV_TRACE is not set # # USB Device Class Driver Options # # CONFIG_USBDEV_COMPOSITE is not set # CONFIG_PL2303 is not set CONFIG_CDCACM=y CONFIG_CDCACM_CONSOLE=y CONFIG_CDCACM_EP0MAXPACKET=64 CONFIG_CDCACM_EPINTIN=1 CONFIG_CDCACM_EPINTIN_FSSIZE=64 CONFIG_CDCACM_EPINTIN_HSSIZE=64 CONFIG_CDCACM_EPBULKOUT=3 CONFIG_CDCACM_EPBULKOUT_FSSIZE=64 CONFIG_CDCACM_EPBULKOUT_HSSIZE=512 CONFIG_CDCACM_EPBULKIN=2 CONFIG_CDCACM_EPBULKIN_FSSIZE=64 CONFIG_CDCACM_EPBULKIN_HSSIZE=512 CONFIG_CDCACM_NRDREQS=4 CONFIG_CDCACM_NWRREQS=4 CONFIG_CDCACM_BULKIN_REQLEN=96 CONFIG_CDCACM_RXBUFSIZE=256 CONFIG_CDCACM_TXBUFSIZE=256 CONFIG_CDCACM_VENDORID=0x0525 CONFIG_CDCACM_PRODUCTID=0xa4a7 CONFIG_CDCACM_VENDORSTR="NuttX" CONFIG_CDCACM_PRODUCTSTR="CDC/ACM Serial" # CONFIG_USBMSC is not set # CONFIG_USBHOST is not set # CONFIG_HAVE_USBTRACE is not set # CONFIG_DRIVERS_WIRELESS is not set # CONFIG_DRIVERS_CONTACTLESS is not set # # System Logging # # CONFIG_ARCH_SYSLOG is not set # CONFIG_RAMLOG is not set # CONFIG_SYSLOG_INTBUFFER is not set # CONFIG_SYSLOG_TIMESTAMP is not set # CONFIG_SYSLOG_SERIAL_CONSOLE is not set CONFIG_SYSLOG_CHAR=y # CONFIG_SYSLOG_CONSOLE is not set # CONFIG_SYSLOG_NONE is not set # CONFIG_SYSLOG_FILE is not set # CONFIG_CONSOLE_SYSLOG is not set CONFIG_SYSLOG_CHAR_CRLF=y CONFIG_SYSLOG_DEVPATH="/dev/ttyS0" # CONFIG_SYSLOG_CHARDEV is not set # # Networking Support # CONFIG_ARCH_HAVE_NET=y # CONFIG_ARCH_HAVE_PHY is not set CONFIG_NET=y # CONFIG_NET_PROMISCUOUS is not set # # Driver buffer configuration # CONFIG_NET_ETH_MTU=590 CONFIG_NET_ETH_TCP_RECVWNDO=536 CONFIG_NET_GUARDSIZE=2 # # Data link support # # CONFIG_NET_MULTILINK is not set CONFIG_NET_ETHERNET=y # CONFIG_NET_LOOPBACK is not set # CONFIG_NET_TUN is not set # # Network Device Operations # # CONFIG_NETDEV_PHY_IOCTL is not set # # Internet Protocol Selection # CONFIG_NET_IPv4=y # CONFIG_NET_IPv6 is not set # # Socket Support # CONFIG_NSOCKET_DESCRIPTORS=8 CONFIG_NET_NACTIVESOCKETS=16 CONFIG_NET_SOCKOPTS=y # CONFIG_NET_SOLINGER is not set # # Raw Socket Support # # CONFIG_NET_PKT is not set # # Unix Domain Socket Support # CONFIG_NET_LOCAL=y CONFIG_NET_LOCAL_STREAM=y CONFIG_NET_LOCAL_DGRAM=y # # TCP/IP Networking # CONFIG_NET_TCP=y # CONFIG_NET_TCPURGDATA is not set CONFIG_NET_TCP_CONNS=8 CONFIG_NET_MAX_LISTENPORTS=20 CONFIG_NET_TCP_READAHEAD=y CONFIG_NET_TCP_WRITE_BUFFERS=y CONFIG_NET_TCP_NWRBCHAINS=8 CONFIG_NET_TCP_RECVDELAY=0 # CONFIG_NET_TCPBACKLOG is not set # CONFIG_NET_SENDFILE is not set # # UDP Networking # # CONFIG_NET_UDP is not set # # ICMP Networking Support # # CONFIG_NET_ICMP is not set # # IGMPv2 Client Support # # CONFIG_NET_IGMP is not set # # ARP Configuration # CONFIG_NET_ARP=y CONFIG_NET_ARPTAB_SIZE=16 CONFIG_NET_ARP_MAXAGE=120 # CONFIG_NET_ARP_IPIN is not set # CONFIG_NET_ARP_SEND is not set # # Network I/O Buffer Support # CONFIG_NET_IOB=y CONFIG_IOB_NBUFFERS=36 CONFIG_IOB_BUFSIZE=196 CONFIG_IOB_NCHAINS=8 CONFIG_IOB_THROTTLE=8 # CONFIG_NET_ARCH_INCR32 is not set # CONFIG_NET_ARCH_CHKSUM is not set # CONFIG_NET_STATISTICS is not set # # Routing Table Configuration # # CONFIG_NET_ROUTE is not set CONFIG_NET_HOSTNAME="" # # Crypto API # # CONFIG_CRYPTO is not set # # File Systems # # # File system configuration # # CONFIG_DISABLE_MOUNTPOINT is not set # CONFIG_FS_AUTOMOUNTER is not set # CONFIG_DISABLE_PSEUDOFS_OPERATIONS is not set CONFIG_FS_READABLE=y CONFIG_FS_WRITABLE=y # CONFIG_FS_NAMED_SEMAPHORES is not set CONFIG_FS_MQUEUE_MPATH="/var/mqueue" # CONFIG_FS_RAMMAP is not set CONFIG_FS_FAT=y CONFIG_FAT_LCNAMES=y CONFIG_FAT_LFN=y CONFIG_FAT_MAXFNAME=32 # CONFIG_FS_FATTIME is not set # CONFIG_FAT_FORCE_INDIRECT is not set # CONFIG_FAT_DMAMEMORY is not set # CONFIG_FAT_DIRECT_RETRY is not set # CONFIG_FS_NXFFS is not set # CONFIG_FS_ROMFS is not set # CONFIG_FS_TMPFS is not set # CONFIG_FS_SMARTFS is not set # CONFIG_FS_BINFS is not set CONFIG_FS_PROCFS=y # CONFIG_FS_PROCFS_REGISTER is not set # # Exclude individual procfs entries # # CONFIG_FS_PROCFS_EXCLUDE_PROCESS is not set # CONFIG_FS_PROCFS_EXCLUDE_UPTIME is not set # CONFIG_FS_PROCFS_EXCLUDE_MOUNTS is not set # CONFIG_FS_PROCFS_EXCLUDE_NET is not set # CONFIG_FS_UNIONFS is not set # # Graphics Support # # CONFIG_NX is not set # # Memory Management # # CONFIG_MM_SMALL is not set CONFIG_MM_REGIONS=2 # CONFIG_ARCH_HAVE_HEAP2 is not set # CONFIG_GRAN is not set # # Audio Support # # CONFIG_AUDIO is not set # # Wireless Support # # # Binary Loader # # CONFIG_BINFMT_DISABLE is not set # CONFIG_BINFMT_EXEPATH is not set # CONFIG_NXFLAT is not set # CONFIG_ELF is not set CONFIG_BUILTIN=y # CONFIG_PIC is not set # CONFIG_SYMTAB_ORDEREDBYNAME is not set # # Library Routines # # # Standard C Library Options # CONFIG_STDIO_BUFFER_SIZE=64 CONFIG_STDIO_LINEBUFFER=y CONFIG_NUNGET_CHARS=2 CONFIG_LIB_HOMEDIR="/" CONFIG_LIBM=y # CONFIG_NOPRINTF_FIELDWIDTH is not set # CONFIG_LIBC_FLOATINGPOINT is not set CONFIG_LIBC_LONG_LONG=y # CONFIG_LIBC_IOCTL_VARIADIC is not set # CONFIG_LIBC_WCHAR is not set # CONFIG_LIBC_LOCALE is not set CONFIG_LIB_RAND_ORDER=1 # CONFIG_EOL_IS_CR is not set # CONFIG_EOL_IS_LF is not set # CONFIG_EOL_IS_BOTH_CRLF is not set CONFIG_EOL_IS_EITHER_CRLF=y # CONFIG_LIBC_EXECFUNCS is not set CONFIG_POSIX_SPAWN_PROXY_STACKSIZE=1024 CONFIG_TASK_SPAWN_DEFAULT_STACKSIZE=2048 # CONFIG_LIBC_STRERROR is not set # CONFIG_LIBC_PERROR_STDOUT is not set CONFIG_LIBC_TMPDIR="/tmp" CONFIG_LIBC_MAX_TMPFILE=32 CONFIG_ARCH_LOWPUTC=y # CONFIG_LIBC_LOCALTIME is not set # CONFIG_TIME_EXTENDED is not set CONFIG_LIB_SENDFILE_BUFSIZE=512 # CONFIG_ARCH_ROMGETC is not set # CONFIG_ARCH_OPTIMIZED_FUNCTIONS is not set CONFIG_ARCH_HAVE_TLS=y # CONFIG_TLS is not set # CONFIG_LIBC_IPv6_ADDRCONV is not set CONFIG_LIBC_NETDB=y # CONFIG_NETDB_HOSTFILE is not set # # Non-standard Library Support # # CONFIG_LIB_CRC64_FAST is not set # CONFIG_LIB_KBDCODEC is not set # CONFIG_LIB_SLCDCODEC is not set # CONFIG_LIB_HEX2BIN is not set # # Basic CXX Support # # CONFIG_C99_BOOL8 is not set CONFIG_HAVE_CXX=y CONFIG_HAVE_CXXINITIALIZE=y # CONFIG_CXX_NEWLONG is not set # # uClibc++ Standard C++ Library # # CONFIG_UCLIBCXX is not set # # Application Configuration # # # NxWidgets/NxWM # # # Built-In Applications # CONFIG_BUILTIN_PROXY_STACKSIZE=1024 # # CAN Utilities # # # Examples # # CONFIG_EXAMPLES_ADC is not set # CONFIG_EXAMPLES_BUTTONS is not set # CONFIG_EXAMPLES_CCTYPE is not set # CONFIG_EXAMPLES_CHAT is not set # CONFIG_EXAMPLES_CONFIGDATA is not set # CONFIG_EXAMPLES_CPUHOG is not set # CONFIG_EXAMPLES_CXXTEST is not set # CONFIG_EXAMPLES_DHCPD is not set # CONFIG_EXAMPLES_ELF is not set # CONFIG_EXAMPLES_FSTEST is not set # CONFIG_EXAMPLES_FTPC is not set # CONFIG_EXAMPLES_FTPD is not set # CONFIG_EXAMPLES_HELLO is not set # CONFIG_EXAMPLES_HELLOXX is not set # CONFIG_EXAMPLES_HIDKBD is not set # CONFIG_EXAMPLES_IGMP is not set # CONFIG_EXAMPLES_JSON is not set # CONFIG_EXAMPLES_KEYPADTEST is not set # CONFIG_EXAMPLES_MEDIA is not set # CONFIG_EXAMPLES_MM is not set # CONFIG_EXAMPLES_MODBUS is not set # CONFIG_EXAMPLES_MOUNT is not set # CONFIG_EXAMPLES_NETTEST is not set # CONFIG_EXAMPLES_NRF24L01TERM is not set CONFIG_EXAMPLES_NSH=y CONFIG_EXAMPLES_NSH_CXXINITIALIZE=y # CONFIG_EXAMPLES_NULL is not set # CONFIG_EXAMPLES_NX is not set # CONFIG_EXAMPLES_NXFFS is not set # CONFIG_EXAMPLES_NXHELLO is not set # CONFIG_EXAMPLES_NXIMAGE is not set # CONFIG_EXAMPLES_NXLINES is not set # CONFIG_EXAMPLES_NXTERM is not set # CONFIG_EXAMPLES_NXTEXT is not set # CONFIG_EXAMPLES_OSTEST is not set # CONFIG_EXAMPLES_PCA9635 is not set # CONFIG_EXAMPLES_PIPE is not set # CONFIG_EXAMPLES_POSIXSPAWN is not set # CONFIG_EXAMPLES_PPPD is not set # CONFIG_EXAMPLES_PWM is not set # CONFIG_EXAMPLES_RFID_READUID is not set # CONFIG_EXAMPLES_RGBLED is not set # CONFIG_EXAMPLES_SENDMAIL is not set # CONFIG_EXAMPLES_SERIALBLASTER is not set # CONFIG_EXAMPLES_SERIALRX is not set # CONFIG_EXAMPLES_SERLOOP is not set # CONFIG_EXAMPLES_SLCD is not set # CONFIG_EXAMPLES_SMART is not set # CONFIG_EXAMPLES_SMART_TEST is not set # CONFIG_EXAMPLES_SMP is not set # CONFIG_EXAMPLES_TCPECHO is not set # CONFIG_EXAMPLES_TELNETD is not set # CONFIG_EXAMPLES_TIFF is not set # CONFIG_EXAMPLES_TOUCHSCREEN is not set # CONFIG_EXAMPLES_UDGRAM is not set # CONFIG_EXAMPLES_USBSERIAL is not set # CONFIG_EXAMPLES_USBTERM is not set # CONFIG_EXAMPLES_USTREAM is not set # CONFIG_EXAMPLES_WATCHDOG is not set # CONFIG_EXAMPLES_WEBSERVER is not set # CONFIG_EXAMPLES_XMLRPC is not set # # File System Utilities # # CONFIG_FSUTILS_INIFILE is not set # CONFIG_FSUTILS_PASSWD is not set # # GPS Utilities # # CONFIG_GPSUTILS_MINMEA_LIB is not set # # Graphics Support # # CONFIG_TIFF is not set # CONFIG_GRAPHICS_TRAVELER is not set # # Interpreters # # CONFIG_INTERPRETERS_BAS is not set # CONFIG_INTERPRETERS_FICL is not set # CONFIG_INTERPRETERS_MICROPYTHON is not set # CONFIG_INTERPRETERS_MINIBASIC is not set # CONFIG_INTERPRETERS_PCODE is not set # # FreeModBus # # CONFIG_MODBUS is not set # # Network Utilities # # CONFIG_NETUTILS_CHAT is not set # CONFIG_NETUTILS_CODECS is not set # CONFIG_NETUTILS_ESP8266 is not set # CONFIG_NETUTILS_FTPC is not set # CONFIG_NETUTILS_FTPD is not set # CONFIG_NETUTILS_JSON is not set CONFIG_NETUTILS_NETLIB=y # CONFIG_NETUTILS_SMTP is not set # CONFIG_NETUTILS_TELNETD is not set # CONFIG_NETUTILS_WEBCLIENT is not set # CONFIG_NETUTILS_WEBSERVER is not set # CONFIG_NETUTILS_XMLRPC is not set # # NSH Library # CONFIG_NSH_LIBRARY=y # CONFIG_NSH_MOTD is not set # # Command Line Configuration # CONFIG_NSH_READLINE=y # CONFIG_NSH_CLE is not set CONFIG_NSH_LINELEN=64 # CONFIG_NSH_DISABLE_SEMICOLON is not set CONFIG_NSH_CMDPARMS=y CONFIG_NSH_MAXARGUMENTS=6 CONFIG_NSH_ARGCAT=y CONFIG_NSH_NESTDEPTH=3 # CONFIG_NSH_DISABLEBG is not set CONFIG_NSH_BUILTIN_APPS=y # # Disable Individual commands # # CONFIG_NSH_DISABLE_ADDROUTE is not set # CONFIG_NSH_DISABLE_ARP is not set # CONFIG_NSH_DISABLE_BASENAME is not set # CONFIG_NSH_DISABLE_CAT is not set # CONFIG_NSH_DISABLE_CD is not set # CONFIG_NSH_DISABLE_CP is not set # CONFIG_NSH_DISABLE_CMP is not set CONFIG_NSH_DISABLE_DATE=y # CONFIG_NSH_DISABLE_DD is not set # CONFIG_NSH_DISABLE_DF is not set # CONFIG_NSH_DISABLE_DELROUTE is not set # CONFIG_NSH_DISABLE_DIRNAME is not set # CONFIG_NSH_DISABLE_ECHO is not set # CONFIG_NSH_DISABLE_EXEC is not set # CONFIG_NSH_DISABLE_EXIT is not set # CONFIG_NSH_DISABLE_FREE is not set # CONFIG_NSH_DISABLE_GET is not set # CONFIG_NSH_DISABLE_HELP is not set # CONFIG_NSH_DISABLE_HEXDUMP is not set # CONFIG_NSH_DISABLE_IFCONFIG is not set # CONFIG_NSH_DISABLE_IFUPDOWN is not set # CONFIG_NSH_DISABLE_KILL is not set # CONFIG_NSH_DISABLE_LOSETUP is not set CONFIG_NSH_DISABLE_LOSMART=y # CONFIG_NSH_DISABLE_LS is not set # CONFIG_NSH_DISABLE_MB is not set # CONFIG_NSH_DISABLE_MKDIR is not set # CONFIG_NSH_DISABLE_MKFATFS is not set # CONFIG_NSH_DISABLE_MKFIFO is not set # CONFIG_NSH_DISABLE_MKRD is not set # CONFIG_NSH_DISABLE_MH is not set # CONFIG_NSH_DISABLE_MOUNT is not set # CONFIG_NSH_DISABLE_MV is not set # CONFIG_NSH_DISABLE_MW is not set CONFIG_NSH_DISABLE_PRINTF=y # CONFIG_NSH_DISABLE_PS is not set # CONFIG_NSH_DISABLE_PUT is not set # CONFIG_NSH_DISABLE_PWD is not set # CONFIG_NSH_DISABLE_RM is not set # CONFIG_NSH_DISABLE_RMDIR is not set # CONFIG_NSH_DISABLE_SET is not set # CONFIG_NSH_DISABLE_SH is not set # CONFIG_NSH_DISABLE_SLEEP is not set # CONFIG_NSH_DISABLE_TIME is not set # CONFIG_NSH_DISABLE_TEST is not set # CONFIG_NSH_DISABLE_UMOUNT is not set # CONFIG_NSH_DISABLE_UNAME is not set # CONFIG_NSH_DISABLE_UNSET is not set # CONFIG_NSH_DISABLE_USLEEP is not set # CONFIG_NSH_DISABLE_WGET is not set # CONFIG_NSH_DISABLE_XD is not set CONFIG_NSH_MMCSDMINOR=0 CONFIG_NSH_MMCSDSLOTNO=0 CONFIG_NSH_MMCSDSPIPORTNO=0 # # Configure Command Options # CONFIG_NSH_CMDOPT_DF_H=y # CONFIG_NSH_CMDOPT_DD_STATS is not set CONFIG_NSH_CODECS_BUFSIZE=128 CONFIG_NSH_CMDOPT_HEXDUMP=y CONFIG_NSH_PROC_MOUNTPOINT="/proc" CONFIG_NSH_FILEIOSIZE=512 # # Scripting Support # # CONFIG_NSH_DISABLESCRIPT is not set # CONFIG_NSH_DISABLE_ITEF is not set # CONFIG_NSH_DISABLE_LOOPS is not set # # Console Configuration # CONFIG_NSH_CONSOLE=y # CONFIG_NSH_USBCONSOLE is not set # CONFIG_NSH_ALTCONDEV is not set CONFIG_NSH_ARCHINIT=y # # Networking Configuration # CONFIG_NSH_NETINIT=y # CONFIG_NSH_NETINIT_THREAD is not set # # IP Address Configuration # # # IPv4 Addresses # CONFIG_NSH_IPADDR=0x0a000002 CONFIG_NSH_DRIPADDR=0x0a000001 CONFIG_NSH_NETMASK=0xffffff00 # CONFIG_NSH_NOMAC is not set CONFIG_NSH_MAX_ROUNDTRIP=20 # CONFIG_NSH_LOGIN is not set # CONFIG_NSH_CONSOLE_LOGIN is not set # # Platform-specific Support # # CONFIG_PLATFORM_CONFIGDATA is not set # # System Libraries and NSH Add-Ons # # CONFIG_SYSTEM_CDCACM is not set # CONFIG_SYSTEM_CLE is not set # CONFIG_SYSTEM_CUTERM is not set # CONFIG_SYSTEM_FREE is not set # CONFIG_SYSTEM_HEX2BIN is not set # CONFIG_SYSTEM_HEXED is not set # CONFIG_SYSTEM_I2CTOOL is not set # CONFIG_SYSTEM_INSTALL is not set CONFIG_IOTJS=y CONFIG_IOTJS_PRIORITY=100 CONFIG_IOTJS_STACKSIZE=16384 # CONFIG_SYSTEM_NETDB is not set # CONFIG_SYSTEM_RAMTEST is not set CONFIG_READLINE_HAVE_EXTMATCH=y CONFIG_SYSTEM_READLINE=y CONFIG_READLINE_ECHO=y CONFIG_READLINE_TABCOMPLETION=y CONFIG_READLINE_MAX_BUILTINS=64 CONFIG_READLINE_MAX_EXTCMDS=64 CONFIG_READLINE_CMD_HISTORY=y CONFIG_READLINE_CMD_HISTORY_LINELEN=80 CONFIG_READLINE_CMD_HISTORY_LEN=16 # CONFIG_SYSTEM_SUDOKU is not set # CONFIG_SYSTEM_SYSTEM is not set # CONFIG_SYSTEM_TEE is not set # CONFIG_SYSTEM_UBLOXMODEM is not set # CONFIG_SYSTEM_VI is not set # CONFIG_SYSTEM_ZMODEM is not set iotjs-1.0/config/nuttx/stm32f4dis/app/000077500000000000000000000000001312466455500176265ustar00rootroot00000000000000iotjs-1.0/config/nuttx/stm32f4dis/app/Kconfig000066400000000000000000000005541312466455500211350ustar00rootroot00000000000000# # For a description of the syntax of this configuration file, # see the file kconfig-language.txt in the NuttX tools repository. # config IOTJS bool "IoT.js" default n ---help--- Enable IoT.js platform if IOTJS config IOTJS_PRIORITY int "IoT.js task priority" default 100 config IOTJS_STACKSIZE int "IoT.js stack size" default 16384 endif iotjs-1.0/config/nuttx/stm32f4dis/app/Make.defs000066400000000000000000000013251312466455500213470ustar00rootroot00000000000000# Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors # Copyright 2016 University of Szeged # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. ifeq ($(CONFIG_IOTJS),y) CONFIGURED_APPS += system/iotjs endif iotjs-1.0/config/nuttx/stm32f4dis/app/Makefile000066400000000000000000000121441312466455500212700ustar00rootroot00000000000000# Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. ############################################################################ # Copyright (C) 2009, 2011-2013 Gregory Nutt. All rights reserved. # Author: Gregory Nutt # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # 3. Neither the name NuttX nor the names of its contributors may be # used to endorse or promote products derived from this software # without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS # OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. # ############################################################################ # TODO, this makefile should run make under the app dirs, instead of # sourcing the Make.defs! -include $(TOPDIR)/.config -include $(TOPDIR)/Make.defs include $(APPDIR)/Make.defs IOTJS_ABSOLUTE_ROOT_DIR := $(shell cd $(TOPDIR) && cd $(IOTJS_ROOT_DIR) && pwd) CONFIG_IOTJS_PRIORITY ?= SCHED_PRIORITY_DEFAULT CONFIG_IOTJS_STACKSIZE ?= 16384 # NSH sysinfo command APPNAME = iotjs CFLAGS += -I$(IOTJS_ABSOLUTE_ROOT_DIR)/deps/jerry/jerry-core/include CFLAGS += -I$(IOTJS_ABSOLUTE_ROOT_DIR)/deps/jerry/jerry-ext/include PRIORITY = $(CONFIG_IOTJS_PRIORITY) STACKSIZE = $(CONFIG_IOTJS_STACKSIZE) HEAPSIZE = $(CONFIG_IOTJS_HEAPSIZE) ASRCS = setjmp.S CSRCS = jerry_port.c MAINSRC = iotjs_main.c LIBS = libhttpparser.a libiotjs.a libjerry-core.a libtuv.a libjerry-libm.a AOBJS = $(ASRCS:.S=$(OBJEXT)) COBJS = $(CSRCS:.c=$(OBJEXT)) MAINOBJ = $(MAINSRC:.c=$(OBJEXT)) SRCS = $(ASRCS) $(CSRCS) $(MAINSRC) OBJS = $(AOBJS) $(COBJS) ifeq ($(R),1) BUILD_TYPE = release else BUILD_TYPE = debug endif ifneq ($(CONFIG_BUILD_KERNEL),y) OBJS += $(MAINOBJ) endif ifeq ($(CONFIG_WINDOWS_NATIVE),y) BIN = ..\..\libapps$(LIBEXT) else ifeq ($(WINTOOL),y) BIN = ..\\..\\libapps$(LIBEXT) else BIN = ../../libapps$(LIBEXT) endif endif ifeq ($(WINTOOL),y) INSTALL_DIR = "${shell cygpath -w $(BIN_DIR)}" else INSTALL_DIR = $(BIN_DIR) endif CONFIG_XYZ_PROGNAME ?= iotjs$(EXEEXT) PROGNAME = $(CONFIG_XYZ_PROGNAME) ROOTDEPPATH = --dep-path . # Common build VPATH = all: .built .PHONY: context depend clean distclean $(AOBJS): %$(OBJEXT): %.S $(call ASSEMBLE, $<, $@) $(COBJS): %$(OBJEXT): %.c $(call COMPILE, $<, $@) copylibs : cp $(IOTJS_ABSOLUTE_ROOT_DIR)/build/arm-nuttx/$(BUILD_TYPE)/lib/lib*.a . $(LIBS) : copylibs $(firstword $(AR)) x $@ .built: $(LIBS) $(OBJS) $(eval OBJS += $(shell find . -name "*.obj")) $(call ARCHIVE, $(BIN), $(OBJS)) $(Q) touch .built ifeq ($(CONFIG_BUILD_KERNEL),y) $(BIN_DIR)$(DELIM)$(PROGNAME): $(OBJS) $(MAINOBJ) @echo "LD: $(PROGNAME)" $(Q) $(LD) $(LDELFFLAGS) $(LDLIBPATH) -o $(INSTALL_DIR)$(DELIM)$(PROGNAME) $(ARCHCRT0OBJ) $(MAINOBJ) $(LDLIBS) $(Q) $(NM) -u $(INSTALL_DIR)$(DELIM)$(PROGNAME) install: $(BIN_DIR)$(DELIM)$(PROGNAME) else install: endif # Register application ifeq ($(CONFIG_NSH_BUILTIN_APPS),y) $(BUILTIN_REGISTRY)$(DELIM)iotjs.bdat: $(DEPCONFIG) Makefile $(call REGISTER,"iotjs",$(PRIORITY),$(STACKSIZE),iotjs_main) context: $(BUILTIN_REGISTRY)$(DELIM)iotjs.bdat else context: endif # Create dependencies .depend: Makefile $(SRCS) $(Q) $(MKDEP) $(ROOTDEPPATH) "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep $(Q) touch $@ depend: .depend clean: $(eval OBJS += $(shell find . -name "*.obj")) $(call DELFILE, $(OBJS)) $(call DELFILE, .built) $(call CLEAN) distclean: clean $(call DELFILE, Make.dep) $(call DELFILE, .depend) -include Make.dep .PHONY: preconfig preconfig: iotjs-1.0/config/nuttx/stm32f4dis/app/iotjs_main.c000066400000000000000000000061121312466455500221260ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /**************************************************************************** * Copyright (C) 2013 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * 3. Neither the name NuttX nor the names of its contributors may be * used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * ****************************************************************************/ /**************************************************************************** * Included Files ****************************************************************************/ #include #include #include #include "setjmp.h" /**************************************************************************** * Public Functions ****************************************************************************/ extern int iotjs_entry(int argc, char *argv[]); extern int tuv_cleanup(void); #ifdef CONFIG_BUILD_KERNEL extern int main(int argc, FAR char *argv[]) #else extern int iotjs_main(int argc, char *argv[]) #endif { int ret = 0; ret = iotjs_entry(argc, argv); tuv_cleanup(); return ret; } iotjs-1.0/config/nuttx/stm32f4dis/app/jerry_port.c000066400000000000000000000036331312466455500221760ustar00rootroot00000000000000/* Copyright 2017-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include "jerryscript-ext/handler.h" #include "jerryscript-port.h" #include "jerryscript.h" /** * Aborts the program. */ void jerry_port_fatal(jerry_fatal_code_t code) { exit(1); } /* jerry_port_fatal */ /** * Provide log message implementation for the engine. */ void jerry_port_log(jerry_log_level_t level, /**< log level */ const char *format, /**< format string */ ...) { /**< parameters */ /* Drain log messages since IoT.js has not support log levels yet. */ } /* jerry_port_log */ /** * Dummy function to get the time zone. * * @return true */ bool jerry_port_get_time_zone(jerry_time_zone_t *tz_p) { /* We live in UTC. */ tz_p->offset = 0; tz_p->daylight_saving_time = 0; return true; } /* jerry_port_get_time_zone */ /** * Dummy function to get the current time. * * @return 0 */ double jerry_port_get_current_time(void) { return 0; } /* jerry_port_get_current_time */ /** * Provide the implementation of jerryx_port_handler_print_char. * Uses 'printf' to print a single character to standard output. */ void jerryx_port_handler_print_char(char c) { /**< the character to print */ printf("%c", c); } /* jerryx_port_handler_print_char */ iotjs-1.0/config/nuttx/stm32f4dis/app/setjmp.S000066400000000000000000000040161312466455500212550ustar00rootroot00000000000000/* Copyright 2017-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* Copyright JS Foundation and other contributors, http://js.foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ .syntax unified .macro func _name .global \_name .type \_name, %function \_name: .endm .macro endfunc _name .size \_name, .-\_name .endm /** * setjmp (jmp_buf env) * * See also: * longjmp * * @return 0 - if returns from direct call, * nonzero - if returns after longjmp. */ func setjmp stmia r0!, {r4 - r11, lr} str sp, [r0], #4 vstm r0, {s16 - s31} mov r0, #0 bx lr endfunc setjmp /** * longjmp (jmp_buf env, int val) * * Note: * if val is not 0, then it would be returned from setjmp, * otherwise - 0 would be returned. * * See also: * setjmp */ func longjmp ldmia r0!, {r4 - r11, lr} ldr sp, [r0] add r0, r0, #4 vldm r0, {s16 - s31} mov r0, r1 cmp r0, #0 bne 1f mov r0, #1 1: bx lr endfunc longjmp iotjs-1.0/config/nuttx/stm32f4dis/app/setjmp.h000066400000000000000000000026471312466455500213120ustar00rootroot00000000000000/* Copyright 2017-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* Copyright JS Foundation and other contributors, http://js.foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef SETJMP_H #define SETJMP_H #include typedef uint64_t jmp_buf[14]; int setjmp(jmp_buf env); void longjmp(jmp_buf env, int val); #endif /* !SETJMP_H */ iotjs-1.0/config/nuttx/stm32f4dis/patch000066400000000000000000000013211312466455500200650ustar00rootroot00000000000000--- a/configs/stm32f4discovery/include/board.h +++ b/configs/stm32f4discovery/include/board.h @@ -253,6 +253,13 @@ # define GPIO_CAN2_TX GPIO_CAN2_TX_1 #endif # Patch code to enable UART1: # It maps pin PB6 and pin PB7 to USART1_TX and USART2_RX respectively. # + +#define GPIO_USART1_RX GPIO_USART1_RX_2 +#define GPIO_USART1_TX GPIO_USART1_TX_2 + # Patch code to enable UART4: # It maps pin PA0 and pin PA1 to UART4_TX and UART4_RX respectively. # Because it makes conflict with pins of USART2, # you have to disable USART2 to use this port. # +#define GPIO_UART4_RX GPIO_UART4_RX_1 +#define GPIO_UART4_TX GPIO_UART4_TX_1 + /* UART2: * * The STM32F4 Discovery has no on-board serial devices, but the console is iotjs-1.0/config/tizenrt/000077500000000000000000000000001312466455500154615ustar00rootroot00000000000000iotjs-1.0/config/tizenrt/artik05x/000077500000000000000000000000001312466455500171305ustar00rootroot00000000000000iotjs-1.0/config/tizenrt/artik05x/app/000077500000000000000000000000001312466455500177105ustar00rootroot00000000000000iotjs-1.0/config/tizenrt/artik05x/app/.gitignore000066400000000000000000000001231312466455500216740ustar00rootroot00000000000000/Make.dep /.depend /.built /*.asm /*.obj /*.rel /*.lst /*.sym /*.adb /*.lib /*.src iotjs-1.0/config/tizenrt/artik05x/app/Kconfig000066400000000000000000000007161312466455500212170ustar00rootroot00000000000000# # For a description of the syntax of this configuration file, # see the file kconfig-language.txt in the NuttX tools repository. # config SYSTEM_IOTJS bool "IoT.js" default y ---help--- Enable IoT.js platform if SYSTEM_IOTJS config IOTJS_PRIORITY int "IoT.js task priority" default 100 config IOTJS_STACKSIZE int "IoT.js stack size" default 32768 endif config USER_ENTRYPOINT string default "iotjs_main" if ENTRY_IOTJS iotjs-1.0/config/tizenrt/artik05x/app/Kconfig_ENTRY000066400000000000000000000001061312466455500221710ustar00rootroot00000000000000config ENTRY_IOTJS bool "iotjs application" depends on SYSTEM_IOTJS iotjs-1.0/config/tizenrt/artik05x/app/Make.defs000066400000000000000000000013341312466455500214310ustar00rootroot00000000000000# Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors # Copyright 2016 University of Szeged # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. ifeq ($(CONFIG_SYSTEM_IOTJS),y) CONFIGURED_APPS += system/iotjs endif iotjs-1.0/config/tizenrt/artik05x/app/Makefile000066400000000000000000000115351312466455500213550ustar00rootroot00000000000000########################################################################### # # Copyright 2016 Samsung Electronics All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, # either express or implied. See the License for the specific # language governing permissions and limitations under the License. # ########################################################################### ############################################################################ # apps/examples/iotjs/Makefile # # Copyright (C) 2008, 2010-2013 Gregory Nutt. All rights reserved. # Author: Gregory Nutt # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in # the documentation and/or other materials provided with the # distribution. # 3. Neither the name NuttX nor the names of its contributors may be # used to endorse or promote products derived from this software # without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS # OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED # AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. # ############################################################################ EXTRA_LIBPATHS += -L$(IOTJS_LIB_DIR) EXTRA_LIBS += libhttpparser.a libiotjs.a libjerrycore.a libtuv.a libjerry-libm.a LINKLIBS=$(EXTRA_LIBS) -include $(TOPDIR)/.config -include $(TOPDIR)/Make.defs include $(APPDIR)/Make.defs # IoT.js application CONFIG_IOTJS_PRIORITY ?= SCHED_PRIORITY_DEFAULT CONFIG_IOTJS_STACKSIZE ?= 16384 IOTJS_LIB_DIR ?= n APPNAME = iotjs PRIORITY = $(CONFIG_IOTJS_PRIORITY) STACKSIZE = $(CONFIG_IOTJS_STACKSIZE) HEAPSIZE = $(CONFIG_IOTJS_HEAPSIZE) ASRCS = CSRCS = MAINSRC = iotjs_main.c AOBJS = $(ASRCS:.S=$(OBJEXT)) COBJS = $(CSRCS:.c=$(OBJEXT)) MAINOBJ = $(MAINSRC:.c=$(OBJEXT)) SRCS = $(ASRCS) $(CSRCS) $(MAINSRC) OBJS = $(AOBJS) $(COBJS) ifeq ($(R),1) BUILD_TYPE = release else BUILD_TYPE = debug endif ifneq ($(CONFIG_BUILD_KERNEL),y) OBJS += $(MAINOBJ) endif ifeq ($(CONFIG_WINDOWS_NATIVE),y) BIN = ..\..\libapps$(LIBEXT) else ifeq ($(WINTOOL),y) BIN = ..\\..\\libapps$(LIBEXT) else BIN = ../../libapps$(LIBEXT) endif endif ifeq ($(WINTOOL),y) INSTALL_DIR = "${shell cygpath -w $(BIN_DIR)}" else INSTALL_DIR = $(BIN_DIR) endif CONFIG_IOTJS_PROGNAME ?= iotjs$(EXEEXT) PROGNAME = $(CONFIG_IOTJS_PROGNAME) ROOTDEPPATH = --dep-path . # Common build VPATH = all: .built .PHONY: clean depend distclean check_iotjs $(AOBJS): %$(OBJEXT): %.S $(call ASSEMBLE, $<, $@) $(COBJS) $(MAINOBJ): %$(OBJEXT): %.c $(call COMPILE, $<, $@) .built: $(OBJS) check_iotjs $(call ARCHIVE, $(BIN), $(OBJS)) @touch .built ifeq ($(CONFIG_BUILD_KERNEL),y) $(BIN_DIR)$(DELIM)$(PROGNAME): $(OBJS) $(MAINOBJ) check_iotjs $(Q) $(LD) $(LDELFFLAGS) $(LDLIBPATH) -o $(INSTALL_DIR)$(DELIM)$(PROGNAME) $(ARCHCRT0OBJ) $(MAINOBJ) $(LDLIBS) $(Q) $(NM) -u $(INSTALL_DIR)$(DELIM)$(PROGNAME) install: $(BIN_DIR)$(DELIM)$(PROGNAME) else install: endif check_iotjs: ifeq ($(IOTJS_LIB_DIR),n) @echo "ERROR: IOTJS_LIB_DIR not set! Aborting..." @exit 1 endif @echo IOTJS_LIB_DIR set! @echo "$(LDLIBPATH), $(IOTJS_LIB_DIR) $(TOPDIR)" @cp $(IOTJS_LIB_DIR)/lib* $(TOPDIR)/../build/output/libraries/ @cp $(IOTJS_LIB_DIR)/../deps/jerry/lib/libjerry-libm.a $(TOPDIR)/../build/output/libraries/ context: .depend: Makefile $(SRCS) @$(MKDEP) $(ROOTDEPPATH) "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep @touch $@ depend: .depend clean: $(call DELFILE, .built) $(call CLEAN) distclean: clean $(call DELFILE, Make.dep) $(call DELFILE, .depend) -include Make.dep .PHONY: preconfig preconfig: iotjs-1.0/config/tizenrt/artik05x/app/iotjs_main.c000066400000000000000000000111201312466455500222030ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /**************************************************************************** * Copyright (C) 2013 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * 3. Neither the name NuttX nor the names of its contributors may be * used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * ****************************************************************************/ /**************************************************************************** * Included Files ****************************************************************************/ #include #include #include #include #include #define USE_IOTJS_THREAD 1 /** * Compiler built-in setjmp function. * * @return 0 when called the first time * 1 when returns from a longjmp call */ int setjmp(jmp_buf buf) { return __builtin_setjmp(buf); } /* setjmp */ /** * Compiler built-in longjmp function. * * Note: * ignores value argument */ void longjmp(jmp_buf buf, int value) { /* Must be called with 1. */ __builtin_longjmp(buf, 1); } /* longjmp */ int iotjs_entry(int argc, char *argv[]); int tuv_cleanup(void); #if USE_IOTJS_THREAD struct iotjs_thread_arg { int argc; char **argv; }; pthread_addr_t iotjs_thread(void *thread_arg) { struct iotjs_thread_arg *arg = thread_arg; int ret = 0; ret = iotjs_entry(arg->argc, arg->argv); tuv_cleanup(); sleep(1); printf("iotjs thread end\n"); return NULL; } int iotjs(int argc, char *argv[]) { pthread_attr_t attr; int status; struct sched_param sparam; pthread_t tid; struct iotjs_thread_arg arg; status = pthread_attr_init(&attr); if (status != 0) { printf("fail to initialize iotjs thread\n"); return -1; } sparam.sched_priority = CONFIG_IOTJS_PRIORITY; status = pthread_attr_setschedparam(&attr, &sparam); status = pthread_attr_setschedpolicy(&attr, SCHED_RR); status = pthread_attr_setstacksize(&attr, CONFIG_IOTJS_STACKSIZE); arg.argc = argc; arg.argv = argv; status = pthread_create(&tid, &attr, iotjs_thread, &arg); if (status < 0) { printf("fail to start iotjs thread\n"); return -1; } pthread_setname_np(tid, "iotjs_thread"); pthread_join(tid, NULL); return 0; } #else static int iotjs(int argc, char *argv[]) { int ret = 0; ret = iotjs_entry(argc, argv); tuv_cleanup(); return ret; } #endif #ifdef CONFIG_BUILD_KERNEL int main(int argc, FAR char *argv[]) #else int iotjs_main(int argc, char *argv[]) #endif { return iotjs(argc, argv); } int iotjs_register_cmd() { tash_cmd_install("iotjs", iotjs, TASH_EXECMD_SYNC); return 0; } iotjs-1.0/deps/000077500000000000000000000000001312466455500134505ustar00rootroot00000000000000iotjs-1.0/deps/http-parser/000077500000000000000000000000001312466455500157215ustar00rootroot00000000000000iotjs-1.0/deps/jerry/000077500000000000000000000000001312466455500146035ustar00rootroot00000000000000iotjs-1.0/deps/libtuv/000077500000000000000000000000001312466455500147555ustar00rootroot00000000000000iotjs-1.0/docs/000077500000000000000000000000001312466455500134455ustar00rootroot00000000000000iotjs-1.0/docs/License.md000066400000000000000000000021561312466455500153550ustar00rootroot00000000000000### Introduce License Policy IoT.js is open source software under the [Apache 2.0 license](https://www.apache.org/licenses/LICENSE-2.0). Complete license and copyright information can be found within the code. > Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors > Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ※ [IoT.js Developer's Certificate of Origin 1.0](IoT.js-Developer's-Certificate-of-Origin-1.0) applies from _15th June in 2015_ ### Open Source Software The following Open Source software supports IoT.js: * **_[libuv](https://github.com/libuv/libuv)_** licensed under [MIT License](http://opensource.org/licenses/MIT) iotjs-1.0/docs/README.md000066400000000000000000000012301312466455500147200ustar00rootroot00000000000000Welcome to the IoT.js! * If you would like to try IoT.js, please check [Getting Started](help/Getting-Started.md). * If you would like to jump into IoT.js, please follow [Development Process](help/Development-Process.md) of IoT.js. ### IoT.js - Project Overview > IoT.js is a framework for "Internet of Things" built on > lightweight JavaScript interpreter ['JerryScript'](https://github.com/jerryscript-project/jerryscript) > and libtuv for event driven(non-blocking I/O model) similar to node.js. - [License](License.md)
### [Getting Started](help/Getting-Started.md) - Developer guide ### [Getting Involved](help/Getting-involved.md) ### Roadmap(TBD) iotjs-1.0/docs/api/000077500000000000000000000000001312466455500142165ustar00rootroot00000000000000iotjs-1.0/docs/api/IoT.js-API-ADC.md000066400000000000000000000045701312466455500166500ustar00rootroot00000000000000### Platform Support The following table shows ADC module APIs available for each platform. | | Linux
(Ubuntu) | Raspbian
(Raspberry Pi) | NuttX
(STM32F4-Discovery) | | :---: | :---: | :---: | :---: | | adc.open | O | X | O | | adcpin.read | O | X | O | | adcpin.readSync | O | X | O | | adcpin.close | O | X | O | | adcpin.closeSync | O | X | O | ## Class: ADC This class allows reading analogue data from hardware pins. The hardware pins can be read from or written to, therefore they are called bidirectional IO pins. This module provides the reading part. On NuttX, you have to know the number of pins that is defined on the target board module. For more information, please see the list below. * [STM32F4-discovery](../targets/nuttx/stm32f4dis/IoT.js-API-Stm32f4dis.md#adc-pin) ### new ADC() Returns a new ADC object which can open an ADC pin. ### adc.open(configuration[, callback]) * `configuration` {Object} * `device` {string} Mandatory configuration on Linux. * `pin` {int} Mandatory configuration on NuttX. * `callback` {Function} * `err`: {Error|null} * Returns: `AdcPin` {adc.AdcPin} Opens an ADC pin with the specified configuration. **Example** ```js var Adc = require('adc'); var adc = new Adc(); var adc0 = adc.open({ device: '/sys/devices/12d10000.adc/iio:device0/in_voltage0_raw' }, function(err) { if (err) { throw err; } }); ``` ## Class: ADCPin ### adcpin.read([callback]) * `callback` {Function} * `err`: {Error|null} Reads the analog value from the pin asynchronously. `callback` will be called having read the analog value. **Example** ```js adc0.read(function(err, value) { if (err) { throw err; } console.log('value:', value); }); ``` ### adcpin.readSync() * Returns: `{int}` Analog value. Reads the analog value from the pin synchronously. **Example** ```js var value = adc0.readSync(); console.log('value:', value); ``` ### adcpin.close([callback]) * `callback` {Function} * `err`: {Error|null} Closes ADC pin asynchronously. This function must be called after the work of ADC finished. `callback` will be called after ADC device is released. **Example** ```js adc0.close(function(err) { if (err) { throw err; } }); ``` ### adcpin.closeSync() Closes ADC pin synchronously. This function must be called after the work of ADC finished. **Example** ```js adc0.closeSync(); console.log('adc pin is closed'); ``` iotjs-1.0/docs/api/IoT.js-API-Assert.md000066400000000000000000000115601312466455500175170ustar00rootroot00000000000000### Platform Support The following shows Assert module APIs available for each platform. | | Linux
(Ubuntu) | Raspbian
(Raspberry Pi) | NuttX
(STM32F4-Discovery) | | :---: | :---: | :---: | :---: | | assert.assert | O | O | O | | assert.doesNotThrow | O | O | O | | assert.equal | O | O | O | | assert.fail | O | O | O | | assert.notEqual | O | O | O | | assert.notStrictEqual | O | O | O | | assert.strictEqual | O | O | O | | assert.throws | O | O | O | # Assert Assert module is designed for writing tests for applications. You can access the functions of the module by adding `require('assert')` to your file. ## Class: AssertionError Assert module will produce `AssertionError` in case of an assertion failure. `AssertionError` inherits standard `Error` thus it has properties provided by `Error` object including additional properties. * `actual` {any} This property contains the actual value. * `expected` {any} This property contains the expected value. * `message` {any} The error message, default value is the error itself. * `name` {string} The name is `AssertionError` string. * `operator` {string} This property contains the operator used for comparing `actual` with `expected`. ### assert(value[, message]) * `value` {any} Value to test. * `message` {any} Message displayed in the thrown error. Checks if the `value` is truthy. If it is not, throws an AssertionError, with the given optional `message`. **Example** ```js var assert = require('assert'); assert.assert(1); // OK assert.assert(true); // OK assert.assert(false); // throws "AssertionError: false == true" assert.assert(0); // throws "AssertionError: 0 == true" assert.assert(false, "it's false"); // throws "AssertionError: it's false" ``` ### doesNotThrow(block[, message]) * `block` {Function} * `message` {any} Message to be displayed. Tests if the given `block` does not throw any exception. Otherwise throws an exception with the given optional `message`. **Example** ```js var assert = require('assert'); assert.doesNotThrow( function() { assert.assert(1); } ); // OK assert.doesNotThrow( function() { assert.assert(0); } ) // throws "AssertionError: Got unwanted exception." ``` ### equal(actual, expected[, message]) * `actual` {any} The actual value. * `expected` {any} The expected value. * `message` {any} Message to be displayed. Tests if `actual == expected` is evaluated to `true`. Otherwise throws an exception with the given optional `message`. **Example** ```js var assert = require('assert'); assert.equal(1, 1); assert.equal(1, '1'); ``` ### fail(actual, expected, message, operator) * `actual` {any} The actual value. * `expected` {any} The expected value. * `message` {any} Message to be displayed. * `operator` {string} The operator. Throws an `AssertionError` exception with the given `message`. **Example** ```js var assert = require('assert'); assert.fail(1, 2, undefined, '>'); // AssertionError: 1 > 2 ``` ### notEqual(actual, expected[, message]) * `actual` {any} The actual value. * `expected` {any} The expected value. * `message` {any} Message to be displayed. Tests if `actual != expected` is evaluated to `true`. Otherwise throws an exception with the given optional `message`. **Example** ```js var assert = require('assert'); assert.notEqual(1, 2); ``` ### notStrictEqual(actual, expected[, message]) * `actual` {any} The actual value. * `expected` {any} The expected value. * `message` {any} Message to be displayed. Tests if `actual !== expected` is evaluated to `true`. Otherwise throws an exception with the given optional `message`. **Example** ```js var assert = require('assert'); assert.notStrictEqual(1, 2); // OK assert.notStrictEqual(1, 1); // AssertionError: 1 !== 1 assert.notStrictEqual(1, '1'); // OK ``` ### strictEqual(actual, expected[, message]) * `actual` {any} The actual value. * `expected` {any} The expected value. * `message` {any} Message to be displayed. Tests if `actual === expected` is evaluated to `true`. Otherwise throws an exception with the given optional `message`. **Example** ```js var assert = require('assert'); assert.strictEqual(1, 1); // OK assert.strictEqual(1, 2); // AssertionError: 1 === 2 assert.strictEqual(1, '1'); // AssertionError: 1 === '1' ``` ### throws(block[, expected, message]) * `block` {Function} The function that throws an error. * `expected` {Function} The expected error type. * `message` {any} Message to be displayed. Tests if the given `block` throws an `expected` error. Otherwise throws an exception with the given optional `message`. **Example** ```js var assert = require('assert'); assert.throws( function() { assert.equal(1, 2); }, assert.AssertionError ); // OK assert.throws( function() { assert.equal(1, 1); }, assert.AssertionError ); // Uncaught error: Missing exception assert.throws( function() { assert.equal(1, 2); }, TypeError ); // AssertionError ``` iotjs-1.0/docs/api/IoT.js-API-BLE.md000066400000000000000000000120321312466455500166530ustar00rootroot00000000000000### Platform Support The following shows BLE module APIs available for each platform. | | Linux
(Ubuntu) | Raspbian
(Raspberry Pi) | NuttX
(STM32F4-Discovery) | | :---: | :---: | :---: | :---: | | ble.startAdvertising | O | O | X | | ble.stopAdvertising | O | O | X | | ble.setServices | O | O | X | # BLE - Bluetooth Low Energy ### Event: 'advertisingStart' * `callback` {Function} * error {Error} Emitted when advertisement starts. **Example** ```js var ble = require('ble'); ble.on('advertisingStart', function(error) { console.log('on -> advertisingStart: ' + (error ? 'error ' + error : 'success')); if (!error) { ble.setServices([ // service data ]); } }); ``` ### Event: 'stateChange' * `callback` {Function} * `state` {String} Can be 'unknown', 'resetting', 'unsupported', 'unauthorized', 'poweredOff' or 'poweredOn'. Emitted when adapter state is changed. **Example** ```js var ble = require('ble'); ble.on('stateChange', function(state){ console.log('onStateChange: ' + state); if (state == 'poweredOn') { ble.startAdvertising('iotjs', ['data'], function(err) { }); } else { ble.stopAdvertising(function(err) { }); } }); ``` ### ble.startAdvertising(name, serviceUuids[, callback]) * `name` {string} Maximum 26 bytes. * `serviceUuids` {Array[String]} * 1 128-bit service UUID * 1 128-bit service UUID + 2 16-bit service UUIDs * 7 16-bit service UUID * `callback` {Function} Error handler. * `error` {Error} Starts advertising. `ble.state` must be in poweredOn state before advertising is started. `ble.on('stateChange', callback(state));` can be used to register for state change events. **Example** ```js var name = 'name'; var serviceUuids = ['fffffffffffffffffffffffffffffff0'] ble.startAdvertising(name, serviceUuids[, callback(error)]); ``` ### ble.stopAdvertising(callback) * `callback` {Function} Error handler. * `error` {Error} Stops advertising. ### ble.setServices(services[, callback]) * `services` {Array[PrimaryService]} * `callback` {Function} Error handler. * `error` {Error} Sets the primary services available on the peripheral. ## Class: Descriptor Descriptors are defined attributes that describe a characteristic value. ### new Descriptor(options) * `options` {Object} * `uuid:` {string} A Universally Unique ID (UUID) is a 16 or 128-bit hex value used to identify the type of every attribute. * `value` {string|Buffer} **Example** ```js var descriptor = new Descriptor({ uuid: '2901', value: 'value' }); ``` ## Class: Characteristic Characteristics are defined attribute types that contain a single logical value. ### new Characteristic(options) * `options` {Object} * `uuid:` {string} A Universally Unique ID (UUID) is a 16 or 128-bit hex value used to identify the type of every attribute. * `properties` {Array[string]} Can be a combination of 'read', 'write', 'writeWithoutResponse', 'notify' and 'indicate'. * `secure` {Array[string]} Enables security for properties, can be a combination of 'read', 'write', 'writeWithoutResponse', 'notify' and 'indicate'. * `value` {Buffer} * `descriptors` {Array[Descriptor]} * `onReadRequest` {Function} Read request handler. (optional) * `offset` {number} (0x0000 - 0xffff) * `callback` {Function} * `result` {Characteristic.RESULT_*} * `data` {Buffer} * `onWriteRequest` {Function} Write request handler. (optional) * `data` {Buffer} * `offset` {number} (0x0000 - 0xffff) * `withoutResponse` {boolean} * `callback` {Function} * `result` {Characteristic.RESULT_*} * `onSubscribe` {Function} Notify/indicate subscribe handler. (optional) * `maxValueSize` {number} Maximum data size. * `updateValueCallback` {Function} * `onUnsubscribe` {Function} Notify/indicate unsubscribe handler. (optional) * `onNotify` {Function} Notify sent handler. (optional) * `onIndicate` {Function} Indicate confirmation received handler. (optional) Returns: {Characteristic} **Example** ```js var characteristic = new Characteristic({ uuid: 'fffffffffffffffffffffffffffffff1', // or 'fff1' for 16-bit properties: ['read', 'write'], secure: [], value: null, descriptors: [descriptor], onReadRequest: null, onWriteRequest: null, onSubscribe: null, onUnsubscribe: null, onNotify: null, onIndicate: null }); ``` ### Characteristic.RESULT_SUCCESS ### Characteristic.RESULT_INVALID_OFFSET ### Characteristic.RESULT_INVALID_ATTRIBUTE_LENGTH ### Characteristic.RESULT_UNLIKELY_ERROR ## Class: PrimaryService PrimaryService is a collection of characteristics and relationships to other services that encapsulate the behavior of part of a device. ### new PrimaryService(options) * `options` {Object} * `uuid` {string} A Universally Unique ID (UUID) is a 16 or 128-bit hex value used to identify the type of every attribute. * `characteristics` {Array[Characteristic]} **Example** ```js var primaryService = new PrimaryService({ uuid: 'fffffffffffffffffffffffffffffff0', // or 'fff0' for 16-bit characteristics: [ // see Characteristic for data type ] }); ``` iotjs-1.0/docs/api/IoT.js-API-Buffer.md000066400000000000000000000315231312466455500174700ustar00rootroot00000000000000### Platform Support The following shows Buffer module APIs available for each platform. | | Linux
(Ubuntu) | Raspbian
(Raspberry Pi) | NuttX
(STM32F4-Discovery) | | :---: | :---: | :---: | :---: | | buf.compare | O | O | O | | buf.copy | O | O | O | | buf.equals | O | O | O | | buf.fill | O | O | O | | buf.slice | O | O | O | | buf.toString | O | O | O | | buf.write | O | O | O | | buf.writeUInt8 | O | O | O | | buf.writeUInt16LE | O | O | O | | buf.writeUInt32LE | O | O | O | | buf.readInt8 | O | O | O | | buf.readUInt8 | O | O | O | | buf.readUInt16LE | O | O | O | # Buffer Buffer class is a global type with various constructors and accessors. IoT.js provides Buffer to manipulate binary data. Currently buffer has a pure ES5 compatible implementation, but this might be reworked to use UInt8Array in the future. **Example** ```js var Buffer = require('buffer'); // Creates a zero-filled Buffer of length 10. var buf1 = Buffer(10); // Creates a Buffer containing [0x1, 0x2, 0x3]. var buf2 = Buffer([1, 2, 3]); // Creates a Buffer containing UTF-8 bytes [0x74, 0xc3, 0xa9, 0x73, 0x74]. var buf3 = Buffer('tést'); ``` ### new Buffer(size) * `size` {integer} Size of the new buffer. Creates a new buffer of `size` bytes and initialize its data to zero. **Example** ```js var Buffer = require('buffer'); var buffer = new Buffer(5); ``` ### new Buffer(buffer) * `buffer` {Buffer} Source buffer. Creates a copy of an existing buffer. The buffer data is not shared between the two buffers. **Example** ```js var Buffer = require('buffer'); var buffer1 = new Buffer(5); var buffer2 = new Buffer(buffer1); ``` ### new Buffer(str[, encoding]) * `str` {string} Source string. * `encoding` {string} Encoding format. Creates a new buffer which contains the CESU-8 representation of the `str` string argument. If `encoding` optional argument is present its value must be `hex`. When this encoding is specified the `str` argument must be a sequence of hexadecimal digit pairs, and these pairs are converted to bytes. **Example** ```js var Buffer = require('buffer'); var buffer = new Buffer(String.fromCharCode(65)) // prints: 1 console.log(buffer); var buffer = new Buffer(String.fromCharCode(128)) // prints: 2 console.log(buffer); var buffer = new Buffer(String.fromCharCode(2048)) // prints: 3 console.log(buffer); var buffer = new Buffer('4142', 'hex') // prints: AB console.log(buffer); ``` ### new Buffer(array) * `array` {Array} Array of numbers. Creates a new Buffer from an array of numbers. The numbers are converted to integers first and their modulo 256 remainder is used for constructing the buffer. **Example** ```js var buffer = new Buffer([65, 256 + 65, 65 - 256, 65.1]) // prints: AAAA console.log(buffer); ``` ### Buffer.byteLength(str, encoding) * `str` {string} Source string. * `encoding` {string} String encoding. * Returns: {integer} Byte length of source string. Returns the byte length of a buffer representing the value of the string argument encoded with encoding. The effect is the same as: ```js return new Buffer(str, encoding).length; ``` **Example** ```js var Buffer = require('buffer'); // prints: 1 console.log(Buffer.byteLength(String.fromCharCode(65))); // prints: 2 console.log(Buffer.byteLength(String.fromCharCode(128))); // prints: 3 console.log(Buffer.byteLength(String.fromCharCode(2048))); // prints: 2 console.log(Buffer.byteLength('4142', 'hex')); ``` ### Buffer.concat(list) * `list` {Array} An array of `Buffer` objects. * Returns: {Buffer} Concatenated buffer. Returns the concatenation of the `Buffer` objects provided in the `list` array. **Example** ```js var Buffer = require('buffer'); var buffer = Buffer.concat([ new Buffer('He'), new Buffer('llo'), new Buffer(' wo'), new Buffer('rld') ]) // prints: Hello world console.log(buffer); ``` ### Buffer.isBuffer(obj) * `obj` {Object} * Returns: {boolean} Returns `true` if `obj` is an instance of `Buffer`. Returns `false` otherwise. **Example** ```js var Buffer = require('buffer'); // prints: true console.log(Buffer.isBuffer(new Buffer(1))); // prints: false console.log(Buffer.isBuffer('str')); ``` ### buf.length * {integer} Returns the capacity of the buffer in bytes. Note: when the buffer is converted to another type (e.g. String) the length of the converted value might be different from this value. **Example** ```js var Buffer = require('buffer'); var buffer = new Buffer([0xc8, 0x80]) // prints: 2 console.log(buffer.length); var str = buffer.toString(); // prints: 1 console.log(str.length); ``` ### buf.compare(otherBuffer) * `otherBuffer` {Buffer} The right-hand side of the comparison. * Returns: {integer} This function performs a lexicographic comparison between two buffers. It returns with `0` if the two buffers are the same. Otherwise it returns with `-1` if the first different byte is lower for `buf`, and `1` if the byte is higher. If the length of the two buffers are different, the comparison is performed until the lower length is reached. If all bytes are the same the function returns with `-1` if `buf.length` is less than `otherBuffer.length` and `1` otherwise. **Example** ```js var Buffer = require('buffer'); var buffer1 = new Buffer('AB'); var buffer2 = new Buffer('A'); var buffer3 = new Buffer('B'); // prints: 0 console.log(buffer1.compare(buffer1)); // prints: 1 console.log(buffer1.compare(buffer2)); // prints: -1 console.log(buffer1.compare(buffer3)); ``` ### buf.copy(targetBuffer[, targetStart[, sourceStart[, sourceEnd]]]) * `targetBuffer` {Buffer} The buffer to be modified. * `targetStart` {Integer} **Default:** `0` * `sourceStart` {integer} **Default:** `0` * `sourceEnd` {integer} **Default:** `buf.length` * Returns: {integer} The number of bytes copied. Copy a sequence of bytes from `buf` buffer to `targetBuffer` buffer. The source byte range is specified by `sourceStart` and `sourceEnd` and the destination byte offset is specified by `targetStart`. Only the `targetBuffer` is modified. **Example** ```js var Buffer = require('buffer'); var buffer1 = new Buffer('Hello XY world!'); var buffer2 = new Buffer(''); buffer2.copy(buffer1, 6, 1, 3); // prints: Hello JS world! console.log(buffer1); ``` ### buf.equals(otherBuffer) * `otherBuffer` {Buffer} The right-hand side of the comparison. * Returns: {boolean} Returns `true` if `this` and `otherBuffer` have exactly the same bytes. Returns `false` otherwise. The effect is the same as: ```js return buf.compare(otherBuffer) == 0; ``` **Example** ```js var Buffer = require('buffer'); var buffer1 = new Buffer('AB'); var buffer2 = new Buffer('4142', 'hex'); var buffer3 = new Buffer('A'); // prints: true console.log(buffer1.equals(buffer2)); // prints: false console.log(buffer1.equals(buffer3)); ``` ### buf.fill(value) * `value` {integer} All bytes are set to this value. * Returns: {Buffer} The original buffer. Set all bytes of the buffer to value. The value is converted to integer first and its modulo 256 remainder is used for updating the buffer. Returns with `buf`. **Example** ```js var Buffer = require('buffer'); var buffer = new Buffer('Hello'); buffer.fill(65); // prints: AAAAA console.log(buffer); buffer.fill(66 - 256); // prints: BBBBB console.log(buffer); ``` ### buf.slice([start[, end]]) * `start` {integer} **Default:** `0` * `end` {integer} **Default:** `buf.length` * Returns: {Buffer} A newly created buffer. This function returns with a newly created buffer which contains the bytes of the `buf` buffer between `start` and `end`. **Example** ```js var Buffer = require('buffer'); var buffer = new Buffer('This is JavaScript!!!'); // prints: JavaScript console.log(buffer.slice(8, 18)); ``` ### buf.toString([start[, end]]) * `start` {integer} **Default:** `0` * `end` {integer} **Default:** `buffer.length` * Returns: {string} Returns a string created from the bytes stored in the buffer. By passing `start` and `end` the conversion can be limited to a subset of the `buf` buffer. If a single `hex` string is passed to the function, the whole buffer is converted to hexadecimal data. **Example** ```js var Buffer = require('buffer'); var buffer = new Buffer('DEFG'); // prints: EF console.log(buffer.toString(1, 3)); // prints: 44454647 console.log(buffer.toString('hex')); ``` ### buf.write(string[, offset[, length]]) * `string` {string} Data to be written into buffer. * `offset` {integer} Start position of writing. **Default:** `0` * `length` {integer} How many bytes to write. **Default:** `buffer.length - offset`. * Returns: {integer} Total number of bytes written. Writes `string` into the `buf` buffer. The start position of the writing can be specified by `offset` and the maximum number of updated bytes can be limited by `length`. Returns total number of bytes written to the buffer. **Example** ```js var Buffer = require('buffer'); var buffer = new Buffer('......'); buffer.write('AB'); buffer.write('XY', 3); // prints: AB.XY. console.log(buffer); var buffer = new Buffer('......'); buffer.write('ABCDEF', 1, 3); // prints: .ABC.. console.log(buffer); ``` ### buf.writeUInt8(value, offset[, noAssert]) * `value` {integer} Number to be written into the buffer. * `offset` {integer} Start position of the writing. * `noAssert` {boolean} Skip argument validation. **Default:** `false` * Returns: {number} Offset plus the number of bytes written. Writes `value` into the buffer starting from `offset` position. The `value` must be a valid 8-bit unsigned integer. If `noAssert` is set and the value is outside of the expected range or the offset is higher than the size of the buffer the operation is undefined. **Example** ```js var Buffer = require('buffer'); var buffer = new Buffer('....'); // prints: 3 console.log(buffer.writeUInt8(65, 2)); // prints: ..A. console.log(buffer); ``` ### buf.writeUInt16LE(value, offset[, noAssert]) * `value` {integer} Number to be written into the buffer. * `offset` {integer} Start position of the writing. * `noAssert` {boolean} Skip argument validation. **Default:** `false` * Returns: {integer} Offset plus the number of bytes written. Writes `value` into the buffer starting from `offset` position with little endian format. The `value` must be a valid 16-bit unsigned integer. If `noAssert` is set and the value is outside of the expected range or the offset is higher than the size of the buffer the operation is undefined. **Example** ```js var Buffer = require('buffer'); var buffer = new Buffer('......'); // prints: 3 console.log(buffer.writeUInt16LE(0x4142, 1)); // prints .BA... console.log(buffer); ``` ### buf.writeUInt32LE(value, offset[, noAssert]) * `value` {integer} Number to be written into the buffer. * `offset` {integer} Start position of the writing. * `noAssert` {boolean} Skip argument validation. **Default:** `false` * Returns: {integer} Offset plus the number of bytes written. Writes `value` into the buffer starting from `offset` position with little endian format. The `value` must be a valid 32-bit unsigned integer. If `noAssert` is set and the value is outside of the expected range or the offset is higher than the size of the buffer the operation is undefined. **Example** ```js var Buffer = require('buffer'); var buffer = new Buffer('......'); // prints: 5 console.log(buffer.writeUInt32LE(0x41424344, 1)); // prints: .DCBA. console.log(buffer); ``` ### buf.readInt8(offset[, noAssert]) * `offset` {number} Start position of buffer for reading. * `noAssert` {boolean} Skip offset validation. **Default:** `false` * Returns: {number} Reads a signed 8-bit integer from `buf` buffer starting from `offset` position. If `noAssert` is set and the offset is higher than the size of the buffer the result is undefined. **Example** ```js var Buffer = require('buffer'); var buffer = new Buffer('ABCDEF'); // prints: 42 console.log(buffer.readUInt8(1).toString(16)); ``` ### buf.readUInt8(offset[, noAssert]) * `offset` {integer} Start position of the reading. * `noAssert` {boolean} Skip argument validation. **Default:** `false` * Returns: {number} Reads an unsigned 8-bit integer from `buf` buffer starting from `offset` position. If `noAssert` is set and the offset is higher than the size of the buffer the result is undefined. **Example** ```js var Buffer = require('buffer'); var buffer = new Buffer('ABCDEF'); // prints: 42 console.log(buffer.readUInt8(1).toString(16)); ``` ### buf.readUInt16LE(offset[, noAssert]) * `offset` {number} Start position of buffer for reading. * `noAssert` {boolean} Skip offset validation. **Default:** `false` * Returns: {number} Reads an unsigned 16-bit integer from `buf` buffer starting from `offset` position with little endian format. If `noAssert` is set and the offset is higher than the size of the buffer the result is undefined. **Example** ```js var Buffer = require('buffer'); var buffer = new Buffer('ABCDEF'); // prints: 4342 console.log(buffer.readUInt16LE(1).toString(16)); ``` iotjs-1.0/docs/api/IoT.js-API-DGRAM.md000066400000000000000000000251701312466455500171120ustar00rootroot00000000000000### Platform Support The following shows dgram module APIs available for each platform. | | Linux
(Ubuntu) | Raspbian
(Raspberry Pi) | NuttX
(STM32F4-Discovery) | | :---: | :---: | :---: | :---: | | dgram.createSocket | O | O | △ ¹ | | dgram.Socket.addMembership | O | O | X | | dgram.Socket.address | O | O | X | | dgram.Socket.bind | O | O | △ ¹ | | dgram.Socket.close | O | O | △ ² | | dgram.Socket.dropMembership | O | O | X | | dgram.Socket.send | O | O | △ ¹ | | dgram.Socket.setBroadcast | O | O | X | | dgram.Socket.setMulticastLoopback | O | O | X | | dgram.Socket.setMulticastTTL | X | X | X | | dgram.Socket.setTTL | O | O | X | 1. On NuttX/STM32F4-Discovery, even a couple of sockets/server/requests might not work properly. 2. On NuttX/STM32F4-Discovery, close() may block due to a bug in poll(). # Dgram The dgram module provides an implementation of UDP Datagram sockets. The following example creates a UDP Datagram server. **Example** ```js var dgram = require('dgram'); var server = dgram.createSocket('udp4'); server.on('error', function (err) { console.log('Error: ' + err); server.close(); }); server.on('message', function(msg, rinfo) { // prints: message received console.log('server got: ' + msg); }); server.on('listening', function() { console.log('server listening at ' + server.address().port); }); server.bind(41234); ``` ### dgram.createSocket(options[, callback]) * `options` {Object} * `type` {string} * `reuseAddr` {boolean} * `callback` {Function} (optional) Creates a new `dgram.Socket` object. The type of the connection is specified by `options.type`. Currently only `udp4` is supported. If `reuseAddr` is true the `socket.bind()` call reuses the address even if this address has been bound by another process. The optional 'callback' function is attached to the [`'message'`](#event-message) event. **Example** ```js var dgram = require('dgram'); var server = dgram.createSocket({ type: 'udp4', reuseAddr: true}); ``` ### dgram.createSocket(type[, callback]) * `type` {string} * `callback` {Function} (optional) Creates a new `dgram.Socket` object. The type of the connection is specified by the `type` argument. Currently only `udp4` is supported. The optional 'callback' function is attached to the [`'message'`](#event-message) event. **Example** ```js var dgram = require('dgram'); var server = dgram.createSocket('udp4'); ``` ## Class: dgram.Socket The `dgram.Socket` object is an `EventEmitter` that encapsulates the datagram functionality. New instances of `dgram.Socket` are created using `dgram.createSocket()`. The new keyword must not be used to create dgram.Socket instances. Supported events: ### Event: 'close' The `'close'` event is emitted after a socket is closed with `close()`. Once triggered, no new `'message'` events will be emitted on this socket. ### Event: 'error' * `exception` {Error} The `'error'` event is emitted whenever any error occurs. A single Error object is passed to the event handler. ### Event: 'listening' The `'listening'` event is emitted whenever a socket begins listening for datagram messages. This occurs as soon as UDP sockets are created. ### Event: 'message' * `msg` {Buffer} The message. * `rinfo` {Object} Remote address information. * `address` {string} The sender address. * `family` {string} The address family ('IPv4'). * `port` {number} The sender port. * `size` {number} The message size. The `'message'` event is emitted when a new datagram is received by the socket. The `msg` argument contains the message data and the `rinfo` argument contains the message properties. ### socket.addMembership(multicastAddress[, multicastInterface]) * `multicastAddress` {string} * `multicastInterface` {string} Joins the multicast group specified by `multicastAddress` and `multicastInterface`. If `multicastInterface` is undefined the operating system will choose one add interface and will add membership to it. To add membership to every available interface, call addMembership multiple times, once per interface. **Example** ```js var dgram = require('dgram'); var multicast_address = '230.255.255.250'; var server = dgram.createSocket('udp4'); server.bind(12345 /* port */, function() { server.addMembership(multicast_address); }); ``` ### socket.address() * Returns: {Object} Returns an object with the properties `address`, `port` and `family`. **Example** ```js var dgram = require('dgram'); var server = dgram.createSocket('udp4'); server.on('listening', function () { var address = server.address(); // prints: address and port of the server address console.log('Addr: ' + address.address + ' port: ' + address.port); }); server.bind(12345 /* port */); ``` ### socket.bind([port][, address][, bindListener]) * `port` {number} * `address` {string} **Default:** `0.0.0.0` * `bindListener` {Function} Assign the `port` and `address` to an UDP socket. If `port` is not specified the operating system selects a random unused port. The optional 'bindListener' function is attached to the [`'listening'`](#event-listening) event. **Example** ```js var dgram = require('dgram'); var socket = dgram.createSocket({ type: 'udp4', reuseAddr: true }); var port = 12345; socket.bind(port, function () { // prints: Listening for packets console.log('Listening for packets'); }); ``` ### socket.bind(options[, bindListener]) * `options` {Object} * `port` {number} * `address` {string} **Default:** `0.0.0.0` * `bindListener` {Function} Assign `options.port` and `options.address` to an UDP socket. If `options.port` is not specified the operating system selects a random unused port. The optional 'bindListener' function is attached to the [`'listening'`](#event-listening) event. **Example** ```js var dgram = require('dgram'); var socket = dgram.createSocket({ type: 'udp4', reuseAddr: true }); socket.bind({ port:12345 }, function () { // prints: Listening for packets console.log('Listening for packets'); }); ``` ### socket.close([closeListener]) * `closeListener` {Function} Close the underlying socket and stop listening for data on it. The optional 'closeListener' function is attached to the [`'close'`](#event-close) event. **Example** ```js var dgram = require('dgram'); var socket = dgram.createSocket({ type: 'udp4', reuseAddr: true }); // prints: Close! socket.close(function () { // prints: Socket is closed console.log('Socket is closed'); }); ``` ### socket.dropMembership(multicastAddress[, multicastInterface]) * `multicastAddress` {string} * `multicastInterface` {string} Leaves for socket the given multicast group with given `multicastAddress` and `multicastInterface`. **Example** ```js var dgram = require('dgram'); var server = dgram.createSocket('udp4'); var multicast_address = '230.255.255.250'; server.bind(12345 /* port */, function() { server.addMembership(multicast_address); }); server.on('message', function(data, rinfo) { // Drop membership when a message arrived. server.dropMembership(multicast_address); }); ``` ### socket.setBroadcast(flag) * `flag` {boolean} Sets or clears the `SO_BROADCAST` socket option. When `flag` is true UDP packets may be sent to a local interface's broadcast address. **Example** ```js var dgram = require('dgram'); var socket = dgram.createSocket({ type: 'udp4', reuseAddr: true }); var port = 41237; socket.bind(port, function() { socket.setBroadcast(true); }); ``` ### socket.send(msg, [offset, length,] port [, address] [, sendListener]) * `msg` {Buffer|string|array} * `offset` {integer} Only valid if `msg` is Buffer. * `length` {integer} Only valid if `msg` is Buffer. * `port` {integer} * `address` {string} **Default:** `127.0.0.1` or `::1` * `sendListener` {Function} * `Error` {Object|null} * `code` {string} Currently it is always `"error"`. * `errno` {string} Same as `code`. * `syscall` {integer} * `address` {string} * `port` {integer} * `length` {integer} Length of data. Transmits a message to the destination socket specified by `address` and `port` arguments. The `msg` argument contains the data to be sent. It can be a {Buffer}, a {string} converted to UTF-8 bytes, or an array of {Buffer} and {string} values. In the latter case the items of the array are concatenated into a single {Buffer} before sending. If send operation is successfully completed, `sendListener` will be called with `null` and the length of data. Otherwise an Error {Object} is passed along with the length of data. **Example** ```js var dgram = require('dgram'); var socket = dgram.createSocket({ type: 'udp4', reuseAddr: true }); var broadcast_address = '255.255.255.255'; var port = 41237; socket.bind(port, function() { socket.setBroadcast(true); socket.send('Hello IoT.js', port, broadcast_address); }); ``` ### socket.sendto(msg, offset, length, port [, address] [, sendListener]) * `msg` {Buffer|string|array} * `offset` {integer} * `length` {integer} * `port` {integer} * `address` {string} **Default:** `127.0.0.1` or `::1` * `sendListener` {Function} Legacy function. It is the same as [`socket.send`](#socket-send-msg-offset-length-port-address-sendListener) except `offset` and `length` arguments are mandatory. ### socket.setMulticastLoopback(flag) * `flag` {boolean} Sets or clears the `IP_MULTICAST_LOOP` socket option. When `flag` is `true` multicast packets will also be received on the local interface. **Example** ```js var dgram = require('dgram'); var socket = dgram.createSocket({ type: 'udp4', reuseAddr: true }); var port = 41237; socket.bind(port, function() { socket.setMulticastLoopback(true); }); ``` ### socket.setMulticastTTL(ttl) * `ttl` {integer} This value must be between 0 and 255. Sets the `IP_MULTICAST_TTL` socket option which pecifies the number of IP hops that a packet is allowed to travel through, specifically for multicast traffic. Each router or gateway that forwards a packet decrements its TTL. When TTL reaches zero the packet is not forwarded anymore. The default on most systems is 1 but can vary. **Example** ```js var dgram = require('dgram'); var socket = dgram.createSocket({ type: 'udp4', reuseAddr: true }); var port = 41237; socket.bind(port, function() { socket.setMulticastTTL(1); }); ``` ### socket.setTTL(ttl) * `ttl` {integer} This value must be between 1 and 255. Sets the `IP_TTL` socket option which specifies the number of IP hops that a packet is allowed to travel through. Each router or gateway that forwards a packet decrements its TTL. When TTL reaches zero the packet is not forwarded anymore. The default on most systems is 64 but can vary. **Example** ```js var dgram = require('dgram'); var socket = dgram.createSocket({ type: 'udp4', reuseAddr: true }); var port = 41237; socket.bind(port, function() { socket.setTTL(64); }); ``` iotjs-1.0/docs/api/IoT.js-API-DNS.md000066400000000000000000000054641312466455500167100ustar00rootroot00000000000000### Platform Support The following shows dns module APIs available for each platform. | | Linux
(Ubuntu) | Raspbian
(Raspberry Pi) | NuttX
(STM32F4-Discovery) | | :---: | :---: | :---: | :---: | | dns.lookup | O | O | X | ※ dns.lookup currently only returns IPv4 addresses. Support for IPv6 addresses are on the roadmap. # DNS The `dns` module provides a method to perform host name resolution. The functionality is implemented on top of the underlying operation system facilities. Please see [Implementation considerations section](#implementation-considerations). The following properties are flags which can be passed as hints for the [`dns.lookup()`](#dnslookuphostname-options-callback) method. ### dns.ADDRCONFIG * `{number}` Returned address types are determined by the types of addresses supported by the current system. ### dns.V4MAPPED * `{number}` If the IPv6 family was specified, but no IPv6 addresses were found, then return IPv4 mapped IPv6 addresses. ### dns.lookup(hostname[, options], callback) * `hostname` {string} Hostname to be resolved. * `options` {Object|number} * `family` {number} The record family. If specified must be 4. Specifies that IPv4 addresses should be returned. * `hints` {number} One or more supported getaddrinfo flags. Multiple flags may be passed by bitwise `OR`ing their values. * `callback` {Function} * `err` {Error|null} If there is no error the value is `null`. * `address` {string} A string representation of an IPv4 address. * `family` {number} 4, denoting the family of `address`. Resolves a hostname (e.g. `iotjs.net`) into the first found A (IPv4) or AAAA (IPv6) record. All `option` properties are option. If `option` is a number, then it must be `4`. If `options` is not provided, then IPv4 addresses are returned if found. On error, `err` is an `Error` object where `err.code` is the error code returned by the underlying system call. The `dns.lookup()` does not necessarily do DNS requests to resolve a hostname. The implementation uses an operating system facility to associate names with addresses. Please read the [Implementation considerations section](#implementation-considerations) for more system dependent information. **Example** ```js var dns = require('dns'); dns.lookup ('localhost', 4, function(err, ip, family) { console.log('ip: ' + ip + ' family: ' + family); }); // ip: 127.0.0.1 family: 4 var options = { family: 4, hints: dns.ADDRCONFIG, }; dns.lookup ('iotjs.net', options, function(err, ip, family) { console.log('ip: ' + ip + ' family: ' + family); }); // ip: 192.30.252.154 family: 4 ``` # Implementation considerations The current implementation only supports host name resolution to IPv4 addresses. On NuttX currently only valid IPv4 addresses are allowed for the [`dns.lookup()`](#dnslookuphostname-options-callback) method. iotjs-1.0/docs/api/IoT.js-API-Events.md000066400000000000000000000123061312466455500175210ustar00rootroot00000000000000### Platform Support The following shows Event module APIs available for each platform. | | Linux
(Ubuntu) | Raspbian
(Raspberry Pi) | NuttX
(STM32F4-Discovery) | | :---: | :---: | :---: | :---: | | emitter.addListener | O | O | O | | emitter.on | O | O | O | | emitter.emit | O | O | O | | emitter.once | O | O | O | | emitter.removeListener | O | O | O | | emitter.removeAllListeners | O | O | O | # Events IoT.js is based on event-driven programming where objects (called "emitters") periodically emit named events. # Class: EventEmitter The `events.EventEmitter` plays a role as base class for "emitters". User application would not directly creates an instance of `EventEmitter` since `EventEmitter` is an abstract trait which defines its behavior and grants to sub-classes. ### new EventEmitter() * Returns {events.EventEmitter}. Returns with a new EventEmitter object. **Example** ```js var EventEmitter = require('events').EventEmitter; var emitter = new EventEmitter(); ``` ### emitter.addListener(event, listener) * `event` {string} The name of the event. * `listener` {Function} The callback function. * `args` {any}. * Returns `emitter` {events.EventEmitter}. It is an alias for `emitter.on(eventName, listener)`. Adds the `listener` callback function to the end of the listener's list for the given `event`. No checks are made to see if the `listener` has already been added. In case of multiple calls the `listener` will be added and called multiple times. **Example** ```js var EventEmitter = require('events').EventEmitter; var emitter = new EventEmitter(); var eventSequence = ''; var listener1 = function() { eventSequence += '2'; }; emitter.addListener('test', listener1); emitter.addListener('test', listener1); emitter.emit('test'); console.log(eventSequence); // prints '22' ``` ### emitter.on(event, listener) * `event` {string} The name of the event. * `listener` {Function} The callback function. * `args` {any}. * Returns `emitter` {events.EventEmitter}. Adds the `listener` callback function to the end of the listener's list for the given `event`. No checks are made to see if the `listener` has already been added. In case of multiple calls the `listener` will be added and called multiple times. **Example** ```js var EventEmitter = require('events').EventEmitter; var emitter = new EventEmitter(); emitter.on('event', function() { console.log('emit event'); }); emitter.emit('event'); ``` ### emitter.emit(event[, args..]) * `event` {string} The name of the event. * `args` {any}. * Returns {boolean}. Synchronously calls each of the listeners registered for the `event`, in the order they were registered, passing the supplied arguments to each. Returns true if the event had listeners, false otherwise. **Example** ```js var EventEmitter = require('events').EventEmitter; var emitter = new EventEmitter(); emitter.addListener('event', function() { console.log('emit event'); }); emitter.emit('event'); // true emitter.emit('not_an_event'); // false ``` ### emitter.once(event, listener) * `event` {string} The name of the event. * `listener` {Function} The callback function. * `args` {any}. * Returns `emitter` {events.EventEmitter}. Adds the `listener` as a one time listener for the `event`. Using this method, it is possible to register a listener that is called at most once for a particular `event`. The listener will be invoked only once, when the first `event` is emitted. **Example** ``` js var EventEmitter = require('events').EventEmitter; var assert = require('assert'); var emitter = new EventEmitter(); var onceCnt = 0; emitter.once('once', function() { onceCnt += 1; }); assert.equal(onceCnt, 0); emitter.emit('once'); assert.equal(onceCnt, 1); emitter.emit('once'); assert.equal(onceCnt, 1); ``` ### emitter.removeListener(event, listener) * `event` {string} The name of the event. * `listener` {Function} The callback function. * `args` {any}. * Returns `emitter` {events.EventEmitter}. Removes `listener` from the list of event listeners. If you add the same `listener` multiple times, this removes only one instance of them. **Example** ```js var EventEmitter = require('events').EventEmitter; var emitter = new EventEmitter(); var listener = function() { console.log('listener'); }; emitter.addListener('event', listener); emitter.removeListener('event', listener); ``` ### emitter.removeAllListeners([event]) * `event` {string} The name of the event. * Returns `emitter` {events.EventEmitter}. Removes all listeners. If `event` was specified, it only removes the listeners for that event. **Example** ``` js var EventEmitter = require('events').EventEmitter; var emitter = new EventEmitter(); function removableListener() { console.log("listener called"); } emitter.addListener('event1', removableListener); emitter.addListener('event2', removableListener); emitter.addListener('event2', removableListener); emitter.addListener('event3', removableListener); emitter.removeAllListeners('event2'); var res = emitter.emit('event2'); // res == false res = emitter.emit('event1'); // res == true, prints "listener called" emitter.removeAllListeners(); res = emitter.emit('event1'); // res == false res = emitter.emit('event3'); // res == false ``` iotjs-1.0/docs/api/IoT.js-API-File-System.md000066400000000000000000000336371312466455500204300ustar00rootroot00000000000000### Platform Support The following shows fs module APIs available for each platform. | | Linux
(Ubuntu) | Raspbian
(Raspberry Pi) | NuttX
(STM32F4-Discovery) | | :---: | :---: | :---: | :---: | | fs.close | O | O | O | | fs.closeSync | O | O | O | | fs.exists | O | O | O | | fs.existsSync | O | O | O | | fs.fstat | O | O | X | | fs.fstatSync | O | O | X | | fs.mkdir | O | O | O | | fs.mkdirSync | O | O | O | | fs.open | O | O | O | | fs.openSync | O | O | O | | fs.read | O | O | O | | fs.readSync | O | O | O | | fs.readdir | O | O | X | | fs.readdirSync | O | O | X | | fs.readFile | O | O | O | | fs.readFileSync | O | O | O | | fs.rename | O | O | O | | fs.renameSync | O | O | O | | fs.rmdir | O | O | O | | fs.rmdirSync | O | O | O | | fs.stat | O | O | O | | fs.statSync | O | O | O | | fs.unlink | O | O | O | | fs.unlinkSync | O | O | O | | fs.write | O | O | O | | fs.writeSync | O | O | O | | fs.writeFile | O | O | O | | fs.writeFileSync | O | O | O | ※ On NuttX path should be passed with a form of **absolute path**. # File System ## Class: fs.Stats fs.Stats class is an object returned from `fs.stat()`,`fs.fstat()` and their synchronous counterparts. ### stats.isDirectory() * Returns: {boolean} Returns true if stated file is a directory. ### stats.isFile() * Returns: {boolean} Returns true if stated file is a file. **Example** ```js var assert = require('assert'); var fs = require('fs'); fs.stat('test.txt', function(err, stat) { if (err) { throw err; } assert.equal(stat.isFile(), true); assert.equal(stat.isDirectory(), false); }); ``` ### fs.close(fd, callback) * `fd` {integer} File descriptor. * `callback` {Function} * `err` {Error|null} Closes the file of `fd` asynchronously. **Example** ```js var fs = require('fs'); fs.open('test.txt', 'r', function(err, fd) { if (err) { throw err; } // do something fs.close(fd, function(err) { if (err) { throw err; } }); }); ``` ### fs.closeSync(fd) * `fd` {integer} File descriptor. Closes the file of `fd` synchronously. **Example** ```js var fs = require('fs'); var fd = fs.openSync('test.txt', 'r'); // do something fs.closeSync(fd); ``` ### fs.exists(path, callback) * `path` {string} File path to be checked. * `callback` {Function} * `exists` {boolean} Checks the file specified by `path` exists asynchronously. **Example** ```js var assert = require('assert'); var fs = require('fs'); fs.exists('test.txt', function(exists) { assert.equal(exists, true); }); ``` ### fs.existsSync(path) * `path` {string} File path to be checked. * Returns: {boolean} True if the file exists, otherwise false. Checks the file specified by `path` exists synchronously. ```js var assert = require('assert'); var fs = require('fs'); var result = fs.existsSync('test.txt'); assert.equal(result, true); ``` ### fs.fstat(fd, callback) * `fd` {integer} File descriptor to be stated. * `callback` {Function} * `err` {Error|null} * `stat` {Object} An instance of `fs.Stats`. Get information about a file what specified by `fd` into `stat` asynchronously. **Example** ```js var assert = require('assert'); var fs = require('fs'); fs.open('test.txt', 'r', function(err, fd) { if (err) { throw err; } fs.fstat(fd, function(err, stat) { if (err) { throw err; } assert.equal(stat.isFile(), true); assert.equal(stat.isDirectory(), false); }); }); ``` ### fs.fstatSync(fd) * `fd` {integer} - File descriptor to be stated. * Returns: {Object} An instance of `fs.Stats`. Get information about a file what specified by `fd` synchronously. **Example** ```js var assert = require('assert'); var fs = require('fs'); fs.open('test.txt', 'r', function(err, fd) { if (err) { throw err; } var stat = fs.fstatSync(fd); assert.equal(stat.isFile(), true); assert.equal(stat.isDirectory(), false); }); ``` ### fs.mkdir(path[, mode], callback) * `path` {string} Path of the directory to be created. * `mode` {string|number} Permission mode. **Default:** `0777` * `callback` {Function} * `err` {Error|null} Creates the directory specified by `path` asynchronously. **Example** ```js var fs = require('fs'); fs.mkdir('testdir', function(err) { if (err) { throw err; } }); ``` ### fs.mkdirSync(path[, mode]) * `path` {string} Path of the directory to be created. * `mode` {string|number} Permission mode. **Default:** `0777` Creates the directory specified by `path` synchronously. **Example** ```js var fs = require('fs'); fs.mkdirSync('testdir'); ``` ### fs.open(path, flags[, mode], callback) * `path` {string} File path to be opened. * `flags` {string} Open flags. * `mode` {string|number} Permission mode. **Default:** `0666` * `callback` {Function} * `err` {Error|null} * `fd` {number} Opens file asynchronously. `flags` can be: * `r` Opens file for reading. Throws an exception if the file does not exist. * `rs` or `sr` Opens file for reading in synchronous mode. Throws an exception if the file does not exist. * `r+` Opens file for reading and writing. Throws an exception if the file does not exist. * `rs+` or `sr+` Opens file for reading and writing in synchronous mode. Throws an exception if the file does not exist. * `w` Opens file for writing. The file is overwritten if it exists. * `wx` or `xw` Opens file for writing. Throws an exception if it exists. * `w+` Opens file for reading and writing. The file is overwritten if it exists. * `wx+` or `xw+` Opens file for reading and writing. Throws an exception if it exists. * `a` Opens file for appending. The file is created if it does not exist. * `ax` or `xa` Opens file for appending. Throws an exception if it exists. * `a+` Opens file for reading and appending. The file is created if it does not exist. * `ax+` or `xa+` Opens file for reading and appending. Throws an exception if it exists. **Example** ```js var fs = require('fs'); fs.open('test.txt', 'r', 755, function(err, fd) { if (err) { throw err; } // do something }); ``` ### fs.openSync(path, flags[, mode]) * `path` {string} File path to be opened. * `flags` {string} Open flags. * `mode` {string|number} Permission mode. **Default:** `0666` * Returns: {number} File descriptor. Opens file synchronously. For available options of the `flags` see [fs.open()](#class-method-fsopenpath-flags-mode-callback). **Example** ```js var fs = require('fs'); var fd = fs.openSync('test.txt', 'r', 755); // do something ``` ### fs.read(fd, buffer, offset, length, position, callback) * `fd` {integer} File descriptor. * `buffer` {Buffer} Buffer that the data will be written to. * `offset` {number} Offset of the buffer where to start writing. * `length` {number} Number of bytes to read. * `position` {number} Specifying where to start read data from the file, if `null` or `undefined`, read from current position. * `callback` {Function} * `err` {Error|null} * `bytesRead` {number} * `buffer` {Buffer} Reads data from the file specified by `fd` asynchronously. **Example** ```js var fs = require('fs'); fs.open('test.txt', 'r', 755, function(err, fd) { if (err) { throw err; } var buffer = new Buffer(64); fs.read(fd, buffer, 0, buffer.length, 0, function(err, bytesRead, buffer) { if (err) { throw err; } }); }); ``` ### fs.readSync(fd, buffer, offset, length, position) * `fd` {integer} File descriptor. * `buffer` {Buffer} Buffer that the data will be written to. * `offset` {number} Offset of the buffer where to start writing. * `length` {number} Number of bytes to read. * `position` {number} Specifying where to start read data from the file, if `null` or `undefined`, read from current position. * Returns: {number} Number of read bytes. Reads data from the file specified by `fd` synchronously. **Example** ```js var fs = require('fs'); var buffer = new Buffer(16); var fd = fs.openSync('test.txt', 'r'); var bytesRead = fs.readSync(fd, buffer, 0, buffer.length, 0); ``` ### fs.readdir(path, callback) * `path` {string} Directory path to be checked. * `callback` {Function} * `err` {Error|null} * `files` {Object} Reads the contents of the directory specified by `path` asynchronously, `.` and `..` are excluded from `files`. **Example** ```js var fs = require('fs'); fs.readdir('testdir', function(err, items) { if (err) { throw err; } // prints: file1,file2,... from 'testdir' console.log(items); }); ``` ### fs.readdirSync(path) * `path` {string} Directory path to be checked. * Returns: {Object} Array of filenames. Reads the contents of the directory specified by `path` synchronously, `.` and `..` are excluded from filenames. **Example** ```js var fs = require('fs'); var items = fs.readdirSync('testdir'); // prints: file1,file2,... from 'testdir' console.log(items); ``` ### fs.readFile(path, callback) * `path` {string} File path to be opened. * `callback` {Function} * `err` {Error|null} * `data` {Buffer} Reads entire file asynchronously into `data`. **Example** ```js var fs = require('fs'); fs.readFile('test.txt', function(err, data) { if (err) { throw err; } // prints: the content of 'test.txt' console.log(data); }); ``` ### fs.readFileSync(path) * `path` {string} File path to be opened. * Returns: {Object} Contents of the file. Reads entire file synchronously. **Example** ```js var fs = require('fs'); var data = fs.readFileSync('test.txt'); ``` ### fs.rename(oldPath, newPath, callback) * `oldPath` {string} Old file path. * `newPath` {string} New file path. * `callback` {Function} * `err` {Error|null} Renames `oldPath` to `newPath` asynchronously. **Example** ```js var fs = require('fs'); fs.rename('test.txt', 'test.txt.async', function(err) { if (err) { throw err; } }); ``` ### fs.renameSync(oldPath, newPath) * `oldPath` {string} Old file path. * `newPath` {string} New file path. Renames `oldPath` to `newPath` synchronously. **Example** ```js var fs = require('fs'); fs.renameSync('test.txt', 'test.txt.sync'); ``` ### fs.rmdir(path, callback) * `path` {string} Directory path to be removed. * `callback` {Function} * `err` {Error|null} Removes the directory specified by `path` asynchronously. **Example** ```js var fs = require('fs'); fs.rmdir('testdir', function() { // do something }); ``` ### fs.rmdirSync(path) * `path` {string} Directory path to be removed. Removes the directory specified by `path` synchronously. ```js var fs = require('fs'); fs.rmdirSync('testdir'); ``` ### fs.stat(path, callback) * `path` {string} File path to be stated. * `callback` {Function} * `err` {Error|null} * `stat` {Object} Get information about a file into `stat` asynchronously. **Example** ```js var assert = require('assert'); var fs = require('fs'); fs.stat('test.txt', function(err, stat) { if (err) { throw err; } assert.equal(stat.isFile(), true); assert.equal(stat.isDirectory(), false); }); ``` ### fs.statSync(path) * `path` {string} File path to be stated. * Returns: {Object} An instance of `fs.Stats`. Get information about a file synchronously. **Example** ```js var assert = require('assert'); var fs = require('fs'); var stat = fs.statSync('test.txt'); assert.equal(stat.isFile(), true); assert.equal(stat.isDirectory(), false); ``` ### fs.unlink(path, callback) * `path` {string} File path to be removed. * `callback` {Function} * `err` {Error|null} Removes the file specified by `path` asynchronously. **Example** ```js var fs = require('fs'); fs.unlink('test.txt', function(err) { if (err) { throw err; } }); ``` ### fs.unlinkSync(path) * `path` {string} File path to be removed. Removes the file specified by `path` synchronously. **Example** ```js var fs = require('fs'); fs.unlinkSync('test.txt'); ``` ### fs.write(fd, buffer, offset, length[, position], callback) * `fd` {integer} File descriptor. * `buffer` {Buffer} Buffer that the data will be written from. * `offset` {number} Offset of the buffer where from start reading. * `length` {number} Number of bytes to write. * `position` {number} Specifying where to start write data to the file, if `null` or `undefined`, write at the current position. * `callback` {Function} * `err` {Error|null} * `bytesWrite` {integer} * `buffer` {Object} Writes `buffer` to the file specified by `fd` asynchronously. **Example** ```js var fs = require('fs'); var file = 'test.txt' var data = new Buffer('IoT.js'); fs.open(file, 'w', function(err, fd) { if (err) { throw err; } fs.write(fd, data, 0, data.length, function(err, bytesWrite, buffer) { if (err) { throw err; } // prints: 6 console.log(bytesWrite); // prints: IoT.js console.log(buffer); }); }); ``` ### fs.writeSync(fd, buffer, offset, length[, position]) * `fd` {integer} File descriptor. * `buffer` {Buffer} Buffer that the data will be written from. * `offset` {number} Offset of the buffer where from start reading. * `length` {number} Number of bytes to write. * `position` {number} Specifying where to start write data to the file, if `null` or `undefined`, write at the current position. * Returns: {number} Number of bytes written. Writes buffer to the file specified by `fd` synchronously. ```js var fs = require('fs'); var file = 'test.txt' var data = new Buffer('IoT.js'); var fd = fs.openSync(file, 'w'); var bytes = fs.writeSync(fd, data, 0, data.length); //prints: 6 console.log(bytes); ``` ### fs.writeFile(path, data, callback) * `path` {string} File path that the `data` will be written. * `data` {string|Buffer} String or buffer that contains data. * `callback` {Function} * `err` {Error|null} Writes entire `data` to the file specified by `path` asynchronously. **Example** ```js var fs = require('fs'); fs.writeFile('test.txt', 'IoT.js', function(err) { if (err) { throw err; } }); ``` ### fs.writeFileSync(path, data) * `path` {string} File path that the `data` will be written. * `data` {string|Buffer} String or buffer that contains data. Writes entire `data` to the file specified by `path` synchronously. **Example** ```js var fs = require('fs'); fs.writeFileSync('test.txt', 'IoT.js'); ``` iotjs-1.0/docs/api/IoT.js-API-GPIO.md000066400000000000000000000105141312466455500170120ustar00rootroot00000000000000### Platform Support The following shows GPIO module APIs available for each platform. | | Linux
(Ubuntu) | Raspbian
(Raspberry Pi) | NuttX
(STM32F4-Discovery) | | :---: | :---: | :---: | :---: | | gpio.open | O | O | O | | gpiopin.write | O | O | O | | gpiopin.writeSync | O | O | O | | gpiopin.read | â–³ | â–³ | O | | gpiopin.readSync | O | O | O | | gpiopin.close | O | O | O | | gpiopin.closeSync | O | O | O | # GPIO The GPIO module provides access the General Purpose Input Output pins of the hardware. On Linux each pin has a logical number starting from `1`. The logical number might be different from the physical pin number of the board. The mapping is available in the documentation of a given board. On NuttX, the pin number is defined in target board module. For more information, please check the following list: [STM32F4-discovery](../targets/nuttx/stm32f4dis/IoT.js-API-Stm32f4dis.md#gpio-pin) ## Class: GPIO ### new GPIO() Returns a new GPIO object which can access any GPIO pins. ### DIRECTION * `IN` Input pin. * `OUT` Output pin. An enumeration which can be used to specify the direction of the pin. ### MODE * `NONE` None. * `PULLUP` Pull-up (pin direction must be [`IN`](#direction)). * `PULLDOWN` Pull-down (pin direction must be [`IN`](#direction)). * `FLOAT` Float (pin direction must be [`OUT`](#direction)). * `PUSHPULL` Push-pull (pin direction must be [`OUT`](#direction)). * `OPENDRAIN` Open drain (pin direction must be [`OUT`](#direction)). An enumeration which can be used to specify the configuration of the pin. ### gpio.open(configuration[, callback]) * `configuration` {Object} * `pin` {number} Pin number. Mandatory field. * `direction` {GPIO.DIRECTION} Pin direction. **Default:** `GPIO.DIRECTION.OUT` * `mode` {GPIO.MODE} Pin mode. **Default:** `GPIO.MODE.NONE` * `callback` {Function} * `error` {Error|null} * Returns: {GPIOPin} Opens the specified GPIO pin and sets the pin configuration. The mode argument is ignored on Linux. The optional `callback` function will be called after opening is completed. The `error` argument is an `Error` object on failure or `null` otherwise. **Example** ```js var GPIO = require('gpio'); var gpio = new GPIO(); var gpio10 = gpio.open({ pin: 10, direction: gpio.DIRECTION.OUT, mode: gpio.MODE.NONE }, function(err) { if (err) { throw err; } }); ``` ## Class: GPIOPin This class represents an opened and configured GPIO pin. It allows getting and setting the status of the pin. ### gpiopin.write(value[, callback]) * `value` {number|boolean} * `callback` {Function} * `error` {Error|null} Asynchronously writes out a boolean `value` to a GPIO pin (a number `value` is converted to boolean first). The optional `callback` function will be called after the write is completed. The `error` argument is an `Error` object on failure or `null` otherwise. **Example** ```js gpio10.write(1, function(err) { if (err) { throw err; } }); ``` ### gpiopin.writeSync(value) * `value` {number|boolean} Writes out a boolean `value` to a GPIO pin synchronously (a number `value` is converted to boolean first). **Example** ```js gpio10.writeSync(1); ``` ### gpiopin.read([callback]) * `callback` {Function} * `error` {Error|null} * `value` {boolean} Asynchronously reads a boolean value from a GPIO pin. The optional `callback` function will be called after the read is completed. The `error` argument is an `Error` object on failure or `null` otherwise. The `value` argument contains the boolean value of the pin. **Example** ```js gpio10.read(function(err, value) { if (err) { throw err; } console.log('value:', value); }); ``` ### gpiopin.readSync() * Returns: {boolean} Returns the boolean value of a GPIO pin. **Example** ```js console.log('value:', gpio10.readSync()); ``` ### gpiopin.close([callback]) * `callback` {Function} * `error` {Error|null} Asynchronously closes a GPIO pin. The optional `callback` function will be called after the close is completed. The `error` argument is an `Error` object on failure or `null` otherwise. **Example** ```js gpio10.close(function(err) { if (err) { throw err; } // prints: gpio pin is closed console.log('gpio pin is closed'); }); ``` ### gpiopin.closeSync() Closes a GPIO pin. **Example** ```js gpio10.closeSync(); // prints: gpio pin is closed console.log('gpio pin is closed'); ``` iotjs-1.0/docs/api/IoT.js-API-HTTP.md000066400000000000000000000215041312466455500170340ustar00rootroot00000000000000### Platform Support The following shows Http module APIs available for each platform. | | Linux
(Ubuntu) | Raspbian
(Raspberry Pi) | NuttX
(STM32F4-Discovery) | | :---: | :---: | :---: | :---: | | http.createServer | O | O | △ ¹ | | http.request | O | O | △ ¹ | | http.get | O | O | △ ¹ | 1. On NuttX/STM32F4-Discovery, even a couple of sockets/server/requests might not work properly. # Http IoT.js provides HTTP to support HTTP server and client enabling users to receive/send HTTP request easily. ### http.createServer([requestListener]) * `requestListener` {Function} * request {http.IncomingMessage} * response {http.ServerResponse} * Returns: {http.Server} The `requestListener` is a function which is automatically added to the `'request'` event. **Example** ```js var server = http.createServer(function(request, response) { ... }); ``` ### http.request(options[, callback]) * `options` {Object} * `host` {string} A domain name or IP address of the server to issue the request to. Defaults to 'localhost'. * `hostname` {string} Alias for host. * `port` {number} Port of remote server. Defaults to 80. * `method` {string} A string specifying the HTTP request method. Defaults to 'GET'. * `path` {string} Request path. Defaults to '/'. Should include query string if any. E.G. '/index.html?page=12'. An exception is thrown when the request path contains illegal characters. Currently, only spaces are rejected but that may change in the future. * `headers` {Object} An object containing request headers. * `callback` {Function} * `response` {http.IncomingMessage} * Returns: {http.ClientRequest} **Example** ```js var http = require('http'); var request = http.request({ method: 'POST', port: 80, headers: {'Content-Length': 3} }); ... request.end(); ``` Note that in the example `req.end()` was called. With `http.request()` one must always call `req.end()` to signify that you're done with the request - even if there is no data being written to the request body. ### http.get(options[, callback]) * `options` {Object} * `callback` {Function} * `response` {http.IncomingMessage} * Returns: {http.ClientRequest} Same as `http.request` except that `http.get` automatically call `req.end()` at the end. **Example** ```js var http = require('http'); http.get({ port: 80, }, function(res) { ... }); ``` ### http.METHODS A list of HTTP methods supported by the parser as `string` properties of an `Object`. ## Class: http.Server This class inherits from `net.Server`. ### Event: 'clientError' * `exception` {Error} * `socket` {net.Socket} If a client connection emits an 'error' event, it will be forwarded here. Listener of this event is responsible for closing/destroying the underlying socket. Default behavior is to destroy the socket immediately on malformed request. **Example** ```js var http = require('http'); var server = http.createServer(function(req, res) { res.end(); }); server.on('clientError', function(err, socket) { socket.end('HTTP/1.1 400 Bad Request\r\n\r\n'); }); server.listen(8000); ``` ### Event: 'close' This event is emitted when server is closed. ### Event: 'connection' * `socket` {net.Socket} This event is emitted when new TCP connection is established. ### Event: 'connect' Emitted each time a client requests an `HTTP CONNECT` method. ### Event: 'request' * `request` {http.IncomingMessage} * `response` {http.ServerResponse} After request header is parsed, this event will be fired. ### server.timeout The number of milliseconds of inactivity before a socket is presumed to have timed out. Default value is 120000 (2 minutes). ### server.listen(port[, hostname][, backlog][, callback]) * `port` {number} * `host` {string} * `backlog` {number} * `callback` {Function} Wait for new TCP connection with specified port and hostname. If no hostname is provided, server accepts any IP address. `backlog` is maximum pending connections. Default backlog length is 511 (not 512). `callback` will be called when server has been bound. **Example** ```js var http = require('http'); var server = http.createServer(function(req, res) { res.end(); }); server.listen(8080, function() {}); ``` ### server.close([callback]) * `callback` {Function} Stop accepting new connection to this server. However, the existing connections are preserved. When server is finally closed after all connections are closed, a callback is called. ### server.setTimeout(ms, cb) * `ms` {number} * `cb` {Function} Registers cb for `'timeout'` event and sets socket's timeout value to ms. This event will be triggered by the underlying socket's 'timeout' event. If cb is not provided, the socket will be destroyed automatically after timeout. If you provide cb, you should handle the socket's timeout. Default timeout for server is 2 minutes. **Example** ```js var http = require('http'); var server = http.createServer(); server.setTimeout(100, function(socket) { socket.destroy(); server.close(); }); ``` ## Class: http.ServerResponse ### Event: 'close' When underlying connection is closed, 'close' event is emitted. ### Event: 'end' This event is fired when no more data to be sent. ### Event: 'finish' This event is emitted when the response has been sent. It does not guarantee that client has received data yet. ### response.end([data][, callback]) * `data` {Buffer | string} * `callback` {Function} Finishes sending the response. If `data` is provided, it sends `data` first, and finishes. If `callback` is specified, it is called when the response stream is finished. ### response.getHeader(name) * `name` {string} Returns `name` field of response's header ### response.removeHeader(name) * `name` {string} Removes `name` field from response's header ### response.setHeader(name, value) * `name` {string} * `value` {string} Sets response's header field(`name`) to `value`. If the field exists, it overwrites the existing value. ### response.setTimeout(ms, cb) * `ms` {number} * `cb` {Function} Registers cb for 'timeout' event and set socket's timeout value to ms. This event will be triggered by the underlying socket's 'timeout' event. ### response.write(data[, callback]) * `data` {Buffer | string} * `callback` {Function} Sends `data` as a response body. `callback` will be called when data is flushed. ### response.writeHead(statusCode[, statusMessage][, headers]) * `statusCode` {number} * `statusMessage` {string} * `headers` {Object} Sets response's header. `headers` is a map between field and value in header. ## Class: http.ClientRequest This object is created internally and returned from http.request(). It represents an in-progress request whose header has already been queued. ### Event: 'close' This event is fired when the underlying socket is closed. ### Event: 'error' * `callback` {Function} * `err` {Error} Emitted if something went wrong with making or parsing the request. ### Event: 'finish' This event is emitted after all the data was sent, meaning header and body all finished sending. ### Event: 'response' * `response` {http.IncomingMessage} This event is emitted when server's response header is parsed. ` http.IncomingMessage` object is passed as argument to handler. ### Event: 'socket' * `socket` {net.Socket} This event is emitted when a socket is assigned to this request. `net.Socket` object is passed as argument to handler. After response header is parsed, this event will be fired. ### request.end([data][, callback]) * `data` {Buffer | string} * `callback` {Function} Finishes sending the request. If `data` is provided, it sends `data` first, and finishes. If `callback` is specified, it is called when the request stream is finished. ### request.setTimeout(ms, cb) * `ms` {number} * `cb` {Function} Registers cb for 'timeout' event and set socket's timeout value to ms. This event will be triggered by the underlying socket's 'timeout' event. If cb is not provided, the socket will be destroyed automatically after timeout. If you provides cb, you should handle the socket's timeout. ### request.write(data[, callback]) * `data` {Buffer | string} * `callback` {Function} Sends `data` as a request body. `callback` will be called when data is flushed. ## Class: http.IncomingMessage http.IncomingMessage inherits `Stream.readable`. ### Event: 'close' When underlying connection is closed, 'close' event is emitted. ### Event: 'end' This event is fired when no more data to be received. ### message.headers HTTP header object. ### message.method Requests method as `string` ### message.socket Underlying socket ### message.statusCode HTTP response status code as `number` of 3-digit. ### message.statusMessage HTTP response status message as `string` ### message.url Requests URL as `string` ### message.setTimeout(ms, cb) * `ms` {number} * `cb` {Function} Registers cb for 'timeout' event set socket's timeout value to ms. This event will be triggered by the underlying socket's 'timeout' event. iotjs-1.0/docs/api/IoT.js-API-I2C.md000066400000000000000000000040111312466455500166240ustar00rootroot00000000000000## Platform Support The following shows I2C module APIs available for each platform. | | Linux
(Ubuntu) | Raspbian
(Raspberry Pi) | NuttX
(STM32F4-Discovery) | | :---: | :---: | :---: | :---: | | i2c.open | O | O | O | | i2cbus.read | O | O | O | | i2cbus.write | O | O | O | | i2cbus.close | O | O | O | # I2C The I2C class supports the I2C protocol. I2C bus has two signals - SDA and SCL. ### new I2C() Returns with an I2C object. **Example** ```js var I2C = require('i2c'); var i2c = new I2C(); ``` ### i2c.open(configuration[, callback]) * `configuration` {Object} Configuration for open I2CBus. * `device` {string(linux)|number(NuttX)} Device path. * `address` {number} Device address. * `callback` {Function} * `err` {Error|null} * Returns: {Object} An instance of I2CBus. Get I2CBus object with configuration. **Example** ```js var I2C = require('i2c'); var i2c = new I2C(); var i2c_bus = i2c.open({device: '/dev/i2c-1', address: 0x23}, function(err) { if (err) { throw err; } }); ``` ## Class: I2CBus ### i2cbus.read(length[, callback]) * `length` {number} Number of bytes to read. * `callback` {Function} * `err` {Error|null} * `res` {Array} Array of bytes. Read bytes from I2C device. **Example** ```js var I2C = require('i2c'); var i2c = new I2C(); var i2c_bus = i2c.open({device: '/dev/i2c-1', address: 0x23}); i2c_bus.read(2, function(err, res) { if (!err) { console.log('read result: ' + res); } }); ``` ### i2cbus.write(bytes[, callback]) * `bytes` {Array} Array of bytes to write. * `callback` {Function} * `err` {Error|null} Write bytes to I2C device. **Example** ```js var I2C = require('i2c'); var i2c = new I2C(); var i2c_bus = i2c.open({device: '/dev/i2c-1', address: 0x23}); i2c_bus.write([0x10], function(err) { if(!err) { console.log('write done'); } }); ``` ### i2cbus.close() Close I2C device. **Example** ```js var I2C = require('i2c'); var i2c = new I2C(); var i2c_bus = i2c.open({device: '/dev/i2c-1', address: 0x23}); i2c_bus.close(); ``` iotjs-1.0/docs/api/IoT.js-API-Module.md000066400000000000000000000024061312466455500175020ustar00rootroot00000000000000### Platform Support The following shows module APIs available for each platform. | | Linux
(Ubuntu) | Raspbian
(Raspberry Pi) | NuttX
(STM32F4-Discovery) | | :---: | :---: | :---: | :---: | | require | O | O | O | # Module The `require` function is always available there is no need to import `module` explicitly. ### require(id) * `id` {string} Module name to be loaded. Loads the module named `id`. **Example** ```js var assert = require('assert'); assert.equal(2, 2); ``` **Loading a module** If a native module named `id` exists, load it and return. (_Native module:_ which module came from the IoT.js itself) `require` function searches for modules in the following order: 1. Current working directory. 2. `iotjs_modules` folder under current working directory. 3. `$HOME/iotjs_modules` 4. `$IOTJS_PATH/iotjs_modules` For each directory in search paths above: - If a file `id` exists, load it and return. - If a file `id.js` exists, load it and retun. - If a directory `id` exists, module system consider the directory as a package: - If `id/package.json` contains **main** property, load the file named **main** property. - If `id/package.json` exists, but neither the **main** property nor the file named **main** property exist, load `index.js`. iotjs-1.0/docs/api/IoT.js-API-Net.md000066400000000000000000000422151312466455500170050ustar00rootroot00000000000000### Platform Support The following shows net module APIs available for each platform. | | Linux
(Ubuntu) | Raspbian
(Raspberry Pi) | NuttX
(STM32F4-Discovery) | | :---: | :---: | :---: | :---: | | net.createServer | O | O | △ ¹ | | net.connect | O | O | △ ¹ | | net.createConnection | O | O | △ ¹ | | net.Server.listen | O | O | △ ¹ | | net.Server.close | O | O | △ ²| | net.Socket.connect | O | O | △ ¹ | | net.Socket.write | O | O | △ ¹ | | net.Socket.end | O | O | △ ¹ ³ | | net.Socket.destroy | O | O | △ ¹ ³ | | net.Socket.pause | O | O | △ ¹ | | net.Socket.resume | O | O | △ ¹ | | net.Socket.setTimeout | O | O | △ ¹ | | net.Socket.setKeepAlive | X | X | X | 1. On NuttX/STM32F4-Discovery, even a couple of sockets/server/requests might not work properly. 2. On NuttX/STM32F4-Discovery, close() may block due to a bug in poll(). 3. When writable stream is finished but readable stream is still alive, IoT.js tries to shutdown the socket, not destroy. However on `NuttX` due to lack of implementation, it does nothing inside. # Net IoT.js provides asynchronous networking through Net module. You can use this module with `require('net')` and create both servers and clients. ### net.connect(options[, connectListener]) * `options` {Object} An object which specifies the connection options. * `connectListener` {Function} Listener for the `'connect'` event. * Returns {net.Socket}. Creates a new `net.Socket` and automatically connects with the supplied `options`. The `options` object specifies the following information: * `port` {number} Port connect to (required). * `host` {string} Host connect to (optional, **Default:** `localhost`). * `family` {number} Version of IP stack. The `options` are passed to both the `net.Socket` constructor and the `socket.connect` method. The `connectListener` is automatically registered as a `'connect'` event listener. **Example** ```js var net = require('net'); var port = 22702; var echo_msg = ''; var socket = net.connect({port: port, family: 4}, function() { socket.end('Hello IoT.js'); }); socket.on('data', function(data) { echo_msg += data; }); socket.on('end', function() { console.log(echo_msg); }); ``` ### net.connect(port[, host][, connectListener]) * `port` {number} Port the client should connect to. * `host` {string} Host the client should connect to. **Default:** `localhost`. * `connectListener` {Function} Listener for the `'connect'` event. * Returns {net.Socket}. Creates a new `net.Socket` and automatically connects to the supplied `port` and `host`. If host is omitted, `localhost` will be assumed. The `connectListener` is automatically registered as a `'connect'` event listener. **Example** ```js var net = require('net'); var port = 22702; var host = '127.0.0.1'; var echo_msg = ''; var socket = net.connect(port, host, function() { socket.end('Hello IoT.js'); }); socket.on('data', function(data) { echo_msg += data; }); socket.on('end', function() { console.log(echo_msg); }); ``` ### net.createConnection(options[, connectListener]) * `options` {Object} An object which specifies the connection options. * `connectListener` {Function} Listener for the `'connect'` event. * Returns {net.Socket}. Creates a new `net.Socket` and automatically connects with the supplied `options`. The `options` are passed to both the `net.Socket` constructor and the `socket.connect` method. The `options` object specifies the following information: * `port` {number} Port connect to (required). * `host` {string} Host connect to (optional, **Default:** `localhost`). * `family` {number} Version of IP stack. The `connectionListener` is automatically registered as a `'connect'` event listener. **Example** ```js var net = require('net'); var port = 80; var echo_msg = ''; var socket = net.createConnection({port: port, family: 4}, function() { socket.end('Hello IoT.js'); }); socket.on('data', function(data) { echo_msg += data; }); socket.on('end', function() { console.log(echo_msg); }); ``` ### net.createConnection(port[, host][, connectListener]) * `port` {number} Port the client should connect to. * `host` {string} Host the client should connect to. **Default:** `localhost`. * `connectListener` {Function} Listener for the `'connect'` event. * Returns {net.Socket}. Creates a new `net.Socket` and automatically connects to the supplied `port` and `host`. It is equivalent to `new net.Socket()` followed by `socket.connect()`. If host is omitted, `localhost` will be assumed. The `connectionListener` is automatically registered as a `'connect'` event listener. **Example** ```js var net = require('net'); var port = 22702; var host = '127.0.0.1'; var echo_msg = ''; var socket = net.createConnection(port, host, function() { socket.end('Hello IoT.js'); }); socket.on('data', function(data) { echo_msg += data; }); socket.on('end', function() { console.log(echo_msg); }); ``` ### net.createServer([options][, connectionListener]) * `options` {Object} An object which specifies the connection options **Default:** `{ allowHalfOpen: false }`. * `connectListener` {Function} Listener for the `'connection'` event. * Returns {net.Server}. Creates a TCP server according to `options`. The `connectionListener` is automatically registered as a `'connection'` event listener. If `allowHalfOpen` is true, then the socket becomes non-readable, but still writable. You should call the `socket.end()` method explicitly. **Example** ```js var net = require('net'); var port = 22702; var server = net.createServer( { allowHalfOpen: true }, function(socket) { server.close(); } ); server.listen(port); server.on('connection', function(socket) { var msg = ''; socket.on('data', function(data) { msg += data; }); socket.on('end', function() { socket.end(msg); }); }); ``` ## Class: net.Server This class is used to create a TCP or local server. You can create `net.Server` instance with `net.createServer()`. ### server.close([closeListener]) * `closeListener` {Function} Listener for the `'close'` event. Stops listening new arriving connection. Server socket will be finally closed when all existing connections are closed, then emits `'close'` event. The `closeListener` is registered as a `'close'` event listener. **Example** ```js var net = require('net'); var server = net.createServer(); var port = 22704; var timeout = 1000; server.listen(port); /* ... */ server.close(); ``` ### server.listen(port[, host][, backlog][, listenListener]) * `port` {number} Port the client should connect to. * `host` {string} Host the client should connect to. * `backlog` {number} The maximum length of the queue of pending connections. **Default:** `511`. * `listenListener` {Function} Listener for the `'listening'` event. * Returns: {Object} The self instance of `net.Server`. Begin accepting connections on the specified port and hostname. If the hostname is omitted, the server will accept connections on any IPv4 address (0.0.0.0). **Example** ```js var net = require('net'); var server = net.createServer(); var port = 22709; server.listen(port); ``` ### server.listen(options[, listenListener]) * options {Object} An object which specifies the connection options. * `listenListener` {Function} Listener for the `'listening'` event. It behaves as the `server.listen(port[, host][, backlog][, listenListener])` function above. The option object supports the following properties: * `port` {number} Port the client should connect to. * `host` {string} Host the client should connect to. * `backlog` {number} The maximum length of the queue of pending connections. **Default:** `511`. **Example** ```js var net = require('net'); var server = net.createServer(); server.listen({port: 80, host: 'localhost'}); ``` ### Event: 'close' * `callback` {Function} Emitted when server has closed the connection. Note that this event will be emitted after all existing connections are closed. **Example** ```js var net = require('net'); var serverCloseEvent = 0; var server = net.createServer(); var port = 80; server.listen(port); server.on('connection', function(socket) { server.on('close', function() { serverCloseEvent++; }); }); ``` ### Event: 'connection(socket)' * `callback` {Function} * `socket` {Net.Socket} Emitted when new connection is established. **Example** ```js var net = require('net'); var server = net.createServer(); var port = 80; server.listen(port); server.on('connection', function(socket) { var msg = ''; socket.on('data', function(data) { msg += data; }); }); ``` ### Event: 'error' * `callback` {Function} Emitted when an error occurs. **Example** ```js var assert = require('assert'); var net = require('net'); var port = 80; var msg = 'Hello IoT.js'; var server = net.createServer(); /* ... */ server.on('error', function() { assert.fail(); server.close(); }); ``` ### Event: 'listening' * `callback` {Function} Emitted when server has been started listening. **Example** ```js var net = require('net'); var port = 80; var server = net.createServer( { allowHalfOpen: true }, function(socket) { server.close(); } ); server.listen(port); server.on('listening', function() { console.log('started listening'); }); ``` ## Class: net.Socket This object is an abstraction of a TCP or a local socket. `net.Socket` inherits from [`Stream.Duplex`](IoT.js-API-Stream.md). They can be created by the user (used as a client with connect()) or by the IoT.js engine (passed to the user through the 'connection' event of a server). ### new net.Socket([options]) * `options` {Object} An optional object which specifies the socket information. * Returns {net.Socket}. Construct a new socket object. The `options` object specifies only the following information: `allowHalfOpen` {boolean}. **Example** ```js var net = require('net'); var socket = new net.Socket(); ``` ### socket.connect(options[, connectListener]) * `options` {Object} An object which specifies the connection information. * `connectListener` {Function} Listener for the `'connect'` event. * Returns {net.Socket}. Creates a new socket object and automatically connects with the supplied `options`. The `options` object specifies following information: * `port` {number} Port connect to (required). * `host` {string} Host connect to (optional, **Default:** `localhost`). * `family` {number} Version of IP stack. The `connectionListener` is automatically registered as a `'connect'` event listener which will be emitted when the connection is established. **Example** ```js var net = require('net'); var port = 22702; var socket = new net.Socket(); socket.connect({port: port, family: 4}, function() { socket.end('Hello IoT.js'); }); ``` ### socket.connect(port[, host][, connectListener]) * `port` {number} Port the client should connect to. * `host` {string} Host the client should connect to. **Default:** `localhost`. * `connectListener` {Function} Listener for the `'connect'` event. * Returns {net.Socket}. Creates a new socket and automatically connects with the supplied `port` and `host`. `connectionListener` is automatically registered as a `'connect'` event listener which will be emitted when the connection is established. **Example** ```js var net = require('net'); var port = 80; var socket = new net.Socket(); socket.connect(port, '127.0.0.1', function() { socket.end('Hello IoT.js'); }); ``` ### socket.destroy() Ensures that no more I/O activity happens on the socket and destroys the socket as soon as possible. **Example** ```js var net = require('net'); var port = 80; var socket = new net.Socket(); socket.connect(port, '127.0.0.1', function() { socket.end('Hello IoT.js'); }); /* ... */ socket.destroy(); ``` ### socket.end([data][, callback]) * `data` {Buffer|string} * `callback` {Function} Half-closes the socket. The socket is no longer writable. If `data` is given it is equivalent to `socket.write(data)` followed by `socket.end()`. **Example** ```js var net = require('net'); var server = net.createServer(); var port = 4010; server.listen(port); server.on('connection', function(socket) { socket.on('data', function(data) { socket.end('Hello IoT.js'); }); }); ``` ### socket.pause() Pauses reading data. **Example** ```js var net = require('net'); var server = net.createServer(); var port = 4010; server.listen(port); server.on('connection', function(socket) { // as soon as connection established, pause the socket socket.pause(); }); ``` ### socket.resume() Resumes reading data after a call to `pause()`. **Example** ```js var net = require('net'); var timers = require('timers'); var server = net.createServer(); var port = 80; var socket = new net.Socket(); var msg = ""; /* ... */ server.listen(port); server.on('connection', function(socket) { socket.on('data', function(data) { msg += data; socket.end(); }); socket.on('close', function() { server.close(); }); // as soon as connection established, pause the socket socket.pause(); // resume after 2 secs timers.setTimeout(function() { socket.resume(); }, 2000); }); ``` ### socket.setKeepAlive([enable][, initialDelay]) * `enable` {boolean} **Default:** `false`. * `initialDelay {number} **Default:** `0`. Enables or disables keep-alive functionality. **Example** ```js var net = require('net'); var keepalive_sock = new net.Socket(); keepalive_sock.setKeepAlive(true, 1000); ``` ### socket.setTimeout(timeout[, callback]) * `timeout` {number} Timeout number. * `callback` {Function} Registered as a `'timeout'` event listener. Sets timeout for the socket. If the socket is inactive for `timeout` milliseconds, `'timeout'` event will emit. **Example** ```js var net = require('net'); var server = net.createServer(); var port = 40; var timeout = 2000; var msg = ''; server.listen(port); server.on('connection', function(socket) { socket.setTimeout(timeout, function() { socket.end(); }); }); ``` ### socket.write(data[, callback]) * `data` {Buffer|string} Data to write. * `callback` {Function} Executed function (when the data is finally written out). Sends `data` on the socket. The optional `callback` function will be called after the given data is flushed through the connection. **Example** ```js var net = require('net'); var timers = require('timers'); var writeat = 1000; var socket = new net.Socket(); /* ... */ socket.on('connect', function() { timers.setTimeout(function() { socket.write('Hello IoT.js'); }, writeat); }); ``` ### Event: 'connect' * `callback` {Function} Emitted after connection is established. **Example** ```js var net = require('net'); var port = 80; var count = 40; /* ... */ for (var i = 0; i < count; ++i) { (function(i) { var socket = new net.Socket(); socket.connect(port, "localhost"); socket.on('connect', function() { socket.end(i.toString()); }); /* ... */ })(i); } ``` ### Event: 'close' * `callback` {Function} Emitted when the socket has been closed. **Example** ```js var net = require('net'); var server = net.createServer(); var port = 80; server.listen(port); server.on('connection', function(socket) { /* ... */ socket.on('close', function() { server.close(); }); }); ``` ### Event: 'data' * `callback` {Function} The data is given an argument (data: Buffer|string). Emitted when data is received from the connection. **Example** ```js var net = require('net'); var msg = ""; var socket = new net.Socket(); /* ... */ socket.on('data', function(data) { msg += data; }); ``` ### Event: 'drain' * `callback` {Function} Emitted when the write buffer becomes empty. **Example** ```js var net = require('net'); var port = 22703; var limit = 200; var server = net.createServer(); server.listen({ port: port }); /* ... */ server.on('connection', function(socket) { var i = 0; var writing = function() { var ok; do { ok = socket.write("" + (i % 10)); if (++i == limit) { socket.end(); ok = false; } } while (ok); }; socket.on('drain', writing); writing(); }); ``` ### Event: 'end' * `callback` {Function} Emitted when FIN packet received. **Example** ```js var net = require('net'); var socket = new net.Socket(); /* ... */ socket.on('end', function() { socket.end(); }); ``` ### Event: 'error' * `callback` {Function} * `err` {Error} Emitted when an error occurs. **Example** ```js var assert = require('assert'); var net = require('net'); var bad_sock = new net.Socket(); bad_sock.on('error', function(err){ assert.equal(err instanceof Error, true); }); ``` ### Event: 'lookup' * `callback` {Function} * `err` {Error} * `address` {string} * `family` {string|null} Emitted after resolving hostname. **Example** ```js var socket = new net.Socket(); var msg = ""; var lookupHandled = false; socket.on('lookup', function(err, ip, family) { lookupHandled = true; }); ``` ### Event: 'timeout' * `callback` {Function}` Emitted when the connection remains idle for the specified timeout. **Example** ```js var net = require('net'); var timedout = false; // Try connect to host that is not exist (Reserved address) var socket = net.createConnection(11111, '192.0.2.1'); socket.setTimeout(1000); socket.on('timeout', function() { timedout = true; socket.destroy(); }); ``` iotjs-1.0/docs/api/IoT.js-API-PWM.md000066400000000000000000000154721312466455500167270ustar00rootroot00000000000000### Platform Support The following shows PWM module APIs available for each platform. | | Linux
(Ubuntu) | Raspbian
(Raspberry Pi) | NuttX
(STM32F4-Discovery) | | :---: | :---: | :---: | :---: | | pwm.open | O | O | O | | pwmpin.setPeriod | O | O | O | | pwmpin.setPeriodSync | O | O | O | | pwmpin.setFrequency | O | O | O | | pwmpin.setFrequencySync | O | O | O | | pwmpin.setDutyCycle | O | O | O | | pwmpin.setDutyCycleSync | O | O | O | | pwmpin.setEnable | O | O | O | | pwmpin.setEnableSync | O | O | O | | pwmpin.close | O | O | O | | pwmpin.closeSync | O | O | O | ## Class: PWM ### new PWM() Returns a new PWM object which can open a PWM pin. This object allows the developer to specify a pin and generate a pulse-width modulatated (PWM) signal through that. ### pwm.open(configuration[, callback]) * `configuration` {Object} Configuration object which can have the following properties. * `pin` {number} The pin number to use with this PWM object (mandatory configuration). * `chip` {number} The PWM chip number (only on Linux). **Default:** `0`. * `period` {number} The period of the PWM signal, in seconds (positive number). * `frequency` {integer} In Hz (positive integer). * `dutyCycle` {number} The active time of the PWM signal, must be within the `0.0` and `1.0` range. * `callback` {Function} Callback function. * `err` {Error|null} The error object or `null` if there were no error. * Returns: `` Opens PWM pin with the specified configuration. To correctly open a PWM pin one must know the correct pin number: * On Linux, `pin` is a number which is `0` or `1`. * On NuttX, you have to know pin name. The pin name is defined in target board module. For more module information, please see below list. * [STM32F4-discovery](../targets/nuttx/stm32f4dis/IoT.js-API-Stm32f4dis.md#pwm-pin) **Example** ```js var Pwm = require('pwm'); var pwm = new Pwm(); var config = { pin: 0, period: 0.1, dutyCycle: 0.5 } var pwm0 = pwm.open(config, function(err) { if (err) { throw err; } }); ``` ## Class: PWMPin ### pwmpin.setPeriod(period[, callback]) * `period` {number} The period of the PWM signal, in seconds (positive number). * `callback` {Function} * `err` {Error|null} The error object or `null` if there were no error. The `setPeriod` method allows the configuration of the period of the PWM signal in seconds. The `period` argument must specified and it should be a positive number. Configuration is done asynchronously and the `callback` method is invoked after the period is configured to the new value or if an error occured. **Example** ```js pwm0.setPeriod(1, function(err) { if (err) { throw err; } console.log('done'); }); // prints: do console.log('do'); // prints: done ``` ### pwmpin.setPeriodSync(period) * `period` {number} The period of the PWM signal, in seconds (positive number). The `setPeriodSync` method allows the configuration of the period of the PWM signal in seconds. The `period` argument must specified and it should be a positive number. Configuration is done synchronously and will block till the period is configured. **Example** ```js pwm0.setPeriodSync(1); // prints: done console.log('done'); ``` ### pwmpin.setFrequency(frequency[, callback]) * `frequency` {integer} In Hz (positive integer). * `callback` {Function} * `err` {Error|null} The error object or `null` if there were no error. The `setFequency` method congifures the frequency of the PWM signal. `frequency` is the measurement of how often the signal is repeated in a single period. Configuration is done asynchronously and the `callback` method is invoked after the frequency is configured to the new value or if an error occured. **Example** ```js pwm0.setFrequency(1, function(err) { if (err) { throw err; } console.log('done'); }); // prints: do console.log('do'); // prints: done ``` ### pwmpin.setFrequencySync(frequency) * `frequency` {integer} In Hz (positive integer). The `setFequencySync` method congifures the frequency of the PWM signal. `frequency` is the measurement of how often the signal is repeated in a single period. Configuration is done synchronously and will block till the frequency is configured. **Example** ```js pwm0.setFrequencySync(1); // prints: done console.log('done'); ``` ### pwmpin.setDutyCycle(dutyCycle[, callback]) * `dutyCycle` {number} Must be within the `0.0` and `1.0` range. * `callback` {Function} * `err` {Error|null} The error object or `null` if there were no error. The `setDutyCycle` method allows the configuration of the duty cycle of the PWM signal. The duty cycle is the ratio of the pulse width in one period. Configuration is done asynchronously and the `callback` method is invoked after the duty cycle is configured to the new value or if an error occured. **Example** ```js pwm0.setDutyCycle(1, function(err) { if (err) { throw err; } console.log('done'); }); // prints: do console.log('do'); // prints: done ``` ### pwmpin.setDutyCycleSync(dutyCycle) * `dutyCycle` {number} Must be within the `0.0` and `1.0` range. The `setDutyCycleSync` method allows the configuration of the duty cycle of the PWM signal. The duty cycle is the ratio of the pulse width in one period. Configuration is done synchronously and will block till the duty cycle is configured. **Example** ```js pwm0.setDutyCycleSync(1); // prints: done console.log('done'); ``` ### pwmpin.setEnable(enable[, callback]) * `enable` {boolean} * `callback` {Function} * `err` {Error|null} The error object or `null` if there were no error. The `setEnable` method can turn on/off the generation of the PWM signal. If the `enable` argument is `true` then the PWN signal generation is turned on. Otherwise the signal generation is turned off. After enabling/disabling the signal generation the `callback` is invoked. **Example** ```js pwm0.setEnable(true, function(err) { if (err) { throw err; } console.log('done'); }); // prints: do console.log('do'); // prints: done ``` ### pwmpin.setEnableSync(enable) * `enable` {boolean} The `setEnableSync` method can turn on/off the generation of the PWM signal. If the `enable` argument is `true` then the PWN signal generation is turned on. Otherwise the signal generation is turned off. **Example** ```js pwm0.setEnableSync(false); // prints: done console.log('done'); ``` ### pwmpin.close([callback]) * `callback` {Function} * `err` {Error|null} The error object or `null` if there were no error. The `close` method closes the PWM pin asynchronously. The `callback` method will be invoked after the PWM device is released. **Example** ```js pwm0.close(function(err) { if (err) { throw err; } console.log('done'); }); // prints: do console.log('do'); // prints: done ``` ### pwmpin.closeSync() The `closeSync` method closes the PWM pin synchronously. **Example** ```js pwm0.closeSync(); // prints: done console.log('done'); ``` iotjs-1.0/docs/api/IoT.js-API-Process.md000066400000000000000000000167601312466455500177030ustar00rootroot00000000000000### Platform Support The following shows process module APIs available for each platform. | | Linux
(Ubuntu) | Raspbian
(Raspberry Pi) | NuttX
(STM32F4-Discovery) | | :---: | :---: | :---: | :---: | | process.nextTick | O | O | O | | process.exit | O | O | O | | process.cwd | O | O | O | | process.chdir | O | O | O | ※ On NuttX, you should pass absolute path to `process.chdir`. # Process The `process` object is a global that provides information about, and control over, the current IoT.js process. As a global, it is always available to IoT.js applications without using `require()`. ### process.arch * {string} The `arch` property returns the processor architecture identifier that the IoT.js process is currently running on. For instance `'arm'`, `'ia32'`, `'x64'`, or `'unknown'`. ### process.argv * {Array} The `argv` property returns an array containing the command line arguments passed when the IoT.js process was launched. The first element is the path to the IoT.js program. The second element is the path of the JavaScript file currently being executed. The remaining elements will be any additional arguments passed via command line. **Example** To print out all command line arguments the following example could be used: ```js process.argv.forEach(function(val, idx) { console.log('index: ' + idx + ' value: ' + val); }); ``` ### process.env * {Object} The `env` property returns an object containing a few environment variables. The following environment elements can be accessed: * `HOME` * `IOTJS_PATH` which is set to `/mnt/sdcard` on NuttX by default. * `env` contains `'experimental'` if the IoT.js was build with experimental support. **Example** ```js console.log('HOME: ' + process.env.HOME); // prints: HOME: /home/user ``` ### process.exitCode * {integer} **Default:** `0` The `exitCode` property can be used to specify the exit code of the IoT.js process. This will be used when the process exits gracefully, or exited via `process.exit()` without specifying an exit code. Specifying an exit code for the `process.exit()` call will override any previous setting of `process.exitCode`. ### process.iotjs * {Object} The `iotjs` property holds IoT.js related information in an object. The following keys can be accessed via this property: * `board` specifies the device type on which the IoT.js is running currently. For instance `'STM32F4DIS'`, `'RP2'`, or `'unknown'`. **Example** ```js console.log(process.iotjs.board); // on Raspberry 2 it prints: RP2 ``` ### process.platform * {string} The `platform` returns the identification of the operating system the IoT.js process is currently running on. For instance `'linux'`, `'darwin'`, `'nuttx'`, `'tizenrt'`, or `'unknown'`. ### process.chdir(path) * `path` {string} The path to change working directory to. The `chdir` method changes the current working directory of the IoT.js process or throws an exception if the operation fails (for instance the `path` specified does not exist). **Example** ```js try { process.chdir('/invalid/path'); } catch(err) { console.log('invalid path'); } // prints: invalid path ``` ### process.cwd() * Returns: {string} The `cwd()` call returns the current working directory of the IoT.js process. **Example** ```js console.log('Current dir: ' + process.cwd()); ``` ### process.exit([code]) * `code` {integer} The exit code. **Default:** `0` The `exit()` method instructs the IoT.js to terminate the process synchronously with an exit status of `code`. If `code` is not specified, exit uses the `process.exitCode` value which defaults to `0`. IoT.js will not exit till all `'exit'` event listeners are called. The `process.exit()` method call will force the process to exit as quickly as possible, ignoring if there is any asynchronous operations still pending. In most situations, it is not necessary to explcitly call `process.exit()`. The IoT.js will exit on its own if there is no additional work pending in the event loop. The `process.exitCode` property can be set to exit code when the process exits gracefully. If it is necessary to terminate the IoT.js process due to an error condition, throwing an uncaught error and allowing the process to terminate accordingly is advised instead of calling `process.exit()`. **Example** To exit with a failure code: ```js process.exit(1); ``` The shell that executed the IoT.js should see the returned exit code as `1`. To set the exit code on graceful exit: ```js doSomeWork() process.exitCode = 1; ``` ### process.nextTick(callback) * `callback` {Function} The `nextTick` method adds the `callback` method to the "next tick queue". Once the current turn of the event loop is completed, all callbacks currently in the next tick queue will be called. This is not a simple alias to `setTimeout` call. It runs before any additional I/O events. **Example** ```js console.log('step 1'); process.nextTick(function() { console.log('step 2'); }); console.log('step 3'); // prints: // step 1 // step 3 // step 2 ``` ### Event: 'exit' * `callback` {Function} * `code` {integer} exitCode The `'exit'` event is emitted when the IoT.js process is about to exit. This can happen two ways: * The `process.exit()` method was called explicitly; * The IoT.js event loop does not have any additional work to perform. There is no way to prevent the exiting, and once all `'exit'` listeners have finished running the process will terminate. The listener callback function is invoked with the exit code specified either by the `process.exitCode` property, or the `exitCode` argument passed to the `process.exit()` method. Listener functions *must* only perform *synchronous* operations. The IoT.js process will exit immediately after calling the `'exit'` event listeners causing any additional work still queued to be abandoned. **Example** ```js process.on('exit', function(code) { console.log('exited with: ' + code); }); ``` ### Event: 'uncaughtException' * `callback` {Function} * `err` {Error} error object uncaught by catch handler The `'uncaughtException'` event is emitted when an uncaught JavaScript exception bubbles all the way back to the event loop. By default, IoT.js handles such exceptions by printing it to `stderr` and exiting. Adding a handler for the `'uncaughtException'` event overrides the default behavior. The listener function is called with the `Error` object passed as the only argument. **Warning: Using the `'uncaughtException'` event correctly** This event is a crude mechanism for exception handling intended to be used only as a last resort. The event should not be used as an eqivalent to 'On Error Resume Next'. Unhandled exceptions inherently mean that a program is in an unknown state. Thus attempting to resume the application code without properly recovering from the exception can cause unforeseen/unpredictable issues. Only one exception thrown within the event handler will be caught and will immediately terminate the application. The correct use of the event is to perform synchronous cleanup of allocated resources (e.g. file descriptors, handles, etc) before shutting down the process. **It is not safe to resume normal operation after this event**. To restart a crashed application in a more reliable way, whether uncaughtException is emitted or not, an external monitoring application should be employed in a separate process to detect application failures and recover or restart as needed. **Example** ```js process.on('uncaughtException', function(err) { console.log('Something went wrong: ' + err); }); nonExistentFunctionCall(); console.log('This will not be printed.'); ``` iotjs-1.0/docs/api/IoT.js-API-SPI.md000066400000000000000000000075451312466455500167210ustar00rootroot00000000000000### Platform Support The following shows spi module APIs available for each platform. | | Linux
(Ubuntu) | Raspbian
(Raspberry Pi) | NuttX
(STM32F4-Discovery) | | :---: | :---: | :---: | :---: | | spi.open | O | O | X | | spibus.transfer | O | O | X | | spibus.transferSync | O | O | X | | spibus.close | O | O | X | | spibus.closeSync | O | O | X | ## Class: SPI SPI (Serial Peripheral Interface) is a communication protocol which defines a way to communicate between devices. ### new SPI() Returns a new SPI object which can open SPI bus. ### SPI.MODE The clock polarity and the clock phase can be specified as `0` or `1` to form four unique modes to provide flexibility in communication between devices. The `SPI.MODE` will specify which one to use (the combinations of the polarity and phase). * `0` Clock Polarity(0), Clock Phase(0), Clock Edge(1) * `1` Clock Polarity(0), Clock Phase(1), Clock Edge(0) * `2` Clock Polarity(1), Clock Phase(0), Clock Edge(1) * `3` Clock Polarity(1), Clock Phase(1), Clock Edge(0) ### SPI.CHIPSELECT * `NONE` * `HIGH` The chip select is an access-enable switch. When the chip select pin is in the `HIGH` state, the device responds to changes on its input pins. ### SPI.BITORDER * `MSB` The most significant bit. * `LSB` The least significant bit. Sets the order of the bits shifted out of and into the SPI bus, either MSB (most-significant bit first) or LSB (least-significant bit first). ### spi.open(configuration[, callback]) * `configuration` {Object} * `device` {string} The specified path for `spidev`. * `mode` {SPI.MODE} The combinations of the polarity and phase. **Default:** `SPI.MODE[0]`. * `chipSelect` {SPI.CHIPSELECT} Chip select state. **Default:** `SPI.CHIPSELECT.NONE`. * `maxSpeed` {number} Maximum transfer speed. **Default:** `500000`. * `bitsPerWord` {number} Bits per word to send (should be 8 or 9). **Default:** `8`. * `bitOrder` {SPI.BITORDER} Order of the bits shifted out of and into the SPI bus. Default: `SPI.BITORDER.MSB`. * `loopback` {boolean} Using loopback. **Default:** `false`. * `callback` {Function}. * `err` {Error|null}. * Returns: {SPIBus}. Opens an SPI device with the specified configuration. **Example** ```js var Spi = require('spi'); var spi = new Spi(); var spi0 = spi.open({ device: '/dev/spidev0.0' }, function(err) { if (err) { throw err; } }); ``` ## Class: SPIBus The SPIBus is commonly used for communication. ### spibus.transfer(txBuffer, rxBuffer[, callback]) * `txBuffer` {Array|Buffer}. * `rxBuffer` {Array|Buffer}. * `callback` {Function}. * `err` {Error|null}. Writes and reads data from the SPI device asynchronously. The `txBuffer` and `rxBuffer` must have equal length. **Example** ```js var tx = new Buffer('Hello IoTjs'); var rx = new Buffer(tx.length); spi0.transfer(tx, rx, function(err) { if (err) { throw err; } var value = ''; for (var i = 0; i < tx.length; i++) { value += String.fromCharCode(rx[i]); } console.log(value); }); ``` ### spibus.transferSync(txBuffer, rxBuffer) * `txBuffer` {Array|Buffer}. * `rxBuffer` {Array|Buffer}. Writes and reads data from the SPI device synchronously. The `txBuffer` and `rxBuffer` must have equal length. **Example** ```js var tx = new Buffer('Hello IoTjs'); var rx = new Buffer(tx.length); spi0.transferSync(tx, rx); var value = ''; for (var i = 0; i < tx.length; i++) { value += String.fromCharCode(rx[i]); } console.log(value); ``` ### spibus.close([callback]) * `callback` {Function}. * `err` {Error|null}. Closes the SPI device asynchronously. The `callback` function will be called after the SPI device is closed. **Example** ```js spi0.close(function(err) { if (err) { throw err; } console.log('spi bus is closed'); }); ``` ### spibus.closeSync() Closes the SPI device synchronously. **Example** ```js spi.closeSync(); console.log('spi bus is closed'); ``` iotjs-1.0/docs/api/IoT.js-API-Stream.md000066400000000000000000000247501312466455500175160ustar00rootroot00000000000000### Platform Support The following shows stream module APIs available for each platform. | | Linux
(Ubuntu) | Raspbian
(Raspberry Pi) | NuttX
(STM32F4-Discovery) | | :---: | :---: | :---: | :---: | | readable.isPaused | O | O | O | | readable.pause | O | O | O | | readable.read | O | O | O | | readable.resume | O | O | O | | writable.end | O | O | O | | writable.write | O | O | O | # Stream A stream is an abstract interface for working with streaming data. Streams can be readable, writable, or both (duplex). All streams are instances of EventEmitter. ## Class: Stream ### new Stream() **This method is only for implementing a new stream type.** This function registers the common properties of all streams. **Example** ```js var Stream = require('stream').Stream; var stream = new Stream(); stream.read = function () { // A custom read function. } ``` ## Class: Stream.Readable Readable stream is an abstraction for a *data source* from which data will be read. At any time a readable stream operates in one of two modes: *flowing* and *paused*. All streams begin in paused mode. In paused mode the stream emits [`'readable'`](#event-readable) event every time a new data is available for read. This data can be read by calling the [`readable.read()`](#readablereadsize) function. A stream can be switched to paused mode by calling the [`readable.pause()`](#readablepause) function. In flowing mode the stream emits [`'data'`](#event-data) events every time when data is received. The data buffer is passed to the callback function. A stream can be switched to flowing mode by calling the [`readable.resume()`](#readableresume) function or by adding a [`'data'`](#event-data) event handler. Supported events: ### Event: 'close' Emitted when the underlying resource has been closed and no more events will be emitted. Not all [`Readable`](#class-streamreadable) streams will emit the `'close'` event. ### Event: 'data' * `chunk` {Buffer|string} Emitted when the stream passes the ownership of the data to a consumer. Only streams in flowing mode emit this event. A stream can be switched to flowing mode by calling the [`readable.resume()`](#readableresume) function or by adding a `'data'` event handler. **Example** ```js var Readable = require('stream').Readable; var readable = new Readable(); readable.on('data', function (chunk) { // prints: data received: message console.log('data received: ' + chunk); }) readable.push("message"); ``` ### Event: 'end' Emitted when there is no more data to be consumed from the stream. **Example** ```js var Readable = require('stream').Readable; var readable = new Readable(); readable.on('end', function () { // prints: no more data console.log('no more data'); }) readable.push(null); ``` ### Event: 'error' * `error` {Object} Emitted when an error is detected by the readable stream. This event may occure any time. ### Event: 'readable' Emitted when there is data available to be read from the stream. This event will also be emitted once the end of the stream data has been reached but before the ['end'](#event-end) event is emitted. **Example** ```js var Readable = require('stream').Readable; var readable = new Readable(); readable.on('readable', function () { // prints:. console.log('data received: ' + this.read()); }) readable.push('message'); ``` ### new Readable(options) * `options` {Object} * `defaultEncoding` {string} **Default:** `utf8` **This method is only for implementing a new [`Readable`](#class-streamreadable) stream type.** This function registers the common properties of [`Readable`](#class-streamreadable) streams. The `options` object allows passing configuration arguments. The `Readable` constructor only supports a few members of the `options` object but descendants may supports more of them. **Example** ```js var Readable = require('stream').Readable; var readable = new Readable({ defaultEncoding: 'utf8' }); ``` ### readable.isPaused() * Returns: {boolean} Returns `true` if the [`Readable`](#class-streamreadable) stream is in paused mode. Otherwise the stream is in flowing mode. By default the stream starts in paused mode. **Example** ```js var Readable = require('stream').Readable; var readable = new Readable(); // prints: true console.log(readable.isPaused()); ``` ### readable.pause() * Returns: {Readable} Stops emitting [`'data'`](#event-data) events if the stream is in flowing mode and sets paused mode. No effect otherwise. **Example** ```js var Readable = require('stream').Readable; var readable = new Readable(); readable.pause(); ``` ### readable.read([size]) * `size` {number} Specify how much data will be read. * Returns: {Buffer|null} The `readable.read()` method pulls some data out of the internal buffer and returns it. If no data is available `null` is returned instead. Note: currently all data must be read. **Example** ```js var Readable = require('stream').Readable; var readable = new Readable(); // prints: null console.log(readable.read()); readable.push('message'); // prints: message console.log(readable.read()); ``` ### readable.resume() * Returns: {Readable} Starts emitting [`'data'`](#events-data) events if the stream is in paused mode and sets flowing mode. No effect otherwise. **Example** ```js var Readable = require('stream').Readable; var readable = new Readable(); readable.resume(); ``` ### readable.push(chunk) * `chunk` {Buffer|string} **This method is only for implementing a new [`Readable`](#class-streamreadable) stream type.** Push a chunk of data to the underlying `Buffer` of this stream. The data can be read by using either [`readable.read()`](#readablereadsize) method or [`'data'`](#event-data) event of this stream. **Example** ```js var Readable = require('stream').Readable; var readable = new Readable(); readable.push('message'); // prints: message console.log(readable.read()); ``` # Class: Stream.Writable Writable stream is an abstraction for a *destination* to which data is written. Several functions of the Stream.Writable class are abstract interfaces and descendants can override them. The [`new Stream.Writable()`](#new-streamwritableoptions) constructor must be used for initializing a writable stream and [`writable._write()`](#writable_writechunk-callback-onwrite) method are required to be implemented. Supported events: ### Event: 'drain' If [`writable.write()`](#writablewritechunk-callback) returns `false` the stream emits a `drain` event when it is appropriate to resume writing data into the stream. **Example** ```js var Writable = require('stream').Writable; // Buffer is full after 1 byte of data. var writable = new Writable({ highWaterMark:1 }); writable._write = function(chunk, callback, onwrite) { onwrite(); } // Writes 1 byte data into the stream. writable.write("X"); writable.on('drain', function() { // prints: can continue writing console.log('can continue writing'); }); writable._readyToWrite(); ``` ### Event: 'error' * `err` {Error} Emitted if an error occures during writing the data. ### Event: 'finish' Emitted after [`writable.end()`](#writableendchunk-callback) has been called and all pending data has been flushed. **Example** ```js var Writable = require('stream').Writable; var writable = new Writable(); writable.on('finish', function() { // prints: end of writing console.log('end of writing'); }); writable.end(); ``` ### new Stream.Writable([options]) * `options` {Object} * `highWaterMark` {number} **This method is only for implementing a new [`Writable`](#class-streamwritable) stream type.** This function registers the common properties of [`Writable`](#class-streamwritable) streams. When the size of the internal buffer reaches `options.highWaterMark` the [`writable.write()`](#writablewritechunk-callback) method starts returning with `false` and the data should be drained before further data is written. **Example** ```js var Writable = require('stream').Writable; var writable = new Writable({ highWaterMark:256 }); ``` ### writable.end([chunk[, callback]]) * `chunk` {Buffer|string} Final data to write. * `callback` {Function} Calling this function signals that no more data will be written to the Writable. The optional `chunk` argument allows writing a final chunk of data. If `chunk` is `null` no data is written. The optional `callback` function is attached as a listener for the ['finish'](#event-finish) event. **Example** ```js var Writable = require('stream').Writable; var writable = new Writable(); writable.end(); ``` ### writable.write(chunk[, callback]) * `chunk` {Buffer|string} Data to write. * `callback` {Function} Called when this chunk of data is flushed. * Returns: {boolean} Converts `chunk` into a sequence of bytes and writes this data to the stream. An optional `callback` function is called when the data is flushed. The returned value is `true` if writing can be continued right after calling this method. Otherwise the returned value is `false` and no data should be written until the [`'drain'`](#event-drain) event is received. **Example** ```js var Writable = require('stream').Writable; var writable = new Writable(); writable.write("String"); ``` ### writable._readyToWrite() **This method is only for implementing a new [`Writable`](#class-streamwritable) stream type.** This method informs the [`Writable`](#class-streamwritable) stream that the implementation is ready for receiving data. **Example** ```js var Writable = require('stream').Writable; var writable = new Writable(); writable._readyToWrite(); ``` ### writable._write(chunk, callback, onwrite) * `chunk` {Buffer|string} The data to be written by the stream. * `callback` {Function} Callback to be called when the chunk of data is flushed. * `onwrite` {Function} Internal Callback to be called for when the chunk of data is flushed. **This method is only for implementing a new [`Writable`](#class-streamwritable) stream type.** This internal method is called by the [`Writable`](#class-streamwritable) stream and the implementation **must** override it. The data to be written is passed as the `chunk` argument. After the operation is completed, both `callback` and `onwrite` function should be called. **Example** ```js var Writable = require('stream').Writable; var writable = new Writable(); writable._write = function(chunk, callback, onwrite) { // prints: message console.log(chunk); onwrite(); if (callback) callback(); } writable._readyToWrite(); writable.write('message'); ``` # Class: Stream.Duplex Duplex streams are streams that implement both the Readable and Writable interfaces. iotjs-1.0/docs/api/IoT.js-API-Timers.md000066400000000000000000000054231312466455500175220ustar00rootroot00000000000000### Platform Support The following shows timer module APIs available for each platform. | | Linux
(Ubuntu) | Raspbian
(Raspberry Pi) | NuttX
(STM32F4-Discovery) | | :---: | :---: | :---: | :---: | | setTimeout | O | O | O | | clearTimeout | O | O | O | | setInterval | O | O | O | | clearInterval | O | O | O | # Timers The `timer` module exposes a global API for scheduling functions to be called at some future period of time. Because the timer functions are globals, there is no need to call require('timers') to use the API. ### setTimeout(callback, delay[, args..]) * `callback` {Function} The function to call when the timer elapses. * `...args` {any} * `delay` {number} The number of milliseconds to wait before calling the `callback`. * `...args` {any} - Optional arguments to pass when the `callback` is called. * Returns: {Timeout} Schedules execution of a one-time `callback` after `delay` milliseconds. Returns a `Timeout` for use with `clearTimeout()`. If `callback` is not a function, a `TypeError` will be thrown. **Example** ```js var timeout = setTimeout(function() { // Do something which will be executed after one second. }, 1000); ``` ### clearTimeout(timeout) * `timeout` {Timeout} A Timeout object returned by `setTimeout()`. Cancels a `Timeout` object created by `setTimeout()`. **Example** ```js var timeout = setTimeout(function() { }, 1000); ... clearTimeout(timeout); ``` ### setInterval(callback, delay[, args..]) * `callback` {Function} The function to call when the timer elapses. * `...args` {any} * `delay` {number} The number of milliseconds to wait before calling the `callback`. * `...args` {any} - Optional arguments to pass when the `callback` is called. * Returns: {Timeout} Schedules repeated execution of `callback` every `delay` milliseconds. Returns a `Timeout` object for use with `clearInterval()`. If `callback` is not a function, a `TypeError` will be thrown. **Example** ```js var timeout = setInterval(function() { // Do something which will be executed repeatadly one time per second. }, 1000); ``` ### clearInterval(timeout) * `timeout` {Timeout} A Timeout object as returned by `setInterval()`. Cancels a `Timeout` object created by `setInterval()`. **Example** ```js var timeout = setInterval(function() { }, 1000); ... clearInterval(timeout); ``` ## Class: Timeout This object is created internally and is returned from `setTimeout()` and `setInterval()`. ### timeout.ref() When called, requests that the IoT.js event loop should not exit as long as the `Timeout` is active. ### timeout.unref() When called, the active `Timeout` object will not force the IoT.js event loop to remain active. If there are no other scheduled activites, the process may exit, the process may exit before the `Timeout` object's callback is invoked. iotjs-1.0/docs/api/IoT.js-API-UART.md000066400000000000000000000060121312466455500170250ustar00rootroot00000000000000### Platform Support The following shows uart module APIs available for each platform. | | Linux
(Ubuntu) | Raspbian
(Raspberry Pi) | NuttX
(STM32F4-Discovery) | | :---: | :---: | :---: | :---: | | uart.open | O | O | O | | uartport.write | O | O | O | | uartport.writeSync | O | O | O | | uartport.close | O | O | X | | uartport.closeSync | O | O | X | ## Class: UART The UART (Universal Asynchronous Receiver/Transmitter) class supports asynchronous serial communication. ### new UART() Returns with a new UART object. ### uart.open(configuration[, callback]) * `configuration` {Object} * `device` {string} Mandatory configuration. * `baudRate` {number} Specifies how fast data is sent over a serial line. **Default:** `9600`. * `dataBits` {number} Number of data bits that are being transmitted. **Default:** `8`. * `callback` {Function}. * `err` {Error|null}. * Returns: {UARTPort}. Opens an UARTPort object with the specified configuration. The `baudRate` must be equal to one of these values: [0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800, 9600, 19200, 38400, 57600, 115200, 230400]. The `dataBits` must be equal to one of these values: [5, 6, 7, 8]. On NuttX, you also need to set the properties of the `configuration` in the NuttX configuration file. Using the NuttX menuconfig, it can be found at the `Device Drivers -> Serial Driver Support -> U[S]ART(N) Configuration` section. You can read more information about the usage of the UART on stm32f4-discovery board: [STM32F4-discovery](../targets/nuttx/stm32f4dis/IoT.js-API-Stm32f4dis.md#uart). **Example** ```js var Uart = require('uart'); var uart = new Uart(); var configuration = { device: '/dev/ttyUSB0' baudRate: 115200, dataBits: 8, } var serial = uart.open(configuration, function(err) { // Do something. }); ``` ## Class: UARTPort The UARTPort class is responsible for transmitting and receiving serial data. ### uartport.write(data[, callback]). * `data` {string}. * `callback` {Function}. * `err` {Error|null}. Writes the given `data` to the UART device asynchronously. **Example** ```js serial.write('Hello?', function(err) { if (err) { // Do something. } serial.close(); }); ``` ### uartport.writeSync(data) * `data` {string}. Writes the given `data` to the UART device synchronously. **Example** ```js serial.writeSync('Hello?'); serial.close(); ``` ### uartport.close([callback]) * `callback` {Function}. * `err` {Error|null)}. Closes the UART device asynchronously. On NuttX/STM32F4Discovery, Uart.close() blocks after close(). It seems that poll() does not work properly on NuttX for some cases. ### uartport.closeSync() Closes the UART device synchronously. On NuttX/STM32F4Discovery, Uart.close() blocks after close(). It seems that poll() does not work properly on NuttX for some cases. ### Event: 'data' * `callback` {Function} * `data` {string} A string from the sender. **Example** ```js /* ... */ serial.on('data', function(data) { console.log('read result: ' + data.toString()); }); ``` iotjs-1.0/docs/api/IoT.js-API-reference.md000066400000000000000000000013011312466455500202040ustar00rootroot00000000000000# IoT.js modules ## Basic API * [Assert](IoT.js-API-Assert.md) * [Buffer](IoT.js-API-Buffer.md) * [DNS](IoT.js-API-DNS.md) * [Events](IoT.js-API-Events.md) * [File System](IoT.js-API-File-System.md) * [HTTP](IoT.js-API-HTTP.md) * [Module](IoT.js-API-Module.md) * [Net](IoT.js-API-Net.md) * [Process](IoT.js-API-Process.md) * [Timers](IoT.js-API-Timers.md) ## Extended API * [(ADC)](IoT.js-API-ADC.md) * [(BLE)](IoT.js-API-BLE.md) * [(GPIO)](IoT.js-API-GPIO.md) * [(I2C)](IoT.js-API-I2C.md) * [(PWM)](IoT.js-API-PWM.md) * [(SPI)](IoT.js-API-SPI.md) * [(UART)](IoT.js-API-UART.md) * [UDP/Datagram](IoT.js-API-DGRAM.md) ## Abstract interfaces * [Stream](IoT.js-API-Stream.md) *() not supported by node.js iotjs-1.0/docs/build/000077500000000000000000000000001312466455500145445ustar00rootroot00000000000000iotjs-1.0/docs/build/Build-Script.md000066400000000000000000000123771312466455500174010ustar00rootroot00000000000000## Overview build.py help you build IoT.js. It locates in "./tools" directory of source tree. It automatically creates a directory where build object and outputs will be generated, checks configurations, tidiness of source code, licenses, and more. Also it downloads, updates and builds submodules. And finally generate IoT.js binary. ## How to use You can build IoT.js with default setting for your host machine with; ``` ./tools/build.py ``` The command will generate runnable IoT.js binary in "./build//debug/iotjs/iotjs". You can also build release binary with; ``` ./tools/build.py --buildtype=release ``` ## Parameters Candidates **NOTE: some parameters are not supported by current version of build.py** -- #### `--buildtype` * `release` | `debug` Specify whether build output will be for 'debug' or 'release'. ``` ./tools/build.py --buildtype=release ``` -- #### `--builddir` Specify a directory where build outputs will be generated. If given path is not exist, build.py will create it. ``` ./tools/build.py --builddir=./build ``` -- #### `--clean` With given this option, build.py will clear all the build directory before start new build. ``` ./tools/build.py --clean ``` -- #### `--buildlib` With given this option, build.py will generate IoT.js output as a library. ``` ./tools/build.py ---buildlib ``` -- #### `--target-arch` * `arm` | `x86` | `i686` | `x86_64` | `x64` Specify target architecture. ``` ./tools/build.py --target-arch=arm ``` -- #### `--target-os` * `linux` | `darwin` | `osx` | `nuttx` Specify target OS. ``` ./tools/build.py --target-os=nuttx --target-arch=arm ``` -- #### `--target-board` * `stm32f4dis` | empty Specify target board. ``` ./tools/build.py --target-os=nuttx --target-arch=arm --target-board=stm32f4dis ``` -- #### `--cmake-param` Specify CMake parameters for IoT.js. "cmake" command for IoT.js will be executed with the given parameter applied. If you have multiple parameters, supply it with multiple use of this option; ``` ./tools/build.py --cmake-param="..." --cmake-param="..." ``` -- #### `--compile-flag` Specify C compiler flags for IoT.js. If you have multiple compile flags, supply it with multiple use of this option; ``` ./tools/build.py --compile-flag="..." --compile-flag="..." ``` -- #### `--link-flag` Specify linker flags for IoT.js. If you have multiple link flags, supply it with multiple use of this option; ``` ./tools/build.py --link-flag="..." --link-flag="..." ``` -- #### `--external-include-dir` Specify external include directory for IoT.js. If you have multiple external include directoies, supply it with multiple use of this option; ``` ./tools/build.py --external-include-dir="..." --external-include-dir="..." ``` -- #### `--external-static-lib` Specify external static library that will be liked with IoT.js statically. If you have multiple such libraries, supply it with multiple use of this option; ``` ./tools/build.py --external-static-lib="libxxx.a" ``` -- #### `--jerry-cmake-param` Specify CMake parameters for JerryScript. "cmake" command for JerryScript will be executed with the given parameter applied. If you have multiple parameters, supply it with multiple use of this option -- #### `--jerry-compile-flag` Specify C compiler flags for JerryScript. If you have multiple cflags, supply it with multiple use of this option ``` ./tools/build.py --jerry-compile-flag="-DCONFIG_ECMA_LCACHE_DISABLE" ``` -- #### `--jerry-link-flag` Specify linker flags for JerryScript. If you have multiple ldflags, supply it with multiple use of this option -- #### `--jerry-heaplimit` Specify object heap limit for JerryScript engine. ``` ./tools/build.py --jerry-heaplimit=80 ``` -- #### `--jerry-memstat` Enable memstat of JerryScript engine. ``` ./tools/build.py --jerry-memstat ``` -- #### `--jerry-lto` With given this option, JerryScript will be built with LTO. ``` ./tools/build.py --jerry-lto ``` -- #### `--no-init-submodule` With given this option, submoduls will not initialized before start build. ``` ./tools/build.py --no-init-submodule ``` -- #### `--no-check-tidy` With given this option, tidy checking will not performed. ``` ./tools/build.py --no-check-tidy ``` -- #### `--no-check-test` With given this option, unit test checking will not performed. ``` ./tools/build.py --no-check-test ``` -- #### `--no-parallel-build` With given this option, compilation process will not run in parallel. In other words, executes `make` without `-j` option. ``` ./tools/build.py --no-parallel-build ``` -- #### `--nuttx-home` To build for nuttx os, nuttx home directory must be given. ``` ./tools/build.py --target-os=nuttx --target-arch=arm --target-board=stm32f4dis --nuttx-home="..." ``` -- #### `--config` Specify build configuration file path. ``` ./tools/build.py --config=build.arm.nuttx.stm32f4dis.config ``` `build.default.config` file is in the source tree for default setting. If this option is not specified, `build.config` file will be applied. If the file is not exist, it will be copied from `build.default.config`. Parameters specified by the config file is applied, and then the parameters given by command line overwrite over the settings. If you need to apply the same set of parameters for each build, making your own config file and trigger build.py with the config file would be more convenient.iotjs-1.0/docs/build/Build-for-ARTIK.md000066400000000000000000000020641312466455500175630ustar00rootroot00000000000000## Build IoT.js for ARTIK ### Tizen on ARTIK10 cross-compile #### Prerequisites * ARTIK10 with Tizen (https://wiki.tizen.org/wiki/Tizen_On_ARTIK) * Tizen Studio with Native app development CLI tools This is required to get rootstrap for Tizen (set of native libraries). * arm-linux-gnueabi-gcc cross compiler (can be found in Tizen Studio / Native toolchain) #### Building 1. Make sure arm-linux-gnueabi-gcc is in path 2. Locate Tizen SDK. Default location is: ~/tizen-studio 3. In platforms/tizen-3.0/mobile there should be compatible rootstrap (eg. mobile-3.0-device) Compile: ``` bash tools/build.py \ --target-arch=arm --target-os=tizen --target-board=artik10 \ --compile-flag="--sysroot=~/tizen-studio/platforms/tizen-3.0/mobile/rootstraps/mobile-3.0-device.core/" ``` #### Testing Transfer iotjs binary and test file to the device: ``` bash sdb push ./build/arm-tizen/debug/bin/iotjs /home/owner/iotjs/ sdb push ./test/run_pass/test_console.js /home/owner/iotjs/ ``` Run the test: ``` bash sdb shell $ cd /home/owner/iotjs $ ./iotjs test_console.js ``` iotjs-1.0/docs/build/Build-for-Linux.md000066400000000000000000000152221312466455500200100ustar00rootroot00000000000000### Overall steps to build for Linux 1. Get the sources 2. Build all at once 3. Execute IoT.js 4. Clean build directory *** #### Build Host Ubuntu 14.04 is recommended. Other Unix like platforms can be used. If it doesn't seem to work properly on other platforms, please look into the [Issues](https://github.com/Samsung/iotjs/issues) page. Someone may have already tried. If you can't find any related one, please leave an issue for help. #### Directory structure This document assumes 'harmony' as the root directory. _JerryScript_, _libtuv_ and _libuv_ are included as sub-modules in `deps` directory. * harmony * iotjs * deps * http-parser * jerry * libuv * libtuv ※ harmony? It's from the initial code name of our project. (_Sounds good, isn't it? :)_) #### Prerequisite You need to install some packages to build IoT.js, as follows; ``` sudo apt-get install gyp cmake build-essential valgrind ``` gcc compiler 4.8 or higher versions are required to compile. If you don't know how to do it, you can get some help from [how-to-install-gcc-4-8](http://askubuntu.com/questions/271388/how-to-install-gcc-4-8) or google. ### 1. Get the sources Clone our repository to look around and test it. If it attracts you and you want to try something interested, please fork it. To get the source for this repository, ``` cd harmony git clone https://github.com/Samsung/iotjs.git cd iotjs ``` Sub-modules(_http-parser_, _JerryScript_, _libuv_ and _libtuv_) will be pulled. And matching hash will be checked out for your current IoT.js version when you run the build script. ### 2. Build all at once IoT.js and required sub-modules are generated all at once in tools directory with build.py. ``` cd iotjs ./tools/build.py ``` #### Set build options Some basic options are provided. Existing build options are listed as follows; ``` buildtype=debug|release (debug is default) builddir=build (build is default) clean buildlib (default is False) target-arch=x86|x86_64|x64|i686|arm (depends on your host platform) target-os=linux|nuttx|darwin|osx (linux is default) target-board cmake-param compile-flag link_flag external-include-dir external-static-lib external-shared-lib iotjs-include-module iotjs-exclude-module jerry-cmake-param jerry-compile-flag jerry-link-flag jerry-lto jerry-heap-section jerry-heaplimit (default is 81, may change) jerry-memstat (default is False) no-init-submodule (default is init) no-check-tidy (default is check) no-check-test (default is check) no-parallel-build no-snapshot nuttx-home= (no default value) ``` To give options, please use two dashes '--' before the option name as described in the following sections. Options that may need explanations. * builddir: compile intermediate and output files are generated here. * buildlib: generating _iotjs_ to a library if True(e.g. for NuttX). give __--buildlib__ to make it True. * jerry-heaplimit: JerryScript default heap size (as of today) is 256Kbytes. This option is to change the size for embedded systems, NuttX for now, and current default is 81KB. For linux, this has no effect. While building nuttx if you see an error `region sram overflowed by xxxx bytes`, you may have to decrease about that amount. * jerry-memstat: turn on the flag so that jerry dumps byte codes and literals and memory usage while parsing and execution. * no-check-tidy: no checks codes are tidy. we recommend to check tidy. * no-check-test: do not run all tests in test folder after build. * nuttx-home: it's NuttX platform specific, to tell where the NuttX configuration and header files are. If you want to know more details about options, please check the [Build Script](Build-Script.md) page. #### Include extended module There are two ways to include [extended module](../api/IoT.js-API-reference.md). The first way is to modify a property value of module in `build.config` file. You can move a module name from 'exclude' to 'include'. The second way is by using build options which is `--iotjs-include-module`. If you enter several modules, separate them with a comma. ``` ./tools/build.py --iotjs-include-module=dgram,pin,gpio ``` #### Options example It's a good practice to build in separate directory, like 'build'. IoT.js generates all outputs into separate **'build'** directory. You can change this by --builddir option. Usually you won't need to use this option. Target and architecture name are used as a name for a directory inside 'build' directory. To build debug version, type the command like below. And you can find the binary in 'output' directory. ``` ./tools/build.py --builddir=output ``` To build 32bit version in x86_64 with debug version as a library, type the command like below. ``` ./tools/build.py --target-arch=i686 --buildlib ``` To build release version with different jerry revision, type the command like below. (Assume that you have already checked it out.) ``` ./tools/build.py --buildtype=release --no-init-submodule ``` #### Build only IoT.js with given build option This section for explaining how to build only IoT.js when you did some modification. IoT.js uses [CMake](http://www.cmake.org/) for makefile generation. You can go inside the build folder and build with 'make' command. Go inside where your target platform name is, for example x86_64 linux, ``` cd build/x86_64-linux/release/iotjs make ``` #### What build script does 1. It will clone sub-modules, this will be done only once when version hash has not changed. 2. Checkout matching version for each sub-modules. 3. Build sub-modules, you can see the outputs at build/(target-arch)-(target-os)/(buildtype)/libs folder. 4. Build IoT.js ### 3. Execute IoT.js Executable name is **'iotjs'** and resides in (target-arch)-(target-os)/(buildtype)/iotjs. To run greetings JavaScript in test folder, for example; ``` ./build/x86_64-linux/debug/iotjs/iotjs ./test/run_pass/test_console.js ``` #### Set execution Options Some execution options are provided as follows; ``` memstat show-opcodes ``` To give options, please use two dashes '--' before the option name as described in following sections. For more details on options, please see below. * memstat: dump memory statistics. To get this, must build with __jerry-memstat__ option. * show-opcodes: print compiled byte-code. #### Options example To print memory statistics, follow the below steps; ``` ./tools/build.py --jerry-memstat ./build/x86_64-linux/debug/iotjs/iotjs --memstat ./test/run_pass/test_console.js ``` With given `show-opcodes` option, opcodes will be shown. ``` ./build/x86_64-linux/debug/iotjs/iotjs --show-opcodes ./test/run_pass/test_console.js ``` ### 4. Clean build directory Just remove the folder as follows; ``` rm -rf build rm -rf deps/libuv/out ``` iotjs-1.0/docs/build/Build-for-NuttX.md000066400000000000000000000104431312466455500177730ustar00rootroot00000000000000## Build IoT.js with NuttX ### Target board We work on STM32F4 board for NuttX and the detail of the reference board is well described at [STM32F4-discovery with BB](http://www.st.com/web/en/catalog/tools/FM116/SC959/SS1532/LN1199/PF255417). ### Relation with STM board? We do not have any business relation with STM board. It is selected because it has enough RAM and Flash ROM, so that development can be more comfortable. And it has lots of pins to play with. When IoT.js is built up and optimized, it may work in devices having smaller resource. ### 1. Prepare for prerequisite #### Linux ```bash $ sudo apt-get install autoconf libtool gperf flex bison autoconf2.13 $ sudo apt-get install cmake libncurses-dev libusb-1.0-0-dev $ sudo apt-get install libsgutils2-dev gcc-arm-none-eabi minicom ``` To use menuconfig in NuttX, you may need to install kconfig frontend. ```bash $ git clone https://github.com/jameswalmsley/kconfig-frontends.git $ cd kconfig-frontends $ ./bootstrap $ ./configure --enable-mconf $ make $ sudo make install $ sudo ldconfig ``` #### macOS * Install Xcode from the app store and run once Xcode to install components. * Install Xcode command line tools. ```bash $ xcode-select --install ``` * Install [Homebrew package manager](http://brew.sh/) * Install packages ```bash $ brew tap PX4/homebrew-px4 $ brew update $ brew install cmake bash-completion pkg-config kconfig-frontends $ brew install gcc-arm-none-eabi libusb minicom ``` ### 2. Build NuttX (For the first time) To generate headers which are required to build IoT.js, for the first time, you need to build NuttX at least once. This time NuttX build will be failed. But don't worry at this time. After one execution, you don't need this sequence any more. #### Supported NuttX version |Repository|Tag Name| |----------|:------:| | nuttx | nuttx-7.19 | | app | nuttx-7.19 | We only guarantee that the specified version will work well. It is recommended to check out with the specified tag from a git repository. #### Follow the instruction * [STM32F4-discovery](../targets/nuttx/stm32f4dis/README.md) ### 3. Build IoT.js for NuttX These options are needed. ```bash --target-arch=arm --target-os=nuttx --nuttx-home=/path/to/nuttx --target-board=stm32f4dis --jerry-heaplimit=[..] ``` For example, ```bash $ ./tools/build.py \ --target-arch=arm --target-os=nuttx --nuttx-home=../nuttx \ --target-board=stm32f4dis --jerry-heaplimit=78 ``` Library files will be generated like below when build is successful. ```bash $ ls build/arm-nuttx/release/lib libhttpparser.a libiotjs.a libjerrycore.a libtuv.a ``` ### 4. Build NuttX This time make command for NuttX has to be successful unlike above. #### Follow the instruction * [STM32F4-discovery](../targets/nuttx/stm32f4dis/README.md) ### 5. Run IoT.js #### USB Connection There are two USB Connections on the Target board. USB mini CN1 and USB micro CN5. Both USB ports need to be connected to your Host. CN1 is used for power and Flashing, but it will not appear as a device in Linux. CN5 is used for NSH and will appear as `/dev/ttyACM0(linux)` or `/dev/tty.usbmodem1(macOS)` when things work well. #### Use minicom ```bash // linux $ minicom --device=/dev/ttyACM0 // macOS $ minicom --device=/dev/tty.usbmodem1 ``` You may need to enable _Add Carriage Return_ option. * Press Ctrl-A + Z + U for short in minicom screen. (For linux user) * Press [Meta](http://osxdaily.com/2013/02/01/use-option-as-meta-key-in-mac-os-x-terminal/) + Z for short in minicom screen. (For macOS user) Press _Enter_ key several times to trigger NuttShell to start. If micro SD is enabled, you can copy any script file to it and run with _nsh_, for example; ``` NuttShell (NSH) nsh> mount -t vfat /dev/mmcsd0 /mnt/sdcard nsh> iotjs /mnt/sdcard/path_to_file.js ``` If you see ``` +-----------------------------+ | | | Cannot open /dev/ttyACM0! | | | +-----------------------------+ ``` and it stays on the screen, something is wrong. Blue LED may blink if NuttX is in abnormal state. Press black(reset) button on the board and try again. If you still see this warning message, begin with original NuttX code and check your board, USB line and other softwares. iotjs-1.0/docs/build/Build-for-RPi2.md000066400000000000000000000073471312466455500174760ustar00rootroot00000000000000## Build IoT.js with Raspberry Pi 2 IoT.js supports two build types: 1. Build on your desktop. We support Linux(Ubuntu) and macOS. - Cross compile 2. Build on Raspberry Pi 2. ### Setting Raspberry Pi IoT.js officially supports Raspbian. For more information, please visit [the official site](https://www.raspberrypi.org/downloads/raspbian/). #### Enable the I2C interface To use I2C module, the I2C interface must be enabled. From the command line type: ```bash sudo raspi-config ``` This will launch raspi-config utility. * Select "9 Advanced Options" * Select "A6 I2C" The screen will ask you to enable I2C interface. * Select "Yes" * Select "Ok" * Select "Finish" to return to the command line. Reboot your Raspberry Pi. #### Enable the PWM interface Raspberry Pi2 has two PWM outputs on the following pins. | PWM Number | GPIO PIN(FUNC) | | :---: | :---: | | PWM0 | GPIO12(4), GPIO18(2) | | PWM1 | GPIO13(4), GPIO19(2) | To use PWM module, you must add PWM overlays in `/boot/config.txt` file. For example, to get a single PWM on GPIO18, add overlays like below. ``` dtoverlay=pwm,pin=18,func=2 ``` For example, to get multi PWM on GPIO18 and GPIO19, add overlays like below. ``` dtoverlay=pwm-2chan,pin=18,func=2,pin2=19,func2=2 ``` For more information about overlays, refer to [README](https://github.com/raspberrypi/linux/blob/rpi-4.9.y/arch/arm/boot/dts/overlays/README). * Note that it is necessary to have root privileges in order to run PWM module. #### Enable the UART interface To use UART module, the UART interface must be enabled. In `/boot/config.txt` file, change the value of enable_uart from 0 to 1. ``` enable_uart=1 ``` To disable the serial console, edit the file `/boot/cmdline.txt`. remove the word phase ```"console=serial0,115200"``` or ```"console=ttyAMA0,115200"``` To enable the serial console, edit the file `/boot/cmdline.txt`. add the word phase ```"console=serial0,115200"``` or ```"console=ttyAMA0,115200"``` Reboot your Raspberry Pi. * Note for Raspberry Pi 3 : You should use /dev/ttyS0 instead of /dev/ttyAMA0 in RPI3. ### Build IoT.js on your desktop. #### Prerequisite ##### Linux Install arm linux cross compiler. ``` bash sudo apt-get install gcc-arm-linux-gnueabihf ``` ##### macOS Install arm linux cross compiler via [this site](http://www.welzels.de/blog/en/arm-cross-compiling-with-mac-os-x/). The default location for arm linux compiler toolchain is **"/usr/local/linaro/arm-linux-gnueabihf-raspbian"**. Then you need to locate c_compiler. In **"./cmake/config/arm-linux.cmake"**, ``` cmake SET(EXTERNAL_CMAKE_C_COMPILER /usr/local/linaro/arm-linux-gnueabihf-raspbian/bin/arm-linux-gnueabihf-gcc) ``` In **"./deps/libtuv/cmake/config/config_arm-linux.cmake"**, ``` cmake SET(CMAKE_C_COMPILER /usr/local/linaro/arm-linux-gnueabihf-raspbian/bin/arm-linux-gnueabihf-gcc) ``` #### Build IoT.js (Cross compile) Give `target-arch`, `target-os` and `target-board` options to the script named 'build.py', then the script do the rest for you. ``` bash ./tools/build.py --buildtype=[release|debug] --target-arch=arm \ --target-os=linux --target-board=rpi2 ``` #### Running in Raspberry Pi 2 This script gives you `build/arm-linux/release/iotjs/iotjs` or `build/arm-linux/debug/iotjs/iotjs`. Copy this binary with your favorite tool or `scp` like below. ``` bash scp build/arm-linux/release/bin/iotjs pi@(your RPi2 IP):/home/pi/. ``` Lastly, open a shell and run with your test program. ``` bash ssh pi@(your RPi2 IP) ./iotjs (your test program) ``` ### Build IoT.js on Raspberry Pi 2 #### Prerequisite Install cmake. ```bash sudo apt-get update sudo apt-get install cmake ``` #### Build IoT.js Executing below command will build IoT.js and run our testsuite. ``` bash ./tools/build.py --target-board=rpi2 ``` iotjs-1.0/docs/devs/000077500000000000000000000000001312466455500144065ustar00rootroot00000000000000iotjs-1.0/docs/devs/Enabling-Experimental-Feature.md000066400000000000000000000047641312466455500225060ustar00rootroot00000000000000# Enabling Experimental Features This document provides a guide on how to write and build experimental features. ## What's experimental build? Experimental build is an executable IoT.js including features that are not yet ready for wide use, so they are protected by an experimental status. Developers can opt in to enabling these features when building IoT.js, but they should be used with caution. Because the changes in experimental build can include not only a brand new module but also the existing modules stably used. So developers and users may face unexpected side effects. You should be aware that all the features handled in experimental build may change, be broken, or be removed in the future. ## How to make IoT.js experimental build You need to make IoT.js using our build script, ["build.py"](https://github.com/Samsung/iotjs/blob/master/tools/build.py), with `--experimental` or `-e` option. ```bash tools/build.py --experimental tools/build.py -e --iotjs-include-module experimental-module tools/build.py -e --config=build.experimental.config ``` For selecting modules to be included, you need to notify the script where your modules exist. You can use `--iotjs-include-module` or `--config` option for that. For further information, please refer to [Writing Builtin JavaScript Module](https://github.com/Samsung/iotjs/blob/master/docs/devs/Writing-New-Builtin-Module.md#writing-builtin-javascript-module). ## Writing Code ### Identifier for C Code Once you make IoT.js with `--experimental` option, a symbolic constant named `EXPERIMENTAL` is predefined in compile stage. You can use the identifier to seperate your experimental code from others as follows. ```c #ifdef EXPERIMENTAL // experimental #else // normal #endif #ifndef EXPERIMENTAL // normal #else // experimental #endif ``` ### Identifier for JavaScript Code In the case of javascript code, you can refer to `process.env.IOTJS_ENV` to check if running IoT.js is built with experimental features. ```javascript if (process.env.IOTJS_ENV === 'experimental') { // experimental } else { // normal } ``` ## Documentation When documenting a guide or an API reference about your experimental module, it's required to explicitly indicate that the features are experimental. Please put the same caution below in every single document. > :exclamation: This document describes an experimental feature and considerations. Please be aware that every experimental feature may change, be broken, or be removed in the future without any notice. iotjs-1.0/docs/devs/Inside-IoT.js-Validated-Struct.md000066400000000000000000000147021312466455500224300ustar00rootroot00000000000000Validated Struct ================ Validated struct is C struct wrapper for encapsulation and validity check. * Validated Struct Declaration * Constructors, Destructor, Methods * Ownership of validated struct instance * Case 1: Validated struct instance as local variable * Case 2: Validated struct instance as parameter & return * Case 3: Validated struct instance as member variable of other struct * Case 4: Validated struct instance as data of asynchronous execution # Validated Struct Declaration ```c typedef struct { int a; void* b; } IOTJS_VALIDATED_STRUCT(iotjs_myclass_t); ``` Above struct will make the member variable encapsulated by wrapping real members with wrapper like below. ```c typedef struct { int a; void* b; } iotjs_myclass_t_impl_t; typedef struct { iotjs_myclass_impl_t unsafe; /* More members for struct validity check exist in debug mode */ } iotjs_myclass_t; int main() { iotjs_myclass_t x; } ``` Only wizards will access the members directly by using `x.unsafe.a`, `x.unafe.b`, ... . Otherwize the members are only accessible with its accessor function. See `src/iotjs_def.h` for more details on real implementation. # Constructors, Destructor, Methods You should create C++-like constructors, destructor and methods with provided accessor. Then you can access the encapsulated member variables using `_this` variable, which has almost same role with C++ `this` keyword. You must call `destroy` for every validated structs you've created. ```c /* Constructor */ iotjs_myclass_t iotjs_myclass_create(int a) { iotjs_myclass_t instance; IOTJS_VALIDATED_STRUCT_CONSTRUCTOR(iotjs_myclass_t, &instance); _this->a = a; _this->b = malloc(a); return instance; } /* Destructor */ void iotjs_myclass_destroy(iotjs_myclass_t* instance) { IOTJS_VALIDATED_STRUCT_DESTRUCTOR(iotjs_myclass_t, instance); free(_this->b); } /* Method */ int iotjs_myclass_get_a(iotjs_myclass_t* instance) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_myclass_t, instance); return _this->a; } int main() { /* Validated struct as local variable */ iotjs_myclass_t local_instance = iotjs_myclass_create(3); printf("%d\n", iotjs_myclass_get_a(&local_instance)); iotjs_myclass_destroy(&local_instance); return 0; } ``` # Ownership of validated struct instance The ground rule is: * Use `iotjs_classname_t` typed variable if the variable *is* responsible for destruction of instance. * Use `iotjs_classname_t*` typed variable if the variable *is not* responsible for destruction of instance. Below Case 1 ~ Case 4 shows the case-by-case example of the ownership rule. ## Case 1: Validated struct instance as local variable The `local_instance` variable in previous example was the local instance of validated struct. Since `local_instance` should be destructed inside the function scope, `iotjs_myclass_t` type was used. ## Case 2: Validated struct instance as parameter & return Previous example also included the example of validated struct instance as parameter and return. When accessing member variable `a` by calling `iotjs_myclass_get_a()`, `iotjs_myclass_t*` type was used as the parameter type, since it *does not* move the responsibility to destruct the instance. And when returning the newly created instance by calling `iotjs_myclass_create()`, `iotjs_myclass_t` type was used as return type, since it *does* move the responsibility to destruct the instance. ## Case 3: Validated struct instance as member variable of other struct ```c /* Validated struct as member variable of other struct */ typedef struct { iotjs_myclass_t member_instance; } IOTJS_VALIDATED_STRUCT(iotjs_otherclass_t) iotjs_otherclass_t iotjs_otherclass_create() { /* Initialization steps for iotjs_otherclass_t */ _this->member_instance = iotjs_myclass_create(3); } void iotjs_otherclass_destroy() { /* Finalization steps for iotjs_otherclass_t */ iotjs_myclass_destroy(&_this->member_instance); } ``` In the case above, `iotjs_myclass_t` instance is used as member variable of other class. Since `iotjs_otherclass_t` is responsible for finalizing the `member_instance`, it owns the variable as `iotjs_myclass_t` type, not pointer type. ## Case 4: Validated struct instance as data of asynchronous execution Another usecase would be using validated struct as callback data. Currently, our all asynchronous datas are wrapped with `iotjs_*wrap_t` type, and they are destructed automatically. ```c /* * Public APIs in iotjs_module_fs.h */ typedef struct { iotjs_reqwrap_t reqwrap; uv_fs_t req; } IOTJS_VALIDATED_STRUCT(iotjs_fsreqwrap_t); iotjs_fsreqwrap_t* iotjs_fsreqwrap_create(const iotjs_jval_t* jcallback); void iotjs_fsreqwrap_dispatched(iotjs_fsreqwrap_t* fsreqwrap); ``` As you can see, constructor returns the `iotjs_fsreqwrap_t*` type, because it does not pass the responsibility to destruct the return value. It is destructed when request is dispatched, which can be informed by calling `iotjs_fsreqwrap_dispatched()`. The destructor `iotjs_fsreqwrap_destroy()` is hidden in c file. ```c /* * Implementation in iotjs_module_fs.c */ iotjs_fsreqwrap_t* iotjs_fsreqwrap_create(const iotjs_jval_t* jcallback) { iotjs_fsreqwrap_t* fsreqwrap = IOTJS_ALLOC(iotjs_fsreqwrap_t); IOTJS_VALIDATED_STRUCT_CONSTRUCTOR(iotjs_fsreqwrap_t, fsreqwrap); iotjs_reqwrap_initialize(&_this->reqwrap, jcallback, (uv_req_t*)&_this->req); return fsreqwrap; } static void iotjs_fsreqwrap_destroy(iotjs_fsreqwrap_t* fsreqwrap) { // private function IOTJS_VALIDATED_STRUCT_DESTRUCTOR(iotjs_fsreqwrap_t, fsreqwrap); uv_fs_req_cleanup(&_this->req); iotjs_reqwrap_destroy(&_this->reqwrap); IOTJS_RELEASE(fsreqwrap); } void iotjs_fsreqwrap_dispatched(iotjs_fsreqwrap_t* fsreqwrap) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_fsreqwrap_t, fsreqwrap); iotjs_fsreqwrap_destroy(fsreqwrap); } /* * Use of iotjs_fsreqwrap_t */ void callback(uv_fs_t* req) { do_something(req); iotjs_fsreqwrap_dispatched(req); /* Call iotjs_*reqwrap_dispatched() when callback called */ } void request(iotjs_jval_t* jcallback) { iotjs_fsreqwrap_t* wrap = iotjs_fsreqwrap_create(jcallback); uv_fs_request(loop, wrap->req, callback); } ``` In the case of tuv request wrapper, `iotjs_*reqwrap_dispatched()` should be called when the request has been dispatched. In the case of tuv handle wrapper, `iotjs_handlewrap_close()` should be called when the handle has been closed. in the case of JavaScript object wrapper, you don't have to do anything because JavaScript engine will call the destructor when the object becomes inaccessible. iotjs-1.0/docs/devs/Inside-IoT.js.md000066400000000000000000000352701312466455500172560ustar00rootroot00000000000000Inside IoT.js ============= * [Design](#design) * [Javascript Binding](#javascript-binding) * iotjs_jval_t * iotjs_jobjectwrap_t * Native handler * Embedding API * [libuv Binding](#libuv-binding) * iotjs_handlewrap_t * iotjs_reqwrap_t * [IoT.js Core](#iotjscoe) * Life cycle of IoT.js * Builtin * Native module * Event loop # Design IoT.js is built on top of [JerryScript](http://jerryscript.net/) and [libuv](http://libuv.org). JerryScript is a lightweight Javascript engine intended to run on small devices for IoT and libuv is a library for supporting asynchronous I/O. There is a layer that binds JerryScript and libuv to IoT.js. We will deals with the layer in [Javascript Binding](#javascript-binding) and [libuv Binding](#javascript-binding) section on this document respectively. IoT.js core layer locates above these binding layer. This core layer plays a central role in this project providing upper layer with fundamental functionality of running main event loop, interacting with Javascript engine, managing I/O resources via libuv, managing life cycle of objects, providing builtin modules, and so forth. [IoT.js Core](#iotjs-core) section deals with the layer in detail. IoT.js provides APIs for user applications to help creating IoT friendly services. You can see the list of API from [IoT.js API Reference](../api/IoT.js-API-reference.md). # Javascript Binding Many modern Javascript Engines come with [embedding API](#embedding-api) to provide functionality for compiling and executing Javascript program, accessing Javascript object and its value, handling errors, managing lifecyles of objects and so on. You can think of Javascript binding layer as an interface between upper layer (IoT.js core) and underlying Javascript engine. Although IoT.js only supports JerryScript for now, there will be a chance that we extend supporting Javascript engine (such as [Duktape](http://duktape.org/) or [V8](https://code.google.com/p/v8/)) in the future. For this reason, we want to keep the layer independent from a specific Javascript engine. You can see interface of the layer in [iotjs_binding.h](../../src/iotjs_binding.h). ## iotjs_jval_t `iotjs_jval_t` struct stands for a real Javascript object. Upper layers will access Javascript object via this struct. This struct provides following functionalities: * Creating a Javascript object using `iotjs_jval_create_*()` constructor. * Creating a Javascript object by a value. * Creating a Javascript function object where its body is implemented in C. * Creating a Javascript Error object. * Creating reference for a Javascript object increasing reference count. * Increasing reference count. * Decreasing reference count. * Checking object type. * Retrieving value. * Calling a Javascript function. * Evaluating a Javascript script. * Set and Get corresponding native data to the Javascript object. ## iotjs_jobjectwrap_t You can refer Javascript object from C code side using `iotjs_jval_t` as saw above. When a reference for a Javascript object was made using `iotjs_jval_t`, it will increase the reference count and will decrease the count when it goes out of scope. ```c { // Create JavaScript object // It increases reference count in JerryScript side. iotjs_jval_t jobject = iotjs_jval_create(); // Use `jobject` ... // Before jobject goes out of scope, destroy it. // It decreases reference count in JerryScript side so that it can be GC-ed. iotjs_jval_destroy(&jobject) } ``` But the situation is different if you want to refer a Javascript object through out program execution until the object is live. You may write code like this: ```c iotjs_jval_t* jobject = (iotjs_jval_t*)malloc(sizeof(iotjs_jval_t)); // Not allowed ``` Unfortunately, we strongly do not recommend that kind of pattern. We treat pointer-types variables in special way. (See [Validated Struct](Inside-IoT.js-Validated-Struct.md) for more details.) To achieve your wish, we recommend using `iotjs_jobjectwrap_t` for that purpose. `iotjs_jobjectwrap_t` is kind of weak pointer to a Javascript Object. It refers a Javascript object but never increase reference count so that Javascript engine can collect the object when it turns into garbage. The `iotjs_jobjectwrap_t` instance will be released at the time the corresponding Javascript object is being reclaimed. Do not hold pointer to the wrapper in native code side globally because even if you are holding a wrapper by pointer, Javascript engine probably releases the corresponding Javascript object resulting deallocation of wrapper. Consequentially your pointer will turned into dangling. The only safe way to get wrapper is to get it from Javascript object. When a wrapper is being created, it links itself with corresponding Javascript object with `iotjs_jval_set_object_native_handle()` method of `iotjs_jval_t`. And you can get the wrapper from the object with `iotjs_jval_get_object_native_handle()` method of `iotjs_jval_t` later when you need it. ## Native handler Some operations - such as file I/O, networking, device control, multitasking, and etc - can not be performed by pure Javascript. IoT.js uses a mechanism called "native handler" to enable such operations performed from Javascript. You can regard native handler as Javascript function object with its body implemented in C. You might think it is somewhat similar to [FFI](https://en.wikipedia.org/wiki/Foreign_function_interface). In a wide sense, it's true for native handler is for calling C function from Javascript. But in a narrow sense, it's not true. Usually main purpose of [FFI](https://en.wikipedia.org/wiki/Foreign_function_interface) is to call a routine written in one language from a program written in another. After a routine was invoked, it is common that the routine just do what it is supposed to do without knowing the surrounding context except arguments. Whereas native handler does know that it is being called from Javascript (actually it is a Javascript function although not written in Javascript) and does access surrounding Javascript execution context using [embedding API](#embedding-api). ## Embedding API Many Javascript engines these days provide embedding API. IoT.js uses the API to create [builtin module](#builtin) and [native handler](#native-handler). See following link if you want further information about the API: * [JerryScript API](http://jerryscript.net/api-reference) * [Duktape API](http://duktape.org/api.html) * [V8 embedder's guide](https://developers.google.com/v8/embed) * [SpiderMonkey API](https://developer.mozilla.org/en-US/docs/Mozilla/Projects/SpiderMonkey/JSAPI_reference) # libuv Binding IoT.js is using [libuv](http://libuv.org/) to perform various asynchronous I/O and threading. Because IoT.js adopts asynchronous programming model, libuv plays very important role in this project. Actually the [main loop](#event-loop) of IoT.js is libuv event loop waiting I/O event, picks the event, and dispatches it to corresponding event handler function. You can read [libuv design document](http://docs.libuv.org/en/v1.x/design.html) to get detailed information about asynchronous programming model based on libuv. ## iotjs_handlewrap_t `iotjs_handlewrap_t` is to bind a Javascript object and a libuv handle (e.g. file descriptor) together. `iotjs_handlewrap_t` inherits `iotjs_jobjectwrap_t` since it is linked with a Javascript object. Unlike `iotjs_jobjectwrap_t`, `iotjs_jobjectwrap_t` increases RC for the Javascript object when an instance of it is created to prevent GC while the handle is alive. The reference counter will be decreased after the handle is closed, allowing GC. ## iotjs_reqwrap_t `iotjs_reqwrap_t` is for wrapping libuv request data and Javascript callback function. And make sure that the Javascript callback function is alive during the I/O operation. Let's look at how asynchronous I/O are treated in IoT.js: 1. Javascript module calls builtin function to perform I/O applying arguments including callback. 2. Builtin creates `iotjs_reqwrap_t` to wrap `uv_req_s` and Javascript callback function. 3. Builtin calls libuv to perform the I/O. 4. After I/O finished, libuv calls builtin after handler. 5. Builtin after handler takes `iotjs_reqwrap_t` containing I/O result and Javascript callback function. 6. Builtin after handler calls Javascript callback. 7. Builtin after handler release `iotjs_reqwrap_t` by calling `iotjs_*reqwrap_dispatch()` `iotjs_reqwrap_t` does not inherits `iotjs_handlewrap_t` for wrapping the callback function object. Note that `HandleWrap` does not increase reference count of wrapping object. It does not guarantee guarantee liveness of the object even if the wrapper is alive. On the other hand, `iotjs_reqwrap_t` increases the reference count for the callback function and decreases when it is being freed to guarantee the liveness of callback function during the request is ongoing. After request is finished and `iotjs_reqwrap_t` released by calling `iotjs_*reqwrap_dispatch()`, the callback function could be collected by GC when it need to be. # IoT.js Core ## Life cycle of IoT.js _Note:_ _We are currently focusing on implementing IoT.js upon JerryScript engine._ _Implementation of initializing process depends on JerryScript API._ _That could be changed when we adopt other Javascript engines._ _Anyway, in this chapter we will explain initialization process based on current implementation._ The process of IoT.js can be summarized as follow: 1. Initialize JerryScript engine. 2. Execute empty script * Create initial Javascript context. 3. Initialize builtin modules. * Create builin modules including ['process'](../api/IoT.js-API-Process.md). 4. Evaluate ['iotjs.js'](../../src/js/iotjs.js). * Generate entry function. 5. Run the entry function passing 'process'. 1. Initialize 'process' module. 2. Load user application script. 3. Run user application. 6. Run [event loop](#event-loop) until there are no more events to be handled. 7. Clean up. ## Builtin "Builtin" is Javascript objects fully implemented in C using [embedding API](#embedding-api). The list of builtin objects can be found at `MAP_MODULE_LIST` macro in ['iotjs_module.h'](../../src/iotjs_module.h). Because methods of builtin modules are implemented as [native handler](#native-handler), are able to access underlying system using libuv, C library, and system call. Also, builtin modules could be used for optimizing performance of CPU bound routine or reduce binary size. Builtin modules are initialized during [intializing step of IoT.js](#life-cycle-of-iotjs) and released just before program terminates. ## Native module The [basic modules and extended modules](../api/IoT.js-API-reference.md) provided by IoT.js are called 'native module' because it will be included IoT.js as binary format.(not as script). There is a [tool](../../tools/js2c.py) that transfer Javascript script source file into C file. Usually a native module needs help from couple of [builtin](#builtin) modules which are implemented in C thus able to access underlying system. Some native modules are bound to global object while others are on demand. On demand modules will be created at the moment when it is first required and will not released until the program terminates. ## Event loop _Note:_ _It would be helpful to read [libuv design overview](http://docs.libuv.org/en/v1.x/design.html) to understand asynchronous I/O programming model if you are not familiar with it._ _Note:_ _In this section we will see simple file open example and relevant code segment. You can find the source files at ['iotjs.c'](../../src/iotjs.c), [`iotjs_module_fs.c`](../../src/module/iotjs_module_fs.c) and ['fs.js'](../../src/js/fs.js)_ IoT.js follows asynchronous I/O programming model proposed by libuv to perform non-blocking, single-threaded, asynchronous I/O. You can find main loop of the program at the file ['iotjs.c'](../../src/iotjs.c) in the source tree. It looks like this: ```c // Run event loop. bool more; do { more = uv_run(iotjs_environment_loop(env), UV_RUN_ONCE); more |= iotjs_process_next_tick(); if (more == false) { more = uv_loop_alive(iotjs_environment_loop(env)); } } while (more); ``` While running a IoT.js application, it could make requests for I/O operations using [IoT.js API](../api/IoT.js-API-reference.md). For example, You can write a code for opening 'hello.txt' file and printing file descriptor out like this: ```js fs.open('hello.txt', 'r', function(err, fd) { console.log('fd:' + fd); }); conosle.log('requested'); ``` To handle the request, IoT.js will wrapping the request and callback function using `iotjs_reqwrap_t`. ```c iotjs_fsreqwrap_t* req_wrap = iotjs_fsreqwrap_create(jcallback); ``` libuv will take charge of actual I/O processing taking the request. ```c uv_fs_t* fs_req = iotjs_fsreqwrap_req(req_wrap); int err = uv_fs_open(iotjs_environment_loop(env), fs_req, path, flags, mode, AfterAsync); ``` Since all I/O are treated as non-blocking, calling for async I/O API returns immediately right after request was sent to libuv. And then next line of javascript program will be executed immediately without waiting the I/O. Thus in the above example 'requested' will be printed out right after file open request was made. If there were I/O requests, `uv_run()` in the main loop waits by polling the requests until at least one of the request processing were finished. When a result for a request was produced, internal part of libuv calls corresponding handler function (let it be after function) back. Usually, the after function retrieves I/O result and `iotjs_reqwrap_t` object from request data. And calling the javascript callback function with the result. ```c iotjs_fsreqwrap_t* req_wrap = (iotjs_fsreqwrap_t*)(req->data); // get request wrapper const iotjs_jval_t* cb = iotjs_fsreqwrap_jcallback(req_wrap); // javascript callback function iotjs_jargs_t jarg = iotjs_jargs_create(2); iotjs_jargs_append_null(&jarg); // in case of success. iotjs_jargs_append_number(req->result); // result - file descriptor for open syscall // callback iotjs_jhelper_make_callback(cb, iotjs_jval_get_null(), &jarg); // cleanup iotjs_jargs_destroy(&jarg); iotjs_fsreqwrap_dispatched(req_wrap); ``` For above file open example, calling javascript callback function would result execution of the handler. ```js function(err, fd) { console.log('fd:' + fd); } ``` One iteration of event loop is finished and `uv_run()` finally returns after all results were handled. Next, it calls next tick handler. ```c more |= iotjs_process_next_tick(); ``` And for next step, main event loop checks if there were no more request to be treated. ```c if (more == false) { more = uv_loop_alive(iotjs_environment_loop(env)); } ``` If there are another iteration of the loop executed. Otherwise, main event loop ends. iotjs-1.0/docs/devs/IoT.js-Package-(outdated).md000066400000000000000000000077121312466455500213260ustar00rootroot00000000000000**The content on this page does not work. Currently, there is no plan to run ipm server. This document will leave for discussion in the future.** IoT.js follows the practice of node.js npm to provide module development community with separate IoT.js own registry. * To see what it actually is, please visit [www.npmjs.com](https://www.npmjs.com/), and also [docs.npmjs.com](https://docs.npmjs.com/). * To avoid confusion with the original server, we'll call it "ipm", for IoT.js Package Manager. * Current status of "ipm" is started and it's for developers so has no separate web page. We need to develop them. * "npm" program is used for publish and download modules. We may fork when customization is needed. ### Installing "npm" ``` sudo apt-get install npm ``` ### Setting registry As ipm uses different server, you need to change registry information ``` npm config set registry="http://ipm.iotjs.net:5984/registry/_design/app/_rewrite" ``` ### Adding your account You may have to register your account if you plan to publish some packages, for example, ``` npm set init.author.name "Your Name" npm set init.author.email "you@example.com" npm set init.author.url "http://yourblog.com" npm adduser ``` Please set to your real name and email address. url is optional. ### Publish a package cd to your package folder you wish to publish and init ``` npm init ``` It'll ask information for your package, for an example; ``` Press ^C at any time to quit. name: (t) echotest version: (1.0.0) 0.0.1 description: simple echo server entry point: (index.js) test command: git repository: keywords: license: (ISC) About to write to /(your working folder)/package.json: { "name": "echotest", "version": "0.0.1", "description": "simple echo server", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "(your name) (your blog page)", "license": "ISC" } Is this ok? (yes) yes ``` and all things are good to go, publish. ``` npm publish ./ ``` Please visit [npmjs.org](https://docs.npmjs.com/getting-started/publishing-npm-packages) for detailed explanations. ### About the license of each packages IoT.js is released under Apache 2.0 license, [this page](../License.md). We assume you also agree on this license when publishing to ipm registry. ### Downloading packages "npm" provides local and global packages and you may be working on some powerful machines. In IoT devices this may be somewhat different. It may not have enough memory, power, network or even no console to give commands. So it can have several scenarios depending on the device you may be working on. This may be some of them; 1) Download to your machine with Linux, Mac or Windows. * Install packages to your powerful machine * Send it to the IoT device through copy to memory card * or send through serial line, BT, USB with old time kermit or z-modem 2) If it has a WiFi the download directly from the registry * But to make this work, we need to develop a small shell program with iotjs. * This can be done with built-in module downloader, we need to develop this. * Issue [#75](https://github.com/Samsung/iotjs/issues/75) to track 3) If your IoT is very small and even has no writable file system * Package modules should be built-in to IoT.js at compile time. * We should also develop this. 4) any more ideas? As for case 1), ``` (cd to some working directory) npm install (copy node_modules folder to your device) ``` As mentioned above, npm has local and global packages. But for IoT.js lets stick on the local only. For some cases running on ROTS there may not be any globals place. ### Package license You may use ipm packages freely under Apache 2.0 license, read [this page](../License.md) ### Searching for packages Searching is possible with search command. See [docs.npmjs.com/cli/search](https://docs.npmjs.com/cli/search). ``` npm search ``` If you omit the keyword, it'll list all packages registered. iotjs-1.0/docs/devs/Logging-IoT.js-execution.md000066400000000000000000000021711312466455500214240ustar00rootroot00000000000000### Logging Support IoT.js supports logging on Debug version. It can output message strings to the stderr console by default or any file you give. To add a message line, use one of three macros in the source, defined in iotjs_module_debug.h ``` DLOG() DDLOG() DDDLOG() ``` DLOG is level 1 which means it's an error so that should be displayed. DDLOG is for warning messages and is level 2. DDDLOG is information you need while IoT.js is running, which is level 3. Default is 1. ### Setting logging level In linux, use `IOTJS_DEBUG_LEVEL` environment variable to change the level, for example, if you want to see error and warning messages; ``` export IOTJS_DEBUG_LEVEL=2 ``` Numbers can be 0, 1, 2 or 3. If you give 0, it will be silence, no message. ### Logging to a file To save to a file, use also the environment variable, for example; ``` export IOTJS_DEBUG_LOGFILE="/home/iotjsdev/iotjslog.txt" ``` You must have file creation rights to that directory. File will be overwritten on every start, so don't run the program before looking inside or backing it up. To disable logging to a file, ``` unset IOTJS_DEBUG_LOGFILE ``` will do. iotjs-1.0/docs/devs/Memory-savings-with-libtuv.md000066400000000000000000000200201312466455500221160ustar00rootroot00000000000000Memory usage with libtuv on iotjs is described here and compared to libuv. * Compared with release version in i686. * iotjs version: hash f8e8391d8c30a76c2f82644e454056c11a2bad1a #### runtime memory usage compare with libuv running iotjs 1) how to build 1-1) with libuv ``` ./tools/build.py --buildtype=release --nochecktest ``` 1-2) with libtuv ``` ./tools/build.py --buildtype=release --nochecktest --tuv ``` 2) memory usage measurement with valgrind running `test httpserver` ``` valgrind ./build/i686-linux/release/iotjs/iotjs ./test/run_pass/test_httpserver.js ``` 2-1) with libuv ``` ==5740== Memcheck, a memory error detector ==5740== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al. ==5740== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info ==5740== Command: ./build/i686-linux/release/iotjs/iotjs ./test/run_pass/test_httpserver.js ==5740== ==5740== ==5740== HEAP SUMMARY: ==5740== in use at exit: 0 bytes in 0 blocks ==5740== total heap usage: 959 allocs, 959 frees, 482,669 bytes allocated ==5740== ==5740== All heap blocks were freed -- no leaks are possible ==5740== ==5740== For counts of detected and suppressed errors, rerun with: -v ==5740== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) ``` 2-2) with libtuv ``` ==7584== Memcheck, a memory error detector ==7584== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al. ==7584== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info ==7584== Command: ./build/i686-linux/release/iotjs/iotjs ./test/run_pass/test_httpserver.js ==7584== ==7584== ==7584== HEAP SUMMARY: ==7584== in use at exit: 0 bytes in 0 blocks ==7584== total heap usage: 955 allocs, 955 frees, 481,645 bytes allocated ==7584== ==7584== All heap blocks were freed -- no leaks are possible ==7584== ==7584== For counts of detected and suppressed errors, rerun with: -v ==7584== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) ``` 482,669 vs 481,645 = 1,024 bytes saved #### binary size 1) build ``` ./tools/build.py --buildtype=release --nochecktest --target-arch=arm --target-os=linux ./tools/build.py --buildtype=release --nochecktest --target-arch=arm --target-os=linux --tuv ``` 2) binary size in i686-linux * libuv : 213,130 / iotjs: 2,512,292, stripped: 782,152 * libtuv: 103,158 / iotjs: 2,460,357, stripped: 732,776 * itself: 109,972 smaller, iotjs: 51,935(striped 49,376) saved 3) binary size in arm-linux * libuv : 176,614 / iotjs: 2,543,525, stripped: 536,460 * libtuv: 83,458 / iotjs: 2,506,455, stripped: 507,548 * itself: 93,156 smaller, iotjs: 37,070(stripped: 28,912) saved #### libuv vs libtuv itself 1) use `tuvtester` as an application to compare. 2) codes changes to make both libuv.a and libtuv.a interchangeable. 2-1) as libtuv uses c++ compiler, wrap all codes with ``` extern "C" { ... } ``` 2-2) for libuv, give `libuv.a` by changing `tuvtest.cmake` file. use file from iotjs build. ``` target_link_libraries(${TUVTESTNAME} LINK_PUBLIC #${TARGETLIBNAME} "/(absolute path to libuv)/libuv.a" ${TUV_LINK_LIBS}) ``` 2-3) some functions that does not exist in libuv. add this bottom of in runner_main.cpp ``` #if 1 #define uv__handle_deinit(h) \ do { \ QUEUE_REMOVE(&(h)->handle_queue); \ QUEUE_INIT(&(h)->handle_queue); \ } \ while (0) void uv_deinit(uv_loop_t* loop, uv_handle_t* handle) { QUEUE* q; uv_handle_t* h; QUEUE_FOREACH(q, &loop->handles_queue) { h = QUEUE_DATA(q, uv_handle_t, handle_queue); if (h == handle) { uv__handle_deinit(handle); break; } } } #endif ``` 2-4) remove test codes that does not run with libuv, tested codes are like this in runner_list.h ``` #define TEST_LIST_ALL(TE) \ TE(idle_basic, 5000) \ TE(timer_init, 5000) \ \ TE(condvar_2, 5000) \ TE(condvar_3, 5000) \ TE(cwd, 5000) \ \ TE(fs_file_noent, 5000) \ TE(fs_file_sync, 5000) \ TE(fs_file_async, 5000) \ TE(fs_file_write_null_buffer, 5000) \ TE(fs_stat_missing_path, 5000) \ TE(fs_open_dir, 5000) \ TE(fs_file_open_append, 5000) \ TE(fs_read_file_eof, 5000) \ \ TE(threadpool_queue_work_simple, 5000) \ // shutdown_eof should be last of tcp test, it'll stop "echo_sevrer" #if defined(__linux__) #define TEST_LIST_EXT(TE) \ #else #define TEST_LIST_EXT(TE) \ #endif #define HELPER_LIST_ALL(TE) \ ``` 3) measure run with valgrind ``` valgrind ./build/i686-linux/release/bin/tuvtester ``` 3-1) with libuv ``` ==24952== Memcheck, a memory error detector ==24952== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al. ==24952== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info ==24952== Command: ./build/i686-linux/release/bin/tuvtester ==24952== Run Helpers... [idle_basic ]...OK [timer_init ]...OK [condvar_2 ]...OK [condvar_3 ]...OK [cwd ]...OK [fs_file_noent ]...OK [fs_file_sync ]...OK [fs_file_async ]...OK [fs_file_write_null_buffer ]...OK [fs_stat_missing_path ]...OK [fs_open_dir ]...OK [fs_file_open_append ]...OK [fs_read_file_eof ]...OK [threadpool_queue_work_simple ]...OK Waiting Helpers to end... ==24952== ==24952== HEAP SUMMARY: ==24952== in use at exit: 0 bytes in 0 blocks ==24952== total heap usage: 44 allocs, 44 frees, 1,727 bytes allocated ==24952== ==24952== All heap blocks were freed -- no leaks are possible ==24952== ==24952== For counts of detected and suppressed errors, rerun with: -v ==24952== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) ``` 3-2) with libtuv ``` ==26621== Memcheck, a memory error detector ==26621== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al. ==26621== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info ==26621== Command: ./build/i686-linux/release/bin/tuvtester ==26621== Run Helpers... [idle_basic ]...OK [timer_init ]...OK [condvar_2 ]...OK [condvar_3 ]...OK [cwd ]...OK [fs_file_noent ]...OK [fs_file_sync ]...OK [fs_file_async ]...OK [fs_file_write_null_buffer ]...OK [fs_stat_missing_path ]...OK [fs_open_dir ]...OK [fs_file_open_append ]...OK [fs_read_file_eof ]...OK [threadpool_queue_work_simple ]...OK Waiting Helpers to end... ==26621== ==26621== HEAP SUMMARY: ==26621== in use at exit: 0 bytes in 0 blocks ==26621== total heap usage: 40 allocs, 40 frees, 991 bytes allocated ==26621== ==26621== All heap blocks were freed -- no leaks are possible ==26621== ==26621== For counts of detected and suppressed errors, rerun with: -v ``` 3-3) result * libuv: 1,727 bytes * libtuv: 991 bytesiotjs-1.0/docs/devs/Optimization-Tips.md000066400000000000000000000046511312466455500203410ustar00rootroot00000000000000Optimization Tips ================= ## Tracing JerryScript heap usage Adding below arguments when building and running IoT.js will show you the JerryScript memory status. ```text $ ./tools/build.py --jerry-memstat $ ./build/bin/iotjs --memstat test.js Heap stats: Heap size = 262136 bytes Allocated = 0 bytes Waste = 0 bytes Peak allocated = 24288 bytes Peak waste = 261 bytes Skip-ahead ratio = 2.6059 Average alloc iteration = 1.1284 Average free iteration = 19.3718 Pools stats: Pool chunks: 0 Peak pool chunks: 735 Free chunks: 0 Pool reuse ratio: 0.3459 ``` Note that currently only JerryScript heap usage can be shown with memstat option, not IoT.js memory usage. You can use system profiler to trace IoT.js memory usage. ## JerryScript 'external magic string' feature When parsing and executing JavaScript module, JavaScript strings occupy a huge amount of space in JerryScript heap. To optimize this kind of heap usage, JerryScript has 'external magic string' feature. If you enable snapshot when building, build script will automatically generate `src/iotjs_string_ext.inl.h` file, which includes all of the JavaScript strings used in builtin modules. This file is used by JerryScript to reduce heap usage. Since same strings will be included only once, you can use this information to get some hints on binary size reduction. Note that only strings with length<32 will be included in this list. ## Placement of JerryScript heap (with an example of STM32F4 CCM Memory) IoT.js uses two kind of heaps: System heap for normal usage, and separated JerryScript heap for javascript. JerryScript heap is implemented as c array with fixed length decided in static time. Its size can be ~512K. For some devices, placing this kind of large memory block can be important issue. For example, STM32F4 chips have *Core Coupled Memory* (a.k.a. *ccm* memory), which is usually used as heap or stack. However, since compiler do not have any special knowledge about JerryScript heap, it can be treated as simple array. You can make your compiler to place the JerryScript heap in specific section by using `--jerry-heap-section` argument when building IoT.js. Your argument will be used with below code in `deps/jerry/jerry-core/jcontext/jcontext.c` ```c #define JERRY_GLOBAL_HEAP_SECTION __attribute__ ((section (JERRY_HEAP_SECTION_ATTR))) jmem_heap_t jerry_global_heap __attribute__ ((aligned (JMEM_ALIGNMENT))) JERRY_GLOBAL_HEAP_SECTION; ``` iotjs-1.0/docs/devs/Use-JerryScript-Debugger.md000066400000000000000000000020351312466455500214640ustar00rootroot00000000000000## Jerry-debugger Detailed description about the debugger is available [here](https://github.com/jerryscript-project/jerryscript/blob/master/docs/07.DEBUGGER.md). ### Enable debugger support in IoT.js To enable the debugger support under IoT.js, the `--jerry-debugger` option should be passed to the `tools/build.py`. The server part of the debugger is intergrated into the binary of IoT.js. If you want to specify the port number of the debugger-server (default: 5001), you can do so with the `--jerry-debugger-port=` option. ### Usage To start the debugger-server: ` --start-debug-server test.js` Two clients are included, a [python](https://github.com/jerryscript-project/jerryscript/blob/master/jerry-debugger/jerry-client-ws.py) and an [HTML](https://github.com/jerryscript-project/jerryscript/blob/master/jerry-debugger/jerry-client-ws.html) variant, they can be found under `deps/jerry/jerry-debugger/`. *Note*: When snapshot support is enabled, you won't be able to examine js-modules that are loaded from snapshots. iotjs-1.0/docs/devs/Writing-New-Builtin-Module.md000066400000000000000000000204301312466455500217300ustar00rootroot00000000000000Writing New Builtin Module ========================== This document provides a guide on how to write a builtin module for IoT.js. Contents: * Writing Builtin JavaScript Module * Writing Native Module Builtin - Using native module in JavaScript module - Registering native module - Native handler * Arguments and Return * Wrapping native object with JS object * Callback You can see more information on the [Optimization Tips](Optimization-Tips.md) page. It will be easier to write a new IoT.js module if you have background on: - [Node.js module](https://nodejs.org/api/modules.html) (for writing IoT.js JavaScript module) - [Node.js native addon](https://nodejs.org/api/addons.html) (for writing IoT.js native module builtin) ## Writing Builtin JavaScript Module Builtin JavaScript module can be written in the same way as writing [Node.js module](https://nodejs.org/api/modules.html). JavaScript file should be located in `src/js/` directory, and you should notify to our build script that your module should be included in one of following ways: * Use `./tools/build.py --iotjs-include-module mymodule` when building * Add your module in `build.config` file Your new module will look like below: src/js/mymodule.js: ```javascript module.exports = { foo: function() { console.log("OK"); }, bar: 123 } ``` user.js: ```javascript var mymodule = require('mymodule'); mymodule.foo(); // prints "OK" console.log(mymodule.bar); // prints "123" ``` and execute: ```sh $ ./tools/build.py $ ${PATH_TO}/iotjs user.js OK 123 ``` ## Writing Native Module Builtin You can implement some part of the builtin module in C, to enhance performance and to fully exploit the H/W functionality, etc. It has similar concept with [Node.js native addon](https://nodejs.org/api/addons.html), but we have different set of APIs. Node.js uses its own binding layer with v8 API, but we use [our own binding layer](../../src/iotjs_binding.h) which wraps [JerryScript API](https://github.com/jerryscript-project/JerryScript/blob/master/jerry-core/jerryscript.h). You can see `src/iotjs_binding.*` files to find more APIs to communicate with JS-side values from native-side. For simple explanation, `console` module will be used as an example. ### Using native module in JavaScript module Logging to console needs native functionality, so `console` JavaScript module in `src/js/console.js` passes its arguments into native handler like: ```javascript var consoleBuiltin = process.binding(process.binding.console); ... Console.prototype.log = consoleBuiltin.stdout(util.format.apply(this, arguments) + '\n'); ``` ### Registering native module According to the code above, `process.binding.console` should be defined before evaluating JavaScript code. IoT.js source code can automatically register native module if some functions are implemented as expected. First you should register your new module into `MODULE_LIST` macro in `src/iotjs_module.h`: ```c #define MAP_MODULE_LIST(F) \ E(F, BUFFER, Buffer, buffer) \ E(F, CONSOLE, Console, console) \ E(F, CONSTANTS, Constants, constants) \ ... ``` Then `iotjs_jval_t Init##ModuleName()` function will be called automatically when registering native module. We already have its implementation in `src/module/iotjs_module_console.c`: ```c iotjs_jval_t InitConsole() { iotjs_jval_t console = iotjs_jval_create_object(); iotjs_jval_set_method(&console, "stdout", Stdout); iotjs_jval_set_method(&console, "stderr", Stderr); return console; } ``` The return value of initializer function (in this case, `iotjs_jval_t console`,) will be passed to JS-side, as a return value of calling `process.binding(process.binding.modulename)`. Calling `iotjs_jval_create_object()` will create a JavaScript object in c code. And you might want to define some functions and properties to the newly created object. `iotjs_jval_set_method()` will register a native handler as a JavaScript function property. (That's how we was able to call `consoleBuiltin.stdout()` in JavaScript.) And `iotjs_jval_set_property_*()` will define a non-function property into object. You can find the example of registering a constant value as a JavaScript property in `src/module/iotjs_module_constants.c`. ### Native handler Native handler reads arguments from JavaScript, executes native operations, and returns the final value to JavaScript. #### Arguments and Return Let's see an example in `src/module/iotjs_module_console.c`: ```c JHANDLER_FUNCTION(Stdout) { JHANDLER_CHECK_ARGS(1, string); iotjs_string_t msg = JHANDLER_GET_ARG(0, string); fprintf(stdout, "%s", iotjs_string_data(&msg)); iotjs_string_destroy(&msg); } ``` Using `JHANDLER_GET_ARG(index, type)` macro inside `JHANDLER_FUNCTION()` will read JS-side argument. Since JavaScript values can have dynamic types, you must check if argument has valid type with `JHANDLER_CHECK_ARGS(number_of_arguments, type1, type2, type3, ...)` macro, which throws JavaScript TypeError when given condition is not satisfied. Calling `void iotjs_jhandler_return_*()` function inside `JHANDLER_FUNCTION()` will return value into JS-side. `undefined` will be returned if you didn't explicitly returned something, like normal JavaScript function does. Console methods doesn't have to return values, but you can easily find more examples from other modules. #### Wrapping native object with JS object `console` module is *state-free* module, i.e., console module implementation doesn't have to hold any values with it. It just passes value and that's all it does. However, there are many cases that module should maintain its state. Maintaining the state in JS-side would be simple. But maintaining values in native-side is not an easy problem, because native-side values should follow the lifecycle of JS-side values. Let's take `Buffer` module as an example. `Buffer` should maintain the native buffer content and its length. And the native buffer content should be deallocated when JS-side buffer variable becomes unreachable. There's `iotjs_jobjectwrap_t` struct for that purpose. if you create a new `iotjs_jobjectwrap_t` struct with JavaScript object as its argument and free handler, the registered free handler will be automatically called when its corresponding JavaScript object becomes unreachable. `Buffer` module also exploits this feature. ```c // This wrapper refer javascript object but never increase reference count // If the object is freed by GC, then this wrapper instance will be also freed. typedef struct { iotjs_jval_t jobject; } iotjs_jobjectwrap_t; typedef struct { iotjs_jobjectwrap_t jobjectwrap; char* buffer; size_t length; } iotjs_bufferwrap_t; static void iotjs_bufferwrap_destroy(iotjs_bufferwrap_t* bufferwrap); IOTJS_DEFINE_NATIVE_HANDLE_INFO(bufferwrap); iotjs_bufferwrap_t* iotjs_bufferwrap_create(const iotjs_jval_t* jbuiltin, size_t length) { iotjs_bufferwrap_t* bufferwrap = IOTJS_ALLOC(iotjs_bufferwrap_t); iotjs_jobjectwrap_initialize(&_this->jobjectwrap, jbuiltin, &bufferwrap_native_info); /* Automatically called */ ... } void iotjs_bufferwrap_destroy(iotjs_bufferwrap_t* bufferwrap) { ... iotjs_jobjectwrap_destroy(&_this->jobjectwrap); IOTJS_RELEASE(bufferwrap); } ``` You can use this code like below: ```c const iotjs_jval_t* jbuiltin = /*...*/; iotjs_bufferwrap_t* buffer_wrap = iotjs_bufferwrap_create(jbuiltin, length); // Now `jbuiltin` object can be used in JS-side, // and when it becomes unreachable, `iotjs_bufferwrap_destroy` will be called. ``` #### Callback Sometimes native handler should call JavaScript function directly. For general function calls (inside current tick), you can use `iotjs_jhelper_call()` function to call JavaScript function from native-side. And for asynchronous callbacks, after `libtuv` calls your native function, if you want to call JS-side callback you should use `iotjs_make_callback()`. It will not only call the callback function, but also handle the exception, and process the next tick(i.e. it will call `iotjs_process_next_tick()`). For asynchronous callbacks, you must consider the lifetime of JS-side callback objects. The lifetime of JS-side callback object should be extended until the native-side callback is really called. You can use `iotjs_reqwrap_t` and `iotjs_handlewrap_t` to achieve this. (Work In Progress) iotjs-1.0/docs/help/000077500000000000000000000000001312466455500143755ustar00rootroot00000000000000iotjs-1.0/docs/help/API-document-sample.md000066400000000000000000000176201312466455500204310ustar00rootroot00000000000000## This is a sample API reference. Please use this as a guideline to write your module's API references. - If you have any questions about this guide, please let us know as an issue. - `Markdown Example` is added to help understanding, and you can ignore it when writing the actual document. - In case of `experimental` module, it's required to explicitly indicate that the features are experimental. Please put the caution below to the begining of the document. > :exclamation: This document describes an experimental feature and considerations. Please be aware that every experimental feature may change, be broken, or be removed in the future without any notice. *** ### Platform Support The following shows `{Your_module_name}` module APIs available for each platform. | | Linux
(Ubuntu) | Raspbian
(Raspberry Pi) | NuttX
(STM32F4-Discovery) | | :---: | :---: | :---: | :---: | | {functionName1} | O | O | O | | {functionName2} | O | O | O | | {functionName3} | O | O | O | ### Contents - [{Your_module_name}](#your_module_name) - [Class: {Your_class_name}](#class-your_class_name) - [Constructor](#constructor) - [`new {Your_class_name}([{argument_name}])`](#new-your_class_nameargument_name) - [Properties](#properties) - [`{your_class_name}.{property_name}`](#your_class_nameproperty_name) - [Static Functions](#static-functions) - [`{Your_class_name}.{your_static_function_name}([{argument_name}])`](#your_class_nameyour_static_function_nameargument_name) - [Prototype Functions](#prototype-functions) - [`{your_class_name}.{your_prototype_function_name}([{argument_name}])`](#your_class_nameyour_prototype_function_nameargument_name) - [Events](#events) - [`{your_events_name}`](#your_events_name) - [Module Functions](#module-functions) - [`{your_module_name}.{your_module_function_name}([{argument_name}])`](#your_module_nameyour_module_function_nameargument_name) # {Your_module_name} - Write a brief description of this module here. - The first character of the title must start with an `uppercase letter`. #### Markdown Example ``` # Timer The timer module exposes a global API for scheduling functions to be called at some future period of time. Because the timer functions are globals, there is no need to call require('timers') to use the API. ``` # Class: {Your_class_name} - Write a brief description of this class here. - The first character of the title must start with an `uppercase letter`. - The table of contents should be in order of `"Constructor"`, `"Properties"`, `"Protype Functions"`, and `"Events"`. - While you are writing this description, if you need to write down module / class / function / event name, arguments, or type which you already mentioned, then enclose the keyword in single-quotation. This rule applies to other items as well. E.g) The given `callback` is called every `delay` milliseconds. If it's not a function, a `TypeError` will be thrown. ## Constructor ### `new {Your_class_name}([{argument_name}])` * `{argument_name} <{Argument_type}> Default: {defalut_value}` - {more information} Notice that every API name is in a single-quote. #### Markdown Example ``` # Class: Buffer Buffer class is a global type with various constructors and accessors. IoT.js provides Buffer to manipulate binary data. Currently buffer has a pure ES5 compatible implementation, but this might be reworked to use `UInt8Array` in the future. ## Constructor ### `new Buffer(size)` * `size Default: 0` - size of the new buffer Creates a new buffer of `size` bytes and initialize its data to zero. ``` ## Properties ### `{your_class_name}.{property_name}` - Write a description of this property here. - The title should be in a single quote. - The first character of the title must start with a `lowercase letter`. **Example** ``` Write a sample usage for this API if needed. ``` #### Markdown Example ``` ## Properties ### `buffer.length` * `` - length of the buffer Returns the capacity of the buffer in bytes. Note: when the buffer is converted to another type (e.g. `String`) the length of the converted value might be different from this value. **Example** ```js var Buffer = require('buffer'); var buffer = new Buffer([0xc8, 0x80]) console.log(buffer.length); // prints 2 var str = buffer.toString(); console.log(str.length); // prints 1 ``` ## Static Functions Write a description of static functions that belongs to the current class. ### `{Your_class_name}.{your_static_function_name}([{argument_name}])` * `{argument_name} <{Argument_type}> Default: {defalut_value}` - {more information} - Write a description of this function here. - The first character of Class in the title must start with an `Uppercase letter`. - The other rules are the same as mentioned before. **Example** ``` Write a sample usage for this API if needed. ``` #### Markdown Example ``` ## Static Functions ### `Buffer.byteLength(str[, encoding])` * `str ` - source string * `encoding ` - string encoding * Returns: `` - byte length of source string Returns the byte length of a buffer representing the value of the `string` argument encoded with `encoding`. The effect is the same as: ```js return new Buffer(str, encoding).length; ``` ## Prototype Functions Write a description of prototype functions that belongs to the current class. ### `{your_class_name}.{your_prototype_function_name}([{argument_name}])` * `{argument_name} <{Argument_type}> Default: {defalut_value}` - {more information} - Write a description of this function here. - The first character of Class in the title must start with a `lowercase letter`. - The other rules are the same as mentioned before. **Example** ``` Write a sample usage for this API if needed. ``` #### Markdown Example ``` ### `emitter.addListener(event, listener)` ### `emitter.on(event, listener)` * `event ` * `listener ` * `...args ` * Returns: `` Adds `listener` to the end of list of event listeners for `event`. **Example** ```js var EventEmitter = require('events').EventEmitter; var emitter = new EventEmitter(); emitter.addListener('event', function() { console.log('emit event'); }); ``` ## Events ### `{your_events_name}` * `{callback_name} <{callback_function_argument}>` * `{argument1} <{argument2_type}>` - {more information} - Write a description of this here. - In case of Event, the name of Class that this event belongs to, is not prepended in the title. - The other rules are the same as mentioned before. #### Markdown Example ``` ## Events ### `'lookup'` * `callback ` * `err | Null` - Optionally, write a description for each argument. * `address ` * `family | Null` ``` - Notice that the `err | Null` above is started with `2 spaces` indentation since it's given to `callback` as parameters, not `lookup` event. # Module Functions - `Module functions` are what you can directly invoke without an instance of a certain Class. E.g) net.connect. - Write a description of this here. ## `{your_module_name}.{your_module_function_name}([{argument_name}])` * `{argument_name} <{Argument_type}> Default: {defalut_value}` - {more information} - Write a description of this function here. - The first character of Class in the title must start with a `lowercase letter`. - The other rules are the same as mentioned before. ### Example ``` Write a sample usage for this API if needed. ``` #### Markdown Example ``` ### `gpio.open(configuration[, callback])` * `configuration ` * `pin ` - pin number to configure, mandatory configuration * `direction Default: GPIO.DIRECTION.OUT` - direction of the pin * `callback ` * Returns: `` ``` - Notice that the `pin ` above is started with `2 spaces` indentation since it's a property inside `configuration`. ssiotjs-1.0/docs/help/Assigned-people.md000066400000000000000000000003261312466455500177370ustar00rootroot00000000000000#### Maintainers * akiss77 (integration) * LaszloLango (integration) * zherczeg (Steering Committee) * yichoi (Steering Committee, Project main contact) #### Committers * chokobole * nova0821 * glistening * hs0225iotjs-1.0/docs/help/Coding-Style-Guideline.md000066400000000000000000000134141312466455500211260ustar00rootroot00000000000000Coding Style Guideline ====================== * [Coding Style Guideline for C](#coding-style-guideline-for-c) * Validated Struct * Header Files * Formatting * Naming * Comments * [Coding Style Guideline for Javascript](#coding-style-guideline-for-javascript) * Javascript Language Rules * Javascript Style Rules * Naming * Formatting * [Coding Style Guideline for Python](#coding-style-guideline-for-python) # Coding Style Guideline for C Our coding style guideline is based on [google c++ coding standard](https://google.github.io/styleguide/cppguide.html), but modified due to some difference between C and C++. When this guideline is ambiguous, just follow the result of running `./tools/check_tidy.py`. Here are `./tools/check_tidy.py` options: ``` --autoedit: Automatically edit the detected clang format errors. No diffs will be displayed. ``` ## Validated Struct Use [Validated Struct](../devs/Inside-IoT.js-Validated-Struct.md) whenever possible, for encapsulation and validity check. ## Header Files ### #define guard Use #define guard in all header files. `_H` format is recommended. #ifndef FILE_H #define FILE_H ... #endif // FILE_H ## Formatting ### Line length maximum 80 characters in a line. ### Indentation 2 space indent at a time. Do not use a tab for indentation. ### Vertical whitespace Add two blank lines between functions. Otherwise minimize use of vertical whitespace. This is more a principle than a rule: don't use blank lines when you don't have to. In particular, don't put more than two blank lines between functions, resist starting functions with a blank line, don't end functions with a blank line, and be discriminating with your use of blank lines inside functions. ### Function call Write a function call all in a line if it fits. If not, break the line into multiple lines after assignment operator, or insert newline between parameters. Do not insert spaces after open paren and before close paren. int value = foo(arg1, arg2, arg3); int value = foo(arg1, arg2, arg3); int value = foo(arg1, arg2, arg3); ### Function Declaration and Definition Use named parameters in function declaration. return_type function_name(int, char); // not allowed return_type function_name(int arg1, char arg2); // Use this Return type should be on the same line as function name and parameters if it fits. If not, break between them aligned with the first argument. return_type function_name(int arg1, char arg2); If even first argument does not fit in a line, write it in a new line with 4 space indent. return_type function_name( int arg1, char arg2); The open curly brace should be at the same line. The close curly brace should be either at the same line as its open curly brace or at new line. return_type function_name(int arg1, char arg2) { }; return_type function_name(int arg1, char arg2) { ... } return_type function_name(int arg1, char arg2) { // not allowed ... } ### Conditionals Use a space between the if and open brace. Open brace on the same line as the if. if (condition) { ... } Short conditional statements may be written without braces. if (condition) do_something(); ### Loops and Switches Use a space between the switch and loops(for, while, do-while) and open brace. Open brace on the same line as the switch and loops. while (condition) { ... } Single loop body statement may be written without braces. while (condition) do_something(); // ok for (condition) do_something(); // ok ## Naming ### Type names Use lower cases and underscore for struct names, and add prefix `iotjs_` and suffix `_t`. typedef struct { ... } iotjs_name_t; ### Function names Use lower cases and underscore for function names. For constructors, destructor, and methods of validated struct `iotjs_mystruct_t`, use names starting with `iotjs_mystruct_*`. Constructor function name should be either `iotjs_mystruct_create` or `iotjs_mystruct_initialize`, depending on whether the constructor returns the instance as return value, or the constructor just initializes the instance passed by parameter. ```c typedef struct { } IOTJS_VALIDATED_STRUCT(iotjs_mystruct_t); iotjs_mystruct_t iotjs_mystruct_create(); // Ok iotjs_mystruct_t* iotjs_mystruct_create(); // Ok void iotjs_mystruct_initialize(iotjs_mystruct_t*); // Ok void iotjs_mystruct_destroy(); int iotjs_mystruct_method(); ``` ### Variable names Use lower cases and underscore for variable names. int lower_case_variable; ## Comments ### Comment style Use either // or /* */ style comments. However, // style is much prefered. # Coding Style Guideline for Javascript This coding standard is based on [google javascript coding standard](https://google.github.io/styleguide/javascriptguide.xml) ## Javascript Language Rules ### var Always declare variable before use. ### Semicolons Always use semicolons. ### Function Declaration in blocks Do not declare functions within a block. ### Wrapper objects of primitive types Do not use wrapper objects for primitive types. ### with Do not use `with` statement. ### Modifying prototypes of builtin objects Do not modify prototypes of builtin objects ## Javascript Style Rules ### Naming Use lowerCamelCase for varible names and function names. var myFirstVariable; function myFirstFunction { ... } Use UpperCamelCase for constructor names function MyConstructorFunction(input) { this.variable = input; ... } ### Formatting Follow C/C++ formatting above. # Coding Style Guideline For Python The coding conventions for Python code follows [PEP 8 - Style Guide for Python Code](https://www.python.org/dev/peps/pep-0008/) iotjs-1.0/docs/help/Community-Guidelines.md000066400000000000000000000034141312466455500207730ustar00rootroot00000000000000All community members must abide by rules of common sense, civility and good neighborliness. Frank discussion is welcomed and encouraged with the goal of arriving at the best technical solution possible. Community participants must adhere to these simple rules: - Respect and acknowledge all contributions, suggestions and comments from the community. - Listen and be open to all opinions, which are subject to open discussion. - Help each other. - Assume people mean well.
### Community Consensus, Lazy Consensus and Slient Consent Community consensus about a Project issue means that the issue has been submitted to and discussed by Contributors, and that ALL discussing member agree about the issue.

Lazy consensus means that Contributors may proceed with work when they have reason to believe that other Contributors in the community will agree with the direction of their work, and do not need to stop or initiate unnecessary discussion about the work. Contributors should publish their work (that is, merge proposals to master branch) in a timely manner to allow others to possibly raise issues about the work. When the Contributor is not sure there will be consensus, they should raise a proposal to the community via appropriate public communication channels(**_currently Github issues is possible way to achieve this_**)

Silent Consent means that those who do not offer a reasoned alternative in course of the discussion implicitly agree with the proposal.
### Meritocracy Responsibilities in the project (including decision making) are given to those who exhibit both the technical skill and dedication to project via their ongoing valuable contributions. Decision making happens inside the community, with more weight given to those who are more familiar with the code. iotjs-1.0/docs/help/Developer's-Guide.md000066400000000000000000000002211312466455500201240ustar00rootroot00000000000000 - [Getting Started](Getting-Started.md) - [Developer Tutorial](Developer-Tutorial.md) - [IoT.js API Reference](../api/IoT.js-API-reference.md)iotjs-1.0/docs/help/Developer-Tutorial.md000066400000000000000000000161461312466455500204550ustar00rootroot00000000000000### Getting Started with Examples As **IoT.js** is asynchronous and event-driven, programming style is pretty much different from traditional blocking synchronous style. This tutorial lets you know how to code with **IoT.js** mainly focused on asynchronous and event-driven style. #### Hello World Firstly, create a javascript file (e.g. `hello.js`) and open it. Then type as following. ```javascript console.log('Hello, world!'); ``` You must be familiar with the code above if you have ever worked with Javascript in web. This is exactly same way as in major web browsers. You can run it with: ``` $ ./iotjs hello.js ``` Then it gives: ``` Hello, world! ``` Pretty simple. But where did `console` come from? `console` is not defined in Global Object according to ECMAScript spec. The answer is `console` is a builtin module so it should have been `require`ed. However, `console` is a special case so we can use it directly without `require`. This is about Module System which we will cover later. #### File Reader To read a file, we need to import *File System* module. When importing a module, we use function `require`. *File System* module is abbreviated as `fs`. You can import it like: ```javascript var fs = require('fs'); ``` Then we can use APIs of `fs`. To read the whole file, use `readFile()`. ```javascript fs.readFile("hello_iotjs.txt", // path readFileCallback); // callback ``` Let's say we want to read `hello_iotjs.txt`. Just pass it as first argument. It may be enough for synchronous style but we must specify a callback function as last argument. `fs.readFile` does not wait for I/O to be done, it just goes on to next code. Sometime after file opening is completely done, callback will be called. This means that we must not implement `readFile` handling code on the next line, but in callback function. Take a look at the callback function for `fs.readFile` below. ```javascript function readFileCallback(err, data) { if (err) throw err; console.log(data.toString()); } ``` We can find two arguments in this function. We can think of them as the results of `fs.open`. In this case(`fs.readFile`), `err` and `data` are given. Of course, each API function has their own argument list. `err` is an `Error` object. We just throw it if an error has occurred. Otherwise we have successfully read the file content and it is stored in `data`. In this example, it only prints the file content but you can do anything you want. ##### full code list ```javascript var fs = require('fs'); fs.readFile("hello_iotjs.txt", // path readFileCallback); // callback function readFileCallback(err, data) { if (err) throw err; console.log(data.toString()); } ``` #### TCP Echo Server `net` module provides APIs for creating servers and clients. In this tutorial, we are going to create a server only. We can connect to the server and test it with external tools(e.g. `nc`). Firstly, we need to require `net` module. ```javascript var net = require('net'); var port = 1235; // custom port number ``` Then create a server with `net.createServer()`. It could have some arguments ```javascript var server = net.createServer(); ``` After creating a server, make the server listen for connections. ```javascript server.listen(port); ``` By calling `listen`, object `server` starts listening with given port. Of course `listen` is processed asynchronously but we do not have to specify a callback. What we want to do next is not necessarily done in the callback because we are just going to add some event handlers. **IoT.js** is event-driven. We can do a lot of stuff with event handlers. Both `Server` and `Socket` object inherits from `EventsEmitter`, so we can add event listeners for them. For servers, we probably want to add a listener for `'connection'` event which is emitted when a new connection is made. Take a look at the following. ```javascript server.on('connection', function(socket) { socket.on('data', function(data) { socket.write("echo: " + data); }); }); ``` In `File Reader` example, we defined callbacks outside and referred them as arguments. In this time the function is embedded as a Function Expression. When `'connection'` event is emitted, it creates a socket and we can get it from the first argument. In the same way we did for server, add a ``data`` listener for each socket which is emitted when data is received. As we are creating an echo server, what we want to do here is just send the `data` back to client. Note that to clarify this is an echoed data, `"echo: "` is prepended to it. That is all. We just implemented an echo server less than 10 lines. Actually, the server will run forever because we did not add code for closing the server. As long as the server is listening, it does not terminate even if there is no more *javascript* code to run. As this is a simple tutorial, just kill the process manually like pressing `Ctrl+C` ##### full code list ```javascript var net = require('net'); var port = 1235; var server = net.createServer(); server.listen(port, 5); server.on('connection', function(socket) { socket.on('data', function(data) { socket.write("echo: " + data); }); }); ``` ##### test the server We have created a server but not a client. Instead of implementing a client, we are going to use a unix tool `nc`. Run the server first: ``` $ ./iotjs echo_server.js & ``` Connect to the server with `nc` ``` $ nc localhost 1235 ``` Type whatever you want to send, and the message will be echoed back. ``` hello, echo server! echo: hello, echo server! ``` ### Module System Javascript(ECMAScript 5.1 or under) itself does not support module system. In web browsers, even though a web page loads several Javascript files, they are evaluated in the same context. To overcome this language limit, **IoT.js** supports [CommonJS](http://www.commonjs.org/) modules. We have used some of native modules through the examples above. When importing those modules, we use `require` function. Once `require`ed a module, we can use its APIs that are exported from the module. It will be covered in the section [Writing user modules](#writing-user-modules). #### Writing user modules When writing a module, APIs must be exposed by adding it in `exports` object. Otherwise it can be used only inside the module. Object `exports` will be returned when another module calls `require`. Let's write a sample module. Save it as `mymodule.js` ```javascript exports.hello = 'Hello, IoT.js!'; // string exports.add = function(a, b) { // function return a + b; } var local = 'local string'; // string (not exported) ``` Let's write another module that uses the module we just wrote. By calling `require`, we get its `exports` object. We will name it `mymodule_test.js` ```javascript var mymodule = require('mymodule'); console.log(mymodule.hello); console.log(mymodule.add(1, 2)); console.log(mymodule.local); ``` Save two files in the same directory so **IoT.js** can automatically find `mymodule.js`. Then we are ready to go. Execute the later script then you will see: ``` $ ./iotjs mymodule_test.js Hello, IoT.js! 3 undefined ``` Note that `console.log(local)` prints `undefined`. It cannot be referred because it is not added in `exports`.iotjs-1.0/docs/help/Development-Process.md000066400000000000000000000117371312466455500206260ustar00rootroot00000000000000* [Proposals, Get Answers and Report a Bug via Github Issues](#proposals-get-answers-and-report-a-bug-via-github-issues) * [Feature development process](#feature-development-process) * [Approval Path for PR(Pull Request)](#approval-path-for-prpull-request) * [Tips on GitHub Issues](#tips-on-github-issues) *** It is the responsibility of IoT.js Maintainers and Reviewers to decide whether submitted code should be integrated into the master branch, returned for revision, or rejected. Individual developers maintain a local copy of the IoT.js codebase using the git revision control system. Git ensures that all participants are working with a common and up-to-date code base at all times. Each developer works to develop, debug, build, and validate their own code against the current codebase, so that when the time comes to integrate into the master branch of the project, their changes apply cleanly and with a minimum amount of merging effort. ### Proposals, Get Answers and Report a Bug via Github Issues If you have a question about IoT.js code, have trouble any documentation, would like to suggest new feature, or find a bug, [review the current IoT.js issues](https://github.com/Samsung/iotjs/issues) in GitHub, and if necessary, [create a new issue](https://github.com/Samsung/iotjs/issues/new). **There are several labels on the Issue. Please choose proper labels on the purpose.** * **bug** * **community** : any issues on the community operation * **enhancement** : feature enhancement proposal * **help wanted** * **new feature request(proposal)** : new feature proposal * **project announcement** : general announcement on the project such as new release, new Maintainer/Reviewer and so on * **question** : any questions on the project and so on. ### Feature development process The IoT.js Project development process is marked by the following highlights: * The feature development process starts with an author discussing a proposed feature with the Maintainers and Reviewers - Open the issue with label 'new feature request(proposal)' * The Maintainers and Reviewers evaluate the idea, give feedback, and finally approve or reject the proposal. * The author shares the proposal with the community via **_Github issues with 'new feature request' label_** * The community provides feedback which can be used by the author to modify their proposal and share it with the community again. * The above steps are repeated until the community reaches a consensus according to the [Community Guidelines](Community-Guidelines.md). * After a consensus is reached, the author proceeds with the implementation and testing of the feature. * After the author is confident their code is ready for integration: - The author generates a patch and signs off on their code. - The author submits a patch according to the [Patch Submission Process](Patch-Submission-Process.md). * The Maintainers and Reviewers watch the pull request for the patch, test the code, and accept or reject the patch accordingly. * After the code passes code review, the Maintainers and Reviewers accept the code(integrated into the master branch), which completes the development process. * After a patch has been accepted, it remains the authoring developer's responsibility to maintain the code throughout its lifecycle, and to provide security and feature updates as needed. ### Approval Path for PR(Pull Request) 1. Developer should create/update PR to a given issue or enhancement 2. If Developer works in a team, then peer-review by a colleague developer should be performed 3. If peer-review was OK, then Developer should summon the component's maintainer 4. Maintainer should check the code: - make precommit testing is OK (performed automatically) - No minor issues (unified implementation style, comments, etc.) - No major issues (memory leak, crashes, breakage of ECMA logic, etc.) 5. If Developer has to rework the solution then goto step 3 6. If everything is OK, then Maintainer should approve the PR with +1(or LGTM) - Code review can be performed by all the members of the project. However only Maintainer can give binding scores. 7. When the PR get +2(2 LGTM from 2 mainatiners respectively), it should be merged. ### Tips on GitHub Issues * Check existing [IoT.js issues](https://github.com/Samsung/iotjs/issues) for the answer to your issue. Duplicating an issue slows you and others. Search through open and closed issues to see if the problem you are running into has already been addressed. * If necessary, [open a new issue](https://github.com/Samsung/iotjs/issues/new). - Clearly describe the issue. + What did you expect to happen? + What actually happened instead? + How can someone else recreate the problem? - Include system details(such as the hardware, library, and operating system you are using and their versions). - Paste error output and logs in the issue or in a Gist(https://gist.github.com/). For more information about GitHub issues, refer to the [GitHub issues guidelines](https://guides.github.com/features/issues/).iotjs-1.0/docs/help/Extended-API-Guideline.md000066400000000000000000000043341312466455500207750ustar00rootroot00000000000000Extended API Guideline ====================== Basically, our basic APIs are based on node.js. They will follow same form with node.js because of compatibility.
However, extended APIs need a guideline because they are implemented by many contributor. (for consistent usability) # Ground Rules ## API naming rules 1. The APIs which have similar role should have same API name. 2. Basically, all APIs are async API. If you want to make sync API, you need to add `Sync` as a suffix.
For example, `readSync()`, `writeSync()`, and so on. ## Generating an object 1. The module object should be generated using `open()` API for consistent usability. (Do not use `New` constructor) 2. `open()` API should have configuable as first argument and callback function as second argument.
callback function is always optional. For example, GPIO module generate an object like below: ```javascript var gpio = require('gpio'); var gpio10 = gpio.open({pin: 10, direction: gpio.DIRECTION.OUT}, function(err){console.log(err);}); ``` ## Minimize event generation 1. The response of the API call uses callback function. 2. Only generate event when user need to know something without any API call. 3. The event which have similar role should have same event name. ## Error generation 1. `error` can be generated in both JS/native side. 2. The `error` shoud be created in the place where it occurs. For example, error can be generated like below: In native side, ```c iotjs_jargs_t jargs = iotjs_jargs_create(2); // kGpioErrRead: int if (result == kGpioErrRead) { iotjs_jargs_append_error_with_code(&jargs, "GPIO Error", kGpioErrRead); } ``` In JavaScript side, ```javascript if (!util.isNumber(value)) { throw new TypeError('Bad arguments'); } ``` ## Type checking 1. Type checking of API argument is possible both in JS and Native. 2. To prevent type checking multiple times, perform type checking on the first function that receives the variable. 3. Throw `error` when type checking is failed. # Recommended Rules 1. Call `close()` api when process module occur `exit` event. 2. If it is possible, use the functions provided by `libtuv` (File open, read, write, etc.) 3. Callback function in API argument should be always optional. iotjs-1.0/docs/help/Getting-Started.md000066400000000000000000000075461312466455500177400ustar00rootroot00000000000000### Overview IoT.js is built based on **JerryScript** (lightweight JavaScript engine) and **libtuv** for asynchronous I/O event handling. #### Source repositories * IoT.js: https://github.com/Samsung/iotjs.git * JerryScript: https://github.com/jerryscript-project/jerryscript.git * libtuv: https://github.com/Samsung/libtuv.git ### Build script There is a script to help you build IoT.js called "[build.py](../../tools/build.py)" in source repository. ### Supported platforms Current supported platforms are **Linux and NuttX** * [Build for Linux](../build/Build-for-Linux.md): Ubuntu 14.04 is used as a base platform. * [Build for NuttX](../build/Build-for-NuttX.md) * [Build for Raspberry Pi 2](../build/Build-for-RPi2.md) ##### Platforms to support * OSX 10.10 as development host * [Artik 1 =>](https://www.artik.io/hardware/artik-1) as target board ##### H/W boards * Current supporting * STM32F4-Discovery + BB * Raspberry Pi 2 * Plan to support * Samsung Artik 1 * STM32F429-Discovery * STM32F411-Nucleo * Intel Edison * (and your contributions including above plans) We will support the correct behavior of APIs for above environments. However, since IoT.js is targeting various kind IoT devices and platforms, single implementation cannot be the best practice for every environments. Therefore embedders should be in charge of optimization for their own environments. For more details on optimization, see the [Optimization Tips](../devs/Optimization-Tips.md) page. ### For Developers #### How to Test When you build ``iotjs`` binary successfully, you can run test driver with this binary. ```bash /path/to/iotjs tools/check_test.js ``` ##### Set test options Some basic options are provided. Existing test options are listed as follows; ``` start-from quiet=yes|no (default is yes) output-file skip-module output-coverage=yes|no (default is no) experimental=yes|no (default is no) ``` To give options, please use two dashes '--' **once** before the option name as described in the following sections. Options that may need explanations. * start-from: a test case file name where the driver starts. * quiet: a flag that indicates if the driver suppresses console outputs of test case. * output-file: a file name where the driver leaves output. * skip-module: a module list to skip test of specific modules. * output-coverage: a flag that indicates wether coverage data should be written to disk * experimental: a flag that indicates if tests for experimental are needed ##### Options example ```bash build/x86_64-linux/debug/bin/iotjs tools/check_test.js -- start-from=test_console.js quiet=no ``` ##### To write a test case Depend on the purpose of the test case (whether it's a positive or negative one), place it under `test/run_pass` or `test/run_fail` directory. The required external resources should be placed into `test/resources`. All test case files must be named in the following form `test_[_` should match one of the JS modules name in the IoT.js. If there is a test case which can not tied to a module (like some js features) then the `iotjs` name can be used as module name. It is important to correctly specify the module name as the test executor relies on that information. 1. Write a test case and place it into the proper directory. 2. List up the test case in [test/testsets.json](../../test/testsets.json), and set attributes (timeout, skip, ...) on the test case if it needs. #### Advanced Topics You can refer to [Writing new IoT.js builtin module](../devs/Writing-New-Builtin-Module.md) and [Optimization Tips](../devs/Optimization-Tips.md) pages for detailed information. ### When something goes wrong Please read the [Logging IoT.js execution](../devs/Logging-IoT.js-execution.md) page how to display and add log messages while developing. ### [IoT.js API Reference](../api/IoT.js-API-reference.md) iotjs-1.0/docs/help/Getting-involved.md000066400000000000000000000015261312466455500201500ustar00rootroot00000000000000To contribute to the IoT.js Project (such as reporting bugs and submitting patches): * Follow the [Development Process](Development-Process.md) and [GitHub contributor guidelines](https://guides.github.com/activities/contributing-to-open-source/). * Add the [IoT.js DCO](IoT.js-Developer's-Certificate-of-Origin-1.0.md) signoff to each commit message during development. * Add the [License](../License.md) if you introduce any new source code or script files ### [Community Guideline](Community-Guidelines.md) ### [IoT.js Developer's Certificate of Origin 1.0](IoT.js-Developer's-Certificate-of-Origin-1.0.md) ### [Coding Style Guideline](Coding-Style-Guideline.md) ### [Inside IoT.js](../devs/Inside-IoT.js.md) ### [Development Process](Development-Process.md) ### [Patch Submission Process](Patch-Submission-Process.md) ### [Governance](Governance.md)iotjs-1.0/docs/help/Governance.md000066400000000000000000000133251312466455500170120ustar00rootroot00000000000000* [Project Roles](#project-roles) - [Contributor](#contributor) - [Committer](#committer) - [Maintainer](#maintainer) - [Selection of Committers and Maintainers](#selection-of-committers-and-maintainers) - [Revocation of Committers/Maintainers status](#revocation-of-committersmaintainers-status) - [Steering Committee](#steering-committee) * [Decision Making Process](#decision-making-process) ## Project Roles The IoT.js project recognizes the following formal roles: Contributor, Committer, and Maintainer. * [Assigned people](Assigned-people.md) #### Contributor A _Contributor_ is a developer who wishes to contribute to the project, at any level. Contributors who show dedication and skill are rewarded with additional rights and responsibilities. Their opinions weigh more when decisions are made, in a fully meritocratic fashion. Contributors are granted the following rights and responsibilities: * Right to contribute code, documentation, translations, artwork, etc. * Right to report defects (bugs) and suggestions for enhancement. * Right to participate in the process of reviewing contributions by others. * Right to initiate and participate in discussions in any communication methods. * Right to approach any member of the community with matters they believe to be important. * Responsibility to abide by decisions, once made. They are welcome to provide new, relevant information to reopen decisions. * Responsibility for issues and bugs introduced by one’s own contributions. * Responsibility to respect the rules of the community. * Responsibility to provide constructive advice whenever participating in discussions and in the review of contributions. #### Committer A _Committer_ is a Contributor who is also responsible for the maintenance of IoT.js source code. Committers have the following rights and responsibilities, in addition to those listed for Contributors: * Right to set goals for the short and medium terms for the project being maintained, alongside the Maintainer. * Right to exceptionally make more invasive changes to the source code, when required. * Right to approve own contribution, after discussing with other Contributors. * Right and responsibility to participate in the feature development process. * Responsibility to ensure all contributions of the project have been reviewed within reasonable time. * Responsibility to ensure the quality of the code to expected levels. * Responsibility to monitor discussions in the community. * Responsibility to participate in the quality verification and release process, when those happen. #### Maintainer A _Maintainer_ is a Contributor who is also responsible for knowing, directing and anticipating the needs of a given IoT.js source code. Maintainers have the following rights and responsibilities, in addition to those listed for Contributors and Committers: * right to set the overall organization of the source code of the project * right to participate in the decision-making of the project, in conjunction with the Committers. * Responsibility to ensure all contributions of the project have been reviewed within reasonable time. - In the reviewing, only Maintainers can give binding scores(refer to [Approval Path for PR(Pull Request)](#approval-path-for-prpull-request)) #### Selection of Committers and Maintainers A candidate for the Committer role should be one of the Contributors who has submitted at least 10 non-trivial patches in project and has shown characteristics consistent with the requirements of the Committer role. A candidate for the Maintainer role should be one of the Committers. To be a candidate for the Committer or Maintainer, a Contributor can self-nominate with proper evidences. The selection process should be achieved by consensus of the Contributors active in. If consensus cannot be achieved, Maintainers will make the decision by voting. #### Revocation of Committers/Maintainers Status A Maintainer or a Committer who intentionally abused his review privilege may have it temporarily suspended on the request of other Committers or Maintainers. Committers and Maintainers not including the person under consideration should discuss on the revocation of the person. If consensus cannot be reached, Maintainers will make the decision by voting. #### Steering Committee _Steering Committee_ oversees and guides the progress of IoT.js project. The Steering Committee have the following responsibilities: * responsibility to oversee the health of the project community. * responsibility to oversee and facilitate the development of the IoT.js source code under the governance rules of the IoT.js Open Source project. * responsibility to guide and direct the development towards goals. * responsibility to sets the goals and roadmap for the project ## Decision Making Process Decisions in the IoT.js project are made always at the lowest level possible that is applicable for the decision in question. Decision makers always need to keep in mind the rules of community and the IoT.js goals and roadmap. * Individual Contributors are making decisions every time they submit changes in the form of deciding what to implement and how to go about it. * Two or more Contributors also make decisions when participating in discussions in community, on bug or feature reports, in reviewing of commits. Their arguments in why a given decision should be made are part of the consensus that needs to be reached for the decision. At this level, the principle of meritocracy is important, as the opinion of those who have contributed more will be given more weight in the consensus-building. * If those Contributors cannot agree and reach consensus on a decision, then IoT.js provides for decisions to be made by Maintainers following their own decision-making process, avoiding stalemates.iotjs-1.0/docs/help/IoT.js-Developer's-Certificate-of-Origin-1.0.md000066400000000000000000000046131312466455500245510ustar00rootroot00000000000000The IoT.js project uses the signed-off-by language and process, to give us a clear chain of trust for every patch received. > By making a contribution to this project, I certify that: > (a) The contribution was created in whole or in part by me and I have the right to submit it under the open source license indicated in the file; or > (b) The contribution is based upon previous work that, to the best of my knowledge, is covered under an appropriate open source license and I have the right under that license to submit that work with modifications, whether created in whole or in part by me, under the same open source license (unless I am permitted to submit under a different license), as indicated in the file; or > (c) The contribution was provided directly to me by some other person who certified (a), (b) or (c) and I have not modified it. > (d) I understand and agree that this project and the contribution are public and that a record of the contribution (including all personal information I submit with it, including my sign-off) is maintained indefinitely and may be redistributed consistent with this project, under the same open source license. ### Using the Signed-Off-By Process We have the same requirements for using the signed-off-by process as the Linux kernel. In short, you need to include a signed-off-by tag in every patch: "Signed-off-by:" this is a developer's certification that he or she has the right to submit the patch for inclusion into the project. It is an agreement to the Developer's Certificate of Origin (above). **Code without a proper signoff cannot be merged into the mainline.** You should use your real name and email address in the format below: > IoT.js-DCO-1.0-Signed-off-by: Random J Developer random@developer.example.org #### How to add DCO every single commit automatically. It is easy to forget adding DCO end of every commit message. Fortunately there is a nice way to do it automatically. Once you've clone the repository into your local machine, you can add `prepare commit message hook` in `.git/hooks` directory like this: ``` #!/usr/bin/env python import sys commit_msg_filepath = sys.argv[1] with open(commit_msg_filepath, "r+") as f: content = f.read() f.seek(0, 0) f.write("%s\n\nIoT.js-DCO-1.0-Signed-off-by: " % content) ``` Please refer [Git Hooks](http://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks) for more information.iotjs-1.0/docs/help/Patch-Submission-Process.md000066400000000000000000000070701312466455500215270ustar00rootroot00000000000000The following guidelines on the submission process are provided to help you be more effective when submitting code to the IoT.js project. When development is complete, a patch set should be submitted via Github pull requests. A review of the patch set will take place. When accepted, the patch set will be integrated into the master branch, verified, and tested. It is then the responsibility of the authoring developer to maintain the code throughout its lifecycle. Please submit all patches in public by opening a pull request. Patches sent privately to Maintainers and Committers will not be considered. Because the IoT.js Project is an Open Source project, be prepared for feedback and criticism-it happens to everyone-. If asked to rework your code, be persistent and resubmit after making changes. #### 1. Scope the patch Smaller patches are generally easier to understand and test, so please submit changes in the smallest increments possible, within reason. Smaller patches are less likely to have unintended consequences, and if they do, getting to root cause is much easier for you and the Maintainers and Committers. Additionally, smaller patches are much more likely to be accepted. #### 2. Sign your work with the [IoT.js DCO](IoT.js-Developer's-Certificate-of-Origin-1.0.md) The sign-off is a simple line at the end of the explanation for the patch, which certifies that you wrote it or otherwise have the right to pass it on as an Open Source patch. The sign-off is required for a patch to be accepted. #### 3. Open [a Github pull request](https://github.com/Samsung/iotjs/pulls) #### 4. What if my patch is rejected? It happens all the time, for many reasons, and not necessarily because the code is bad. Take the feedback, adapt your code, and try again. Remember, the ultimate goal is to preserve the quality of the code and maintain the focus of the Project through intensive review. Maintainers and Committers typically have to process a lot of submissions, and the time for any individual response is generally limited. If the reason for rejection is unclear, please ask for more information to the Maintainers and Committers. If you have a solid technical reason to disagree with feedback and you feel that reason has been overlooked, take the time to thoroughly explain it in your response. #### 5. Code review Code review can be performed by all the members of the Project (not just Maintainers and Committers). Members can review code changes and share their opinion by comments with the following principles: * Discuss code; never discuss the code's author. * Respect and acknowledge contributions, suggestions, and comments. * Listen and be open to all different opinions. * Help each other. Changes are submitted via pull requests and only the Maintainers and Committers should approve or reject the pull request. Changes should be reviewed in reasonable amount of time. Maintainers and Committers should leave changes open for some time (at least 1 full business day) so others can offer feedback. Review times increase with the complexity of the review. ### Tips on GitHub Pull Requests * Fork the GitHub repository(https://guides.github.com/activities/forking/) and clone it locally. Connect your local repository to the original upstream repository by adding it as a remote. Pull in upstream changes often to stay up-to-date so that when you submit your pull request, merge conflicts will be less likely. * For more details, see [GitHub fork synching guidelines](https://help.github.com/articles/syncing-a-fork/). [Create a branch](https://guides.github.com/introduction/flow/) for your edits.iotjs-1.0/docs/targets/000077500000000000000000000000001312466455500151165ustar00rootroot00000000000000iotjs-1.0/docs/targets/nuttx/000077500000000000000000000000001312466455500163005ustar00rootroot00000000000000iotjs-1.0/docs/targets/nuttx/stm32f4dis/000077500000000000000000000000001312466455500202025ustar00rootroot00000000000000iotjs-1.0/docs/targets/nuttx/stm32f4dis/IoT.js-API-Stm32f4dis.md000066400000000000000000000111011312466455500240730ustar00rootroot00000000000000## Pin In order to use system IO, such as GPIO, PWM and ADC you need to know the pin name. The `stm32f4dis` module has pin object which is designed to find a pin name easier. **Example** ```js var pin = require('stm32f4dis').pin; ``` ### GPIO Pin P[port][pin] A configured GPIO pin. The `port` must be equal to a capital letter from 'A' to 'D'. The `pin` must be equal to an integer from 0 to 15. **Example** ```js var gpio = require('gpio'); var pin = require('stm32f4dis').pin; gpio.open(pin.PD6); ``` ### PWM Pin PWM[timer].CH[channel]_[number] A configured PWM pin. The `timer` must be equal to an integer from 1 to 14. The `channel` must be equal to an integer from 1 to 4, but it also depends on the `timer`. The `number` must be equal to an integer form 1 to 2, and 3 in case of PWM3.CH1_3, PWM3.CH2_3 and PWM2.CH1_3. **Example** ```js var pwm = require('pwm'); var pin = require('stm32f4dis').pin; var pwm2 = new pwm(pin.PWM2.CH1_2); ``` The following table shows the available PWM pin names and their corresponding GPIO pins. | PWM Pin Name | GPIO Name | PWM Pin Name | GPIO Name| | :---: | :---: | :---: | :---: | | PWM1.CH1_1 | PA8 | PWM4.CH1_1| PB6 | | PWM1.CH1_2 | PE9 | PWM4.CH1_2| PD12 | | PWM1.CH2_1 | PA9 | PWM4.CH2_1| PB7 | | PWM1.CH2_2 | PE11 | PWM4.CH2_2| PD13 | | PWM1.CH3_1 | PA10 | PWM4.CH3_1| PB8 | | PWM1.CH3_2 | PE13 | PWM4.CH3_2| PD14 | | PWM1.CH4_1 | PA11 | PWM4.CH4_1| PB9 | | PWM1.CH4_2 | PE14 | PWM4.CH4_2| PD15 | | PWM2.CH1_1| PA0 | PWM5.CH1_1| PA0 | | PWM2.CH1_2| PA15 | PWM5.CH2_1| PA1 | | PWM2.CH1_3| PA5 | PWM5.CH3_1| PA2 | | PWM2.CH2_1| PA1 | PWM5.CH4_1| PA3 | | PWM2.CH2_2| PB3 | PWM8.CH1_1| PC6 | | PWM2.CH3_1| PA2| PWM8.CH2_1| PC7| | PWM2.CH3_2| PB10| PWM8.CH3_1| PC8| | PWM2.CH4_1| PA3 | PWM8.CH4_1| PC9 | | PWM2.CH4_2| PB11 | PWM9.CH1_1 | PA2 | | PWM3.CH1_1 | PA6 | PWM9.CH1_2 | PE5 | | PWM3.CH1_2 | PB4 | PWM9.CH2_1 | PA3 | | PWM3.CH1_3 | PC6 | PWM9.CH2_2 | PE6 | | PWM3.CH2_1 | PA7 | PWM10.CH1_1 | PB8 | | PWM3.CH2_2 | PB5 | PWM11.CH1_1 | PB9 | | PWM3.CH2_3 | PC7 | PWM12.CH1_2 | PB14 | | PWM3.CH3_1 | PA11 | PWM12.CH2_1 | PB15 | | PWM3.CH3_2 | PE14 | PWM13.CH1_1 | PA6 | | PWM3.CH4_1 | PB1 | PWM14.CH1_1 | PA7 | | PWM3.CH4_2 | PC9 | | | ### ADC Pin ADC[number]_[timer] A configured ADC pin. The `number` must be equal to an integer from 1 to 3. The `timer` must be equal to an integer from 0 to 15. **Example** ```js var adc = require('adc'); var pin = require('stm32f4dis').pin; var adc1 = new adc(pin.ADC1_3); ``` The following table shows the available ADC pin names and their corresponding GPIO pins. | ADC Pin Name | GPIO Name | | :--- | :---: | | ADC1_0, ADC2_0, ADC3_0 | PA0 | | ADC1_1, ADC2_1, ADC3_1 | PA1 | | ADC1_2, ADC2_2, ADC3_2 | PA2 | | ADC1_3, ADC2_3, ADC3_3 | PA3 | | ADC1_4, ADC2_4 | PA4 | | ADC1_5, ADC2_5 | PA5 | | ADC1_6, ADC2_6 | PA6 | | ADC1_7, ADC2_7 | PA7 | | ADC1_8, ADC2_8 | PB0 | | ADC1_9, ADC2_9 | PB1 | | ADC1_10, ADC2_10, ADC3_10 | PC0 | | ADC1_11, ADC2_11, ADC3_11 | PC1 | | ADC1_12, ADC2_12, ADC3_12 | PC2 | | ADC1_13, ADC2_13, ADC3_13 | PC3 | | ADC1_14, ADC2_14 | PC4 | | ADC1_15, ADC2_15 | PC5 | ## UART Port Information In order to use the UART on stm32f4-discovery board, you must use proper pins. The stm32f4-discovery board supports 4 UART ports, such as USART2, USART3, UART5, USART6. The UART5 port and the SDIO uses the same pin for connection. SDIO is enabled by default, so be careful when you enable the UART5 port. The following table shows the U[S]ART pin map: | U[S]ART Pin Name | GPIO Name | | :--- | :---: | | USART2_RX | PA3 | | USART2_TX | PA2 | | USART3_RX | PB11 | | USART3_TX | PB10 | | UART5_RX | PD2 | | UART5_TX | PC12 | | USART6_RX | PC7 | | USART6_TX | PC6 | Note: The name of the UART device cannot find by the `stm32f4dis.pin` module, because it can be changed in the NuttX configuration file. It should be '/dev/ttyS[0-3]'. ### Enable USART1 and UART4 The current version of the NuttX does not support the USART1 and UART4 ports for stm32f4-discovery board. The `config/nuttx/stm32f4dis/patch` file contains the implementations of the the USART1 and UART4 ports. It maps the PB6 and PB7 gpio pins to USART1_TX and USART2_RX, PA0 and PA1 gpio pins to UART4_TX and UART4_RX respectively. Note: You can add more ports according to the patch file. **Apply the patch** ```bash ~/workspace/nuttx$ patch -p1 < ../iotjs/config/nuttx/stm32f4dis/patch ``` ## I2C Port Information In order to use the I2C on stm32f4-discovery board, you must use proper pins. Currently only I2C1 is supported. The following table shows the I2C pin map: | I2C Pin Name | GPIO Name | | :--- | :---: | | I2C1_SCL | PB8 | | I2C1_SDA | PB7 | iotjs-1.0/docs/targets/nuttx/stm32f4dis/README.md000066400000000000000000000145471312466455500214740ustar00rootroot00000000000000### About This directory contains files to run IoT.js on [STM32F4-Discovery board](http://www.st.com/content/st_com/en/products/evaluation-tools/product-evaluation-tools/mcu-eval-tools/stm32-mcu-eval-tools/stm32-mcu-discovery-kits/stm32f4discovery.html) with [NuttX](http://nuttx.org/) ### How to build #### 1. Set up the build environment for STM32F4-Discovery board Clone IoT.js and NuttX into iotjs-nuttx directory ```bash $ mkdir iotjs-nuttx $ cd iotjs-nuttx $ git clone https://github.com/Samsung/iotjs.git $ git clone https://bitbucket.org/nuttx/nuttx.git --branch nuttx-7.19 $ git clone https://bitbucket.org/nuttx/apps.git --branch nuttx-7.19 $ git clone https://github.com/texane/stlink.git ``` Note that we only support the specified git tag from nuttx repository The following directory structure is created after these commands ```bash iotjs-nuttx + apps + iotjs | + config | + nuttx | + stm32f4dis + nuttx + stlink ``` #### 2. Add IoT.js as a builtin application for NuttX ```bash $ cd apps/system $ mkdir iotjs $ cp ../../iotjs/config/nuttx/stm32f4dis/app/* ./iotjs/ ``` #### 3. Configure NuttX ```bash # assuming you are in iotjs-nuttx folder $ cd nuttx/tools # configure NuttX USB console shell $ ./configure.sh stm32f4discovery/usbnsh ``` Now you can configure nuttx like either of below. For convenience, we provide built-in configure file for you. (This configure file is equipped with modules specified as `always`. For `optional` modules, you might follow instructions below.) ```bash $ cd .. $ cp ../iotjs/config/nuttx/stm32f4dis/.config.default .config ``` Or if you want to configure yourself, you can follow guide below. ```bash $ cd .. # might require to run "make menuconfig" twice $ make menuconfig ``` Followings are the options to set: * Common * Change `Build Setup -> Build Host Platform` from _Windows_ to [_Linux_|_OSX_] * Enable `System Type -> FPU support` * Enable `System Type -> STM32 Peripheral Support -> SDIO` * Enable `RTOS Features -> Clocks and Timers -> Support CLOCK_MONOTONIC` * Enable `RTOS Features -> Pthread Options -> Enable mutex types` * Enable `RTOS Features -> Files and I/O -> Enable /dev/console` * Enable `RTOS Features -> Work queue support -> High priority (kernel) worker thread` * Disable `Device Drivers -> Disable driver poll interfaces` * Enable `Device Drivers -> MMC/SD Driver Support` * Enable `Device Drivers -> MMC/SD Driver Support -> MMC/SD SDIO transfer support` * Enable `Networking Support -> Networking Support` * Enable `Networking Support -> Socket Support -> Socket options` * Enable `Networking Support -> Unix Domain Socket Support` * Enable `Networking Support -> TCP/IP Networking` * Enable `Networking Support -> TCP/IP Networking -> Enable TCP/IP write buffering` * Enable `File Systems -> FAT file system` * Enable `File Systems -> FAT file system -> FAT upper/lower names` * Enable `File Systems -> FAT file system -> FAT long file names` * Enable `Device Drivers -> Network Device/PHY Support -> Late driver initialization` * Enable `Library Routines -> Standard Math library` * Enable `Application Configuration -> System Libraries and NSH Add-ons -> IoT.js` * Enable all children of `Application Configuration -> System Libraries and NSH Add-ons -> readline() Support` (for those who wants to use readline) * For `net` module * Enable `System Type -> STM32 Peripheral Support -> Ethernet MAC` * Disable `System Type -> STM32 Peripheral Support -> USART2` * Enable `System Type -> STM32 Peripheral Support -> USART6` * Set `System Type -> Ethernet MAC configuration -> PHY address` to `0` * Set `System Type -> Ethernet MAC configuration -> PHY Status Register Address (decimal)` to `31` * Enable `System Type -> Ethernet MAC configuration -> PHY Status Alternate Bit Layout` * Set `System Type -> Ethernet MAC configuration -> PHY Mode Mask` to `0x001c` * Set `System Type -> Ethernet MAC configuration -> 10MBase-T Half Duplex Value` to `0x0004` * Set `System Type -> Ethernet MAC configuration -> 100Base-T Half Duplex Value` to `0x0008` * Set `System Type -> Ethernet MAC configuration -> 10Base-T Full Duplex Value` to `0x0014` * Set `System Type -> Ethernet MAC configuration -> 10MBase-T Full Duplex Value` to `0x0018` * Set `System Type -> Ethernet MAC configuration -> RMII clock configuration` to `External RMII clock` * Enable `Board Selection -> STM32F4DIS-BB base board` * Set `Device Drivers -> Network Device/PHY Support -> Board PHY Selection` to `SMSC LAN8720 PHY` * Enable `Networking Support -> Data link support -> Local loopback` * Enable `Networking Support -> TCP/IP Networking -> TCP/IP backlog support` * Enable `Networking Support -> ARP Configuration -> ARP send` * For `dgram` * Enable `Networking Support > UDP Networking` * For `pwm` module * Enable `System Type -> STM32 Peripheral Support -> TIM(N)` * Enable `System Type -> Timer Configuration -> TIM(N) PWM` * Set `System Type -> Timer Configuration -> TIM(N) PWM -> TIM(n) PWM Output Channel` to channel number you want * Enable `Device Drivers -> PWM Driver Support` * For `adc` module * Enable `System Type -> STM32 Peripheral Support -> ADC(N)` * Enable `System Type -> STM32 Peripheral Support -> TIM(M)` * Enable `System Type -> Timer Configuration -> TIM(M) ADC` * Enable `Device Drivers -> Analog Device(ADC/DAC) Support` * Enable `Device Drivers -> Analog Device(ADC/DAC) Support -> Analog-to-Digital Conversion` * For `uart` module * Enable `System Type -> STM32 Peripheral Support -> U[S]ART(N)` * For `i2c` module * Enable `System Type -> STM32 Peripheral Support -> I2C1` * Enable `Device Drivers -> I2C Driver Support` #### 4. Build IoT.js for NuttX ##### Follow the instruction * [Build-for-NuttX](../../../build/Build-for-NuttX.md) #### 5. Build NuttX ```bash # assuming you are in iotjs-nuttx folder $ cd nuttx/ $ make IOTJS_ROOT_DIR=../iotjs ``` For release version, you can type R=1 make on the command shell. #### 6. Flashing Connect Mini-USB for power supply and connect Micro-USB for `NSH` console. To configure `stlink` utility for flashing, follow the instructions [here](https://github.com/texane/stlink#build-from-sources). To install, ```bash # assuming you are in stlink folder $ cd stlink $ make ``` To flash, ```bash # assuming you are in nuttx folder $ cd nuttx $ sudo ../stlink/build/Release/st-flash write nuttx.bin 0x8000000 ``` iotjs-1.0/docs/targets/tizenrt/000077500000000000000000000000001312466455500166155ustar00rootroot00000000000000iotjs-1.0/docs/targets/tizenrt/artik05x/000077500000000000000000000000001312466455500202645ustar00rootroot00000000000000iotjs-1.0/docs/targets/tizenrt/artik05x/IoT.js-API-artik053.md000066400000000000000000000010601312466455500236600ustar00rootroot00000000000000## Artik053 module ## `Pin` To use system IO, such as PWM, you must know pin name. ### `PWM Pin Number` For example, ``` javascript var pwm = new require('pwm')(); var config = { pin: 0, period: 0.001, dutyCycle: 0.5 } var pwm0 = pwm.open(config, function() { if (err) { throw err; } }); ``` The following is a list of PWM pin numbers. | PWM Pin number | GPIO Name | | :---: | :---: | | 0 | XPWMTOUT_0 | | 1 | XPWMTOUT_1 | | 2 | XPWMTOUT_2 | | 3 | XPWMTOUT_3 | | 4 | XPWMTOUT_4 | | 5 | XPWMTOUT_5 | | 6 | XPWMTOUT_6 | iotjs-1.0/docs/targets/tizenrt/artik05x/README.md000066400000000000000000000035411312466455500215460ustar00rootroot00000000000000### About This directory contains files to run IoT.js on [TizenRT](https://github.com/Samsung/TizenRT). WARNING: **This document is not 100% accurate since Artik05x board with tooling is not available yet** ### How to build #### 1. Set up the build environment for Artik05x board Clone IoT.js and TizenRT into iotjs-tizenrt directory ```bash $ mkdir iotjs-tizenrt $ cd iotjs-tizenrt $ git clone https://github.com/Samsung/iotjs.git $ git clone https://github.com/Samsung/TizenRT.git tizenrt ``` The following directory structure is created after these commands ```bash iotjs-tizenrt + iotjs | + config | + tizenrt | + artik05x + tizenrt ``` #### 2. Add IoT.js as a builtin application for TizenRT ```bash $ cd tizenrt/apps/system $ mkdir iotjs $ cp ../../../iotjs/config/tizenrt/artik05x/app/* ./iotjs/ ``` **WARNING: Manual modification is required** **WARNING: Below two bullet points are subject to change** * change tizenrt/apps/system/Kconfig to include iotjs folder ``` menu "IoT.js node.js like Javascript runtime" source "$APPSDIR/system/iotjs/Kconfig" endmenu ``` * Libraries required to link iotjs have to be supplied in some way ``` EXTRA_LIBS = -lhttpparser -liotjs -ljerrycore -ltuv -ljerry-libm ``` #### 3. Configure TizenRT ```bash $ cd tizenrt/os/tools $ ./configure.sh sidk_s5jt200/hello_with_tash $ cd .. # might require to run "make menuconfig" twice $ make menuconfig ``` #### 4. Build IoT.js for TizenRT ```bash $ cd iotjs $ ./tools/build.py --target-arch=arm --target-os=tizenrt --target-board=artik05x --sysroot=../tizenrt/os ``` #### 5. Build TizenRT ```bash $ cd tizenrt/os IOTJS_LIB_DIR=../iotjs/build/arm-tizenrt/debug/lib make ``` Binaries are available in `tizenrt/build/output/bin` #### 6. Flashing Yet to be announced on [TizenRT page](https://github.com/Samsung/TizenRT#board) iotjs-1.0/include/000077500000000000000000000000001312466455500141405ustar00rootroot00000000000000iotjs-1.0/include/iotjs.h000066400000000000000000000016131312466455500154420ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef IOTJS_IOTJS_H #define IOTJS_IOTJS_H #ifdef __cplusplus #define IOTJS_EXTERN_C extern "C" #else /* !__cplusplus */ #define IOTJS_EXTERN_C extern #endif /* !__cplusplus */ IOTJS_EXTERN_C int iotjs_entry(int argc, char** argv); #endif /* IOTJS_IOTJS_H */ iotjs-1.0/iotjs_linux.c000066400000000000000000000013331312466455500152300ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "iotjs.h" int main(int argc, char** argv) { return iotjs_entry(argc, argv); } iotjs-1.0/samples/000077500000000000000000000000001312466455500141615ustar00rootroot00000000000000iotjs-1.0/samples/gpio_led.js000066400000000000000000000022031312466455500162760ustar00rootroot00000000000000/* Copyright 2017-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var Gpio = require('gpio'); var pin = require('systemio_pin').pin; var gpio = new Gpio(); var gpio_led = gpio.open({ pin: pin.led1, direction: gpio.DIRECTION.OUT }, function(err) { if (!err) { gpio_led.writeSync(true); var interval = setInterval(function() { gpio_led.read(function(err, value) { if (!err) { console.log("read value:%d", value); gpio_led.write(!value); } else { clearInterval(interval); } }); }, 1000); } }); iotjs-1.0/samples/http_hello/000077500000000000000000000000001312466455500163235ustar00rootroot00000000000000iotjs-1.0/samples/http_hello/client_get.js000066400000000000000000000020371312466455500210000ustar00rootroot00000000000000/* Copyright 2017-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var http = require('http'); var options = { hostname: '127.0.0.1', port: 8080, path: '/' }; http.request(options, function (res) { receive(res, function (data) { console.log(data); }); }).end(); function receive(incoming, callback) { var data = ''; incoming.on('data', function (chunk) { data += chunk; }); incoming.on('end', function () { callback ? callback(data) : ''; }); } iotjs-1.0/samples/http_hello/client_post.js000066400000000000000000000023461312466455500212110ustar00rootroot00000000000000/* Copyright 2017-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var http = require('http'); var message = JSON.stringify({ greeting: 'Hello, IoT.JS!', answer: '', }); var options = { hostname: '127.0.0.1', port: 8080, path: '/', method: 'POST', headers: { 'Content-Length': message.length } }; http.request(options, function (res) { receive(res, function (data) { var obj = JSON.parse(data); console.log(obj.answer); }); }).end(message); function receive(incoming, callback) { var data = ''; incoming.on('data', function (chunk) { data += chunk; }); incoming.on('end', function () { callback ? callback(data) : ''; }); } iotjs-1.0/samples/http_hello/server.js000066400000000000000000000030631312466455500201710ustar00rootroot00000000000000/* Copyright 2017-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var http = require('http'); var port = 8080; http.createServer(function (req, res) { if (req.method == 'GET') { status(res, 'Hello, IoT.JS!'); } else if (req.method == 'POST') { receive(req, function (data) { var obj = JSON.parse(data); obj.answer = 'Hello, There!' status(res, obj); }); } }).listen(port); function receive(incoming, callback) { var data = ''; incoming.on('data', function (chunk) { data += chunk; }); incoming.on('end', function () { callback ? callback(data) : ''; }); } function status(res, data) { var isJson = (typeof data === 'object'); if (isJson) { data = JSON.stringify(data); } var headers = { 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Headers': 'Origin, X-Requested-With, Content-Type, Accept', 'Content-Type': isJson ? 'application/json' : 'text/plain', }; res.writeHead(200, headers); res.end(data); }; iotjs-1.0/samples/net_hello/000077500000000000000000000000001312466455500161325ustar00rootroot00000000000000iotjs-1.0/samples/net_hello/client.js000066400000000000000000000016711312466455500177530ustar00rootroot00000000000000/* Copyright 2017-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var net = require('net'); var port = 7468; var msg = ''; var socket = new net.Socket(); var address = process.argv[2] ? process.argv[2] : "127.0.0.1"; socket.connect(port, address); socket.on('data', function(data) { msg += data; }); socket.on('end', function() { console.log(msg); socket.end(); }); iotjs-1.0/samples/net_hello/server.js000066400000000000000000000014651312466455500200040ustar00rootroot00000000000000/* Copyright 2017-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var net = require('net'); var port = 7468; var server = net.createServer(); server.listen(port, 5); server.on('connection', function(socket) { socket.end('Hello IoT.js'); }); iotjs-1.0/samples/systemio_pin.js000066400000000000000000000016041312466455500172420ustar00rootroot00000000000000/* Copyright 2017-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var pin = {}; if (process.platform === 'linux') { pin.led1 = 20; } else if (process.platform === 'nuttx') { var stm32_pin = require('stm32f4dis').pin; pin.led1 = stm32_pin.PA10; } else { throw new Error('Unsupported platform'); } exports.pin = pin; iotjs-1.0/src/000077500000000000000000000000001312466455500133045ustar00rootroot00000000000000iotjs-1.0/src/iotjs.c000066400000000000000000000132451312466455500146050ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "iotjs_def.h" #include "iotjs.h" #include "iotjs_handlewrap.h" #include "iotjs_js.h" #include "iotjs_string_ext.h" #include "jerryscript-debugger.h" #ifndef __NUTTX__ #include "jerryscript-port-default.h" #endif #include "jerryscript-port.h" #include "jerryscript.h" #include #include /** * Initialize JerryScript. */ static bool iotjs_jerry_initialize(const iotjs_environment_t* env) { // Set jerry run flags. uint32_t jerry_flag = JERRY_INIT_EMPTY; if (iotjs_environment_config(env)->memstat) { jerry_flag |= JERRY_INIT_MEM_STATS; #ifndef __NUTTX__ jerry_port_default_set_log_level(JERRY_LOG_LEVEL_DEBUG); #endif } if (iotjs_environment_config(env)->show_opcode) { jerry_flag |= JERRY_INIT_SHOW_OPCODES; #ifndef __NUTTX__ jerry_port_default_set_log_level(JERRY_LOG_LEVEL_DEBUG); #endif } if (iotjs_environment_config(env)->debugger) { jerry_flag |= JERRY_INIT_DEBUGGER; } // Initialize jerry. jerry_init((jerry_init_flag_t)jerry_flag); if (iotjs_environment_config(env)->debugger) { jerry_debugger_continue(); } // Set magic strings. iotjs_register_jerry_magic_string(); // Do parse and run to generate initial javascript environment. jerry_value_t parsed_code = jerry_parse((jerry_char_t*)"", 0, false); if (jerry_value_has_error_flag(parsed_code)) { DLOG("jerry_parse() failed"); jerry_release_value(parsed_code); return false; } jerry_value_t ret_val = jerry_run(parsed_code); if (jerry_value_has_error_flag(ret_val)) { DLOG("jerry_run() failed"); jerry_release_value(parsed_code); jerry_release_value(ret_val); return false; } jerry_release_value(parsed_code); jerry_release_value(ret_val); return true; } static void iotjs_jerry_release() { jerry_cleanup(); } static bool iotjs_run() { // Evaluating 'iotjs.js' returns a function. bool throws = false; #ifndef ENABLE_SNAPSHOT iotjs_jval_t jmain = iotjs_jhelper_eval("iotjs.js", strlen("iotjs.js"), iotjs_s, iotjs_l, false, &throws); #else iotjs_jval_t jmain = iotjs_jhelper_exec_snapshot(iotjs_s, iotjs_l, &throws); #endif if (throws) { iotjs_uncaught_exception(&jmain); } iotjs_jval_destroy(&jmain); return !throws; } static bool iotjs_start(iotjs_environment_t* env) { // Initialize commonly used jerry values iotjs_binding_initialize(); // Bind environment to global object. const iotjs_jval_t* global = iotjs_jval_get_global_object(); iotjs_jval_set_object_native_handle(global, (uintptr_t)(env), NULL); // Initialize builtin modules. iotjs_module_list_init(); // Initialize builtin process module. const iotjs_jval_t* process = iotjs_module_initialize_if_necessary(MODULE_PROCESS); // Call the entry. // load and call iotjs.js iotjs_environment_go_state_running_main(env); iotjs_jval_set_property_jval(global, "process", process); iotjs_run(); // Run event loop. iotjs_environment_go_state_running_loop(env); bool more; do { more = uv_run(iotjs_environment_loop(env), UV_RUN_ONCE); more |= iotjs_process_next_tick(); if (more == false) { more = uv_loop_alive(iotjs_environment_loop(env)); } jerry_value_t ret_val = jerry_run_all_enqueued_jobs(); if (jerry_value_has_error_flag(ret_val)) { DLOG("jerry_run_all_enqueued_jobs() failed"); } } while (more); iotjs_environment_go_state_exiting(env); // Emit 'exit' event. iotjs_process_emit_exit(0); // Release builtin modules. iotjs_module_list_cleanup(); // Release commonly used jerry values. iotjs_binding_finalize(); return true; } static void iotjs_uv_walk_to_close_callback(uv_handle_t* handle, void* arg) { iotjs_handlewrap_t* handle_wrap = iotjs_handlewrap_from_handle(handle); IOTJS_ASSERT(handle_wrap != NULL); iotjs_handlewrap_close(handle_wrap, NULL); } int iotjs_entry(int argc, char** argv) { // Initialize debug print. init_debug_settings(); // Create environment. iotjs_environment_t* env = (iotjs_environment_t*)iotjs_environment_get(); // Parse command line arguments. if (!iotjs_environment_parse_command_line_arguments(env, (uint32_t)argc, argv)) { DLOG("iotjs_environment_parse_command_line_arguments failed"); return 1; } // Set event loop. iotjs_environment_set_loop(env, uv_default_loop()); // Initialize JerryScript engine. if (!iotjs_jerry_initialize(env)) { DLOG("iotjs_jerry_initialize failed"); return 1; } // Start IoT.js if (!iotjs_start(env)) { DLOG("iotjs_start failed"); return 1; } // close uv loop. // uv_stop(iotjs_environment_loop(env)); uv_walk(iotjs_environment_loop(env), iotjs_uv_walk_to_close_callback, NULL); uv_run(iotjs_environment_loop(env), UV_RUN_DEFAULT); int res = uv_loop_close(iotjs_environment_loop(env)); IOTJS_ASSERT(res == 0); // Release JerryScript engine. iotjs_jerry_release(); // Release environment. iotjs_environment_release(); // Release debug print setting. release_debug_settings(); return 0; } iotjs-1.0/src/iotjs_binding.c000066400000000000000000000610741312466455500163020ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "iotjs_def.h" #include "iotjs_binding.h" #include static iotjs_jval_t jundefined; static iotjs_jval_t jnull; static iotjs_jval_t jtrue; static iotjs_jval_t jfalse; static iotjs_jval_t jglobal; static iotjs_jargs_t jargs_empty; static jerry_value_t iotjs_jval_as_raw(const iotjs_jval_t* jval); iotjs_jval_t iotjs_jval_create_number(double v) { iotjs_jval_t jval; IOTJS_VALIDATED_STRUCT_CONSTRUCTOR(iotjs_jval_t, &jval); _this->value = jerry_create_number(v); return jval; } iotjs_jval_t iotjs_jval_create_string(const iotjs_string_t* v) { iotjs_jval_t jval; IOTJS_VALIDATED_STRUCT_CONSTRUCTOR(iotjs_jval_t, &jval); const jerry_char_t* data = (const jerry_char_t*)(iotjs_string_data(v)); jerry_size_t size = iotjs_string_size(v); if (jerry_is_valid_utf8_string(data, size)) { _this->value = jerry_create_string_sz_from_utf8(data, size); } else { _this->value = jerry_create_error(JERRY_ERROR_TYPE, (const jerry_char_t*)"Invalid UTF-8 string"); } return jval; } iotjs_jval_t iotjs_jval_get_string_size(const iotjs_string_t* str) { iotjs_jval_t str_val = iotjs_jval_create_string(str); IOTJS_VALIDATED_STRUCT_METHOD(iotjs_jval_t, &str_val); jerry_size_t size = jerry_get_string_size(_this->value); iotjs_jval_t jval = iotjs_jval_create_number(size); iotjs_jval_destroy(&str_val); return jval; } iotjs_jval_t iotjs_jval_create_string_raw(const char* data) { iotjs_jval_t jval; IOTJS_VALIDATED_STRUCT_CONSTRUCTOR(iotjs_jval_t, &jval); _this->value = jerry_create_string((const jerry_char_t*)data); return jval; } iotjs_jval_t iotjs_jval_create_object() { iotjs_jval_t jval; IOTJS_VALIDATED_STRUCT_CONSTRUCTOR(iotjs_jval_t, &jval); _this->value = jerry_create_object(); return jval; } iotjs_jval_t iotjs_jval_create_array(uint32_t len) { iotjs_jval_t jval; IOTJS_VALIDATED_STRUCT_CONSTRUCTOR(iotjs_jval_t, &jval); _this->value = jerry_create_array(len); return jval; } iotjs_jval_t iotjs_jval_create_byte_array(uint32_t len, const char* data) { iotjs_jval_t jval; IOTJS_VALIDATED_STRUCT_CONSTRUCTOR(iotjs_jval_t, &jval); IOTJS_ASSERT(data != NULL); _this->value = jerry_create_array(len); for (uint32_t i = 0; i < len; i++) { jerry_value_t val = jerry_create_number((double)data[i]); jerry_set_property_by_index(_this->value, i, val); jerry_release_value(val); } return jval; } iotjs_jval_t iotjs_jval_create_function(JHandlerType handler) { iotjs_jval_t jval; IOTJS_VALIDATED_STRUCT_CONSTRUCTOR(iotjs_jval_t, &jval); _this->value = jerry_create_external_function(handler); IOTJS_ASSERT(jerry_value_is_constructor(_this->value)); return jval; } iotjs_jval_t iotjs_jval_create_error(const char* msg) { return iotjs_jval_create_error_type(IOTJS_ERROR_COMMON, msg); } iotjs_jval_t iotjs_jval_create_error_type(iotjs_error_t type, const char* msg) { iotjs_jval_t jval; IOTJS_VALIDATED_STRUCT_CONSTRUCTOR(iotjs_jval_t, &jval); const jerry_char_t* jmsg = (const jerry_char_t*)(msg); _this->value = jerry_create_error((jerry_error_t)type, jmsg); jerry_value_clear_error_flag(&_this->value); return jval; } iotjs_jval_t iotjs_jval_create_copied(const iotjs_jval_t* other) { iotjs_jval_t jval; IOTJS_VALIDATED_STRUCT_CONSTRUCTOR(iotjs_jval_t, &jval); _this->value = jerry_acquire_value(iotjs_jval_as_raw(other)); return jval; } static iotjs_jval_t iotjs_jval_create_raw(jerry_value_t val) { iotjs_jval_t jval; IOTJS_VALIDATED_STRUCT_CONSTRUCTOR(iotjs_jval_t, &jval); _this->value = val; return jval; } void iotjs_jval_destroy(iotjs_jval_t* jval) { IOTJS_VALIDATED_STRUCT_DESTRUCTOR(iotjs_jval_t, jval); jerry_release_value(_this->value); } static void iotjs_jval_destroy_norelease(iotjs_jval_t* jval) { IOTJS_VALIDATABLE_STRUCT_DESTRUCTOR_VALIDATE(iotjs_jval_t, jval); } iotjs_jval_t* iotjs_jval_get_undefined() { return &jundefined; } iotjs_jval_t* iotjs_jval_get_null() { return &jnull; } iotjs_jval_t* iotjs_jval_get_boolean(bool v) { return v ? &jtrue : &jfalse; } iotjs_jval_t* iotjs_jval_get_global_object() { return &jglobal; } #define TYPE_CHECKER_BODY(jval_type) \ bool iotjs_jval_is_##jval_type(const iotjs_jval_t* val) { \ const IOTJS_VALIDATED_STRUCT_METHOD(iotjs_jval_t, val); \ return jerry_value_is_##jval_type(_this->value); \ } FOR_EACH_JVAL_TYPES(TYPE_CHECKER_BODY) #undef TYPE_CHECKER_BODY bool iotjs_jval_as_boolean(const iotjs_jval_t* jval) { const IOTJS_VALIDATED_STRUCT_METHOD(iotjs_jval_t, jval); IOTJS_ASSERT(iotjs_jval_is_boolean(jval)); return jerry_get_boolean_value(_this->value); } double iotjs_jval_as_number(const iotjs_jval_t* jval) { const IOTJS_VALIDATED_STRUCT_METHOD(iotjs_jval_t, jval); IOTJS_ASSERT(iotjs_jval_is_number(jval)); return jerry_get_number_value(_this->value); } iotjs_string_t iotjs_jval_as_string(const iotjs_jval_t* jval) { const IOTJS_VALIDATED_STRUCT_METHOD(iotjs_jval_t, jval); IOTJS_ASSERT(iotjs_jval_is_string(jval)); jerry_size_t size = jerry_get_string_size(_this->value); if (size == 0) return iotjs_string_create(); char* buffer = iotjs_buffer_allocate(size + 1); jerry_char_t* jerry_buffer = (jerry_char_t*)(buffer); size_t check = jerry_string_to_char_buffer(_this->value, jerry_buffer, size); IOTJS_ASSERT(check == size); buffer[size] = '\0'; iotjs_string_t res = iotjs_string_create_with_buffer(buffer, size); return res; } const iotjs_jval_t* iotjs_jval_as_object(const iotjs_jval_t* jval) { IOTJS_VALIDATABLE_STRUCT_METHOD_VALIDATE(iotjs_jval_t, jval); IOTJS_ASSERT(iotjs_jval_is_object(jval)); return jval; } const iotjs_jval_t* iotjs_jval_as_array(const iotjs_jval_t* jval) { IOTJS_VALIDATABLE_STRUCT_METHOD_VALIDATE(iotjs_jval_t, jval); IOTJS_ASSERT(iotjs_jval_is_array(jval)); return jval; } const iotjs_jval_t* iotjs_jval_as_function(const iotjs_jval_t* jval) { IOTJS_VALIDATABLE_STRUCT_METHOD_VALIDATE(iotjs_jval_t, jval); IOTJS_ASSERT(iotjs_jval_is_function(jval)); return jval; } static jerry_value_t iotjs_jval_as_raw(const iotjs_jval_t* jval) { const IOTJS_VALIDATED_STRUCT_METHOD(iotjs_jval_t, jval); return _this->value; } void iotjs_jval_set_method(const iotjs_jval_t* jobj, const char* name, iotjs_native_handler_t handler) { IOTJS_VALIDATABLE_STRUCT_METHOD_VALIDATE(iotjs_jval_t, jobj); IOTJS_ASSERT(iotjs_jval_is_object(jobj)); iotjs_jval_t jfunc = iotjs_jval_create_function_with_dispatch(handler); iotjs_jval_set_property_jval(jobj, name, &jfunc); iotjs_jval_destroy(&jfunc); } void iotjs_jval_set_property_jval(const iotjs_jval_t* jobj, const char* name, const iotjs_jval_t* val) { const IOTJS_VALIDATED_STRUCT_METHOD(iotjs_jval_t, jobj); IOTJS_ASSERT(iotjs_jval_is_object(jobj)); jerry_value_t prop_name = jerry_create_string((const jerry_char_t*)(name)); jerry_value_t value = iotjs_jval_as_raw(val); jerry_value_t ret_val = jerry_set_property(_this->value, prop_name, value); jerry_release_value(prop_name); IOTJS_ASSERT(!jerry_value_has_error_flag(ret_val)); jerry_release_value(ret_val); } void iotjs_jval_set_property_null(const iotjs_jval_t* jobj, const char* name) { IOTJS_VALIDATABLE_STRUCT_METHOD_VALIDATE(iotjs_jval_t, jobj); iotjs_jval_set_property_jval(jobj, name, iotjs_jval_get_null()); } void iotjs_jval_set_property_undefined(const iotjs_jval_t* jobj, const char* name) { IOTJS_VALIDATABLE_STRUCT_METHOD_VALIDATE(iotjs_jval_t, jobj); iotjs_jval_set_property_jval(jobj, name, iotjs_jval_get_undefined()); } void iotjs_jval_set_property_boolean(const iotjs_jval_t* jobj, const char* name, bool v) { IOTJS_VALIDATABLE_STRUCT_METHOD_VALIDATE(iotjs_jval_t, jobj); iotjs_jval_set_property_jval(jobj, name, iotjs_jval_get_boolean(v)); } void iotjs_jval_set_property_number(const iotjs_jval_t* jobj, const char* name, double v) { IOTJS_VALIDATABLE_STRUCT_METHOD_VALIDATE(iotjs_jval_t, jobj); iotjs_jval_t jval = iotjs_jval_create_number(v); iotjs_jval_set_property_jval(jobj, name, &jval); iotjs_jval_destroy(&jval); } void iotjs_jval_set_property_string(const iotjs_jval_t* jobj, const char* name, const iotjs_string_t* v) { IOTJS_VALIDATABLE_STRUCT_METHOD_VALIDATE(iotjs_jval_t, jobj); iotjs_jval_t jval = iotjs_jval_create_string(v); iotjs_jval_set_property_jval(jobj, name, &jval); iotjs_jval_destroy(&jval); } void iotjs_jval_set_property_string_raw(const iotjs_jval_t* jobj, const char* name, const char* v) { IOTJS_VALIDATABLE_STRUCT_METHOD_VALIDATE(iotjs_jval_t, jobj); iotjs_jval_t jval = iotjs_jval_create_string_raw(v); iotjs_jval_set_property_jval(jobj, name, &jval); iotjs_jval_destroy(&jval); } iotjs_jval_t iotjs_jval_get_property(const iotjs_jval_t* jobj, const char* name) { const IOTJS_VALIDATED_STRUCT_METHOD(iotjs_jval_t, jobj); IOTJS_ASSERT(iotjs_jval_is_object(jobj)); jerry_value_t prop_name = jerry_create_string((const jerry_char_t*)(name)); jerry_value_t res = jerry_get_property(_this->value, prop_name); jerry_release_value(prop_name); if (jerry_value_has_error_flag(res)) { jerry_release_value(res); return iotjs_jval_create_copied(iotjs_jval_get_undefined()); } return iotjs_jval_create_raw(res); } void iotjs_jval_set_object_native_handle(const iotjs_jval_t* jobj, uintptr_t ptr, JNativeInfoType native_info) { const IOTJS_VALIDATED_STRUCT_METHOD(iotjs_jval_t, jobj); IOTJS_ASSERT(iotjs_jval_is_object(jobj)); jerry_set_object_native_pointer(_this->value, (void*)ptr, native_info); } uintptr_t iotjs_jval_get_object_native_handle(const iotjs_jval_t* jobj) { const IOTJS_VALIDATED_STRUCT_METHOD(iotjs_jval_t, jobj); IOTJS_ASSERT(iotjs_jval_is_object(jobj)); uintptr_t ptr = 0x0; JNativeInfoType out_info; jerry_get_object_native_pointer(_this->value, (void**)&ptr, &out_info); return ptr; } uintptr_t iotjs_jval_get_object_from_jhandler(iotjs_jhandler_t* jhandler, JNativeInfoType native_info) { const iotjs_jval_t* jobj = JHANDLER_GET_THIS(object); const IOTJS_DECLARE_THIS(iotjs_jval_t, jobj); if (!jerry_value_is_object(_this->value)) { return 0; } uintptr_t ptr = 0; JNativeInfoType out_native_info; if (jerry_get_object_native_pointer(_this->value, (void**)&ptr, &out_native_info)) { if (ptr && out_native_info == native_info) { return ptr; } } JHANDLER_THROW(COMMON, "Unsafe access"); return 0; } void iotjs_jval_set_property_by_index(const iotjs_jval_t* jarr, uint32_t idx, const iotjs_jval_t* jval) { const IOTJS_VALIDATED_STRUCT_METHOD(iotjs_jval_t, jarr); IOTJS_ASSERT(iotjs_jval_is_object(jarr)); jerry_value_t value = iotjs_jval_as_raw(jval); jerry_value_t ret_val = jerry_set_property_by_index(_this->value, idx, value); IOTJS_ASSERT(!jerry_value_has_error_flag(ret_val)); jerry_release_value(ret_val); } iotjs_jval_t iotjs_jval_get_property_by_index(const iotjs_jval_t* jarr, uint32_t idx) { const IOTJS_VALIDATED_STRUCT_METHOD(iotjs_jval_t, jarr); IOTJS_ASSERT(iotjs_jval_is_object(jarr)); jerry_value_t res = jerry_get_property_by_index(_this->value, idx); if (jerry_value_has_error_flag(res)) { jerry_release_value(res); return iotjs_jval_create_copied(iotjs_jval_get_undefined()); } return iotjs_jval_create_raw(res); } iotjs_jval_t iotjs_jhelper_call(const iotjs_jval_t* jfunc, const iotjs_jval_t* jthis, const iotjs_jargs_t* jargs, bool* throws) { IOTJS_ASSERT(iotjs_jval_is_object(jfunc)); jerry_value_t* jargv_ = NULL; jerry_length_t jargc_ = iotjs_jargs_length(jargs); #ifdef NDEBUG jargv_ = (jerry_value_t*)jargs->unsafe.argv; #else if (jargc_ > 0) { unsigned buffer_size = sizeof(iotjs_jval_t) * jargc_; jargv_ = (jerry_value_t*)iotjs_buffer_allocate(buffer_size); for (unsigned i = 0; i < jargc_; ++i) { jargv_[i] = iotjs_jval_as_raw(iotjs_jargs_get(jargs, i)); } } #endif jerry_value_t jfunc_ = iotjs_jval_as_raw(jfunc); jerry_value_t jthis_ = iotjs_jval_as_raw(jthis); jerry_value_t res = jerry_call_function(jfunc_, jthis_, jargv_, jargc_); #ifndef NDEBUG if (jargv_) { iotjs_buffer_release((char*)jargv_); } #endif *throws = jerry_value_has_error_flag(res); jerry_value_clear_error_flag(&res); return iotjs_jval_create_raw(res); } iotjs_jval_t iotjs_jhelper_call_ok(const iotjs_jval_t* jfunc, const iotjs_jval_t* jthis, const iotjs_jargs_t* jargs) { bool throws; iotjs_jval_t jres = iotjs_jhelper_call(jfunc, jthis, jargs, &throws); IOTJS_ASSERT(!throws); return jres; } iotjs_jval_t iotjs_jhelper_eval(const char* name, size_t name_len, const uint8_t* data, size_t size, bool strict_mode, bool* throws) { jerry_value_t res = jerry_parse_named_resource((const jerry_char_t*)name, name_len, (const jerry_char_t*)data, size, strict_mode); *throws = jerry_value_has_error_flag(res); if (!*throws) { jerry_value_t func = res; res = jerry_run(func); jerry_release_value(func); *throws = jerry_value_has_error_flag(res); } jerry_value_clear_error_flag(&res); return iotjs_jval_create_raw(res); } #ifdef ENABLE_SNAPSHOT iotjs_jval_t iotjs_jhelper_exec_snapshot(const void* snapshot_p, size_t snapshot_size, bool* throws) { jerry_value_t res = jerry_exec_snapshot(snapshot_p, snapshot_size, false); /* the snapshot buffer can be referenced * until jerry_cleanup is not called */ *throws = jerry_value_has_error_flag(res); jerry_value_clear_error_flag(&res); return iotjs_jval_create_raw(res); } #endif iotjs_jargs_t iotjs_jargs_create(uint16_t capacity) { iotjs_jargs_t jargs; IOTJS_VALIDATED_STRUCT_CONSTRUCTOR(iotjs_jargs_t, &jargs); _this->capacity = capacity; _this->argc = 0; if (capacity > 0) { unsigned buffer_size = sizeof(iotjs_jval_t) * capacity; _this->argv = (iotjs_jval_t*)iotjs_buffer_allocate(buffer_size); } else { return jargs_empty; } return jargs; } static void iotjs_jargs_initialize_empty(iotjs_jargs_t* jargs) { IOTJS_VALIDATED_STRUCT_CONSTRUCTOR(iotjs_jargs_t, jargs); _this->capacity = 0; _this->argc = 0; _this->argv = NULL; } const iotjs_jargs_t* iotjs_jargs_get_empty() { return &jargs_empty; } void iotjs_jargs_destroy(iotjs_jargs_t* jargs) { IOTJS_VALIDATED_STRUCT_DESTRUCTOR(iotjs_jargs_t, jargs); IOTJS_ASSERT(_this->argv == NULL || _this->argc > 0); IOTJS_ASSERT(_this->argc <= _this->capacity); if (_this->capacity > 0) { for (unsigned i = 0; i < _this->argc; ++i) { iotjs_jval_destroy(&_this->argv[i]); } iotjs_buffer_release((char*)_this->argv); } else { IOTJS_ASSERT(_this->argv == NULL); } } uint16_t iotjs_jargs_length(const iotjs_jargs_t* jargs) { const IOTJS_VALIDATED_STRUCT_METHOD(iotjs_jargs_t, jargs); return _this->argc; } void iotjs_jargs_append_jval(iotjs_jargs_t* jargs, const iotjs_jval_t* x) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_jargs_t, jargs); IOTJS_ASSERT(_this->argc < _this->capacity); _this->argv[_this->argc++] = iotjs_jval_create_copied(x); } void iotjs_jargs_append_undefined(iotjs_jargs_t* jargs) { IOTJS_VALIDATABLE_STRUCT_METHOD_VALIDATE(iotjs_jargs_t, jargs); iotjs_jargs_append_jval(jargs, iotjs_jval_get_undefined()); } void iotjs_jargs_append_null(iotjs_jargs_t* jargs) { IOTJS_VALIDATABLE_STRUCT_METHOD_VALIDATE(iotjs_jargs_t, jargs); iotjs_jargs_append_jval(jargs, iotjs_jval_get_null()); } void iotjs_jargs_append_bool(iotjs_jargs_t* jargs, bool x) { IOTJS_VALIDATABLE_STRUCT_METHOD_VALIDATE(iotjs_jargs_t, jargs); iotjs_jargs_append_jval(jargs, iotjs_jval_get_boolean(x)); } void iotjs_jargs_append_number(iotjs_jargs_t* jargs, double x) { IOTJS_VALIDATABLE_STRUCT_METHOD_VALIDATE(iotjs_jargs_t, jargs); iotjs_jval_t jval = iotjs_jval_create_number(x); iotjs_jargs_append_jval(jargs, &jval); iotjs_jval_destroy(&jval); } void iotjs_jargs_append_string(iotjs_jargs_t* jargs, const iotjs_string_t* x) { IOTJS_VALIDATABLE_STRUCT_METHOD_VALIDATE(iotjs_jargs_t, jargs); iotjs_jval_t jval = iotjs_jval_create_string(x); iotjs_jargs_append_jval(jargs, &jval); iotjs_jval_destroy(&jval); } void iotjs_jargs_append_error(iotjs_jargs_t* jargs, const char* msg) { IOTJS_VALIDATABLE_STRUCT_METHOD_VALIDATE(iotjs_jargs_t, jargs); iotjs_jval_t error = iotjs_jval_create_error(msg); iotjs_jargs_append_jval(jargs, &error); iotjs_jval_destroy(&error); } void iotjs_jargs_append_string_raw(iotjs_jargs_t* jargs, const char* x) { IOTJS_VALIDATABLE_STRUCT_METHOD_VALIDATE(iotjs_jargs_t, jargs); iotjs_jval_t jval = iotjs_jval_create_string_raw(x); iotjs_jargs_append_jval(jargs, &jval); iotjs_jval_destroy(&jval); } void iotjs_jargs_replace(iotjs_jargs_t* jargs, uint16_t index, const iotjs_jval_t* x) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_jargs_t, jargs); IOTJS_ASSERT(index < _this->argc); iotjs_jval_destroy(&_this->argv[index]); _this->argv[index] = iotjs_jval_create_copied(x); } const iotjs_jval_t* iotjs_jargs_get(const iotjs_jargs_t* jargs, uint16_t index) { const IOTJS_VALIDATED_STRUCT_METHOD(iotjs_jargs_t, jargs); IOTJS_ASSERT(index < _this->argc); return &_this->argv[index]; } void iotjs_jhandler_initialize(iotjs_jhandler_t* jhandler, const jerry_value_t jfunc, const jerry_value_t jthis, const jerry_value_t jargv[], const uint16_t jargc) { IOTJS_VALIDATED_STRUCT_CONSTRUCTOR(iotjs_jhandler_t, jhandler); _this->jfunc = iotjs_jval_create_raw(jfunc); _this->jthis = iotjs_jval_create_raw(jthis); _this->jret = iotjs_jval_create_copied(iotjs_jval_get_undefined()); #ifdef NDEBUG _this->jargv = (iotjs_jval_t*)jargv; #else if (jargc > 0) { unsigned buffer_size = sizeof(iotjs_jval_t) * jargc; _this->jargv = (iotjs_jval_t*)iotjs_buffer_allocate(buffer_size); for (int i = 0; i < jargc; ++i) { _this->jargv[i] = iotjs_jval_create_raw(jargv[i]); } } else { _this->jargv = NULL; } _this->finished = false; #endif _this->jargc = jargc; } void iotjs_jhandler_destroy(iotjs_jhandler_t* jhandler) { IOTJS_VALIDATED_STRUCT_DESTRUCTOR(iotjs_jhandler_t, jhandler); iotjs_jval_destroy_norelease(&_this->jfunc); iotjs_jval_destroy_norelease(&_this->jthis); iotjs_jval_destroy_norelease(&_this->jret); #ifndef NDEBUG if (_this->jargc > 0) { for (int i = 0; i < _this->jargc; ++i) { iotjs_jval_destroy_norelease(&_this->jargv[i]); } iotjs_buffer_release((char*)(_this->jargv)); } else { IOTJS_ASSERT(_this->jargv == NULL); } #endif } const iotjs_jval_t* iotjs_jhandler_get_function(iotjs_jhandler_t* jhandler) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_jhandler_t, jhandler); return &_this->jfunc; } const iotjs_jval_t* iotjs_jhandler_get_this(iotjs_jhandler_t* jhandler) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_jhandler_t, jhandler); return &_this->jthis; } const iotjs_jval_t* iotjs_jhandler_get_arg(iotjs_jhandler_t* jhandler, uint16_t index) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_jhandler_t, jhandler); IOTJS_ASSERT(index < _this->jargc); return &_this->jargv[index]; } uint16_t iotjs_jhandler_get_arg_length(iotjs_jhandler_t* jhandler) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_jhandler_t, jhandler); return _this->jargc; } void iotjs_jhandler_return_jval(iotjs_jhandler_t* jhandler, const iotjs_jval_t* ret) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_jhandler_t, jhandler); #ifndef NDEBUG IOTJS_ASSERT(_this->finished == false); #endif iotjs_jval_destroy(&_this->jret); _this->jret = iotjs_jval_create_copied(ret); #ifndef NDEBUG _this->finished = true; #endif } void iotjs_jhandler_return_undefined(iotjs_jhandler_t* jhandler) { IOTJS_VALIDATABLE_STRUCT_METHOD_VALIDATE(iotjs_jhandler_t, jhandler); iotjs_jhandler_return_jval(jhandler, iotjs_jval_get_undefined()); } void iotjs_jhandler_return_null(iotjs_jhandler_t* jhandler) { IOTJS_VALIDATABLE_STRUCT_METHOD_VALIDATE(iotjs_jhandler_t, jhandler); iotjs_jhandler_return_jval(jhandler, iotjs_jval_get_null()); } void iotjs_jhandler_return_boolean(iotjs_jhandler_t* jhandler, bool ret) { IOTJS_VALIDATABLE_STRUCT_METHOD_VALIDATE(iotjs_jhandler_t, jhandler); iotjs_jhandler_return_jval(jhandler, iotjs_jval_get_boolean(ret)); } void iotjs_jhandler_return_number(iotjs_jhandler_t* jhandler, double ret) { IOTJS_VALIDATABLE_STRUCT_METHOD_VALIDATE(iotjs_jhandler_t, jhandler); iotjs_jval_t jval = iotjs_jval_create_number(ret); iotjs_jhandler_return_jval(jhandler, &jval); iotjs_jval_destroy(&jval); } void iotjs_jhandler_return_string(iotjs_jhandler_t* jhandler, const iotjs_string_t* ret) { IOTJS_VALIDATABLE_STRUCT_METHOD_VALIDATE(iotjs_jhandler_t, jhandler); iotjs_jval_t jval = iotjs_jval_create_string(ret); iotjs_jhandler_return_jval(jhandler, &jval); iotjs_jval_destroy(&jval); } void iotjs_jhandler_return_string_raw(iotjs_jhandler_t* jhandler, const char* ret) { IOTJS_VALIDATABLE_STRUCT_METHOD_VALIDATE(iotjs_jhandler_t, jhandler); iotjs_jval_t jval = iotjs_jval_create_string_raw(ret); iotjs_jhandler_return_jval(jhandler, &jval); iotjs_jval_destroy(&jval); } void iotjs_jhandler_throw(iotjs_jhandler_t* jhandler, const iotjs_jval_t* err) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_jhandler_t, jhandler); #ifndef NDEBUG IOTJS_ASSERT(_this->finished == false); #endif iotjs_jval_destroy(&_this->jret); _this->jret = iotjs_jval_create_copied(err); jerry_value_set_error_flag(&_this->jret.unsafe.value); #ifndef NDEBUG _this->finished = true; #endif } static jerry_value_t iotjs_native_dispatch_function( const jerry_value_t jfunc, const jerry_value_t jthis, const jerry_value_t jargv[], const JRawLengthType jargc) { uintptr_t target_function_ptr = 0x0; JNativeInfoType out_info; if (!jerry_get_object_native_pointer(jfunc, (void**)&target_function_ptr, &out_info)) { const jerry_char_t* jmsg = (const jerry_char_t*)("Internal dispatch error"); return jerry_create_error((jerry_error_t)IOTJS_ERROR_COMMON, jmsg); } IOTJS_ASSERT(target_function_ptr != 0x0); iotjs_jhandler_t jhandler; iotjs_jhandler_initialize(&jhandler, jfunc, jthis, jargv, jargc); ((iotjs_native_handler_t)target_function_ptr)(&jhandler); jerry_value_t ret_val = jhandler.unsafe.jret.unsafe.value; iotjs_jhandler_destroy(&jhandler); return ret_val; } iotjs_jval_t iotjs_jval_create_function_with_dispatch( iotjs_native_handler_t handler) { iotjs_jval_t jfunc = iotjs_jval_create_function(iotjs_native_dispatch_function); iotjs_jval_set_object_native_handle(&jfunc, (uintptr_t)handler, NULL); return jfunc; } void iotjs_binding_initialize() { jundefined = iotjs_jval_create_raw(jerry_create_undefined()); jnull = iotjs_jval_create_raw(jerry_create_null()); jtrue = iotjs_jval_create_raw(jerry_create_boolean(true)); jfalse = iotjs_jval_create_raw(jerry_create_boolean(false)); jglobal = iotjs_jval_create_raw(jerry_get_global_object()); IOTJS_ASSERT(iotjs_jval_is_object(&jglobal)); iotjs_jargs_initialize_empty(&jargs_empty); #ifdef NDEBUG assert(sizeof(iotjs_jval_t) == sizeof(jerry_value_t)); #endif } void iotjs_binding_finalize() { iotjs_jval_destroy(&jundefined); iotjs_jval_destroy(&jnull); iotjs_jval_destroy(&jtrue); iotjs_jval_destroy(&jfalse); iotjs_jval_destroy(&jglobal); iotjs_jargs_destroy(&jargs_empty); } iotjs-1.0/src/iotjs_binding.h000066400000000000000000000301621312466455500163010ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef IOTJS_BINDING_H #define IOTJS_BINDING_H #include "iotjs_util.h" #include "jerryscript.h" #include typedef jerry_external_handler_t JHandlerType; typedef const jerry_object_native_info_t* JNativeInfoType; typedef jerry_length_t JRawLengthType; typedef enum { IOTJS_ERROR_COMMON = JERRY_ERROR_COMMON, IOTJS_ERROR_EVAL = JERRY_ERROR_EVAL, IOTJS_ERROR_RANGE = JERRY_ERROR_RANGE, IOTJS_ERROR_REFERENCE = JERRY_ERROR_REFERENCE, IOTJS_ERROR_SYNTAX = JERRY_ERROR_SYNTAX, IOTJS_ERROR_TYPE = JERRY_ERROR_TYPE, IOTJS_ERROR_URI = JERRY_ERROR_URI } iotjs_error_t; #define FOR_EACH_JVAL_TYPES(F) \ F(undefined) \ F(null) \ F(boolean) \ F(number) \ F(string) \ F(object) \ F(array) \ F(function) typedef struct { jerry_value_t value; // JavaScript value representation } IOTJS_VALIDATED_STRUCT(iotjs_jval_t); typedef struct { iotjs_jval_t jfunc; iotjs_jval_t jthis; iotjs_jval_t* jargv; iotjs_jval_t jret; uint16_t jargc; #ifndef NDEBUG bool finished; #endif } IOTJS_VALIDATED_STRUCT(iotjs_jhandler_t); typedef void (*iotjs_native_handler_t)(iotjs_jhandler_t* jhandler); /* Constructors */ iotjs_jval_t iotjs_jval_create_number(double v); iotjs_jval_t iotjs_jval_create_string(const iotjs_string_t* v); iotjs_jval_t iotjs_jval_create_string_raw(const char* data); iotjs_jval_t iotjs_jval_create_object(); iotjs_jval_t iotjs_jval_create_array(uint32_t len); iotjs_jval_t iotjs_jval_create_byte_array(uint32_t len, const char* data); iotjs_jval_t iotjs_jval_create_function(JHandlerType handler); iotjs_jval_t iotjs_jval_create_error(const char* msg); iotjs_jval_t iotjs_jval_create_error_type(iotjs_error_t type, const char* msg); iotjs_jval_t iotjs_jval_create_copied(const iotjs_jval_t* other); iotjs_jval_t iotjs_jval_get_string_size(const iotjs_string_t* str); iotjs_jval_t* iotjs_jval_get_undefined(); iotjs_jval_t* iotjs_jval_get_null(); iotjs_jval_t* iotjs_jval_get_boolean(bool v); iotjs_jval_t* iotjs_jval_get_global_object(); /* Destructor */ void iotjs_jval_destroy(iotjs_jval_t* jval); #define THIS_JVAL const iotjs_jval_t* jval /* Type Checkers */ bool iotjs_jval_is_undefined(THIS_JVAL); bool iotjs_jval_is_null(THIS_JVAL); bool iotjs_jval_is_boolean(THIS_JVAL); bool iotjs_jval_is_number(THIS_JVAL); bool iotjs_jval_is_string(THIS_JVAL); bool iotjs_jval_is_object(THIS_JVAL); bool iotjs_jval_is_array(THIS_JVAL); bool iotjs_jval_is_function(THIS_JVAL); /* Type Converters */ bool iotjs_jval_as_boolean(THIS_JVAL); double iotjs_jval_as_number(THIS_JVAL); iotjs_string_t iotjs_jval_as_string(THIS_JVAL); const iotjs_jval_t* iotjs_jval_as_object(THIS_JVAL); const iotjs_jval_t* iotjs_jval_as_array(THIS_JVAL); const iotjs_jval_t* iotjs_jval_as_function(THIS_JVAL); /* Methods for General JavaScript Object */ void iotjs_jval_set_method(THIS_JVAL, const char* name, iotjs_native_handler_t handler); void iotjs_jval_set_property_jval(THIS_JVAL, const char* name, const iotjs_jval_t* value); void iotjs_jval_set_property_null(THIS_JVAL, const char* name); void iotjs_jval_set_property_undefined(THIS_JVAL, const char* name); void iotjs_jval_set_property_boolean(THIS_JVAL, const char* name, bool v); void iotjs_jval_set_property_number(THIS_JVAL, const char* name, double v); void iotjs_jval_set_property_string(THIS_JVAL, const char* name, const iotjs_string_t* v); void iotjs_jval_set_property_string_raw(THIS_JVAL, const char* name, const char* v); iotjs_jval_t iotjs_jval_get_property(THIS_JVAL, const char* name); void iotjs_jval_set_object_native_handle(THIS_JVAL, uintptr_t ptr, JNativeInfoType native_info); uintptr_t iotjs_jval_get_object_native_handle(THIS_JVAL); uintptr_t iotjs_jval_get_object_from_jhandler(iotjs_jhandler_t* jhandler, JNativeInfoType native_info); void iotjs_jval_set_property_by_index(THIS_JVAL, uint32_t idx, const iotjs_jval_t* value); iotjs_jval_t iotjs_jval_get_property_by_index(THIS_JVAL, uint32_t idx); #undef THIS_JVAL typedef struct { uint16_t capacity; uint16_t argc; iotjs_jval_t* argv; } IOTJS_VALIDATED_STRUCT(iotjs_jargs_t); iotjs_jargs_t iotjs_jargs_create(uint16_t capacity); const iotjs_jargs_t* iotjs_jargs_get_empty(); void iotjs_jargs_destroy(iotjs_jargs_t* jargs); uint16_t iotjs_jargs_length(const iotjs_jargs_t* jargs); void iotjs_jargs_append_jval(iotjs_jargs_t* jargs, const iotjs_jval_t* x); void iotjs_jargs_append_undefined(iotjs_jargs_t* jargs); void iotjs_jargs_append_null(iotjs_jargs_t* jargs); void iotjs_jargs_append_bool(iotjs_jargs_t* jargs, bool x); void iotjs_jargs_append_number(iotjs_jargs_t* jargs, double x); void iotjs_jargs_append_string(iotjs_jargs_t* jargs, const iotjs_string_t* x); void iotjs_jargs_append_string_raw(iotjs_jargs_t* jargs, const char* x); void iotjs_jargs_append_error(iotjs_jargs_t* jargs, const char* msg); void iotjs_jargs_replace(iotjs_jargs_t* jargs, uint16_t index, const iotjs_jval_t* x); const iotjs_jval_t* iotjs_jargs_get(const iotjs_jargs_t* jargs, uint16_t index); // Calls JavaScript function. iotjs_jval_t iotjs_jhelper_call(const iotjs_jval_t* jfunc, const iotjs_jval_t* jthis, const iotjs_jargs_t* jargs, bool* throws); // Calls javascript function. iotjs_jval_t iotjs_jhelper_call_ok(const iotjs_jval_t* jfunc, const iotjs_jval_t* jthis, const iotjs_jargs_t* jargs); // Evaluates javascript source file. iotjs_jval_t iotjs_jhelper_eval(const char* name, size_t name_len, const uint8_t* data, size_t size, bool strict_mode, bool* throws); #ifdef ENABLE_SNAPSHOT // Evaluates javascript snapshot. iotjs_jval_t iotjs_jhelper_exec_snapshot(const void* snapshot_p, size_t snapshot_size, bool* throws); #endif void iotjs_jhandler_initialize(iotjs_jhandler_t* jhandler, const jerry_value_t jfunc, const jerry_value_t jthis, const jerry_value_t jargv[], const uint16_t jargc); void iotjs_jhandler_destroy(iotjs_jhandler_t* jhandler); const iotjs_jval_t* iotjs_jhandler_get_function(iotjs_jhandler_t* jhandler); const iotjs_jval_t* iotjs_jhandler_get_this(iotjs_jhandler_t* jhandler); const iotjs_jval_t* iotjs_jhandler_get_arg(iotjs_jhandler_t* jhandler, uint16_t index); uint16_t iotjs_jhandler_get_arg_length(iotjs_jhandler_t* jhandler); void iotjs_jhandler_return_jval(iotjs_jhandler_t* jhandler, const iotjs_jval_t* ret); void iotjs_jhandler_return_undefined(iotjs_jhandler_t* jhandler); void iotjs_jhandler_return_null(iotjs_jhandler_t* jhandler); void iotjs_jhandler_return_boolean(iotjs_jhandler_t* jhandler, bool x); void iotjs_jhandler_return_number(iotjs_jhandler_t* jhandler, double x); void iotjs_jhandler_return_string(iotjs_jhandler_t* jhandler, const iotjs_string_t* x); void iotjs_jhandler_return_string_raw(iotjs_jhandler_t* jhandler, const char* x); void iotjs_jhandler_throw(iotjs_jhandler_t* jhandler, const iotjs_jval_t* err); iotjs_jval_t iotjs_jval_create_function_with_dispatch( iotjs_native_handler_t handler); #define JHANDLER_THROW(TYPE, message) \ iotjs_jval_t e = iotjs_jval_create_error_type(IOTJS_ERROR_##TYPE, message); \ iotjs_jhandler_throw(jhandler, &e); \ iotjs_jval_destroy(&e); #define JHANDLER_CHECK(predicate) \ if (!(predicate)) { \ char buffer[64]; \ snprintf(buffer, 63, "Internal error (%s)", __func__); \ JHANDLER_THROW(COMMON, buffer) \ return; \ } #define JHANDLER_CHECK_TYPE(jval, type) \ JHANDLER_CHECK(iotjs_jval_is_##type(jval)); #define JHANDLER_CHECK_ARG(index, type) \ JHANDLER_CHECK_TYPE(iotjs_jhandler_get_arg(jhandler, index), type); #define JHANDLER_CHECK_ARG_IF_EXIST(index, type) \ if (iotjs_jhandler_get_arg_length(jhandler) > index) { \ JHANDLER_CHECK_TYPE(iotjs_jhandler_get_arg(jhandler, index), type); \ } #define JHANDLER_CHECK_ARGS_0() #define JHANDLER_CHECK_ARGS_1(type0) \ JHANDLER_CHECK_ARGS_0(); \ JHANDLER_CHECK_ARG(0, type0); #define JHANDLER_CHECK_ARGS_2(type0, type1) \ JHANDLER_CHECK_ARGS_1(type0); \ JHANDLER_CHECK_ARG(1, type1); #define JHANDLER_CHECK_ARGS_3(type0, type1, type2) \ JHANDLER_CHECK_ARGS_2(type0, type1); \ JHANDLER_CHECK_ARG(2, type2); #define JHANDLER_CHECK_ARGS_4(type0, type1, type2, type3) \ JHANDLER_CHECK_ARGS_3(type0, type1, type2); \ JHANDLER_CHECK_ARG(3, type3); #define JHANDLER_CHECK_ARGS_5(type0, type1, type2, type3, type4) \ JHANDLER_CHECK_ARGS_4(type0, type1, type2, type3); \ JHANDLER_CHECK_ARG(4, type4); // Workaround for GCC type-limits warning static inline bool ge(uint16_t a, uint16_t b) { return a >= b; } #define JHANDLER_CHECK_ARGS(argc, ...) \ JHANDLER_CHECK(ge(iotjs_jhandler_get_arg_length(jhandler), argc)); \ JHANDLER_CHECK_ARGS_##argc(__VA_ARGS__) #define JHANDLER_CHECK_THIS(type) \ JHANDLER_CHECK_TYPE(iotjs_jhandler_get_this(jhandler), type); #define JHANDLER_GET_ARG(index, type) \ iotjs_jval_as_##type(iotjs_jhandler_get_arg(jhandler, index)) #define JHANDLER_GET_ARG_IF_EXIST(index, type) \ ((iotjs_jhandler_get_arg_length(jhandler) > index) \ ? (iotjs_jval_is_##type(iotjs_jhandler_get_arg(jhandler, index)) \ ? iotjs_jhandler_get_arg(jhandler, index) \ : NULL) \ : NULL) #define JHANDLER_GET_THIS(type) \ iotjs_jval_as_##type(iotjs_jhandler_get_this(jhandler)) #define JHANDLER_FUNCTION(name) static void name(iotjs_jhandler_t* jhandler) #if defined(EXPERIMENTAL) && !defined(DEBUG) // This code branch is to be in #ifdef NDEBUG #define DJHANDLER_CHECK_ARG(index, type) ((void)0) #define DJHANDLER_CHECK_ARGS(argc, ...) ((void)0) #define DJHANDLER_CHECK_THIS(type) ((void)0) #define DJHANDLER_CHECK_ARG_IF_EXIST(index, type) ((void)0) #else #define DJHANDLER_CHECK_ARG(index, type) JHANDLER_CHECK_ARG(index, type) #define DJHANDLER_CHECK_ARGS(argc, ...) JHANDLER_CHECK_ARGS(argc, __VA_ARGS__) #define DJHANDLER_CHECK_THIS(type) JHANDLER_CHECK_THIS(type) #define DJHANDLER_CHECK_ARG_IF_EXIST(index, type) \ JHANDLER_CHECK_ARG_IF_EXIST(index, type) #endif #define JHANDLER_DECLARE_THIS_PTR(type, name) \ iotjs_##type##_t* name = (iotjs_##type##_t*) \ iotjs_jval_get_object_from_jhandler(jhandler, &this_module_native_info); \ if (!name) { \ return; \ } void iotjs_binding_initialize(); void iotjs_binding_finalize(); #endif /* IOTJS_BINDING_H */ iotjs-1.0/src/iotjs_binding_helper.c000066400000000000000000000072111312466455500176320ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "iotjs_def.h" #include #include #include void iotjs_uncaught_exception(const iotjs_jval_t* jexception) { const iotjs_jval_t* process = iotjs_module_get(MODULE_PROCESS); iotjs_jval_t jonuncaughtexception = iotjs_jval_get_property(process, IOTJS_MAGIC_STRING__ONUNCAUGHTEXCEPTION); IOTJS_ASSERT(iotjs_jval_is_function(&jonuncaughtexception)); iotjs_jargs_t args = iotjs_jargs_create(1); iotjs_jargs_append_jval(&args, jexception); bool throws; iotjs_jval_t jres = iotjs_jhelper_call(&jonuncaughtexception, process, &args, &throws); iotjs_jargs_destroy(&args); iotjs_jval_destroy(&jres); iotjs_jval_destroy(&jonuncaughtexception); if (throws) { exit(2); } } void iotjs_process_emit_exit(int code) { const iotjs_jval_t* process = iotjs_module_get(MODULE_PROCESS); iotjs_jval_t jexit = iotjs_jval_get_property(process, IOTJS_MAGIC_STRING_EMITEXIT); IOTJS_ASSERT(iotjs_jval_is_function(&jexit)); iotjs_jargs_t jargs = iotjs_jargs_create(1); iotjs_jargs_append_number(&jargs, code); bool throws; iotjs_jval_t jres = iotjs_jhelper_call(&jexit, process, &jargs, &throws); iotjs_jargs_destroy(&jargs); iotjs_jval_destroy(&jres); iotjs_jval_destroy(&jexit); if (throws) { exit(2); } } // Calls next tick callbacks registered via `process.nextTick()`. bool iotjs_process_next_tick() { const iotjs_jval_t* process = iotjs_module_get(MODULE_PROCESS); iotjs_jval_t jon_next_tick = iotjs_jval_get_property(process, IOTJS_MAGIC_STRING__ONNEXTTICK); IOTJS_ASSERT(iotjs_jval_is_function(&jon_next_tick)); iotjs_jval_t jres = iotjs_jhelper_call_ok(&jon_next_tick, iotjs_jval_get_undefined(), iotjs_jargs_get_empty()); IOTJS_ASSERT(iotjs_jval_is_boolean(&jres)); bool ret = iotjs_jval_as_boolean(&jres); iotjs_jval_destroy(&jres); iotjs_jval_destroy(&jon_next_tick); return ret; } // Make a callback for the given `function` with `this_` binding and `args` // arguments. The next tick callbacks registered via `process.nextTick()` // will be called after the callback function `function` returns. void iotjs_make_callback(const iotjs_jval_t* jfunction, const iotjs_jval_t* jthis, const iotjs_jargs_t* jargs) { iotjs_jval_t result = iotjs_make_callback_with_result(jfunction, jthis, jargs); iotjs_jval_destroy(&result); } iotjs_jval_t iotjs_make_callback_with_result(const iotjs_jval_t* jfunction, const iotjs_jval_t* jthis, const iotjs_jargs_t* jargs) { // Calls back the function. bool throws; iotjs_jval_t jres = iotjs_jhelper_call(jfunction, jthis, jargs, &throws); if (throws) { iotjs_uncaught_exception(&jres); } // Calls the next tick callbacks. iotjs_process_next_tick(); // Return value. return jres; } const iotjs_jval_t* iotjs_init_process_module() { return iotjs_module_initialize_if_necessary(MODULE_PROCESS); } iotjs-1.0/src/iotjs_binding_helper.h000066400000000000000000000024511312466455500176400ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef IOTJS_BINDING_HELPER_H #define IOTJS_BINDING_HELPER_H #include "iotjs_binding.h" void iotjs_uncaught_exception(const iotjs_jval_t* jexception); void iotjs_process_emit_exit(int code); bool iotjs_process_next_tick(); void iotjs_make_callback(const iotjs_jval_t* jfunction, const iotjs_jval_t* jthis, const iotjs_jargs_t* jargs); iotjs_jval_t iotjs_make_callback_with_result(const iotjs_jval_t* jfunction, const iotjs_jval_t* jthis, const iotjs_jargs_t* jargs); const iotjs_jval_t* iotjs_init_process_module(); #endif /* IOTJS_BINDING_HELPER_H */ iotjs-1.0/src/iotjs_debuglog.c000066400000000000000000000037571312466455500164640ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include "iotjs_debuglog.h" #ifdef ENABLE_DEBUG_LOG int iotjs_debug_level = DBGLEV_ERR; FILE* iotjs_log_stream; const char* iotjs_debug_prefix[4] = { "", "ERR", "WRN", "INF" }; #endif // ENABLE_DEBUG_LOG void init_debug_settings() { #ifdef ENABLE_DEBUG_LOG const char* dbglevel = NULL; const char* dbglogfile = NULL; #if defined(__linux__) || defined(__APPLE__) dbglevel = getenv("IOTJS_DEBUG_LEVEL"); dbglogfile = getenv("IOTJS_DEBUG_LOGFILE"); #endif // defined(__linux__) || defined(__APPLE__) if (dbglevel) { iotjs_debug_level = atoi(dbglevel); if (iotjs_debug_level < 0) iotjs_debug_level = 0; if (iotjs_debug_level > DBGLEV_INFO) iotjs_debug_level = DBGLEV_INFO; } iotjs_log_stream = stderr; if (dbglogfile) { FILE* logstream; logstream = fopen(dbglogfile, "w+"); if (logstream != NULL) iotjs_log_stream = logstream; } // fprintf(stderr, "DBG LEV = %d", iotjs_debug_level); // fprintf(stderr, "DBG OUT = %s", (dbglogfile==NULL?"(stderr)":dbglogfile)); #endif // ENABLE_DEBUG_LOG } void release_debug_settings() { #ifdef ENABLE_DEBUG_LOG if (iotjs_log_stream != stderr || iotjs_log_stream != stdout) { fclose(iotjs_log_stream); } // some embed systems(ex, nuttx) may need this iotjs_log_stream = stderr; iotjs_debug_level = DBGLEV_ERR; #endif // ENABLE_DEBUG_LOG } iotjs-1.0/src/iotjs_debuglog.h000066400000000000000000000040261312466455500164570ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef IOTJS_DEBUGLOG_H #define IOTJS_DEBUGLOG_H #ifdef ENABLE_DEBUG_LOG #include extern int iotjs_debug_level; extern FILE* iotjs_log_stream; extern const char* iotjs_debug_prefix[4]; #define DBGLEV_ERR 1 #define DBGLEV_WARN 2 #define DBGLEV_INFO 3 #define IOTJS_DLOG(lvl, ...) \ do { \ if (0 <= lvl && lvl <= iotjs_debug_level && iotjs_log_stream) { \ fprintf(iotjs_log_stream, "[%s] ", iotjs_debug_prefix[lvl]); \ fprintf(iotjs_log_stream, __VA_ARGS__); \ fprintf(iotjs_log_stream, "\n"); \ fflush(iotjs_log_stream); \ } \ } while (0) #define DLOG(...) IOTJS_DLOG(DBGLEV_ERR, __VA_ARGS__) #define DDLOG(...) IOTJS_DLOG(DBGLEV_WARN, __VA_ARGS__) #define DDDLOG(...) IOTJS_DLOG(DBGLEV_INFO, __VA_ARGS__) /* Use DLOG for errors, default you will see them Use DDLOG for warnings, set iotjs_debug_level=2 to see them USE DDDLOG for information, set iotjs_debug_level=3 to see them */ #else /* !ENABLE_DEBUG_LOG */ #define IOTJS_DLOG(...) #define DLOG(...) #define DDLOG(...) #define DDDLOG(...) #endif /* ENABLE_DEBUG_LOG */ void init_debug_settings(); void release_debug_settings(); #endif /* IOTJS_DEBUGLOG_H */ iotjs-1.0/src/iotjs_def.h000066400000000000000000000121501312466455500154220ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef IOTJS_DEF_H #define IOTJS_DEF_H #ifndef IOTJS_MAX_READ_BUFFER_SIZE #if defined(__NUTTX__) || defined(__TIZENRT__) #define IOTJS_MAX_READ_BUFFER_SIZE 1023 #define IOTJS_MAX_PATH_SIZE 120 #else #define IOTJS_MAX_READ_BUFFER_SIZE 65535 #define IOTJS_MAX_PATH_SIZE PATH_MAX #endif #endif #ifndef IOTJS_ASSERT #ifdef NDEBUG #define IOTJS_ASSERT(x) ((void)(x)) #else #define IOTJS_ASSERT(x) assert(x) #endif #endif #if defined(__arm__) #define TARGET_ARCH "arm" #elif defined(__i686__) #define TARGET_ARCH "ia32" #elif defined(__x86_64__) #define TARGET_ARCH "x64" #else #define TARGET_ARCH "unknown" #endif #if defined(__linux__) #define TARGET_OS "linux" #elif defined(__NUTTX__) #define TARGET_OS "nuttx" #elif defined(__APPLE__) #define TARGET_OS "darwin" #elif defined(__TIZENRT__) #define TARGET_OS "tizenrt" #else #define TARGET_OS "unknown" #endif #if !defined(STRINGIFY) #define STRINGIFY(x) #x #endif #if !defined(TOSTRING) #define TOSTRING(x) STRINGIFY(x) #endif #if !defined(TARGET_BOARD) #define TARGET_BOARD "unknown" #endif #define IOTJS_VALID_MAGIC_SEQUENCE 0xfee1c001 /* feel cool */ #define IOTJS_INVALID_MAGIC_SEQUENCE 0xfee1badd /* feel bad */ #define IOTJS_DECLARE_THIS(iotjs_classname_t, x) \ iotjs_classname_t##_impl_t* _this = &(x)->unsafe; /* Avoid compiler warnings if needed. */ #define IOTJS_UNUSED(x) ((void)(x)) #ifdef NDEBUG #define IOTJS_VALIDATED_STRUCT(iotjs_classname_t) \ iotjs_classname_t##_impl_t; \ typedef struct iotjs_classname_t { \ iotjs_classname_t##_impl_t unsafe; \ } iotjs_classname_t; #define IOTJS_VALIDATED_STRUCT_STATIC_INITIALIZER(...) __VA_ARGS__ #define IOTJS_VALIDATED_STRUCT_CONSTRUCTOR(iotjs_classname_t, x) \ IOTJS_DECLARE_THIS(iotjs_classname_t, x); #define IOTJS_VALIDATED_STRUCT_DESTRUCTOR(iotjs_classname_t, x) \ IOTJS_DECLARE_THIS(iotjs_classname_t, x); #define IOTJS_VALIDATED_STRUCT_METHOD(iotjs_classname_t, x) \ IOTJS_DECLARE_THIS(iotjs_classname_t, x); #define IOTJS_VALIDATABLE_STRUCT_DESTRUCTOR_VALIDATE(iotjs_classname_t, x) #define IOTJS_VALIDATABLE_STRUCT_METHOD_VALIDATE(iotjs_classname_t, x) #else /* !NDEBUG */ #define IOTJS_VALIDATED_STRUCT(iotjs_classname_t) \ iotjs_classname_t##_impl_t; \ typedef struct iotjs_classname_t { \ iotjs_classname_t##_impl_t unsafe; \ uint32_t flag_create; \ char* valgrind_tracer; \ } iotjs_classname_t; #define IOTJS_VALIDATED_STRUCT_STATIC_INITIALIZER(...) \ { IOTJS_VALID_MAGIC_SEQUENCE, iotjs_buffer_allocate(4), __VA_ARGS__ } #define IOTJS_VALIDATE_FLAG(iotjs_classname_t, x) \ if ((x)->flag_create != IOTJS_VALID_MAGIC_SEQUENCE) { \ DLOG("`%s %s` is not initialized properly.", #iotjs_classname_t, #x); \ IOTJS_ASSERT(false); \ } #define IOTJS_VALIDATED_STRUCT_CONSTRUCTOR(iotjs_classname_t, x) \ IOTJS_DECLARE_THIS(iotjs_classname_t, x); \ /* IOTJS_ASSERT((x)->flag_create != IOTJS_VALID_MAGIC_SEQUENCE); */ \ (x)->flag_create = IOTJS_VALID_MAGIC_SEQUENCE; \ (x)->valgrind_tracer = iotjs_buffer_allocate(4); #define IOTJS_VALIDATED_STRUCT_DESTRUCTOR(iotjs_classname_t, x) \ IOTJS_DECLARE_THIS(iotjs_classname_t, x); \ IOTJS_VALIDATE_FLAG(iotjs_classname_t, x); \ (x)->flag_create = IOTJS_INVALID_MAGIC_SEQUENCE; \ iotjs_buffer_release((x)->valgrind_tracer); #define IOTJS_VALIDATED_STRUCT_METHOD(iotjs_classname_t, x) \ IOTJS_DECLARE_THIS(iotjs_classname_t, x); \ IOTJS_VALIDATE_FLAG(iotjs_classname_t, x); #define IOTJS_VALIDATABLE_STRUCT_DESTRUCTOR_VALIDATE(iotjs_classname_t, x) \ IOTJS_VALIDATE_FLAG(iotjs_classname_t, x); \ (x)->flag_create = IOTJS_INVALID_MAGIC_SEQUENCE; \ iotjs_buffer_release((x)->valgrind_tracer); #define IOTJS_VALIDATABLE_STRUCT_METHOD_VALIDATE(iotjs_classname_t, x) \ IOTJS_VALIDATE_FLAG(iotjs_classname_t, x); #endif /* NDEBUG */ #include #include #include /* PATH_MAX */ #include #include // commonly used header files #include "iotjs_binding.h" #include "iotjs_binding_helper.h" #include "iotjs_debuglog.h" #include "iotjs_env.h" #include "iotjs_magic_strings.h" #include "iotjs_module.h" #include "iotjs_string.h" #include "iotjs_util.h" #endif /* IOTJS_DEF_H */ iotjs-1.0/src/iotjs_env.c000066400000000000000000000124501312466455500154520ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "iotjs_def.h" #include "iotjs_env.h" #include static iotjs_environment_t current_env; static bool initialized = false; /** * Constructor/Destructor on private section. * To prevent create an instance of iotjs_environment_t. * The only way to get an instance of environment is iotjs_environment_get() */ static void iotjs_environment_initialize(iotjs_environment_t* env); static void iotjs_environment_destroy(iotjs_environment_t* env); /** * Get the singleton instance of iotjs_environment_t. */ const iotjs_environment_t* iotjs_environment_get() { if (!initialized) { iotjs_environment_initialize(¤t_env); initialized = true; } return ¤t_env; } /** * Release the singleton instance of iotjs_environment_t. */ void iotjs_environment_release() { if (initialized) { iotjs_environment_destroy(¤t_env); initialized = false; } } /** * Initialize an instance of iotjs_environment_t. */ static void iotjs_environment_initialize(iotjs_environment_t* env) { IOTJS_VALIDATED_STRUCT_CONSTRUCTOR(iotjs_environment_t, env); _this->argc = 0; _this->argv = NULL; _this->loop = NULL; _this->state = kInitializing; _this->config.memstat = false; _this->config.show_opcode = false; } /** * Destroy an instance of iotjs_environment_t. */ static void iotjs_environment_destroy(iotjs_environment_t* env) { IOTJS_VALIDATED_STRUCT_DESTRUCTOR(iotjs_environment_t, env); if (_this->argv) { // release command line argument strings. // _argv[0] and _argv[1] refer addresses in static memory space. // Others refer addresses in heap space that is need to be deallocated. for (uint32_t i = 2; i < _this->argc; ++i) { iotjs_buffer_release(_this->argv[i]); } iotjs_buffer_release((char*)_this->argv); } } /** * Parse command line arguments */ bool iotjs_environment_parse_command_line_arguments(iotjs_environment_t* env, uint32_t argc, char** argv) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_environment_t, env); // Parse IoT.js command line arguments. uint32_t i = 1; while (i < argc && argv[i][0] == '-') { if (!strcmp(argv[i], "--memstat")) { _this->config.memstat = true; } else if (!strcmp(argv[i], "--show-opcodes")) { _this->config.show_opcode = true; } else if (!strcmp(argv[i], "--start-debug-server")) { _this->config.debugger = true; } else { fprintf(stderr, "unknown command line option: %s\n", argv[i]); return false; } ++i; } // There must be at least one argument after processing the IoT.js args. if ((argc - i) < 1) { fprintf(stderr, "Usage: iotjs [options] {script | script.js} [arguments]\n"); return false; } // Remaining arguments are for application. _this->argc = 2; size_t buffer_size = ((size_t)(_this->argc + argc - i)) * sizeof(char*); _this->argv = (char**)iotjs_buffer_allocate(buffer_size); _this->argv[0] = argv[0]; _this->argv[1] = argv[i++]; while (i < argc) { _this->argv[_this->argc] = iotjs_buffer_allocate(strlen(argv[i]) + 1); strcpy(_this->argv[_this->argc], argv[i]); _this->argc++; i++; } return true; } uint32_t iotjs_environment_argc(const iotjs_environment_t* env) { const IOTJS_VALIDATED_STRUCT_METHOD(iotjs_environment_t, env); return _this->argc; } const char* iotjs_environment_argv(const iotjs_environment_t* env, uint32_t idx) { const IOTJS_VALIDATED_STRUCT_METHOD(iotjs_environment_t, env); return _this->argv[idx]; } uv_loop_t* iotjs_environment_loop(const iotjs_environment_t* env) { const IOTJS_VALIDATED_STRUCT_METHOD(iotjs_environment_t, env); return _this->loop; } void iotjs_environment_set_loop(iotjs_environment_t* env, uv_loop_t* loop) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_environment_t, env); _this->loop = loop; } const Config* iotjs_environment_config(const iotjs_environment_t* env) { const IOTJS_VALIDATED_STRUCT_METHOD(iotjs_environment_t, env); return &_this->config; } void iotjs_environment_go_state_running_main(iotjs_environment_t* env) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_environment_t, env); IOTJS_ASSERT(_this->state == kInitializing); _this->state = kRunningMain; } void iotjs_environment_go_state_running_loop(iotjs_environment_t* env) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_environment_t, env); IOTJS_ASSERT(_this->state == kRunningMain); _this->state = kRunningLoop; } void iotjs_environment_go_state_exiting(iotjs_environment_t* env) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_environment_t, env); IOTJS_ASSERT(_this->state < kExiting); _this->state = kExiting; } iotjs-1.0/src/iotjs_env.h000066400000000000000000000040601312466455500154550ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef IOTJS_ENV_H #define IOTJS_ENV_H #include "uv.h" typedef struct { bool memstat; bool show_opcode; bool debugger; } Config; typedef enum { kInitializing, kRunningMain, kRunningLoop, kExiting, } State; typedef struct { // Number of application arguments including 'iotjs' and app name. uint32_t argc; // Application arguments list including 'iotjs' and app name. char** argv; // I/O event loop. uv_loop_t* loop; // Running state. State state; // Run config Config config; } IOTJS_VALIDATED_STRUCT(iotjs_environment_t); const iotjs_environment_t* iotjs_environment_get(); void iotjs_environment_release(); bool iotjs_environment_parse_command_line_arguments(iotjs_environment_t* env, uint32_t argc, char** argv); uint32_t iotjs_environment_argc(const iotjs_environment_t* env); const char* iotjs_environment_argv(const iotjs_environment_t* env, uint32_t idx); uv_loop_t* iotjs_environment_loop(const iotjs_environment_t* env); void iotjs_environment_set_loop(iotjs_environment_t* env, uv_loop_t* loop); const Config* iotjs_environment_config(const iotjs_environment_t* env); void iotjs_environment_go_state_running_main(iotjs_environment_t* env); void iotjs_environment_go_state_running_loop(iotjs_environment_t* env); void iotjs_environment_go_state_exiting(iotjs_environment_t* env); #endif /* IOTJS_ENV_H */ iotjs-1.0/src/iotjs_exception.c000066400000000000000000000016611312466455500166620ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "iotjs_def.h" #include "iotjs_exception.h" #include #include "uv.h" iotjs_jval_t iotjs_create_uv_exception(int errorno, const char* syscall) { static char msg[256]; snprintf(msg, sizeof(msg), "'%s' %s", syscall, uv_strerror(errorno)); return iotjs_jval_create_error(msg); } iotjs-1.0/src/iotjs_exception.h000066400000000000000000000014421312466455500166640ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef IOTJS_EXCEPTION_H #define IOTJS_EXCEPTION_H iotjs_jval_t iotjs_create_uv_exception(int errorno, const char* syscall); #endif /* IOTJS_EXCEPTION_H */ iotjs-1.0/src/iotjs_handlewrap.c000066400000000000000000000100651312466455500170070ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "iotjs_def.h" #include "iotjs_handlewrap.h" void iotjs_handlewrap_initialize(iotjs_handlewrap_t* handlewrap, const iotjs_jval_t* jobject, uv_handle_t* handle, JNativeInfoType native_info) { IOTJS_VALIDATED_STRUCT_CONSTRUCTOR(iotjs_handlewrap_t, handlewrap); // Increase ref count of Javascript object to guarantee it is alive until the // handle has closed. iotjs_jval_t jobjectref = iotjs_jval_create_copied(jobject); iotjs_jobjectwrap_initialize(&_this->jobjectwrap, &jobjectref, native_info); _this->handle = handle; _this->on_close_cb = NULL; handle->data = handlewrap; iotjs_handlewrap_validate(handlewrap); } void iotjs_handlewrap_destroy(iotjs_handlewrap_t* handlewrap) { IOTJS_VALIDATED_STRUCT_DESTRUCTOR(iotjs_handlewrap_t, handlewrap); // Handle should have been release before this. IOTJS_ASSERT(_this->handle == NULL); iotjs_jobjectwrap_destroy(&_this->jobjectwrap); } iotjs_handlewrap_t* iotjs_handlewrap_from_handle(uv_handle_t* handle) { iotjs_handlewrap_t* handlewrap = (iotjs_handlewrap_t*)(handle->data); iotjs_handlewrap_validate(handlewrap); return handlewrap; } iotjs_handlewrap_t* iotjs_handlewrap_from_jobject(const iotjs_jval_t* jobject) { iotjs_handlewrap_t* handlewrap = (iotjs_handlewrap_t*)(iotjs_jval_get_object_native_handle(jobject)); iotjs_handlewrap_validate(handlewrap); return handlewrap; } uv_handle_t* iotjs_handlewrap_get_uv_handle(iotjs_handlewrap_t* handlewrap) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_handlewrap_t, handlewrap); iotjs_handlewrap_validate(handlewrap); return _this->handle; } iotjs_jval_t* iotjs_handlewrap_jobject(iotjs_handlewrap_t* handlewrap) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_handlewrap_t, handlewrap); iotjs_handlewrap_validate(handlewrap); return iotjs_jobjectwrap_jobject(&_this->jobjectwrap); } static void iotjs_handlewrap_on_close(iotjs_handlewrap_t* handlewrap) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_handlewrap_t, handlewrap); // The handle closed. // Calls registered close handler function. if (_this->on_close_cb) { _this->on_close_cb(_this->handle); } // Set handle null. _this->handle = NULL; // Decrease ref count of Javascript object. From now the object can be // reclaimed. iotjs_jval_destroy(iotjs_jobjectwrap_jobject(&_this->jobjectwrap)); } static void iotjs_on_handle_closed(uv_handle_t* handle) { iotjs_handlewrap_t* handlewrap = iotjs_handlewrap_from_handle(handle); iotjs_handlewrap_on_close(handlewrap); } void iotjs_handlewrap_close(iotjs_handlewrap_t* handlewrap, OnCloseHandler on_close_cb) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_handlewrap_t, handlewrap); if (_this->handle != NULL && !uv_is_closing(_this->handle)) { _this->on_close_cb = on_close_cb; uv_close(_this->handle, iotjs_on_handle_closed); } else { DDLOG("Attempt to close uninitialized or already closed handle"); } } void iotjs_handlewrap_validate(iotjs_handlewrap_t* handlewrap) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_handlewrap_t, handlewrap); IOTJS_ASSERT((iotjs_handlewrap_t*)_this == handlewrap); IOTJS_ASSERT((iotjs_jobjectwrap_t*)_this == &_this->jobjectwrap); IOTJS_ASSERT((void*)_this == _this->handle->data); IOTJS_ASSERT((uintptr_t)_this == iotjs_jval_get_object_native_handle( iotjs_jobjectwrap_jobject(&_this->jobjectwrap))); } iotjs-1.0/src/iotjs_handlewrap.h000066400000000000000000000046151312466455500170200ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef IOTJS_HANDLEWRAP_H #define IOTJS_HANDLEWRAP_H #include #include "iotjs_binding.h" #include "iotjs_objectwrap.h" typedef void (*OnCloseHandler)(uv_handle_t*); // UV handle wrapper. // This wrapper connects a Javascript object and a libuv handler. // This wrapper will increase ref count for the Javascript object and decrease // it after corresponding handle has closed. Hence the Javascript object will // not turn into garbage until the handle is open. // Javascript object // -> // Create a handle wrap, initializing uv handle, increase ref count. // -> // The javascript object will be alive until handle has closed. // -> // Handle closed, release handle, decrease ref count. // -> // The javascript object now can be reclaimed by GC. typedef struct { iotjs_jobjectwrap_t jobjectwrap; uv_handle_t* handle; OnCloseHandler on_close_cb; } IOTJS_VALIDATED_STRUCT(iotjs_handlewrap_t); // jobject: Object that connect with the uv handle void iotjs_handlewrap_initialize(iotjs_handlewrap_t* handlewrap, const iotjs_jval_t* jobject, uv_handle_t* handle, JNativeInfoType native_info); void iotjs_handlewrap_destroy(iotjs_handlewrap_t* handlewrap); void iotjs_handlewrap_close(iotjs_handlewrap_t* handlewrap, OnCloseHandler on_close_cb); iotjs_handlewrap_t* iotjs_handlewrap_from_handle(uv_handle_t* handle); iotjs_handlewrap_t* iotjs_handlewrap_from_jobject(const iotjs_jval_t* jobject); uv_handle_t* iotjs_handlewrap_get_uv_handle(iotjs_handlewrap_t* handlewrap); iotjs_jval_t* iotjs_handlewrap_jobject(iotjs_handlewrap_t* handlewrap); void iotjs_handlewrap_validate(iotjs_handlewrap_t* handlewrap); #endif /* IOTJS_HANDLEWRAP_H */ iotjs-1.0/src/iotjs_magic_strings.h000066400000000000000000000202731312466455500175220ustar00rootroot00000000000000/* Copyright 2017-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef IOTJS_STRING_CONSTANTS_H #define IOTJS_STRING_CONSTANTS_H #define IOTJS_MAGIC_STRING_0 "0" #define IOTJS_MAGIC_STRING_1 "1" #define IOTJS_MAGIC_STRING_2 "2" #define IOTJS_MAGIC_STRING_3 "3" #define IOTJS_MAGIC_STRING_ADC "Adc" #define IOTJS_MAGIC_STRING_ADDMEMBERSHIP "addMembership" #define IOTJS_MAGIC_STRING_ADDRESS "address" #define IOTJS_MAGIC_STRING_ARCH "arch" #define IOTJS_MAGIC_STRING_ARGV "argv" #define IOTJS_MAGIC_STRING_BAUDRATE "baudRate" #define IOTJS_MAGIC_STRING_BIND "bind" #define IOTJS_MAGIC_STRING_BINDCONTROL "bindControl" #define IOTJS_MAGIC_STRING_BINDING "binding" #define IOTJS_MAGIC_STRING_BINDRAW "bindRaw" #define IOTJS_MAGIC_STRING_BINDUSER "bindUser" #define IOTJS_MAGIC_STRING_BITORDER "bitOrder" #define IOTJS_MAGIC_STRING_BITORDER_U "BITORDER" #define IOTJS_MAGIC_STRING_BITSPERWORD "bitsPerWord" #define IOTJS_MAGIC_STRING_BOARD "board" #define IOTJS_MAGIC_STRING_BOTH_U "BOTH" #define IOTJS_MAGIC_STRING_BUFFER "Buffer" #define IOTJS_MAGIC_STRING__BUFFER "_buffer" #define IOTJS_MAGIC_STRING__BUILTIN "_builtin" #define IOTJS_MAGIC_STRING_BYTELENGTH "byteLength" #define IOTJS_MAGIC_STRING_BYTEPARSED "byteParsed" #define IOTJS_MAGIC_STRING_CHDIR "chdir" #define IOTJS_MAGIC_STRING_CHIP "chip" #define IOTJS_MAGIC_STRING_CHIPSELECT "chipSelect" #define IOTJS_MAGIC_STRING_CHIPSELECT_U "CHIPSELECT" #define IOTJS_MAGIC_STRING_CLOSE "close" #define IOTJS_MAGIC_STRING_CLOSESYNC "closeSync" #define IOTJS_MAGIC_STRING_CODE "code" #define IOTJS_MAGIC_STRING_COMPARE "compare" #define IOTJS_MAGIC_STRING_COMPILE "compile" #define IOTJS_MAGIC_STRING_COMPILENATIVEPTR "compileNativePtr" #define IOTJS_MAGIC_STRING_CONNECT "connect" #define IOTJS_MAGIC_STRING_COPY "copy" #define IOTJS_MAGIC_STRING__CREATESTAT "_createStat" #define IOTJS_MAGIC_STRING_CREATETCP "createTCP" #define IOTJS_MAGIC_STRING_CWD "cwd" #define IOTJS_MAGIC_STRING_DATABITS "dataBits" #define IOTJS_MAGIC_STRING_DEVICE "device" #define IOTJS_MAGIC_STRING_DIRECTION "direction" #define IOTJS_MAGIC_STRING_DIRECTION_U "DIRECTION" #define IOTJS_MAGIC_STRING_DOEXIT "doExit" #define IOTJS_MAGIC_STRING_DROPMEMBERSHIP "dropMembership" #define IOTJS_MAGIC_STRING_DUTYCYCLE "dutyCycle" #define IOTJS_MAGIC_STRING_EDGE "edge" #define IOTJS_MAGIC_STRING_EDGE_U "EDGE" #define IOTJS_MAGIC_STRING_EMIT "emit" #define IOTJS_MAGIC_STRING_EMITEXIT "emitExit" #define IOTJS_MAGIC_STRING_ENV "env" #define IOTJS_MAGIC_STRING_ERRNAME "errname" #define IOTJS_MAGIC_STRING_EXECUTE "execute" #define IOTJS_MAGIC_STRING_EXPORT "export" #define IOTJS_MAGIC_STRING_FALLING_U "FALLING" #define IOTJS_MAGIC_STRING_FAMILY "family" #define IOTJS_MAGIC_STRING_FINISH "finish" #define IOTJS_MAGIC_STRING_FLOAT "FLOAT" #define IOTJS_MAGIC_STRING_FSTAT "fstat" #define IOTJS_MAGIC_STRING_GETADDRINFO "getaddrinfo" #define IOTJS_MAGIC_STRING_GETSOCKNAME "getsockname" #define IOTJS_MAGIC_STRING_GPIO "Gpio" #define IOTJS_MAGIC_STRING_HANDLER "handler" #define IOTJS_MAGIC_STRING_HANDLETIMEOUT "handleTimeout" #define IOTJS_MAGIC_STRING_HEADERS "headers" #define IOTJS_MAGIC_STRING_HEXWRITE "hexWrite" #define IOTJS_MAGIC_STRING_HIGH "HIGH" #define IOTJS_MAGIC_STRING_HOME "HOME" #define IOTJS_MAGIC_STRING_HTTPPARSER "HTTPParser" #define IOTJS_MAGIC_STRING_IN "IN" #define IOTJS_MAGIC_STRING_IOTJS_ENV "IOTJS_ENV" #define IOTJS_MAGIC_STRING_IOTJS_PATH "IOTJS_PATH" #define IOTJS_MAGIC_STRING_IOTJS "iotjs" #define IOTJS_MAGIC_STRING_IPV4 "IPv4" #define IOTJS_MAGIC_STRING_IPV6 "IPv6" #define IOTJS_MAGIC_STRING_ISALIVEEXCEPTFOR "isAliveExceptFor" #define IOTJS_MAGIC_STRING_ISDEVUP "isDevUp" #define IOTJS_MAGIC_STRING_LENGTH "length" #define IOTJS_MAGIC_STRING_LISTEN "listen" #define IOTJS_MAGIC_STRING_LOOPBACK "loopback" #define IOTJS_MAGIC_STRING_LSB "LSB" #define IOTJS_MAGIC_STRING_MAXSPEED "maxSpeed" #define IOTJS_MAGIC_STRING_METHOD "method" #define IOTJS_MAGIC_STRING_METHODS "methods" #define IOTJS_MAGIC_STRING_MKDIR "mkdir" #define IOTJS_MAGIC_STRING_MODE "mode" #define IOTJS_MAGIC_STRING_MODE_U "MODE" #define IOTJS_MAGIC_STRING_MSB "MSB" #define IOTJS_MAGIC_STRING_NATIVE_SOURCES "native_sources" #define IOTJS_MAGIC_STRING_NONE "NONE" #define IOTJS_MAGIC_STRING_ONBODY "OnBody" #define IOTJS_MAGIC_STRING_ONCLOSE "onclose" #define IOTJS_MAGIC_STRING_ONCONNECTION "onconnection" #define IOTJS_MAGIC_STRING_ONHEADERSCOMPLETE "OnHeadersComplete" #define IOTJS_MAGIC_STRING_ONHEADERS "OnHeaders" #define IOTJS_MAGIC_STRING_ONMESSAGECOMPLETE "OnMessageComplete" #define IOTJS_MAGIC_STRING_ONMESSAGE "onmessage" #define IOTJS_MAGIC_STRING__ONNEXTTICK "_onNextTick" #define IOTJS_MAGIC_STRING_ONREAD "onread" #define IOTJS_MAGIC_STRING__ONUNCAUGHTEXCEPTION "_onUncaughtException" #define IOTJS_MAGIC_STRING_OPENDRAIN "OPENDRAIN" #define IOTJS_MAGIC_STRING_OPEN "open" #define IOTJS_MAGIC_STRING_OUT "OUT" #define IOTJS_MAGIC_STRING_OWNER "owner" #define IOTJS_MAGIC_STRING_PAUSE "pause" #define IOTJS_MAGIC_STRING_PERIOD "period" #define IOTJS_MAGIC_STRING_PIN "pin" #define IOTJS_MAGIC_STRING_PLATFORM "platform" #define IOTJS_MAGIC_STRING_PORT "port" #define IOTJS_MAGIC_STRING_PROTOTYPE "prototype" #define IOTJS_MAGIC_STRING_PULLDOWN "PULLDOWN" #define IOTJS_MAGIC_STRING_PULLUP "PULLUP" #define IOTJS_MAGIC_STRING_PUSHPULL "PUSHPULL" #define IOTJS_MAGIC_STRING_READDIR "readdir" #define IOTJS_MAGIC_STRING_READ "read" #define IOTJS_MAGIC_STRING_READSOURCE "readSource" #define IOTJS_MAGIC_STRING_READSTART "readStart" #define IOTJS_MAGIC_STRING_READSYNC "readSync" #define IOTJS_MAGIC_STRING_READUINT8 "readUInt8" #define IOTJS_MAGIC_STRING_RECVSTART "recvStart" #define IOTJS_MAGIC_STRING_RECVSTOP "recvStop" #define IOTJS_MAGIC_STRING_REF "ref" #define IOTJS_MAGIC_STRING_REINITIALIZE "reinitialize" #define IOTJS_MAGIC_STRING_RENAME "rename" #define IOTJS_MAGIC_STRING_REQUEST "REQUEST" #define IOTJS_MAGIC_STRING_RESPONSE "RESPONSE" #define IOTJS_MAGIC_STRING_RESUME "resume" #define IOTJS_MAGIC_STRING__REUSEADDR "_reuseAddr" #define IOTJS_MAGIC_STRING_RISING_U "RISING" #define IOTJS_MAGIC_STRING_RMDIR "rmdir" #define IOTJS_MAGIC_STRING_SEND "send" #define IOTJS_MAGIC_STRING_SETADDRESS "setAddress" #define IOTJS_MAGIC_STRING_SETBROADCAST "setBroadcast" #define IOTJS_MAGIC_STRING_SETDUTYCYCLE "setDutyCycle" #define IOTJS_MAGIC_STRING_SETENABLE "setEnable" #define IOTJS_MAGIC_STRING_SETFILTER "setFilter" #define IOTJS_MAGIC_STRING_SETFREQUENCY "setFrequency" #define IOTJS_MAGIC_STRING_SETKEEPALIVE "setKeepAlive" #define IOTJS_MAGIC_STRING_SETMULTICASTLOOPBACK "setMulticastLoopback" #define IOTJS_MAGIC_STRING_SETMULTICASTTTL "setMulticastTTL" #define IOTJS_MAGIC_STRING_SETPERIOD "setPeriod" #define IOTJS_MAGIC_STRING_SETTTL "setTTL" #define IOTJS_MAGIC_STRING_SHOULDKEEPALIVE "shouldkeepalive" #define IOTJS_MAGIC_STRING_SHUTDOWN "shutdown" #define IOTJS_MAGIC_STRING_SLICE "slice" #define IOTJS_MAGIC_STRING_SPI "Spi" #define IOTJS_MAGIC_STRING_START "start" #define IOTJS_MAGIC_STRING_STAT "stat" #define IOTJS_MAGIC_STRING_STATUS_MSG "status_msg" #define IOTJS_MAGIC_STRING_STATUS "status" #define IOTJS_MAGIC_STRING_STDERR "stderr" #define IOTJS_MAGIC_STRING_STDOUT "stdout" #define IOTJS_MAGIC_STRING_STOP "stop" #define IOTJS_MAGIC_STRING_TOHEXSTRING "toHexString" #define IOTJS_MAGIC_STRING_TOSTRING "toString" #define IOTJS_MAGIC_STRING_TRANSFERARRAY "transferArray" #define IOTJS_MAGIC_STRING_TRANSFERBUFFER "transferBuffer" #define IOTJS_MAGIC_STRING_UNEXPORT "unexport" #define IOTJS_MAGIC_STRING_UNLINK "unlink" #define IOTJS_MAGIC_STRING_UNREF "unref" #define IOTJS_MAGIC_STRING_UPGRADE "upgrade" #define IOTJS_MAGIC_STRING_URL "url" #define IOTJS_MAGIC_STRING_WRITESYNC "writeSync" #define IOTJS_MAGIC_STRING_WRITEUINT8 "writeUInt8" #define IOTJS_MAGIC_STRING_WRITE "write" #endif /* IOTJS_STRING_CONSTANTS_H */ iotjs-1.0/src/iotjs_module.c000066400000000000000000000042121312466455500161440ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "iotjs_def.h" #include "iotjs_module.h" typedef struct { ModuleKind kind; iotjs_jval_t jmodule; register_func fn_register; } iotjs_module_t; static iotjs_module_t modules[MODULE_COUNT]; #define DECLARE_MODULE_INITIALIZER(upper, Camel, lower) \ iotjs_jval_t Init##Camel(); MAP_MODULE_LIST(DECLARE_MODULE_INITIALIZER) #undef DECLARE_MODULE_INITIALIZER #define INIT_MODULE_LIST(upper, Camel, lower) \ modules[MODULE_##upper].kind = MODULE_##upper; \ modules[MODULE_##upper].jmodule = *iotjs_jval_get_undefined(); \ modules[MODULE_##upper].fn_register = Init##Camel; void iotjs_module_list_init() { MAP_MODULE_LIST(INIT_MODULE_LIST) } #undef INIT_MODULE_LIST #define CLENUP_MODULE_LIST(upper, Camel, lower) \ if (!iotjs_jval_is_undefined(&modules[MODULE_##upper].jmodule)) \ iotjs_jval_destroy(&modules[MODULE_##upper].jmodule); void iotjs_module_list_cleanup() { MAP_MODULE_LIST(CLENUP_MODULE_LIST) } #undef CLENUP_MODULE_LIST const iotjs_jval_t* iotjs_module_initialize_if_necessary(ModuleKind kind) { IOTJS_ASSERT(kind < MODULE_COUNT); IOTJS_ASSERT(&modules[kind].fn_register != NULL); if (iotjs_jval_is_undefined(&modules[kind].jmodule)) { modules[kind].jmodule = modules[kind].fn_register(); } return iotjs_module_get(kind); } const iotjs_jval_t* iotjs_module_get(ModuleKind kind) { IOTJS_ASSERT(kind < MODULE_COUNT); IOTJS_ASSERT(!iotjs_jval_is_undefined(&modules[kind].jmodule)); return &modules[kind].jmodule; } iotjs-1.0/src/iotjs_module.h000066400000000000000000000046311312466455500161560ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef IOTJS_MODULE_H #define IOTJS_MODULE_H #include "iotjs_binding.h" typedef iotjs_jval_t (*register_func)(); #define CONCATENATE(x, ...) x##__VA_ARGS__ #define IF(c) CONCATENATE(IF_, c) #define IF_1(expr) expr #define IF_0(expr) // Check if specific module is enabled #define E(F, UPPER, Camel, lower) \ IF(ENABLE_MODULE_##UPPER)(F(UPPER, Camel, lower)) // List of builtin modules #define MAP_MODULE_LIST(F) \ E(F, ADC, Adc, adc) \ E(F, BLEHCISOCKET, Blehcisocket, blehcisocket) \ E(F, BUFFER, Buffer, buffer) \ E(F, CONSOLE, Console, console) \ E(F, CONSTANTS, Constants, constants) \ E(F, DNS, Dns, dns) \ E(F, FS, Fs, fs) \ E(F, GPIO, Gpio, gpio) \ E(F, HTTPPARSER, Httpparser, httpparser) \ E(F, I2C, I2c, i2c) \ E(F, PROCESS, Process, process) \ E(F, PWM, Pwm, pwm) \ E(F, SPI, Spi, spi) \ E(F, STM32F4DIS, Stm32f4dis, stm32f4dis) \ E(F, TESTDRIVER, Testdriver, testdriver) \ E(F, TCP, Tcp, tcp) \ E(F, TIMER, Timer, timer) \ E(F, UART, Uart, uart) \ E(F, UDP, Udp, udp) #define ENUMDEF_MODULE_LIST(upper, Camel, lower) MODULE_##upper, typedef enum { MAP_MODULE_LIST(ENUMDEF_MODULE_LIST) // enumerate modules MODULE_COUNT, } ModuleKind; #undef ENUMDEF_MODULE_LIST void iotjs_module_list_init(); void iotjs_module_list_cleanup(); const iotjs_jval_t* iotjs_module_initialize_if_necessary(ModuleKind kind); const iotjs_jval_t* iotjs_module_get(ModuleKind kind); #endif /* IOTJS_MODULE_H */ iotjs-1.0/src/iotjs_objectwrap.c000066400000000000000000000044031312466455500170210ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "iotjs_def.h" #include "iotjs_objectwrap.h" void iotjs_jobjectwrap_initialize(iotjs_jobjectwrap_t* jobjectwrap, const iotjs_jval_t* jobject, JNativeInfoType native_info) { IOTJS_VALIDATED_STRUCT_CONSTRUCTOR(iotjs_jobjectwrap_t, jobjectwrap); IOTJS_ASSERT(iotjs_jval_is_object(jobject)); // This wrapper holds pointer to the javascript object but never increases // reference count. _this->jobject = *((iotjs_jval_t*)jobject); // Set native pointer of the object to be this wrapper. // If the object is freed by GC, the wrapper instance should also be freed. iotjs_jval_set_object_native_handle(&_this->jobject, (uintptr_t)jobjectwrap, native_info); } void iotjs_jobjectwrap_destroy(iotjs_jobjectwrap_t* jobjectwrap) { IOTJS_VALIDATABLE_STRUCT_DESTRUCTOR_VALIDATE(iotjs_jobjectwrap_t, jobjectwrap); /* Do nothing on _this->jobject */ } iotjs_jval_t* iotjs_jobjectwrap_jobject(iotjs_jobjectwrap_t* jobjectwrap) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_jobjectwrap_t, jobjectwrap); iotjs_jval_t* jobject = &_this->jobject; IOTJS_ASSERT((uintptr_t)jobjectwrap == iotjs_jval_get_object_native_handle(jobject)); IOTJS_ASSERT(iotjs_jval_is_object(jobject)); return jobject; } iotjs_jobjectwrap_t* iotjs_jobjectwrap_from_jobject( const iotjs_jval_t* jobject) { iotjs_jobjectwrap_t* wrap = (iotjs_jobjectwrap_t*)(iotjs_jval_get_object_native_handle(jobject)); IOTJS_ASSERT(iotjs_jval_is_object(iotjs_jobjectwrap_jobject(wrap))); return wrap; } iotjs-1.0/src/iotjs_objectwrap.h000066400000000000000000000036771312466455500170420ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef IOTJS_OBJECTWRAP_H #define IOTJS_OBJECTWRAP_H #include "iotjs_binding.h" // This wrapper refer javascript object but never increase reference count // If the object is freed by GC, then this wrapper instance will be also freed. typedef struct { iotjs_jval_t jobject; } IOTJS_VALIDATED_STRUCT(iotjs_jobjectwrap_t); void iotjs_jobjectwrap_initialize(iotjs_jobjectwrap_t* jobjectwrap, const iotjs_jval_t* jobject, JNativeInfoType native_info); void iotjs_jobjectwrap_destroy(iotjs_jobjectwrap_t* jobjectwrap); iotjs_jval_t* iotjs_jobjectwrap_jobject(iotjs_jobjectwrap_t* jobjectwrap); iotjs_jobjectwrap_t* iotjs_jobjectwrap_from_jobject( const iotjs_jval_t* jobject); #define IOTJS_DEFINE_NATIVE_HANDLE_INFO(module) \ static const jerry_object_native_info_t module##_native_info = { \ .free_cb = (jerry_object_native_free_callback_t)iotjs_##module##_destroy \ } #define IOTJS_DEFINE_NATIVE_HANDLE_INFO_THIS_MODULE(name) \ static void iotjs_##name##_destroy(iotjs_##name##_t* wrap); \ static const jerry_object_native_info_t this_module_native_info = { \ .free_cb = (jerry_object_native_free_callback_t)iotjs_##name##_destroy \ } #endif /* IOTJS_OBJECTWRAP_H */ iotjs-1.0/src/iotjs_reqwrap.c000066400000000000000000000036631312466455500163510ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "iotjs_def.h" #include "iotjs_reqwrap.h" void iotjs_reqwrap_initialize(iotjs_reqwrap_t* reqwrap, const iotjs_jval_t* jcallback, uv_req_t* request) { IOTJS_VALIDATED_STRUCT_CONSTRUCTOR(iotjs_reqwrap_t, reqwrap); IOTJS_ASSERT(iotjs_jval_is_function(jcallback)); _this->jcallback = iotjs_jval_create_copied(jcallback); _this->request = request; _this->request->data = reqwrap; } void iotjs_reqwrap_destroy(iotjs_reqwrap_t* reqwrap) { IOTJS_VALIDATED_STRUCT_DESTRUCTOR(iotjs_reqwrap_t, reqwrap); iotjs_jval_destroy(&_this->jcallback); } static void iotjs_reqwrap_validate(iotjs_reqwrap_t* reqwrap) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_reqwrap_t, reqwrap); IOTJS_ASSERT(_this->request->data == reqwrap); } const iotjs_jval_t* iotjs_reqwrap_jcallback(iotjs_reqwrap_t* reqwrap) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_reqwrap_t, reqwrap); iotjs_reqwrap_validate(reqwrap); return &_this->jcallback; } uv_req_t* iotjs_reqwrap_req(iotjs_reqwrap_t* reqwrap) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_reqwrap_t, reqwrap); iotjs_reqwrap_validate(reqwrap); return _this->request; } iotjs_reqwrap_t* iotjs_reqwrap_from_request(uv_req_t* req) { iotjs_reqwrap_t* reqwrap = req->data; iotjs_reqwrap_validate(reqwrap); return reqwrap; } iotjs-1.0/src/iotjs_reqwrap.h000066400000000000000000000031501312466455500163450ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef IOTJS_REQWRAP_H #define IOTJS_REQWRAP_H #include #include "iotjs_binding.h" // UV request wrapper. // Wrapping UV request and JavaScript callback. // When an instance of request wrapper is created. it will increase ref count // for JavaScript callback function to prevent it from reclaimed by GC. The // reference count will decrease back when wrapper is being freed. typedef struct { iotjs_jval_t jcallback; uv_req_t* request; } IOTJS_VALIDATED_STRUCT(iotjs_reqwrap_t); void iotjs_reqwrap_initialize(iotjs_reqwrap_t* reqwrap, const iotjs_jval_t* jcallback, uv_req_t* request); void iotjs_reqwrap_destroy(iotjs_reqwrap_t* reqwrap); // To retrieve javascript callback function object. const iotjs_jval_t* iotjs_reqwrap_jcallback(iotjs_reqwrap_t* reqwrap); // To retrieve pointer to uv request. uv_req_t* iotjs_reqwrap_req(iotjs_reqwrap_t* reqwrap); iotjs_reqwrap_t* iotjs_reqwrap_from_request(uv_req_t* req); #endif /* IOTJS_REQWRAP_H */ iotjs-1.0/src/iotjs_string.c000066400000000000000000000057021312466455500161720ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "iotjs_def.h" #include "iotjs_string.h" #include "iotjs_util.h" #include iotjs_string_t iotjs_string_create() { iotjs_string_t str; IOTJS_VALIDATED_STRUCT_CONSTRUCTOR(iotjs_string_t, &str); _this->size = 0; _this->data = NULL; return str; } iotjs_string_t iotjs_string_create_with_size(const char* data, size_t size) { iotjs_string_t str; IOTJS_VALIDATED_STRUCT_CONSTRUCTOR(iotjs_string_t, &str); _this->size = size; if (size > 0) { IOTJS_ASSERT(data != NULL); _this->data = iotjs_buffer_allocate(size); memcpy(_this->data, data, size); } else { _this->data = NULL; } return str; } iotjs_string_t iotjs_string_create_with_buffer(char* buffer, size_t size) { iotjs_string_t str; IOTJS_VALIDATED_STRUCT_CONSTRUCTOR(iotjs_string_t, &str); _this->size = size; if (size > 0) { IOTJS_ASSERT(buffer != NULL); _this->data = buffer; } else { _this->data = NULL; } return str; } void iotjs_string_destroy(iotjs_string_t* str) { IOTJS_VALIDATED_STRUCT_DESTRUCTOR(iotjs_string_t, str); if (_this->data != NULL) { iotjs_buffer_release(_this->data); _this->size = 0; } } bool iotjs_string_is_empty(const iotjs_string_t* str) { const IOTJS_VALIDATED_STRUCT_METHOD(iotjs_string_t, str); return _this->size == 0; } void iotjs_string_make_empty(iotjs_string_t* str) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_string_t, str); if (_this->data != NULL) { iotjs_buffer_release(_this->data); _this->size = 0; _this->data = NULL; } } void iotjs_string_append(iotjs_string_t* str, const char* data, size_t size) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_string_t, str); IOTJS_ASSERT(data != NULL); if (size == 0) { return; } if (_this->data != NULL) { _this->data = iotjs_buffer_reallocate(_this->data, _this->size + size); } else { IOTJS_ASSERT(_this->size == 0); _this->data = iotjs_buffer_allocate(size); } memcpy(_this->data + _this->size, data, size); _this->size += size; } const char* iotjs_string_data(const iotjs_string_t* str) { const IOTJS_VALIDATED_STRUCT_METHOD(iotjs_string_t, str); if (_this->data == NULL) { return ""; } return _this->data; } unsigned iotjs_string_size(const iotjs_string_t* str) { const IOTJS_VALIDATED_STRUCT_METHOD(iotjs_string_t, str); return _this->size; } iotjs-1.0/src/iotjs_string.h000066400000000000000000000027721312466455500162030ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef IOTJS_STRING_H #define IOTJS_STRING_H typedef struct { size_t size; char* data; } IOTJS_VALIDATED_STRUCT(iotjs_string_t); // Create new string iotjs_string_t iotjs_string_create(); iotjs_string_t iotjs_string_create_with_size(const char* data, size_t size); iotjs_string_t iotjs_string_create_with_buffer(char* buffer, size_t size); // Destroy string void iotjs_string_destroy(iotjs_string_t* str); // Check if string is empty bool iotjs_string_is_empty(const iotjs_string_t* str); // Make string empty void iotjs_string_make_empty(iotjs_string_t* str); // Append `data` to tail of the string. void iotjs_string_append(iotjs_string_t* str, const char* data, size_t size); // Returns pointer to the bytes (never returns NULL) const char* iotjs_string_data(const iotjs_string_t* str); unsigned iotjs_string_size(const iotjs_string_t* str); #endif /* IOTJS_STRING_H */ iotjs-1.0/src/iotjs_string_ext.c000066400000000000000000000032531312466455500170510ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "iotjs_def.h" // // strings in iotjs built-in scripts // #include "iotjs_string_ext.inl.h" // // declare string items // #define MAGICSTR_EX_DEF(NAME, STRING) \ static const char jerry_magic_string_ex_##NAME[] = STRING; JERRY_MAGIC_STRING_ITEMS #undef MAGICSTR_EX_DEF // // declare strings length array // static const jerry_length_t magic_string_lengths[] = { #define MAGICSTR_EX_DEF(NAME, STRING) \ (jerry_length_t)(sizeof(jerry_magic_string_ex_##NAME) - 1u), JERRY_MAGIC_STRING_ITEMS #undef MAGICSTR_EX_DEF }; // // declare strings table // static const jerry_char_ptr_t magic_string_items[] = { #define MAGICSTR_EX_DEF(NAME, STRING) \ (const jerry_char_ptr_t) jerry_magic_string_ex_##NAME, JERRY_MAGIC_STRING_ITEMS #undef MAGICSTR_EX_DEF }; void iotjs_register_jerry_magic_string(void) { uint32_t num_magic_string_items = (uint32_t)(sizeof(magic_string_items) / sizeof(jerry_char_ptr_t)); jerry_register_magic_strings(magic_string_items, num_magic_string_items, magic_string_lengths); } iotjs-1.0/src/iotjs_string_ext.h000066400000000000000000000014111312466455500170500ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef IOTJS_STRING_EXT_H #define IOTJS_STRING_EXT_H void iotjs_register_jerry_magic_string(void); #endif /* IOTJS_STRING_EXT_H */ iotjs-1.0/src/iotjs_util.c000066400000000000000000000035701312466455500156420ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "iotjs_def.h" #include "iotjs_util.h" #include #include #include iotjs_string_t iotjs_file_read(const char* path) { FILE* file = fopen(path, "rb"); IOTJS_ASSERT(file != NULL); fseek(file, 0, SEEK_END); long ftell_ret = ftell(file); IOTJS_ASSERT(ftell_ret >= 0); size_t len = (size_t)ftell_ret; fseek(file, 0, SEEK_SET); char* buffer = iotjs_buffer_allocate(len + 1); #if defined(__NUTTX__) || defined(__TIZENRT__) char* ptr = buffer; unsigned nread = 0; unsigned read = 0; while ((nread = fread(ptr, 1, IOTJS_MAX_READ_BUFFER_SIZE, file)) > 0) { read += nread; ptr = buffer + read; } #else size_t read = fread(buffer, 1, len, file); #endif IOTJS_ASSERT(read == len); *(buffer + len) = 0; fclose(file); iotjs_string_t contents = iotjs_string_create_with_buffer(buffer, len); return contents; } char* iotjs_buffer_allocate(size_t size) { char* buffer = (char*)(calloc(size, sizeof(char))); IOTJS_ASSERT(buffer != NULL); return buffer; } char* iotjs_buffer_reallocate(char* buffer, size_t size) { IOTJS_ASSERT(buffer != NULL); return (char*)(realloc(buffer, size)); } void iotjs_buffer_release(char* buffer) { IOTJS_ASSERT(buffer != NULL); free(buffer); } iotjs-1.0/src/iotjs_util.h000066400000000000000000000023171312466455500156450ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef IOTJS_UTIL_H #define IOTJS_UTIL_H #include "iotjs_string.h" // Return value should be released with iotjs_string_destroy() iotjs_string_t iotjs_file_read(const char* path); char* iotjs_buffer_allocate(size_t size); char* iotjs_buffer_reallocate(char* buffer, size_t size); void iotjs_buffer_release(char* buff); #define IOTJS_ALLOC(type) /* Allocate (type)-sized, (type*)-typed memory */ \ (type*)iotjs_buffer_allocate(sizeof(type)) #define IOTJS_RELEASE(ptr) /* Release memory allocated by IOTJS_ALLOC() */ \ iotjs_buffer_release((char*)ptr) #endif /* IOTJS_UTIL_H */ iotjs-1.0/src/js/000077500000000000000000000000001312466455500137205ustar00rootroot00000000000000iotjs-1.0/src/js/adc.js000066400000000000000000000055251312466455500150140ustar00rootroot00000000000000/* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var util = require('util'); var adc = process.binding(process.binding.adc); function Adc() { if (!(this instanceof Adc)) { return new Adc(); } } Adc.prototype.open = function(configuration, callback) { return adcPinOpen(configuration, callback); }; function adcPinOpen(configuration, callback) { var _binding = null; function AdcPin(configuration, callback) { var self = this; if (util.isObject(configuration)) { if (process.platform === 'linux') { if (!util.isString(configuration.device)) { throw new TypeError( 'Bad configuration - device is mandatory and should be String'); } } else if (process.platform === 'nuttx') { if (!util.isNumber(configuration.pin)) { throw new TypeError( 'Bad configuration - pin is mandatory and should be Number'); } } } else { throw new TypeError('Bad arguments - configuration should be Object') } _binding = new adc.Adc(configuration, function(err) { util.isFunction(callback) && callback.call(self, err); }); process.on('exit', (function(self) { return function() { if (!util.isNull(_binding)) { self.closeSync(); } }; })(this)); } AdcPin.prototype.read = function(callback) { var self = this; if (util.isNull(_binding)) { throw new Error('ADC pin is not opened'); } _binding.read(function(err, value) { util.isFunction(callback) && callback.call(self, err, value); }); }; AdcPin.prototype.readSync = function() { if (util.isNull(_binding)) { throw new Error('ADC pin is not opened'); } return _binding.read(); }; AdcPin.prototype.close = function(callback) { var self = this; if (util.isNull(_binding)) { throw new Error('ADC pin is not opened'); } _binding.close(function(err) { util.isFunction(callback) && callback.call(self, err); }); _binding = null; }; AdcPin.prototype.closeSync = function() { if (util.isNull(_binding)) { throw new Error('ADC pin is not opened'); } _binding.close(); _binding = null; }; return new AdcPin(configuration, callback); } module.exports = Adc; iotjs-1.0/src/js/assert.js000066400000000000000000000077231312466455500155700ustar00rootroot00000000000000// Originally from narwhal.js (http://narwhaljs.org) // Copyright (c) 2009 Thomas Robinson <280north.com> // Copyright (c) 2015 Samsung Electronics Co., Ltd. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the 'Software'), to // deal in the Software without restriction, including without limitation the // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or // sell copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. /* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var util = require('util'); function AssertionError(options) { this.name = 'AssertionError'; this.actual = options.actual; this.expected = options.expected; this.operator = options.operator; if (options.message) { this.message = options.message; } else { this.message = getMessage(this); } } util.inherits(AssertionError, Error); function getMessage(assertion) { return JSON.stringify(assertion, ['actual', 'expected', 'operator']); } function assert(value, message) { if (!value) { fail(value, true, message, '=='); } } function fail(actual, expected, message, operator) { throw new AssertionError({ message: message, actual: actual, expected: expected, operator: operator }); } function equal(actual, expected, message) { if (actual != expected) { fail(actual, expected, message, '=='); } } function notEqual(actual, expected, message) { if (actual == expected) { fail(actual, expected, message, '!='); } } function strictEqual(actual, expected, message) { if (actual !== expected) { fail(actual, expected, message, '==='); } } function notStrictEqual(actual, expected, message) { if (actual === expected) { fail(actual, expected, message, '!=='); } } function throws(block, expected, message) { var actual; try { block(); } catch (e) { actual = e; } message = (expected && expected.name ? '(' + expected.name + ').' : '.') + (message ? ' ' + message : '.'); if (!actual) { fail(actual, expected, 'Missing expected exception' + message); } if (expected && !(actual instanceof expected)) { throw actual; } } function doesNotThrow(block, message) { var actual; try { block(); } catch (e) { actual = e; } message = (message ? ' ' + message : ''); if (actual) { fail(actual, null, 'Got unwanted exception.' + message); } } assert.AssertionError = AssertionError; assert.assert = assert; assert.fail = fail; assert.equal = equal; assert.notEqual = notEqual; assert.strictEqual = strictEqual; assert.notStrictEqual = notStrictEqual; assert.throws = throws; assert.doesNotThrow = doesNotThrow; module.exports = assert; iotjs-1.0/src/js/ble.js000066400000000000000000000171561312466455500150320ustar00rootroot00000000000000/* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* Copyright (C) 2015 Sandeep Mistry sandeep.mistry@gmail.com * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ var debug = console.log; // require('debug')('ble'); var events = require('events'); var util = require('util'); var UuidUtil = require('ble_uuid_util'); var PrimaryService = require('ble_primary_service'); var Characteristic = require('ble_characteristic'); var Descriptor = require('ble_descriptor'); var bindings = null; var platform = process.platform; if (platform === 'darwin') { // bindings = require('./mac/bindings'); } else if (platform === 'linux' || platform === 'win32' || platform === 'android') { bindings = require('ble_hci_socket_bindings'); } else { throw new Error('Unsupported platform'); } function Bleno() { this.platform = 'unknown'; this.state = 'unknown'; this.address = 'unknown'; this.rssi = 0; this.mtu = 20; this._bindings = bindings; this._bindings.on('stateChange', this.onStateChange.bind(this)); this._bindings.on('platform', this.onPlatform.bind(this)); this._bindings.on('addressChange', this.onAddressChange.bind(this)); this._bindings.on('advertisingStart', this.onAdvertisingStart.bind(this)); this._bindings.on('advertisingStop', this.onAdvertisingStop.bind(this)); this._bindings.on('servicesSet', this.onServicesSet.bind(this)); this._bindings.on('accept', this.onAccept.bind(this)); this._bindings.on('mtuChange', this.onMtuChange.bind(this)); this._bindings.on('disconnect', this.onDisconnect.bind(this)); this._bindings.on('rssiUpdate', this.onRssiUpdate.bind(this)); this._bindings.init(); } util.inherits(Bleno, events.EventEmitter); Bleno.prototype.PrimaryService = PrimaryService; Bleno.prototype.Characteristic = Characteristic; Bleno.prototype.Descriptor = Descriptor; Bleno.prototype.onPlatform = function(platform) { debug('platform ' + platform); this.platform = platform; }; Bleno.prototype.onStateChange = function(state) { debug('stateChange ' + state); this.state = state; this.emit('stateChange', state); }; Bleno.prototype.onAddressChange = function(address) { debug('addressChange ' + address); this.address = address; }; Bleno.prototype.onAccept = function(clientAddress) { debug('accept ' + clientAddress); this.emit('accept', clientAddress); }; Bleno.prototype.onMtuChange = function(mtu) { debug('mtu ' + mtu); this.mtu = mtu; this.emit('mtuChange', mtu); }; Bleno.prototype.onDisconnect = function(clientAddress) { debug('disconnect' + clientAddress); this.emit('disconnect', clientAddress); }; Bleno.prototype.startAdvertising = function(name, serviceUuids, callback) { if (this.state !== 'poweredOn') { var error = new Error('Could not start advertising, state is ' + this.state + ' (not poweredOn)'); if (typeof callback === 'function') { callback(error); } else { throw error; } } else { if (callback) { this.once('advertisingStart', callback); } var undashedServiceUuids = []; if (serviceUuids && serviceUuids.length) { for (var i = 0; i < serviceUuids.length; i++) { undashedServiceUuids[i] = UuidUtil.removeDashes(serviceUuids[i]); } } this._bindings.startAdvertising(name, undashedServiceUuids); } }; Bleno.prototype.startAdvertisingIBeacon = function(uuid, major, minor, measuredPower, callback) { if (this.state !== 'poweredOn') { var error = new Error('Could not start advertising, state is ' + this.state + ' (not poweredOn)'); if (typeof callback === 'function') { callback(error); } else { throw error; } } else { var undashedUuid = UuidUtil.removeDashes(uuid); var uuidData = new Buffer(undashedUuid, 'hex'); var uuidDataLength = uuidData.length; var iBeaconData = new Buffer(uuidData.length + 5); for (var i = 0; i < uuidDataLength; i++) { iBeaconData[i] = uuidData[i]; } iBeaconData.writeUInt16BE(major, uuidDataLength); iBeaconData.writeUInt16BE(minor, uuidDataLength + 2); iBeaconData.writeInt8(measuredPower, uuidDataLength + 4); if (callback) { this.once('advertisingStart', callback); } debug('iBeacon data = ' + iBeaconData.toString('hex')); this._bindings.startAdvertisingIBeacon(iBeaconData); } }; Bleno.prototype.onAdvertisingStart = function(error) { debug('advertisingStart: ' + error); if (error) { this.emit('advertisingStartError', error); } this.emit('advertisingStart', error); }; Bleno.prototype.startAdvertisingWithEIRData = function(advertisementData, scanData, callback) { if (typeof scanData === 'function') { callback = scanData; scanData = null; } if (this.state !== 'poweredOn') { var error = new Error('Could not advertising scanning, state is ' + this.state + ' (not poweredOn)'); if (typeof callback === 'function') { callback(error); } else { throw error; } } else { if (callback) { this.once('advertisingStart', callback); } this._bindings.startAdvertisingWithEIRData(advertisementData, scanData); } }; Bleno.prototype.stopAdvertising = function(callback) { if (callback) { this.once('advertisingStop', callback); } this._bindings.stopAdvertising(); }; Bleno.prototype.onAdvertisingStop = function() { debug('advertisingStop'); this.emit('advertisingStop'); }; Bleno.prototype.setServices = function(services, callback) { if (callback) { this.once('servicesSet', callback); } this._bindings.setServices(services); }; Bleno.prototype.onServicesSet = function(error) { debug('servicesSet'); if (error) { this.emit('servicesSetError', error); } this.emit('servicesSet', error); }; Bleno.prototype.disconnect = function() { debug('disconnect'); this._bindings.disconnect(); }; Bleno.prototype.updateRssi = function(callback) { if (callback) { this.once('rssiUpdate', function(rssi) { callback(null, rssi); }); } this._bindings.updateRssi(); }; Bleno.prototype.onRssiUpdate = function(rssi) { this.emit('rssiUpdate', rssi); }; module.exports = new Bleno(); iotjs-1.0/src/js/ble_characteristic.js000066400000000000000000000111551312466455500200730ustar00rootroot00000000000000/* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* Copyright (C) 2015 Sandeep Mistry sandeep.mistry@gmail.com * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ var events = require('events'); var util = require('util'); var debug = console.log; // require('debug')('ble_characteristic'); var UuidUtil = require('ble_uuid_util'); function Characteristic(options) { this.uuid = UuidUtil.removeDashes(options.uuid); this.properties = options.properties || []; this.secure = options.secure || []; this.value = options.value || null; this.descriptors = options.descriptors || []; if (this.value && (this.properties.length !== 1 || this.properties[0] !== 'read')) { throw new Error('Characteristics with value can be read only!'); } if (options.onReadRequest) { this.onReadRequest = options.onReadRequest; } if (options.onWriteRequest) { this.onWriteRequest = options.onWriteRequest; } if (options.onSubscribe) { this.onSubscribe = options.onSubscribe; } if (options.onUnsubscribe) { this.onUnsubscribe = options.onUnsubscribe; } if (options.onNotify) { this.onNotify = options.onNotify; } if (options.onIndicate) { this.onIndicate = options.onIndicate; } this.on('readRequest', this.onReadRequest.bind(this)); this.on('writeRequest', this.onWriteRequest.bind(this)); this.on('subscribe', this.onSubscribe.bind(this)); this.on('unsubscribe', this.onUnsubscribe.bind(this)); this.on('notify', this.onNotify.bind(this)); this.on('indicate', this.onIndicate.bind(this)); } util.inherits(Characteristic, events.EventEmitter); Characteristic.RESULT_SUCCESS = Characteristic.prototype.RESULT_SUCCESS = 0x00; Characteristic.RESULT_INVALID_OFFSET = Characteristic.prototype.RESULT_INVALID_OFFSET = 0x07; Characteristic.RESULT_ATTR_NOT_LONG = Characteristic.prototype.RESULT_ATTR_NOT_LONG = 0x0b; Characteristic.RESULT_INVALID_ATTRIBUTE_LENGTH = Characteristic.prototype.RESULT_INVALID_ATTRIBUTE_LENGTH = 0x0d; Characteristic.RESULT_UNLIKELY_ERROR = Characteristic.prototype.RESULT_UNLIKELY_ERROR = 0x0e; Characteristic.prototype.toString = function() { return JSON.stringify({ uuid: this.uuid, properties: this.properties, secure: this.secure, value: this.value, descriptors: this.descriptors }); }; Characteristic.prototype.onReadRequest = function(offset, callback) { callback(this.RESULT_UNLIKELY_ERROR, null); }; Characteristic.prototype.onWriteRequest = function(data, offset, withoutResponse, callback) { callback(this.RESULT_UNLIKELY_ERROR); }; Characteristic.prototype.onSubscribe = function(maxValueSize, updateValueCallback) { this.maxValueSize = maxValueSize; this.updateValueCallback = updateValueCallback; }; Characteristic.prototype.onUnsubscribe = function() { this.maxValueSize = null; this.updateValueCallback = null; }; Characteristic.prototype.onNotify = function() { }; Characteristic.prototype.onIndicate = function() { }; module.exports = Characteristic; iotjs-1.0/src/js/ble_descriptor.js000066400000000000000000000042661312466455500172660ustar00rootroot00000000000000/* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* Copyright (C) 2015 Sandeep Mistry sandeep.mistry@gmail.com * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ var debug = console.log; // require('debug')('descriptor'); var UuidUtil = require('ble_uuid_util'); function Descriptor(options) { this.uuid = UuidUtil.removeDashes(options.uuid); this.value = options.value || new Buffer(0); } Descriptor.prototype.toString = function() { return JSON.stringify({ uuid: this.uuid, value: Buffer.isBuffer(this.value) ? this.value.toString('hex') : this.value }); }; module.exports = Descriptor; iotjs-1.0/src/js/ble_hci_socket.js000066400000000000000000000041131312466455500172120ustar00rootroot00000000000000/* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* Copyright (C) 2015 Sandeep Mistry sandeep.mistry@gmail.com * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ var events = require('events'); var BluetoothHciSocket= process.binding(process.binding.blehcisocket); inherits(BluetoothHciSocket, events.EventEmitter); // extend prototype function inherits(target, source) { for (var k in source.prototype) { target.prototype[k] = source.prototype[k]; } } module.exports = BluetoothHciSocket; iotjs-1.0/src/js/ble_hci_socket_acl_stream.js000066400000000000000000000054131312466455500214100ustar00rootroot00000000000000/* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* Copyright (C) 2015 Sandeep Mistry sandeep.mistry@gmail.com * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ var debug = console.log; // require('debug')('acl-att-stream'); var events = require('events'); var util = require('util'); var crypto = require('ble_hci_socket_crypto'); var Smp = require('ble_hci_socket_smp'); var AclStream = function(hci, handle, localAddressType, localAddress, remoteAddressType, remoteAddress) { this._hci = hci; this._handle = handle; this.encypted = false; this._smp = new Smp(this, localAddressType, localAddress, remoteAddressType, remoteAddress); }; util.inherits(AclStream, events.EventEmitter); AclStream.prototype.write = function(cid, data) { this._hci.writeAclDataPkt(this._handle, cid, data); }; AclStream.prototype.push = function(cid, data) { if (data) { this.emit('data', cid, data); } else { this.emit('end'); } }; AclStream.prototype.pushEncrypt = function(encrypt) { this.encrypted = encrypt ? true : false; this.emit('encryptChange', this.encrypted); }; AclStream.prototype.pushLtkNegReply = function() { this.emit('ltkNegReply'); }; module.exports = AclStream; iotjs-1.0/src/js/ble_hci_socket_bindings.js000066400000000000000000000174301312466455500210750ustar00rootroot00000000000000/* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* Copyright (C) 2015 Sandeep Mistry sandeep.mistry@gmail.com * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ var debug = console.log; // require('debug')('ble_hci-socket_bindings'); var events = require('events'); var util = require('util'); var AclStream = require('ble_hci_socket_acl_stream'); var Hci = require('ble_hci_socket_hci'); var Gap = require('ble_hci_socket_gap'); var Gatt = require('ble_hci_socket_gatt'); var BlenoBindings = function() { this._state = null; this._advertising = false; this._hci = new Hci(); this._gap = new Gap(this._hci); this._gatt = new Gatt(this._hci); this._address = null; this._handle = null; this._aclStream = null; }; util.inherits(BlenoBindings, events.EventEmitter); BlenoBindings.prototype.startAdvertising = function(name, serviceUuids) { this._advertising = true; this._gap.startAdvertising(name, serviceUuids); }; BlenoBindings.prototype.startAdvertisingIBeacon = function(data) { this._advertising = true; this._gap.startAdvertisingIBeacon(data); }; BlenoBindings.prototype.startAdvertisingWithEIRData = function(advertisementData, scanData) { this._advertising = true; this._gap.startAdvertisingWithEIRData(advertisementData, scanData); }; BlenoBindings.prototype.stopAdvertising = function() { this._advertising = false; this._gap.stopAdvertising(); }; BlenoBindings.prototype.setServices = function(services) { this._gatt.setServices(services); this.emit('servicesSet'); }; BlenoBindings.prototype.disconnect = function() { if (this._handle) { debug('disconnect by server'); this._hci.disconnect(this._handle); } }; BlenoBindings.prototype.updateRssi = function() { if (this._handle) { this._hci.readRssi(this._handle); } }; BlenoBindings.prototype.init = function() { this.onSigIntBinded = this.onSigInt.bind(this); process.on('SIGINT', this.onSigIntBinded); process.on('exit', this.onExit.bind(this)); this._gap.on('advertisingStart', this.onAdvertisingStart.bind(this)); this._gap.on('advertisingStop', this.onAdvertisingStop.bind(this)); this._gatt.on('mtuChange', this.onMtuChange.bind(this)); this._hci.on('stateChange', this.onStateChange.bind(this)); this._hci.on('addressChange', this.onAddressChange.bind(this)); this._hci.on('readLocalVersion', this.onReadLocalVersion.bind(this)); this._hci.on('leConnComplete', this.onLeConnComplete.bind(this)); this._hci.on('leConnUpdateComplete', this.onLeConnUpdateComplete.bind(this)); this._hci.on('rssiRead', this.onRssiRead.bind(this)); this._hci.on('disconnComplete', this.onDisconnComplete.bind(this)); this._hci.on('encryptChange', this.onEncryptChange.bind(this)); this._hci.on('leLtkNegReply', this.onLeLtkNegReply.bind(this)); this._hci.on('aclDataPkt', this.onAclDataPkt.bind(this)); this.emit('platform', process.platform); this._hci.init(); }; BlenoBindings.prototype.onStateChange = function(state) { if (this._state === state) { return; } this._state = state; if (state === 'unauthorized') { console.log('bleno warning: adapter state unauthorized, please run as root or with sudo'); console.log(' or see README for information on running without root/sudo:'); console.log(' https://github.com/sandeepmistry/bleno#running-on-linux'); } else if (state === 'unsupported') { console.log('bleno warning: adapter does not support Bluetooth Low Energy (BLE, Bluetooth Smart).'); console.log(' Try to run with environment variable:'); console.log(' [sudo] BLENO_HCI_DEVICE_ID=x node ...'); } this.emit('stateChange', state); }; BlenoBindings.prototype.onAddressChange = function(address) { this.emit('addressChange', address); }; BlenoBindings.prototype.onReadLocalVersion = function(hciVer, hciRev, lmpVer, manufacturer, lmpSubVer) { if (manufacturer === 93) { // Realtek Semiconductor Corporation this._gatt.maxMtu = 23; } }; BlenoBindings.prototype.onAdvertisingStart = function(error) { this.emit('advertisingStart', error); }; BlenoBindings.prototype.onAdvertisingStop = function() { this.emit('advertisingStop'); }; BlenoBindings.prototype.onLeConnComplete = function(status, handle, role, addressType, address, interval, latency, supervisionTimeout, masterClockAccuracy) { if (role !== 1) { // not slave, ignore return; } this._address = address; this._handle = handle; this._aclStream = new AclStream(this._hci, handle, this._hci.addressType, this._hci.address, addressType, address); this._gatt.setAclStream(this._aclStream); this.emit('accept', address); }; BlenoBindings.prototype.onLeConnUpdateComplete = function(handle, interval, latency, supervisionTimeout) { // no-op }; BlenoBindings.prototype.onDisconnComplete = function(handle, reason) { if (this._aclStream) { this._aclStream.push(null, null); } var address = this._address; this._address = null; this._handle = null; this._aclStream = null; if (address) { this.emit('disconnect', address); // TODO: use reason } if (this._advertising) { this._gap.restartAdvertising(); } }; BlenoBindings.prototype.onEncryptChange = function(handle, encrypt) { if (this._handle === handle && this._aclStream) { this._aclStream.pushEncrypt(encrypt); } }; BlenoBindings.prototype.onLeLtkNegReply = function(handle) { if (this._handle === handle && this._aclStream) { this._aclStream.pushLtkNegReply(); } }; BlenoBindings.prototype.onMtuChange = function(mtu) { this.emit('mtuChange', mtu); }; BlenoBindings.prototype.onRssiRead = function(handle, rssi) { this.emit('rssiUpdate', rssi); }; BlenoBindings.prototype.onAclDataPkt = function(handle, cid, data) { if (this._handle === handle && this._aclStream) { this._aclStream.push(cid, data); } }; BlenoBindings.prototype.onSigInt = function() { var sigIntListeners = process.listeners('SIGINT'); if (sigIntListeners[sigIntListeners.length - 1] === this.onSigIntBinded) { // we are the last listener, so exit // this will trigger onExit, and clean up process.exit(1); } }; BlenoBindings.prototype.onExit = function() { this._gap.stopAdvertising(); this.disconnect(); }; module.exports = new BlenoBindings(); iotjs-1.0/src/js/ble_hci_socket_crypto.js000066400000000000000000000057651312466455500206300ustar00rootroot00000000000000/* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* Copyright (C) 2015 Sandeep Mistry sandeep.mistry@gmail.com * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ var crypto = require('ble_hci_socket_crypto'); function r() { return crypto.randomBytes(16); } function c1(k, r, pres, preq, iat, ia, rat, ra) { var p1 = Buffer.concat([ iat, rat, preq, pres ]); var p2 = Buffer.concat([ ra, ia, new Buffer('00000000', 'hex') ]); var res = xor(r, p1); res = e(k, res); res = xor(res, p2); res = e(k, res); return res; } function s1(k, r1, r2) { return e(k, Buffer.concat([ r2.slice(0, 8), r1.slice(0, 8) ])); } function e(key, data) { key = swap(key); data = swap(data); var cipher = crypto.createCipheriv('aes-128-ecb', key, ''); cipher.setAutoPadding(false); return swap(Buffer.concat([ cipher.update(data), cipher.final() ])); } function xor(b1, b2) { var result = new Buffer(b1.length); for (var i = 0; i < b1.length; i++) { //result[i] = b1[i] ^ b2[i]; result.writeUInt8(b1.readUInt8(i) ^ b2.readUInt8(i), i); } return result; } function swap(input) { var output = new Buffer(input.length); for (var i = 0; i < output.length; i++) { //output[i] = input[input.length - i - 1]; output.writeUInt8(input.readUInt8(input.length - i - 1), i); } return output; } module.exports = { r: r, c1: c1, s1: s1, e: e }; iotjs-1.0/src/js/ble_hci_socket_gap.js000066400000000000000000000176771312466455500200640ustar00rootroot00000000000000/* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* Copyright (C) 2015 Sandeep Mistry sandeep.mistry@gmail.com * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ var debug = console.log; // require('debug')('gap'); var events = require('events'); var util = require('util'); var Hci = require('ble_hci_socket_hci'); var isLinux = (process.platform === 'linux'); var isIntelEdison = false; // isLinux && (os.release().indexOf('edison') !== -1); var isYocto = false; //TODO isLinux && (os.release().indexOf('yocto') !== -1); function Gap(hci) { this._hci = hci; this._advertiseState = null; this._hci.on('error', this.onHciError.bind(this)); this._hci.on('leAdvertisingParametersSet', this.onHciLeAdvertisingParametersSet.bind(this)); this._hci.on('leAdvertisingDataSet', this.onHciLeAdvertisingDataSet.bind(this)); this._hci.on('leScanResponseDataSet', this.onHciLeScanResponseDataSet.bind(this)); this._hci.on('leAdvertiseEnableSet', this.onHciLeAdvertiseEnableSet.bind(this)); } util.inherits(Gap, events.EventEmitter); Gap.prototype.startAdvertising = function(name, serviceUuids) { debug('startAdvertising: name = ' + name + ', serviceUuids = ' + JSON.stringify(serviceUuids, null, 2)); var advertisementDataLength = 3; var scanDataLength = 0; var serviceUuids16bit = []; var serviceUuids128bit = []; var i = 0; if (name && name.length) { scanDataLength += 2 + name.length; } if (serviceUuids && serviceUuids.length) { for (i = 0; i < serviceUuids.length; i++) { var serviceUuid = new Buffer(serviceUuids[i].match(/.{1,2}/g).reverse().join(''), 'hex'); if (serviceUuid.length === 2) { serviceUuids16bit.push(serviceUuid); } else if (serviceUuid.length === 16) { serviceUuids128bit.push(serviceUuid); } } } if (serviceUuids16bit.length) { advertisementDataLength += 2 + 2 * serviceUuids16bit.length; } if (serviceUuids128bit.length) { advertisementDataLength += 2 + 16 * serviceUuids128bit.length; } var advertisementData = new Buffer(advertisementDataLength); var scanData = new Buffer(scanDataLength); // flags advertisementData.writeUInt8(2, 0); advertisementData.writeUInt8(0x01, 1); advertisementData.writeUInt8(0x06, 2); var advertisementDataOffset = 3; if (serviceUuids16bit.length) { advertisementData.writeUInt8(1 + 2 * serviceUuids16bit.length, advertisementDataOffset); advertisementDataOffset++; advertisementData.writeUInt8(0x03, advertisementDataOffset); advertisementDataOffset++; for (i = 0; i < serviceUuids16bit.length; i++) { serviceUuids16bit[i].copy(advertisementData, advertisementDataOffset); advertisementDataOffset += serviceUuids16bit[i].length; } } if (serviceUuids128bit.length) { advertisementData.writeUInt8(1 + 16 * serviceUuids128bit.length, advertisementDataOffset); advertisementDataOffset++; advertisementData.writeUInt8(0x06, advertisementDataOffset); advertisementDataOffset++; for (i = 0; i < serviceUuids128bit.length; i++) { serviceUuids128bit[i].copy(advertisementData, advertisementDataOffset); advertisementDataOffset += serviceUuids128bit[i].length; } } // name if (name && name.length) { var nameBuffer = new Buffer(name); scanData.writeUInt8(1 + nameBuffer.length, 0); scanData.writeUInt8(0x08, 1); nameBuffer.copy(scanData, 2); } this.startAdvertisingWithEIRData(advertisementData, scanData); }; Gap.prototype.startAdvertisingIBeacon = function(data) { debug('startAdvertisingIBeacon: data = ' + data.toString('hex')); var dataLength = data.length; var manufacturerDataLength = 4 + dataLength; var advertisementDataLength = 5 + manufacturerDataLength; var scanDataLength = 0; var advertisementData = new Buffer(advertisementDataLength); var scanData = new Buffer(0); // flags advertisementData.writeUInt8(2, 0); advertisementData.writeUInt8(0x01, 1); advertisementData.writeUInt8(0x06, 2); advertisementData.writeUInt8(manufacturerDataLength + 1, 3); advertisementData.writeUInt8(0xff, 4); advertisementData.writeUInt16LE(0x004c, 5); // Apple Company Identifier LE (16 bit) advertisementData.writeUInt8(0x02, 7); // type, 2 => iBeacon advertisementData.writeUInt8(dataLength, 8); data.copy(advertisementData, 9); this.startAdvertisingWithEIRData(advertisementData, scanData); }; Gap.prototype.startAdvertisingWithEIRData = function(advertisementData, scanData) { advertisementData = advertisementData || new Buffer(0); scanData = scanData || new Buffer(0); debug('startAdvertisingWithEIRData: advertisement data = ' + advertisementData.toString('hex') + ', scan data = ' + scanData.toString('hex')); var error = null; if (advertisementData.length > 31) { error = new Error('Advertisement data is over maximum limit of 31 bytes'); } else if (scanData.length > 31) { error = new Error('Scan data is over maximum limit of 31 bytes'); } if (error) { this.emit('advertisingStart', error); } else { this._advertiseState = 'starting'; if (isIntelEdison || isYocto) { // work around for Intel Edison debug('skipping first set of scan response and advertisement data'); } else { this._hci.setScanResponseData(scanData); this._hci.setAdvertisingData(advertisementData); } this._hci.setAdvertiseEnable(true); this._hci.setScanResponseData(scanData); this._hci.setAdvertisingData(advertisementData); } }; Gap.prototype.restartAdvertising = function() { this._advertiseState = 'restarting'; this._hci.setAdvertiseEnable(true); }; Gap.prototype.stopAdvertising = function() { this._advertiseState = 'stopping'; this._hci.setAdvertiseEnable(false); }; Gap.prototype.onHciError = function(error) { }; Gap.prototype.onHciLeAdvertisingParametersSet = function(status) { }; Gap.prototype.onHciLeAdvertisingDataSet = function(status) { }; Gap.prototype.onHciLeScanResponseDataSet = function(status) { }; Gap.prototype.onHciLeAdvertiseEnableSet = function(status) { if (this._advertiseState === 'starting') { this._advertiseState = 'started'; var error = null; if (status) { error = new Error(Hci.STATUS_MAPPER[status] || ('Unknown (' + status + ')')); } this.emit('advertisingStart', error); } else if (this._advertiseState === 'stopping') { this._advertiseState = 'stopped'; this.emit('advertisingStop'); } }; module.exports = Gap; iotjs-1.0/src/js/ble_hci_socket_gatt.js000066400000000000000000001025651312466455500202430ustar00rootroot00000000000000/* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* Copyright (C) 2015 Sandeep Mistry sandeep.mistry@gmail.com * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ /*jshint loopfunc: true */ var debug = console.log; // require('debug')('ble_hci_socket_gatt'); var events = require('events'); var util = require('util'); var ATT_OP_ERROR = 0x01; var ATT_OP_MTU_REQ = 0x02; var ATT_OP_MTU_RESP = 0x03; var ATT_OP_FIND_INFO_REQ = 0x04; var ATT_OP_FIND_INFO_RESP = 0x05; var ATT_OP_FIND_BY_TYPE_REQ = 0x06; var ATT_OP_FIND_BY_TYPE_RESP = 0x07; var ATT_OP_READ_BY_TYPE_REQ = 0x08; var ATT_OP_READ_BY_TYPE_RESP = 0x09; var ATT_OP_READ_REQ = 0x0a; var ATT_OP_READ_RESP = 0x0b; var ATT_OP_READ_BLOB_REQ = 0x0c; var ATT_OP_READ_BLOB_RESP = 0x0d; var ATT_OP_READ_MULTI_REQ = 0x0e; var ATT_OP_READ_MULTI_RESP = 0x0f; var ATT_OP_READ_BY_GROUP_REQ = 0x10; var ATT_OP_READ_BY_GROUP_RESP = 0x11; var ATT_OP_WRITE_REQ = 0x12; var ATT_OP_WRITE_RESP = 0x13; var ATT_OP_WRITE_CMD = 0x52; var ATT_OP_PREP_WRITE_REQ = 0x16; var ATT_OP_PREP_WRITE_RESP = 0x17; var ATT_OP_EXEC_WRITE_REQ = 0x18; var ATT_OP_EXEC_WRITE_RESP = 0x19; var ATT_OP_HANDLE_NOTIFY = 0x1b; var ATT_OP_HANDLE_IND = 0x1d; var ATT_OP_HANDLE_CNF = 0x1e; var ATT_OP_SIGNED_WRITE_CMD = 0xd2; var GATT_PRIM_SVC_UUID = 0x2800; var GATT_INCLUDE_UUID = 0x2802; var GATT_CHARAC_UUID = 0x2803; var GATT_CLIENT_CHARAC_CFG_UUID = 0x2902; var GATT_SERVER_CHARAC_CFG_UUID = 0x2903; var ATT_ECODE_SUCCESS = 0x00; var ATT_ECODE_INVALID_HANDLE = 0x01; var ATT_ECODE_READ_NOT_PERM = 0x02; var ATT_ECODE_WRITE_NOT_PERM = 0x03; var ATT_ECODE_INVALID_PDU = 0x04; var ATT_ECODE_AUTHENTICATION = 0x05; var ATT_ECODE_REQ_NOT_SUPP = 0x06; var ATT_ECODE_INVALID_OFFSET = 0x07; var ATT_ECODE_AUTHORIZATION = 0x08; var ATT_ECODE_PREP_QUEUE_FULL = 0x09; var ATT_ECODE_ATTR_NOT_FOUND = 0x0a; var ATT_ECODE_ATTR_NOT_LONG = 0x0b; var ATT_ECODE_INSUFF_ENCR_KEY_SIZE = 0x0c; var ATT_ECODE_INVAL_ATTR_VALUE_LEN = 0x0d; var ATT_ECODE_UNLIKELY = 0x0e; var ATT_ECODE_INSUFF_ENC = 0x0f; var ATT_ECODE_UNSUPP_GRP_TYPE = 0x10; var ATT_ECODE_INSUFF_RESOURCES = 0x11; var ATT_CID = 0x0004; var Gatt = function() { this.maxMtu = 256; this._mtu = 23; this._preparedWriteRequest = null; this.setServices([]); this.onAclStreamDataBinded = this.onAclStreamData.bind(this); this.onAclStreamEndBinded = this.onAclStreamEnd.bind(this); }; util.inherits(Gatt, events.EventEmitter); Gatt.prototype.setServices = function(services) { var deviceName = process.env.BLENO_DEVICE_NAME || process.platform; // base services and characteristics var allServices = [ { uuid: '1800', characteristics: [ { uuid: '2a00', properties: ['read'], secure: [], value: new Buffer(deviceName), descriptors: [] }, { uuid: '2a01', properties: ['read'], secure: [], value: new Buffer([0x80, 0x00]), descriptors: [] } ] }, { uuid: '1801', characteristics: [ { uuid: '2a05', properties: ['indicate'], secure: [], value: new Buffer([0x00, 0x00, 0x00, 0x00]), descriptors: [] } ] } ].concat(services); this._handles = []; var handle = 0; var i; var j; for (i = 0; i < allServices.length; i++) { var service = allServices[i]; handle++; var serviceHandle = handle; this._handles[serviceHandle] = { type: 'service', uuid: service.uuid, attribute: service, startHandle: serviceHandle // endHandle filled in below }; for (j = 0; j < service.characteristics.length; j++) { var characteristic = service.characteristics[j]; var properties = 0; var secure = 0; if (characteristic.properties.indexOf('read') !== -1) { properties |= 0x02; if (characteristic.secure.indexOf('read') !== -1) { secure |= 0x02; } } if (characteristic.properties.indexOf('writeWithoutResponse') !== -1) { properties |= 0x04; if (characteristic.secure.indexOf('writeWithoutResponse') !== -1) { secure |= 0x04; } } if (characteristic.properties.indexOf('write') !== -1) { properties |= 0x08; if (characteristic.secure.indexOf('write') !== -1) { secure |= 0x08; } } if (characteristic.properties.indexOf('notify') !== -1) { properties |= 0x10; if (characteristic.secure.indexOf('notify') !== -1) { secure |= 0x10; } } if (characteristic.properties.indexOf('indicate') !== -1) { properties |= 0x20; if (characteristic.secure.indexOf('indicate') !== -1) { secure |= 0x20; } } handle++; var characteristicHandle = handle; handle++; var characteristicValueHandle = handle; this._handles[characteristicHandle] = { type: 'characteristic', uuid: characteristic.uuid, properties: properties, secure: secure, attribute: characteristic, startHandle: characteristicHandle, valueHandle: characteristicValueHandle }; this._handles[characteristicValueHandle] = { type: 'characteristicValue', handle: characteristicValueHandle, value: characteristic.value }; if (properties & 0x30) { // notify or indicate // add client characteristic configuration descriptor handle++; var clientCharacteristicConfigurationDescriptorHandle = handle; this._handles[clientCharacteristicConfigurationDescriptorHandle] = { type: 'descriptor', handle: clientCharacteristicConfigurationDescriptorHandle, uuid: '2902', attribute: characteristic, properties: (0x02 | 0x04 | 0x08), // read/write secure: (secure & 0x10) ? (0x02 | 0x04 | 0x08) : 0, value: new Buffer([0x00, 0x00]) }; } for (var k = 0; k < characteristic.descriptors.length; k++) { var descriptor = characteristic.descriptors[k]; handle++; var descriptorHandle = handle; this._handles[descriptorHandle] = { type: 'descriptor', handle: descriptorHandle, uuid: descriptor.uuid, attribute: descriptor, properties: 0x02, // read only secure: 0x00, value: descriptor.value }; } } this._handles[serviceHandle].endHandle = handle; } var debugHandles = []; for (i = 0; i < this._handles.length; i++) { handle = this._handles[i]; debugHandles[i] = {}; for(j in handle) { if (Buffer.isBuffer(handle[j])) { debugHandles[i][j] = handle[j] ? 'Buffer(\'' + handle[j].toString('hex') + '\', \'hex\')' : null; } else if (j !== 'attribute') { debugHandles[i][j] = handle[j]; } } } debug('handles = ' + JSON.stringify(debugHandles, null, 2)); }; Gatt.prototype.setAclStream = function(aclStream) { this._mtu = 23; this._preparedWriteRequest = null; this._aclStream = aclStream; this._aclStream.on('data', this.onAclStreamDataBinded); this._aclStream.on('end', this.onAclStreamEndBinded); }; Gatt.prototype.onAclStreamData = function(cid, data) { if (cid !== ATT_CID) { return; } this.handleRequest(data); }; Gatt.prototype.onAclStreamEnd = function() { this._aclStream.removeListener('data', this.onAclStreamDataBinded); this._aclStream.removeListener('end', this.onAclStreamEndBinded); }; Gatt.prototype.send = function(data) { debug('send: ' + data.toString('hex')); this._aclStream.write(ATT_CID, data); }; Gatt.prototype.errorResponse = function(opcode, handle, status) { var buf = new Buffer(5); buf.writeUInt8(ATT_OP_ERROR, 0); buf.writeUInt8(opcode, 1); buf.writeUInt16LE(handle, 2); buf.writeUInt8(status, 4); return buf; }; Gatt.prototype.handleRequest = function(request) { debug('handing request: ' + request.toString('hex')); var requestType = request.readUInt8(0); //buf[0]; var response = null; switch(requestType) { case ATT_OP_MTU_REQ: response = this.handleMtuRequest(request); break; case ATT_OP_FIND_INFO_REQ: response = this.handleFindInfoRequest(request); break; case ATT_OP_FIND_BY_TYPE_REQ: response = this.handleFindByTypeRequest(request); break; case ATT_OP_READ_BY_TYPE_REQ: response = this.handleReadByTypeRequest(request); break; case ATT_OP_READ_REQ: case ATT_OP_READ_BLOB_REQ: response = this.handleReadOrReadBlobRequest(request); break; case ATT_OP_READ_BY_GROUP_REQ: response = this.handleReadByGroupRequest(request); break; case ATT_OP_WRITE_REQ: case ATT_OP_WRITE_CMD: response = this.handleWriteRequestOrCommand(request); break; case ATT_OP_PREP_WRITE_REQ: response = this.handlePrepareWriteRequest(request); break; case ATT_OP_EXEC_WRITE_REQ: response = this.handleExecuteWriteRequest(request); break; case ATT_OP_HANDLE_CNF: response = this.handleConfirmation(request); break; default: case ATT_OP_READ_MULTI_REQ: case ATT_OP_SIGNED_WRITE_CMD: response = this.errorResponse(requestType, 0x0000, ATT_ECODE_REQ_NOT_SUPP); break; } if (response) { debug('response: ' + response.toString('hex')); this.send(response); } }; Gatt.prototype.handleMtuRequest = function(request) { var mtu = request.readUInt16LE(1); if (mtu < 23) { mtu = 23; } else if (mtu > this.maxMtu) { mtu = this.maxMtu; } this._mtu = mtu; this.emit('mtuChange', this._mtu); var response = new Buffer(3); response.writeUInt8(ATT_OP_MTU_RESP, 0); response.writeUInt16LE(mtu, 1); return response; }; Gatt.prototype.handleFindInfoRequest = function(request) { var response = null; var startHandle = request.readUInt16LE(1); var endHandle = request.readUInt16LE(3); var infos = []; var uuid = null; for (i = startHandle; i <= endHandle; i++) { var handle = this._handles[i]; if (!handle) { break; } uuid = null; if ('service' === handle.type) { uuid = '2800'; } else if ('includedService' === handle.type) { uuid = '2802'; } else if ('characteristic' === handle.type) { uuid = '2803'; } else if ('characteristicValue' === handle.type) { uuid = this._handles[i - 1].uuid; } else if ('descriptor' === handle.type) { uuid = handle.uuid; } if (uuid) { infos.push({ handle: i, uuid: uuid }); } } if (infos.length) { var uuidSize = infos[0].uuid.length / 2; var numInfo = 1; for (i = 1; i < infos.length; i++) { if (infos[0].uuid.length !== infos[i].uuid.length) { break; } numInfo++; } var lengthPerInfo = (uuidSize === 2) ? 4 : 18; var maxInfo = Math.floor((this._mtu - 2) / lengthPerInfo); numInfo = Math.min(numInfo, maxInfo); response = new Buffer(2 + numInfo * lengthPerInfo); //response[0] = ATT_OP_FIND_INFO_RESP; //response[1] = (uuidSize === 2) ? 0x01 : 0x2; response.writeUInt8(ATT_OP_FIND_INFO_RESP, 0); response.writeUInt8((uuidSize === 2) ? 0x01 : 0x2, 1); for (i = 0; i < numInfo; i++) { var info = infos[i]; response.writeUInt16LE(info.handle, 2 + i * lengthPerInfo); uuid = new Buffer(info.uuid.match(/.{1,2}/g).reverse().join(''), 'hex'); for (var j = 0; j < uuid.length; j++) { //response[2 + i * lengthPerInfo + 2 + j] = uuid[j]; response.writeUInt8(uuid[j], 2 + i * lengthPerInfo + 2 + j); } } } else { response = this.errorResponse(ATT_OP_FIND_INFO_REQ, startHandle, ATT_ECODE_ATTR_NOT_FOUND); } return response; }; Gatt.prototype.handleFindByTypeRequest = function(request) { var response = null; var startHandle = request.readUInt16LE(1); var endHandle = request.readUInt16LE(3); var uuid = request.slice(5, 7).toString('hex').match(/.{1,2}/g).reverse().join(''); var value = request.slice(7).toString('hex').match(/.{1,2}/g).reverse().join(''); var handles = []; var handle; for (var i = startHandle; i <= endHandle; i++) { handle = this._handles[i]; if (!handle) { break; } if ('2800' === uuid && handle.type === 'service' && handle.uuid === value) { handles.push({ start: handle.startHandle, end: handle.endHandle }); } } if (handles.length) { var lengthPerHandle = 4; var numHandles = handles.length; var maxHandles = Math.floor((this._mtu - 1) / lengthPerHandle); numHandles = Math.min(numHandles, maxHandles); response = new Buffer(1 + numHandles * lengthPerHandle); //response[0] = ATT_OP_FIND_BY_TYPE_RESP; response.writeUInt8(ATT_OP_FIND_BY_TYPE_RESP, 0); for (i = 0; i < numHandles; i++) { handle = handles[i]; response.writeUInt16LE(handle.start, 1 + i * lengthPerHandle); response.writeUInt16LE(handle.end, 1 + i * lengthPerHandle + 2); } } else { response = this.errorResponse(ATT_OP_FIND_BY_TYPE_REQ, startHandle, ATT_ECODE_ATTR_NOT_FOUND); } return response; }; Gatt.prototype.handleReadByGroupRequest = function(request) { var response = null; var startHandle = request.readUInt16LE(1); var endHandle = request.readUInt16LE(3); var uuid = request.slice(5).toString('hex').match(/.{1,2}/g).reverse().join(''); debug('read by group: startHandle = 0x' + startHandle.toString(16) + ', endHandle = 0x' + endHandle.toString(16) + ', uuid = 0x' + uuid.toString(16)); if ('2800' === uuid || '2802' === uuid) { var services = []; var type = ('2800' === uuid) ? 'service' : 'includedService'; var i; for (i = startHandle; i <= endHandle; i++) { var handle = this._handles[i]; if (!handle) { break; } if (handle.type === type) { services.push(handle); } } if (services.length) { var uuidSize = services[0].uuid.length / 2; var numServices = 1; for (i = 1; i < services.length; i++) { if (services[0].uuid.length !== services[i].uuid.length) { break; } numServices++; } var lengthPerService = (uuidSize === 2) ? 6 : 20; var maxServices = Math.floor((this._mtu - 2) / lengthPerService); numServices = Math.min(numServices, maxServices); response = new Buffer(2 + numServices * lengthPerService); //response[0] = ATT_OP_READ_BY_GROUP_RESP; //response[1] = lengthPerService; response.writeUInt8(ATT_OP_READ_BY_GROUP_RESP, 0); response.writeUInt8(lengthPerService, 1); for (i = 0; i < numServices; i++) { var service = services[i]; response.writeUInt16LE(service.startHandle, 2 + i * lengthPerService); response.writeUInt16LE(service.endHandle, 2 + i * lengthPerService + 2); var serviceUuid = new Buffer(service.uuid.match(/.{1,2}/g).reverse().join(''), 'hex'); for (var j = 0; j < serviceUuid.length; j++) { //response[2 + i * lengthPerService + 4 + j] = serviceUuid[j]; response.writeUInt8(serviceUuid.readUInt8(j), 2 + i * lengthPerService + 4 + j); } } } else { response = this.errorResponse(ATT_OP_READ_BY_GROUP_REQ, startHandle, ATT_ECODE_ATTR_NOT_FOUND); } } else { response = this.errorResponse(ATT_OP_READ_BY_GROUP_REQ, startHandle, ATT_ECODE_UNSUPP_GRP_TYPE); } return response; }; Gatt.prototype.handleReadByTypeRequest = function(request) { var response = null; var startHandle = request.readUInt16LE(1); var endHandle = request.readUInt16LE(3); var uuid = request.slice(5).toString('hex').match(/.{1,2}/g).reverse().join(''); var i; var handle; debug('read by type: startHandle = 0x' + startHandle.toString(16) + ', endHandle = 0x' + endHandle.toString(16) + ', uuid = 0x' + uuid.toString(16)); if ('2803' === uuid) { var characteristics = []; for (i = startHandle; i <= endHandle; i++) { handle = this._handles[i]; if (!handle) { break; } if (handle.type === 'characteristic') { characteristics.push(handle); } } if (characteristics.length) { var uuidSize = characteristics[0].uuid.length / 2; var numCharacteristics = 1; for (i = 1; i < characteristics.length; i++) { if (characteristics[0].uuid.length !== characteristics[i].uuid.length) { break; } numCharacteristics++; } var lengthPerCharacteristic = (uuidSize === 2) ? 7 : 21; var maxCharacteristics = Math.floor((this._mtu - 2) / lengthPerCharacteristic); numCharacteristics = Math.min(numCharacteristics, maxCharacteristics); response = new Buffer(2 + numCharacteristics * lengthPerCharacteristic); //response[0] = ATT_OP_READ_BY_TYPE_RESP; //response[1] = lengthPerCharacteristic; response.writeUInt8(ATT_OP_READ_BY_TYPE_RESP, 0); response.writeUInt8(lengthPerCharacteristic, 1); for (i = 0; i < numCharacteristics; i++) { var characteristic = characteristics[i]; response.writeUInt16LE(characteristic.startHandle, 2 + i * lengthPerCharacteristic); response.writeUInt8(characteristic.properties, 2 + i * lengthPerCharacteristic + 2); response.writeUInt16LE(characteristic.valueHandle, 2 + i * lengthPerCharacteristic + 3); var characteristicUuid = new Buffer(characteristic.uuid.match(/.{1,2}/g).reverse().join(''), 'hex'); for (var j = 0; j < characteristicUuid.length; j++) { //response[2 + i * lengthPerCharacteristic + 5 + j] = characteristicUuid[j]; response.writeUInt8(characteristicUuid.readUInt8(j), 2 + i * lengthPerCharacteristic + 5 + j); } } } else { response = this.errorResponse(ATT_OP_READ_BY_TYPE_REQ, startHandle, ATT_ECODE_ATTR_NOT_FOUND); } } else { var handleAttribute = null; var valueHandle = null; var secure = false; for (i = startHandle; i <= endHandle; i++) { handle = this._handles[i]; if (!handle) { break; } if (handle.type === 'characteristic' && handle.uuid === uuid) { handleAttribute = handle.attribute; valueHandle = handle.valueHandle; secure = handle.secure & 0x02; break; } else if (handle.type === 'descriptor' && handle.uuid === uuid) { valueHandle = i; secure = handle.secure & 0x02; break; } } if (secure && !this._aclStream.encrypted) { response = this.errorResponse(ATT_OP_READ_BY_TYPE_REQ, startHandle, ATT_ECODE_AUTHENTICATION); } else if (valueHandle) { var callback = (function(valueHandle) { return function(result, data) { var callbackResponse = null; if (ATT_ECODE_SUCCESS === result) { var dataLength = Math.min(data.length, this._mtu - 4); callbackResponse = new Buffer(4 + dataLength); //callbackResponse[0] = ATT_OP_READ_BY_TYPE_RESP; //callbackResponse[1] = dataLength + 2; callbackResponse.writeUInt8(ATT_OP_READ_BY_TYPE_RESP, 0); callbackResponse.writeUInt8(dataLength + 2, 1); callbackResponse.writeUInt16LE(valueHandle, 2); for (i = 0; i < dataLength; i++) { //callbackResponse[4 + i] = data[i]; callbackResponse.writeUInt8(data.readUInt8(i), 4 + i); } } else { callbackResponse = this.errorResponse(requestType, valueHandle, result); } debug('read by type response: ' + callbackResponse.toString('hex')); this.send(callbackResponse); }.bind(this); }.bind(this))(valueHandle); var data = this._handles[valueHandle].value; if (data) { callback(ATT_ECODE_SUCCESS, data); } else if (handleAttribute) { handleAttribute.emit('readRequest', 0, callback); } else { callback(ATT_ECODE_UNLIKELY); } } else { response = this.errorResponse(ATT_OP_READ_BY_TYPE_REQ, startHandle, ATT_ECODE_ATTR_NOT_FOUND); } } return response; }; Gatt.prototype.handleReadOrReadBlobRequest = function(request) { var response = null; //var requestType = request[0]; var requestType = request.readUInt8(0); var valueHandle = request.readUInt16LE(1); var offset = (requestType === ATT_OP_READ_BLOB_REQ) ? request.readUInt16LE(3) : 0; var handle = this._handles[valueHandle]; if (handle) { var result = null; var data = null; var handleType = handle.type; var callback = (function(requestType, valueHandle) { return function(result, data) { var callbackResponse = null; if (ATT_ECODE_SUCCESS === result) { var dataLength = Math.min(data.length, this._mtu - 1); callbackResponse = new Buffer(1 + dataLength); //callbackResponse[0] = (requestType === ATT_OP_READ_BLOB_REQ) ? ATT_OP_READ_BLOB_RESP : ATT_OP_READ_RESP; callbackResponse.writeUInt8((requestType === ATT_OP_READ_BLOB_REQ) ? ATT_OP_READ_BLOB_RESP : ATT_OP_READ_RESP, 0); for (i = 0; i < dataLength; i++) { //callbackResponse[1 + i] = data[i]; callbackResponse.writeUInt8(data.readUInt8(i), 1 + i); } } else { callbackResponse = this.errorResponse(requestType, valueHandle, result); } debug('read response: ' + callbackResponse.toString('hex')); this.send(callbackResponse); }.bind(this); }.bind(this))(requestType, valueHandle); if (handleType === 'service' || handleType === 'includedService') { result = ATT_ECODE_SUCCESS; data = new Buffer(handle.uuid.match(/.{1,2}/g).reverse().join(''), 'hex'); } else if (handleType === 'characteristic') { var uuid = new Buffer(handle.uuid.match(/.{1,2}/g).reverse().join(''), 'hex'); result = ATT_ECODE_SUCCESS; data = new Buffer(3 + uuid.length); data.writeUInt8(handle.properties, 0); data.writeUInt16LE(handle.valueHandle, 1); for (i = 0; i < uuid.length; i++) { //data[i + 3] = uuid[i]; data.writeUInt8(uuid.readUInt8(i), i + 3); } } else if (handleType === 'characteristicValue' || handleType === 'descriptor') { var handleProperties = handle.properties; var handleSecure = handle.secure; var handleAttribute = handle.attribute; if (handleType === 'characteristicValue') { handleProperties = this._handles[valueHandle - 1].properties; handleSecure = this._handles[valueHandle - 1].secure; handleAttribute = this._handles[valueHandle - 1].attribute; } if (handleProperties & 0x02) { if (handleSecure & 0x02 && !this._aclStream.encrypted) { result = ATT_ECODE_AUTHENTICATION; } else { data = handle.value; if (data) { result = ATT_ECODE_SUCCESS; } else { handleAttribute.emit('readRequest', offset, callback); } } } else { result = ATT_ECODE_READ_NOT_PERM; // non-readable } } if (data && typeof data === 'string') { data = new Buffer(data); } if (result === ATT_ECODE_SUCCESS && data && offset) { if (data.length < offset) { errorCode = ATT_ECODE_INVALID_OFFSET; data = null; } else { data = data.slice(offset); } } if (result !== null) { callback(result, data); } } else { response = this.errorResponse(requestType, valueHandle, ATT_ECODE_INVALID_HANDLE); } return response; }; Gatt.prototype.handleWriteRequestOrCommand = function(request) { var response = null; //var requestType = request[0]; var requestType = request.readUInt8(0); var withoutResponse = (requestType === ATT_OP_WRITE_CMD); var valueHandle = request.readUInt16LE(1); var data = request.slice(3); var offset = 0; var handle = this._handles[valueHandle]; if (handle) { if (handle.type === 'characteristicValue') { handle = this._handles[valueHandle - 1]; } var handleProperties = handle.properties; var handleSecure = handle.secure; if (handleProperties && (withoutResponse ? (handleProperties & 0x04) : (handleProperties & 0x08))) { var callback = (function(requestType, valueHandle, withoutResponse) { return function(result) { if (!withoutResponse) { var callbackResponse = null; if (ATT_ECODE_SUCCESS === result) { callbackResponse = new Buffer([ATT_OP_WRITE_RESP]); } else { callbackResponse = this.errorResponse(requestType, valueHandle, result); } debug('write response: ' + callbackResponse.toString('hex')); this.send(callbackResponse); } }.bind(this); }.bind(this))(requestType, valueHandle, withoutResponse); if (handleSecure & (withoutResponse ? 0x04 : 0x08) && !this._aclStream.encrypted) { response = this.errorResponse(requestType, valueHandle, ATT_ECODE_AUTHENTICATION); } else if (handle.type === 'descriptor' || handle.uuid === '2902') { var result = null; if (data.length !== 2) { result = ATT_ECODE_INVAL_ATTR_VALUE_LEN; } else { var value = data.readUInt16LE(0); var handleAttribute = handle.attribute; handle.value = data; if (value & 0x0003) { var updateValueCallback = (function(valueHandle, attribute) { return function(data) { var dataLength = Math.min(data.length, this._mtu - 3); var useNotify = attribute.properties.indexOf('notify') !== -1; var useIndicate = attribute.properties.indexOf('indicate') !== -1; var i; if (useNotify) { var notifyMessage = new Buffer(3 + dataLength); notifyMessage.writeUInt8(ATT_OP_HANDLE_NOTIFY, 0); notifyMessage.writeUInt16LE(valueHandle, 1); for (i = 0; i < dataLength; i++) { //notifyMessage[3 + i] = data[i]; notifyMessage.writeUInt8(data.readUInt8(i), 3 + i); } debug('notify message: ' + notifyMessage.toString('hex')); this.send(notifyMessage); attribute.emit('notify'); } else if (useIndicate) { var indicateMessage = new Buffer(3 + dataLength); indicateMessage.writeUInt8(ATT_OP_HANDLE_IND, 0); indicateMessage.writeUInt16LE(valueHandle, 1); for (i = 0; i < dataLength; i++) { //indicateMessage[3 + i] = data[i]; indicateMessage.writeUInt8(data.readUInt8(i), 3 + i); } this._lastIndicatedAttribute = attribute; debug('indicate message: ' + indicateMessage.toString('hex')); this.send(indicateMessage); } }.bind(this); }.bind(this))(valueHandle - 1, handleAttribute); if (handleAttribute.emit) { handleAttribute.emit('subscribe', this._mtu - 3, updateValueCallback); } } else { handleAttribute.emit('unsubscribe'); } result = ATT_ECODE_SUCCESS; } callback(result); } else { handle.attribute.emit('writeRequest', data, offset, withoutResponse, callback); } } else { response = this.errorResponse(requestType, valueHandle, ATT_ECODE_WRITE_NOT_PERM); } } else { response = this.errorResponse(requestType, valueHandle, ATT_ECODE_INVALID_HANDLE); } return response; }; Gatt.prototype.handlePrepareWriteRequest = function(request) { var response = null; //var requestType = request[0]; var requestType = request.readUInt8(0); var valueHandle = request.readUInt16LE(1); var offset = request.readUInt16LE(3); var data = request.slice(5); var handle = this._handles[valueHandle]; if (handle) { if (handle.type === 'characteristicValue') { handle = this._handles[valueHandle - 1]; var handleProperties = handle.properties; var handleSecure = handle.secure; if (handleProperties && (handleProperties & 0x08)) { if ((handleSecure & 0x08) && !this._aclStream.encrypted) { response = this.errorResponse(requestType, valueHandle, ATT_ECODE_AUTHENTICATION); } else if (this._preparedWriteRequest) { if (this._preparedWriteRequest.handle !== handle) { response = this.errorResponse(requestType, valueHandle, ATT_ECODE_UNLIKELY); } else if (offset === (this._preparedWriteRequest.offset + this._preparedWriteRequest.data.length)) { this._preparedWriteRequest.data = Buffer.concat([ this._preparedWriteRequest.data, data ]); response = new Buffer(request.length); request.copy(response); //response[0] = ATT_OP_PREP_WRITE_RESP; response.writeUInt8(ATT_OP_PREP_WRITE_RESP, 0); } else { response = this.errorResponse(requestType, valueHandle, ATT_ECODE_INVALID_OFFSET); } } else { this._preparedWriteRequest = { handle: handle, valueHandle: valueHandle, offset: offset, data: data }; response = new Buffer(request.length); request.copy(response); // response[0] = ATT_OP_PREP_WRITE_RESP; response.writeUInt8(ATT_OP_PREP_WRITE_RESP, 0); } } else { response = this.errorResponse(requestType, valueHandle, ATT_ECODE_WRITE_NOT_PERM); } } else { response = this.errorResponse(requestType, valueHandle, ATT_ECODE_ATTR_NOT_LONG); } } else { response = this.errorResponse(requestType, valueHandle, ATT_ECODE_INVALID_HANDLE); } return response; }; Gatt.prototype.handleExecuteWriteRequest = function(request) { var response = null; //var requestType = request[0]; //var flag = request[1]; var requestType = request.readUInt8(0); var flag = request.readUInt8(1); if (this._preparedWriteRequest) { var valueHandle = this._preparedWriteRequest.valueHandle; if (flag === 0x00) { response = new Buffer([ATT_OP_EXEC_WRITE_RESP]); } else if (flag === 0x01) { var callback = (function(requestType, valueHandle) { return function(result) { var callbackResponse = null; if (ATT_ECODE_SUCCESS === result) { callbackResponse = new Buffer([ATT_OP_EXEC_WRITE_RESP]); } else { callbackResponse = this.errorResponse(requestType, valueHandle, result); } debug('execute write response: ' + callbackResponse.toString('hex')); this.send(callbackResponse); }.bind(this); }.bind(this))(requestType, this._preparedWriteRequest.valueHandle); this._preparedWriteRequest.handle.attribute.emit('writeRequest', this._preparedWriteRequest.data, this._preparedWriteRequest.offset, false, callback); } else { response = this.errorResponse(requestType, 0x0000, ATT_ECODE_UNLIKELY); } this._preparedWriteRequest = null; } else { response = this.errorResponse(requestType, 0x0000, ATT_ECODE_UNLIKELY); } return response; }; Gatt.prototype.handleConfirmation = function(request) { if (this._lastIndicatedAttribute) { if (this._lastIndicatedAttribute.emit) { this._lastIndicatedAttribute.emit('indicate'); } this._lastIndicatedAttribute = null; } }; module.exports = Gatt; iotjs-1.0/src/js/ble_hci_socket_hci.js000066400000000000000000000451331312466455500200440ustar00rootroot00000000000000/* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* Copyright (C) 2015 Sandeep Mistry sandeep.mistry@gmail.com * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ var debug = console.log; // require('debug')('ble_hci'); var events = require('events'); var util = require('util'); var BluetoothHciSocket = require('ble_hci_socket'); var HCI_COMMAND_PKT = 0x01; var HCI_ACLDATA_PKT = 0x02; var HCI_EVENT_PKT = 0x04; var ACL_START_NO_FLUSH = 0x00; var ACL_CONT = 0x01; var ACL_START = 0x02; var EVT_DISCONN_COMPLETE = 0x05; var EVT_ENCRYPT_CHANGE = 0x08; var EVT_CMD_COMPLETE = 0x0e; var EVT_CMD_STATUS = 0x0f; var EVT_LE_META_EVENT = 0x3e; var EVT_LE_CONN_COMPLETE = 0x01; var EVT_LE_CONN_UPDATE_COMPLETE = 0x03; var OGF_LINK_CTL = 0x01; var OCF_DISCONNECT = 0x0006; var OGF_HOST_CTL = 0x03; var OCF_SET_EVENT_MASK = 0x0001; var OCF_RESET = 0x0003; var OCF_READ_LE_HOST_SUPPORTED = 0x006c; var OCF_WRITE_LE_HOST_SUPPORTED = 0x006d; var OGF_INFO_PARAM = 0x04; var OCF_READ_LOCAL_VERSION = 0x0001; var OCF_READ_BD_ADDR = 0x0009; var OGF_STATUS_PARAM = 0x05; var OCF_READ_RSSI = 0x0005; var OGF_LE_CTL = 0x08; var OCF_LE_SET_EVENT_MASK = 0x0001; var OCF_LE_SET_ADVERTISING_PARAMETERS = 0x0006; var OCF_LE_SET_ADVERTISING_DATA = 0x0008; var OCF_LE_SET_SCAN_RESPONSE_DATA = 0x0009; var OCF_LE_SET_ADVERTISE_ENABLE = 0x000a; var OCF_LE_LTK_NEG_REPLY = 0x001B; var DISCONNECT_CMD = OCF_DISCONNECT | OGF_LINK_CTL << 10; var SET_EVENT_MASK_CMD = OCF_SET_EVENT_MASK | OGF_HOST_CTL << 10; var RESET_CMD = OCF_RESET | OGF_HOST_CTL << 10; var READ_LE_HOST_SUPPORTED_CMD = OCF_READ_LE_HOST_SUPPORTED | OGF_HOST_CTL << 10; var WRITE_LE_HOST_SUPPORTED_CMD = OCF_WRITE_LE_HOST_SUPPORTED | OGF_HOST_CTL << 10; var READ_LOCAL_VERSION_CMD = OCF_READ_LOCAL_VERSION | (OGF_INFO_PARAM << 10); var READ_BD_ADDR_CMD = OCF_READ_BD_ADDR | (OGF_INFO_PARAM << 10); var READ_RSSI_CMD = OCF_READ_RSSI | OGF_STATUS_PARAM << 10; var LE_SET_EVENT_MASK_CMD = OCF_LE_SET_EVENT_MASK | OGF_LE_CTL << 10; var LE_SET_ADVERTISING_PARAMETERS_CMD = OCF_LE_SET_ADVERTISING_PARAMETERS | OGF_LE_CTL << 10; var LE_SET_ADVERTISING_DATA_CMD = OCF_LE_SET_ADVERTISING_DATA | OGF_LE_CTL << 10; var LE_SET_SCAN_RESPONSE_DATA_CMD = OCF_LE_SET_SCAN_RESPONSE_DATA | OGF_LE_CTL << 10; var LE_SET_ADVERTISE_ENABLE_CMD = OCF_LE_SET_ADVERTISE_ENABLE | OGF_LE_CTL << 10; var LE_LTK_NEG_REPLY_CMD = OCF_LE_LTK_NEG_REPLY | OGF_LE_CTL << 10; var HCI_OE_USER_ENDED_CONNECTION = 0x13; var STATUS_MAPPER = require('ble_hci_socket_hci_status'); var Hci = function() { this._socket = new BluetoothHciSocket(); this._isDevUp = null; this._state = null; this._deviceId = null; this._handleBuffers = {}; this.on('stateChange', this.onStateChange.bind(this)); }; util.inherits(Hci, events.EventEmitter); Hci.STATUS_MAPPER = STATUS_MAPPER; Hci.prototype.init = function() { this._socket.on('data', this.onSocketData.bind(this)); this._socket.on('error', this.onSocketError.bind(this)); var deviceId = process.env.BLENO_HCI_DEVICE_ID ? parseInt(process.env.BLENO_HCI_DEVICE_ID) : undefined; if (process.env.HCI_CHANNEL_USER) { this._deviceId = this._socket.bindUser(deviceId); this._socket.start(); this.reset(); } else { this._deviceId = this._socket.bindRaw(deviceId); this._socket.start(); this.pollIsDevUp(); } }; Hci.prototype.pollIsDevUp = function() { var isDevUp = this._socket.isDevUp(); if (this._isDevUp !== isDevUp) { if (isDevUp) { this.setSocketFilter(); this.setEventMask(); this.setLeEventMask(); this.readLocalVersion(); this.writeLeHostSupported(); this.readLeHostSupported(); this.readBdAddr(); } else { this.emit('stateChange', 'poweredOff'); } this._isDevUp = isDevUp; } setTimeout(this.pollIsDevUp.bind(this), 1000); }; Hci.prototype.setSocketFilter = function() { var filter = new Buffer(14); var typeMask = (1 << HCI_EVENT_PKT)| (1 << HCI_ACLDATA_PKT); var eventMask1 = (1 << EVT_DISCONN_COMPLETE) | (1 << EVT_ENCRYPT_CHANGE) | (1 << EVT_CMD_COMPLETE) | (1 << EVT_CMD_STATUS); var eventMask2 = (1 << (EVT_LE_META_EVENT - 32)); var opcode = 0; filter.writeUInt32LE(typeMask, 0); filter.writeUInt32LE(eventMask1, 4); filter.writeUInt32LE(eventMask2, 8); filter.writeUInt16LE(opcode, 12); debug('setting filter to: ' + filter.toString('hex')); this._socket.setFilter(filter); }; Hci.prototype.setEventMask = function() { var cmd = new Buffer(12); var eventMask = new Buffer('fffffbff07f8bf3d', 'hex'); // header cmd.writeUInt8(HCI_COMMAND_PKT, 0); cmd.writeUInt16LE(SET_EVENT_MASK_CMD, 1); // length cmd.writeUInt8(eventMask.length, 3); eventMask.copy(cmd, 4); debug('set event mask - writing: ' + cmd.toString('hex')); this._socket.write(cmd); }; Hci.prototype.reset = function() { var cmd = new Buffer(4); // header cmd.writeUInt8(HCI_COMMAND_PKT, 0); cmd.writeUInt16LE(OCF_RESET | OGF_HOST_CTL << 10, 1); // length cmd.writeUInt8(0x00, 3); debug('reset - writing: ' + cmd.toString('hex')); this._socket.write(cmd); }; Hci.prototype.readLeHostSupported = function() { var cmd = new Buffer(4); // header cmd.writeUInt8(HCI_COMMAND_PKT, 0); cmd.writeUInt16LE(READ_LE_HOST_SUPPORTED_CMD, 1); // length cmd.writeUInt8(0x00, 3); debug('read LE host supported - writing: ' + cmd.toString('hex')); this._socket.write(cmd); }; Hci.prototype.writeLeHostSupported = function() { var cmd = new Buffer(6); // header cmd.writeUInt8(HCI_COMMAND_PKT, 0); cmd.writeUInt16LE(WRITE_LE_HOST_SUPPORTED_CMD, 1); // length cmd.writeUInt8(0x02, 3); // data cmd.writeUInt8(0x01, 4); // le cmd.writeUInt8(0x00, 5); // simul debug('write LE host supported - writing: ' + cmd.toString('hex')); this._socket.write(cmd); }; Hci.prototype.readLocalVersion = function() { var cmd = new Buffer(4); // header cmd.writeUInt8(HCI_COMMAND_PKT, 0); cmd.writeUInt16LE(READ_LOCAL_VERSION_CMD, 1); // length cmd.writeUInt8(0x0, 3); debug('read local version - writing: ' + cmd.toString('hex')); this._socket.write(cmd); }; Hci.prototype.readBdAddr = function() { var cmd = new Buffer(4); // header cmd.writeUInt8(HCI_COMMAND_PKT, 0); cmd.writeUInt16LE(READ_BD_ADDR_CMD, 1); // length cmd.writeUInt8(0x0, 3); debug('read bd addr - writing: ' + cmd.toString('hex')); this._socket.write(cmd); }; Hci.prototype.setLeEventMask = function() { var cmd = new Buffer(12); var leEventMask = new Buffer('1f00000000000000', 'hex'); // header cmd.writeUInt8(HCI_COMMAND_PKT, 0); cmd.writeUInt16LE(LE_SET_EVENT_MASK_CMD, 1); // length cmd.writeUInt8(leEventMask.length, 3); leEventMask.copy(cmd, 4); debug('set le event mask - writing: ' + cmd.toString('hex')); this._socket.write(cmd); }; Hci.prototype.setAdvertisingParameters = function() { var cmd = new Buffer(19); // header cmd.writeUInt8(HCI_COMMAND_PKT, 0); cmd.writeUInt16LE(LE_SET_ADVERTISING_PARAMETERS_CMD, 1); // length cmd.writeUInt8(15, 3); var advertisementInterval = Math.floor((process.env.BLENO_ADVERTISING_INTERVAL ? parseInt(process.env.BLENO_ADVERTISING_INTERVAL) : 100) * 1.6); // data cmd.writeUInt16LE(advertisementInterval, 4); // min interval cmd.writeUInt16LE(advertisementInterval, 6); // max interval cmd.writeUInt8(0x00, 8); // adv type cmd.writeUInt8(0x00, 9); // own addr typ cmd.writeUInt8(0x00, 10); // direct addr type (new Buffer('000000000000', 'hex')).copy(cmd, 11); // direct addr cmd.writeUInt8(0x07, 17); cmd.writeUInt8(0x00, 18); debug('set advertisement parameters - writing: ' + cmd.toString('hex')); this._socket.write(cmd); }; Hci.prototype.setAdvertisingData = function(data) { var cmd = new Buffer(36); cmd.fill(0x00); // header cmd.writeUInt8(HCI_COMMAND_PKT, 0); cmd.writeUInt16LE(LE_SET_ADVERTISING_DATA_CMD, 1); // length cmd.writeUInt8(32, 3); // data cmd.writeUInt8(data.length, 4); data.copy(cmd, 5); debug('set advertisement data - writing: ' + cmd.toString('hex')); this._socket.write(cmd); }; Hci.prototype.setScanResponseData = function(data) { var cmd = new Buffer(36); cmd.fill(0x00); // header cmd.writeUInt8(HCI_COMMAND_PKT, 0); cmd.writeUInt16LE(LE_SET_SCAN_RESPONSE_DATA_CMD, 1); // length cmd.writeUInt8(32, 3); // data cmd.writeUInt8(data.length, 4); data.copy(cmd, 5); debug('set scan response data - writing: ' + cmd.toString('hex')); this._socket.write(cmd); }; Hci.prototype.setAdvertiseEnable = function(enabled) { var cmd = new Buffer(5); // header cmd.writeUInt8(HCI_COMMAND_PKT, 0); cmd.writeUInt16LE(LE_SET_ADVERTISE_ENABLE_CMD, 1); // length cmd.writeUInt8(0x01, 3); // data cmd.writeUInt8(enabled ? 0x01 : 0x00, 4); // enable: 0 -> disabled, 1 -> enabled debug('set advertise enable - writing: ' + cmd.toString('hex')); this._socket.write(cmd); }; Hci.prototype.disconnect = function(handle, reason) { var cmd = new Buffer(7); reason = reason || HCI_OE_USER_ENDED_CONNECTION; // header cmd.writeUInt8(HCI_COMMAND_PKT, 0); cmd.writeUInt16LE(DISCONNECT_CMD, 1); // length cmd.writeUInt8(0x03, 3); // data cmd.writeUInt16LE(handle, 4); // handle cmd.writeUInt8(reason, 6); // reason debug('disconnect - writing: ' + cmd.toString('hex')); this._socket.write(cmd); }; Hci.prototype.readRssi = function(handle) { var cmd = new Buffer(6); // header cmd.writeUInt8(HCI_COMMAND_PKT, 0); cmd.writeUInt16LE(READ_RSSI_CMD, 1); // length cmd.writeUInt8(0x02, 3); // data cmd.writeUInt16LE(handle, 4); // handle debug('read rssi - writing: ' + cmd.toString('hex')); this._socket.write(cmd); }; Hci.prototype.writeAclDataPkt = function(handle, cid, data) { var pkt = new Buffer(9 + data.length); // header pkt.writeUInt8(HCI_ACLDATA_PKT, 0); pkt.writeUInt16LE(handle | ACL_START_NO_FLUSH << 12, 1); pkt.writeUInt16LE(data.length + 4, 3); // data length 1 pkt.writeUInt16LE(data.length, 5); // data length 2 pkt.writeUInt16LE(cid, 7); data.copy(pkt, 9); debug('write acl data pkt - writing: ' + pkt.toString('hex')); this._socket.write(pkt); }; Hci.prototype.onSocketData = function(data) { debug('onSocketData: ' + data.toString('hex')); var eventType = data.readUInt8(0); var handle; debug('\tevent type = ' + eventType); if (HCI_EVENT_PKT === eventType) { var subEventType = data.readUInt8(1); debug('\tsub event type = ' + subEventType); if (subEventType === EVT_DISCONN_COMPLETE) { handle = data.readUInt16LE(4); var reason = data.readUInt8(6); debug('\t\thandle = ' + handle); debug('\t\treason = ' + reason); this.emit('disconnComplete', handle, reason); } else if (subEventType === EVT_ENCRYPT_CHANGE) { handle = data.readUInt16LE(4); var encrypt = data.readUInt8(6); debug('\t\thandle = ' + handle); debug('\t\tencrypt = ' + encrypt); this.emit('encryptChange', handle, encrypt); } else if (subEventType === EVT_CMD_COMPLETE) { var cmd = data.readUInt16LE(4); var status = data.readUInt8(6); var result = data.slice(7); debug('\t\tcmd = ' + cmd); debug('\t\tstatus = ' + status); debug('\t\tresult = ' + result.toString('hex')); this.processCmdCompleteEvent(cmd, status, result); } else if (subEventType === EVT_LE_META_EVENT) { var leMetaEventType = data.readUInt8(3); var leMetaEventStatus = data.readUInt8(4); var leMetaEventData = data.slice(5); debug('\t\tLE meta event type = ' + leMetaEventType); debug('\t\tLE meta event status = ' + leMetaEventStatus); debug('\t\tLE meta event data = ' + leMetaEventData.toString('hex')); this.processLeMetaEvent(leMetaEventType, leMetaEventStatus, leMetaEventData); } } else if (HCI_ACLDATA_PKT === eventType) { var flags = data.readUInt16LE(1) >> 12; handle = data.readUInt16LE(1) & 0x0fff; if (ACL_START === flags) { var cid = data.readUInt16LE(7); var length = data.readUInt16LE(5); var pktData = data.slice(9); debug('\t\tcid = ' + cid); if (length === pktData.length) { debug('\t\thandle = ' + handle); debug('\t\tdata = ' + pktData.toString('hex')); this.emit('aclDataPkt', handle, cid, pktData); } else { this._handleBuffers[handle] = { length: length, cid: cid, data: pktData }; } } else if (ACL_CONT === flags) { if (!this._handleBuffers[handle] || !this._handleBuffers[handle].data) { return; } this._handleBuffers[handle].data = Buffer.concat([ this._handleBuffers[handle].data, data.slice(5) ]); if (this._handleBuffers[handle].data.length === this._handleBuffers[handle].length) { this.emit('aclDataPkt', handle, this._handleBuffers[handle].cid, this._handleBuffers[handle].data); delete this._handleBuffers[handle]; } } } }; Hci.prototype.onSocketError = function(error) { debug('onSocketError: ' + error.message); if (error.message === 'Operation not permitted') { this.emit('stateChange', 'unauthorized'); } else if (error.message === 'Network is down') { // no-op } }; Hci.prototype.processCmdCompleteEvent = function(cmd, status, result) { var handle; if (cmd === RESET_CMD) { this.setEventMask(); this.setLeEventMask(); this.readLocalVersion(); this.writeLeHostSupported(); this.readLeHostSupported(); this.readBdAddr(); } else if (cmd === READ_LE_HOST_SUPPORTED_CMD) { if (status === 0) { var le = result.readUInt8(0); var simul = result.readUInt8(1); debug('\t\t\tle = ' + le); debug('\t\t\tsimul = ' + simul); } } else if (cmd === READ_LOCAL_VERSION_CMD) { var hciVer = result.readUInt8(0); var hciRev = result.readUInt16LE(1); var lmpVer = result.readInt8(3); var manufacturer = result.readUInt16LE(4); var lmpSubVer = result.readUInt16LE(6); if (hciVer < 0x06) { this.emit('stateChange', 'unsupported'); } else if (this._state !== 'poweredOn') { this.setAdvertiseEnable(false); this.setAdvertisingParameters(); } this.emit('readLocalVersion', hciVer, hciRev, lmpVer, manufacturer, lmpSubVer); } else if (cmd === READ_BD_ADDR_CMD) { this.addressType = 'public'; this.address = result.toString('hex').match(/.{1,2}/g).reverse().join(':'); debug('address = ' + this.address); this.emit('addressChange', this.address); } else if (cmd === LE_SET_ADVERTISING_PARAMETERS_CMD) { this.emit('stateChange', 'poweredOn'); this.emit('leAdvertisingParametersSet', status); } else if (cmd === LE_SET_ADVERTISING_DATA_CMD) { this.emit('leAdvertisingDataSet', status); } else if (cmd === LE_SET_SCAN_RESPONSE_DATA_CMD) { this.emit('leScanResponseDataSet', status); } else if (cmd === LE_SET_ADVERTISE_ENABLE_CMD) { this.emit('leAdvertiseEnableSet', status); } else if (cmd === READ_RSSI_CMD) { handle = result.readUInt16LE(0); var rssi = result.readInt8(2); debug('\t\t\thandle = ' + handle); debug('\t\t\trssi = ' + rssi); this.emit('rssiRead', handle, rssi); } else if (cmd === LE_LTK_NEG_REPLY_CMD) { handle = result.readUInt16LE(0); debug('\t\t\thandle = ' + handle); this.emit('leLtkNegReply', handle); } }; Hci.prototype.processLeMetaEvent = function(eventType, status, data) { if (eventType === EVT_LE_CONN_COMPLETE) { this.processLeConnComplete(status, data); } else if (eventType === EVT_LE_CONN_UPDATE_COMPLETE) { this.processLeConnUpdateComplete(status, data); } }; Hci.prototype.processLeConnComplete = function(status, data) { var handle = data.readUInt16LE(0); var role = data.readUInt8(2); var addressType = data.readUInt8(3) === 0x01 ? 'random': 'public'; var address = data.slice(4, 10).toString('hex').match(/.{1,2}/g).reverse().join(':'); var interval = data.readUInt16LE(10) * 1.25; var latency = data.readUInt16LE(12); // TODO: multiplier? var supervisionTimeout = data.readUInt16LE(14) * 10; var masterClockAccuracy = data.readUInt8(16); // TODO: multiplier? debug('\t\t\thandle = ' + handle); debug('\t\t\trole = ' + role); debug('\t\t\taddress type = ' + addressType); debug('\t\t\taddress = ' + address); debug('\t\t\tinterval = ' + interval); debug('\t\t\tlatency = ' + latency); debug('\t\t\tsupervision timeout = ' + supervisionTimeout); debug('\t\t\tmaster clock accuracy = ' + masterClockAccuracy); this.emit('leConnComplete', status, handle, role, addressType, address, interval, latency, supervisionTimeout, masterClockAccuracy); }; Hci.prototype.processLeConnUpdateComplete = function(status, data) { var handle = data.readUInt16LE(0); var interval = data.readUInt16LE(2) * 1.25; var latency = data.readUInt16LE(4); // TODO: multiplier? var supervisionTimeout = data.readUInt16LE(6) * 10; debug('\t\t\thandle = ' + handle); debug('\t\t\tinterval = ' + interval); debug('\t\t\tlatency = ' + latency); debug('\t\t\tsupervision timeout = ' + supervisionTimeout); this.emit('leConnUpdateComplete', status, handle, interval, latency, supervisionTimeout); }; Hci.prototype.onStateChange = function(state) { this._state = state; }; module.exports = Hci; iotjs-1.0/src/js/ble_hci_socket_hci_status.js000066400000000000000000000077001312466455500214450ustar00rootroot00000000000000/* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* Copyright (C) 2015 Sandeep Mistry sandeep.mistry@gmail.com * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ [ "Success", "Unknown HCI Command", "Unknown Connection Identifier", "Hardware Failure", "Page Timeout", "Authentication Failure", "PIN or Key Missing", "Memory Capacity Exceeded", "Connection Timeout", "Connection Limit Exceeded", "Synchronous Connection Limit to a Device Exceeded", "ACL Connection Already Exists", "Command Disallowed", "Connection Rejected due to Limited Resources", "Connection Rejected due to Security Reasons", "Connection Rejected due to Unacceptable BD_ADDR", "Connection Accept Timeout Exceeded", "Unsupported Feature or Parameter Value", "Invalid HCI Command Parameters", "Remote User Terminated Connection", "Remote Device Terminated due to Low Resources", "Remote Device Terminated due to Power Off", "Connection Terminated By Local Host", "Repeated Attempts", "Pairing Not Allowed", "Unknown LMP PDU", "Unsupported Remote Feature / Unsupported LMP Feature", "SCO Offset Rejected", "SCO Interval Rejected", "SCO Air Mode Rejected", "Invalid LMP Parameters / Invalid LL Parameters", "Unspecified Error", "Unsupported LMP Parameter Value / Unsupported LL Parameter Value", "Role Change Not Allowed", "LMP Response Timeout / LL Response Timeout", "LMP Error Transaction Collision", "LMP PDU Not Allowed", "Encryption Mode Not Acceptable", "Link Key cannot be Changed", "Requested QoS Not Supported", "Instant Passed", "Pairing With Unit Key Not Supported", "Different Transaction Collision", "Reserved", "QoS Unacceptable Parameter", "QoS Rejected", "Channel Classification Not Supported", "Insufficient Security", "Parameter Out Of Manadatory Range", "Reserved", "Role Switch Pending", "Reserved", "Reserved Slot Violation", "Role Switch Failed", "Extended Inquiry Response Too Large", "Secure Simple Pairing Not Supported By Host", "Host Busy - Pairing", "Connection Rejected due to No Suitable Channel Found", "Controller Busy", "Unacceptable Connection Parameters" , "Directed Advertising Timeout", "Connection Terminated due to MIC Failure", "Connection Failed to be Established", "MAC Connection Failed", "Coarse Clock Adjustment Rejected but Will Try to Adjust Using Clock Dragging" ] iotjs-1.0/src/js/ble_hci_socket_mgmt.js000066400000000000000000000074521312466455500202470ustar00rootroot00000000000000/* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* Copyright (C) 2015 Sandeep Mistry sandeep.mistry@gmail.com * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ var debug = console.log; // require('debug')('ble_mgmt'); var events = require('events'); var util = require('util'); var BluetoothHciSocket = require('ble_hci_socket'); var LTK_INFO_SIZE = 36; var MGMT_OP_LOAD_LONG_TERM_KEYS = 0x0013; function Mgmt() { this._socket = new BluetoothHciSocket(); this._ltkInfos = []; this._socket.on('data', this.onSocketData.bind(this)); this._socket.on('error', this.onSocketError.bind(this)); this._socket.bindControl(); this._socket.start(); } Mgmt.prototype.onSocketData = function(data) { debug('on data ->' + data.toString('hex')); }; Mgmt.prototype.onSocketError = function(error) { debug('on error ->' + error.message); }; Mgmt.prototype.addLongTermKey = function(address, addressType, authenticated, master, ediv, rand, key) { var ltkInfo = new Buffer(LTK_INFO_SIZE); address.copy(ltkInfo, 0); ltkInfo.writeUInt8(addressType.readUInt8(0) + 1, 6); // BDADDR_LE_PUBLIC = 0x01, BDADDR_LE_RANDOM 0x02, so add one ltkInfo.writeUInt8(authenticated, 7); ltkInfo.writeUInt8(master, 8); ltkInfo.writeUInt8(key.length, 9); ediv.copy(ltkInfo, 10); rand.copy(ltkInfo, 12); key.copy(ltkInfo, 20); this._ltkInfos.push(ltkInfo); this.loadLongTermKeys(); }; Mgmt.prototype.clearLongTermKeys = function() { this._ltkInfos = []; this.loadLongTermKeys(); }; Mgmt.prototype.loadLongTermKeys = function() { var numLongTermKeys = this._ltkInfos.length; var op = new Buffer(2 + numLongTermKeys * LTK_INFO_SIZE); op.writeUInt16LE(numLongTermKeys, 0); for (var i = 0; i < numLongTermKeys; i++) { this._ltkInfos[i].copy(op, 2 + i * LTK_INFO_SIZE); } this.write(MGMT_OP_LOAD_LONG_TERM_KEYS, 0, op); }; Mgmt.prototype.write = function(opcode, index, data) { var length = 0; if (data) { length = data.length; } var pkt = new Buffer(6 + length); pkt.writeUInt16LE(opcode, 0); pkt.writeUInt16LE(index, 2); pkt.writeUInt16LE(length, 4); if (length) { data.copy(pkt, 6); } debug('writing -> ' + pkt.toString('hex')); this._socket.write(pkt); }; module.exports = new Mgmt(); iotjs-1.0/src/js/ble_hci_socket_smp.js000066400000000000000000000145701312466455500201010ustar00rootroot00000000000000/* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* Copyright (C) 2015 Sandeep Mistry sandeep.mistry@gmail.com * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ var debug = console.log; // require('debug')('ble_hci_socket_smp'); var events = require('events'); var util = require('util'); var crypto = require('ble_hci_socket_crypto'); var mgmt = require('ble_hci_socket_mgmt'); var SMP_CID = 0x0006; var SMP_PAIRING_REQUEST = 0x01; var SMP_PAIRING_RESPONSE = 0x02; var SMP_PAIRING_CONFIRM = 0x03; var SMP_PAIRING_RANDOM = 0x04; var SMP_PAIRING_FAILED = 0x05; var SMP_ENCRYPT_INFO = 0x06; var SMP_MASTER_IDENT = 0x07; var SMP_UNSPECIFIED = 0x08; var Smp = function(aclStream, localAddressType, localAddress, remoteAddressType, remoteAddress) { this._aclStream = aclStream; this._iat = new Buffer([(remoteAddressType === 'random') ? 0x01 : 0x00]); this._ia = new Buffer(remoteAddress.split(':').reverse().join(''), 'hex'); this._rat = new Buffer([(localAddressType === 'random') ? 0x01 : 0x00]); this._ra = new Buffer(localAddress.split(':').reverse().join(''), 'hex'); this._stk = null; this._random = null; this._diversifier = null; this.onAclStreamDataBinded = this.onAclStreamData.bind(this); this.onAclStreamEncryptChangeBinded = this.onAclStreamEncryptChange.bind(this); this.onAclStreamLtkNegReplyBinded = this.onAclStreamLtkNegReply.bind(this); this.onAclStreamEndBinded = this.onAclStreamEnd.bind(this); this._aclStream.on('data', this.onAclStreamDataBinded); this._aclStream.on('encryptChange', this.onAclStreamEncryptChangeBinded); this._aclStream.on('ltkNegReply', this.onAclStreamLtkNegReplyBinded); this._aclStream.on('end', this.onAclStreamEndBinded); }; util.inherits(Smp, events.EventEmitter); Smp.prototype.onAclStreamData = function(cid, data) { if (cid !== SMP_CID) { return; } var code = data.readUInt8(0); if (SMP_PAIRING_REQUEST === code) { this.handlePairingRequest(data); } else if (SMP_PAIRING_CONFIRM === code) { this.handlePairingConfirm(data); } else if (SMP_PAIRING_RANDOM === code) { this.handlePairingRandom(data); } else if (SMP_PAIRING_FAILED === code) { this.handlePairingFailed(data); } }; Smp.prototype.onAclStreamEncryptChange = function(encrypted) { if (encrypted) { if (this._stk && this._diversifier && this._random) { this.write(Buffer.concat([ new Buffer([SMP_ENCRYPT_INFO]), this._stk ])); this.write(Buffer.concat([ new Buffer([SMP_MASTER_IDENT]), this._diversifier, this._random ])); } } }; Smp.prototype.onAclStreamLtkNegReply = function() { this.write(new Buffer([ SMP_PAIRING_FAILED, SMP_UNSPECIFIED ])); this.emit('fail'); }; Smp.prototype.onAclStreamEnd = function() { this._aclStream.removeListener('data', this.onAclStreamDataBinded); this._aclStream.removeListener('encryptChange', this.onAclStreamEncryptChangeBinded); this._aclStream.removeListener('ltkNegReply', this.onAclStreamLtkNegReplyBinded); this._aclStream.removeListener('end', this.onAclStreamEndBinded); }; Smp.prototype.handlePairingRequest = function(data) { this._preq = data; this._pres = new Buffer([ SMP_PAIRING_RESPONSE, 0x03, // IO capability: NoInputNoOutput 0x00, // OOB data: Authentication data not present 0x01, // Authentication requirement: Bonding - No MITM 0x10, // Max encryption key size 0x00, // Initiator key distribution: 0x01 // Responder key distribution: EncKey ]); this.write(this._pres); }; Smp.prototype.handlePairingConfirm = function(data) { this._pcnf = data; this._tk = new Buffer('00000000000000000000000000000000', 'hex'); this._r = crypto.r(); this.write(Buffer.concat([ new Buffer([SMP_PAIRING_CONFIRM]), crypto.c1(this._tk, this._r, this._pres, this._preq, this._iat, this._ia, this._rat, this._ra) ])); }; Smp.prototype.handlePairingRandom = function(data) { var r = data.slice(1); var pcnf = Buffer.concat([ new Buffer([SMP_PAIRING_CONFIRM]), crypto.c1(this._tk, r, this._pres, this._preq, this._iat, this._ia, this._rat, this._ra) ]); if (this._pcnf.toString('hex') === pcnf.toString('hex')) { this._diversifier = new Buffer('0000', 'hex'); this._random = new Buffer('0000000000000000', 'hex'); this._stk = crypto.s1(this._tk, this._r, r); mgmt.addLongTermKey(this._ia, this._iat, 0, 0, this._diversifier, this._random, this._stk); this.write(Buffer.concat([ new Buffer([SMP_PAIRING_RANDOM]), this._r ])); } else { this.write(new Buffer([ SMP_PAIRING_FAILED, SMP_PAIRING_CONFIRM ])); this.emit('fail'); } }; Smp.prototype.handlePairingFailed = function(data) { this.emit('fail'); }; Smp.prototype.write = function(data) { this._aclStream.write(SMP_CID, data); }; module.exports = Smp; iotjs-1.0/src/js/ble_primary_service.js000066400000000000000000000044371312466455500203130ustar00rootroot00000000000000/* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* Copyright (C) 2015 Sandeep Mistry sandeep.mistry@gmail.com * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ var events = require('events'); var util = require('util'); var debug = console.log; // require('debug')('ble_primary_service'); var UuidUtil = require('ble_uuid_util'); function PrimaryService(options) { this.uuid = UuidUtil.removeDashes(options.uuid); this.characteristics = options.characteristics || []; } util.inherits(PrimaryService, events.EventEmitter); PrimaryService.prototype.toString = function() { return JSON.stringify({ uuid: this.uuid, characteristics: this.characteristics }); }; module.exports = PrimaryService; iotjs-1.0/src/js/ble_uuid_util.js000066400000000000000000000035561312466455500171140ustar00rootroot00000000000000/* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* Copyright (C) 2015 Sandeep Mistry sandeep.mistry@gmail.com * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ module.exports.removeDashes = function(uuid) { if (uuid) { uuid = uuid.replace(/-/g, ''); } return uuid; }; iotjs-1.0/src/js/buffer.js000066400000000000000000000216211312466455500155310ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var bufferBuiltin = process.binding(process.binding.buffer); var util = require('util'); function checkInt(buffer, value, offset, ext, max, min) { if (value > max || value < min) throw new TypeError('value is out of bounds'); if (offset + ext > buffer.length) throw new RangeError('index out of range'); } function checkOffset(offset, ext, length) { if (offset + ext > length) throw new RangeError('index out of range'); } // Buffer constructor // [1] new Buffer(size) // [2] new Buffer(buffer) // [3] new Buffer(string) // [4] new Buffer(string, encoding) // [5] new Buffer(array) function Buffer(subject, encoding) { if (!util.isBuffer(this)) { return new Buffer(subject); } if (util.isNumber(subject)) { this.length = subject > 0 ? subject >>> 0 : 0; } else if (util.isString(subject)) { this.length = Buffer.byteLength(subject, encoding); } else if (util.isBuffer(subject) || util.isArray(subject)) { this.length = subject.length; } else { throw new TypeError('Bad arguments: Buffer(string|number|Buffer|Array)'); } this._builtin = new bufferBuiltin(this, this.length); if (util.isString(subject)) { if (!util.isUndefined(encoding) && util.isString(encoding)) { switch (encoding) { case 'hex': if (this._builtin.hexWrite(subject, 0, this.length) != this.length) { throw new TypeError('Invalid hex string'); } break; default: this.write(subject); } } else { this.write(subject); } } else if (util.isBuffer(subject)) { subject.copy(this); } else if (util.isArray(subject)) { for (var i = 0; i < this.length; ++i) { this._builtin.writeUInt8(subject[i], i); } } } // Buffer.byteLength(string) Buffer.byteLength = function(str, encoding) { var len = bufferBuiltin.byteLength(str); if (!util.isUndefined(encoding) && util.isString(encoding)) { switch (encoding) { case 'hex': return len >>> 1; } } return len; }; // Buffer.concat(list) Buffer.concat = function(list) { if (!util.isArray(list)) { throw new TypeError('Bad arguments: Buffer.concat([Buffer])'); } var length = 0; for (var i = 0; i < list.length; ++i) { if (!util.isBuffer(list[i])) { throw new TypeError('Bad arguments: Buffer.concat([Buffer])'); } length += list[i].length; } var buffer = new Buffer(length); var pos = 0; for (var i = 0; i < list.length; ++i) { list[i].copy(buffer, pos); pos += list[i].length; } return buffer; }; // Buffer.isBuffer(object) Buffer.isBuffer = function(object) { return util.isBuffer(object); }; // buffer.equals(otherBuffer) Buffer.prototype.equals = function(otherBuffer) { if (!util.isBuffer(otherBuffer)) { throw new TypeError('Bad arguments: buffer.equals(Buffer)'); } return this._builtin.compare(otherBuffer) == 0; }; // buffer.compare(otherBuffer) Buffer.prototype.compare = function(otherBuffer) { if (!util.isBuffer(otherBuffer)) { throw new TypeError('Bad arguments: buffer.compare(Buffer)'); } return this._builtin.compare(otherBuffer); }; // buffer.copy(target[, targetStart[, sourceStart[, sourceEnd]]]) // [1] buffer.copy(target) // [2] buffer.copy(target, targetStart) // [3] buffer.copy(target, targetStart, sourceStart) // [4] buffer.copy(target, targetStart, sourceStart, sourceEnd) // * targetStart - default to 0 // * sourceStart - default to 0 // * sourceEnd - default to buffer.length Buffer.prototype.copy = function(target, targetStart, sourceStart, sourceEnd) { if (!util.isBuffer(target)) { throw new TypeError('Bad arguments: buff.copy(Buffer)'); } targetStart = util.isUndefined(targetStart) ? 0 : ~~targetStart; sourceStart = util.isUndefined(sourceStart) ? 0 : ~~sourceStart; sourceEnd = util.isUndefined(sourceEnd) ? this.length : ~~ sourceEnd; if ((sourceEnd > sourceStart) && (targetStart < 0)) { throw new RangeError('Attempt to write outside buffer bounds'); } return this._builtin.copy(target, targetStart, sourceStart, sourceEnd); }; // buffer.write(string[, offset[, length]]) // [1] buffer.write(string) // [2] buffer.write(string, offset) // [3] buffer.write(string, offset, length) // * offset - default to 0 // * length - default to buffer.length - offset Buffer.prototype.write = function(string, offset, length) { if (!util.isString(string)) { throw new TypeError('Bad arguments: buff.write(string)'); } offset = util.isUndefined(offset) ? 0 : ~~offset; if (string.length > 0 && (offset < 0 || offset >= this.length)) { throw new RangeError('Attempt to write outside buffer bounds'); } var remaining = this.length - offset; length = util.isUndefined(length) ? remaining : ~~length; return this._builtin.write(string, offset, length); }; // buff.slice([start[, end]]) // [1] buff.slice() // [2] buff.slice(start) // [3] buff.slice(start, end) // * start - default to 0 // * end - default to buff.length Buffer.prototype.slice = function(start, end) { start = util.isUndefined(start) ? 0 : ~~start; end = util.isUndefined(end) ? this.length : ~~end; return this._builtin.slice(start, end); }; // buff.toString([encoding,[,start[, end]]]) // [1] buff.toString() // [2] buff.toString(start) // [3] buff.toString(start, end) // [4] buff.toString('hex') // * start - default to 0 // * end - default to buff.length Buffer.prototype.toString = function(start, end) { if (util.isString(start) && start === "hex" && util.isUndefined(end)) { return this._builtin.toHexString(); } start = util.isUndefined(start) ? 0 : ~~start; end = util.isUndefined(end) ? this.length : ~~end; return this._builtin.toString(start, end); }; // buff.writeUInt8(value, offset[,noAssert]) // [1] buff.writeUInt8(value, offset) // [2] buff.writeUInt8(value, offset, noAssert) Buffer.prototype.writeUInt8 = function(value, offset, noAssert) { value = +value; offset = offset >>> 0; if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0); this._builtin.writeUInt8(value & 0xff, offset); return offset + 1; }; // buff.writeUInt16LE(value, offset[,noAssert]) // [1] buff.writeUInt16LE(value, offset) // [2] buff.writeUInt16LE(value, offset, noAssert) Buffer.prototype.writeUInt16LE = function(value, offset, noAssert) { value = +value; offset = offset >>> 0; if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0); this._builtin.writeUInt8(value & 0xff, offset); this._builtin.writeUInt8((value >>> 8) & 0xff, offset + 1); return offset + 2; }; // buff.writeUInt32LE(value, offset[,noAssert]) // [1] buff.writeUInt32LE(value, offset) // [2] buff.writeUInt32LE(value, offset, noAssert) Buffer.prototype.writeUInt32LE = function(value, offset, noAssert) { value = +value; offset = offset >>> 0; if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0); this._builtin.writeUInt8((value >>> 24) & 0xff, offset + 3); this._builtin.writeUInt8((value >>> 16) & 0xff, offset + 2); this._builtin.writeUInt8((value >>> 8) & 0xff, offset + 1); this._builtin.writeUInt8(value & 0xff, offset); return offset + 4; }; // buff.readUInt8(offset[,noAssert]) // [1] buff.readUInt8(offset) // [2] buff.readUInt8(offset, noAssert) Buffer.prototype.readUInt8 = function(offset, noAssert) { offset = offset >>> 0; if (!noAssert) checkOffset(offset, 1, this.length); return this._builtin.readUInt8(offset); }; // buff.readInt8(offset[,noAssert]) // [1] buff.readInt8(offset) // [2] buff.readInt8(offset, noAssert) Buffer.prototype.readInt8 = function(offset, noAssert) { offset = offset >>> 0; if (!noAssert) checkOffset(offset, 1, this.length); var val = this._builtin.readUInt8(offset); return !(val & 0x80) ? val : (0xff - val + 1) * -1; }; // buff.readUInt16LE(offset[,noAssert]) // [1] buff.readUInt16LE(offset) // [2] buff.readUInt16LE(offset, noAssert) Buffer.prototype.readUInt16LE = function(offset, noAssert) { offset = offset >>> 0; if (!noAssert) checkOffset(offset, 2, this.length); return this._builtin.readUInt8(offset) | (this._builtin.readUInt8(offset + 1) << 8); }; // buff.fill(value) Buffer.prototype.fill = function(value) { if (util.isNumber(value)) { value = value & 255; for (var i = 0; i < this.length; i++) { this._builtin.writeUInt8(value, i); } } return this; }; module.exports = Buffer; module.exports.Buffer = Buffer; iotjs-1.0/src/js/console.js000066400000000000000000000021121312466455500157140ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var util = require('util'); var consoleBuiltin = process.binding(process.binding.console); function Console() { } Console.prototype.log = Console.prototype.info = function() { consoleBuiltin.stdout(util.format.apply(this, arguments) + '\n'); }; Console.prototype.warn = Console.prototype.error = function() { consoleBuiltin.stderr(util.format.apply(this, arguments) + '\n'); }; module.exports = new Console(); module.exports.Console = Console; iotjs-1.0/src/js/constants.js000066400000000000000000000012771312466455500163010ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ module.exports = process.binding(process.binding.constants); iotjs-1.0/src/js/dgram.js000066400000000000000000000254261312466455500153610ustar00rootroot00000000000000/* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var EventEmitter = require('events').EventEmitter; var util = require('util'); var UDP = process.binding(process.binding.udp); var BIND_STATE_UNBOUND = 0; var BIND_STATE_BINDING = 1; var BIND_STATE_BOUND = 2; // lazily loaded var dns = null; function lookup(address, family, callback) { if (!dns) dns = require('dns'); return dns.lookup(address, family, callback); } function lookup4(address, callback) { return lookup(address || '0.0.0.0', 4, callback); } function newHandle(type) { if (type == 'udp4') { var handle = new UDP(); handle.lookup = lookup4; return handle; } throw new Error('Bad socket type specified. Valid types are: udp4'); } function Socket(type, listener) { EventEmitter.call(this); var options = undefined; if (util.isObject(type)) { options = type; type = options.type; } var handle = newHandle(type); handle.owner = this; this._handle = handle; this._receiving = false; this._bindState = BIND_STATE_UNBOUND; this.type = type; this.fd = null; // compatibility hack // If true - UV_UDP_REUSEADDR flag will be set this._reuseAddr = options && options.reuseAddr; if (util.isFunction(listener)) this.on('message', listener); } util.inherits(Socket, EventEmitter); exports.Socket = Socket; exports.createSocket = function(type, listener) { return new Socket(type, listener); }; function startListening(socket) { socket._handle.onmessage = onMessage; // Todo: handle errors socket._handle.recvStart(); socket._receiving = true; socket._bindState = BIND_STATE_BOUND; socket.fd = -42; // compatibility hack socket.emit('listening'); } Socket.prototype.bind = function(port, address, callback) { var self = this; self._healthCheck(); if (this._bindState != BIND_STATE_UNBOUND) throw new Error('Socket is already bound'); this._bindState = BIND_STATE_BINDING; var address; if (util.isFunction(port)) { callback = port; port = 0; address = ''; } else if (util.isObject(port)) { callback = address; address = port.address || ''; port = port.port; } else if (util.isFunction(address)) { callback = address; address = ''; } if (util.isFunction(callback)) self.once('listening', callback); // defaulting address for bind to all interfaces if (!address && self._handle.lookup === lookup4) { address = '0.0.0.0'; } // resolve address first self._handle.lookup(address, function(err, ip) { if (err) { self._bindState = BIND_STATE_UNBOUND; self.emit('error', err); return; } if (!self._handle) return; // handle has been closed in the mean time self._handle._reuseAddr = self._reuseAddr; var err = self._handle.bind(ip, port | 0); if (err) { var ex = util.exceptionWithHostPort(err, 'bind', ip, port); self.emit('error', ex); self._bindState = BIND_STATE_UNBOUND; // Todo: close? return; } startListening(self); }); return self; } // thin wrapper around `send`, here for compatibility with dgram_legacy.js Socket.prototype.sendto = function(buffer, offset, length, port, address, callback) { if (!(util.isNumber(offset)) || !(util.isNumber(length))) throw new Error('send takes offset and length as args 2 and 3'); if (!(util.isString(address))) throw new Error(this.type + ' sockets must send to port, address'); this.send(buffer, offset, length, port, address, callback); }; function sliceBuffer(buffer, offset, length) { if (util.isString(buffer)) buffer = new Buffer(buffer); else if (!(util.isBuffer(buffer))) throw new TypeError('First argument must be a buffer or string'); offset = offset >>> 0; length = length >>> 0; return buffer.slice(offset, offset + length); } function fixBufferList(list) { var newlist = new Array(list.length); for (var i = 0, l = list.length; i < l; i++) { var buf = list[i]; if (util.isString(buf)) newlist[i] = new Buffer(buf); else if (!(util.isBuffer(buf))) return null; else newlist[i] = buf; } return newlist; } function enqueue(self, toEnqueue) { // If the send queue hasn't been initialized yet, do it, and install an // event handler that flushes the send queue after binding is done. if (!self._queue) { self._queue = []; self.once('listening', clearQueue); } self._queue.push(toEnqueue); return; } function clearQueue() { var queue = this._queue; this._queue = undefined; // Flush the send queue. for (var i = 0; i < queue.length; i++) queue[i](); } // valid combinations // send(buffer, offset, length, port, address, callback) // send(buffer, offset, length, port, address) // send(buffer, offset, length, port) // send(bufferOrList, port, address, callback) // send(bufferOrList, port, address) // send(bufferOrList, port) Socket.prototype.send = function(buffer, offset, length, port, address, callback) { var self = this; var list; if (address || (port && !(util.isFunction(port)))) { buffer = sliceBuffer(buffer, offset, length); } else { callback = port; port = offset; address = length; } if (!util.isArray(buffer)) { if (util.isString(buffer)) { list = [ new Buffer(buffer) ]; } else if (!util.isBuffer(buffer)) { throw new TypeError('First argument must be a buffer or a string'); } else { list = [ buffer ]; } } else if (!(list = fixBufferList(buffer))) { throw new TypeError('Buffer list arguments must be buffers or strings'); } port = port >>> 0; if (port === 0 || port > 65535) throw new RangeError('Port should be > 0 and < 65536'); // Normalize callback so it's either a function or undefined but not anything // else. if (!(util.isFunction(callback))) callback = undefined; self._healthCheck(); if (self._bindState === BIND_STATE_UNBOUND) self.bind(0, null); if (list.length === 0) list.push(new Buffer(0)); // If the socket hasn't been bound yet, push the outbound packet onto the // send queue and send after binding is complete. if (self._bindState !== BIND_STATE_BOUND) { enqueue(self, self.send.bind(self, list, port, address, callback)); return; } self._handle.lookup(address, function afterDns(ex, ip) { doSend(ex, self, ip, list, address, port, callback); }); }; function doSend(ex, self, ip, list, address, port, callback) { if (ex) { if (util.isFunction(callback)) { callback(ex); return; } self.emit('error', ex); return; } else if (!self._handle) { return; } var buf = Buffer.concat(list); var err = self._handle.send(buf, port, ip, function (err, length) { if (err) { err = util.exceptionWithHostPort(err, 'send', address, port); } else { err = null; } if (util.isFunction(callback)) { callback(err, length); } }); if (err && callback) { // don't emit as error, dgram_legacy.js compatibility var ex = exceptionWithHostPort(err, 'send', address, port); process.nextTick(callback, ex); } } Socket.prototype.close = function(callback) { if (util.isFunction(callback)) this.on('close', callback); if (this._queue) { this._queue.push(this.close.bind(this)); return this; } this._healthCheck(); this._stopReceiving(); this._handle.close(); this._handle = null; var self = this; process.nextTick(function() { self.emit('close'); }); return this; }; Socket.prototype.address = function() { this._healthCheck(); var out = {}; var err = this._handle.getsockname(out); if (err) { throw util.errnoException(err, 'getsockname'); } return out; }; Socket.prototype.setBroadcast = function(arg) { var err = this._handle.setBroadcast(arg ? 1 : 0); if (err) { throw util.errnoException(err, 'setBroadcast'); } }; Socket.prototype.setTTL = function(arg) { if (!(util.isNumber(arg))) { throw new TypeError('Argument must be a number'); } var err = this._handle.setTTL(arg); if (err) { throw util.errnoException(err, 'setTTL'); } return arg; }; Socket.prototype.setMulticastTTL = function(arg) { if (!(util.isNumber(arg))) { throw new TypeError('Argument must be a number'); } var err = this._handle.setMulticastTTL(arg); if (err) { throw util.errnoException(err, 'setMulticastTTL'); } return arg; }; Socket.prototype.setMulticastLoopback = function(arg) { var err = this._handle.setMulticastLoopback(arg ? 1 : 0); if (err) { throw util.errnoException(err, 'setMulticastLoopback'); } return arg; // 0.4 compatibility }; Socket.prototype.addMembership = function(multicastAddress, interfaceAddress) { this._healthCheck(); if (!multicastAddress) { throw new Error('multicast address must be specified'); } var err = this._handle.addMembership(multicastAddress, interfaceAddress); if (err) { throw util.errnoException(err, 'addMembership'); } }; Socket.prototype.dropMembership = function(multicastAddress, interfaceAddress) { this._healthCheck(); if (!multicastAddress) { throw new Error('multicast address must be specified'); } var err = this._handle.dropMembership(multicastAddress, interfaceAddress); if (err) { throw util.errnoException(err, 'dropMembership'); } }; Socket.prototype._healthCheck = function() { if (!this._handle) throw new Error('Not running'); // error message from dgram_legacy.js }; Socket.prototype._stopReceiving = function() { if (!this._receiving) return; this._handle.recvStop(); this._receiving = false; this.fd = null; // compatibility hack }; function onMessage(nread, handle, buf, rinfo) { var self = handle.owner; if (nread < 0) { return self.emit('error', errnoException(nread, 'recvmsg')); } rinfo.size = buf.length; // compatibility self.emit('message', buf, rinfo); } /* TODO: Implement Socket.prototype.ref. Socket.prototype.ref = function() { if (this._handle) this._handle.ref(); return this; }; */ /* TODO: Implement Socket.prototype.unref. Socket.prototype.unref = function() { if (this._handle) this._handle.unref(); return this; }; */ iotjs-1.0/src/js/dns.js000066400000000000000000000054411312466455500150460ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var util = require('util'); var dnsBuiltin = process.binding(process.binding.dns); function dnsException(err, syscall, hostname) { var ex = new Error(syscall + ' ' + err + (hostname ? ' ' + hostname : '')); // TODO(hanjoung.lee@samsung.com) err should be a string (currently a number) ex.code = err; ex.errno = err; ex.syscall = syscall; if (hostname) { ex.hostname = hostname; } return ex; } exports.lookup = function lookup(hostname, options, callback) { var hints = 0; var family = -1; // Parse arguments if (!util.isString(hostname)) { throw TypeError('invalid argument: hostname must be a string'); } if (util.isFunction(options)) { callback = options; family = 0; } else if (!util.isFunction(callback)) { throw TypeError('invalid argument: callback must be passed'); } else if (util.isObject(options)) { hints = options.hints >>> 0; family = options.family >>> 0; if (hints < 0 || hints > (exports.ADDRCONFIG | exports.V4MAPPED)) { throw new TypeError('invalid argument: invalid hints flags'); } } else if (util.isNumber(options)) { family = ~~options; } else { throw TypeError( 'invalid argument: options must be either an object or number'); } if (family !== 0 && family !== 4 && family !== 6) throw new TypeError('invalid argument: family must be 4 or 6'); function getaddrinfo() { var err = dnsBuiltin.getaddrinfo( hostname, family, hints, function(err, address, family) { var errObj = null; if (err) { errObj = dnsException(err, 'getaddrinfo', hostname); } callback(errObj, address, family); }); if (err) { callback(dnsException(err, 'getaddrinfo', hostname), address, family); } } if (process.platform != 'nuttx' && process.platform != 'tizenrt') { getaddrinfo(); } else { // dnsBuiltin.getaddrinfo is synchronous on these platforms. // needs to be wrapped into an asynchronous call. process.nextTick(function() { getaddrinfo() }); } }; // uv_getaddrinfo flags exports.ADDRCONFIG = dnsBuiltin.AI_ADDRCONFIG; exports.V4MAPPED = dnsBuiltin.AI_V4MAPPED; iotjs-1.0/src/js/events.js000066400000000000000000000056751312466455500155770ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var util = require('util'); function EventEmitter() { this._events = {}; }; module.exports.EventEmitter = EventEmitter; EventEmitter.prototype.emit = function(type) { if (!this._events) { this._events = {}; } // About to emit 'error' event but there are no listeners for it. if (type === 'error' && !this._events.error) { var err = arguments[1]; if (err instanceof Error) { throw err; } else { throw Error("Uncaught 'error' event"); } } var listeners = this._events[type]; if (util.isArray(listeners)) { listeners = listeners.slice(); var args = Array.prototype.slice.call(arguments, 1); for (var i = 0; i < listeners.length; ++i) { listeners[i].apply(this, args); } return true; } return false; }; EventEmitter.prototype.addListener = function(type, listener) { if (!util.isFunction(listener)) { throw new TypeError('listener must be a function'); } if (!this._events) { this._events = {}; } if (!this._events[type]) { this._events[type] = []; } this._events[type].push(listener); return this; }; EventEmitter.prototype.on = EventEmitter.prototype.addListener; EventEmitter.prototype.once = function(type, listener) { if (!util.isFunction(listener)) { throw new TypeError('listener must be a function'); } var f = function() { // here `this` is this not global, because EventEmitter binds event object // for this when it calls back the handler. this.removeListener(f.type, f); f.listener.apply(this, arguments); }; f.type = type; f.listener = listener; this.on(type, f); return this; }; EventEmitter.prototype.removeListener = function(type, listener) { if (!util.isFunction(listener)) { throw new TypeError('listener must be a function'); } var list = this._events[type]; if (Array.isArray(list)) { for (var i = list.length - 1; i >= 0; --i) { if (list[i] == listener || (list[i].listener && list[i].listener == listener)) { list.splice(i, 1); if (!list.length) { delete this._events[type]; } break; } } } return this; }; EventEmitter.prototype.removeAllListeners = function(type) { if (arguments.length === 0) { this._events = {}; } else { delete this._events[type]; } return this; }; iotjs-1.0/src/js/fs.js000066400000000000000000000265441312466455500147010ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var fs = exports; var constants = require('constants'); var util = require('util'); var fsBuiltin = process.binding(process.binding.fs); fs.Stats = function(stat) { this.dev = stat.dev; this.mode = stat.mode; this.nlink = stat.nlink; this.uid = stat.uid; this.gid = stat.gid; this.rdev = stat.rdev; this.blksize = stat.blksize; this.ino = stat.ino; this.size = stat.size; this.blocks = stat.blocks; }; fs.Stats.prototype.isDirectory = function() { return ((this.mode & constants.S_IFMT) === constants.S_IFDIR); }; fs.Stats.prototype.isFile = function() { return ((this.mode & constants.S_IFMT) === constants.S_IFREG); }; fsBuiltin._createStat = function(stat) { return new fs.Stats(stat); }; fs.exists = function(path, callback) { if (!path || !path.length) { process.nextTick(function () { if (callback) callback(false); }); return; } var cb = function(err, stat) { if (callback) callback(err ? false : true); }; fsBuiltin.stat(checkArgString(path, 'path'), checkArgFunction(cb, 'callback')); }; fs.existsSync = function(path) { if (!path || !path.length) { return false; } try { fsBuiltin.stat(checkArgString(path, 'path')); return true; } catch (e) { return false; } }; fs.stat = function(path, callback) { fsBuiltin.stat(checkArgString(path, 'path'), checkArgFunction(callback, 'callback')); }; fs.statSync = function(path) { return fsBuiltin.stat(checkArgString(path, 'path')); }; fs.fstat = function(fd, callback) { fsBuiltin.fstat(checkArgNumber(fd, 'fd'), checkArgFunction(callback, 'callback')); }; fs.fstatSync = function(fd) { return fsBuiltin.fstat(checkArgNumber(fd, 'fd')); }; fs.close = function(fd, callback) { fsBuiltin.close(checkArgNumber(fd, 'fd'), checkArgFunction(callback, 'callback')); }; fs.closeSync = function(fd) { fsBuiltin.close(checkArgNumber(fd, 'fd')); }; fs.open = function(path, flags, mode, callback) { fsBuiltin.open(checkArgString(path, 'path'), convertFlags(flags), convertMode(mode, 438), checkArgFunction(arguments[arguments.length - 1]), 'callback'); }; fs.openSync = function(path, flags, mode) { return fsBuiltin.open(checkArgString(path, 'path'), convertFlags(flags), convertMode(mode, 438)); }; fs.read = function(fd, buffer, offset, length, position, callback) { if (util.isNullOrUndefined(position)) { position = -1; // Read from the current position. } callback = checkArgFunction(callback, 'callback'); var cb = function(err, bytesRead) { callback(err, bytesRead || 0, buffer); }; return fsBuiltin.read(checkArgNumber(fd, 'fd'), checkArgBuffer(buffer, 'buffer'), checkArgNumber(offset, 'offset'), checkArgNumber(length, 'length'), checkArgNumber(position, 'position'), cb); }; fs.readSync = function(fd, buffer, offset, length, position) { if (util.isNullOrUndefined(position)) { position = -1; // Read from the current position. } return fsBuiltin.read(checkArgNumber(fd, 'fd'), checkArgBuffer(buffer, 'buffer'), checkArgNumber(offset, 'offset'), checkArgNumber(length, 'length'), checkArgNumber(position, 'position')); }; fs.write = function(fd, buffer, offset, length, position, callback) { if (util.isFunction(position)) { callback = position; position = -1; // write at current position. } else if (util.isNullOrUndefined(position)) { position = -1; // write at current position. } callback = checkArgFunction(callback, 'callback'); var cb = function(err, written) { callback(err, written, buffer); }; return fsBuiltin.write(checkArgNumber(fd, 'fd'), checkArgBuffer(buffer, 'buffer'), checkArgNumber(offset, 'offset'), checkArgNumber(length, 'length'), checkArgNumber(position, 'position'), cb); }; fs.writeSync = function(fd, buffer, offset, length, position) { if (util.isNullOrUndefined(position)) { position = -1; // write at current position. } return fsBuiltin.write(checkArgNumber(fd, 'fd'), checkArgBuffer(buffer, 'buffer'), checkArgNumber(offset, 'offset'), checkArgNumber(length, 'length'), checkArgNumber(position, 'position')); }; fs.readFile = function(path, callback) { checkArgString(path); checkArgFunction(callback); var fd; var buffers; fs.open(path, 'r', function(err, _fd) { if (err) { return callback(err); } fd = _fd; buffers = []; // start read read(); }); var read = function() { // Read segment of data. var buffer = new Buffer(1023); fs.read(fd, buffer, 0, 1023, -1, afterRead); }; var afterRead = function(err, bytesRead, buffer) { if (err) { fs.close(fd, function(err) { return callback(err); }); } if (bytesRead === 0) { // End of file. close(); } else { // continue reading. buffers.push(buffer.slice(0, bytesRead)); read(); } }; var close = function() { fs.close(fd, function(err) { return callback(err, Buffer.concat(buffers)); }); } }; fs.readFileSync = function(path) { checkArgString(path); var fd = fs.openSync(path, 'r', 438); var buffers = []; while (true) { try { var buffer = new Buffer(1023); var bytesRead = fs.readSync(fd, buffer, 0, 1023); if (bytesRead) { buffers.push(buffer.slice(0, bytesRead)); } else { break; } } catch (e) { break; } } fs.closeSync(fd); return Buffer.concat(buffers); }; fs.writeFile = function(path, data, callback) { checkArgString(path); checkArgFunction(callback); var fd; var len; var bytesWritten; var buffer = ensureBuffer(data); fs.open(path, 'w', function(err, _fd) { if (err) { return callback(err); } fd = _fd; len = buffer.length; bytesWritten = 0; write(); }); var write = function() { var tryN = (len - bytesWritten) >= 1024 ? 1023 : (len - bytesWritten); fs.write(fd, buffer, bytesWritten, tryN, bytesWritten, afterWrite); }; var afterWrite = function(err, n) { if (err) { fs.close(fd, function(err) { return callback(err); }); } if (n <= 0 || bytesWritten + n == len) { // End of buffer fs.close(fd, function(err) { callback(err); }); } else { // continue writing bytesWritten += n; write(); } }; }; fs.writeFileSync = function(path, data) { checkArgString(path); var buffer = ensureBuffer(data); var fd = fs.openSync(path, 'w'); var len = buffer.length; var bytesWritten = 0; while (true) { try { var tryN = (len - bytesWritten) >= 1024 ? 1023 : (len - bytesWritten); var n = fs.writeSync(fd, buffer, bytesWritten, tryN, bytesWritten); bytesWritten += n; if (bytesWritten == len) { break; } } catch (e) { break; } } fs.closeSync(fd); return bytesWritten; }; fs.mkdir = function(path, mode, callback) { if (util.isFunction(mode)) callback = mode; checkArgString(path, 'path'); checkArgFunction(callback, 'callback'); fsBuiltin.mkdir(path, convertMode(mode, 511), callback); }; fs.mkdirSync = function(path, mode) { return fsBuiltin.mkdir(checkArgString(path, 'path'), convertMode(mode, 511)); }; fs.rmdir = function(path, callback) { checkArgString(path, 'path'); checkArgFunction(callback, 'callback'); fsBuiltin.rmdir(path, callback); }; fs.rmdirSync = function(path) { return fsBuiltin.rmdir(checkArgString(path, 'path')); }; fs.unlink = function(path, callback) { checkArgString(path); checkArgFunction(callback); fsBuiltin.unlink(path, callback); }; fs.unlinkSync = function(path) { return fsBuiltin.unlink(checkArgString(path, 'path')); }; fs.rename = function(oldPath, newPath, callback) { checkArgString(oldPath); checkArgString(newPath); checkArgFunction(callback); fsBuiltin.rename(oldPath, newPath, callback); }; fs.renameSync = function(oldPath, newPath) { checkArgString(oldPath); checkArgString(newPath); fsBuiltin.rename(oldPath, newPath); }; fs.readdir = function(path, callback) { checkArgString(path); checkArgFunction(callback); fsBuiltin.readdir(path, callback); }; fs.readdirSync = function(path) { return fsBuiltin.readdir(checkArgString(path, 'path')); }; function convertFlags(flag) { var O_APPEND = constants.O_APPEND; var O_CREAT = constants.O_CREAT; var O_EXCL = constants.O_EXCL; var O_RDONLY = constants.O_RDONLY; var O_RDWR = constants.O_RDWR; var O_SYNC = constants.O_SYNC; var O_TRUNC = constants.O_TRUNC; var O_WRONLY = constants.O_WRONLY; if (util.isString(flag)) { switch (flag) { case 'r': return O_RDONLY; case 'rs': case 'sr': return O_RDONLY | O_SYNC; case 'r+': return O_RDWR; case 'rs+': case 'sr+': return O_RDWR | O_SYNC; case 'w': return O_TRUNC | O_CREAT | O_WRONLY; case 'wx': case 'xw': return O_TRUNC | O_CREAT | O_WRONLY | O_EXCL; case 'w+': return O_TRUNC | O_CREAT | O_RDWR; case 'wx+': case 'xw+': return O_TRUNC | O_CREAT | O_RDWR | O_EXCL; case 'a': return O_APPEND | O_CREAT | O_WRONLY; case 'ax': case 'xa': return O_APPEND | O_CREAT | O_WRONLY | O_EXCL; case 'a+': return O_APPEND | O_CREAT | O_RDWR; case 'ax+': case 'xa+': return O_APPEND | O_CREAT | O_RDWR | O_EXCL; } } throw new TypeError('Bad argument: flags'); } function convertMode(mode, def) { if (util.isNumber(mode)) { return mode; } else if (util.isString(mode)) { return parseInt(mode, 8); } else if (def) { return convertMode(def); } return undefined; } function ensureBuffer(data) { if (util.isBuffer(data)) { return data; } return new Buffer(data + ''); // coert to string and make it a buffer } function checkArgType(value, name, checkFunc) { if (checkFunc(value)) { return value; } else { throw new TypeError('Bad arguments: ' + name); } } function checkArgBuffer(value, name) { return checkArgType(value, name, util.isBuffer); } function checkArgNumber(value, name) { return checkArgType(value, name, util.isNumber); } function checkArgString(value, name) { return checkArgType(value, name, util.isString); } function checkArgFunction(value, name) { return checkArgType(value, name, util.isFunction); } iotjs-1.0/src/js/gpio.js000066400000000000000000000125641312466455500152240ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var EventEmitter = require('events').EventEmitter; var gpio = process.binding(process.binding.gpio); var util = require('util'); var defaultConfiguration = { direction: gpio.DIRECTION.OUT, mode: gpio.MODE.NONE, edge: gpio.EDGE.NONE }; function Gpio() { if (!(this instanceof Gpio)) { return new Gpio(); } } Gpio.prototype.open = function(configuration, callback) { return gpioPinOpen(configuration, callback); }; Gpio.prototype.DIRECTION = gpio.DIRECTION; Gpio.prototype.MODE = gpio.MODE; Gpio.prototype.EDGE = gpio.EDGE; function gpioPinOpen(configuration, callback) { var _binding = null; function GpioPin(configuration, callback) { var self = this; // validate pin if (util.isObject(configuration)) { if (!util.isNumber(configuration.pin)) { throw new TypeError('Bad configuration - pin is mandatory and number'); } } else { throw new TypeError('Bad arguments - configuration should be Object') } // validate direction if (!util.isUndefined(configuration.direction)) { if (configuration.direction !== gpio.DIRECTION.IN && configuration.direction !== gpio.DIRECTION.OUT) { throw new TypeError( 'Bad configuration - direction should be DIRECTION.IN or OUT'); } } else { configuration.direction = defaultConfiguration.direction; } // validate mode var mode = configuration.mode; if (process.platform === 'nuttx' && !util.isUndefined(mode)) { if (configuration.direction === gpio.DIRECTION.IN) { if (mode !== gpio.MODE.NONE && mode !== gpio.MODE.PULLUP && mode !== gpio.MODE.PULLDOWN) { throw new TypeError( 'Bad configuration - mode should be MODE.NONE, PULLUP or PULLDOWN'); } } else if (configuration.direction === gpio.DIRECTION.OUT) { if (mode !== gpio.MODE.NONE && mode !== gpio.MODE.FLOAT && mode !== gpio.MODE.PUSHPULL && mode !== gpio.MODE.OPENDRAIN) { throw new TypeError( 'Bad configuration - ' + 'mode should be MODE.NONE, FLOAT, PUSHPULL or OPENDRAIN'); } } } else { configuration.mode = defaultConfiguration.mode; } // validate edge var edge = configuration.edge; if (!util.isUndefined(configuration.edge)) { if (edge !== gpio.EDGE.NONE && edge !== gpio.EDGE.RISING && edge !== gpio.EDGE.FALLING && edge !== gpio.EDGE.BOTH) { throw new TypeError( 'Bad configuration - ' + 'edge should be EDGE.NONE, RISING, FALLING or BOTH'); } } else { configuration.edge = defaultConfiguration.edge; } EventEmitter.call(this); _binding = new gpio.Gpio(configuration, function(err) { util.isFunction(callback) && callback.call(self, err); }); _binding.onChange = function() { self.emit('change'); }; process.on('exit', (function(self) { return function() { if (!util.isNull(_binding)) { self.closeSync(); } }; })(this)); } util.inherits(GpioPin, EventEmitter); GpioPin.prototype.write = function(value, callback) { var self = this; if (util.isNull(_binding)) { throw new Error('GPIO pin is not opened'); } if (!util.isNumber(value) && !util.isBoolean(value)) { throw new TypeError('Bad arguments - value should be Boolean'); } _binding.write(!!value, function(err) { util.isFunction(callback) && callback.call(self, err); }); }; GpioPin.prototype.writeSync = function(value) { if (util.isNull(_binding)) { throw new Error('GPIO pin is not opened'); } if (!util.isNumber(value) && !util.isBoolean(value)) { throw new TypeError('Bad arguments - value should be Boolean'); } _binding.write(!!value); }; GpioPin.prototype.read = function(callback) { var self = this; if (util.isNull(_binding)) { throw new Error('GPIO pin is not opened'); } _binding.read(function(err, value) { util.isFunction(callback) && callback.call(self, err, value); }); }; GpioPin.prototype.readSync = function() { if (util.isNull(_binding)) { throw new Error('GPIO pin is not opened'); } return _binding.read(); }; GpioPin.prototype.close = function(callback) { var self = this; if (util.isNull(_binding)) { throw new Error('GPIO pin is not opened'); } _binding.close(function(err) { util.isFunction(callback) && callback.call(self, err); }); _binding = null; }; GpioPin.prototype.closeSync = function() { if (util.isNull(_binding)) { throw new Error('GPIO pin is not opened'); } _binding.close(); _binding = null; }; return new GpioPin(configuration, callback); } module.exports = Gpio; iotjs-1.0/src/js/http.js000066400000000000000000000022541312466455500152400ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var Server = require('http_server').Server; var client = require('http_client'); var HTTPParser = process.binding(process.binding.httpparser).HTTPParser; var ClientRequest = exports.ClientRequest = client.ClientRequest; exports.request = function(options, cb) { return new ClientRequest(options, cb); }; exports.createServer = function(requestListener){ return new Server(requestListener); }; exports.METHODS = HTTPParser.methods; exports.get = function(options, cb) { var req = exports.request(options, cb); req.end(); return req; }; iotjs-1.0/src/js/http_client.js000066400000000000000000000123461312466455500166010ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var util = require('util'); var net = require('net'); var HTTPParser = process.binding(process.binding.httpparser).HTTPParser; var IncomingMessage = require('http_incoming').IncomingMessage; var OutgoingMessage = require('http_outgoing').OutgoingMessage; var Buffer = require('buffer'); var common = require('http_common'); function ClientRequest(options, cb) { var self = this; OutgoingMessage.call(self); // get port, host and method. var port = options.port = options.port || 80; var host = options.host = options.hostname || options.host || '127.0.0.1'; var method = options.method || 'GET'; self.path = options.path || '/'; // If `options` contains header information, save it. if (options.headers) { var keys = Object.keys(options.headers); for (var i = 0, l = keys.length; i < l; i++) { var key = keys[i]; self.setHeader(key, options.headers[key]); } } // Register response event handler. if (cb) { self.once('response', cb); } // Create socket. var conn = new net.Socket(); // connect server. conn.connect(port, host); // setup connection information. setupConnection(self, conn); // store first header line to be sent. var firstHeaderLine = method + ' ' + self.path + ' HTTP/1.1\r\n'; self._storeHeader(firstHeaderLine); } util.inherits(ClientRequest, OutgoingMessage); exports.ClientRequest = ClientRequest; function setupConnection(req, socket) { var parser = common.createHTTPParser(); parser.reinitialize(HTTPParser.RESPONSE); req.socket = socket; req.connection = socket; parser.socket = socket; parser.incoming = null; parser._headers = []; req.parser = parser; socket.parser = parser; socket._httpMessage = req; parser.onIncoming = parserOnIncomingClient; socket.on('error', socketOnError); socket.on('data', socketOnData); socket.on('end', socketOnEnd); socket.on('close', socketOnClose); // socket emitted when a socket is assigned to req process.nextTick(function() { req.emit('socket', socket); }); } function socketOnClose() { var socket = this; var req = socket._httpMessage; var parser = socket.parser; socket.read(); req.emit('close'); if (req.res && req.res.readable) { // Socket closed before we emitted 'end' var res = req.res; res.on('end', function() { res.emit('close'); }); res.push(null); } else if (!req.res) { // socket closed before response starts. var err = new Error('socket hang up'); req.emit('error', err); } if (parser) { // unref all links to parser, make parser GCed parser.finish(); parser = null; socket.parser = null; req.parser = null; } } function socketOnError(er) { var socket = this; var parser = socket.parser; if (parser) { // unref all links to parser, make parser GCed parser.finish(); parser = null; socket.parser = null; } socket.destroy(); } function socketOnData(d) { var socket = this; var req = this._httpMessage; var parser = this.parser; var ret = parser.execute(d); if (ret instanceof Error) { // unref all links to parser, make parser GCed parser.finish(); parser = null; socket.parser = null; req.parser = null; socket.destroy(); req.emit('error', ret); } } function socketOnEnd() { var socket = this; var req = this._httpMessage; var parser = this.parser; if (parser) { // unref all links to parser, make parser GCed parser.finish(); parser = null; socket.parser = null; req.parser = null; } socket.destroy(); } // This is called by parserOnHeadersComplete after response header is parsed. // TODO: keepalive support function parserOnIncomingClient(res, shouldKeepAlive) { var socket = this.socket; var req = socket._httpMessage; if (req.res) { // server sent responses twice. socket.destroy(); return false; } req.res = res; res.req = req; res.on('end', responseOnEnd); req.emit('response', res); // response to HEAD req has no body var isHeadResponse = (req.method == 'HEAD'); return isHeadResponse; } var responseOnEnd = function() { var res = this; var req = res.req; var socket = req.socket; if (socket._socketState.writable) { socket.destroySoon(); } }; ClientRequest.prototype.setTimeout = function(ms, cb) { var self = this; if (cb) self.once('timeout', cb); var emitTimeout = function() { self.emit('timeout'); }; // In IoT.js, socket is already assigned, // thus, it is sufficient to trigger timeout on socket 'connect' event. this.socket.once('connect', function() { self.socket.setTimeout(ms, emitTimeout); }); }; iotjs-1.0/src/js/http_common.js000066400000000000000000000061531312466455500166120ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var util = require('util'); var HTTPParser = process.binding(process.binding.httpparser).HTTPParser; var IncomingMessage = require('http_incoming').IncomingMessage; var OutgoingMessage = require('http_outgoing').OutgoingMessage; var createHTTPParser = function() { // REQUEST is the default type. // For RESPONSE, use HTTPParser.reinitialize(HTTPParser.RESPONSE) var parser = new HTTPParser(HTTPParser.REQUEST); // cb during http parsing from C side(http_parser) parser.OnHeaders = parserOnHeaders; parser.OnHeadersComplete = parserOnHeadersComplete; parser.OnBody = parserOnBody; parser.OnMessageComplete = parserOnMessageComplete; return parser; }; exports.createHTTPParser = createHTTPParser; // This is called when parsing of incoming http msg done function parserOnMessageComplete() { var stream = this.incoming; if (stream) { stream.complete = true; // no more data from incoming, stream will emit 'end' event stream.push(null); } stream.socket.resume(); } // This is called when header part in http msg is parsed. function parserOnHeadersComplete(info) { var headers = info.headers; var url = info.url; if (!url) { url = this._url; this.url = ""; } if (!headers) { headers = this._headers; this._headers = []; } this.incoming = new IncomingMessage(this.socket); this.incoming.url = url; // add header fields of headers to incoming.headers this.incoming.addHeaders(headers); if (util.isNumber(info.method)) { // for server this.incoming.method = HTTPParser.methods[info.method]; } else { // for client this.incoming.statusCode = info.status; this.incoming.statusMessage = info.status_msg; } // For client side, if response to 'HEAD' request, we will skip parsing body var skipBody = this.onIncoming(this.incoming, info.shouldkeepalive); return skipBody; } // parserOnBody is called when HTTPParser parses http msg(incoming) and // get body part(buf from start at length of len) function parserOnBody(buf, start, len) { var stream = this.incoming; if (!stream) { return; } // Push body part into incoming stream, which will emit 'data' event var body = buf.slice(start, start+len); stream.push(body); } // This is called when http header is fragmented and // HTTPParser sends it to JS in separate pieces. function parserOnHeaders(headers, url) { // push new header parts into existing array this._headers.push.apply(this._headers, headers); if (url) { this._url += url; } } iotjs-1.0/src/js/http_incoming.js000066400000000000000000000032011312466455500171140ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var util = require('util'); var stream = require('stream'); function IncomingMessage(socket) { stream.Readable.call(this); this.socket = socket; this.connection = socket; this.readable = true; this.headers = {}; this.complete = false; // for request (server) this.url = ''; this.method = null; // for response (client) this.statusCode = null; this.statusMessage = null; } util.inherits(IncomingMessage, stream.Readable); exports.IncomingMessage = IncomingMessage; IncomingMessage.prototype.read = function(n) { this.read = stream.Readable.prototype.read; return this.read(n); }; IncomingMessage.prototype.addHeaders = function(headers) { if (!this.headers) { this.headers = {}; } // FIXME: handle headers as array if array C API is done. for (var i=0; i * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * Neither the name of the author nor the * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* This file includes all APIs in 'node-i2c'(https://github.com/kelly/node-i2c). * Some functions are translated from coffee script(i2c.coffee) in 'node-i2c'. */ var util = require('util'); var i2c = process.binding(process.binding.i2c); function I2C() { if (!(this instanceof I2C)) { return new I2C(); } } I2C.prototype.open = function(configurable, callback) { return i2cBusOpen(configurable, callback); }; function i2cBusOpen(configurable, callback) { var _binding = null; function I2CBus(configurable, callback) { if (util.isObject(configurable)) { if (process.platform === 'linux') { if (!util.isString(configurable.device)) { throw new TypeError('Bad configurable - device: String'); } } else if (process.platform === 'nuttx') { if (!util.isNumber(configurable.device)) { throw new TypeError('Bad configurable - device: Number'); } } if (!util.isNumber(configurable.address)) { throw new TypeError('Bad configurable - address: Number'); } this.address = configurable.address; _binding = new i2c(configurable.device, (function(_this) { return function(err) { if (!err) { _this.setAddress(configurable.address); } util.isFunction(callback) && callback(err); }; })(this)); } } I2CBus.prototype.close = function() { _binding.close(); }; I2CBus.prototype.setAddress = function(address, callback) { if (!util.isNumber(address)) { throw new TypeError('Bad argument - address: Number'); } this.address = address; _binding.setAddress(this.address); util.isFunction(callback) && callback(); }; I2CBus.prototype.write = function(array, callback) { if (!util.isArray(array)) { throw new TypeError('Bad argument - array: Array'); } this.setAddress(this.address); _binding.write(array, function(err) { util.isFunction(callback) && callback(err); }); }; I2CBus.prototype.read = function(length, callback) { if (!util.isNumber(length)) { throw new TypeError('Bad argument - length: Number'); } this.setAddress(this.address); _binding.read(length, function(err, data) { util.isFunction(callback) && callback(err, data); }); }; return new I2CBus(configurable, callback); } module.exports = I2C; iotjs-1.0/src/js/iotjs.js000066400000000000000000000100721312466455500154060ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ this.global = this; function Native(id) { this.id = id; this.filename = id + '.js'; this.exports = {}; } Native.cache = {}; Native.require = function(id) { if (id == 'native') { return Native; } if (Native.cache[id]) { return Native.cache[id].exports; } var nativeMod = new Native(id); Native.cache[id] = nativeMod; nativeMod.compile(); return nativeMod.exports; } Native.prototype.compile = function() { // process.native_sources has a list of pointers to // the source strings defined in 'iotjs_js.h', not // source strings. var fn = process.compileNativePtr(this.id); fn(this.exports, Native.require, this); } global.console = Native.require('console'); global.Buffer = Native.require('buffer'); (function() { var timers = undefined; var _timeoutHandler = function(mode) { if (timers == undefined) { timers = Native.require('timers'); } return timers[mode].apply(this, Array.prototype.slice.call(arguments, 1)); } global.setTimeout = _timeoutHandler.bind(this, 'setTimeout'); global.setInterval = _timeoutHandler.bind(this, 'setInterval'); global.clearTimeout = _timeoutHandler.bind(this, 'clearTimeout'); global.clearInterval = _timeoutHandler.bind(this, 'clearInterval'); })(); var EventEmitter = Native.require('events').EventEmitter; EventEmitter.call(process); var keys = Object.keys(EventEmitter.prototype); var keysLength = keys.length; for (var i = 0; i < keysLength; ++i) { var key = keys[i]; if (!process[key]) { process[key] = EventEmitter.prototype[key]; } } var nextTickQueue = []; process.nextTick = nextTick; process._onNextTick = _onNextTick; function _onNextTick() { // clone nextTickQueue to new array object, and calls function // iterating the cloned array. This is because, // during processing nextTick // a callback could add another next tick callback using // `process.nextTick()`, if we calls back iterating original // `nextTickQueue` that could turn into infinite loop. var callbacks = nextTickQueue.slice(0); nextTickQueue = []; var len = callbacks.length; for (var i = 0; i < len; ++i) { try { callbacks[i](); } catch (e) { process._onUncaughtException(e); } } return nextTickQueue.length > 0; } function nextTick(callback) { nextTickQueue.push(callback); } process._onUncaughtException = _onUncaughtException; function _onUncaughtException(error) { var event = 'uncaughtException'; if (process._events[event] && process._events[event].length > 0) { try { // Emit uncaughtException event. process.emit('uncaughtException', error); } catch (e) { // Even uncaughtException handler thrown, that could not be handled. console.error('uncaughtException handler throws: ' + e); process.exit(1); } } else { // Exit if there are no handler for uncaught exception. console.error('uncaughtException: ' + error); process.exit(1); } } process.exitCode = 0; process._exiting = false; process.emitExit = function(code) { if (!process._exiting) { process._exiting = true; if (code || code == 0) { process.exitCode = code; } process.emit('exit', process.exitCode || 0); } } process.exit = function(code) { try { process.emitExit(code); } catch (e) { process.exitCode = 1; process._onUncaughtException(e); } finally { process.doExit(process.exitCode || 0); } } var module = Native.require('module'); module.runMain(); iotjs-1.0/src/js/module.js000066400000000000000000000076501312466455500155530ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var Native = require('native'); var fs = Native.require('fs'); function iotjs_module_t(id, parent) { this.id = id; this.exports = {}; this.filename = null; this.parent = parent; }; module.exports = iotjs_module_t; iotjs_module_t.cache = {}; iotjs_module_t.wrapper = Native.wrapper; iotjs_module_t.wrap = Native.wrap; var cwd; try { cwd = process.cwd(); } catch (e) { } var moduledirs = [""] if(cwd){ moduledirs.push(cwd + "/"); moduledirs.push(cwd + "/iotjs_modules/"); } if(process.env.HOME){ moduledirs.push(process.env.HOME + "/iotjs_modules/"); } if(process.env.IOTJS_PATH){ moduledirs.push(process.env.IOTJS_PATH + "/iotjs_modules/") } iotjs_module_t.resolveDirectories = function(id, parent) { var dirs = moduledirs; if(parent) { if(!parent.dirs){ parent.dirs = []; } dirs = parent.dirs.concat(dirs); } return dirs; }; iotjs_module_t.resolveFilepath = function(id, directories) { for(var i = 0; i>> 0, hints: 0 }; if (!util.isNumber(port) || port < 0 || port > 65535) throw new RangeError('port should be >= 0 and < 65536: ' + options.port); if (dnsopts.family !== 0 && dnsopts.family !== 4 && dnsopts.family !== 6) throw new RangeError('family should be 4 or 6: ' + dnsopts.family); self._host = host; dns.lookup(host, dnsopts, function(err, ip, family) { if (self._socketState.destroyed) { return; } self.emit('lookup', err, ip, family); if (err) { process.nextTick(function() { self.emit('error', err); self.destroy(); }); } else { resetSocketTimeout(self); connect(self, ip, port); } }); return self; }; Socket.prototype.write = function(data, callback) { if (!util.isString(data) && !util.isBuffer(data)) { throw new TypeError('invalid argument'); } return stream.Duplex.prototype.write.call(this, data, callback); }; Socket.prototype._write = function(chunk, callback, afterWrite) { assert(util.isBuffer(chunk)); assert(util.isFunction(afterWrite)); var self = this; resetSocketTimeout(self); self._handle.owner = self; self._handle.write(chunk, function(status) { afterWrite(status); if (util.isFunction(callback)) { callback.call(self, status); } }); }; Socket.prototype.end = function(data, callback) { var self = this; var state = self._socketState; // end of writable stream. stream.Writable.prototype.end.call(self, data, callback); // this socket is no longer writable. state.writable = false; }; // Destroy this socket as fast as possible. Socket.prototype.destroy = function() { var self = this; var state = self._socketState; if (state.destroyed) { return; } if (state.writable) { self.end(); } // unset timeout clearSocketTimeout(self); if (self._writableState.ended && self._handle) { close(self); state.destroyed = true; } else { self.once('finish', function() { self.destroy(); }); } }; // Destroy this socket as fast as possible if this socket is no longer readable. Socket.prototype.destroySoon = function() { var self = this; var state = self._socketState; if (state.writable) { self.end(); } if (self._writableState.finished) { self.destroy(); } else { self.once('finish', self.destroy); } } Socket.prototype.setKeepAlive = function(enable, delay) { var self = this; enable = +Boolean(enable); if (self._handle && self._handle.setKeepAlive) { self._handle.setKeepAlive(enable, ~~(delay / 1000)); } }; Socket.prototype.address = function() { if (!this._handle || !this._handle.getsockname) { return {}; } if (!this._sockname) { var out = {}; var err = this._handle.getsockname(out); if (err) return {}; // FIXME(bnoordhuis) Throw? this._sockname = out; } return this._sockname; }; Socket.prototype.setTimeout = function(msecs, callback) { var self = this; self._timeout = msecs; clearSocketTimeout(self); if (msecs === 0) { if (callback) { self.removeListener('timeout', callback); } } else { self._timer = setTimeout(function() { self.emit('timeout'); clearSocketTimeout(self); }, msecs); if (callback) { self.once('timeout', callback); } } }; function connect(socket, ip, port) { var afterConnect = function(status) { var state = socket._socketState; state.connecting = false; if (state.destroyed) { return; } if (status == 0) { onSocketConnect(socket); socket.emit('connect'); } else { socket.destroy(); emitError(socket, new Error('connect failed - status: ' + TCP.errname(status))); } }; var err = socket._handle.connect(ip, port, afterConnect); if (err) { emitError(socket, new Error('connect failed - status: ' + TCP.errname(err))); } } function close(socket) { socket._handle.owner = socket; socket._handle.onclose = function() { socket.emit('close'); }; var handle = socket._handle; socket._handle = null; handle.close(); if (socket._server) { var server = socket._server; server._socketCount--; server._emitCloseIfDrained(); socket._server = null; } } function resetSocketTimeout(socket) { var state = socket._socketState; if (!state.destroyed) { // start timeout over again clearSocketTimeout(socket); socket._timer = setTimeout(function() { socket.emit('timeout'); clearSocketTimeout(socket); }, socket._timeout); } }; function clearSocketTimeout(socket) { if (socket._timer) { clearTimeout(socket._timer); socket._timer = null; } }; function emitError(socket, err) { socket.emit('error', err); } function maybeDestroy(socket) { var state = socket._socketState; if (!state.connecting && !state.writable && !state.readable) { socket.destroy(); } } function onSocketConnect(socket) { var state = socket._socketState; state.connecting = false; state.connected = true; resetSocketTimeout(socket); socket._readyToWrite(); // `readStart` on next tick, after connection event handled. process.nextTick(function() { socket._handle.owner = socket; socket._handle.onread = onread; socket._handle.readStart(); }); } function onread(socket, nread, isEOF, buffer) { var state = socket._socketState; resetSocketTimeout(socket); if (isEOF) { // pushing readable stream null means EOF. stream.Readable.prototype.push.call(socket, null); if (socket._readableState.length == 0) { // this socket is no longer readable. state.readable = false; // destroy if this socket is not writable. maybeDestroy(socket); } } else if (nread < 0) { var err = new Error('read error: ' + nread); stream.Readable.prototype.error.call(socket, err); } else if (nread > 0) { if (process.platform != 'nuttx') { stream.Readable.prototype.push.call(socket, buffer); return; } var str = buffer.toString(); var eofNeeded = false; if (str.length >= 6 && str.substr(str.length - 6, str.length) == '\\e\\n\\d') { eofNeeded = true; buffer = buffer.slice(0, str.length - 6); } if (str.length == 6 && eofNeeded) { // Socket.prototype.end with no argument } else { stream.Readable.prototype.push.call(socket, buffer); } if (eofNeeded) { onread(socket, 0, true, null); } } } // Writable stream finished. function onSocketFinish() { var self = this; var state = self._socketState; if (!state.readable || self._readableState.ended || !self._handle) { // no readable stream or ended, destroy(close) socket. return self.destroy(); } else { // Readable stream alive, shutdown only outgoing stream. var err = self._handle.shutdown(function() { if (self._readableState.ended) { self.destroy(); } }); } } // Readable stream ended. function onSocketEnd() { var state = this._socketState; maybeDestroy(this); if (!state.allowHalfOpen) { this.destroySoon(); } } function Server(options, connectionListener) { if (!(this instanceof Server)) { return new Server(options, connectionListener); } EventEmitter.call(this); if (util.isFunction(options)) { connectionListener = options; options = {}; } else { options = options || {}; } if (util.isFunction(connectionListener)) { this.on('connection', connectionListener); } this._handle = null; this._socketCount = 0; this.allowHalfOpen = options.allowHalfOpen || false; } // Server inherits EventEmitter. util.inherits(Server, EventEmitter); // listen Server.prototype.listen = function() { var self = this; var args = normalizeListenArgs(arguments); var options = args[0]; var callback = args[1]; var port = options.port; var host = util.isString(options.host) ? options.host : '0.0.0.0'; var backlog = util.isNumber(options.backlog) ? options.backlog : 511; if (!util.isNumber(port)) { throw new Error('invalid argument - need port number'); } // register listening event listener. if (util.isFunction(callback)) { self.once('listening', callback); } // Create server handle. if (!self._handle) { self._handle = createTCP(); } // bind port var err = self._handle.bind(host, port); if (err) { self._handle.close(); return self.emit('error', err); } // listen self._handle.onconnection = onconnection; self._handle.createTCP = createTCP; self._handle.owner = self; var err = self._handle.listen(backlog); if (err) { self._handle.close(); return self.emit('error', err); } process.nextTick(function() { if (self._handle) { self.emit('listening'); } }); return this; }; Server.prototype.address = function() { if (this._handle && this._handle.getsockname) { var out = {}; this._handle.getsockname(out); // TODO(bnoordhuis) Check err and throw? return out; } return null; }; Server.prototype.close = function(callback) { if (util.isFunction(callback)) { if (!this._handle) { this.once('close', function() { callback(new Error('Not running')); }); } else { this.once('close', callback); } } if (this._handle) { this._handle.close(); this._handle = null; } this._emitCloseIfDrained(); return this; }; Server.prototype._emitCloseIfDrained = function() { var self = this; if (self._handle || self._socketCount > 0) { return; } process.nextTick(function() { self.emit('close'); }); }; // This function is called after server accepted connection request // from a client. // This binding // * server tcp handle // Parameters // * status - status code // * clientHandle - client socket handle (tcp). function onconnection(status, clientHandle) { var server = this.owner; if (status) { server.emit('error', new Error('accept error: ' + TCP.errname(status))); return; } // Create socket object for connecting client. var socket = new Socket({ handle: clientHandle, allowHalfOpen: server.allowHalfOpen }); socket._server = server; onSocketConnect(socket); server._socketCount++; server.emit('connection', socket); } function normalizeListenArgs(args) { var options = {}; if (util.isObject(args[0])) { options = args[0]; } else { var idx = 0; options.port = args[idx++]; if (util.isString(args[idx])) { options.host = args[idx++]; } if (util.isNumber(args[idx])) { options.backlog = args[idx++]; } } var cb = args[args.length - 1]; return util.isFunction(cb) ? [options, cb] : [options]; } function normalizeConnectArgs(args) { var options = {}; if (util.isObject(args[0])) { options = args[0]; } else { options.port = args[0]; if (util.isString(args[1])) { options.host = args[1]; } } var cb = args[args.length - 1]; return util.isFunction(cb) ? [options, cb] : [options]; } exports.createServer = function(options, callback) { return new Server(options, callback); }; // net.connect(options[, connectListener]) // net.connect(port[, host][, connectListener]) exports.connect = exports.createConnection = function() { var args = normalizeConnectArgs(arguments); var socket = new Socket(args[0]); return Socket.prototype.connect.apply(socket, args); }; module.exports.Socket = Socket; module.exports.Server = Server; iotjs-1.0/src/js/pwm.js000066400000000000000000000146521312466455500150710ustar00rootroot00000000000000/* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var util = require('util'); var pwm = process.binding(process.binding.pwm); function Pwm() { if (!(this instanceof Pwm)) { return new Pwm(); } } Pwm.prototype.open = function(configuration, callback) { return pwmPinOpen(configuration, callback); }; function pwmPinOpen(configuration, callback) { var _binding = null; function PwmPin(configuration, callback) { var self = this; self._configuration = {}; if (util.isObject(configuration)) { if (process.platform === 'linux') { if (util.isNumber(configuration.chip)) { self._configuration.chip = configuration.chip } else { self._configuration.chip = 0; } } if (!util.isNumber(configuration.pin)) { throw new TypeError( 'Bad configuration - pin is mandatory and should be Number'); } else { self._configuration.pin = configuration.pin; } } else { throw new TypeError('Bad arguments - configuration should be Object') } // validate configuration var dutyCycle = configuration.dutyCycle; var period = configuration.period; if (!util.isNumber(period) && util.isNumber(configuration.frequency)) { period = 1.0 / configuration.frequency; } if (util.isNumber(dutyCycle) && dutyCycle >= 0.0 && dutyCycle <= 1.0 && util.isNumber(period) && util.isFinite(period) && period > 0) { self._configuration.dutyCycle = dutyCycle; self._configuration.period = period; } _binding = new pwm(self._configuration, function(err) { util.isFunction(callback) && callback.call(self, err); }); process.on('exit', (function(self) { return function() { if (!util.isNull(_binding)) { self.closeSync(); } }; })(this)); } PwmPin.prototype._validatePeriod = function(period) { if (!util.isNumber(period)) { throw new TypeError('Period is not a number(' + typeof(period) + ')'); } else if (period < 0) { throw new RangeError('Period(' + period + ') is negative'); } return true; }; PwmPin.prototype._validateFrequency = function(frequency) { if (!util.isNumber(frequency)) { throw new TypeError('Frequency is not a number(' + typeof(frequency) + ')'); } else if (frequency <= 0) { throw RangeError('Nonpositivie frequency of ' + frequency); } return true; }; PwmPin.prototype._validateDutyCycle = function(dutyCycle) { if (!util.isNumber(dutyCycle)) { throw TypeError('DutyCycle is not a number(' + typeof(dutyCycle) + ')'); } else if (dutyCycle < 0.0 || dutyCycle > 1.0) { throw RangeError('DutyCycle of ' + dutyCycle + ' out of bounds [0..1]'); } return true; }; PwmPin.prototype.setPeriod = function(period, callback) { var self = this; if (util.isNull(_binding)) { throw new Error('Pwm pin is not opened'); } if (this._validatePeriod(period)) { _binding.setPeriod(period, function(err) { util.isFunction(callback) && callback.call(self, err); }); } }; PwmPin.prototype.setPeriodSync = function(period) { if (util.isNull(_binding)) { throw new Error('Pwm pin is not opened'); } if (this._validatePeriod(period)) { _binding.setPeriod(period); } }; PwmPin.prototype.setFrequency = function(frequency, callback) { var self = this; if (util.isNull(_binding)) { throw new Error('Pwm pin is not opened'); } if (this._validateFrequency(frequency)) { _binding.setPeriod(1.0 / frequency, function(err) { util.isFunction(callback) && callback.call(self, err); }); } }; PwmPin.prototype.setFrequencySync = function(frequency) { if (util.isNull(_binding)) { throw new Error('Pwm pin is not opened'); } if (this._validateFrequency(frequency)) { _binding.setPeriod(1.0 / frequency); } }; PwmPin.prototype.setDutyCycle = function(dutyCycle, callback) { var self = this; if (util.isNull(_binding)) { throw new Error('Pwm pin is not opened'); } // Check arguments. if (this._validateDutyCycle(dutyCycle)) { _binding.setDutyCycle(dutyCycle, function(err) { util.isFunction(callback) && callback.call(self, err); }); } }; PwmPin.prototype.setDutyCycleSync = function(dutyCycle) { if (util.isNull(_binding)) { throw new Error('Pwm pin is not opened'); } // Check arguments. if (this._validateDutyCycle(dutyCycle)) { _binding.setDutyCycle(dutyCycle); } }; PwmPin.prototype.setEnable = function(enable, callback) { var self = this; if (util.isNull(_binding)) { throw new Error('Pwm pin is not opened'); } // Check arguments. if (!util.isNumber(enable) && !util.isBoolean(enable)) { throw new TypeError('enable is of type ' + typeof(enable)); } _binding.setEnable(!!enable, function(err) { util.isFunction(callback) && callback.call(self, err); }); }; PwmPin.prototype.setEnableSync = function(enable) { if (util.isNull(_binding)) { throw new Error('Pwm pin is not opened'); } // Check arguments. if (!util.isNumber(enable) && !util.isBoolean(enable)) { throw new TypeError('enable is of type ' + typeof(enable)); } _binding.setEnable(!!enable); }; PwmPin.prototype.close = function(callback) { var self = this; if (util.isNull(_binding)) { throw new Error('Pwm pin is not opened'); } _binding.close(function(err) { util.isFunction(callback) && callback.call(self, err); }); _binding = null; }; PwmPin.prototype.closeSync = function() { if (util.isNull(_binding)) { throw new Error('Pwm pin is not opened'); } _binding.close(); _binding = null; }; return new PwmPin(configuration, callback); } module.exports = Pwm; iotjs-1.0/src/js/spi.js000066400000000000000000000147471312466455500150660ustar00rootroot00000000000000/* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var util = require('util'); var spi = process.binding(process.binding.spi); var defaultConfiguration = { mode : spi.MODE[0], chipSelect : spi.CHIPSELECT.NONE, maxSpeed : 500000, bitsPerWord : 8, bitOrder : spi.BITORDER.MSB, loopback : false }; function Spi() { if (!(this instanceof Spi)) { return new Spi(); } } Spi.prototype.open = function(configuration, callback) { return spiBusOpen(configuration, callback); }; Spi.prototype.MODE = spi.MODE; Spi.prototype.CHIPSELECT = spi.CHIPSELECT; Spi.prototype.BITORDER = spi.BITORDER; function spiBusOpen(configuration, callback) { var _binding = null; function SpiBus(configuration, callback) { var self = this; // validate device if (util.isObject(configuration)) { if (!util.isString(configuration.device)) { throw new TypeError( 'Bad configuration - device is mandatory and String'); } } else { throw new TypeError('Bad arguments - configuration should be Object'); } // validate mode var mode = configuration.mode; if (!util.isUndefined(mode)) { if (mode !== spi.MODE[0] && mode !== spi.MODE[1] && mode !== spi.MODE[2] && mode !== spi.MODE[3]) { throw new TypeError( 'Bad arguments - mode should be MODE[0], [1], [2] or [3]'); } } else { configuration.mode = defaultConfiguration.mode; } // validate chip-select var chipSelect = configuration.chipSelect; if (!util.isUndefined(chipSelect)) { if (chipSelect != spi.CHIPSELECT.NONE && chipSelect != spi.CHIPSELECT.HIGH) { throw new TypeError( 'Bad arguments - chipSelect should be CHIPSELECT.NONE or HIGH'); } } else { configuration.chipSelect = defaultConfiguration.chipSelect; } // validate max speed if (!util.isUndefined(configuration.maxSpeed)) { if (!util.isNumber(configuration.maxSpeed)) { throw new TypeError('Bad arguments - maxSpeed should be Number'); } } else { configuration.maxSpeed = defaultConfiguration.maxSpeed } // validate bits per word var bitsPerWord = configuration.bitsPerWord; if (!util.isUndefined(bitsPerWord)) { if (bitsPerWord != 8 && bitsPerWord != 9) { throw new TypeError('Bad arguments - bitsPerWord should be 8 or 9'); } } else { configuration.bitsPerWord = defaultConfiguration.bitsPerWord; } // validate bit order var bitOrder = configuration.bitOrder; if (!util.isUndefined(bitOrder)) { if (bitOrder != spi.BITORDER.MSB && bitOrder != spi.BITORDER.LSB) { throw new TypeError( 'Bad arguments - bitOrder should be BITORDER.MSB or LSB'); } } else { configuration.bitOrder = defaultConfiguration.bitOrder; } // validate loopback var loopback = configuration.loopback; if (!util.isUndefined(loopback)) { if (!util.isBoolean(loopback)) { throw new TypeError('Bad arguments - loopback should be Boolean'); } } else { configuration.loopback = defaultConfiguration.loopback; } _binding = new spi.Spi(configuration, function(err) { util.isFunction(callback) && callback.call(self, err); }); process.on('exit', (function(self) { return function() { if (!util.isNull(_binding)) { self.closeSync(); } }; })(this)); } SpiBus.prototype.transfer = function(txBuffer, rxBuffer, callback) { var self = this; if (util.isNull(_binding)) { throw new Error('SPI bus is not opened'); } if (util.isUndefined(txBuffer.length) || util.isUndefined(rxBuffer.length) || txBuffer.length <= 0 || rxBuffer.length <= 0 || txBuffer.length != rxBuffer.length) { throw new Error('Bad arguments - buffer length'); } var rxLength = rxBuffer.length; var afterCallback = function(err, buffer) { for (var i = 0; i < rxLength; i++) { rxBuffer[i] = buffer[i]; } util.isFunction(callback) && callback.call(self, err); }; if (util.isArray(txBuffer) && util.isArray(rxBuffer)) { _binding.transferArray(txBuffer, rxBuffer, afterCallback); } else if (util.isBuffer(txBuffer) && util.isBuffer(rxBuffer)) { _binding.transferBuffer(txBuffer, rxBuffer, afterCallback); } else { throw new TypeError('Bad arguments - buffer should be Array or Buffer'); } }; SpiBus.prototype.transferSync = function(txBuffer, rxBuffer) { if (util.isNull(_binding)) { throw new Error('SPI bus is not opened'); } if (util.isUndefined(txBuffer.length) || util.isUndefined(rxBuffer.length) || txBuffer.length <= 0 || rxBuffer.length <= 0 || txBuffer.length != rxBuffer.length) { throw new Error('Bad arguments - buffer length'); } var data = null; if (util.isArray(txBuffer) && util.isArray(rxBuffer)) { data = _binding.transferArray(txBuffer, rxBuffer); } else if (util.isBuffer(txBuffer) && util.isBuffer(rxBuffer)) { data = _binding.transferBuffer(txBuffer, rxBuffer); } else { throw new TypeError('Bad arguments - buffer should be Array or Buffer'); } if (data !== null && (util.isArray(data) || util.isBuffer(data)) && data.length === rxBuffer.length) { for (var i = 0; i < rxBuffer.length; i++) { rxBuffer[i] = data[i]; } } else { throw new Error('Spi Transfer Error'); } }; SpiBus.prototype.close = function(callback) { var self = this; if (util.isNull(_binding)) { throw new Error('SPI bus is not opened'); } return _binding.close(function(err) { util.isFunction(callback) && callback.call(self, err); }); }; SpiBus.prototype.closeSync = function() { if (util.isNull(_binding)) { throw new Error('SPI bus is not opened'); } return _binding.close(); }; return new SpiBus(configuration, callback); } module.exports = Spi; iotjs-1.0/src/js/stm32f4dis.js000066400000000000000000000012771312466455500161670ustar00rootroot00000000000000/* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ module.exports = process.binding(process.binding.stm32f4dis); iotjs-1.0/src/js/stream.js000066400000000000000000000017211312466455500155520ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var eventEmitter = require('events').EventEmitter; var util = require('util'); function Stream() { eventEmitter.call(this); }; util.inherits(Stream, eventEmitter); exports.Stream = Stream; exports.Readable = require('stream_readable'); exports.Writable = require('stream_writable'); exports.Duplex = require('stream_duplex'); iotjs-1.0/src/js/stream_duplex.js000066400000000000000000000025001312466455500171270ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var util = require('util'); var Readable = require('stream_readable'); var Writable = require('stream_writable'); function Duplex(options) { if (!(this instanceof Duplex)) { return new Duplex(options); } Readable.call(this, options); Writable.call(this, options); } // Duplex inherits Readable. util.inherits(Duplex, Readable); // Duplex should also inherits Writable but there are no way for inheriting // from multiple parents. Copy properties from Writable. var keys = Object.keys(Writable.prototype); for (var i = 0; i < keys.length; ++i) { var key = keys[i]; if (!Duplex.prototype[key]) { Duplex.prototype[key] = Writable.prototype[key]; } } module.exports = Duplex; iotjs-1.0/src/js/stream_readable.js000066400000000000000000000101461312466455500173720ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var Stream = require('stream').Stream; var util = require('util'); var assert = require('assert'); function ReadableState(options) { options = options || {}; // the internal array of buffers. this.buffer = []; // the sum of length of buffers. this.length = 0; this.defaultEncoding = options.defaultEncoding || 'utf8'; // true if in flowing mode. this.flowing = false; // become `true` when the stream meet EOF. this.ended = false; // become `true` just before emit 'end' event. this.endEmitted = false; }; function Readable(options) { if (!(this instanceof Readable)) { return new Readable(options); } this._readableState = new ReadableState(options); Stream.call(this); }; util.inherits(Readable, Stream); Readable.prototype.read = function(n) { var state = this._readableState; var res; if (!util.isNumber(n) || n > state.length) { n = state.length; } else if (n < 0) { n = 0; } if (n > 0) { res = readBuffer(this, n); } else { res = null; } if (state.ended && state.length == 0) { emitEnd(this); } return res; }; Readable.prototype.on = function(ev, cb) { var res = Stream.prototype.on.call(this, ev, cb); if (ev === 'data') { this.resume(); } return res; }; Readable.prototype.isPaused = function() { return !this._readableState.flowing; }; Readable.prototype.pause = function() { var state = this._readableState; if (state.flowing) { state.flowing = false; this.emit('pause'); } return this; }; Readable.prototype.resume = function() { var state = this._readableState; if (!state.flowing) { state.flowing = true; if (state.length > 0) { emitData(this, readBuffer(this)); } } return this; }; Readable.prototype.error = function(error) { this.emit('error', error); }; Readable.prototype.push = function(chunk, encoding) { var state = this._readableState; if (util.isNull(chunk)) { onEof(this); } else if (!util.isString(chunk) && !util.isBuffer(chunk)) { this.error(TypeError('Invalid chunk')); } else if (state.ended) { this.error(Error('stream.push() after EOF')); } else { if (util.isString(chunk)) { encoding = encoding || state.defaultEncoding; chunk = new Buffer(chunk, encoding); } if (state.flowing) { emitData(this, chunk); } else { state.length += chunk.length; state.buffer.push(chunk); this.emit('readable'); } } }; function readBuffer(stream, n) { var state = stream._readableState; var res; if (n == 0 || util.isNullOrUndefined(n)) { n = state.length; } if (state.buffer.length === 0 || state.length === 0) { res = null; } else if (n >= state.length) { res = Buffer.concat(state.buffer); state.buffer = []; state.length = 0; } else { throw new Error('not implemented'); } return res; }; function emitEnd(stream) { var state = stream._readableState; if (stream.length > 0 || !state.ended) { throw new Error('stream ended on non-EOF stream'); } if (!state.endEmitted) { state.endEmitted = true; stream.emit('end'); } }; function emitData(stream, data) { var state = stream._readableState; assert.equal(readBuffer(stream), null); stream.emit('data', data); if (state.ended && state.length == 0) { emitEnd(stream); } }; function onEof(stream) { var state = stream._readableState; state.ended = true; if (state.length == 0) { emitEnd(stream); } }; module.exports = Readable; iotjs-1.0/src/js/stream_writable.js000066400000000000000000000144251312466455500174500ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var stream = require('stream'); var util = require('util'); var Stream = stream.Stream; var Duplex = stream.Duplex; var defaultHighWaterMark = 128; function WriteReq(chunk, callback) { this.chunk = chunk; this.callback = callback; } function WritableState(options) { // buffer of WriteReq this.buffer = []; // total length of messages not flushed yet. this.length = 0; // high water mark. // The point where write() starts retuning false. this.highWaterMark = (options && util.isNumber(options.highWaterMark)) ? options.highWaterMark : defaultHighWaterMark; // 'true' if stream is ready to write. this.ready = false; // `true` if stream is writing down data underlying system. this.writing = false; // the length of message being writing. this.writingLength = 0; // turn 'true' when some messages are buffered. After buffered messages are // all sent, 'drain' event will be emitted. this.needDrain = false; // become `true` when `end()` called. this.ending = false; // become `true` when there are no date to write. this.ended = false; } function Writable(options) { if (!(this instanceof Writable) && !(this instanceof stream.Duplex)) { return new Writable(options); } this._writableState = new WritableState(options); Stream.call(this); } util.inherits(Writable, Stream); // Write chunk of data to underlying system stream. // Control flow in general description // Writable.prototype.write() // || // writeOrBuffer() // || // doWrite() // || // ConcreteStream.prototype._write() // | // underlying stream // | // Writable.prototype._onwrite() Writable.prototype.write = function(chunk, callback) { var state = this._writableState; if (state.ended) { writeAfterEnd(this, callback); return false; } return writeOrBuffer(this, chunk, callback); }; // This function object never to be called. concrete stream should override // this method. Writable.prototype._write = function(chunk, callback, onwrite) { throw new Error('unreachable'); } Writable.prototype.end = function(chunk, callback) { var state = this._writableState; // Because NuttX cannot poll 'EOF',so forcely raise EOF event. if (process.platform == 'nuttx') { if (!state.ending) { if (util.isNullOrUndefined(chunk)) { chunk = '\\e\\n\\d'; } else { chunk += '\\e\\n\\d'; } } } if (!util.isNullOrUndefined(chunk)) { this.write(chunk); } if (!state.ending) { endWritable(this, callback); } }; // When stream is ready to write, concrete stream implementation should call // this method to inform it. Writable.prototype._readyToWrite = function() { var state = this._writableState; state.ready = true; writeBuffered(this); }; // A chunk of data has been written down to stream. Writable.prototype._onwrite = function() { var state = this._writableState; state.length -= state.writingLength; state.writing = false; state.writingLength = 0; writeBuffered(this); }; // A write call occured after end. function writeAfterEnd(stream, callback) { var err = new Error('write after end'); stream.emit('error', err); if (util.isFunction(callback)) { process.nextTick(callback.bind(undefined, err)); } } function writeOrBuffer(stream, chunk, callback) { var state = stream._writableState; if (util.isString(chunk)) { chunk = new Buffer(chunk); } state.length += chunk.length; if (!state.ready || state.writing || state.buffer.length > 0) { // stream not yet ready or there is pending request to write. // push this request into write queue. state.buffer.push(new WriteReq(chunk, callback)); } else { // here means there is no pending data. write out. doWrite(stream, chunk, callback); } // total length of buffered message exceeded high water mark. if (state.length >= state.highWaterMark) { state.needDrain = true; } return !state.needDrain; } function writeBuffered(stream) { var state = stream._writableState; if (!state.writing) { if (state.buffer.length == 0) { onEmptyBuffer(stream); } else { var req = state.buffer.shift(); doWrite(stream, req.chunk, req.callback); } } } function doWrite(stream, chunk, callback) { var state = stream._writableState; if (state.writing) { return new Error('write during writing'); } // The stream is now writing. state.writing = true; state.writingLength = chunk.length; // Write down the chunk data. stream._write(chunk, callback, stream._onwrite.bind(stream)); } // No more data to write. if this stream is being finishing, emit 'finish'. function onEmptyBuffer(stream) { var state = stream._writableState; if (state.ending) { emitFinish(stream); } else if (state.needDrain) { emitDrain(stream); } } // Writable.prototype.end() was called. register callback for 'finish' event. // After finish writing out buffered data, 'finish' event will be fired. function endWritable(stream, callback) { var state = stream._writableState; state.ending = true; if (callback) { stream.once('finish', callback); } // If nothing left, emit finish event at next tick. if (!state.writing && state.buffer.length == 0) { process.nextTick(emitFinish.bind(undefined, stream)); } } // Emit 'drain' event function emitDrain(stream) { var state = stream._writableState; if (state.needDrain) { state.needDrain = false; stream.emit('drain'); } } // Emit 'finish' event to notify this stream is finished. function emitFinish(stream) { var state = stream._writableState; if (!state.ended) { state.ended = true; stream.emit('finish'); } } module.exports = Writable; iotjs-1.0/src/js/testdriver.js000066400000000000000000000012771312466455500164600ustar00rootroot00000000000000/* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ module.exports = process.binding(process.binding.testdriver); iotjs-1.0/src/js/timers.js000066400000000000000000000051361312466455500155660ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var Timer = process.binding(process.binding.timer); var util = require('util'); var TIMEOUT_MAX = 2147483647; // 2^31-1 function Timeout(after) { this.after = after; this.isrepeat = false; this.callback = null; this.handler = null; } Timer.prototype.handleTimeout = function() { var timeout = this.timeoutObj; // 'this' is Timer object if (timeout && timeout.callback) { timeout.callback(); if (!timeout.isrepeat) { timeout.unref(); } } }; Timeout.prototype.ref = function() { var repeat = 0; var handler = new Timer(); if (this.isrepeat) { repeat = this.after; } handler.timeoutObj = this; this.handler = handler; handler.start(this.after, repeat); }; Timeout.prototype.unref = function() { this.callback = undefined; if (this.handler) { this.handler.timeoutObj = undefined; this.handler.stop(); this.handler = undefined; } }; function timeoutConfigurator(isrepeat, callback, delay) { if (!util.isFunction(callback)) { throw new TypeError('Bad arguments: callback must be a Function'); } delay *= 1; if (delay < 1 || delay > TIMEOUT_MAX) { delay = 1; } var timeout = new Timeout(delay); // set timeout handler. if (arguments.length <= 3) { timeout.callback = callback; } else { var args = Array.prototype.slice.call(arguments, 3); args.splice(0, 0, timeout); timeout.callback = callback.bind.apply(callback, args); } timeout.isrepeat = isrepeat; timeout.ref(); return timeout; } exports.setTimeout = timeoutConfigurator.bind(undefined, false); exports.setInterval = timeoutConfigurator.bind(undefined, true); function clearTimeoutBase(timeoutType, timeout) { if (timeout) { if (timeout instanceof Timeout) { timeout.unref(); } else { throw new Error(timeoutType + '() - invalid timeout'); } } } exports.clearTimeout = clearTimeoutBase.bind(undefined, 'clearTimeout'); exports.clearInterval = clearTimeoutBase.bind(undefined, 'clearInterval'); iotjs-1.0/src/js/uart.js000066400000000000000000000071731312466455500152410ustar00rootroot00000000000000/* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var EventEmitter = require('events').EventEmitter; var util = require('util'); var uart = process.binding(process.binding.uart); // VALIDATION ARRAYS var BAUDRATE = [0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400 , 4800, 9600, 19200, 38400, 57600, 115200, 230400]; var DATABITS = [5, 6, 7, 8]; var defaultConfiguration = { baudRate: 9600, dataBits: 8 }; function Uart() { if (!(this instanceof Uart)) { return new Uart(); } } Uart.prototype.open = function(configuration, callback) { return uartPortOpen(configuration, callback); }; function uartPortOpen(configuration, callback) { var _binding = null; function UartPort(configuration, callback) { //constructor var self = this; if (util.isObject(configuration)) { if (!util.isString(configuration.device)) { throw new TypeError( 'Bad configuration - device is mandatory and should be String'); } } else { throw new TypeError('Bad arguments - configuration should be Object'); } // validate baud rate if (!util.isUndefined(configuration.baudRate)) { if (BAUDRATE.indexOf(configuration.baudRate) === -1) { throw new TypeError("Invalid 'baudRate': " + configuration.baudRate); } } else { configuration.baudRate = defaultConfiguration.baudRate; } // validate data bits if (!util.isUndefined(configuration.dataBits)) { if (DATABITS.indexOf(configuration.dataBits) === -1) { throw new TypeError("Invalid 'databits': " + configuration.dataBits); } } else { configuration.dataBits = defaultConfiguration.dataBits; } EventEmitter.call(this); _binding = new uart(configuration, this, function(err) { util.isFunction(callback) && callback.call(self, err); }); process.on('exit', (function(self) { return function() { if (!util.isNull(_binding)) { self.closeSync(); } }; })(this)); } util.inherits(UartPort, EventEmitter); UartPort.prototype.write = function(buffer, callback) { var self = this; if (util.isNull(_binding)) { throw new Error('UART port is not opened'); } _binding.write(buffer, function(err) { util.isFunction(callback) && callback.call(self, err); }); }; UartPort.prototype.writeSync = function(buffer) { var self = this; if (util.isNull(_binding)) { throw new Error('UART port is not opened'); } _binding.write(buffer); }; UartPort.prototype.close = function(callback) { var self = this; if (util.isNull(_binding)) { throw new Error('UART port is not opened'); } _binding.close(function(err) { util.isFunction(callback) && callback.call(self, err); }); _binding = null; }; UartPort.prototype.closeSync = function() { if (util.isNull(_binding)) { throw new Error('UART port is not opened'); } _binding.close(); _binding = null; }; return new UartPort(configuration, callback); } module.exports = Uart; iotjs-1.0/src/js/util.js000066400000000000000000000070621312466455500152400ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ function isNull(arg) { return arg === null; } function isUndefined(arg) { return arg === undefined; } function isNullOrUndefined(arg) { return isNull(arg) || isUndefined(arg); } function isNumber(arg) { return typeof arg === 'number'; } function isFinite(arg) { return (arg == 0) || (arg != arg / 2); } function isBoolean(arg) { return typeof arg === 'boolean'; } function isString(arg) { return typeof arg === 'string'; } function isObject(arg) { return typeof arg === 'object' && arg != null; } function isFunction(arg) { return typeof arg === 'function'; } function isBuffer(arg) { return arg instanceof Buffer; } function inherits(ctor, superCtor) { ctor.prototype = Object.create(superCtor.prototype, { constructor: { value: ctor, enumerable: false, writable: true, configurable: true } }); }; function format(s) { if (!isString(s)) { var arrs = []; for (var i = 0; i < arguments.length; ++i) { arrs.push(formatValue(arguments[i])); } return arrs.join(' '); } var i = 1; var args = arguments; var str = String(s).replace(/%[sdj%]/g, function(m) { if (m === '%%') { return '%'; } if (i >= args.length) { return m; } switch (m) { case '%s': return String(args[i++]); case '%d': return Number(args[i++]); case '%j': try { return JSON.stringify(args[i++]); } catch (_) { return '[Circular]'; } default: return m; } }); while (i < args.length) { str += ' ' + formatValue(args[i++]); } return str; } function formatValue(v) { if (isUndefined(v)) { return 'undefined'; } else if (isNull(v)) { return 'null'; } else { return v.toString(); } } function errnoException(err, syscall, original) { var errname = "error"; // uv.errname(err); var message = syscall + ' ' + errname; if (original) message += ' ' + original; var e = new Error(message); e.code = errname; e.errno = errname; e.syscall = syscall; return e; }; function exceptionWithHostPort(err, syscall, address, port, additional) { var details; if (port && port > 0) { details = address + ':' + port; } else { details = address; } if (additional) { details += ' - Local (' + additional + ')'; } var ex = exports.errnoException(err, syscall, details); ex.address = address; if (port) { ex.port = port; } return ex; }; exports.isNull = isNull; exports.isUndefined = isUndefined; exports.isNullOrUndefined = isNullOrUndefined; exports.isNumber = isNumber; exports.isBoolean = isBoolean; exports.isString = isString; exports.isObject = isObject; exports.isFinite = isFinite; exports.isFunction = isFunction; exports.isBuffer = isBuffer; exports.isArray = Array.isArray; exports.exceptionWithHostPort = exceptionWithHostPort; exports.errnoException = errnoException; exports.inherits = inherits; exports.format = format; iotjs-1.0/src/modules/000077500000000000000000000000001312466455500147545ustar00rootroot00000000000000iotjs-1.0/src/modules/iotjs_module_adc.c000066400000000000000000000202731312466455500204300ustar00rootroot00000000000000/* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "iotjs_def.h" #include "iotjs_module_adc.h" #include "iotjs_objectwrap.h" IOTJS_DEFINE_NATIVE_HANDLE_INFO_THIS_MODULE(adc); static iotjs_adc_t* iotjs_adc_instance_from_jval(const iotjs_jval_t* jadc); static iotjs_adc_t* iotjs_adc_create(const iotjs_jval_t* jadc) { iotjs_adc_t* adc = IOTJS_ALLOC(iotjs_adc_t); IOTJS_VALIDATED_STRUCT_CONSTRUCTOR(iotjs_adc_t, adc); iotjs_jobjectwrap_initialize(&_this->jobjectwrap, jadc, &this_module_native_info); return adc; } static void iotjs_adc_destroy(iotjs_adc_t* adc) { IOTJS_VALIDATED_STRUCT_DESTRUCTOR(iotjs_adc_t, adc); iotjs_jobjectwrap_destroy(&_this->jobjectwrap); #if defined(__linux__) iotjs_string_destroy(&_this->device); #endif IOTJS_RELEASE(adc); } #define THIS iotjs_adc_reqwrap_t* adc_reqwrap static iotjs_adc_reqwrap_t* iotjs_adc_reqwrap_create( const iotjs_jval_t* jcallback, iotjs_adc_t* adc, AdcOp op) { iotjs_adc_reqwrap_t* adc_reqwrap = IOTJS_ALLOC(iotjs_adc_reqwrap_t); IOTJS_VALIDATED_STRUCT_CONSTRUCTOR(iotjs_adc_reqwrap_t, adc_reqwrap); iotjs_reqwrap_initialize(&_this->reqwrap, jcallback, (uv_req_t*)&_this->req); _this->req_data.op = op; _this->adc_instance = adc; return adc_reqwrap; } static void iotjs_adc_reqwrap_destroy(THIS) { IOTJS_VALIDATED_STRUCT_DESTRUCTOR(iotjs_adc_reqwrap_t, adc_reqwrap); iotjs_reqwrap_destroy(&_this->reqwrap); IOTJS_RELEASE(adc_reqwrap); } static void iotjs_adc_reqwrap_dispatched(THIS) { IOTJS_VALIDATABLE_STRUCT_METHOD_VALIDATE(iotjs_adc_reqwrap_t, adc_reqwrap); iotjs_adc_reqwrap_destroy(adc_reqwrap); } static uv_work_t* iotjs_adc_reqwrap_req(THIS) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_adc_reqwrap_t, adc_reqwrap); return &_this->req; } static const iotjs_jval_t* iotjs_adc_reqwrap_jcallback(THIS) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_adc_reqwrap_t, adc_reqwrap); return iotjs_reqwrap_jcallback(&_this->reqwrap); } static iotjs_adc_t* iotjs_adc_instance_from_jval(const iotjs_jval_t* jadc) { uintptr_t handle = iotjs_jval_get_object_native_handle(jadc); return (iotjs_adc_t*)handle; } iotjs_adc_reqwrap_t* iotjs_adc_reqwrap_from_request(uv_work_t* req) { return (iotjs_adc_reqwrap_t*)(iotjs_reqwrap_from_request((uv_req_t*)req)); } iotjs_adc_reqdata_t* iotjs_adc_reqwrap_data(THIS) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_adc_reqwrap_t, adc_reqwrap); return &_this->req_data; } iotjs_adc_t* iotjs_adc_instance_from_reqwrap(THIS) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_adc_reqwrap_t, adc_reqwrap); return _this->adc_instance; } #undef THIS static void iotjs_adc_after_work(uv_work_t* work_req, int status) { iotjs_adc_reqwrap_t* req_wrap = iotjs_adc_reqwrap_from_request(work_req); iotjs_adc_reqdata_t* req_data = iotjs_adc_reqwrap_data(req_wrap); iotjs_jargs_t jargs = iotjs_jargs_create(2); bool result = req_data->result; if (status) { iotjs_jval_t error = iotjs_jval_create_error("System error"); iotjs_jargs_append_jval(&jargs, &error); iotjs_jval_destroy(&error); } else { switch (req_data->op) { case kAdcOpOpen: if (!result) { iotjs_jargs_append_error(&jargs, "Failed to open ADC device"); } else { iotjs_jargs_append_null(&jargs); } break; case kAdcOpRead: if (!result) { iotjs_jargs_append_error(&jargs, "Cannot read from ADC device"); } else { iotjs_jargs_append_null(&jargs); iotjs_jargs_append_number(&jargs, req_data->value); } break; case kAdcOpClose: if (!result) { iotjs_jargs_append_error(&jargs, "Cannot close ADC device"); } else { iotjs_jargs_append_null(&jargs); } break; default: { IOTJS_ASSERT(!"Unreachable"); break; } } } const iotjs_jval_t* jcallback = iotjs_adc_reqwrap_jcallback(req_wrap); iotjs_make_callback(jcallback, iotjs_jval_get_undefined(), &jargs); iotjs_jargs_destroy(&jargs); iotjs_adc_reqwrap_dispatched(req_wrap); } static void iotjs_adc_set_configuration(iotjs_adc_t* adc, const iotjs_jval_t* jconfiguration) { #if defined(__linux__) IOTJS_VALIDATED_STRUCT_METHOD(iotjs_adc_t, adc); iotjs_jval_t jdevice = iotjs_jval_get_property(jconfiguration, IOTJS_MAGIC_STRING_DEVICE); _this->device = iotjs_jval_as_string(&jdevice); iotjs_jval_destroy(&jdevice); #elif defined(__NUTTX__) IOTJS_VALIDATED_STRUCT_METHOD(iotjs_adc_t, adc); iotjs_jval_t jpin = iotjs_jval_get_property(jconfiguration, IOTJS_MAGIC_STRING_PIN); _this->pin = iotjs_jval_as_number(&jpin); iotjs_jval_destroy(&jpin); #endif } static void iotjs_adc_read_worker(uv_work_t* work_req) { ADC_WORKER_INIT; int32_t value = iotjs_adc_read(adc); if (value < 0) { req_data->result = false; return; } req_data->value = value; req_data->result = true; } static void iotjs_adc_close_worker(uv_work_t* work_req) { ADC_WORKER_INIT; // Release driver if (!iotjs_adc_close(adc)) { req_data->result = false; return; } req_data->result = true; } #define ADC_ASYNC(call, this, jcallback, op) \ do { \ uv_loop_t* loop = iotjs_environment_loop(iotjs_environment_get()); \ iotjs_adc_reqwrap_t* req_wrap = \ iotjs_adc_reqwrap_create(jcallback, this, op); \ uv_work_t* req = iotjs_adc_reqwrap_req(req_wrap); \ uv_queue_work(loop, req, iotjs_adc_##call##_worker, iotjs_adc_after_work); \ } while (0) JHANDLER_FUNCTION(AdcConstructor) { DJHANDLER_CHECK_THIS(object); DJHANDLER_CHECK_ARGS(2, object, function); // Create ADC object const iotjs_jval_t* jadc = JHANDLER_GET_THIS(object); iotjs_adc_t* adc = iotjs_adc_create(jadc); IOTJS_ASSERT(adc == iotjs_adc_instance_from_jval(jadc)); iotjs_adc_set_configuration(adc, JHANDLER_GET_ARG(0, object)); const iotjs_jval_t* jcallback = JHANDLER_GET_ARG(1, function); ADC_ASYNC(open, adc, jcallback, kAdcOpOpen); } JHANDLER_FUNCTION(Read) { JHANDLER_DECLARE_THIS_PTR(adc, adc); DJHANDLER_CHECK_ARG_IF_EXIST(0, function); const iotjs_jval_t* jcallback = JHANDLER_GET_ARG_IF_EXIST(0, function); if (jcallback) { ADC_ASYNC(read, adc, jcallback, kAdcOpRead); } else { int32_t value = iotjs_adc_read(adc); if (value < 0) { JHANDLER_THROW(COMMON, "ADC Read Error"); } else { iotjs_jhandler_return_number(jhandler, value); } } } JHANDLER_FUNCTION(Close) { JHANDLER_DECLARE_THIS_PTR(adc, adc); DJHANDLER_CHECK_ARG_IF_EXIST(0, function); const iotjs_jval_t* jcallback = JHANDLER_GET_ARG_IF_EXIST(0, function); if (jcallback) { ADC_ASYNC(close, adc, jcallback, kAdcOpClose); } else { if (!iotjs_adc_close(adc)) { JHANDLER_THROW(COMMON, "ADC Close Error"); } } iotjs_jhandler_return_null(jhandler); } iotjs_jval_t InitAdc() { iotjs_jval_t jadc = iotjs_jval_create_object(); iotjs_jval_t jadcConstructor = iotjs_jval_create_function_with_dispatch(AdcConstructor); iotjs_jval_set_property_jval(&jadc, IOTJS_MAGIC_STRING_ADC, &jadcConstructor); iotjs_jval_t jprototype = iotjs_jval_create_object(); iotjs_jval_set_method(&jprototype, IOTJS_MAGIC_STRING_READ, Read); iotjs_jval_set_method(&jprototype, IOTJS_MAGIC_STRING_CLOSE, Close); iotjs_jval_set_property_jval(&jadcConstructor, IOTJS_MAGIC_STRING_PROTOTYPE, &jprototype); iotjs_jval_destroy(&jprototype); iotjs_jval_destroy(&jadcConstructor); return jadc; } iotjs-1.0/src/modules/iotjs_module_adc.h000066400000000000000000000037411312466455500204360ustar00rootroot00000000000000/* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef IOTJS_MODULE_ADC_H #define IOTJS_MODULE_ADC_H #include "iotjs_def.h" #include "iotjs_objectwrap.h" #include "iotjs_reqwrap.h" typedef enum { kAdcOpOpen, kAdcOpRead, kAdcOpClose, } AdcOp; typedef struct { iotjs_jobjectwrap_t jobjectwrap; #if defined(__linux__) iotjs_string_t device; #elif defined(__NUTTX__) uint32_t pin; #endif int32_t device_fd; } IOTJS_VALIDATED_STRUCT(iotjs_adc_t); typedef struct { int32_t value; bool result; AdcOp op; } iotjs_adc_reqdata_t; typedef struct { iotjs_reqwrap_t reqwrap; uv_work_t req; iotjs_adc_reqdata_t req_data; iotjs_adc_t* adc_instance; } IOTJS_VALIDATED_STRUCT(iotjs_adc_reqwrap_t); #define THIS iotjs_adc_reqwrap_t* adc_reqwrap iotjs_adc_reqwrap_t* iotjs_adc_reqwrap_from_request(uv_work_t* req); iotjs_adc_reqdata_t* iotjs_adc_reqwrap_data(THIS); iotjs_adc_t* iotjs_adc_instance_from_reqwrap(THIS); #undef THIS #define ADC_WORKER_INIT \ iotjs_adc_reqwrap_t* req_wrap = iotjs_adc_reqwrap_from_request(work_req); \ iotjs_adc_reqdata_t* req_data = iotjs_adc_reqwrap_data(req_wrap); \ iotjs_adc_t* adc = iotjs_adc_instance_from_reqwrap(req_wrap); int32_t iotjs_adc_read(iotjs_adc_t* adc); bool iotjs_adc_close(iotjs_adc_t* adc); void iotjs_adc_open_worker(uv_work_t* work_req); #endif /* IOTJS_MODULE_ADC_H */ iotjs-1.0/src/modules/iotjs_module_blehcisocket.c000066400000000000000000000151411312466455500223360ustar00rootroot00000000000000/* Copyright 2017-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* Copyright (C) 2015 Sandeep Mistry sandeep.mistry@gmail.com * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #include "iotjs_def.h" #include "iotjs_module_blehcisocket.h" #include "iotjs_module_buffer.h" #include #include #include #define THIS iotjs_blehcisocket_t* blehcisocket IOTJS_DEFINE_NATIVE_HANDLE_INFO_THIS_MODULE(blehcisocket); iotjs_blehcisocket_t* iotjs_blehcisocket_create(const iotjs_jval_t* jble) { THIS = IOTJS_ALLOC(iotjs_blehcisocket_t); IOTJS_VALIDATED_STRUCT_CONSTRUCTOR(iotjs_blehcisocket_t, blehcisocket); iotjs_jobjectwrap_initialize(&_this->jobjectwrap, jble, &this_module_native_info); iotjs_blehcisocket_initialize(blehcisocket); return blehcisocket; } iotjs_blehcisocket_t* iotjs_blehcisocket_instance_from_jval( const iotjs_jval_t* jble) { iotjs_jobjectwrap_t* jobjectwrap = iotjs_jobjectwrap_from_jobject(jble); return (iotjs_blehcisocket_t*)jobjectwrap; } static void iotjs_blehcisocket_destroy(THIS) { iotjs_blehcisocket_close(blehcisocket); IOTJS_VALIDATED_STRUCT_DESTRUCTOR(iotjs_blehcisocket_t, blehcisocket); iotjs_jobjectwrap_destroy(&_this->jobjectwrap); IOTJS_RELEASE(blehcisocket); } JHANDLER_FUNCTION(Start) { JHANDLER_DECLARE_THIS_PTR(blehcisocket, blehcisocket); DJHANDLER_CHECK_ARGS(0); iotjs_blehcisocket_start(blehcisocket); iotjs_jhandler_return_undefined(jhandler); } JHANDLER_FUNCTION(BindRaw) { JHANDLER_DECLARE_THIS_PTR(blehcisocket, blehcisocket); JHANDLER_CHECK(ge(iotjs_jhandler_get_arg_length(jhandler), 1)); int devId = 0; int* pDevId = NULL; const iotjs_jval_t* raw = iotjs_jhandler_get_arg(jhandler, 0); if (iotjs_jval_is_number(raw)) { devId = iotjs_jval_as_number(raw); pDevId = &devId; } int ret = iotjs_blehcisocket_bindRaw(blehcisocket, pDevId); iotjs_jhandler_return_number(jhandler, ret); } JHANDLER_FUNCTION(BindUser) { JHANDLER_DECLARE_THIS_PTR(blehcisocket, blehcisocket); DJHANDLER_CHECK_ARGS(1, number); int devId = JHANDLER_GET_ARG(0, number); int* pDevId = &devId; int ret = iotjs_blehcisocket_bindUser(blehcisocket, pDevId); iotjs_jhandler_return_number(jhandler, ret); } JHANDLER_FUNCTION(BindControl) { JHANDLER_DECLARE_THIS_PTR(blehcisocket, blehcisocket); DJHANDLER_CHECK_ARGS(0); iotjs_blehcisocket_bindControl(blehcisocket); iotjs_jhandler_return_undefined(jhandler); } JHANDLER_FUNCTION(IsDevUp) { JHANDLER_DECLARE_THIS_PTR(blehcisocket, blehcisocket); DJHANDLER_CHECK_ARGS(0); bool ret = iotjs_blehcisocket_isDevUp(blehcisocket); iotjs_jhandler_return_boolean(jhandler, ret); } JHANDLER_FUNCTION(SetFilter) { JHANDLER_DECLARE_THIS_PTR(blehcisocket, blehcisocket); DJHANDLER_CHECK_ARGS(1, object); iotjs_bufferwrap_t* buffer = iotjs_bufferwrap_from_jbuffer(JHANDLER_GET_ARG(0, object)); iotjs_blehcisocket_setFilter(blehcisocket, iotjs_bufferwrap_buffer(buffer), iotjs_bufferwrap_length(buffer)); iotjs_jhandler_return_undefined(jhandler); } JHANDLER_FUNCTION(Stop) { JHANDLER_DECLARE_THIS_PTR(blehcisocket, blehcisocket); DJHANDLER_CHECK_ARGS(0); iotjs_blehcisocket_stop(blehcisocket); iotjs_jhandler_return_undefined(jhandler); } JHANDLER_FUNCTION(Write) { JHANDLER_DECLARE_THIS_PTR(blehcisocket, blehcisocket); DJHANDLER_CHECK_ARGS(1, object); iotjs_bufferwrap_t* buffer = iotjs_bufferwrap_from_jbuffer(JHANDLER_GET_ARG(0, object)); iotjs_blehcisocket_write(blehcisocket, iotjs_bufferwrap_buffer(buffer), iotjs_bufferwrap_length(buffer)); iotjs_jhandler_return_undefined(jhandler); } JHANDLER_FUNCTION(BleHciSocketCons) { DJHANDLER_CHECK_THIS(object); DJHANDLER_CHECK_ARGS(0); // Create object const iotjs_jval_t* jblehcisocket = JHANDLER_GET_THIS(object); iotjs_blehcisocket_t* blehcisocket = iotjs_blehcisocket_create(jblehcisocket); IOTJS_ASSERT(blehcisocket == (iotjs_blehcisocket_t*)(iotjs_jval_get_object_native_handle( jblehcisocket))); } iotjs_jval_t InitBlehcisocket() { iotjs_jval_t jblehcisocketCons = iotjs_jval_create_function_with_dispatch(BleHciSocketCons); iotjs_jval_t prototype = iotjs_jval_create_object(); iotjs_jval_set_method(&prototype, IOTJS_MAGIC_STRING_START, Start); iotjs_jval_set_method(&prototype, IOTJS_MAGIC_STRING_BINDRAW, BindRaw); iotjs_jval_set_method(&prototype, IOTJS_MAGIC_STRING_BINDUSER, BindUser); iotjs_jval_set_method(&prototype, IOTJS_MAGIC_STRING_BINDCONTROL, BindControl); iotjs_jval_set_method(&prototype, IOTJS_MAGIC_STRING_ISDEVUP, IsDevUp); iotjs_jval_set_method(&prototype, IOTJS_MAGIC_STRING_SETFILTER, SetFilter); iotjs_jval_set_method(&prototype, IOTJS_MAGIC_STRING_STOP, Stop); iotjs_jval_set_method(&prototype, IOTJS_MAGIC_STRING_WRITE, Write); iotjs_jval_set_property_jval(&jblehcisocketCons, IOTJS_MAGIC_STRING_PROTOTYPE, &prototype); iotjs_jval_destroy(&prototype); return jblehcisocketCons; } iotjs-1.0/src/modules/iotjs_module_blehcisocket.h000066400000000000000000000063551312466455500223520ustar00rootroot00000000000000/* Copyright 2017-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* Copyright (C) 2015 Sandeep Mistry sandeep.mistry@gmail.com * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #ifndef IOTJS_MODULE_BLE_HCI_SOCKET_H #define IOTJS_MODULE_BLE_HCI_SOCKET_H #include "iotjs_def.h" #include "iotjs_objectwrap.h" #include "iotjs_reqwrap.h" typedef struct { iotjs_jobjectwrap_t jobjectwrap; int _mode; int _socket; int _devId; uv_poll_t _pollHandle; int _l2sockets[1024]; int _l2socketCount; uint8_t _address[6]; uint8_t _addressType; } IOTJS_VALIDATED_STRUCT(iotjs_blehcisocket_t); #define THIS iotjs_blehcisocket_t* iotjs_blehcisocket iotjs_blehcisocket_t* iotjs_blehcisocket_create(const iotjs_jval_t* jble); iotjs_blehcisocket_t* iotjs_blehcisocket_instance_from_jval( const iotjs_jval_t* jble); void iotjs_blehcisocket_initialize(THIS); void iotjs_blehcisocket_close(THIS); void iotjs_blehcisocket_start(THIS); int iotjs_blehcisocket_bindRaw(THIS, int* devId); int iotjs_blehcisocket_bindUser(THIS, int* devId); void iotjs_blehcisocket_bindControl(THIS); bool iotjs_blehcisocket_isDevUp(THIS); void iotjs_blehcisocket_setFilter(THIS, char* data, size_t length); void iotjs_blehcisocket_poll(THIS); void iotjs_blehcisocket_stop(THIS); void iotjs_blehcisocket_write(THIS, char* data, size_t length); void iotjs_blehcisocket_emitErrnoError(THIS); int iotjs_blehcisocket_devIdFor(THIS, int* pDevId, bool isUp); int iotjs_blehcisocket_kernelDisconnectWorkArounds(THIS, int length, char* data); #undef THIS void iotjs_blehcisocket_poll_cb(uv_poll_t* handle, int status, int events); #endif /* IOTJS_MODULE_BLE_HCI_SOCKET_H */ iotjs-1.0/src/modules/iotjs_module_buffer.c000066400000000000000000000370431312466455500211550ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "iotjs_def.h" #include "iotjs_module_buffer.h" #include #include #include IOTJS_DEFINE_NATIVE_HANDLE_INFO_THIS_MODULE(bufferwrap); iotjs_bufferwrap_t* iotjs_bufferwrap_create(const iotjs_jval_t* jbuiltin, size_t length) { iotjs_bufferwrap_t* bufferwrap = IOTJS_ALLOC(iotjs_bufferwrap_t); IOTJS_VALIDATED_STRUCT_CONSTRUCTOR(iotjs_bufferwrap_t, bufferwrap); iotjs_jobjectwrap_initialize(&_this->jobjectwrap, jbuiltin, &this_module_native_info); if (length > 0) { _this->length = length; _this->buffer = iotjs_buffer_allocate(length); IOTJS_ASSERT(_this->buffer != NULL); } else { _this->length = 0; _this->buffer = NULL; } IOTJS_ASSERT( bufferwrap == (iotjs_bufferwrap_t*)(iotjs_jval_get_object_native_handle(jbuiltin))); return bufferwrap; } static void iotjs_bufferwrap_destroy(iotjs_bufferwrap_t* bufferwrap) { IOTJS_VALIDATED_STRUCT_DESTRUCTOR(iotjs_bufferwrap_t, bufferwrap); if (_this->buffer != NULL) { iotjs_buffer_release(_this->buffer); } iotjs_jobjectwrap_destroy(&_this->jobjectwrap); IOTJS_RELEASE(bufferwrap); } iotjs_bufferwrap_t* iotjs_bufferwrap_from_jbuiltin( const iotjs_jval_t* jbuiltin) { IOTJS_ASSERT(iotjs_jval_is_object(jbuiltin)); iotjs_bufferwrap_t* buffer = (iotjs_bufferwrap_t*)iotjs_jval_get_object_native_handle(jbuiltin); IOTJS_ASSERT(buffer != NULL); return buffer; } iotjs_bufferwrap_t* iotjs_bufferwrap_from_jbuffer(const iotjs_jval_t* jbuffer) { IOTJS_ASSERT(iotjs_jval_is_object(jbuffer)); iotjs_jval_t jbuiltin = iotjs_jval_get_property(jbuffer, IOTJS_MAGIC_STRING__BUILTIN); iotjs_bufferwrap_t* buffer = iotjs_bufferwrap_from_jbuiltin(&jbuiltin); iotjs_jval_destroy(&jbuiltin); return buffer; } iotjs_jval_t* iotjs_bufferwrap_jbuiltin(iotjs_bufferwrap_t* bufferwrap) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_bufferwrap_t, bufferwrap); return iotjs_jobjectwrap_jobject(&_this->jobjectwrap); } iotjs_jval_t iotjs_bufferwrap_jbuffer(iotjs_bufferwrap_t* bufferwrap) { IOTJS_VALIDATABLE_STRUCT_METHOD_VALIDATE(iotjs_bufferwrap_t, bufferwrap); iotjs_jval_t* jbuiltin = iotjs_bufferwrap_jbuiltin(bufferwrap); return iotjs_jval_get_property(jbuiltin, IOTJS_MAGIC_STRING__BUFFER); } char* iotjs_bufferwrap_buffer(iotjs_bufferwrap_t* bufferwrap) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_bufferwrap_t, bufferwrap); return _this->buffer; } size_t iotjs_bufferwrap_length(iotjs_bufferwrap_t* bufferwrap) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_bufferwrap_t, bufferwrap); #ifndef NDEBUG iotjs_jval_t jbuf = iotjs_bufferwrap_jbuffer(bufferwrap); iotjs_jval_t jlength = iotjs_jval_get_property(&jbuf, IOTJS_MAGIC_STRING_LENGTH); size_t length = iotjs_jval_as_number(&jlength); IOTJS_ASSERT(length == _this->length); iotjs_jval_destroy(&jbuf); iotjs_jval_destroy(&jlength); #endif return _this->length; } static size_t bound_range(size_t index, size_t low, size_t upper) { if (index == SIZE_MAX) { return low; } if (index > upper) { return upper; } return index; } static int8_t hex2bin(char c) { if (c >= '0' && c <= '9') return (int8_t)(c - '0'); if (c >= 'A' && c <= 'F') return (int8_t)(10 + (c - 'A')); if (c >= 'a' && c <= 'f') return (int8_t)(10 + (c - 'a')); return (int8_t)(-1); } static size_t hex_decode(char* buf, size_t len, const char* src, const size_t srcLen) { size_t i; for (i = 0; i < len && i * 2 + 1 < srcLen; ++i) { int8_t a = hex2bin(src[i * 2 + 0]); int8_t b = hex2bin(src[i * 2 + 1]); if (a == -1 || b == -1) return i; buf[i] = (a << 4) | b; } return i; } int iotjs_bufferwrap_compare(const iotjs_bufferwrap_t* bufferwrap, const iotjs_bufferwrap_t* other) { const IOTJS_VALIDATED_STRUCT_METHOD(iotjs_bufferwrap_t, bufferwrap); const char* other_buffer = other->unsafe.buffer; size_t other_length = other->unsafe.length; size_t i = 0; size_t j = 0; while (i < _this->length && j < other_length) { if (_this->buffer[i] < other_buffer[j]) { return -1; } else if (_this->buffer[i] > other_buffer[j]) { return 1; } ++i; ++j; } if (j < other_length) { return -1; } else if (i < _this->length) { return 1; } return 0; } size_t iotjs_bufferwrap_copy_internal(iotjs_bufferwrap_t* bufferwrap, const char* src, size_t src_from, size_t src_to, size_t dst_from) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_bufferwrap_t, bufferwrap); size_t copied = 0; size_t dst_length = _this->length; for (size_t i = src_from, j = dst_from; i < src_to && j < dst_length; ++i, ++j) { *(_this->buffer + j) = *(src + i); ++copied; } return copied; } size_t iotjs_bufferwrap_copy(iotjs_bufferwrap_t* bufferwrap, const char* src, size_t len) { IOTJS_VALIDATABLE_STRUCT_METHOD_VALIDATE(iotjs_bufferwrap_t, bufferwrap); return iotjs_bufferwrap_copy_internal(bufferwrap, src, 0, len, 0); } iotjs_jval_t iotjs_bufferwrap_create_buffer(size_t len) { iotjs_jval_t* jglobal = iotjs_jval_get_global_object(); iotjs_jval_t jbuffer = iotjs_jval_get_property(jglobal, IOTJS_MAGIC_STRING_BUFFER); IOTJS_ASSERT(iotjs_jval_is_function(&jbuffer)); iotjs_jargs_t jargs = iotjs_jargs_create(1); iotjs_jargs_append_number(&jargs, len); iotjs_jval_t jres = iotjs_jhelper_call_ok(&jbuffer, iotjs_jval_get_undefined(), &jargs); IOTJS_ASSERT(iotjs_jval_is_object(&jres)); iotjs_jargs_destroy(&jargs); iotjs_jval_destroy(&jbuffer); return jres; } JHANDLER_FUNCTION(Buffer) { DJHANDLER_CHECK_THIS(object); DJHANDLER_CHECK_ARGS(2, object, number); const iotjs_jval_t* jbuiltin = JHANDLER_GET_THIS(object); const iotjs_jval_t* jbuffer = JHANDLER_GET_ARG(0, object); size_t length = JHANDLER_GET_ARG(1, number); iotjs_jval_set_property_jval(jbuiltin, IOTJS_MAGIC_STRING__BUFFER, jbuffer); iotjs_bufferwrap_t* buffer_wrap = iotjs_bufferwrap_create(jbuiltin, length); IOTJS_UNUSED(buffer_wrap); } JHANDLER_FUNCTION(Compare) { JHANDLER_DECLARE_THIS_PTR(bufferwrap, src_buffer_wrap); DJHANDLER_CHECK_ARGS(1, object); const iotjs_jval_t* jdst_buffer = JHANDLER_GET_ARG(0, object); iotjs_bufferwrap_t* dst_buffer_wrap = iotjs_bufferwrap_from_jbuffer(jdst_buffer); int compare = iotjs_bufferwrap_compare(src_buffer_wrap, dst_buffer_wrap); iotjs_jhandler_return_number(jhandler, compare); } #define DECLARE_SIZE_T_FROM_DOUBLE(n, d) \ size_t n; \ do { \ if (d < 0 || isnan(d) || isinf(d)) { \ n = SIZE_MAX; \ } else { \ n = (size_t)d; \ } \ } while (0) JHANDLER_FUNCTION(Copy) { JHANDLER_DECLARE_THIS_PTR(bufferwrap, src_buffer_wrap); DJHANDLER_CHECK_ARGS(4, object, number, number, number); const iotjs_jval_t* jdst_buffer = JHANDLER_GET_ARG(0, object); iotjs_bufferwrap_t* dst_buffer_wrap = iotjs_bufferwrap_from_jbuffer(jdst_buffer); size_t dst_length = iotjs_bufferwrap_length(dst_buffer_wrap); size_t src_length = iotjs_bufferwrap_length(src_buffer_wrap); DECLARE_SIZE_T_FROM_DOUBLE(dst_start, JHANDLER_GET_ARG(1, number)); dst_start = bound_range(dst_start, 0, dst_length); DECLARE_SIZE_T_FROM_DOUBLE(src_start, JHANDLER_GET_ARG(2, number)); src_start = bound_range(src_start, 0, src_length); DECLARE_SIZE_T_FROM_DOUBLE(src_end, JHANDLER_GET_ARG(3, number)); src_end = bound_range(src_end, 0, src_length); if (src_end < src_start) { src_end = src_start; } const char* src_data = iotjs_bufferwrap_buffer(src_buffer_wrap); size_t copied = iotjs_bufferwrap_copy_internal(dst_buffer_wrap, src_data, src_start, src_end, dst_start); iotjs_jhandler_return_number(jhandler, copied); } JHANDLER_FUNCTION(Write) { JHANDLER_DECLARE_THIS_PTR(bufferwrap, buffer_wrap); DJHANDLER_CHECK_ARGS(3, string, number, number); iotjs_string_t src = JHANDLER_GET_ARG(0, string); size_t buffer_length = iotjs_bufferwrap_length(buffer_wrap); DECLARE_SIZE_T_FROM_DOUBLE(offset, JHANDLER_GET_ARG(1, number)); offset = bound_range(offset, 0, buffer_length); DECLARE_SIZE_T_FROM_DOUBLE(length, JHANDLER_GET_ARG(2, number)); length = bound_range(length, 0, buffer_length - offset); length = bound_range(length, 0, iotjs_string_size(&src)); const char* src_data = iotjs_string_data(&src); size_t copied = iotjs_bufferwrap_copy_internal(buffer_wrap, src_data, 0, length, offset); iotjs_jhandler_return_number(jhandler, copied); iotjs_string_destroy(&src); } JHANDLER_FUNCTION(WriteUInt8) { JHANDLER_DECLARE_THIS_PTR(bufferwrap, buffer_wrap); DJHANDLER_CHECK_ARGS(2, number, number); const char src[] = { (char)JHANDLER_GET_ARG(0, number) }; size_t length = 1; size_t buffer_length = iotjs_bufferwrap_length(buffer_wrap); DECLARE_SIZE_T_FROM_DOUBLE(offset, JHANDLER_GET_ARG(1, number)); offset = bound_range(offset, 0, buffer_length); length = bound_range(length, 0, buffer_length - offset); length = bound_range(length, 0, 1); size_t copied = iotjs_bufferwrap_copy_internal(buffer_wrap, src, 0, length, offset); iotjs_jhandler_return_number(jhandler, copied); } JHANDLER_FUNCTION(HexWrite) { JHANDLER_DECLARE_THIS_PTR(bufferwrap, buffer_wrap); DJHANDLER_CHECK_ARGS(3, string, number, number); iotjs_string_t src = JHANDLER_GET_ARG(0, string); size_t buffer_length = iotjs_bufferwrap_length(buffer_wrap); DECLARE_SIZE_T_FROM_DOUBLE(offset, JHANDLER_GET_ARG(1, number)); offset = bound_range(offset, 0, buffer_length); DECLARE_SIZE_T_FROM_DOUBLE(length, JHANDLER_GET_ARG(2, number)); length = bound_range(length, 0, buffer_length - offset); const char* src_data = iotjs_string_data(&src); unsigned src_length = iotjs_string_size(&src); char* src_buf = iotjs_buffer_allocate(length); size_t nbytes = hex_decode(src_buf, length, src_data, src_length); size_t copied = iotjs_bufferwrap_copy_internal(buffer_wrap, src_buf, 0, nbytes, offset); iotjs_jhandler_return_number(jhandler, copied); iotjs_buffer_release(src_buf); iotjs_string_destroy(&src); } JHANDLER_FUNCTION(ReadUInt8) { JHANDLER_DECLARE_THIS_PTR(bufferwrap, buffer_wrap); DJHANDLER_CHECK_ARGS(1, number); size_t buffer_length = iotjs_bufferwrap_length(buffer_wrap); DECLARE_SIZE_T_FROM_DOUBLE(offset, JHANDLER_GET_ARG(0, number)); offset = bound_range(offset, 0, buffer_length - 1); char* buffer = iotjs_bufferwrap_buffer(buffer_wrap); iotjs_jhandler_return_number(jhandler, (uint8_t)buffer[offset]); } JHANDLER_FUNCTION(Slice) { JHANDLER_DECLARE_THIS_PTR(bufferwrap, buffer_wrap); DJHANDLER_CHECK_ARGS(2, number, number); int64_t start = JHANDLER_GET_ARG(0, number); int64_t end = JHANDLER_GET_ARG(1, number); size_t start_idx, end_idx; if (start < 0) { size_t len = iotjs_bufferwrap_length(buffer_wrap); if ((size_t)(-start) > len) { start_idx = SIZE_MAX; } else { start_idx = (size_t)start + len; } } else { start_idx = (size_t)start; } start_idx = bound_range(start_idx, 0, iotjs_bufferwrap_length(buffer_wrap)); if (end < 0) { size_t len = iotjs_bufferwrap_length(buffer_wrap); if ((size_t)(-end) > len) { end_idx = SIZE_MAX; } else { end_idx = (size_t)end + len; } } else { end_idx = (size_t)end; } end_idx = bound_range(end_idx, 0, iotjs_bufferwrap_length(buffer_wrap)); if (end_idx < start_idx) { end_idx = start_idx; } size_t length = (size_t)(end_idx - start_idx); iotjs_jval_t jnew_buffer = iotjs_bufferwrap_create_buffer(length); iotjs_bufferwrap_t* new_buffer_wrap = iotjs_bufferwrap_from_jbuffer(&jnew_buffer); iotjs_bufferwrap_copy_internal(new_buffer_wrap, iotjs_bufferwrap_buffer(buffer_wrap), start_idx, end_idx, 0); iotjs_jhandler_return_jval(jhandler, &jnew_buffer); iotjs_jval_destroy(&jnew_buffer); } JHANDLER_FUNCTION(ToString) { JHANDLER_DECLARE_THIS_PTR(bufferwrap, buffer_wrap); DJHANDLER_CHECK_ARGS(2, number, number); DECLARE_SIZE_T_FROM_DOUBLE(start, JHANDLER_GET_ARG(0, number)); start = bound_range(start, 0, iotjs_bufferwrap_length(buffer_wrap)); DECLARE_SIZE_T_FROM_DOUBLE(end, JHANDLER_GET_ARG(1, number)); end = bound_range(end, 0, iotjs_bufferwrap_length(buffer_wrap)); if (end < start) { end = start; } size_t length = end - start; const char* data = iotjs_bufferwrap_buffer(buffer_wrap) + start; length = strnlen(data, length); iotjs_string_t str = iotjs_string_create_with_size(data, length); iotjs_jhandler_return_string(jhandler, &str); iotjs_string_destroy(&str); } JHANDLER_FUNCTION(ToHexString) { JHANDLER_DECLARE_THIS_PTR(bufferwrap, buffer_wrap); size_t length = iotjs_bufferwrap_length(buffer_wrap); const char* data = iotjs_bufferwrap_buffer(buffer_wrap); char* buffer = iotjs_buffer_allocate(length * 2); iotjs_string_t str = iotjs_string_create_with_buffer(buffer, length * 2); for (size_t i = 0; i < length; i++) { memcpy(buffer, &"0123456789abcdef"[data[i] >> 4 & 0xF], 1); buffer++; memcpy(buffer, &"0123456789abcdef"[data[i] >> 0 & 0xF], 1); buffer++; } iotjs_jhandler_return_string(jhandler, &str); iotjs_string_destroy(&str); } JHANDLER_FUNCTION(ByteLength) { DJHANDLER_CHECK_THIS(object); DJHANDLER_CHECK_ARGS(1, string); iotjs_string_t str = JHANDLER_GET_ARG(0, string); iotjs_jval_t size = iotjs_jval_get_string_size(&str); iotjs_jhandler_return_jval(jhandler, &size); iotjs_string_destroy(&str); iotjs_jval_destroy(&size); } iotjs_jval_t InitBuffer() { iotjs_jval_t buffer = iotjs_jval_create_function_with_dispatch(Buffer); iotjs_jval_t prototype = iotjs_jval_create_object(); iotjs_jval_t byte_length = iotjs_jval_create_function_with_dispatch(ByteLength); iotjs_jval_set_property_jval(&buffer, IOTJS_MAGIC_STRING_PROTOTYPE, &prototype); iotjs_jval_set_property_jval(&buffer, IOTJS_MAGIC_STRING_BYTELENGTH, &byte_length); iotjs_jval_set_method(&prototype, IOTJS_MAGIC_STRING_COMPARE, Compare); iotjs_jval_set_method(&prototype, IOTJS_MAGIC_STRING_COPY, Copy); iotjs_jval_set_method(&prototype, IOTJS_MAGIC_STRING_WRITE, Write); iotjs_jval_set_method(&prototype, IOTJS_MAGIC_STRING_HEXWRITE, HexWrite); iotjs_jval_set_method(&prototype, IOTJS_MAGIC_STRING_WRITEUINT8, WriteUInt8); iotjs_jval_set_method(&prototype, IOTJS_MAGIC_STRING_READUINT8, ReadUInt8); iotjs_jval_set_method(&prototype, IOTJS_MAGIC_STRING_SLICE, Slice); iotjs_jval_set_method(&prototype, IOTJS_MAGIC_STRING_TOSTRING, ToString); iotjs_jval_set_method(&prototype, IOTJS_MAGIC_STRING_TOHEXSTRING, ToHexString); iotjs_jval_destroy(&prototype); iotjs_jval_destroy(&byte_length); return buffer; } iotjs-1.0/src/modules/iotjs_module_buffer.h000066400000000000000000000034271312466455500211610ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef IOTJS_MODULE_BUFFER_H #define IOTJS_MODULE_BUFFER_H #include "iotjs_objectwrap.h" typedef struct { iotjs_jobjectwrap_t jobjectwrap; char* buffer; size_t length; } IOTJS_VALIDATED_STRUCT(iotjs_bufferwrap_t); iotjs_bufferwrap_t* iotjs_bufferwrap_create(const iotjs_jval_t* jbuiltin, size_t length); iotjs_bufferwrap_t* iotjs_bufferwrap_from_jbuiltin( const iotjs_jval_t* jbuiltin); iotjs_bufferwrap_t* iotjs_bufferwrap_from_jbuffer(const iotjs_jval_t* jbuffer); iotjs_jval_t* iotjs_bufferwrap_jbuiltin(iotjs_bufferwrap_t* bufferwrap); iotjs_jval_t iotjs_bufferwrap_jbuffer(iotjs_bufferwrap_t* bufferwrap); char* iotjs_bufferwrap_buffer(iotjs_bufferwrap_t* bufferwrap); size_t iotjs_bufferwrap_length(iotjs_bufferwrap_t* bufferwrap); int iotjs_bufferwrap_compare(const iotjs_bufferwrap_t* bufferwrap, const iotjs_bufferwrap_t* other); size_t iotjs_bufferwrap_copy(iotjs_bufferwrap_t* bufferwrap, const char* src, size_t len); // Create buffer object. iotjs_jval_t iotjs_bufferwrap_create_buffer(size_t len); #endif /* IOTJS_MODULE_BUFFER_H */ iotjs-1.0/src/modules/iotjs_module_console.c000066400000000000000000000023551312466455500213440ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "iotjs_def.h" static void Print(iotjs_jhandler_t* jhandler, FILE* out_fd) { JHANDLER_CHECK_ARGS(1, string); iotjs_string_t msg = JHANDLER_GET_ARG(0, string); fprintf(out_fd, "%s", iotjs_string_data(&msg)); iotjs_string_destroy(&msg); } JHANDLER_FUNCTION(Stdout) { Print(jhandler, stdout); } JHANDLER_FUNCTION(Stderr) { Print(jhandler, stderr); } iotjs_jval_t InitConsole() { iotjs_jval_t console = iotjs_jval_create_object(); iotjs_jval_set_method(&console, IOTJS_MAGIC_STRING_STDOUT, Stdout); iotjs_jval_set_method(&console, IOTJS_MAGIC_STRING_STDERR, Stderr); return console; } iotjs-1.0/src/modules/iotjs_module_constants.c000066400000000000000000000026201312466455500217110ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "iotjs_def.h" #include "iotjs_module.h" #define SET_CONSTANT(object, constant) \ do { \ iotjs_jval_set_property_number(object, #constant, constant); \ } while (0) iotjs_jval_t InitConstants() { iotjs_jval_t constants = iotjs_jval_create_object(); SET_CONSTANT(&constants, O_APPEND); SET_CONSTANT(&constants, O_CREAT); SET_CONSTANT(&constants, O_EXCL); SET_CONSTANT(&constants, O_RDONLY); SET_CONSTANT(&constants, O_RDWR); SET_CONSTANT(&constants, O_SYNC); SET_CONSTANT(&constants, O_TRUNC); SET_CONSTANT(&constants, O_WRONLY); SET_CONSTANT(&constants, S_IFMT); SET_CONSTANT(&constants, S_IFDIR); SET_CONSTANT(&constants, S_IFREG); return constants; } iotjs-1.0/src/modules/iotjs_module_dns.c000066400000000000000000000136351312466455500204710ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "iotjs_def.h" #include "iotjs_module_dns.h" #include "iotjs_reqwrap.h" #include "uv.h" #define THIS iotjs_getaddrinfo_reqwrap_t* getaddrinfo_reqwrap iotjs_getaddrinfo_reqwrap_t* iotjs_getaddrinfo_reqwrap_create( const iotjs_jval_t* jcallback) { iotjs_getaddrinfo_reqwrap_t* getaddrinfo_reqwrap = IOTJS_ALLOC(iotjs_getaddrinfo_reqwrap_t); IOTJS_VALIDATED_STRUCT_CONSTRUCTOR(iotjs_getaddrinfo_reqwrap_t, getaddrinfo_reqwrap); iotjs_reqwrap_initialize(&_this->reqwrap, jcallback, (uv_req_t*)&_this->req); return getaddrinfo_reqwrap; } static void iotjs_getaddrinfo_reqwrap_destroy(THIS) { IOTJS_VALIDATED_STRUCT_DESTRUCTOR(iotjs_getaddrinfo_reqwrap_t, getaddrinfo_reqwrap); iotjs_reqwrap_destroy(&_this->reqwrap); IOTJS_RELEASE(getaddrinfo_reqwrap); } void iotjs_getaddrinfo_reqwrap_dispatched(THIS) { IOTJS_VALIDATABLE_STRUCT_METHOD_VALIDATE(iotjs_getaddrinfo_reqwrap_t, getaddrinfo_reqwrap); iotjs_getaddrinfo_reqwrap_destroy(getaddrinfo_reqwrap); } uv_getaddrinfo_t* iotjs_getaddrinfo_reqwrap_req(THIS) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_getaddrinfo_reqwrap_t, getaddrinfo_reqwrap); return &_this->req; } const iotjs_jval_t* iotjs_getaddrinfo_reqwrap_jcallback(THIS) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_getaddrinfo_reqwrap_t, getaddrinfo_reqwrap); return iotjs_reqwrap_jcallback(&_this->reqwrap); } #undef THIS #if !defined(__NUTTX__) && !defined(__TIZENRT__) static void AfterGetAddrInfo(uv_getaddrinfo_t* req, int status, struct addrinfo* res) { iotjs_getaddrinfo_reqwrap_t* req_wrap = (iotjs_getaddrinfo_reqwrap_t*)(req->data); iotjs_jargs_t args = iotjs_jargs_create(3); iotjs_jargs_append_number(&args, status); if (status == 0) { char ip[INET6_ADDRSTRLEN]; int family; const char* addr; // Only first address is used if (res->ai_family == AF_INET) { struct sockaddr_in* sockaddr = (struct sockaddr_in*)(res->ai_addr); addr = (char*)(&(sockaddr->sin_addr)); family = 4; } else { struct sockaddr_in6* sockaddr = (struct sockaddr_in6*)(res->ai_addr); addr = (char*)(&(sockaddr->sin6_addr)); family = 6; } int err = uv_inet_ntop(res->ai_family, addr, ip, INET6_ADDRSTRLEN); if (err) { ip[0] = 0; } iotjs_jargs_append_string_raw(&args, ip); iotjs_jargs_append_number(&args, family); } uv_freeaddrinfo(res); // Make the callback into JavaScript iotjs_make_callback(iotjs_getaddrinfo_reqwrap_jcallback(req_wrap), iotjs_jval_get_undefined(), &args); iotjs_jargs_destroy(&args); iotjs_getaddrinfo_reqwrap_dispatched(req_wrap); } #endif JHANDLER_FUNCTION(GetAddrInfo) { DJHANDLER_CHECK_THIS(object); DJHANDLER_CHECK_ARGS(4, string, number, number, function); iotjs_string_t hostname = JHANDLER_GET_ARG(0, string); int option = JHANDLER_GET_ARG(1, number); int flags = JHANDLER_GET_ARG(2, number); const iotjs_jval_t* jcallback = JHANDLER_GET_ARG(3, function); int family; if (option == 0) { #if defined(__NUTTX__) || defined(__TIZENRT__) family = AF_INET; #else family = AF_UNSPEC; #endif } else if (option == 4) { family = AF_INET; } else if (option == 6) { family = AF_INET6; } else { JHANDLER_THROW(TYPE, "bad address family"); return; } #if defined(__NUTTX__) || defined(__TIZENRT__) iotjs_jargs_t args = iotjs_jargs_create(3); int err = 0; char ip[INET6_ADDRSTRLEN]; const char* hostname_data = iotjs_string_data(&hostname); if (strcmp(hostname_data, "localhost") == 0) { strcpy(ip, "127.0.0.1"); } else { struct sockaddr_in addr; int result = inet_pton(family, hostname_data, &(addr.sin_addr)); if (result != 1) { err = errno; } else { inet_ntop(family, &(addr.sin_addr), ip, INET6_ADDRSTRLEN); } } iotjs_jargs_append_number(&args, err); iotjs_jargs_append_string_raw(&args, ip); iotjs_jargs_append_number(&args, option); iotjs_make_callback(jcallback, iotjs_jval_get_undefined(), &args); iotjs_jargs_destroy(&args); IOTJS_UNUSED(flags); #else iotjs_getaddrinfo_reqwrap_t* req_wrap = iotjs_getaddrinfo_reqwrap_create(jcallback); static const struct addrinfo empty_hints; struct addrinfo hints = empty_hints; hints.ai_family = family; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = flags; int err = uv_getaddrinfo(iotjs_environment_loop(iotjs_environment_get()), iotjs_getaddrinfo_reqwrap_req(req_wrap), AfterGetAddrInfo, iotjs_string_data(&hostname), NULL, &hints); if (err) { iotjs_getaddrinfo_reqwrap_dispatched(req_wrap); } #endif iotjs_jhandler_return_number(jhandler, err); iotjs_string_destroy(&hostname); } #define SET_CONSTANT(object, constant) \ do { \ iotjs_jval_set_property_number(object, #constant, constant); \ } while (0) iotjs_jval_t InitDns() { iotjs_jval_t dns = iotjs_jval_create_object(); iotjs_jval_set_method(&dns, IOTJS_MAGIC_STRING_GETADDRINFO, GetAddrInfo); SET_CONSTANT(&dns, AI_ADDRCONFIG); SET_CONSTANT(&dns, AI_V4MAPPED); return dns; } iotjs-1.0/src/modules/iotjs_module_dns.h000066400000000000000000000023441312466455500204710ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef IOTJS_MODULE_DNS_H #define IOTJS_MODULE_DNS_H #include "iotjs_def.h" #include "iotjs_reqwrap.h" typedef struct { iotjs_reqwrap_t reqwrap; uv_getaddrinfo_t req; } IOTJS_VALIDATED_STRUCT(iotjs_getaddrinfo_reqwrap_t); #define THIS iotjs_getaddrinfo_reqwrap_t* getaddrinfo_reqwrap iotjs_getaddrinfo_reqwrap_t* iotjs_getaddrinfo_reqwrap_create( const iotjs_jval_t* jcallback); void iotjs_getaddrinfo_reqwrap_dispatched(THIS); uv_getaddrinfo_t* iotjs_getaddrinfo_reqwrap_req(THIS); const iotjs_jval_t* iotjs_getaddrinfo_reqwrap_jcallback(THIS); #undef THIS #endif /* IOTJS_MODULE_DNS_H */ iotjs-1.0/src/modules/iotjs_module_fs.c000066400000000000000000000365341312466455500203200ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "iotjs_def.h" #include "iotjs_module_fs.h" #include "iotjs_module_buffer.h" #include "iotjs_exception.h" #include "iotjs_reqwrap.h" #undef JHANDLER_FUNCTION #define JHANDLER_FUNCTION(name) static void name(iotjs_jhandler_t* jhandler) iotjs_fs_reqwrap_t* iotjs_fs_reqwrap_create(const iotjs_jval_t* jcallback) { iotjs_fs_reqwrap_t* fs_reqwrap = IOTJS_ALLOC(iotjs_fs_reqwrap_t); IOTJS_VALIDATED_STRUCT_CONSTRUCTOR(iotjs_fs_reqwrap_t, fs_reqwrap); iotjs_reqwrap_initialize(&_this->reqwrap, jcallback, (uv_req_t*)&_this->req); return fs_reqwrap; } static void iotjs_fs_reqwrap_destroy(iotjs_fs_reqwrap_t* fs_reqwrap) { IOTJS_VALIDATED_STRUCT_DESTRUCTOR(iotjs_fs_reqwrap_t, fs_reqwrap); uv_fs_req_cleanup(&_this->req); iotjs_reqwrap_destroy(&_this->reqwrap); IOTJS_RELEASE(fs_reqwrap); } void iotjs_fs_reqwrap_dispatched(iotjs_fs_reqwrap_t* fs_reqwrap) { IOTJS_VALIDATABLE_STRUCT_METHOD_VALIDATE(iotjs_fs_reqwrap_t, fs_reqwrap); iotjs_fs_reqwrap_destroy(fs_reqwrap); } uv_fs_t* iotjs_fs_reqwrap_req(iotjs_fs_reqwrap_t* fs_reqwrap) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_fs_reqwrap_t, fs_reqwrap); return &_this->req; } const iotjs_jval_t* iotjs_fs_reqwrap_jcallback(iotjs_fs_reqwrap_t* fs_reqwrap) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_fs_reqwrap_t, fs_reqwrap); return iotjs_reqwrap_jcallback(&_this->reqwrap); } iotjs_jval_t MakeStatObject(uv_stat_t* statbuf); static void AfterAsync(uv_fs_t* req) { iotjs_fs_reqwrap_t* req_wrap = (iotjs_fs_reqwrap_t*)(req->data); IOTJS_ASSERT(req_wrap != NULL); IOTJS_ASSERT(iotjs_fs_reqwrap_req(req_wrap) == req); const iotjs_jval_t* cb = iotjs_fs_reqwrap_jcallback(req_wrap); IOTJS_ASSERT(iotjs_jval_is_function(cb)); iotjs_jargs_t jarg = iotjs_jargs_create(2); if (req->result < 0) { iotjs_jval_t jerror = iotjs_create_uv_exception(req->result, "open"); iotjs_jargs_append_jval(&jarg, &jerror); iotjs_jval_destroy(&jerror); } else { iotjs_jargs_append_null(&jarg); switch (req->fs_type) { case UV_FS_CLOSE: { break; } case UV_FS_OPEN: case UV_FS_READ: case UV_FS_WRITE: { iotjs_jargs_append_number(&jarg, (double)req->result); break; } case UV_FS_SCANDIR: { int r; uv_dirent_t ent; uint32_t idx = 0; iotjs_jval_t ret = iotjs_jval_create_array(0); while ((r = uv_fs_scandir_next(req, &ent)) != UV_EOF) { iotjs_jval_t name = iotjs_jval_create_string_raw(ent.name); iotjs_jval_set_property_by_index(&ret, idx, &name); iotjs_jval_destroy(&name); idx++; } iotjs_jargs_append_jval(&jarg, &ret); iotjs_jval_destroy(&ret); break; } case UV_FS_FSTAT: case UV_FS_STAT: { uv_stat_t s = (req->statbuf); iotjs_jval_t ret = MakeStatObject(&s); iotjs_jargs_append_jval(&jarg, &ret); iotjs_jval_destroy(&ret); break; } default: { iotjs_jargs_append_null(&jarg); break; } } } iotjs_make_callback(cb, iotjs_jval_get_undefined(), &jarg); iotjs_jargs_destroy(&jarg); iotjs_fs_reqwrap_dispatched(req_wrap); } static void AfterSync(uv_fs_t* req, int err, const char* syscall_name, iotjs_jhandler_t* jhandler) { if (err < 0) { iotjs_jval_t jerror = iotjs_create_uv_exception(err, syscall_name); iotjs_jhandler_throw(jhandler, &jerror); iotjs_jval_destroy(&jerror); } else { switch (req->fs_type) { case UV_FS_CLOSE: break; case UV_FS_OPEN: case UV_FS_READ: case UV_FS_WRITE: iotjs_jhandler_return_number(jhandler, err); break; case UV_FS_FSTAT: case UV_FS_STAT: { uv_stat_t* s = &(req->statbuf); iotjs_jval_t stat = MakeStatObject(s); iotjs_jhandler_return_jval(jhandler, &stat); iotjs_jval_destroy(&stat); break; } case UV_FS_MKDIR: case UV_FS_RMDIR: case UV_FS_UNLINK: case UV_FS_RENAME: iotjs_jhandler_return_undefined(jhandler); break; case UV_FS_SCANDIR: { int r; uv_dirent_t ent; uint32_t idx = 0; iotjs_jval_t ret = iotjs_jval_create_array(0); while ((r = uv_fs_scandir_next(req, &ent)) != UV_EOF) { iotjs_jval_t name = iotjs_jval_create_string_raw(ent.name); iotjs_jval_set_property_by_index(&ret, idx, &name); iotjs_jval_destroy(&name); idx++; } iotjs_jhandler_return_jval(jhandler, &ret); iotjs_jval_destroy(&ret); break; } default: { IOTJS_ASSERT(false); break; } } } } static inline bool IsWithinBounds(size_t off, size_t len, size_t max) { if (off > max) return false; if (max - off < len) return false; return true; } #define FS_ASYNC(env, syscall, pcallback, ...) \ iotjs_fs_reqwrap_t* req_wrap = iotjs_fs_reqwrap_create(pcallback); \ uv_fs_t* fs_req = iotjs_fs_reqwrap_req(req_wrap); \ int err = uv_fs_##syscall(iotjs_environment_loop(env), fs_req, __VA_ARGS__, \ AfterAsync); \ if (err < 0) { \ fs_req->result = err; \ AfterAsync(fs_req); \ } \ iotjs_jhandler_return_null(jhandler); #define FS_SYNC(env, syscall, ...) \ uv_fs_t fs_req; \ int err = uv_fs_##syscall(iotjs_environment_loop(env), &fs_req, __VA_ARGS__, \ NULL); \ AfterSync(&fs_req, err, #syscall, jhandler); \ uv_fs_req_cleanup(&fs_req); JHANDLER_FUNCTION(Close) { DJHANDLER_CHECK_THIS(object); DJHANDLER_CHECK_ARGS(1, number); DJHANDLER_CHECK_ARG_IF_EXIST(1, function); const iotjs_environment_t* env = iotjs_environment_get(); int fd = JHANDLER_GET_ARG(0, number); const iotjs_jval_t* jcallback = JHANDLER_GET_ARG_IF_EXIST(1, function); if (jcallback) { FS_ASYNC(env, close, jcallback, fd); } else { FS_SYNC(env, close, fd); } } JHANDLER_FUNCTION(Open) { DJHANDLER_CHECK_THIS(object); DJHANDLER_CHECK_ARGS(3, string, number, number); DJHANDLER_CHECK_ARG_IF_EXIST(3, function); const iotjs_environment_t* env = iotjs_environment_get(); iotjs_string_t path = JHANDLER_GET_ARG(0, string); int flags = JHANDLER_GET_ARG(1, number); int mode = JHANDLER_GET_ARG(2, number); const iotjs_jval_t* jcallback = JHANDLER_GET_ARG_IF_EXIST(3, function); if (jcallback) { FS_ASYNC(env, open, jcallback, iotjs_string_data(&path), flags, mode); } else { FS_SYNC(env, open, iotjs_string_data(&path), flags, mode); } iotjs_string_destroy(&path); } JHANDLER_FUNCTION(Read) { DJHANDLER_CHECK_THIS(object); DJHANDLER_CHECK_ARGS(5, number, object, number, number, number); DJHANDLER_CHECK_ARG_IF_EXIST(5, function); const iotjs_environment_t* env = iotjs_environment_get(); int fd = JHANDLER_GET_ARG(0, number); const iotjs_jval_t* jbuffer = JHANDLER_GET_ARG(1, object); size_t offset = JHANDLER_GET_ARG(2, number); size_t length = JHANDLER_GET_ARG(3, number); int position = JHANDLER_GET_ARG(4, number); const iotjs_jval_t* jcallback = JHANDLER_GET_ARG_IF_EXIST(5, function); iotjs_bufferwrap_t* buffer_wrap = iotjs_bufferwrap_from_jbuffer(jbuffer); char* data = iotjs_bufferwrap_buffer(buffer_wrap); size_t data_length = iotjs_bufferwrap_length(buffer_wrap); JHANDLER_CHECK(data != NULL); JHANDLER_CHECK(data_length > 0); if (offset >= data_length) { JHANDLER_THROW(RANGE, "offset out of bound"); return; } if (!IsWithinBounds(offset, length, data_length)) { JHANDLER_THROW(RANGE, "length out of bound"); return; } uv_buf_t uvbuf = uv_buf_init(data + offset, length); if (jcallback) { FS_ASYNC(env, read, jcallback, fd, &uvbuf, 1, position); } else { FS_SYNC(env, read, fd, &uvbuf, 1, position); } } JHANDLER_FUNCTION(Write) { DJHANDLER_CHECK_THIS(object); DJHANDLER_CHECK_ARGS(5, number, object, number, number, number); DJHANDLER_CHECK_ARG_IF_EXIST(5, function); const iotjs_environment_t* env = iotjs_environment_get(); int fd = JHANDLER_GET_ARG(0, number); const iotjs_jval_t* jbuffer = JHANDLER_GET_ARG(1, object); size_t offset = JHANDLER_GET_ARG(2, number); size_t length = JHANDLER_GET_ARG(3, number); int position = JHANDLER_GET_ARG(4, number); const iotjs_jval_t* jcallback = JHANDLER_GET_ARG_IF_EXIST(5, function); iotjs_bufferwrap_t* buffer_wrap = iotjs_bufferwrap_from_jbuffer(jbuffer); char* data = iotjs_bufferwrap_buffer(buffer_wrap); size_t data_length = iotjs_bufferwrap_length(buffer_wrap); JHANDLER_CHECK(data != NULL); JHANDLER_CHECK(data_length > 0); if (offset >= data_length) { JHANDLER_THROW(RANGE, "offset out of bound"); return; } if (!IsWithinBounds(offset, length, data_length)) { JHANDLER_THROW(RANGE, "length out of bound"); return; } uv_buf_t uvbuf = uv_buf_init(data + offset, length); if (jcallback) { FS_ASYNC(env, write, jcallback, fd, &uvbuf, 1, position); } else { FS_SYNC(env, write, fd, &uvbuf, 1, position); } } iotjs_jval_t MakeStatObject(uv_stat_t* statbuf) { const iotjs_jval_t* fs = iotjs_module_get(MODULE_FS); iotjs_jval_t create_stat = iotjs_jval_get_property(fs, IOTJS_MAGIC_STRING__CREATESTAT); IOTJS_ASSERT(iotjs_jval_is_function(&create_stat)); iotjs_jval_t jstat = iotjs_jval_create_object(); #define X(statobj, name) \ iotjs_jval_set_property_number(statobj, #name, statbuf->st_##name); X(&jstat, dev) X(&jstat, mode) X(&jstat, nlink) X(&jstat, uid) X(&jstat, gid) X(&jstat, rdev) X(&jstat, blksize) X(&jstat, ino) X(&jstat, size) X(&jstat, blocks) #undef X iotjs_jargs_t jargs = iotjs_jargs_create(1); iotjs_jargs_append_jval(&jargs, &jstat); iotjs_jval_destroy(&jstat); iotjs_jval_t res = iotjs_jhelper_call_ok(&create_stat, iotjs_jval_get_undefined(), &jargs); iotjs_jargs_destroy(&jargs); iotjs_jval_destroy(&create_stat); return res; } JHANDLER_FUNCTION(Stat) { DJHANDLER_CHECK_THIS(object); DJHANDLER_CHECK_ARGS(1, string); DJHANDLER_CHECK_ARG_IF_EXIST(1, function); const iotjs_environment_t* env = iotjs_environment_get(); iotjs_string_t path = JHANDLER_GET_ARG(0, string); const iotjs_jval_t* jcallback = JHANDLER_GET_ARG_IF_EXIST(1, function); if (jcallback) { FS_ASYNC(env, stat, jcallback, iotjs_string_data(&path)); } else { FS_SYNC(env, stat, iotjs_string_data(&path)); } iotjs_string_destroy(&path); } JHANDLER_FUNCTION(Fstat) { DJHANDLER_CHECK_THIS(object); DJHANDLER_CHECK_ARGS(1, number); DJHANDLER_CHECK_ARG_IF_EXIST(1, function); const iotjs_environment_t* env = iotjs_environment_get(); int fd = JHANDLER_GET_ARG(0, number); const iotjs_jval_t* jcallback = JHANDLER_GET_ARG_IF_EXIST(1, function); if (jcallback) { FS_ASYNC(env, fstat, jcallback, fd); } else { FS_SYNC(env, fstat, fd); } } JHANDLER_FUNCTION(MkDir) { DJHANDLER_CHECK_THIS(object); DJHANDLER_CHECK_ARGS(2, string, number); DJHANDLER_CHECK_ARG_IF_EXIST(2, function); const iotjs_environment_t* env = iotjs_environment_get(); iotjs_string_t path = JHANDLER_GET_ARG(0, string); int mode = JHANDLER_GET_ARG(1, number); const iotjs_jval_t* jcallback = JHANDLER_GET_ARG_IF_EXIST(2, function); if (jcallback) { FS_ASYNC(env, mkdir, jcallback, iotjs_string_data(&path), mode); } else { FS_SYNC(env, mkdir, iotjs_string_data(&path), mode); } iotjs_string_destroy(&path); } JHANDLER_FUNCTION(RmDir) { DJHANDLER_CHECK_THIS(object); DJHANDLER_CHECK_ARGS(1, string); DJHANDLER_CHECK_ARG_IF_EXIST(1, function); const iotjs_environment_t* env = iotjs_environment_get(); iotjs_string_t path = JHANDLER_GET_ARG(0, string); const iotjs_jval_t* jcallback = JHANDLER_GET_ARG_IF_EXIST(1, function); if (jcallback) { FS_ASYNC(env, rmdir, jcallback, iotjs_string_data(&path)); } else { FS_SYNC(env, rmdir, iotjs_string_data(&path)); } iotjs_string_destroy(&path); } JHANDLER_FUNCTION(Unlink) { DJHANDLER_CHECK_THIS(object); DJHANDLER_CHECK_ARGS(1, string); DJHANDLER_CHECK_ARG_IF_EXIST(1, function); const iotjs_environment_t* env = iotjs_environment_get(); iotjs_string_t path = JHANDLER_GET_ARG(0, string); const iotjs_jval_t* jcallback = JHANDLER_GET_ARG_IF_EXIST(1, function); if (jcallback) { FS_ASYNC(env, unlink, jcallback, iotjs_string_data(&path)); } else { FS_SYNC(env, unlink, iotjs_string_data(&path)); } iotjs_string_destroy(&path); } JHANDLER_FUNCTION(Rename) { DJHANDLER_CHECK_THIS(object); DJHANDLER_CHECK_ARGS(2, string, string); DJHANDLER_CHECK_ARG_IF_EXIST(2, function); const iotjs_environment_t* env = iotjs_environment_get(); iotjs_string_t oldPath = JHANDLER_GET_ARG(0, string); iotjs_string_t newPath = JHANDLER_GET_ARG(1, string); const iotjs_jval_t* jcallback = JHANDLER_GET_ARG_IF_EXIST(2, function); if (jcallback) { FS_ASYNC(env, rename, jcallback, iotjs_string_data(&oldPath), iotjs_string_data(&newPath)); } else { FS_SYNC(env, rename, iotjs_string_data(&oldPath), iotjs_string_data(&newPath)); } iotjs_string_destroy(&oldPath); iotjs_string_destroy(&newPath); } JHANDLER_FUNCTION(ReadDir) { DJHANDLER_CHECK_THIS(object); DJHANDLER_CHECK_ARGS(1, string); DJHANDLER_CHECK_ARG_IF_EXIST(1, function); const iotjs_environment_t* env = iotjs_environment_get(); iotjs_string_t path = JHANDLER_GET_ARG(0, string); const iotjs_jval_t* jcallback = JHANDLER_GET_ARG_IF_EXIST(1, function); if (jcallback) { FS_ASYNC(env, scandir, jcallback, iotjs_string_data(&path), 0); } else { FS_SYNC(env, scandir, iotjs_string_data(&path), 0); } iotjs_string_destroy(&path); } iotjs_jval_t InitFs() { iotjs_jval_t fs = iotjs_jval_create_object(); iotjs_jval_set_method(&fs, IOTJS_MAGIC_STRING_CLOSE, Close); iotjs_jval_set_method(&fs, IOTJS_MAGIC_STRING_OPEN, Open); iotjs_jval_set_method(&fs, IOTJS_MAGIC_STRING_READ, Read); iotjs_jval_set_method(&fs, IOTJS_MAGIC_STRING_WRITE, Write); iotjs_jval_set_method(&fs, IOTJS_MAGIC_STRING_STAT, Stat); iotjs_jval_set_method(&fs, IOTJS_MAGIC_STRING_FSTAT, Fstat); iotjs_jval_set_method(&fs, IOTJS_MAGIC_STRING_MKDIR, MkDir); iotjs_jval_set_method(&fs, IOTJS_MAGIC_STRING_RMDIR, RmDir); iotjs_jval_set_method(&fs, IOTJS_MAGIC_STRING_UNLINK, Unlink); iotjs_jval_set_method(&fs, IOTJS_MAGIC_STRING_RENAME, Rename); iotjs_jval_set_method(&fs, IOTJS_MAGIC_STRING_READDIR, ReadDir); return fs; } iotjs-1.0/src/modules/iotjs_module_fs.h000066400000000000000000000022271312466455500203150ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef IOTJS_MODULE_FS_H #define IOTJS_MODULE_FS_H #include "iotjs_def.h" #include "iotjs_reqwrap.h" typedef struct { iotjs_reqwrap_t reqwrap; uv_fs_t req; } IOTJS_VALIDATED_STRUCT(iotjs_fs_reqwrap_t); iotjs_fs_reqwrap_t* iotjs_fs_reqwrap_create(const iotjs_jval_t* jcallback); void iotjs_fs_reqwrap_dispatched(iotjs_fs_reqwrap_t* fs_reqwrap); uv_fs_t* iotjs_fs_reqwrap_req(iotjs_fs_reqwrap_t* fs_reqwrap); const iotjs_jval_t* iotjs_fs_reqwrap_jcallback(iotjs_fs_reqwrap_t* fs_reqwrap); #endif /* IOTJS_MODULE_FS_H */ iotjs-1.0/src/modules/iotjs_module_gpio.c000066400000000000000000000304671312466455500206450ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include "iotjs_def.h" #include "iotjs_module_gpio.h" #include "iotjs_objectwrap.h" #include static iotjs_gpio_t* iotjs_gpio_instance_from_jval(const iotjs_jval_t* jgpio); IOTJS_DEFINE_NATIVE_HANDLE_INFO_THIS_MODULE(gpio); static iotjs_gpio_t* iotjs_gpio_create(const iotjs_jval_t* jgpio) { iotjs_gpio_t* gpio = IOTJS_ALLOC(iotjs_gpio_t); IOTJS_VALIDATED_STRUCT_CONSTRUCTOR(iotjs_gpio_t, gpio); iotjs_jobjectwrap_initialize(&_this->jobjectwrap, jgpio, &this_module_native_info); #if defined(__linux__) _this->value_fd = -1; #endif return gpio; } static void iotjs_gpio_destroy(iotjs_gpio_t* gpio) { IOTJS_VALIDATED_STRUCT_DESTRUCTOR(iotjs_gpio_t, gpio); iotjs_jobjectwrap_destroy(&_this->jobjectwrap); IOTJS_RELEASE(gpio); } #define THIS iotjs_gpio_reqwrap_t* gpio_reqwrap static iotjs_gpio_reqwrap_t* iotjs_gpio_reqwrap_create( const iotjs_jval_t* jcallback, iotjs_gpio_t* gpio, GpioOp op) { iotjs_gpio_reqwrap_t* gpio_reqwrap = IOTJS_ALLOC(iotjs_gpio_reqwrap_t); IOTJS_VALIDATED_STRUCT_CONSTRUCTOR(iotjs_gpio_reqwrap_t, gpio_reqwrap); iotjs_reqwrap_initialize(&_this->reqwrap, jcallback, (uv_req_t*)&_this->req); _this->req_data.op = op; _this->gpio_instance = gpio; return gpio_reqwrap; } static void iotjs_gpio_reqwrap_destroy(THIS) { IOTJS_VALIDATED_STRUCT_DESTRUCTOR(iotjs_gpio_reqwrap_t, gpio_reqwrap); iotjs_reqwrap_destroy(&_this->reqwrap); IOTJS_RELEASE(gpio_reqwrap); } static void iotjs_gpio_reqwrap_dispatched(THIS) { IOTJS_VALIDATABLE_STRUCT_METHOD_VALIDATE(iotjs_gpio_reqwrap_t, gpio_reqwrap); iotjs_gpio_reqwrap_destroy(gpio_reqwrap); } static uv_work_t* iotjs_gpio_reqwrap_req(THIS) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_gpio_reqwrap_t, gpio_reqwrap); return &_this->req; } static const iotjs_jval_t* iotjs_gpio_reqwrap_jcallback(THIS) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_gpio_reqwrap_t, gpio_reqwrap); return iotjs_reqwrap_jcallback(&_this->reqwrap); } static iotjs_gpio_t* iotjs_gpio_instance_from_jval(const iotjs_jval_t* jgpio) { uintptr_t handle = iotjs_jval_get_object_native_handle(jgpio); return (iotjs_gpio_t*)handle; } iotjs_gpio_reqwrap_t* iotjs_gpio_reqwrap_from_request(uv_work_t* req) { return (iotjs_gpio_reqwrap_t*)(iotjs_reqwrap_from_request((uv_req_t*)req)); } iotjs_gpio_reqdata_t* iotjs_gpio_reqwrap_data(THIS) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_gpio_reqwrap_t, gpio_reqwrap); return &_this->req_data; } iotjs_gpio_t* iotjs_gpio_instance_from_reqwrap(THIS) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_gpio_reqwrap_t, gpio_reqwrap); return _this->gpio_instance; } #undef THIS static void iotjs_gpio_write_worker(uv_work_t* work_req) { GPIO_WORKER_INIT; if (!iotjs_gpio_write(gpio, req_data->value)) { req_data->result = false; return; } req_data->result = true; } static void iotjs_gpio_read_worker(uv_work_t* work_req) { GPIO_WORKER_INIT; int result = iotjs_gpio_read(gpio); if (result < 0) { req_data->result = false; return; } req_data->result = true; req_data->value = (bool)result; } static void iotjs_gpio_close_worker(uv_work_t* work_req) { GPIO_WORKER_INIT; if (!iotjs_gpio_close(gpio)) { req_data->result = false; return; } req_data->result = true; } static void iotjs_gpio_after_worker(uv_work_t* work_req, int status) { iotjs_gpio_reqwrap_t* req_wrap = iotjs_gpio_reqwrap_from_request(work_req); iotjs_gpio_reqdata_t* req_data = iotjs_gpio_reqwrap_data(req_wrap); iotjs_jargs_t jargs = iotjs_jargs_create(2); bool result = req_data->result; if (status) { iotjs_jargs_append_error(&jargs, "GPIO System Error"); } else { switch (req_data->op) { case kGpioOpOpen: if (!result) { iotjs_jargs_append_error(&jargs, "GPIO Open Error"); } else { iotjs_jargs_append_null(&jargs); } break; case kGpioOpWrite: if (!result) { iotjs_jargs_append_error(&jargs, "GPIO Write Error"); } else { iotjs_jargs_append_null(&jargs); } break; case kGpioOpRead: if (!result) { iotjs_jargs_append_error(&jargs, "GPIO Read Error"); } else { iotjs_jargs_append_null(&jargs); iotjs_jargs_append_bool(&jargs, req_data->value); } break; case kGpioOpClose: if (!result) { iotjs_jargs_append_error(&jargs, "GPIO Close Error"); } else { iotjs_jargs_append_null(&jargs); } break; default: IOTJS_ASSERT(!"Unreachable"); break; } } const iotjs_jval_t* jcallback = iotjs_gpio_reqwrap_jcallback(req_wrap); iotjs_make_callback(jcallback, iotjs_jval_get_undefined(), &jargs); iotjs_jargs_destroy(&jargs); iotjs_gpio_reqwrap_dispatched(req_wrap); } static void gpio_set_configurable(iotjs_gpio_t* gpio, const iotjs_jval_t* jconfigurable) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_gpio_t, gpio); iotjs_jval_t jpin = iotjs_jval_get_property(jconfigurable, IOTJS_MAGIC_STRING_PIN); _this->pin = iotjs_jval_as_number(&jpin); iotjs_jval_destroy(&jpin); iotjs_jval_t jdirection = iotjs_jval_get_property(jconfigurable, IOTJS_MAGIC_STRING_DIRECTION); _this->direction = (GpioDirection)iotjs_jval_as_number(&jdirection); iotjs_jval_destroy(&jdirection); iotjs_jval_t jmode = iotjs_jval_get_property(jconfigurable, IOTJS_MAGIC_STRING_MODE); _this->mode = (GpioMode)iotjs_jval_as_number(&jmode); iotjs_jval_destroy(&jmode); iotjs_jval_t jedge = iotjs_jval_get_property(jconfigurable, IOTJS_MAGIC_STRING_EDGE); _this->edge = (GpioMode)iotjs_jval_as_number(&jedge); iotjs_jval_destroy(&jedge); } #define GPIO_ASYNC(call, this, jcallback, op) \ do { \ uv_loop_t* loop = iotjs_environment_loop(iotjs_environment_get()); \ iotjs_gpio_reqwrap_t* req_wrap = \ iotjs_gpio_reqwrap_create(jcallback, this, op); \ uv_work_t* req = iotjs_gpio_reqwrap_req(req_wrap); \ uv_queue_work(loop, req, iotjs_gpio_##call##_worker, \ iotjs_gpio_after_worker); \ } while (0) #define GPIO_ASYNC_WITH_VALUE(call, this, jcallback, op, val) \ do { \ uv_loop_t* loop = iotjs_environment_loop(iotjs_environment_get()); \ iotjs_gpio_reqwrap_t* req_wrap = \ iotjs_gpio_reqwrap_create(jcallback, this, op); \ uv_work_t* req = iotjs_gpio_reqwrap_req(req_wrap); \ iotjs_gpio_reqdata_t* req_data = iotjs_gpio_reqwrap_data(req_wrap); \ req_data->value = val; \ uv_queue_work(loop, req, iotjs_gpio_##call##_worker, \ iotjs_gpio_after_worker); \ } while (0) JHANDLER_FUNCTION(GpioConstructor) { DJHANDLER_CHECK_THIS(object); DJHANDLER_CHECK_ARGS(2, object, function); // Create GPIO object const iotjs_jval_t* jgpio = JHANDLER_GET_THIS(object); iotjs_gpio_t* gpio = iotjs_gpio_create(jgpio); IOTJS_ASSERT(gpio == iotjs_gpio_instance_from_jval(jgpio)); gpio_set_configurable(gpio, JHANDLER_GET_ARG(0, object)); const iotjs_jval_t* jcallback = JHANDLER_GET_ARG(1, function); GPIO_ASYNC(open, gpio, jcallback, kGpioOpOpen); } JHANDLER_FUNCTION(Write) { JHANDLER_DECLARE_THIS_PTR(gpio, gpio); DJHANDLER_CHECK_ARGS(1, boolean); DJHANDLER_CHECK_ARG_IF_EXIST(1, function); const iotjs_jval_t* jcallback = JHANDLER_GET_ARG_IF_EXIST(1, function); bool value = JHANDLER_GET_ARG(0, boolean); if (jcallback) { GPIO_ASYNC_WITH_VALUE(write, gpio, jcallback, kGpioOpWrite, value); } else { if (!iotjs_gpio_write(gpio, value)) { JHANDLER_THROW(COMMON, "GPIO WriteSync Error"); } } iotjs_jhandler_return_null(jhandler); } JHANDLER_FUNCTION(Read) { JHANDLER_DECLARE_THIS_PTR(gpio, gpio); DJHANDLER_CHECK_ARGS(0); DJHANDLER_CHECK_ARG_IF_EXIST(0, function); const iotjs_jval_t* jcallback = JHANDLER_GET_ARG_IF_EXIST(0, function); if (jcallback) { GPIO_ASYNC(read, gpio, jcallback, kGpioOpRead); iotjs_jhandler_return_null(jhandler); } else { int value = iotjs_gpio_read(gpio); if (value < 0) { JHANDLER_THROW(COMMON, "GPIO ReadSync Error"); } iotjs_jhandler_return_boolean(jhandler, value); } } JHANDLER_FUNCTION(Close) { JHANDLER_DECLARE_THIS_PTR(gpio, gpio) DJHANDLER_CHECK_ARG_IF_EXIST(0, function); const iotjs_jval_t* jcallback = JHANDLER_GET_ARG_IF_EXIST(0, function); if (jcallback) { GPIO_ASYNC(close, gpio, jcallback, kGpioOpClose); } else { if (!iotjs_gpio_close(gpio)) { JHANDLER_THROW(COMMON, "GPIO CloseSync Error"); } } iotjs_jhandler_return_null(jhandler); } iotjs_jval_t InitGpio() { iotjs_jval_t jgpio = iotjs_jval_create_object(); iotjs_jval_t jgpioConstructor = iotjs_jval_create_function_with_dispatch(GpioConstructor); iotjs_jval_set_property_jval(&jgpio, IOTJS_MAGIC_STRING_GPIO, &jgpioConstructor); iotjs_jval_t jprototype = iotjs_jval_create_object(); iotjs_jval_set_method(&jprototype, IOTJS_MAGIC_STRING_WRITE, Write); iotjs_jval_set_method(&jprototype, IOTJS_MAGIC_STRING_READ, Read); iotjs_jval_set_method(&jprototype, IOTJS_MAGIC_STRING_CLOSE, Close); iotjs_jval_set_property_jval(&jgpioConstructor, IOTJS_MAGIC_STRING_PROTOTYPE, &jprototype); iotjs_jval_destroy(&jprototype); iotjs_jval_destroy(&jgpioConstructor); // GPIO direction properties iotjs_jval_t jdirection = iotjs_jval_create_object(); iotjs_jval_set_property_number(&jdirection, IOTJS_MAGIC_STRING_IN, kGpioDirectionIn); iotjs_jval_set_property_number(&jdirection, IOTJS_MAGIC_STRING_OUT, kGpioDirectionOut); iotjs_jval_set_property_jval(&jgpio, IOTJS_MAGIC_STRING_DIRECTION_U, &jdirection); iotjs_jval_destroy(&jdirection); // GPIO mode properties iotjs_jval_t jmode = iotjs_jval_create_object(); iotjs_jval_set_property_number(&jmode, IOTJS_MAGIC_STRING_NONE, kGpioModeNone); #if defined(__NUTTX__) iotjs_jval_set_property_number(&jmode, IOTJS_MAGIC_STRING_PULLUP, kGpioModePullup); iotjs_jval_set_property_number(&jmode, IOTJS_MAGIC_STRING_PULLDOWN, kGpioModePulldown); iotjs_jval_set_property_number(&jmode, IOTJS_MAGIC_STRING_FLOAT, kGpioModeFloat); iotjs_jval_set_property_number(&jmode, IOTJS_MAGIC_STRING_PUSHPULL, kGpioModePushpull); iotjs_jval_set_property_number(&jmode, IOTJS_MAGIC_STRING_OPENDRAIN, kGpioModeOpendrain); #endif iotjs_jval_set_property_jval(&jgpio, IOTJS_MAGIC_STRING_MODE_U, &jmode); iotjs_jval_destroy(&jmode); // GPIO edge properties iotjs_jval_t jedge = iotjs_jval_create_object(); iotjs_jval_set_property_number(&jedge, IOTJS_MAGIC_STRING_NONE, kGpioEdgeNone); iotjs_jval_set_property_number(&jedge, IOTJS_MAGIC_STRING_RISING_U, kGpioEdgeRising); iotjs_jval_set_property_number(&jedge, IOTJS_MAGIC_STRING_FALLING_U, kGpioEdgeFalling); iotjs_jval_set_property_number(&jedge, IOTJS_MAGIC_STRING_BOTH_U, kGpioEdgeBoth); iotjs_jval_set_property_jval(&jgpio, IOTJS_MAGIC_STRING_EDGE_U, &jedge); iotjs_jval_destroy(&jedge); return jgpio; } iotjs-1.0/src/modules/iotjs_module_gpio.h000066400000000000000000000051721312466455500206450ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef IOTJS_MODULE_GPIO_H #define IOTJS_MODULE_GPIO_H #include "iotjs_def.h" #include "iotjs_objectwrap.h" #include "iotjs_reqwrap.h" #if defined(__TIZENRT__) #include #endif typedef enum { kGpioDirectionIn = 0, kGpioDirectionOut, } GpioDirection; typedef enum { kGpioModeNone = 0, kGpioModePullup, kGpioModePulldown, kGpioModeFloat, kGpioModePushpull, kGpioModeOpendrain, } GpioMode; typedef enum { kGpioEdgeNone = 0, kGpioEdgeRising, kGpioEdgeFalling, kGpioEdgeBoth, } GpioEdge; typedef enum { kGpioOpOpen, kGpioOpWrite, kGpioOpRead, kGpioOpClose, } GpioOp; typedef struct { bool value; bool result; GpioOp op; } iotjs_gpio_reqdata_t; // This Gpio class provides interfaces for GPIO operation. typedef struct { iotjs_jobjectwrap_t jobjectwrap; uint32_t pin; GpioDirection direction; GpioMode mode; GpioEdge edge; #if defined(__linux__) int value_fd; uv_thread_t thread; uv_mutex_t mutex; #elif defined(__TIZENRT__) iotbus_gpio_context_h gpio_context; #endif } IOTJS_VALIDATED_STRUCT(iotjs_gpio_t); typedef struct { iotjs_reqwrap_t reqwrap; uv_work_t req; iotjs_gpio_reqdata_t req_data; iotjs_gpio_t* gpio_instance; } IOTJS_VALIDATED_STRUCT(iotjs_gpio_reqwrap_t); #define THIS iotjs_gpio_reqwrap_t* gpio_reqwrap iotjs_gpio_reqwrap_t* iotjs_gpio_reqwrap_from_request(uv_work_t* req); iotjs_gpio_reqdata_t* iotjs_gpio_reqwrap_data(THIS); iotjs_gpio_t* iotjs_gpio_instance_from_reqwrap(THIS); #undef THIS #define GPIO_WORKER_INIT \ iotjs_gpio_reqwrap_t* req_wrap = iotjs_gpio_reqwrap_from_request(work_req); \ iotjs_gpio_reqdata_t* req_data = iotjs_gpio_reqwrap_data(req_wrap); \ iotjs_gpio_t* gpio = iotjs_gpio_instance_from_reqwrap(req_wrap); void iotjs_gpio_open_worker(uv_work_t* work_req); bool iotjs_gpio_write(iotjs_gpio_t* gpio, bool value); int iotjs_gpio_read(iotjs_gpio_t* gpio); bool iotjs_gpio_close(iotjs_gpio_t* gpio); #endif /* IOTJS_MODULE_GPIO_H */ iotjs-1.0/src/modules/iotjs_module_httpparser.c000066400000000000000000000402241312466455500220730ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "iotjs_def.h" #include "iotjs_module_httpparser.h" #include "iotjs_module_buffer.h" #include #include #include #define THIS iotjs_httpparserwrap_t* httpparserwrap IOTJS_DEFINE_NATIVE_HANDLE_INFO_THIS_MODULE(httpparserwrap); iotjs_httpparserwrap_t* iotjs_httpparserwrap_create(const iotjs_jval_t* jparser, http_parser_type type) { iotjs_httpparserwrap_t* httpparserwrap = IOTJS_ALLOC(iotjs_httpparserwrap_t); IOTJS_VALIDATED_STRUCT_CONSTRUCTOR(iotjs_httpparserwrap_t, httpparserwrap); iotjs_jobjectwrap_initialize(&_this->jobjectwrap, jparser, &this_module_native_info); _this->url = iotjs_string_create(); _this->status_msg = iotjs_string_create(); for (size_t i = 0; i < HEADER_MAX; i++) { _this->fields[i] = iotjs_string_create(); _this->values[i] = iotjs_string_create(); } iotjs_httpparserwrap_initialize(httpparserwrap, type); _this->parser.data = httpparserwrap; return httpparserwrap; } static void iotjs_httpparserwrap_destroy(THIS) { IOTJS_VALIDATED_STRUCT_DESTRUCTOR(iotjs_httpparserwrap_t, httpparserwrap); iotjs_string_destroy(&_this->url); iotjs_string_destroy(&_this->status_msg); for (size_t i = 0; i < HEADER_MAX; i++) { iotjs_string_destroy(&_this->fields[i]); iotjs_string_destroy(&_this->values[i]); } iotjs_jobjectwrap_destroy(&_this->jobjectwrap); IOTJS_RELEASE(httpparserwrap); } void iotjs_httpparserwrap_initialize(THIS, http_parser_type type) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_httpparserwrap_t, httpparserwrap); http_parser_init(&_this->parser, type); iotjs_string_make_empty(&_this->url); iotjs_string_make_empty(&_this->status_msg); _this->n_fields = 0; _this->n_values = 0; _this->flushed = false; _this->cur_jbuf = NULL; _this->cur_buf = NULL; _this->cur_buf_len = 0; } // http-parser callbacks static int iotjs_httpparserwrap_on_message_begin(http_parser* parser) { iotjs_httpparserwrap_t* httpparserwrap = (iotjs_httpparserwrap_t*)(parser->data); IOTJS_VALIDATED_STRUCT_METHOD(iotjs_httpparserwrap_t, httpparserwrap); iotjs_string_make_empty(&_this->url); iotjs_string_make_empty(&_this->status_msg); return 0; } static int iotjs_httpparserwrap_on_url(http_parser* parser, const char* at, size_t length) { iotjs_httpparserwrap_t* httpparserwrap = (iotjs_httpparserwrap_t*)(parser->data); IOTJS_VALIDATED_STRUCT_METHOD(iotjs_httpparserwrap_t, httpparserwrap); iotjs_string_append(&_this->url, at, length); return 0; } static int iotjs_httpparserwrap_on_status(http_parser* parser, const char* at, size_t length) { iotjs_httpparserwrap_t* httpparserwrap = (iotjs_httpparserwrap_t*)(parser->data); IOTJS_VALIDATED_STRUCT_METHOD(iotjs_httpparserwrap_t, httpparserwrap); iotjs_string_append(&_this->status_msg, at, length); return 0; } static int iotjs_httpparserwrap_on_header_field(http_parser* parser, const char* at, size_t length) { iotjs_httpparserwrap_t* httpparserwrap = (iotjs_httpparserwrap_t*)(parser->data); IOTJS_VALIDATED_STRUCT_METHOD(iotjs_httpparserwrap_t, httpparserwrap); if (_this->n_fields == _this->n_values) { _this->n_fields++; // values and fields are flushed to JS // before corresponding OnHeaderValue is called. if (_this->n_fields == HEADER_MAX) { iotjs_httpparserwrap_flush(httpparserwrap); // to JS world _this->n_fields = 1; _this->n_values = 0; } iotjs_string_make_empty(&_this->fields[_this->n_fields - 1]); } IOTJS_ASSERT(_this->n_fields == _this->n_values + 1); iotjs_string_append(&_this->fields[_this->n_fields - 1], at, length); return 0; } static int iotjs_httpparserwrap_on_header_value(http_parser* parser, const char* at, size_t length) { iotjs_httpparserwrap_t* httpparserwrap = (iotjs_httpparserwrap_t*)(parser->data); IOTJS_VALIDATED_STRUCT_METHOD(iotjs_httpparserwrap_t, httpparserwrap); if (_this->n_fields != _this->n_values) { _this->n_values++; iotjs_string_make_empty(&_this->values[_this->n_values - 1]); } IOTJS_ASSERT(_this->n_fields == _this->n_values); iotjs_string_append(&_this->values[_this->n_values - 1], at, length); return 0; } static int iotjs_httpparserwrap_on_headers_complete(http_parser* parser) { iotjs_httpparserwrap_t* httpparserwrap = (iotjs_httpparserwrap_t*)(parser->data); IOTJS_VALIDATED_STRUCT_METHOD(iotjs_httpparserwrap_t, httpparserwrap); const iotjs_jval_t* jobj = iotjs_httpparserwrap_jobject(httpparserwrap); iotjs_jval_t func = iotjs_jval_get_property(jobj, IOTJS_MAGIC_STRING_ONHEADERSCOMPLETE); IOTJS_ASSERT(iotjs_jval_is_function(&func)); // URL iotjs_jargs_t argv = iotjs_jargs_create(1); iotjs_jval_t info = iotjs_jval_create_object(); if (_this->flushed) { // If some headers already are flushed, // flush the remaining headers. // In Flush function, url is already flushed to JS. iotjs_httpparserwrap_flush(httpparserwrap); } else { // Here, there was no flushed header. // We need to make a new header object with all header fields iotjs_jval_t jheader = iotjs_httpparserwrap_make_header(httpparserwrap); iotjs_jval_set_property_jval(&info, IOTJS_MAGIC_STRING_HEADERS, &jheader); iotjs_jval_destroy(&jheader); if (_this->parser.type == HTTP_REQUEST) { IOTJS_ASSERT(!iotjs_string_is_empty(&_this->url)); iotjs_jval_set_property_string(&info, IOTJS_MAGIC_STRING_URL, &_this->url); } } _this->n_fields = _this->n_values = 0; // Method if (_this->parser.type == HTTP_REQUEST) { iotjs_jval_set_property_number(&info, IOTJS_MAGIC_STRING_METHOD, _this->parser.method); } // Status if (_this->parser.type == HTTP_RESPONSE) { iotjs_jval_set_property_number(&info, IOTJS_MAGIC_STRING_STATUS, _this->parser.status_code); iotjs_jval_set_property_string(&info, IOTJS_MAGIC_STRING_STATUS_MSG, &_this->status_msg); } // For future support, current http_server module does not support // upgrade and keepalive. // upgrade iotjs_jval_set_property_boolean(&info, IOTJS_MAGIC_STRING_UPGRADE, _this->parser.upgrade); // shouldkeepalive iotjs_jval_set_property_boolean(&info, IOTJS_MAGIC_STRING_SHOULDKEEPALIVE, http_should_keep_alive(&_this->parser)); iotjs_jargs_append_jval(&argv, &info); iotjs_jval_t res = iotjs_make_callback_with_result(&func, jobj, &argv); bool ret = iotjs_jval_as_boolean(&res); iotjs_jargs_destroy(&argv); iotjs_jval_destroy(&func); iotjs_jval_destroy(&res); iotjs_jval_destroy(&info); return ret; } static int iotjs_httpparserwrap_on_body(http_parser* parser, const char* at, size_t length) { iotjs_httpparserwrap_t* httpparserwrap = (iotjs_httpparserwrap_t*)(parser->data); IOTJS_VALIDATED_STRUCT_METHOD(iotjs_httpparserwrap_t, httpparserwrap); const iotjs_jval_t* jobj = iotjs_httpparserwrap_jobject(httpparserwrap); iotjs_jval_t func = iotjs_jval_get_property(jobj, IOTJS_MAGIC_STRING_ONBODY); IOTJS_ASSERT(iotjs_jval_is_function(&func)); iotjs_jargs_t argv = iotjs_jargs_create(3); iotjs_jargs_append_jval(&argv, _this->cur_jbuf); iotjs_jargs_append_number(&argv, at - _this->cur_buf); iotjs_jargs_append_number(&argv, length); iotjs_make_callback(&func, jobj, &argv); iotjs_jargs_destroy(&argv); iotjs_jval_destroy(&func); return 0; } static int iotjs_httpparserwrap_on_message_complete(http_parser* parser) { iotjs_httpparserwrap_t* httpparserwrap = (iotjs_httpparserwrap_t*)(parser->data); IOTJS_VALIDATABLE_STRUCT_METHOD_VALIDATE(iotjs_httpparserwrap_t, httpparserwrap); const iotjs_jval_t* jobj = iotjs_httpparserwrap_jobject(httpparserwrap); iotjs_jval_t func = iotjs_jval_get_property(jobj, IOTJS_MAGIC_STRING_ONMESSAGECOMPLETE); IOTJS_ASSERT(iotjs_jval_is_function(&func)); iotjs_make_callback(&func, jobj, iotjs_jargs_get_empty()); iotjs_jval_destroy(&func); return 0; } iotjs_jval_t iotjs_httpparserwrap_make_header(THIS) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_httpparserwrap_t, httpparserwrap); iotjs_jval_t jheader = iotjs_jval_create_array(_this->n_values * 2); for (size_t i = 0; i < _this->n_values; i++) { iotjs_jval_t f = iotjs_jval_create_string(&_this->fields[i]); iotjs_jval_t v = iotjs_jval_create_string(&_this->values[i]); iotjs_jval_set_property_by_index(&jheader, i * 2, &f); iotjs_jval_set_property_by_index(&jheader, i * 2 + 1, &v); iotjs_jval_destroy(&f); iotjs_jval_destroy(&v); } return jheader; } void iotjs_httpparserwrap_flush(THIS) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_httpparserwrap_t, httpparserwrap); const iotjs_jval_t* jobj = iotjs_httpparserwrap_jobject(httpparserwrap); iotjs_jval_t func = iotjs_jval_get_property(jobj, IOTJS_MAGIC_STRING_ONHEADERS); IOTJS_ASSERT(iotjs_jval_is_function(&func)); iotjs_jargs_t argv = iotjs_jargs_create(2); iotjs_jval_t jheader = iotjs_httpparserwrap_make_header(httpparserwrap); iotjs_jargs_append_jval(&argv, &jheader); iotjs_jval_destroy(&jheader); if (_this->parser.type == HTTP_REQUEST && !iotjs_string_is_empty(&_this->url)) { iotjs_jargs_append_string(&argv, &_this->url); } iotjs_make_callback(&func, jobj, &argv); iotjs_string_make_empty(&_this->url); iotjs_jargs_destroy(&argv); iotjs_jval_destroy(&func); _this->flushed = true; } void iotjs_httpparserwrap_set_buf(THIS, iotjs_jval_t* jbuf, char* buf, size_t sz) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_httpparserwrap_t, httpparserwrap); _this->cur_jbuf = jbuf; _this->cur_buf = buf; _this->cur_buf_len = sz; } iotjs_jval_t* iotjs_httpparserwrap_jobject(THIS) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_httpparserwrap_t, httpparserwrap); return iotjs_jobjectwrap_jobject(&_this->jobjectwrap); } http_parser* iotjs_httpparserwrap_parser(THIS) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_httpparserwrap_t, httpparserwrap); return &_this->parser; } #undef THIS const struct http_parser_settings settings = { iotjs_httpparserwrap_on_message_begin, iotjs_httpparserwrap_on_url, iotjs_httpparserwrap_on_status, iotjs_httpparserwrap_on_header_field, iotjs_httpparserwrap_on_header_value, iotjs_httpparserwrap_on_headers_complete, iotjs_httpparserwrap_on_body, iotjs_httpparserwrap_on_message_complete, NULL, /* on_chunk_header */ NULL, /* on_chunk_complete */ }; JHANDLER_FUNCTION(Reinitialize) { JHANDLER_DECLARE_THIS_PTR(httpparserwrap, parser); DJHANDLER_CHECK_ARGS(1, number); http_parser_type httpparser_type = (http_parser_type)(JHANDLER_GET_ARG(0, number)); IOTJS_ASSERT(httpparser_type == HTTP_REQUEST || httpparser_type == HTTP_RESPONSE); iotjs_httpparserwrap_initialize(parser, httpparser_type); } JHANDLER_FUNCTION(Finish) { JHANDLER_DECLARE_THIS_PTR(httpparserwrap, parser); DJHANDLER_CHECK_ARGS(0); http_parser* nativeparser = iotjs_httpparserwrap_parser(parser); size_t rv = http_parser_execute(nativeparser, &settings, NULL, 0); if (rv != 0) { enum http_errno err = HTTP_PARSER_ERRNO(nativeparser); iotjs_jval_t eobj = iotjs_jval_create_error("Parse Error"); iotjs_jval_set_property_number(&eobj, IOTJS_MAGIC_STRING_BYTEPARSED, 0); iotjs_jval_set_property_string_raw(&eobj, IOTJS_MAGIC_STRING_CODE, http_errno_name(err)); iotjs_jhandler_return_jval(jhandler, &eobj); iotjs_jval_destroy(&eobj); } } JHANDLER_FUNCTION(Execute) { JHANDLER_DECLARE_THIS_PTR(httpparserwrap, parser); DJHANDLER_CHECK_ARGS(1, object); const iotjs_jval_t* jbuffer = JHANDLER_GET_ARG(0, object); iotjs_bufferwrap_t* buffer_wrap = iotjs_bufferwrap_from_jbuffer(jbuffer); char* buf_data = iotjs_bufferwrap_buffer(buffer_wrap); size_t buf_len = iotjs_bufferwrap_length(buffer_wrap); JHANDLER_CHECK(buf_data != NULL); JHANDLER_CHECK(buf_len > 0); iotjs_httpparserwrap_set_buf(parser, (iotjs_jval_t*)jbuffer, buf_data, buf_len); http_parser* nativeparser = iotjs_httpparserwrap_parser(parser); size_t nparsed = http_parser_execute(nativeparser, &settings, buf_data, buf_len); iotjs_httpparserwrap_set_buf(parser, NULL, NULL, 0); if (!nativeparser->upgrade && nparsed != buf_len) { // nparsed should equal to buf_len except UPGRADE protocol enum http_errno err = HTTP_PARSER_ERRNO(nativeparser); iotjs_jval_t eobj = iotjs_jval_create_error("Parse Error"); iotjs_jval_set_property_number(&eobj, IOTJS_MAGIC_STRING_BYTEPARSED, 0); iotjs_jval_set_property_string_raw(&eobj, IOTJS_MAGIC_STRING_CODE, http_errno_name(err)); iotjs_jhandler_return_jval(jhandler, &eobj); iotjs_jval_destroy(&eobj); } else { iotjs_jhandler_return_number(jhandler, nparsed); } } JHANDLER_FUNCTION(Pause) { JHANDLER_DECLARE_THIS_PTR(httpparserwrap, parser); DJHANDLER_CHECK_ARGS(0); http_parser* nativeparser = iotjs_httpparserwrap_parser(parser); http_parser_pause(nativeparser, 1); } JHANDLER_FUNCTION(Resume) { JHANDLER_DECLARE_THIS_PTR(httpparserwrap, parser); DJHANDLER_CHECK_ARGS(0); http_parser* nativeparser = iotjs_httpparserwrap_parser(parser); http_parser_pause(nativeparser, 0); } JHANDLER_FUNCTION(HTTPParserCons) { DJHANDLER_CHECK_THIS(object); DJHANDLER_CHECK_ARGS(1, number); const iotjs_jval_t* jparser = JHANDLER_GET_THIS(object); http_parser_type httpparser_type = (http_parser_type)(JHANDLER_GET_ARG(0, number)); IOTJS_ASSERT(httpparser_type == HTTP_REQUEST || httpparser_type == HTTP_RESPONSE); iotjs_httpparserwrap_t* parser = iotjs_httpparserwrap_create(jparser, httpparser_type); IOTJS_ASSERT(iotjs_jval_is_object(iotjs_httpparserwrap_jobject(parser))); } iotjs_jval_t InitHttpparser() { iotjs_jval_t httpparser = iotjs_jval_create_object(); iotjs_jval_t jParserCons = iotjs_jval_create_function_with_dispatch(HTTPParserCons); iotjs_jval_set_property_jval(&httpparser, IOTJS_MAGIC_STRING_HTTPPARSER, &jParserCons); iotjs_jval_set_property_number(&jParserCons, IOTJS_MAGIC_STRING_REQUEST, HTTP_REQUEST); iotjs_jval_set_property_number(&jParserCons, IOTJS_MAGIC_STRING_RESPONSE, HTTP_RESPONSE); iotjs_jval_t methods = iotjs_jval_create_object(); #define V(num, name, string) \ iotjs_jval_set_property_string_raw(&methods, #num, #string); HTTP_METHOD_MAP(V) #undef V iotjs_jval_set_property_jval(&jParserCons, IOTJS_MAGIC_STRING_METHODS, &methods); iotjs_jval_t prototype = iotjs_jval_create_object(); iotjs_jval_set_method(&prototype, IOTJS_MAGIC_STRING_EXECUTE, Execute); iotjs_jval_set_method(&prototype, IOTJS_MAGIC_STRING_REINITIALIZE, Reinitialize); iotjs_jval_set_method(&prototype, IOTJS_MAGIC_STRING_FINISH, Finish); iotjs_jval_set_method(&prototype, IOTJS_MAGIC_STRING_PAUSE, Pause); iotjs_jval_set_method(&prototype, IOTJS_MAGIC_STRING_RESUME, Resume); iotjs_jval_set_property_jval(&jParserCons, IOTJS_MAGIC_STRING_PROTOTYPE, &prototype); iotjs_jval_destroy(&jParserCons); iotjs_jval_destroy(&methods); iotjs_jval_destroy(&prototype); return httpparser; } iotjs-1.0/src/modules/iotjs_module_httpparser.h000066400000000000000000000043041312466455500220770ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef IOTJS_MODULE_HTTPPARSER_H #define IOTJS_MODULE_HTTPPARSER_H #include "iotjs_objectwrap.h" #include "http_parser.h" // If # of header fields == HEADER_MAX, flush header to JS side. // This is weired : # of maximum headers in C equals to HEADER_MAX-1. // This is because , OnHeaders cb, we increase n_fields first, // and check whether field == HEADER_MAX. // ex) HEADER_MAX 2 means that we can keep at most 1 header field/value // during http parsing. // Increase this to minimize inter JS-C call #define HEADER_MAX 10 typedef struct { iotjs_jobjectwrap_t jobjectwrap; http_parser parser; iotjs_string_t url; iotjs_string_t status_msg; iotjs_string_t fields[HEADER_MAX]; iotjs_string_t values[HEADER_MAX]; size_t n_fields; size_t n_values; iotjs_jval_t* cur_jbuf; char* cur_buf; size_t cur_buf_len; bool flushed; } IOTJS_VALIDATED_STRUCT(iotjs_httpparserwrap_t); typedef enum http_parser_type http_parser_type; #define THIS iotjs_httpparserwrap_t* httpparserwrap iotjs_httpparserwrap_t* iotjs_httpparserwrap_create(const iotjs_jval_t* jparser, http_parser_type type); void iotjs_httpparserwrap_initialize(THIS, http_parser_type type); iotjs_jval_t iotjs_httpparserwrap_make_header(THIS); void iotjs_httpparserwrap_flush(THIS); void iotjs_httpparserwrap_set_buf(THIS, iotjs_jval_t* jbuf, char* buf, size_t sz); iotjs_jval_t* iotjs_httpparserwrap_jobject(THIS); http_parser* iotjs_httpparserwrap_parser(THIS); #undef THIS #endif /* IOTJS_MODULE_HTTPPARSER_H */ iotjs-1.0/src/modules/iotjs_module_i2c.c000066400000000000000000000230441312466455500203550ustar00rootroot00000000000000/* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "iotjs_def.h" #include "iotjs_module_i2c.h" #include "iotjs_objectwrap.h" #define THIS iotjs_i2c_reqwrap_t* i2c_reqwrap IOTJS_DEFINE_NATIVE_HANDLE_INFO_THIS_MODULE(i2c); iotjs_i2c_reqwrap_t* iotjs_i2c_reqwrap_create(const iotjs_jval_t* jcallback, iotjs_i2c_t* i2c, I2cOp op) { iotjs_i2c_reqwrap_t* i2c_reqwrap = IOTJS_ALLOC(iotjs_i2c_reqwrap_t); IOTJS_VALIDATED_STRUCT_CONSTRUCTOR(iotjs_i2c_reqwrap_t, i2c_reqwrap); iotjs_reqwrap_initialize(&_this->reqwrap, jcallback, (uv_req_t*)&_this->req); _this->req_data.op = op; #if defined(__linux__) || defined(__APPLE__) _this->req_data.device = iotjs_string_create(""); #endif _this->i2c_data = i2c; return i2c_reqwrap; } static void iotjs_i2c_reqwrap_destroy(THIS) { IOTJS_VALIDATED_STRUCT_DESTRUCTOR(iotjs_i2c_reqwrap_t, i2c_reqwrap); iotjs_reqwrap_destroy(&_this->reqwrap); #if defined(__linux__) || defined(__APPLE__) iotjs_string_destroy(&_this->req_data.device); #endif IOTJS_RELEASE(i2c_reqwrap); } void iotjs_i2c_reqwrap_dispatched(THIS) { IOTJS_VALIDATABLE_STRUCT_METHOD_VALIDATE(iotjs_i2c_reqwrap_t, i2c_reqwrap); iotjs_i2c_reqwrap_destroy(i2c_reqwrap); } uv_work_t* iotjs_i2c_reqwrap_req(THIS) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_i2c_reqwrap_t, i2c_reqwrap); return &_this->req; } const iotjs_jval_t* iotjs_i2c_reqwrap_jcallback(THIS) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_i2c_reqwrap_t, i2c_reqwrap); return iotjs_reqwrap_jcallback(&_this->reqwrap); } iotjs_i2c_reqwrap_t* iotjs_i2c_reqwrap_from_request(uv_work_t* req) { return (iotjs_i2c_reqwrap_t*)(iotjs_reqwrap_from_request((uv_req_t*)req)); } iotjs_i2c_reqdata_t* iotjs_i2c_reqwrap_data(THIS) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_i2c_reqwrap_t, i2c_reqwrap); return &_this->req_data; } iotjs_i2c_t* iotjs_i2c_instance_from_reqwrap(THIS) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_i2c_reqwrap_t, i2c_reqwrap); return _this->i2c_data; } #undef THIS iotjs_i2c_t* iotjs_i2c_create(const iotjs_jval_t* ji2c) { iotjs_i2c_t* i2c = IOTJS_ALLOC(iotjs_i2c_t); IOTJS_VALIDATED_STRUCT_CONSTRUCTOR(iotjs_i2c_t, i2c); #if defined(__linux__) _this->device_fd = -1; #elif defined(__NUTTX__) _this->i2c_master = NULL; #endif iotjs_jobjectwrap_initialize(&_this->jobjectwrap, ji2c, &this_module_native_info); return i2c; } static void iotjs_i2c_destroy(iotjs_i2c_t* i2c) { IOTJS_VALIDATED_STRUCT_DESTRUCTOR(iotjs_i2c_t, i2c); iotjs_jobjectwrap_destroy(&_this->jobjectwrap); IOTJS_RELEASE(i2c); } iotjs_i2c_t* iotjs_i2c_instance_from_jval(const iotjs_jval_t* ji2c) { iotjs_jobjectwrap_t* jobjectwrap = iotjs_jobjectwrap_from_jobject(ji2c); return (iotjs_i2c_t*)jobjectwrap; } void AfterI2CWork(uv_work_t* work_req, int status) { iotjs_i2c_reqwrap_t* req_wrap = iotjs_i2c_reqwrap_from_request(work_req); iotjs_i2c_reqdata_t* req_data = iotjs_i2c_reqwrap_data(req_wrap); iotjs_jargs_t jargs = iotjs_jargs_create(2); if (status) { iotjs_jval_t error = iotjs_jval_create_error("System error"); iotjs_jargs_append_jval(&jargs, &error); iotjs_jval_destroy(&error); } else { switch (req_data->op) { case kI2cOpOpen: { if (req_data->error == kI2cErrOpen) { iotjs_jval_t error = iotjs_jval_create_error("Failed to open I2C device"); iotjs_jargs_append_jval(&jargs, &error); iotjs_jval_destroy(&error); } else { iotjs_jargs_append_null(&jargs); } break; } case kI2cOpWrite: { if (req_data->error == kI2cErrWrite) { iotjs_jval_t error = iotjs_jval_create_error("Cannot write to device"); iotjs_jargs_append_jval(&jargs, &error); iotjs_jval_destroy(&error); } else { iotjs_jargs_append_null(&jargs); } break; } case kI2cOpRead: { if (req_data->error == kI2cErrRead) { iotjs_jval_t error = iotjs_jval_create_error("Cannot read from device"); iotjs_jargs_append_jval(&jargs, &error); iotjs_jargs_append_null(&jargs); iotjs_jval_destroy(&error); } else { iotjs_jargs_append_null(&jargs); iotjs_jval_t result = iotjs_jval_create_byte_array(req_data->buf_len, req_data->buf_data); iotjs_jargs_append_jval(&jargs, &result); iotjs_jval_destroy(&result); if (req_data->delay > 0) { uv_sleep(req_data->delay); } if (req_data->buf_data != NULL) { iotjs_buffer_release(req_data->buf_data); } } break; } default: { IOTJS_ASSERT(!"Unreachable"); break; } } } const iotjs_jval_t* jcallback = iotjs_i2c_reqwrap_jcallback(req_wrap); iotjs_make_callback(jcallback, iotjs_jval_get_undefined(), &jargs); iotjs_jargs_destroy(&jargs); iotjs_i2c_reqwrap_dispatched(req_wrap); } static void GetI2cArray(const iotjs_jval_t* jarray, iotjs_i2c_reqdata_t* req_data) { // FIXME // Need to implement a function to get array info from iotjs_jval_t Array. iotjs_jval_t jlength = iotjs_jval_get_property(jarray, IOTJS_MAGIC_STRING_LENGTH); IOTJS_ASSERT(!iotjs_jval_is_undefined(&jlength)); req_data->buf_len = iotjs_jval_as_number(&jlength); req_data->buf_data = iotjs_buffer_allocate(req_data->buf_len); for (uint8_t i = 0; i < req_data->buf_len; i++) { iotjs_jval_t jdata = iotjs_jval_get_property_by_index(jarray, i); req_data->buf_data[i] = iotjs_jval_as_number(&jdata); iotjs_jval_destroy(&jdata); } iotjs_jval_destroy(&jlength); } #define I2C_ASYNC(op) \ do { \ uv_loop_t* loop = iotjs_environment_loop(iotjs_environment_get()); \ uv_work_t* req = iotjs_i2c_reqwrap_req(req_wrap); \ uv_queue_work(loop, req, op##Worker, AfterI2CWork); \ } while (0) JHANDLER_FUNCTION(I2cCons) { DJHANDLER_CHECK_THIS(object); #if defined(__linux__) || defined(__APPLE__) DJHANDLER_CHECK_ARGS(2, string, function); iotjs_string_t device = JHANDLER_GET_ARG(0, string); #elif defined(__NUTTX__) DJHANDLER_CHECK_ARGS(2, number, function); int device = JHANDLER_GET_ARG(0, number); #endif // Create I2C object const iotjs_jval_t* ji2c = JHANDLER_GET_THIS(object); iotjs_i2c_t* i2c = iotjs_i2c_create(ji2c); IOTJS_ASSERT(i2c == (iotjs_i2c_t*)(iotjs_jval_get_object_native_handle(ji2c))); // Create I2C request wrap const iotjs_jval_t* jcallback = JHANDLER_GET_ARG(1, function); iotjs_i2c_reqwrap_t* req_wrap = iotjs_i2c_reqwrap_create(jcallback, i2c, kI2cOpOpen); iotjs_i2c_reqdata_t* req_data = iotjs_i2c_reqwrap_data(req_wrap); #if defined(__linux__) || defined(__APPLE__) iotjs_string_append(&req_data->device, iotjs_string_data(&device), iotjs_string_size(&device)); #elif defined(__NUTTX__) req_data->device = device; #endif I2C_ASYNC(Open); } JHANDLER_FUNCTION(SetAddress) { JHANDLER_DECLARE_THIS_PTR(i2c, i2c); DJHANDLER_CHECK_ARGS(1, number); I2cSetAddress(i2c, JHANDLER_GET_ARG(0, number)); iotjs_jhandler_return_null(jhandler); } JHANDLER_FUNCTION(Close) { JHANDLER_DECLARE_THIS_PTR(i2c, i2c); DJHANDLER_CHECK_ARGS(0); I2cClose(i2c); iotjs_jhandler_return_null(jhandler); } JHANDLER_FUNCTION(Write) { JHANDLER_DECLARE_THIS_PTR(i2c, i2c); DJHANDLER_CHECK_ARGS(2, array, function); const iotjs_jval_t* jcallback = JHANDLER_GET_ARG(1, function); iotjs_i2c_reqwrap_t* req_wrap = iotjs_i2c_reqwrap_create(jcallback, i2c, kI2cOpWrite); iotjs_i2c_reqdata_t* req_data = iotjs_i2c_reqwrap_data(req_wrap); GetI2cArray(JHANDLER_GET_ARG(0, array), req_data); I2C_ASYNC(Write); iotjs_jhandler_return_null(jhandler); } JHANDLER_FUNCTION(Read) { JHANDLER_DECLARE_THIS_PTR(i2c, i2c); DJHANDLER_CHECK_ARGS(2, number, function); const iotjs_jval_t* jcallback = JHANDLER_GET_ARG(1, function); iotjs_i2c_reqwrap_t* req_wrap = iotjs_i2c_reqwrap_create(jcallback, i2c, kI2cOpRead); iotjs_i2c_reqdata_t* req_data = iotjs_i2c_reqwrap_data(req_wrap); req_data->buf_len = JHANDLER_GET_ARG(0, number); req_data->delay = 0; I2C_ASYNC(Read); iotjs_jhandler_return_null(jhandler); } iotjs_jval_t InitI2c() { iotjs_jval_t jI2cCons = iotjs_jval_create_function_with_dispatch(I2cCons); iotjs_jval_t prototype = iotjs_jval_create_object(); iotjs_jval_set_method(&prototype, IOTJS_MAGIC_STRING_SETADDRESS, SetAddress); iotjs_jval_set_method(&prototype, IOTJS_MAGIC_STRING_CLOSE, Close); iotjs_jval_set_method(&prototype, IOTJS_MAGIC_STRING_WRITE, Write); iotjs_jval_set_method(&prototype, IOTJS_MAGIC_STRING_READ, Read); iotjs_jval_set_property_jval(&jI2cCons, IOTJS_MAGIC_STRING_PROTOTYPE, &prototype); iotjs_jval_destroy(&prototype); return jI2cCons; } iotjs-1.0/src/modules/iotjs_module_i2c.h000066400000000000000000000051711312466455500203630ustar00rootroot00000000000000/* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef IOTJS_MODULE_I2C_H #define IOTJS_MODULE_I2C_H #include "iotjs_def.h" #include "iotjs_objectwrap.h" #include "iotjs_reqwrap.h" #if defined(__NUTTX__) #include #endif typedef enum { kI2cOpSetAddress, kI2cOpOpen, kI2cOpClose, kI2cOpWrite, kI2cOpRead, } I2cOp; typedef enum { kI2cErrOk = 0, kI2cErrOpen = -1, kI2cErrRead = -2, kI2cErrWrite = -3, } I2cError; typedef struct { #if defined(__linux__) || defined(__APPLE__) iotjs_string_t device; #elif defined(__NUTTX__) int device; #endif char* buf_data; uint8_t buf_len; uint8_t byte; uint8_t cmd; int32_t delay; I2cOp op; I2cError error; } iotjs_i2c_reqdata_t; // This I2c class provides interfaces for I2C operation. typedef struct { iotjs_jobjectwrap_t jobjectwrap; #if defined(__linux__) int device_fd; uint8_t addr; #elif defined(__NUTTX__) struct i2c_master_s* i2c_master; struct i2c_config_s config; #endif } IOTJS_VALIDATED_STRUCT(iotjs_i2c_t); typedef struct { iotjs_reqwrap_t reqwrap; uv_work_t req; iotjs_i2c_reqdata_t req_data; iotjs_i2c_t* i2c_data; } IOTJS_VALIDATED_STRUCT(iotjs_i2c_reqwrap_t); iotjs_i2c_t* iotjs_i2c_create(const iotjs_jval_t* ji2c); iotjs_i2c_t* iotjs_i2c_instance_from_jval(const iotjs_jval_t* ji2c); #define THIS iotjs_i2c_reqwrap_t* i2c_reqwrap iotjs_i2c_reqwrap_t* iotjs_i2c_reqwrap_create(const iotjs_jval_t* jcallback, iotjs_i2c_t* i2c, I2cOp op); void iotjs_i2c_reqwrap_dispatched(THIS); uv_work_t* iotjs_i2c_reqwrap_req(THIS); const iotjs_jval_t* iotjs_i2c_reqwrap_jcallback(THIS); iotjs_i2c_reqwrap_t* iotjs_i2c_reqwrap_from_request(uv_work_t* req); iotjs_i2c_reqdata_t* iotjs_i2c_reqwrap_data(THIS); iotjs_i2c_t* iotjs_i2c_instance_from_reqwrap(THIS); #undef THIS void I2cSetAddress(iotjs_i2c_t* i2c, uint8_t address); void OpenWorker(uv_work_t* work_req); void I2cClose(iotjs_i2c_t* i2c); void WriteWorker(uv_work_t* work_req); void ReadWorker(uv_work_t* work_req); #endif /* IOTJS_MODULE_I2C_H */ iotjs-1.0/src/modules/iotjs_module_process.c000066400000000000000000000204671312466455500213640ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "iotjs_def.h" #include "iotjs_js.h" #include "jerryscript-debugger.h" #include JHANDLER_FUNCTION(Binding) { JHANDLER_CHECK_ARGS(1, number); ModuleKind module_kind = (ModuleKind)JHANDLER_GET_ARG(0, number); const iotjs_jval_t* jmodule = iotjs_module_initialize_if_necessary(module_kind); iotjs_jhandler_return_jval(jhandler, jmodule); } static iotjs_jval_t WrapEval(const char* name, size_t name_len, const char* source, size_t length, bool* throws) { static const char* wrapper[2] = { "(function(exports, require, module) {", "\n});\n" }; size_t len0 = strlen(wrapper[0]); size_t len1 = strlen(wrapper[1]); size_t buffer_length = len0 + len1 + length; char* buffer = iotjs_buffer_allocate(buffer_length); memcpy(buffer, wrapper[0], len0); memcpy(buffer + len0, source, length); memcpy(buffer + len0 + length, wrapper[1], len1); iotjs_jval_t res = iotjs_jhelper_eval(name, name_len, (uint8_t*)buffer, buffer_length, false, throws); iotjs_buffer_release(buffer); return res; } JHANDLER_FUNCTION(Compile) { JHANDLER_CHECK_ARGS(2, string, string); iotjs_string_t file = JHANDLER_GET_ARG(0, string); iotjs_string_t source = JHANDLER_GET_ARG(1, string); const char* filename = iotjs_string_data(&file); const iotjs_environment_t* env = iotjs_environment_get(); if (iotjs_environment_config(env)->debugger) { jerry_debugger_stop(); } bool throws; iotjs_jval_t jres = WrapEval(filename, strlen(filename), iotjs_string_data(&source), iotjs_string_size(&source), &throws); if (!throws) { iotjs_jhandler_return_jval(jhandler, &jres); } else { iotjs_jhandler_throw(jhandler, &jres); } iotjs_string_destroy(&file); iotjs_string_destroy(&source); iotjs_jval_destroy(&jres); } JHANDLER_FUNCTION(CompileNativePtr) { JHANDLER_CHECK_ARGS(1, string); iotjs_string_t id = JHANDLER_GET_ARG(0, string); const char* name = iotjs_string_data(&id); int i = 0; while (natives[i].name != NULL) { if (!strcmp(natives[i].name, name)) { break; } i++; } if (natives[i].name != NULL) { bool throws; #ifdef ENABLE_SNAPSHOT iotjs_jval_t jres = iotjs_jhelper_exec_snapshot(natives[i].code, natives[i].length, &throws); #else iotjs_jval_t jres = WrapEval(name, iotjs_string_size(&id), (const char*)natives[i].code, natives[i].length, &throws); #endif if (!throws) { iotjs_jhandler_return_jval(jhandler, &jres); } else { iotjs_jhandler_throw(jhandler, &jres); } iotjs_jval_destroy(&jres); } else { iotjs_jval_t jerror = iotjs_jval_create_error("Unknown native module"); iotjs_jhandler_throw(jhandler, &jerror); iotjs_jval_destroy(&jerror); } iotjs_string_destroy(&id); } JHANDLER_FUNCTION(ReadSource) { JHANDLER_CHECK_ARGS(1, string); iotjs_string_t path = JHANDLER_GET_ARG(0, string); iotjs_string_t code = iotjs_file_read(iotjs_string_data(&path)); iotjs_jhandler_return_string(jhandler, &code); iotjs_string_destroy(&path); iotjs_string_destroy(&code); } JHANDLER_FUNCTION(Cwd) { JHANDLER_CHECK_ARGS(0); char path[IOTJS_MAX_PATH_SIZE]; size_t size_path = sizeof(path); int err = uv_cwd(path, &size_path); if (err) { JHANDLER_THROW(COMMON, "cwd error"); return; } iotjs_jhandler_return_string_raw(jhandler, path); } JHANDLER_FUNCTION(Chdir) { JHANDLER_CHECK_ARGS(1, string); iotjs_string_t path = JHANDLER_GET_ARG(0, string); int err = uv_chdir(iotjs_string_data(&path)); if (err) { iotjs_string_destroy(&path); JHANDLER_THROW(COMMON, "chdir error"); return; } iotjs_string_destroy(&path); } JHANDLER_FUNCTION(DoExit) { JHANDLER_CHECK_ARGS(1, number); // Release builtin modules. iotjs_module_list_cleanup(); // Release commonly used jerry values. iotjs_binding_finalize(); int exit_code = JHANDLER_GET_ARG(0, number); exit(exit_code); } void SetNativeSources(iotjs_jval_t* native_sources) { for (int i = 0; natives[i].name; i++) { iotjs_jval_set_property_jval(native_sources, natives[i].name, iotjs_jval_get_boolean(true)); } } static void SetProcessEnv(iotjs_jval_t* process) { const char *homedir, *iotjspath, *iotjsenv; homedir = getenv("HOME"); if (homedir == NULL) { homedir = ""; } iotjspath = getenv("IOTJS_PATH"); if (iotjspath == NULL) { #if defined(__NUTTX__) || defined(__TIZENRT__) iotjspath = "/mnt/sdcard"; #else iotjspath = ""; #endif } #if defined(EXPERIMENTAL) iotjsenv = "experimental"; #else iotjsenv = ""; #endif iotjs_jval_t env = iotjs_jval_create_object(); iotjs_jval_set_property_string_raw(&env, IOTJS_MAGIC_STRING_HOME, homedir); iotjs_jval_set_property_string_raw(&env, IOTJS_MAGIC_STRING_IOTJS_PATH, iotjspath); iotjs_jval_set_property_string_raw(&env, IOTJS_MAGIC_STRING_IOTJS_ENV, iotjsenv); iotjs_jval_set_property_jval(process, IOTJS_MAGIC_STRING_ENV, &env); iotjs_jval_destroy(&env); } static void SetProcessIotjs(iotjs_jval_t* process) { // IoT.js specific iotjs_jval_t iotjs = iotjs_jval_create_object(); iotjs_jval_set_property_jval(process, IOTJS_MAGIC_STRING_IOTJS, &iotjs); iotjs_jval_set_property_string_raw(&iotjs, IOTJS_MAGIC_STRING_BOARD, TOSTRING(TARGET_BOARD)); iotjs_jval_destroy(&iotjs); } static void SetProcessArgv(iotjs_jval_t* process) { const iotjs_environment_t* env = iotjs_environment_get(); uint32_t argc = iotjs_environment_argc(env); iotjs_jval_t argv = iotjs_jval_create_array(argc); for (uint32_t i = 0; i < argc; ++i) { const char* argvi = iotjs_environment_argv(env, i); iotjs_jval_t arg = iotjs_jval_create_string_raw(argvi); iotjs_jval_set_property_by_index(&argv, i, &arg); iotjs_jval_destroy(&arg); } iotjs_jval_set_property_jval(process, IOTJS_MAGIC_STRING_ARGV, &argv); iotjs_jval_destroy(&argv); } iotjs_jval_t InitProcess() { iotjs_jval_t process = iotjs_jval_create_object(); iotjs_jval_set_method(&process, IOTJS_MAGIC_STRING_BINDING, Binding); iotjs_jval_set_method(&process, IOTJS_MAGIC_STRING_COMPILE, Compile); iotjs_jval_set_method(&process, IOTJS_MAGIC_STRING_COMPILENATIVEPTR, CompileNativePtr); iotjs_jval_set_method(&process, IOTJS_MAGIC_STRING_READSOURCE, ReadSource); iotjs_jval_set_method(&process, IOTJS_MAGIC_STRING_CWD, Cwd); iotjs_jval_set_method(&process, IOTJS_MAGIC_STRING_CHDIR, Chdir); iotjs_jval_set_method(&process, IOTJS_MAGIC_STRING_DOEXIT, DoExit); SetProcessEnv(&process); // process.native_sources iotjs_jval_t native_sources = iotjs_jval_create_object(); SetNativeSources(&native_sources); iotjs_jval_set_property_jval(&process, IOTJS_MAGIC_STRING_NATIVE_SOURCES, &native_sources); iotjs_jval_destroy(&native_sources); // process.platform iotjs_jval_set_property_string_raw(&process, IOTJS_MAGIC_STRING_PLATFORM, TARGET_OS); // process.arch iotjs_jval_set_property_string_raw(&process, IOTJS_MAGIC_STRING_ARCH, TARGET_ARCH); // Set iotjs SetProcessIotjs(&process); SetProcessArgv(&process); // Binding module id. iotjs_jval_t jbinding = iotjs_jval_get_property(&process, IOTJS_MAGIC_STRING_BINDING); #define ENUMDEF_MODULE_LIST(upper, Camel, lower) \ iotjs_jval_set_property_number(&jbinding, #lower, MODULE_##upper); MAP_MODULE_LIST(ENUMDEF_MODULE_LIST) #undef ENUMDEF_MODULE_LIST iotjs_jval_destroy(&jbinding); return process; } iotjs-1.0/src/modules/iotjs_module_pwm.c000066400000000000000000000261271312466455500205100ustar00rootroot00000000000000/* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "iotjs_def.h" #include "iotjs_module_pwm.h" #include "iotjs_objectwrap.h" static iotjs_pwm_t* iotjs_pwm_instance_from_jval(const iotjs_jval_t* jpwm); IOTJS_DEFINE_NATIVE_HANDLE_INFO_THIS_MODULE(pwm); static iotjs_pwm_t* iotjs_pwm_create(const iotjs_jval_t* jpwm) { iotjs_pwm_t* pwm = IOTJS_ALLOC(iotjs_pwm_t); IOTJS_VALIDATED_STRUCT_CONSTRUCTOR(iotjs_pwm_t, pwm); iotjs_jobjectwrap_initialize(&_this->jobjectwrap, jpwm, &this_module_native_info); _this->period = -1; _this->duty_cycle = 0; #if defined(__NUTTX__) _this->device_fd = -1; #endif return pwm; } static void iotjs_pwm_destroy(iotjs_pwm_t* pwm) { IOTJS_VALIDATED_STRUCT_DESTRUCTOR(iotjs_pwm_t, pwm); iotjs_jobjectwrap_destroy(&_this->jobjectwrap); #if defined(__linux__) iotjs_string_destroy(&_this->device); #endif IOTJS_RELEASE(pwm); } #define THIS iotjs_pwm_reqwrap_t* pwm_reqwrap static iotjs_pwm_reqwrap_t* iotjs_pwm_reqwrap_create( const iotjs_jval_t* jcallback, iotjs_pwm_t* pwm, PwmOp op) { iotjs_pwm_reqwrap_t* pwm_reqwrap = IOTJS_ALLOC(iotjs_pwm_reqwrap_t); IOTJS_VALIDATED_STRUCT_CONSTRUCTOR(iotjs_pwm_reqwrap_t, pwm_reqwrap); iotjs_reqwrap_initialize(&_this->reqwrap, jcallback, (uv_req_t*)&_this->req); _this->req_data.op = op; _this->pwm_instance = pwm; _this->req_data.caller = NULL; return pwm_reqwrap; } static void iotjs_pwm_reqwrap_destroy(THIS) { IOTJS_VALIDATED_STRUCT_DESTRUCTOR(iotjs_pwm_reqwrap_t, pwm_reqwrap); iotjs_reqwrap_destroy(&_this->reqwrap); IOTJS_RELEASE(pwm_reqwrap); } static void iotjs_pwm_reqwrap_dispatched(THIS) { IOTJS_VALIDATABLE_STRUCT_METHOD_VALIDATE(iotjs_pwm_reqwrap_t, pwm_reqwrap); iotjs_pwm_reqwrap_destroy(pwm_reqwrap); } static uv_work_t* iotjs_pwm_reqwrap_req(THIS) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_pwm_reqwrap_t, pwm_reqwrap); return &_this->req; } static const iotjs_jval_t* iotjs_pwm_reqwrap_jcallback(THIS) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_pwm_reqwrap_t, pwm_reqwrap); return iotjs_reqwrap_jcallback(&_this->reqwrap); } static iotjs_pwm_t* iotjs_pwm_instance_from_jval(const iotjs_jval_t* jpwm) { uintptr_t handle = iotjs_jval_get_object_native_handle(jpwm); return (iotjs_pwm_t*)handle; } iotjs_pwm_reqwrap_t* iotjs_pwm_reqwrap_from_request(uv_work_t* req) { return (iotjs_pwm_reqwrap_t*)(iotjs_reqwrap_from_request((uv_req_t*)req)); } iotjs_pwm_reqdata_t* iotjs_pwm_reqwrap_data(THIS) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_pwm_reqwrap_t, pwm_reqwrap); return &_this->req_data; } iotjs_pwm_t* iotjs_pwm_instance_from_reqwrap(THIS) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_pwm_reqwrap_t, pwm_reqwrap); return _this->pwm_instance; } static void iotjs_pwm_set_configuration(const iotjs_jval_t* jconfiguration, iotjs_pwm_t* pwm) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_pwm_t, pwm); iotjs_jval_t jpin = iotjs_jval_get_property(jconfiguration, IOTJS_MAGIC_STRING_PIN); _this->pin = iotjs_jval_as_number(&jpin); #if defined(__linux__) iotjs_jval_t jchip = iotjs_jval_get_property(jconfiguration, IOTJS_MAGIC_STRING_CHIP); _this->chip = iotjs_jval_as_number(&jchip); iotjs_jval_destroy(&jchip); #endif iotjs_jval_t jperiod = iotjs_jval_get_property(jconfiguration, IOTJS_MAGIC_STRING_PERIOD); if (iotjs_jval_is_number(&jperiod)) _this->period = iotjs_jval_as_number(&jperiod); iotjs_jval_t jduty_cycle = iotjs_jval_get_property(jconfiguration, IOTJS_MAGIC_STRING_DUTYCYCLE); if (iotjs_jval_is_number(&jduty_cycle)) _this->duty_cycle = iotjs_jval_as_number(&jduty_cycle); iotjs_jval_destroy(&jpin); iotjs_jval_destroy(&jperiod); iotjs_jval_destroy(&jduty_cycle); } #undef THIS static void iotjs_pwm_common_worker(uv_work_t* work_req) { PWM_WORKER_INIT; IOTJS_ASSERT(req_data->caller != NULL); if (!req_data->caller(pwm)) { req_data->result = false; return; } req_data->result = true; } static void iotjs_pwm_after_worker(uv_work_t* work_req, int status) { iotjs_pwm_reqwrap_t* req_wrap = iotjs_pwm_reqwrap_from_request(work_req); iotjs_pwm_reqdata_t* req_data = iotjs_pwm_reqwrap_data(req_wrap); iotjs_jargs_t jargs = iotjs_jargs_create(1); bool result = req_data->result; if (status) { iotjs_jval_t error = iotjs_jval_create_error("System error"); iotjs_jargs_append_jval(&jargs, &error); iotjs_jval_destroy(&error); } else { switch (req_data->op) { case kPwmOpOpen: if (!result) { iotjs_jargs_append_error(&jargs, "Failed to open PWM device"); } else { iotjs_jargs_append_null(&jargs); } break; case kPwmOpSetDutyCycle: if (!result) { iotjs_jargs_append_error(&jargs, "Failed to set duty-cycle"); } else { iotjs_jargs_append_null(&jargs); } break; case kPwmOpSetPeriod: if (!result) { iotjs_jargs_append_error(&jargs, "Failed to set period"); } else { iotjs_jargs_append_null(&jargs); } break; case kPwmOpSetEnable: if (!result) { iotjs_jargs_append_error(&jargs, "Failed to set enable"); } else { iotjs_jargs_append_null(&jargs); } break; case kPwmOpClose: if (!result) { iotjs_jargs_append_error(&jargs, "Cannot close PWM device"); } else { iotjs_jargs_append_null(&jargs); } break; default: { IOTJS_ASSERT(!"Unreachable"); break; } } } const iotjs_jval_t* jcallback = iotjs_pwm_reqwrap_jcallback(req_wrap); iotjs_make_callback(jcallback, iotjs_jval_get_undefined(), &jargs); iotjs_jargs_destroy(&jargs); iotjs_pwm_reqwrap_dispatched(req_wrap); } #define PWM_ASYNC(call, this, jcallback, op) \ do { \ uv_loop_t* loop = iotjs_environment_loop(iotjs_environment_get()); \ iotjs_pwm_reqwrap_t* req_wrap = \ iotjs_pwm_reqwrap_create(jcallback, this, op); \ uv_work_t* req = iotjs_pwm_reqwrap_req(req_wrap); \ uv_queue_work(loop, req, iotjs_pwm_##call##_worker, \ iotjs_pwm_after_worker); \ } while (0) #define PWM_ASYNC_COMMON_WORKER(call, this, jcallback, op) \ do { \ uv_loop_t* loop = iotjs_environment_loop(iotjs_environment_get()); \ iotjs_pwm_reqwrap_t* req_wrap = \ iotjs_pwm_reqwrap_create(jcallback, this, op); \ uv_work_t* req = iotjs_pwm_reqwrap_req(req_wrap); \ iotjs_pwm_reqdata_t* req_data = iotjs_pwm_reqwrap_data(req_wrap); \ req_data->caller = call; \ uv_queue_work(loop, req, iotjs_pwm_common_worker, iotjs_pwm_after_worker); \ } while (0) JHANDLER_FUNCTION(PWMConstructor) { DJHANDLER_CHECK_THIS(object); DJHANDLER_CHECK_ARGS(2, object, function); // Create PWM object const iotjs_jval_t* jpwm = JHANDLER_GET_THIS(object); iotjs_pwm_t* pwm = iotjs_pwm_create(jpwm); IOTJS_ASSERT(pwm == iotjs_pwm_instance_from_jval(jpwm)); const iotjs_jval_t* jconfiguration = JHANDLER_GET_ARG(0, object); const iotjs_jval_t* jcallback = JHANDLER_GET_ARG(1, function); // Set configuration iotjs_pwm_set_configuration(jconfiguration, pwm); PWM_ASYNC(open, pwm, jcallback, kPwmOpOpen); } JHANDLER_FUNCTION(SetPeriod) { JHANDLER_DECLARE_THIS_PTR(pwm, pwm); DJHANDLER_CHECK_ARGS(1, number); DJHANDLER_CHECK_ARG_IF_EXIST(1, function); const iotjs_jval_t* jcallback = JHANDLER_GET_ARG_IF_EXIST(1, function); IOTJS_VALIDATED_STRUCT_METHOD(iotjs_pwm_t, pwm); _this->period = JHANDLER_GET_ARG(0, number); if (jcallback) { PWM_ASYNC_COMMON_WORKER(iotjs_pwm_set_period, pwm, jcallback, kPwmOpSetPeriod); } else { if (!iotjs_pwm_set_period(pwm)) { JHANDLER_THROW(COMMON, "PWM SetPeriod Error"); } } iotjs_jhandler_return_null(jhandler); } JHANDLER_FUNCTION(SetDutyCycle) { JHANDLER_DECLARE_THIS_PTR(pwm, pwm); DJHANDLER_CHECK_ARGS(1, number); DJHANDLER_CHECK_ARG_IF_EXIST(1, function); const iotjs_jval_t* jcallback = JHANDLER_GET_ARG_IF_EXIST(1, function); IOTJS_VALIDATED_STRUCT_METHOD(iotjs_pwm_t, pwm); _this->duty_cycle = JHANDLER_GET_ARG(0, number); if (jcallback) { PWM_ASYNC_COMMON_WORKER(iotjs_pwm_set_dutycycle, pwm, jcallback, kPwmOpSetDutyCycle); } else { if (!iotjs_pwm_set_dutycycle(pwm)) { JHANDLER_THROW(COMMON, "PWM SetDutyCycle Error"); } } iotjs_jhandler_return_null(jhandler); } JHANDLER_FUNCTION(SetEnable) { JHANDLER_DECLARE_THIS_PTR(pwm, pwm); DJHANDLER_CHECK_ARGS(1, boolean); DJHANDLER_CHECK_ARG_IF_EXIST(1, function); const iotjs_jval_t* jcallback = JHANDLER_GET_ARG_IF_EXIST(1, function); IOTJS_VALIDATED_STRUCT_METHOD(iotjs_pwm_t, pwm); _this->enable = JHANDLER_GET_ARG(0, boolean); if (jcallback) { PWM_ASYNC_COMMON_WORKER(iotjs_pwm_set_enable, pwm, jcallback, kPwmOpSetEnable); } else { if (!iotjs_pwm_set_enable(pwm)) { JHANDLER_THROW(COMMON, "PWM SetEnabe Error"); } } iotjs_jhandler_return_null(jhandler); } JHANDLER_FUNCTION(Close) { JHANDLER_DECLARE_THIS_PTR(pwm, pwm); DJHANDLER_CHECK_ARG_IF_EXIST(0, function); const iotjs_jval_t* jcallback = JHANDLER_GET_ARG_IF_EXIST(0, function); if (jcallback) { PWM_ASYNC_COMMON_WORKER(iotjs_pwm_close, pwm, jcallback, kPwmOpClose); } else { if (!iotjs_pwm_close(pwm)) { JHANDLER_THROW(COMMON, "PWM Close Error"); } } iotjs_jhandler_return_null(jhandler); } iotjs_jval_t InitPwm() { iotjs_jval_t jpwm_constructor = iotjs_jval_create_function_with_dispatch(PWMConstructor); iotjs_jval_t jprototype = iotjs_jval_create_object(); iotjs_jval_set_method(&jprototype, IOTJS_MAGIC_STRING_SETPERIOD, SetPeriod); iotjs_jval_set_method(&jprototype, IOTJS_MAGIC_STRING_SETDUTYCYCLE, SetDutyCycle); iotjs_jval_set_method(&jprototype, IOTJS_MAGIC_STRING_SETENABLE, SetEnable); iotjs_jval_set_method(&jprototype, IOTJS_MAGIC_STRING_CLOSE, Close); iotjs_jval_set_property_jval(&jpwm_constructor, IOTJS_MAGIC_STRING_PROTOTYPE, &jprototype); iotjs_jval_destroy(&jprototype); return jpwm_constructor; } iotjs-1.0/src/modules/iotjs_module_pwm.h000066400000000000000000000045721312466455500205150ustar00rootroot00000000000000/* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef IOTJS_MODULE_PWM_H #define IOTJS_MODULE_PWM_H #include "iotjs_def.h" #include "iotjs_objectwrap.h" #include "iotjs_reqwrap.h" #if defined(__TIZENRT__) #include #include #endif typedef enum { kPwmOpOpen, kPwmOpSetDutyCycle, kPwmOpSetPeriod, kPwmOpSetFrequency, kPwmOpSetEnable, kPwmOpClose, } PwmOp; typedef struct { iotjs_jobjectwrap_t jobjectwrap; #if defined(__linux__) int chip; iotjs_string_t device; #elif defined(__NUTTX__) int device_fd; #elif defined(__TIZENRT__) iotbus_pwm_context_h ctx; #endif uint32_t pin; double duty_cycle; double period; bool enable; } IOTJS_VALIDATED_STRUCT(iotjs_pwm_t); typedef bool (*pwm_func_ptr)(iotjs_pwm_t*); typedef struct { pwm_func_ptr caller; bool result; PwmOp op; } iotjs_pwm_reqdata_t; typedef struct { iotjs_reqwrap_t reqwrap; uv_work_t req; iotjs_pwm_reqdata_t req_data; iotjs_pwm_t* pwm_instance; } IOTJS_VALIDATED_STRUCT(iotjs_pwm_reqwrap_t); #define THIS iotjs_pwm_reqwrap_t* pwm_reqwrap iotjs_pwm_reqwrap_t* iotjs_pwm_reqwrap_from_request(uv_work_t* req); iotjs_pwm_reqdata_t* iotjs_pwm_reqwrap_data(THIS); iotjs_pwm_t* iotjs_pwm_instance_from_reqwrap(THIS); #undef THIS #define PWM_WORKER_INIT \ iotjs_pwm_reqwrap_t* req_wrap = iotjs_pwm_reqwrap_from_request(work_req); \ iotjs_pwm_reqdata_t* req_data = iotjs_pwm_reqwrap_data(req_wrap); \ iotjs_pwm_t* pwm = iotjs_pwm_instance_from_reqwrap(req_wrap); void iotjs_pwm_open_worker(uv_work_t* work_req); bool iotjs_pwm_set_period(iotjs_pwm_t* pwm); bool iotjs_pwm_set_dutycycle(iotjs_pwm_t* pwm); bool iotjs_pwm_set_enable(iotjs_pwm_t* pwm); bool iotjs_pwm_close(iotjs_pwm_t* pwm); #endif /* IOTJS_MODULE_PWM_H */ iotjs-1.0/src/modules/iotjs_module_spi.c000066400000000000000000000340461312466455500204770ustar00rootroot00000000000000/* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "iotjs_def.h" #include "iotjs_module_spi.h" #include "iotjs_module_buffer.h" #include "iotjs_objectwrap.h" #include IOTJS_DEFINE_NATIVE_HANDLE_INFO_THIS_MODULE(spi); static iotjs_spi_t* iotjs_spi_create(const iotjs_jval_t* jspi) { iotjs_spi_t* spi = IOTJS_ALLOC(iotjs_spi_t); IOTJS_VALIDATED_STRUCT_CONSTRUCTOR(iotjs_spi_t, spi); iotjs_jobjectwrap_initialize(&_this->jobjectwrap, jspi, &this_module_native_info); _this->device = iotjs_string_create(""); return spi; } static void iotjs_spi_destroy(iotjs_spi_t* spi) { IOTJS_VALIDATED_STRUCT_DESTRUCTOR(iotjs_spi_t, spi); iotjs_jobjectwrap_destroy(&_this->jobjectwrap); iotjs_string_destroy(&_this->device); IOTJS_RELEASE(spi); } #define THIS iotjs_spi_reqwrap_t* spi_reqwrap static iotjs_spi_reqwrap_t* iotjs_spi_reqwrap_create( const iotjs_jval_t* jcallback, iotjs_spi_t* spi, SpiOp op) { iotjs_spi_reqwrap_t* spi_reqwrap = IOTJS_ALLOC(iotjs_spi_reqwrap_t); IOTJS_VALIDATED_STRUCT_CONSTRUCTOR(iotjs_spi_reqwrap_t, spi_reqwrap); iotjs_reqwrap_initialize(&_this->reqwrap, jcallback, (uv_req_t*)&_this->req); _this->req_data.op = op; _this->spi_instance = spi; return spi_reqwrap; } static void iotjs_spi_reqwrap_destroy(THIS) { IOTJS_VALIDATED_STRUCT_DESTRUCTOR(iotjs_spi_reqwrap_t, spi_reqwrap); iotjs_reqwrap_destroy(&_this->reqwrap); IOTJS_RELEASE(spi_reqwrap); } static void iotjs_spi_reqwrap_dispatched(THIS) { IOTJS_VALIDATABLE_STRUCT_METHOD_VALIDATE(iotjs_spi_reqwrap_t, spi_reqwrap); iotjs_spi_reqwrap_destroy(spi_reqwrap); } static uv_work_t* iotjs_spi_reqwrap_req(THIS) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_spi_reqwrap_t, spi_reqwrap); return &_this->req; } static const iotjs_jval_t* iotjs_spi_reqwrap_jcallback(THIS) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_spi_reqwrap_t, spi_reqwrap); return iotjs_reqwrap_jcallback(&_this->reqwrap); } iotjs_spi_reqwrap_t* iotjs_spi_reqwrap_from_request(uv_work_t* req) { return (iotjs_spi_reqwrap_t*)(iotjs_reqwrap_from_request((uv_req_t*)req)); } iotjs_spi_reqdata_t* iotjs_spi_reqwrap_data(THIS) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_spi_reqwrap_t, spi_reqwrap); return &_this->req_data; } iotjs_spi_t* iotjs_spi_instance_from_reqwrap(THIS) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_spi_reqwrap_t, spi_reqwrap); return _this->spi_instance; } #undef THIS static int iotjs_spi_get_array_data(char** buf, const iotjs_jval_t* jarray) { iotjs_jval_t jlength = iotjs_jval_get_property(jarray, IOTJS_MAGIC_STRING_LENGTH); IOTJS_ASSERT(!iotjs_jval_is_undefined(&jlength)); size_t length = iotjs_jval_as_number(&jlength); IOTJS_ASSERT((int)length >= 0); *buf = iotjs_buffer_allocate(length); for (size_t i = 0; i < length; i++) { iotjs_jval_t jdata = iotjs_jval_get_property_by_index(jarray, i); (*buf)[i] = iotjs_jval_as_number(&jdata); iotjs_jval_destroy(&jdata); } iotjs_jval_destroy(&jlength); return (int)length; } static void iotjs_spi_set_array_buffer(iotjs_spi_t* spi, const iotjs_jval_t* jtx_buf, const iotjs_jval_t* jrx_buf) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_spi_t, spi); int tx_buf_len = iotjs_spi_get_array_data(&_this->tx_buf_data, jtx_buf); int rx_buf_len = iotjs_spi_get_array_data(&_this->rx_buf_data, jrx_buf); IOTJS_ASSERT(_this->tx_buf_data != NULL && _this->rx_buf_data != NULL); IOTJS_ASSERT(tx_buf_len > 0 && rx_buf_len > 0 && tx_buf_len == rx_buf_len); _this->buf_len = tx_buf_len; } static void iotjs_spi_set_buffer(iotjs_spi_t* spi, const iotjs_jval_t* jtx_buf, const iotjs_jval_t* jrx_buf) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_spi_t, spi); iotjs_bufferwrap_t* tx_buf = iotjs_bufferwrap_from_jbuffer(jtx_buf); iotjs_bufferwrap_t* rx_buf = iotjs_bufferwrap_from_jbuffer(jrx_buf); _this->tx_buf_data = iotjs_bufferwrap_buffer(tx_buf); uint8_t tx_buf_len = iotjs_bufferwrap_length(tx_buf); _this->rx_buf_data = iotjs_bufferwrap_buffer(rx_buf); uint8_t rx_buf_len = iotjs_bufferwrap_length(rx_buf); IOTJS_ASSERT(_this->tx_buf_data != NULL && _this->rx_buf_data != NULL); IOTJS_ASSERT(tx_buf_len > 0 && rx_buf_len > 0 && tx_buf_len == rx_buf_len); _this->buf_len = tx_buf_len; } static void iotjs_spi_release_buffer(iotjs_spi_t* spi) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_spi_t, spi); iotjs_buffer_release(_this->tx_buf_data); iotjs_buffer_release(_this->rx_buf_data); } static void iotjs_spi_set_configuration(iotjs_spi_t* spi, const iotjs_jval_t* joptions) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_spi_t, spi); iotjs_jval_t jdevice = iotjs_jval_get_property(joptions, IOTJS_MAGIC_STRING_DEVICE); _this->device = iotjs_jval_as_string(&jdevice); iotjs_jval_destroy(&jdevice); iotjs_jval_t jmode = iotjs_jval_get_property(joptions, IOTJS_MAGIC_STRING_MODE); _this->mode = (SpiMode)iotjs_jval_as_number(&jmode); iotjs_jval_destroy(&jmode); iotjs_jval_t jchip_select = iotjs_jval_get_property(joptions, IOTJS_MAGIC_STRING_CHIPSELECT); _this->chip_select = (SpiChipSelect)iotjs_jval_as_number(&jchip_select); iotjs_jval_destroy(&jchip_select); iotjs_jval_t jmax_speed = iotjs_jval_get_property(joptions, IOTJS_MAGIC_STRING_MAXSPEED); _this->max_speed = iotjs_jval_as_number(&jmax_speed); iotjs_jval_destroy(&jmax_speed); iotjs_jval_t jbits_per_word = iotjs_jval_get_property(joptions, IOTJS_MAGIC_STRING_BITSPERWORD); _this->bits_per_word = (SpiOrder)iotjs_jval_as_number(&jbits_per_word); iotjs_jval_destroy(&jbits_per_word); iotjs_jval_t jbit_order = iotjs_jval_get_property(joptions, IOTJS_MAGIC_STRING_BITORDER); _this->bit_order = (SpiOrder)iotjs_jval_as_number(&jbit_order); iotjs_jval_destroy(&jbit_order); iotjs_jval_t jloopback = iotjs_jval_get_property(joptions, IOTJS_MAGIC_STRING_LOOPBACK); _this->loopback = iotjs_jval_as_boolean(&jloopback); iotjs_jval_destroy(&jloopback); } /* * SPI worker function */ static void iotjs_spi_transfer_worker(uv_work_t* work_req) { SPI_WORKER_INIT; if (!iotjs_spi_transfer(spi)) { req_data->result = false; return; } req_data->result = true; } static void iotjs_spi_close_worker(uv_work_t* work_req) { SPI_WORKER_INIT; if (!iotjs_spi_close(spi)) { req_data->result = false; return; } req_data->result = true; } static void iotjs_spi_after_work(uv_work_t* work_req, int status) { iotjs_spi_reqwrap_t* req_wrap = iotjs_spi_reqwrap_from_request(work_req); iotjs_spi_reqdata_t* req_data = iotjs_spi_reqwrap_data(req_wrap); iotjs_spi_t* spi = iotjs_spi_instance_from_reqwrap(req_wrap); iotjs_jargs_t jargs = iotjs_jargs_create(2); bool result = req_data->result; if (status) { iotjs_jargs_append_error(&jargs, "System error"); } else { switch (req_data->op) { case kSpiOpOpen: if (!result) { iotjs_jargs_append_error(&jargs, "Failed to export SPI device"); } else { iotjs_jargs_append_null(&jargs); } break; case kSpiOpTransfer: if (!result) { iotjs_jargs_append_error(&jargs, "Cannot transfer from SPI device"); } else { iotjs_jargs_append_null(&jargs); IOTJS_VALIDATED_STRUCT_METHOD(iotjs_spi_t, spi); // Append read data iotjs_jval_t result_data = iotjs_jval_create_byte_array(_this->buf_len, _this->rx_buf_data); iotjs_jargs_append_jval(&jargs, &result_data); iotjs_jval_destroy(&result_data); } iotjs_spi_release_buffer(spi); break; case kSpiOpClose: if (!result) { iotjs_jargs_append_error(&jargs, "Failed to unexport SPI device"); } else { iotjs_jargs_append_null(&jargs); } break; default: { IOTJS_ASSERT(!"Unreachable"); break; } } } const iotjs_jval_t* jcallback = iotjs_spi_reqwrap_jcallback(req_wrap); iotjs_make_callback(jcallback, iotjs_jval_get_undefined(), &jargs); iotjs_jargs_destroy(&jargs); iotjs_spi_reqwrap_dispatched(req_wrap); } iotjs_spi_t* iotjs_spi_get_instance(const iotjs_jval_t* jspi) { uintptr_t handle = iotjs_jval_get_object_native_handle(jspi); return (iotjs_spi_t*)(handle); } #define SPI_ASYNC(call, this, jcallback, op) \ do { \ uv_loop_t* loop = iotjs_environment_loop(iotjs_environment_get()); \ iotjs_spi_reqwrap_t* req_wrap = \ iotjs_spi_reqwrap_create(jcallback, this, op); \ uv_work_t* req = iotjs_spi_reqwrap_req(req_wrap); \ uv_queue_work(loop, req, iotjs_spi_##call##_worker, iotjs_spi_after_work); \ } while (0) JHANDLER_FUNCTION(SpiConstructor) { DJHANDLER_CHECK_THIS(object); DJHANDLER_CHECK_ARGS(2, object, function); // Create SPI object const iotjs_jval_t* jspi = JHANDLER_GET_THIS(object); iotjs_spi_t* spi = iotjs_spi_create(jspi); IOTJS_ASSERT(spi == iotjs_spi_get_instance(jspi)); // Set configuration const iotjs_jval_t* jconfiguration = JHANDLER_GET_ARG(0, object); iotjs_spi_set_configuration(spi, jconfiguration); const iotjs_jval_t* jcallback = JHANDLER_GET_ARG(1, function); SPI_ASYNC(open, spi, jcallback, kSpiOpOpen); } // FIXME: do not need transferArray if array buffer is implemented. JHANDLER_FUNCTION(TransferArray) { JHANDLER_DECLARE_THIS_PTR(spi, spi); DJHANDLER_CHECK_ARGS(2, array, array); DJHANDLER_CHECK_ARG_IF_EXIST(2, function); const iotjs_jval_t* jcallback = JHANDLER_GET_ARG_IF_EXIST(2, function); iotjs_spi_set_array_buffer(spi, JHANDLER_GET_ARG(0, array), JHANDLER_GET_ARG(1, array)); if (jcallback) { SPI_ASYNC(transfer, spi, jcallback, kSpiOpTransfer); } else { if (!iotjs_spi_transfer(spi)) { JHANDLER_THROW(COMMON, "SPI Transfer Error"); } else { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_spi_t, spi); iotjs_jval_t result = iotjs_jval_create_byte_array(_this->buf_len, _this->rx_buf_data); iotjs_jhandler_return_jval(jhandler, &result); iotjs_jval_destroy(&result); } } } JHANDLER_FUNCTION(TransferBuffer) { JHANDLER_DECLARE_THIS_PTR(spi, spi); DJHANDLER_CHECK_ARGS(2, object, object); DJHANDLER_CHECK_ARG_IF_EXIST(2, function); const iotjs_jval_t* jcallback = JHANDLER_GET_ARG_IF_EXIST(2, function); iotjs_spi_set_buffer(spi, JHANDLER_GET_ARG(0, object), JHANDLER_GET_ARG(1, object)); if (jcallback) { SPI_ASYNC(transfer, spi, jcallback, kSpiOpTransfer); } else { if (!iotjs_spi_transfer(spi)) { JHANDLER_THROW(COMMON, "SPI Transfer Error"); } else { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_spi_t, spi); iotjs_jval_t result = iotjs_jval_create_byte_array(_this->buf_len, _this->rx_buf_data); iotjs_jhandler_return_jval(jhandler, &result); iotjs_jval_destroy(&result); } } } JHANDLER_FUNCTION(Close) { JHANDLER_DECLARE_THIS_PTR(spi, spi); DJHANDLER_CHECK_ARG_IF_EXIST(0, function); const iotjs_jval_t* jcallback = JHANDLER_GET_ARG_IF_EXIST(0, function); if (jcallback) { SPI_ASYNC(close, spi, jcallback, kSpiOpClose); } else { if (!iotjs_spi_close(spi)) { JHANDLER_THROW(COMMON, "SPI Close Error"); } } iotjs_jhandler_return_null(jhandler); } iotjs_jval_t InitSpi() { iotjs_jval_t jspi = iotjs_jval_create_object(); iotjs_jval_t jspiConstructor = iotjs_jval_create_function_with_dispatch(SpiConstructor); iotjs_jval_set_property_jval(&jspi, IOTJS_MAGIC_STRING_SPI, &jspiConstructor); iotjs_jval_t prototype = iotjs_jval_create_object(); iotjs_jval_set_method(&prototype, IOTJS_MAGIC_STRING_TRANSFERARRAY, TransferArray); iotjs_jval_set_method(&prototype, IOTJS_MAGIC_STRING_TRANSFERBUFFER, TransferBuffer); iotjs_jval_set_method(&prototype, IOTJS_MAGIC_STRING_CLOSE, Close); iotjs_jval_set_property_jval(&jspiConstructor, IOTJS_MAGIC_STRING_PROTOTYPE, &prototype); iotjs_jval_destroy(&prototype); iotjs_jval_destroy(&jspiConstructor); // SPI mode properties iotjs_jval_t jmode = iotjs_jval_create_object(); iotjs_jval_set_property_number(&jmode, IOTJS_MAGIC_STRING_0, kSpiMode_0); iotjs_jval_set_property_number(&jmode, IOTJS_MAGIC_STRING_1, kSpiMode_1); iotjs_jval_set_property_number(&jmode, IOTJS_MAGIC_STRING_2, kSpiMode_2); iotjs_jval_set_property_number(&jmode, IOTJS_MAGIC_STRING_3, kSpiMode_3); iotjs_jval_set_property_jval(&jspi, IOTJS_MAGIC_STRING_MODE_U, &jmode); iotjs_jval_destroy(&jmode); // SPI mode properties iotjs_jval_t jcs = iotjs_jval_create_object(); iotjs_jval_set_property_number(&jcs, IOTJS_MAGIC_STRING_NONE, kSpiCsNone); iotjs_jval_set_property_number(&jcs, IOTJS_MAGIC_STRING_HIGH, kSpiCsHigh); iotjs_jval_set_property_jval(&jspi, IOTJS_MAGIC_STRING_CHIPSELECT_U, &jcs); iotjs_jval_destroy(&jcs); // SPI order properties iotjs_jval_t jbit_order = iotjs_jval_create_object(); iotjs_jval_set_property_number(&jbit_order, IOTJS_MAGIC_STRING_MSB, kSpiOrderMsb); iotjs_jval_set_property_number(&jbit_order, IOTJS_MAGIC_STRING_LSB, kSpiOrderLsb); iotjs_jval_set_property_jval(&jspi, IOTJS_MAGIC_STRING_BITORDER_U, &jbit_order); iotjs_jval_destroy(&jbit_order); return jspi; } iotjs-1.0/src/modules/iotjs_module_spi.h000066400000000000000000000045321312466455500205010ustar00rootroot00000000000000/* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef IOTJS_MODULE_SPI_H #define IOTJS_MODULE_SPI_H #include "iotjs_def.h" #include "iotjs_module_buffer.h" #include "iotjs_objectwrap.h" #include "iotjs_reqwrap.h" typedef enum { kSpiOpOpen, kSpiOpTransfer, kSpiOpClose, } SpiOp; typedef enum { kSpiMode_0, kSpiMode_1, kSpiMode_2, kSpiMode_3, } SpiMode; typedef enum { kSpiCsNone, kSpiCsHigh, } SpiChipSelect; typedef enum { kSpiOrderMsb, kSpiOrderLsb } SpiOrder; typedef struct { iotjs_jobjectwrap_t jobjectwrap; iotjs_string_t device; int32_t device_fd; SpiMode mode; SpiChipSelect chip_select; SpiOrder bit_order; uint8_t bits_per_word; uint16_t delay; uint32_t max_speed; bool loopback; // SPI buffer char* tx_buf_data; char* rx_buf_data; uint8_t buf_len; } IOTJS_VALIDATED_STRUCT(iotjs_spi_t); typedef struct { bool result; SpiOp op; } iotjs_spi_reqdata_t; typedef struct { iotjs_reqwrap_t reqwrap; uv_work_t req; iotjs_spi_reqdata_t req_data; iotjs_spi_t* spi_instance; } IOTJS_VALIDATED_STRUCT(iotjs_spi_reqwrap_t); #define THIS iotjs_spi_reqwrap_t* spi_reqwrap iotjs_spi_reqwrap_t* iotjs_spi_reqwrap_from_request(uv_work_t* req); iotjs_spi_reqdata_t* iotjs_spi_reqwrap_data(THIS); iotjs_spi_t* iotjs_spi_instance_from_reqwrap(THIS); #undef THIS #define SPI_WORKER_INIT \ iotjs_spi_reqwrap_t* req_wrap = iotjs_spi_reqwrap_from_request(work_req); \ iotjs_spi_reqdata_t* req_data = iotjs_spi_reqwrap_data(req_wrap); \ iotjs_spi_t* spi = iotjs_spi_instance_from_reqwrap(req_wrap); bool iotjs_spi_transfer(iotjs_spi_t* spi); bool iotjs_spi_close(iotjs_spi_t* spi); void iotjs_spi_open_worker(uv_work_t* work_req); #endif /* IOTJS_MODULE_SPI_H */ iotjs-1.0/src/modules/iotjs_module_stm32f4dis.c000066400000000000000000000016001312466455500215740ustar00rootroot00000000000000/* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "iotjs_def.h" #include "iotjs_module_stm32f4dis.h" iotjs_jval_t InitStm32f4dis() { iotjs_jval_t stm32f4dis = iotjs_jval_create_object(); #if defined(__NUTTX__) iotjs_stm32f4dis_pin_initialize(&stm32f4dis); #endif return stm32f4dis; } iotjs-1.0/src/modules/iotjs_module_stm32f4dis.h000066400000000000000000000014601312466455500216050ustar00rootroot00000000000000/* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef IOTJS_MODULE_STM32F4DIS_H #define IOTJS_MODULE_STM32F4DIS_H void iotjs_stm32f4dis_pin_initialize(const iotjs_jval_t* jobj); #endif /* IOTJS_MODULE_STM32F4DIS_H */ iotjs-1.0/src/modules/iotjs_module_tcp.c000066400000000000000000000467621312466455500205020ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "iotjs_def.h" #include "iotjs_module_tcp.h" #include "iotjs_handlewrap.h" #include "iotjs_module_buffer.h" #include "iotjs_reqwrap.h" IOTJS_DEFINE_NATIVE_HANDLE_INFO_THIS_MODULE(tcpwrap); iotjs_tcpwrap_t* iotjs_tcpwrap_create(const iotjs_jval_t* jtcp) { iotjs_tcpwrap_t* tcpwrap = IOTJS_ALLOC(iotjs_tcpwrap_t); IOTJS_VALIDATED_STRUCT_CONSTRUCTOR(iotjs_tcpwrap_t, tcpwrap); iotjs_handlewrap_initialize(&_this->handlewrap, jtcp, (uv_handle_t*)(&_this->handle), &this_module_native_info); const iotjs_environment_t* env = iotjs_environment_get(); uv_tcp_init(iotjs_environment_loop(env), &_this->handle); return tcpwrap; } static void iotjs_tcpwrap_destroy(iotjs_tcpwrap_t* tcpwrap) { IOTJS_VALIDATED_STRUCT_DESTRUCTOR(iotjs_tcpwrap_t, tcpwrap); iotjs_handlewrap_destroy(&_this->handlewrap); IOTJS_RELEASE(tcpwrap); } iotjs_tcpwrap_t* iotjs_tcpwrap_from_handle(uv_tcp_t* tcp_handle) { uv_handle_t* handle = (uv_handle_t*)(tcp_handle); iotjs_handlewrap_t* handlewrap = iotjs_handlewrap_from_handle(handle); iotjs_tcpwrap_t* tcpwrap = (iotjs_tcpwrap_t*)handlewrap; IOTJS_ASSERT(iotjs_tcpwrap_tcp_handle(tcpwrap) == tcp_handle); return tcpwrap; } iotjs_tcpwrap_t* iotjs_tcpwrap_from_jobject(const iotjs_jval_t* jtcp) { iotjs_handlewrap_t* handlewrap = iotjs_handlewrap_from_jobject(jtcp); return (iotjs_tcpwrap_t*)handlewrap; } uv_tcp_t* iotjs_tcpwrap_tcp_handle(iotjs_tcpwrap_t* tcpwrap) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_tcpwrap_t, tcpwrap); uv_handle_t* handle = iotjs_handlewrap_get_uv_handle(&_this->handlewrap); return (uv_tcp_t*)handle; } iotjs_jval_t* iotjs_tcpwrap_jobject(iotjs_tcpwrap_t* tcpwrap) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_tcpwrap_t, tcpwrap); return iotjs_handlewrap_jobject(&_this->handlewrap); } #define THIS iotjs_connect_reqwrap_t* connect_reqwrap static void iotjs_connect_reqwrap_destroy(THIS); iotjs_connect_reqwrap_t* iotjs_connect_reqwrap_create( const iotjs_jval_t* jcallback) { iotjs_connect_reqwrap_t* connect_reqwrap = IOTJS_ALLOC(iotjs_connect_reqwrap_t); IOTJS_VALIDATED_STRUCT_CONSTRUCTOR(iotjs_connect_reqwrap_t, connect_reqwrap); iotjs_reqwrap_initialize(&_this->reqwrap, jcallback, (uv_req_t*)&_this->req); return connect_reqwrap; } static void iotjs_connect_reqwrap_destroy(THIS) { IOTJS_VALIDATED_STRUCT_DESTRUCTOR(iotjs_connect_reqwrap_t, connect_reqwrap); iotjs_reqwrap_destroy(&_this->reqwrap); IOTJS_RELEASE(connect_reqwrap); } void iotjs_connect_reqwrap_dispatched(THIS) { IOTJS_VALIDATABLE_STRUCT_METHOD_VALIDATE(iotjs_connect_reqwrap_t, connect_reqwrap); iotjs_connect_reqwrap_destroy(connect_reqwrap); } uv_connect_t* iotjs_connect_reqwrap_req(THIS) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_connect_reqwrap_t, connect_reqwrap); return &_this->req; } const iotjs_jval_t* iotjs_connect_reqwrap_jcallback(THIS) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_connect_reqwrap_t, connect_reqwrap); return iotjs_reqwrap_jcallback(&_this->reqwrap); } #undef THIS #define THIS iotjs_write_reqwrap_t* write_reqwrap static void iotjs_write_reqwrap_destroy(THIS); iotjs_write_reqwrap_t* iotjs_write_reqwrap_create( const iotjs_jval_t* jcallback) { iotjs_write_reqwrap_t* write_reqwrap = IOTJS_ALLOC(iotjs_write_reqwrap_t); IOTJS_VALIDATED_STRUCT_CONSTRUCTOR(iotjs_write_reqwrap_t, write_reqwrap); iotjs_reqwrap_initialize(&_this->reqwrap, jcallback, (uv_req_t*)&_this->req); return write_reqwrap; } static void iotjs_write_reqwrap_destroy(THIS) { IOTJS_VALIDATED_STRUCT_DESTRUCTOR(iotjs_write_reqwrap_t, write_reqwrap); iotjs_reqwrap_destroy(&_this->reqwrap); IOTJS_RELEASE(write_reqwrap); } void iotjs_write_reqwrap_dispatched(THIS) { IOTJS_VALIDATABLE_STRUCT_METHOD_VALIDATE(iotjs_write_reqwrap_t, write_reqwrap); iotjs_write_reqwrap_destroy(write_reqwrap); } uv_write_t* iotjs_write_reqwrap_req(THIS) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_write_reqwrap_t, write_reqwrap); return &_this->req; } const iotjs_jval_t* iotjs_write_reqwrap_jcallback(THIS) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_write_reqwrap_t, write_reqwrap); return iotjs_reqwrap_jcallback(&_this->reqwrap); } #undef THIS #define THIS iotjs_shutdown_reqwrap_t* shutdown_reqwrap static void iotjs_shutdown_reqwrap_destroy(THIS); iotjs_shutdown_reqwrap_t* iotjs_shutdown_reqwrap_create( const iotjs_jval_t* jcallback) { iotjs_shutdown_reqwrap_t* shutdown_reqwrap = IOTJS_ALLOC(iotjs_shutdown_reqwrap_t); IOTJS_VALIDATED_STRUCT_CONSTRUCTOR(iotjs_shutdown_reqwrap_t, shutdown_reqwrap); iotjs_reqwrap_initialize(&_this->reqwrap, jcallback, (uv_req_t*)&_this->req); return shutdown_reqwrap; } static void iotjs_shutdown_reqwrap_destroy(THIS) { IOTJS_VALIDATED_STRUCT_DESTRUCTOR(iotjs_shutdown_reqwrap_t, shutdown_reqwrap); iotjs_reqwrap_destroy(&_this->reqwrap); IOTJS_RELEASE(shutdown_reqwrap); } void iotjs_shutdown_reqwrap_dispatched(THIS) { IOTJS_VALIDATABLE_STRUCT_METHOD_VALIDATE(iotjs_shutdown_reqwrap_t, shutdown_reqwrap); iotjs_shutdown_reqwrap_destroy(shutdown_reqwrap); } uv_shutdown_t* iotjs_shutdown_reqwrap_req(THIS) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_shutdown_reqwrap_t, shutdown_reqwrap); return &_this->req; } const iotjs_jval_t* iotjs_shutdown_reqwrap_jcallback(THIS) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_shutdown_reqwrap_t, shutdown_reqwrap); return iotjs_reqwrap_jcallback(&_this->reqwrap); } #undef THIS JHANDLER_FUNCTION(TCP) { DJHANDLER_CHECK_THIS(object); DJHANDLER_CHECK_ARGS(0); const iotjs_jval_t* jtcp = JHANDLER_GET_THIS(object); iotjs_tcpwrap_t* tcp_wrap = iotjs_tcpwrap_create(jtcp); IOTJS_UNUSED(tcp_wrap); } JHANDLER_FUNCTION(Open) { } // Socket close result handler. void AfterClose(uv_handle_t* handle) { iotjs_handlewrap_t* wrap = iotjs_handlewrap_from_handle(handle); // tcp object. const iotjs_jval_t* jtcp = iotjs_handlewrap_jobject(wrap); // callback function. iotjs_jval_t jcallback = iotjs_jval_get_property(jtcp, IOTJS_MAGIC_STRING_ONCLOSE); if (iotjs_jval_is_function(&jcallback)) { iotjs_make_callback(&jcallback, iotjs_jval_get_undefined(), iotjs_jargs_get_empty()); } iotjs_jval_destroy(&jcallback); } // Close socket JHANDLER_FUNCTION(Close) { JHANDLER_DECLARE_THIS_PTR(handlewrap, wrap); DJHANDLER_CHECK_ARGS(0); // close uv handle, `AfterClose` will be called after socket closed. iotjs_handlewrap_close(wrap, AfterClose); } // Socket binding, this function would be called from server socket before // start listening. // [0] address // [1] port JHANDLER_FUNCTION(Bind) { JHANDLER_DECLARE_THIS_PTR(tcpwrap, tcp_wrap); DJHANDLER_CHECK_ARGS(2, string, number); iotjs_string_t address = JHANDLER_GET_ARG(0, string); int port = JHANDLER_GET_ARG(1, number); sockaddr_in addr; int err = uv_ip4_addr(iotjs_string_data(&address), port, &addr); if (err == 0) { err = uv_tcp_bind(iotjs_tcpwrap_tcp_handle(tcp_wrap), (const sockaddr*)(&addr), 0); } iotjs_jhandler_return_number(jhandler, err); iotjs_string_destroy(&address); } // Connection request result handler. static void AfterConnect(uv_connect_t* req, int status) { iotjs_connect_reqwrap_t* req_wrap = (iotjs_connect_reqwrap_t*)(req->data); IOTJS_ASSERT(req_wrap != NULL); // Take callback function object. // function afterConnect(status) const iotjs_jval_t* jcallback = iotjs_connect_reqwrap_jcallback(req_wrap); IOTJS_ASSERT(iotjs_jval_is_function(jcallback)); // Only parameter is status code. iotjs_jargs_t args = iotjs_jargs_create(1); iotjs_jargs_append_number(&args, status); // Make callback. iotjs_make_callback(jcallback, iotjs_jval_get_undefined(), &args); // Destroy args iotjs_jargs_destroy(&args); // Release request wrapper. iotjs_connect_reqwrap_dispatched(req_wrap); } // Create a connection using the socket. // [0] address // [1] port // [2] callback JHANDLER_FUNCTION(Connect) { JHANDLER_DECLARE_THIS_PTR(tcpwrap, tcp_wrap); DJHANDLER_CHECK_ARGS(3, string, number, function); iotjs_string_t address = JHANDLER_GET_ARG(0, string); int port = JHANDLER_GET_ARG(1, number); const iotjs_jval_t* jcallback = JHANDLER_GET_ARG(2, function); sockaddr_in addr; int err = uv_ip4_addr(iotjs_string_data(&address), port, &addr); if (err == 0) { // Create connection request wrapper. iotjs_connect_reqwrap_t* req_wrap = iotjs_connect_reqwrap_create(jcallback); // Create connection request. err = uv_tcp_connect(iotjs_connect_reqwrap_req(req_wrap), iotjs_tcpwrap_tcp_handle(tcp_wrap), (const sockaddr*)(&addr), AfterConnect); if (err) { iotjs_connect_reqwrap_dispatched(req_wrap); } } iotjs_jhandler_return_number(jhandler, err); iotjs_string_destroy(&address); } // A client socket wants to connect to this server. // Parameters: // * uv_stream_t* handle - server handle // * int status - status code static void OnConnection(uv_stream_t* handle, int status) { // Server tcp wrapper. iotjs_tcpwrap_t* tcp_wrap = iotjs_tcpwrap_from_handle((uv_tcp_t*)handle); // Tcp object const iotjs_jval_t* jtcp = iotjs_tcpwrap_jobject(tcp_wrap); // `onconnection` callback. iotjs_jval_t jonconnection = iotjs_jval_get_property(jtcp, IOTJS_MAGIC_STRING_ONCONNECTION); IOTJS_ASSERT(iotjs_jval_is_function(&jonconnection)); // The callback takes two parameter // [0] status // [1] client tcp object iotjs_jargs_t args = iotjs_jargs_create(2); iotjs_jargs_append_number(&args, status); if (status == 0) { // Create client socket handle wrapper. iotjs_jval_t jcreate_tcp = iotjs_jval_get_property(jtcp, IOTJS_MAGIC_STRING_CREATETCP); IOTJS_ASSERT(iotjs_jval_is_function(&jcreate_tcp)); iotjs_jval_t jclient_tcp = iotjs_jhelper_call_ok(&jcreate_tcp, iotjs_jval_get_undefined(), iotjs_jargs_get_empty()); IOTJS_ASSERT(iotjs_jval_is_object(&jclient_tcp)); iotjs_tcpwrap_t* tcp_wrap_client = (iotjs_tcpwrap_t*)(iotjs_jval_get_object_native_handle(&jclient_tcp)); uv_stream_t* client_handle = (uv_stream_t*)(iotjs_tcpwrap_tcp_handle(tcp_wrap_client)); int err = uv_accept(handle, client_handle); if (err) { return; } iotjs_jargs_append_jval(&args, &jclient_tcp); iotjs_jval_destroy(&jcreate_tcp); iotjs_jval_destroy(&jclient_tcp); } iotjs_make_callback(&jonconnection, jtcp, &args); iotjs_jval_destroy(&jonconnection); iotjs_jargs_destroy(&args); } JHANDLER_FUNCTION(Listen) { JHANDLER_DECLARE_THIS_PTR(tcpwrap, tcp_wrap); DJHANDLER_CHECK_ARGS(1, number); int backlog = JHANDLER_GET_ARG(0, number); int err = uv_listen((uv_stream_t*)(iotjs_tcpwrap_tcp_handle(tcp_wrap)), backlog, OnConnection); iotjs_jhandler_return_number(jhandler, err); } void AfterWrite(uv_write_t* req, int status) { iotjs_write_reqwrap_t* req_wrap = (iotjs_write_reqwrap_t*)(req->data); iotjs_tcpwrap_t* tcp_wrap = (iotjs_tcpwrap_t*)(req->handle->data); IOTJS_ASSERT(req_wrap != NULL); IOTJS_ASSERT(tcp_wrap != NULL); // Take callback function object. const iotjs_jval_t* jcallback = iotjs_write_reqwrap_jcallback(req_wrap); // Only parameter is status code. iotjs_jargs_t args = iotjs_jargs_create(1); iotjs_jargs_append_number(&args, status); // Make callback. iotjs_make_callback(jcallback, iotjs_jval_get_undefined(), &args); // Destroy args iotjs_jargs_destroy(&args); // Release request wrapper. iotjs_write_reqwrap_dispatched(req_wrap); } JHANDLER_FUNCTION(Write) { JHANDLER_DECLARE_THIS_PTR(tcpwrap, tcp_wrap); DJHANDLER_CHECK_ARGS(2, object, function); const iotjs_jval_t* jbuffer = JHANDLER_GET_ARG(0, object); iotjs_bufferwrap_t* buffer_wrap = iotjs_bufferwrap_from_jbuffer(jbuffer); char* buffer = iotjs_bufferwrap_buffer(buffer_wrap); size_t len = iotjs_bufferwrap_length(buffer_wrap); uv_buf_t buf; buf.base = buffer; buf.len = len; const iotjs_jval_t* arg1 = JHANDLER_GET_ARG(1, object); iotjs_write_reqwrap_t* req_wrap = iotjs_write_reqwrap_create(arg1); int err = uv_write(iotjs_write_reqwrap_req(req_wrap), (uv_stream_t*)(iotjs_tcpwrap_tcp_handle(tcp_wrap)), &buf, 1, AfterWrite); if (err) { iotjs_write_reqwrap_dispatched(req_wrap); } iotjs_jhandler_return_number(jhandler, err); } void OnAlloc(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf) { if (suggested_size > IOTJS_MAX_READ_BUFFER_SIZE) { suggested_size = IOTJS_MAX_READ_BUFFER_SIZE; } buf->base = iotjs_buffer_allocate(suggested_size); buf->len = suggested_size; } void OnRead(uv_stream_t* handle, ssize_t nread, const uv_buf_t* buf) { iotjs_tcpwrap_t* tcp_wrap = iotjs_tcpwrap_from_handle((uv_tcp_t*)handle); // tcp handle const iotjs_jval_t* jtcp = iotjs_tcpwrap_jobject(tcp_wrap); // socket object iotjs_jval_t jsocket = iotjs_jval_get_property(jtcp, IOTJS_MAGIC_STRING_OWNER); IOTJS_ASSERT(iotjs_jval_is_object(&jsocket)); // onread callback iotjs_jval_t jonread = iotjs_jval_get_property(jtcp, IOTJS_MAGIC_STRING_ONREAD); IOTJS_ASSERT(iotjs_jval_is_function(&jonread)); iotjs_jargs_t jargs = iotjs_jargs_create(4); iotjs_jargs_append_jval(&jargs, &jsocket); iotjs_jargs_append_number(&jargs, nread); iotjs_jargs_append_bool(&jargs, false); if (nread <= 0) { if (buf->base != NULL) { iotjs_buffer_release(buf->base); } if (nread < 0) { if (nread == UV__EOF) { iotjs_jargs_replace(&jargs, 2, iotjs_jval_get_boolean(true)); } iotjs_make_callback(&jonread, iotjs_jval_get_undefined(), &jargs); } } else { iotjs_jval_t jbuffer = iotjs_bufferwrap_create_buffer((size_t)nread); iotjs_bufferwrap_t* buffer_wrap = iotjs_bufferwrap_from_jbuffer(&jbuffer); iotjs_bufferwrap_copy(buffer_wrap, buf->base, (size_t)nread); iotjs_jargs_append_jval(&jargs, &jbuffer); iotjs_make_callback(&jonread, iotjs_jval_get_undefined(), &jargs); iotjs_jval_destroy(&jbuffer); iotjs_buffer_release(buf->base); } iotjs_jargs_destroy(&jargs); iotjs_jval_destroy(&jonread); iotjs_jval_destroy(&jsocket); } JHANDLER_FUNCTION(ReadStart) { JHANDLER_DECLARE_THIS_PTR(tcpwrap, tcp_wrap); int err = uv_read_start((uv_stream_t*)(iotjs_tcpwrap_tcp_handle(tcp_wrap)), OnAlloc, OnRead); iotjs_jhandler_return_number(jhandler, err); } static void AfterShutdown(uv_shutdown_t* req, int status) { iotjs_shutdown_reqwrap_t* req_wrap = (iotjs_shutdown_reqwrap_t*)(req->data); iotjs_tcpwrap_t* tcp_wrap = (iotjs_tcpwrap_t*)(req->handle->data); IOTJS_ASSERT(req_wrap != NULL); IOTJS_ASSERT(tcp_wrap != NULL); // function onShutdown(status) const iotjs_jval_t* jonshutdown = iotjs_shutdown_reqwrap_jcallback(req_wrap); IOTJS_ASSERT(iotjs_jval_is_function(jonshutdown)); iotjs_jargs_t args = iotjs_jargs_create(1); iotjs_jargs_append_number(&args, status); iotjs_make_callback(jonshutdown, iotjs_jval_get_undefined(), &args); iotjs_jargs_destroy(&args); iotjs_shutdown_reqwrap_dispatched(req_wrap); } JHANDLER_FUNCTION(Shutdown) { JHANDLER_DECLARE_THIS_PTR(tcpwrap, tcp_wrap); DJHANDLER_CHECK_ARGS(1, function); const iotjs_jval_t* arg0 = JHANDLER_GET_ARG(0, object); iotjs_shutdown_reqwrap_t* req_wrap = iotjs_shutdown_reqwrap_create(arg0); int err = uv_shutdown(iotjs_shutdown_reqwrap_req(req_wrap), (uv_stream_t*)(iotjs_tcpwrap_tcp_handle(tcp_wrap)), AfterShutdown); if (err) { iotjs_shutdown_reqwrap_dispatched(req_wrap); } iotjs_jhandler_return_number(jhandler, err); } // Enable/Disable keepalive option. // [0] enable // [1] delay JHANDLER_FUNCTION(SetKeepAlive) { JHANDLER_DECLARE_THIS_PTR(tcpwrap, tcp_wrap); DJHANDLER_CHECK_ARGS(2, number, number); int enable = JHANDLER_GET_ARG(0, number); unsigned delay = JHANDLER_GET_ARG(1, number); int err = uv_tcp_keepalive(iotjs_tcpwrap_tcp_handle(tcp_wrap), enable, delay); iotjs_jhandler_return_number(jhandler, err); } JHANDLER_FUNCTION(ErrName) { DJHANDLER_CHECK_THIS(object); DJHANDLER_CHECK_ARGS(1, number); int errorcode = JHANDLER_GET_ARG(0, number); iotjs_jhandler_return_string_raw(jhandler, uv_err_name(errorcode)); } // used in iotjs_module_udp.cpp void AddressToJS(const iotjs_jval_t* obj, const sockaddr* addr) { char ip[INET6_ADDRSTRLEN]; const sockaddr_in* a4; const sockaddr_in6* a6; int port; switch (addr->sa_family) { case AF_INET6: { a6 = (const sockaddr_in6*)(addr); uv_inet_ntop(AF_INET6, &a6->sin6_addr, ip, sizeof ip); port = ntohs(a6->sin6_port); iotjs_jval_set_property_string_raw(obj, IOTJS_MAGIC_STRING_ADDRESS, ip); iotjs_jval_set_property_string_raw(obj, IOTJS_MAGIC_STRING_FAMILY, IOTJS_MAGIC_STRING_IPV6); iotjs_jval_set_property_number(obj, IOTJS_MAGIC_STRING_PORT, port); break; } case AF_INET: { a4 = (const sockaddr_in*)(addr); uv_inet_ntop(AF_INET, &a4->sin_addr, ip, sizeof ip); port = ntohs(a4->sin_port); iotjs_jval_set_property_string_raw(obj, IOTJS_MAGIC_STRING_ADDRESS, ip); iotjs_jval_set_property_string_raw(obj, IOTJS_MAGIC_STRING_FAMILY, IOTJS_MAGIC_STRING_IPV4); iotjs_jval_set_property_number(obj, IOTJS_MAGIC_STRING_PORT, port); break; } default: { iotjs_jval_set_property_string_raw(obj, IOTJS_MAGIC_STRING_ADDRESS, ""); break; } } } GetSockNameFunction(tcpwrap, tcp_handle, uv_tcp_getsockname); JHANDLER_FUNCTION(GetSockeName) { DoGetSockName(jhandler); } iotjs_jval_t InitTcp() { iotjs_jval_t tcp = iotjs_jval_create_function_with_dispatch(TCP); iotjs_jval_t prototype = iotjs_jval_create_object(); iotjs_jval_t errname = iotjs_jval_create_function_with_dispatch(ErrName); iotjs_jval_set_property_jval(&tcp, IOTJS_MAGIC_STRING_PROTOTYPE, &prototype); iotjs_jval_set_property_jval(&tcp, IOTJS_MAGIC_STRING_ERRNAME, &errname); iotjs_jval_set_method(&prototype, IOTJS_MAGIC_STRING_OPEN, Open); iotjs_jval_set_method(&prototype, IOTJS_MAGIC_STRING_CLOSE, Close); iotjs_jval_set_method(&prototype, IOTJS_MAGIC_STRING_CONNECT, Connect); iotjs_jval_set_method(&prototype, IOTJS_MAGIC_STRING_BIND, Bind); iotjs_jval_set_method(&prototype, IOTJS_MAGIC_STRING_LISTEN, Listen); iotjs_jval_set_method(&prototype, IOTJS_MAGIC_STRING_WRITE, Write); iotjs_jval_set_method(&prototype, IOTJS_MAGIC_STRING_READSTART, ReadStart); iotjs_jval_set_method(&prototype, IOTJS_MAGIC_STRING_SHUTDOWN, Shutdown); iotjs_jval_set_method(&prototype, IOTJS_MAGIC_STRING_SETKEEPALIVE, SetKeepAlive); iotjs_jval_set_method(&prototype, IOTJS_MAGIC_STRING_GETSOCKNAME, GetSockeName); iotjs_jval_destroy(&prototype); iotjs_jval_destroy(&errname); return tcp; } iotjs-1.0/src/modules/iotjs_module_tcp.h000066400000000000000000000076151312466455500205010ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef IOTJS_MODULE_TCP_H #define IOTJS_MODULE_TCP_H #include "iotjs_binding.h" #include "iotjs_handlewrap.h" #include "iotjs_reqwrap.h" typedef struct sockaddr sockaddr; typedef struct sockaddr_in sockaddr_in; typedef struct sockaddr_in6 sockaddr_in6; typedef struct sockaddr_storage sockaddr_storage; typedef struct { iotjs_handlewrap_t handlewrap; uv_tcp_t handle; } IOTJS_VALIDATED_STRUCT(iotjs_tcpwrap_t); iotjs_tcpwrap_t* iotjs_tcpwrap_create(const iotjs_jval_t* jtcp); iotjs_tcpwrap_t* iotjs_tcpwrap_from_handle(uv_tcp_t* handle); iotjs_tcpwrap_t* iotjs_tcpwrap_from_jobject(const iotjs_jval_t* jtcp); uv_tcp_t* iotjs_tcpwrap_tcp_handle(iotjs_tcpwrap_t* tcpwrap); iotjs_jval_t* iotjs_tcpwrap_jobject(iotjs_tcpwrap_t* tcpwrap); typedef struct { iotjs_reqwrap_t reqwrap; uv_connect_t req; } IOTJS_VALIDATED_STRUCT(iotjs_connect_reqwrap_t); #define THIS iotjs_connect_reqwrap_t* connect_reqwrap iotjs_connect_reqwrap_t* iotjs_connect_reqwrap_create( const iotjs_jval_t* jcallback); void iotjs_connect_reqwrap_dispatched(THIS); uv_connect_t* iotjs_connect_reqwrap_req(THIS); const iotjs_jval_t* iotjs_connect_reqwrap_jcallback(THIS); #undef THIS typedef struct { iotjs_reqwrap_t reqwrap; uv_write_t req; } IOTJS_VALIDATED_STRUCT(iotjs_write_reqwrap_t); #define THIS iotjs_write_reqwrap_t* write_reqwrap iotjs_write_reqwrap_t* iotjs_write_reqwrap_create( const iotjs_jval_t* jcallback); void iotjs_write_reqwrap_dispatched(THIS); uv_write_t* iotjs_write_reqwrap_req(THIS); const iotjs_jval_t* iotjs_write_reqwrap_jcallback(THIS); #undef THIS typedef struct { iotjs_reqwrap_t reqwrap; uv_shutdown_t req; } IOTJS_VALIDATED_STRUCT(iotjs_shutdown_reqwrap_t); #define THIS iotjs_shutdown_reqwrap_t* shutdown_reqwrap iotjs_shutdown_reqwrap_t* iotjs_shutdown_reqwrap_create( const iotjs_jval_t* jcallback); void iotjs_shutdown_reqwrap_dispatched(THIS); uv_shutdown_t* iotjs_shutdown_reqwrap_req(THIS); const iotjs_jval_t* iotjs_shutdown_reqwrap_jcallback(THIS); #undef THIS void AddressToJS(const iotjs_jval_t* obj, const sockaddr* addr); #define GetSockNameFunction(wraptype, handletype, function) \ static void DoGetSockName(iotjs_jhandler_t* jhandler) { \ DJHANDLER_CHECK_ARGS(1, object); \ \ iotjs_##wraptype##_t* wrap = \ iotjs_##wraptype##_from_jobject(JHANDLER_GET_THIS(object)); \ IOTJS_ASSERT(wrap != NULL); \ \ sockaddr_storage storage; \ int addrlen = sizeof(storage); \ sockaddr* const addr = (sockaddr*)(&storage); \ int err = function(iotjs_##wraptype##_##handletype(wrap), addr, &addrlen); \ if (err == 0) \ AddressToJS(JHANDLER_GET_ARG(0, object), addr); \ iotjs_jhandler_return_number(jhandler, err); \ } #endif /* IOTJS_MODULE_TCP_H */ iotjs-1.0/src/modules/iotjs_module_testdriver.c000066400000000000000000000044221312466455500220720ustar00rootroot00000000000000/* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "iotjs_def.h" #include "iotjs_module_timer.h" // Only for test driver JHANDLER_FUNCTION(IsAliveExceptFor) { JHANDLER_CHECK(iotjs_jhandler_get_arg_length(jhandler) == 1); const iotjs_environment_t* env = iotjs_environment_get(); uv_loop_t* loop = iotjs_environment_loop(env); const iotjs_jval_t* arg0 = iotjs_jhandler_get_arg(jhandler, 0); if (iotjs_jval_is_null(arg0)) { int alive = uv_loop_alive(loop); iotjs_jhandler_return_boolean(jhandler, alive); } else { JHANDLER_CHECK(iotjs_jval_is_object(arg0)); iotjs_jval_t jtimer = iotjs_jval_get_property(arg0, IOTJS_MAGIC_STRING_HANDLER); iotjs_timerwrap_t* timer_wrap = iotjs_timerwrap_from_jobject(&jtimer); iotjs_jval_destroy(&jtimer); bool has_active_reqs = uv_loop_has_active_reqs(loop); bool has_closing_handler = loop->closing_handles != NULL; bool ret = true; bool alive = !has_active_reqs && !has_closing_handler; if (alive) { unsigned int active_handlers = loop->active_handles; if (active_handlers == 1u) { const uv_timer_t* timer_handle = iotjs_timerwrap_handle(timer_wrap); int timer_alive = uv_is_active((uv_handle_t*)timer_handle); if (timer_alive) { // If the timer handler we set for test driver is alive, // then it can be safely terminated. ret = false; } } } iotjs_jhandler_return_boolean(jhandler, ret); } } iotjs_jval_t InitTestdriver() { iotjs_jval_t testdriver = iotjs_jval_create_object(); iotjs_jval_set_method(&testdriver, IOTJS_MAGIC_STRING_ISALIVEEXCEPTFOR, IsAliveExceptFor); return testdriver; } iotjs-1.0/src/modules/iotjs_module_timer.c000066400000000000000000000127721312466455500210260ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "iotjs_def.h" #include "iotjs_module_timer.h" static void iotjs_timerwrap_destroy(iotjs_timerwrap_t* timerwrap); static void iotjs_timerwrap_on_timeout(iotjs_timerwrap_t* timerwrap); IOTJS_DEFINE_NATIVE_HANDLE_INFO_THIS_MODULE(timerwrap); iotjs_timerwrap_t* iotjs_timerwrap_create(const iotjs_jval_t* jtimer) { iotjs_timerwrap_t* timerwrap = IOTJS_ALLOC(iotjs_timerwrap_t); uv_timer_t* uv_timer = IOTJS_ALLOC(uv_timer_t); IOTJS_VALIDATED_STRUCT_CONSTRUCTOR(iotjs_timerwrap_t, timerwrap); iotjs_handlewrap_initialize(&_this->handlewrap, jtimer, (uv_handle_t*)(uv_timer), &this_module_native_info); // Initialize timer handler. const iotjs_environment_t* env = iotjs_environment_get(); uv_timer_init(iotjs_environment_loop(env), uv_timer); return timerwrap; } static void iotjs_timerwrap_destroy(iotjs_timerwrap_t* timerwrap) { IOTJS_VALIDATED_STRUCT_DESTRUCTOR(iotjs_timerwrap_t, timerwrap); iotjs_handlewrap_destroy(&_this->handlewrap); IOTJS_RELEASE(timerwrap); } static void TimoutHandlerDestroy(uv_handle_t* handle) { IOTJS_RELEASE(handle); } // This function is called from uv when timeout expires. static void TimeoutHandler(uv_timer_t* handle) { // Find timer wrap from handle. iotjs_timerwrap_t* timer_wrap = iotjs_timerwrap_from_handle(handle); // Call the timeout handler. iotjs_timerwrap_on_timeout(timer_wrap); } int iotjs_timerwrap_start(iotjs_timerwrap_t* timerwrap, uint64_t timeout, uint64_t repeat) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_timerwrap_t, timerwrap); // Start uv timer. uv_timer_t* uv_timer = (uv_timer_t*)iotjs_handlewrap_get_uv_handle(&_this->handlewrap); return uv_timer_start(uv_timer, TimeoutHandler, timeout, repeat); } int iotjs_timerwrap_stop(iotjs_timerwrap_t* timerwrap) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_timerwrap_t, timerwrap); if (!uv_is_closing(iotjs_handlewrap_get_uv_handle(&_this->handlewrap))) { iotjs_handlewrap_close(&_this->handlewrap, TimoutHandlerDestroy); } return 0; } static void iotjs_timerwrap_on_timeout(iotjs_timerwrap_t* timerwrap) { IOTJS_VALIDATABLE_STRUCT_METHOD_VALIDATE(iotjs_timerwrap_t, timerwrap); // Call javascript timeout handler function. const iotjs_jval_t* jobject = iotjs_timerwrap_jobject(timerwrap); iotjs_jval_t jcallback = iotjs_jval_get_property(jobject, IOTJS_MAGIC_STRING_HANDLETIMEOUT); iotjs_make_callback(&jcallback, jobject, iotjs_jargs_get_empty()); iotjs_jval_destroy(&jcallback); } uv_timer_t* iotjs_timerwrap_handle(iotjs_timerwrap_t* timerwrap) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_timerwrap_t, timerwrap); return (uv_timer_t*)iotjs_handlewrap_get_uv_handle(&_this->handlewrap); } iotjs_jval_t* iotjs_timerwrap_jobject(iotjs_timerwrap_t* timerwrap) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_timerwrap_t, timerwrap); iotjs_jval_t* jobject = iotjs_handlewrap_jobject(&_this->handlewrap); IOTJS_ASSERT(iotjs_jval_is_object(jobject)); return jobject; } iotjs_timerwrap_t* iotjs_timerwrap_from_handle(uv_timer_t* timer_handle) { uv_handle_t* handle = (uv_handle_t*)(timer_handle); iotjs_handlewrap_t* handlewrap = iotjs_handlewrap_from_handle(handle); iotjs_timerwrap_t* timerwrap = (iotjs_timerwrap_t*)handlewrap; IOTJS_ASSERT(iotjs_timerwrap_handle(timerwrap) == timer_handle); return timerwrap; } iotjs_timerwrap_t* iotjs_timerwrap_from_jobject(const iotjs_jval_t* jtimer) { iotjs_handlewrap_t* handlewrap = iotjs_handlewrap_from_jobject(jtimer); return (iotjs_timerwrap_t*)handlewrap; } JHANDLER_FUNCTION(Start) { // Check parameters. JHANDLER_DECLARE_THIS_PTR(timerwrap, timer_wrap); JHANDLER_CHECK_ARGS(2, number, number); // parameters. uint64_t timeout = JHANDLER_GET_ARG(0, number); uint64_t repeat = JHANDLER_GET_ARG(1, number); // Start timer. int res = iotjs_timerwrap_start(timer_wrap, timeout, repeat); iotjs_jhandler_return_number(jhandler, res); } JHANDLER_FUNCTION(Stop) { JHANDLER_DECLARE_THIS_PTR(timerwrap, timer_wrap); // Stop timer. int res = iotjs_timerwrap_stop(timer_wrap); iotjs_jhandler_return_number(jhandler, res); } JHANDLER_FUNCTION(Timer) { JHANDLER_CHECK_THIS(object); const iotjs_jval_t* jtimer = JHANDLER_GET_THIS(object); iotjs_timerwrap_t* timer_wrap = iotjs_timerwrap_create(jtimer); IOTJS_ASSERT(iotjs_jval_is_object(iotjs_timerwrap_jobject(timer_wrap))); IOTJS_ASSERT(iotjs_jval_get_object_native_handle(jtimer) != 0); } iotjs_jval_t InitTimer() { iotjs_jval_t timer = iotjs_jval_create_function_with_dispatch(Timer); iotjs_jval_t prototype = iotjs_jval_create_object(); iotjs_jval_set_property_jval(&timer, IOTJS_MAGIC_STRING_PROTOTYPE, &prototype); iotjs_jval_set_method(&prototype, IOTJS_MAGIC_STRING_START, Start); iotjs_jval_set_method(&prototype, IOTJS_MAGIC_STRING_STOP, Stop); iotjs_jval_destroy(&prototype); return timer; } iotjs-1.0/src/modules/iotjs_module_timer.h000066400000000000000000000026721312466455500210310ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef IOTJS_MODULE_TIMER_H #define IOTJS_MODULE_TIMER_H #include "iotjs_binding.h" #include "iotjs_handlewrap.h" typedef struct { iotjs_handlewrap_t handlewrap; } IOTJS_VALIDATED_STRUCT(iotjs_timerwrap_t); iotjs_timerwrap_t* iotjs_timerwrap_create(const iotjs_jval_t* jtimer); iotjs_timerwrap_t* iotjs_timerwrap_from_jobject(const iotjs_jval_t* jtimer); iotjs_timerwrap_t* iotjs_timerwrap_from_handle(uv_timer_t* timer_handle); uv_timer_t* iotjs_timerwrap_handle(iotjs_timerwrap_t* timerwrap); iotjs_jval_t* iotjs_timerwrap_jobject(iotjs_timerwrap_t* timerwrap); // Start timer. int iotjs_timerwrap_start(iotjs_timerwrap_t* timerwrap, uint64_t timeout, uint64_t repeat); // Stop & close timer. int iotjs_timerwrap_stop(iotjs_timerwrap_t* timerwrap); #endif /* IOTJS_MODULE_TIMER_H */ iotjs-1.0/src/modules/iotjs_module_uart.c000066400000000000000000000243351312466455500206570ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include "iotjs_def.h" #include "iotjs_module_uart.h" #include "iotjs_objectwrap.h" static iotjs_uart_t* iotjs_uart_instance_from_jval(const iotjs_jval_t* juart); IOTJS_DEFINE_NATIVE_HANDLE_INFO_THIS_MODULE(uart); static iotjs_uart_t* iotjs_uart_create(const iotjs_jval_t* juart) { iotjs_uart_t* uart = IOTJS_ALLOC(iotjs_uart_t); IOTJS_VALIDATED_STRUCT_CONSTRUCTOR(iotjs_uart_t, uart); iotjs_jobjectwrap_initialize(&_this->jobjectwrap, juart, &this_module_native_info); _this->device_fd = -1; return uart; } static void iotjs_uart_destroy(iotjs_uart_t* uart) { IOTJS_VALIDATED_STRUCT_DESTRUCTOR(iotjs_uart_t, uart); iotjs_jobjectwrap_destroy(&_this->jobjectwrap); iotjs_string_destroy(&_this->device_path); IOTJS_RELEASE(uart); } #define THIS iotjs_uart_reqwrap_t* uart_reqwrap static iotjs_uart_reqwrap_t* iotjs_uart_reqwrap_create( const iotjs_jval_t* jcallback, iotjs_uart_t* uart, UartOp op) { iotjs_uart_reqwrap_t* uart_reqwrap = IOTJS_ALLOC(iotjs_uart_reqwrap_t); IOTJS_VALIDATED_STRUCT_CONSTRUCTOR(iotjs_uart_reqwrap_t, uart_reqwrap); iotjs_reqwrap_initialize(&_this->reqwrap, jcallback, (uv_req_t*)&_this->req); _this->req_data.op = op; _this->uart_instance = uart; return uart_reqwrap; } static void iotjs_uart_reqwrap_destroy(THIS) { IOTJS_VALIDATED_STRUCT_DESTRUCTOR(iotjs_uart_reqwrap_t, uart_reqwrap); iotjs_reqwrap_destroy(&_this->reqwrap); IOTJS_RELEASE(uart_reqwrap); } static void iotjs_uart_reqwrap_dispatched(THIS) { IOTJS_VALIDATABLE_STRUCT_METHOD_VALIDATE(iotjs_uart_reqwrap_t, uart_reqwrap); iotjs_uart_reqwrap_destroy(uart_reqwrap); } static uv_work_t* iotjs_uart_reqwrap_req(THIS) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_uart_reqwrap_t, uart_reqwrap); return &_this->req; } static const iotjs_jval_t* iotjs_uart_reqwrap_jcallback(THIS) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_uart_reqwrap_t, uart_reqwrap); return iotjs_reqwrap_jcallback(&_this->reqwrap); } static iotjs_uart_t* iotjs_uart_instance_from_jval(const iotjs_jval_t* juart) { iotjs_jobjectwrap_t* jobjectwrap = iotjs_jobjectwrap_from_jobject(juart); return (iotjs_uart_t*)jobjectwrap; } iotjs_uart_reqwrap_t* iotjs_uart_reqwrap_from_request(uv_work_t* req) { return (iotjs_uart_reqwrap_t*)(iotjs_reqwrap_from_request((uv_req_t*)req)); } iotjs_uart_reqdata_t* iotjs_uart_reqwrap_data(THIS) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_uart_reqwrap_t, uart_reqwrap); return &_this->req_data; } iotjs_uart_t* iotjs_uart_instance_from_reqwrap(THIS) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_uart_reqwrap_t, uart_reqwrap); return _this->uart_instance; } #undef THIS static bool iotjs_uart_close(iotjs_uart_t* uart) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_uart_t, uart); uv_poll_t* poll_handle = &_this->poll_handle; if (_this->device_fd > 0) { if (!uv_is_closing((uv_handle_t*)poll_handle)) { uv_close((uv_handle_t*)poll_handle, NULL); } if (close(_this->device_fd) < 0) { return false; } } return true; } static void iotjs_uart_write_worker(uv_work_t* work_req) { UART_WORKER_INIT; if (!iotjs_uart_write(uart)) { req_data->result = false; return; } req_data->result = true; } static void iotjs_uart_close_worker(uv_work_t* work_req) { UART_WORKER_INIT; if (!iotjs_uart_close(uart)) { req_data->result = false; return; } req_data->result = true; } static void iotjs_uart_after_worker(uv_work_t* work_req, int status) { iotjs_uart_reqwrap_t* req_wrap = iotjs_uart_reqwrap_from_request(work_req); iotjs_uart_reqdata_t* req_data = iotjs_uart_reqwrap_data(req_wrap); iotjs_jargs_t jargs = iotjs_jargs_create(1); if (status) { iotjs_jval_t error = iotjs_jval_create_error("System error"); iotjs_jargs_append_jval(&jargs, &error); iotjs_jval_destroy(&error); } else { switch (req_data->op) { case kUartOpOpen: { if (!req_data->result) { iotjs_jargs_append_error(&jargs, "Failed to open UART device"); } else { iotjs_jargs_append_null(&jargs); } break; } case kUartOpWrite: { iotjs_uart_t* uart = iotjs_uart_instance_from_reqwrap(req_wrap); IOTJS_VALIDATED_STRUCT_METHOD(iotjs_uart_t, uart); iotjs_string_destroy(&_this->buf_data); if (!req_data->result) { iotjs_jargs_append_error(&jargs, "Cannot write to device"); } else { iotjs_jargs_append_null(&jargs); } break; } case kUartOpClose: { if (!req_data->result) { iotjs_jargs_append_error(&jargs, "Failed to close UART device"); } else { iotjs_jargs_append_null(&jargs); } break; } default: { IOTJS_ASSERT(!"Unreachable"); break; } } } const iotjs_jval_t* jcallback = iotjs_uart_reqwrap_jcallback(req_wrap); iotjs_make_callback(jcallback, iotjs_jval_get_undefined(), &jargs); iotjs_jargs_destroy(&jargs); iotjs_uart_reqwrap_dispatched(req_wrap); } static void iotjs_uart_onread(iotjs_jval_t* jthis, char* buf) { iotjs_jval_t jemit = iotjs_jval_get_property(jthis, "emit"); IOTJS_ASSERT(iotjs_jval_is_function(&jemit)); iotjs_jargs_t jargs = iotjs_jargs_create(2); iotjs_jval_t str = iotjs_jval_create_string_raw("data"); iotjs_jval_t data = iotjs_jval_create_string_raw(buf); iotjs_jargs_append_jval(&jargs, &str); iotjs_jargs_append_jval(&jargs, &data); iotjs_jhelper_call_ok(&jemit, jthis, &jargs); iotjs_jval_destroy(&str); iotjs_jval_destroy(&data); iotjs_jargs_destroy(&jargs); iotjs_jval_destroy(&jemit); } void iotjs_uart_read_cb(uv_poll_t* req, int status, int events) { iotjs_uart_t* uart = (iotjs_uart_t*)req->data; IOTJS_VALIDATED_STRUCT_METHOD(iotjs_uart_t, uart); char buf[UART_WRITE_BUFFER_SIZE]; int i = read(_this->device_fd, buf, UART_WRITE_BUFFER_SIZE - 1); if (i > 0) { buf[i] = '\0'; DDDLOG("%s - read data: %s", __func__, buf); iotjs_uart_onread(&_this->jemitter_this, buf); } } #define UART_ASYNC(call, this, jcallback, op) \ do { \ uv_loop_t* loop = iotjs_environment_loop(iotjs_environment_get()); \ iotjs_uart_reqwrap_t* req_wrap = \ iotjs_uart_reqwrap_create(jcallback, this, op); \ uv_work_t* req = iotjs_uart_reqwrap_req(req_wrap); \ uv_queue_work(loop, req, iotjs_uart_##call##_worker, \ iotjs_uart_after_worker); \ } while (0) JHANDLER_FUNCTION(UartConstructor) { DJHANDLER_CHECK_THIS(object); DJHANDLER_CHECK_ARGS(3, object, object, function); // Create UART object const iotjs_jval_t* juart = JHANDLER_GET_THIS(object); iotjs_uart_t* uart = iotjs_uart_create(juart); IOTJS_ASSERT(uart == iotjs_uart_instance_from_jval(juart)); IOTJS_VALIDATED_STRUCT_METHOD(iotjs_uart_t, uart); const iotjs_jval_t* jconfiguration = JHANDLER_GET_ARG(0, object); const iotjs_jval_t* jemitter_this = JHANDLER_GET_ARG(1, object); _this->jemitter_this = iotjs_jval_create_copied(jemitter_this); const iotjs_jval_t* jcallback = JHANDLER_GET_ARG(2, function); // set configuration iotjs_jval_t jdevice = iotjs_jval_get_property(jconfiguration, IOTJS_MAGIC_STRING_DEVICE); iotjs_jval_t jbaud_rate = iotjs_jval_get_property(jconfiguration, IOTJS_MAGIC_STRING_BAUDRATE); iotjs_jval_t jdata_bits = iotjs_jval_get_property(jconfiguration, IOTJS_MAGIC_STRING_DATABITS); _this->device_path = iotjs_jval_as_string(&jdevice); _this->baud_rate = iotjs_jval_as_number(&jbaud_rate); _this->data_bits = iotjs_jval_as_number(&jdata_bits); DDDLOG("%s - path: %s, baudRate: %d, dataBits: %d", __func__, iotjs_string_data(&_this->device_path), _this->baud_rate, _this->data_bits); iotjs_jval_destroy(&jdevice); iotjs_jval_destroy(&jbaud_rate); iotjs_jval_destroy(&jdata_bits); UART_ASYNC(open, uart, jcallback, kUartOpOpen); } JHANDLER_FUNCTION(Write) { JHANDLER_DECLARE_THIS_PTR(uart, uart); DJHANDLER_CHECK_ARGS(1, string); DJHANDLER_CHECK_ARG_IF_EXIST(1, function); const iotjs_jval_t* jcallback = JHANDLER_GET_ARG_IF_EXIST(1, function); IOTJS_VALIDATED_STRUCT_METHOD(iotjs_uart_t, uart); _this->buf_data = JHANDLER_GET_ARG(0, string); _this->buf_len = iotjs_string_size(&_this->buf_data); if (jcallback) { UART_ASYNC(write, uart, jcallback, kUartOpWrite); } else { bool result = iotjs_uart_write(uart); iotjs_string_destroy(&_this->buf_data); if (!result) { JHANDLER_THROW(COMMON, "UART Write Error"); return; } } iotjs_jhandler_return_null(jhandler); } JHANDLER_FUNCTION(Close) { JHANDLER_DECLARE_THIS_PTR(uart, uart); DJHANDLER_CHECK_ARG_IF_EXIST(0, function); const iotjs_jval_t* jcallback = JHANDLER_GET_ARG_IF_EXIST(0, function); IOTJS_VALIDATED_STRUCT_METHOD(iotjs_uart_t, uart); iotjs_jval_destroy(&_this->jemitter_this); if (jcallback) { UART_ASYNC(close, uart, jcallback, kUartOpClose); } else { if (!iotjs_uart_close(uart)) { JHANDLER_THROW(COMMON, "UART Close Error"); } } } iotjs_jval_t InitUart() { iotjs_jval_t juart_constructor = iotjs_jval_create_function_with_dispatch(UartConstructor); iotjs_jval_t prototype = iotjs_jval_create_object(); iotjs_jval_set_method(&prototype, IOTJS_MAGIC_STRING_WRITE, Write); iotjs_jval_set_method(&prototype, IOTJS_MAGIC_STRING_CLOSE, Close); iotjs_jval_set_property_jval(&juart_constructor, IOTJS_MAGIC_STRING_PROTOTYPE, &prototype); iotjs_jval_destroy(&prototype); return juart_constructor; } iotjs-1.0/src/modules/iotjs_module_uart.h000066400000000000000000000041631312466455500206610ustar00rootroot00000000000000/* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef IOTJS_MODULE_UART_H #define IOTJS_MODULE_UART_H #include "iotjs_def.h" #include "iotjs_objectwrap.h" #include "iotjs_reqwrap.h" #define UART_WRITE_BUFFER_SIZE 512 typedef enum { kUartOpOpen, kUartOpClose, kUartOpWrite, } UartOp; typedef struct { iotjs_jobjectwrap_t jobjectwrap; iotjs_jval_t jemitter_this; int device_fd; int baud_rate; uint8_t data_bits; iotjs_string_t device_path; iotjs_string_t buf_data; unsigned buf_len; uv_poll_t poll_handle; } IOTJS_VALIDATED_STRUCT(iotjs_uart_t); typedef struct { UartOp op; bool result; } iotjs_uart_reqdata_t; typedef struct { iotjs_reqwrap_t reqwrap; uv_work_t req; iotjs_uart_reqdata_t req_data; iotjs_uart_t* uart_instance; } IOTJS_VALIDATED_STRUCT(iotjs_uart_reqwrap_t); #define THIS iotjs_uart_reqwrap_t* uart_reqwrap iotjs_uart_reqwrap_t* iotjs_uart_reqwrap_from_request(uv_work_t* req); iotjs_uart_reqdata_t* iotjs_uart_reqwrap_data(THIS); iotjs_uart_t* iotjs_uart_instance_from_reqwrap(THIS); #undef THIS #define UART_WORKER_INIT \ iotjs_uart_reqwrap_t* req_wrap = iotjs_uart_reqwrap_from_request(work_req); \ iotjs_uart_reqdata_t* req_data = iotjs_uart_reqwrap_data(req_wrap); \ iotjs_uart_t* uart = iotjs_uart_instance_from_reqwrap(req_wrap); void iotjs_uart_read_cb(uv_poll_t* req, int status, int events); void iotjs_uart_open_worker(uv_work_t* work_req); bool iotjs_uart_write(iotjs_uart_t* uart); #endif /* IOTJS_MODULE_UART_H */ iotjs-1.0/src/modules/iotjs_module_udp.c000066400000000000000000000337721312466455500205010ustar00rootroot00000000000000/* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "iotjs_def.h" #include "iotjs_module_udp.h" #include "iotjs_handlewrap.h" #include "iotjs_module_buffer.h" #include "iotjs_module_tcp.h" #include "iotjs_reqwrap.h" IOTJS_DEFINE_NATIVE_HANDLE_INFO_THIS_MODULE(udpwrap); iotjs_udpwrap_t* iotjs_udpwrap_create(const iotjs_jval_t* judp) { iotjs_udpwrap_t* udpwrap = IOTJS_ALLOC(iotjs_udpwrap_t); IOTJS_VALIDATED_STRUCT_CONSTRUCTOR(iotjs_udpwrap_t, udpwrap); iotjs_handlewrap_initialize(&_this->handlewrap, judp, (uv_handle_t*)(&_this->handle), &this_module_native_info); const iotjs_environment_t* env = iotjs_environment_get(); uv_udp_init(iotjs_environment_loop(env), &_this->handle); return udpwrap; } static void iotjs_udpwrap_destroy(iotjs_udpwrap_t* udpwrap) { IOTJS_VALIDATED_STRUCT_DESTRUCTOR(iotjs_udpwrap_t, udpwrap); iotjs_handlewrap_destroy(&_this->handlewrap); IOTJS_RELEASE(udpwrap); } iotjs_udpwrap_t* iotjs_udpwrap_from_handle(uv_udp_t* udp_handle) { uv_handle_t* handle = (uv_handle_t*)(udp_handle); iotjs_handlewrap_t* handlewrap = iotjs_handlewrap_from_handle(handle); iotjs_udpwrap_t* udpwrap = (iotjs_udpwrap_t*)handlewrap; IOTJS_ASSERT(iotjs_udpwrap_udp_handle(udpwrap) == udp_handle); return udpwrap; } iotjs_udpwrap_t* iotjs_udpwrap_from_jobject(const iotjs_jval_t* judp) { iotjs_handlewrap_t* handlewrap = iotjs_handlewrap_from_jobject(judp); return (iotjs_udpwrap_t*)handlewrap; } uv_udp_t* iotjs_udpwrap_udp_handle(iotjs_udpwrap_t* udpwrap) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_udpwrap_t, udpwrap); uv_handle_t* handle = iotjs_handlewrap_get_uv_handle(&_this->handlewrap); return (uv_udp_t*)handle; } iotjs_jval_t* iotjs_udpwrap_jobject(iotjs_udpwrap_t* udpwrap) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_udpwrap_t, udpwrap); return iotjs_handlewrap_jobject(&_this->handlewrap); } #define THIS iotjs_send_reqwrap_t* send_reqwrap iotjs_send_reqwrap_t* iotjs_send_reqwrap_create(const iotjs_jval_t* jcallback, const size_t msg_size) { iotjs_send_reqwrap_t* send_reqwrap = IOTJS_ALLOC(iotjs_send_reqwrap_t); IOTJS_VALIDATED_STRUCT_CONSTRUCTOR(iotjs_send_reqwrap_t, send_reqwrap); iotjs_reqwrap_initialize(&_this->reqwrap, jcallback, (uv_req_t*)&_this->req); _this->msg_size = msg_size; return send_reqwrap; } static void iotjs_send_reqwrap_destroy(THIS) { IOTJS_VALIDATED_STRUCT_DESTRUCTOR(iotjs_send_reqwrap_t, send_reqwrap); iotjs_reqwrap_destroy(&_this->reqwrap); IOTJS_RELEASE(send_reqwrap); } void iotjs_send_reqwrap_dispatched(THIS) { IOTJS_VALIDATABLE_STRUCT_METHOD_VALIDATE(iotjs_send_reqwrap_t, send_reqwrap); iotjs_send_reqwrap_destroy(send_reqwrap); } uv_udp_send_t* iotjs_send_reqwrap_req(THIS) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_send_reqwrap_t, send_reqwrap); return &_this->req; } const iotjs_jval_t* iotjs_send_reqwrap_jcallback(THIS) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_send_reqwrap_t, send_reqwrap); return iotjs_reqwrap_jcallback(&_this->reqwrap); } size_t iotjs_send_reqwrap_msg_size(THIS) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_send_reqwrap_t, send_reqwrap); return _this->msg_size; } #undef THIS JHANDLER_FUNCTION(UDP) { DJHANDLER_CHECK_THIS(object); DJHANDLER_CHECK_ARGS(0); const iotjs_jval_t* judp = JHANDLER_GET_THIS(object); iotjs_udpwrap_t* udp_wrap = iotjs_udpwrap_create(judp); IOTJS_UNUSED(udp_wrap); } JHANDLER_FUNCTION(Bind) { JHANDLER_DECLARE_THIS_PTR(udpwrap, udp_wrap); DJHANDLER_CHECK_ARGS(2, string, number); iotjs_string_t address = JHANDLER_GET_ARG(0, string); const int port = JHANDLER_GET_ARG(1, number); const iotjs_jval_t* this_obj = JHANDLER_GET_THIS(object); iotjs_jval_t reuse_addr = iotjs_jval_get_property(this_obj, IOTJS_MAGIC_STRING__REUSEADDR); IOTJS_ASSERT(iotjs_jval_is_boolean(&reuse_addr) || iotjs_jval_is_undefined(&reuse_addr)); unsigned int flags = 0; if (!iotjs_jval_is_undefined(&reuse_addr)) { flags = iotjs_jval_as_boolean(&reuse_addr) ? UV_UDP_REUSEADDR : 0; } char addr[sizeof(sockaddr_in6)]; int err = uv_ip4_addr(iotjs_string_data(&address), port, (sockaddr_in*)(&addr)); if (err == 0) { err = uv_udp_bind(iotjs_udpwrap_udp_handle(udp_wrap), (const sockaddr*)(&addr), flags); } iotjs_jhandler_return_number(jhandler, err); iotjs_jval_destroy(&reuse_addr); iotjs_string_destroy(&address); } static void OnAlloc(uv_handle_t* handle, size_t suggested_size, uv_buf_t* buf) { if (suggested_size > IOTJS_MAX_READ_BUFFER_SIZE) { suggested_size = IOTJS_MAX_READ_BUFFER_SIZE; } buf->base = iotjs_buffer_allocate(suggested_size); buf->len = suggested_size; } static void OnRecv(uv_udp_t* handle, ssize_t nread, const uv_buf_t* buf, const struct sockaddr* addr, unsigned int flags) { if (nread == 0 && addr == NULL) { if (buf->base != NULL) iotjs_buffer_release(buf->base); return; } iotjs_udpwrap_t* udp_wrap = iotjs_udpwrap_from_handle(handle); // udp handle const iotjs_jval_t* judp = iotjs_udpwrap_jobject(udp_wrap); IOTJS_ASSERT(iotjs_jval_is_object(judp)); // onmessage callback iotjs_jval_t jonmessage = iotjs_jval_get_property(judp, IOTJS_MAGIC_STRING_ONMESSAGE); IOTJS_ASSERT(iotjs_jval_is_function(&jonmessage)); iotjs_jargs_t jargs = iotjs_jargs_create(4); iotjs_jargs_append_number(&jargs, nread); iotjs_jargs_append_jval(&jargs, judp); if (nread < 0) { if (buf->base != NULL) iotjs_buffer_release(buf->base); iotjs_make_callback(&jonmessage, iotjs_jval_get_undefined(), &jargs); iotjs_jval_destroy(&jonmessage); iotjs_jargs_destroy(&jargs); return; } iotjs_jval_t jbuffer = iotjs_bufferwrap_create_buffer((size_t)nread); iotjs_bufferwrap_t* buffer_wrap = iotjs_bufferwrap_from_jbuffer(&jbuffer); iotjs_bufferwrap_copy(buffer_wrap, buf->base, (size_t)nread); iotjs_jargs_append_jval(&jargs, &jbuffer); iotjs_jval_t rinfo = iotjs_jval_create_object(); AddressToJS(&rinfo, addr); iotjs_jargs_append_jval(&jargs, &rinfo); iotjs_make_callback(&jonmessage, iotjs_jval_get_undefined(), &jargs); iotjs_jval_destroy(&rinfo); iotjs_jval_destroy(&jbuffer); iotjs_jval_destroy(&jonmessage); iotjs_buffer_release(buf->base); iotjs_jargs_destroy(&jargs); } JHANDLER_FUNCTION(RecvStart) { JHANDLER_DECLARE_THIS_PTR(udpwrap, udp_wrap); DJHANDLER_CHECK_ARGS(0); int err = uv_udp_recv_start(iotjs_udpwrap_udp_handle(udp_wrap), OnAlloc, OnRecv); // UV_EALREADY means that the socket is already bound but that's okay if (err == UV_EALREADY) err = 0; iotjs_jhandler_return_number(jhandler, err); } JHANDLER_FUNCTION(RecvStop) { JHANDLER_DECLARE_THIS_PTR(udpwrap, udp_wrap); DJHANDLER_CHECK_ARGS(0); int r = uv_udp_recv_stop(iotjs_udpwrap_udp_handle(udp_wrap)); iotjs_jhandler_return_number(jhandler, r); } static void OnSend(uv_udp_send_t* req, int status) { iotjs_send_reqwrap_t* req_wrap = (iotjs_send_reqwrap_t*)(req->data); IOTJS_ASSERT(req_wrap != NULL); // Take callback function object. const iotjs_jval_t* jcallback = iotjs_send_reqwrap_jcallback(req_wrap); if (iotjs_jval_is_function(jcallback)) { // Take callback function object. iotjs_jargs_t jargs = iotjs_jargs_create(2); iotjs_jargs_append_number(&jargs, status); iotjs_jargs_append_number(&jargs, iotjs_send_reqwrap_msg_size(req_wrap)); iotjs_make_callback(jcallback, iotjs_jval_get_undefined(), &jargs); iotjs_jargs_destroy(&jargs); } iotjs_send_reqwrap_dispatched(req_wrap); } // Send messages using the socket. // [0] buffer // [1] port // [2] ip // [3] callback function JHANDLER_FUNCTION(Send) { JHANDLER_DECLARE_THIS_PTR(udpwrap, udp_wrap); DJHANDLER_CHECK_ARGS(3, object, number, string); IOTJS_ASSERT(iotjs_jval_is_function(iotjs_jhandler_get_arg(jhandler, 3)) || iotjs_jval_is_undefined(iotjs_jhandler_get_arg(jhandler, 3))); const iotjs_jval_t* jbuffer = JHANDLER_GET_ARG(0, object); const unsigned short port = JHANDLER_GET_ARG(1, number); iotjs_string_t address = JHANDLER_GET_ARG(2, string); const iotjs_jval_t* jcallback = JHANDLER_GET_ARG(3, object); iotjs_bufferwrap_t* buffer_wrap = iotjs_bufferwrap_from_jbuffer(jbuffer); char* buffer = iotjs_bufferwrap_buffer(buffer_wrap); size_t len = iotjs_bufferwrap_length(buffer_wrap); iotjs_send_reqwrap_t* req_wrap = iotjs_send_reqwrap_create(jcallback, len); uv_buf_t buf; buf.base = buffer; buf.len = len; char addr[sizeof(sockaddr_in6)]; int err = uv_ip4_addr(iotjs_string_data(&address), port, (sockaddr_in*)(&addr)); if (err == 0) { err = uv_udp_send(iotjs_send_reqwrap_req(req_wrap), iotjs_udpwrap_udp_handle(udp_wrap), &buf, 1, (const sockaddr*)(&addr), OnSend); } if (err) { iotjs_send_reqwrap_dispatched(req_wrap); } iotjs_jhandler_return_number(jhandler, err); iotjs_string_destroy(&address); } // Close socket JHANDLER_FUNCTION(Close) { JHANDLER_DECLARE_THIS_PTR(handlewrap, wrap); DJHANDLER_CHECK_ARGS(0); iotjs_handlewrap_close(wrap, NULL); } GetSockNameFunction(udpwrap, udp_handle, uv_udp_getsockname); JHANDLER_FUNCTION(GetSockeName) { DoGetSockName(jhandler); } #define IOTJS_UV_SET_SOCKOPT(fn) \ JHANDLER_DECLARE_THIS_PTR(udpwrap, udp_wrap); \ DJHANDLER_CHECK_ARGS(1, number); \ \ int flag = JHANDLER_GET_ARG(0, number); \ int err = fn(iotjs_udpwrap_udp_handle(udp_wrap), flag); \ \ iotjs_jhandler_return_number(jhandler, err); JHANDLER_FUNCTION(SetBroadcast) { #if !defined(__NUTTX__) && !defined(__TIZENRT__) IOTJS_UV_SET_SOCKOPT(uv_udp_set_broadcast); #else IOTJS_ASSERT(!"Not implemented"); iotjs_jhandler_return_null(jhandler); #endif } JHANDLER_FUNCTION(SetTTL) { #if !defined(__NUTTX__) && !defined(__TIZENRT__) IOTJS_UV_SET_SOCKOPT(uv_udp_set_ttl); #else IOTJS_ASSERT(!"Not implemented"); iotjs_jhandler_return_null(jhandler); #endif } JHANDLER_FUNCTION(SetMulticastTTL) { #if !defined(__NUTTX__) && !defined(__TIZENRT__) IOTJS_UV_SET_SOCKOPT(uv_udp_set_multicast_ttl); #else IOTJS_ASSERT(!"Not implemented"); iotjs_jhandler_return_null(jhandler); #endif } JHANDLER_FUNCTION(SetMulticastLoopback) { #if !defined(__NUTTX__) && !defined(__TIZENRT__) IOTJS_UV_SET_SOCKOPT(uv_udp_set_multicast_loop); #else IOTJS_ASSERT(!"Not implemented"); iotjs_jhandler_return_null(jhandler); #endif } #undef IOTJS_UV_SET_SOCKOPT void SetMembership(iotjs_jhandler_t* jhandler, uv_membership membership) { #if !defined(__NUTTX__) && !defined(__TIZENRT__) JHANDLER_DECLARE_THIS_PTR(udpwrap, udp_wrap); DJHANDLER_CHECK_ARGS(1, string); iotjs_string_t address = JHANDLER_GET_ARG(0, string); const iotjs_jval_t* arg1 = iotjs_jhandler_get_arg(jhandler, 1); bool isUndefinedOrNull = iotjs_jval_is_undefined(arg1) || iotjs_jval_is_null(arg1); iotjs_string_t iface; const char* iface_cstr; if (isUndefinedOrNull) { iface_cstr = NULL; } else { iface = iotjs_jval_as_string(arg1); iface_cstr = iotjs_string_data(&iface); } int err = uv_udp_set_membership(iotjs_udpwrap_udp_handle(udp_wrap), iotjs_string_data(&address), iface_cstr, membership); iotjs_jhandler_return_number(jhandler, err); iotjs_string_destroy(&address); if (!isUndefinedOrNull) iotjs_string_destroy(&iface); #else IOTJS_ASSERT(!"Not implemented"); iotjs_jhandler_return_null(jhandler); #endif } JHANDLER_FUNCTION(AddMembership) { SetMembership(jhandler, UV_JOIN_GROUP); } JHANDLER_FUNCTION(DropMembership) { SetMembership(jhandler, UV_LEAVE_GROUP); } JHANDLER_FUNCTION(Ref) { IOTJS_ASSERT(!"Not implemented"); iotjs_jhandler_return_null(jhandler); } JHANDLER_FUNCTION(Unref) { IOTJS_ASSERT(!"Not implemented"); iotjs_jhandler_return_null(jhandler); } iotjs_jval_t InitUdp() { iotjs_jval_t udp = iotjs_jval_create_function_with_dispatch(UDP); iotjs_jval_t prototype = iotjs_jval_create_object(); iotjs_jval_set_property_jval(&udp, IOTJS_MAGIC_STRING_PROTOTYPE, &prototype); iotjs_jval_set_method(&prototype, IOTJS_MAGIC_STRING_BIND, Bind); iotjs_jval_set_method(&prototype, IOTJS_MAGIC_STRING_RECVSTART, RecvStart); iotjs_jval_set_method(&prototype, IOTJS_MAGIC_STRING_RECVSTOP, RecvStop); iotjs_jval_set_method(&prototype, IOTJS_MAGIC_STRING_SEND, Send); iotjs_jval_set_method(&prototype, IOTJS_MAGIC_STRING_CLOSE, Close); iotjs_jval_set_method(&prototype, IOTJS_MAGIC_STRING_GETSOCKNAME, GetSockeName); iotjs_jval_set_method(&prototype, IOTJS_MAGIC_STRING_SETBROADCAST, SetBroadcast); iotjs_jval_set_method(&prototype, IOTJS_MAGIC_STRING_SETTTL, SetTTL); iotjs_jval_set_method(&prototype, IOTJS_MAGIC_STRING_SETMULTICASTTTL, SetMulticastTTL); iotjs_jval_set_method(&prototype, IOTJS_MAGIC_STRING_SETMULTICASTLOOPBACK, SetMulticastLoopback); iotjs_jval_set_method(&prototype, IOTJS_MAGIC_STRING_ADDMEMBERSHIP, AddMembership); iotjs_jval_set_method(&prototype, IOTJS_MAGIC_STRING_DROPMEMBERSHIP, DropMembership); iotjs_jval_set_method(&prototype, IOTJS_MAGIC_STRING_REF, Ref); iotjs_jval_set_method(&prototype, IOTJS_MAGIC_STRING_UNREF, Unref); iotjs_jval_destroy(&prototype); return udp; } iotjs-1.0/src/modules/iotjs_module_udp.h000066400000000000000000000033221312466455500204720ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef IOTJS_MODULE_UDP_H #define IOTJS_MODULE_UDP_H #include "iotjs_def.h" #include "iotjs_handlewrap.h" #include "iotjs_reqwrap.h" typedef struct { iotjs_handlewrap_t handlewrap; uv_udp_t handle; } IOTJS_VALIDATED_STRUCT(iotjs_udpwrap_t); iotjs_udpwrap_t* iotjs_udpwrap_create(const iotjs_jval_t* judp); iotjs_udpwrap_t* iotjs_udpwrap_from_handle(uv_udp_t* handle); iotjs_udpwrap_t* iotjs_udpwrap_from_jobject(const iotjs_jval_t* judp); uv_udp_t* iotjs_udpwrap_udp_handle(iotjs_udpwrap_t* udpwrap); iotjs_jval_t* iotjs_udpwrap_jobject(iotjs_udpwrap_t* udpwrap); typedef struct { iotjs_reqwrap_t reqwrap; uv_udp_send_t req; size_t msg_size; } IOTJS_VALIDATED_STRUCT(iotjs_send_reqwrap_t); #define THIS iotjs_send_reqwrap_t* send_reqwrap iotjs_send_reqwrap_t* iotjs_send_reqwrap_create(const iotjs_jval_t* jcallback, const size_t msg_size); void iotjs_send_reqwrap_dispatched(THIS); uv_udp_send_t* iotjs_send_reqwrap_req(THIS); const iotjs_jval_t* iotjs_send_reqwrap_jcallback(THIS); #undef THIS #endif /* IOTJS_MODULE_UDP_H */ iotjs-1.0/src/platform/000077500000000000000000000000001312466455500151305ustar00rootroot00000000000000iotjs-1.0/src/platform/linux/000077500000000000000000000000001312466455500162675ustar00rootroot00000000000000iotjs-1.0/src/platform/linux/iotjs_module_adc-linux.c000066400000000000000000000036161312466455500231020ustar00rootroot00000000000000/* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef IOTJS_MODULE_ADC_LINUX_GENERAL_INL_H #define IOTJS_MODULE_ADC_LINUX_GENERAL_INL_H #include #include #include #include #include "iotjs_systemio-linux.h" #include "modules/iotjs_module_adc.h" #define ADC_PIN_FORMAT ADC_INTERFACE ADC_PIN_INTERFACE #define ADC_PATH_BUFFER_SIZE DEVICE_IO_PATH_BUFFER_SIZE #define ADC_PIN_BUFFER_SIZE DEVICE_IO_PIN_BUFFER_SIZE #define ADC_VALUE_BUFFER_SIZE 64 // Implementation used here are based on: // https://www.kernel.org/doc/Documentation/adc/sysfs.txt int32_t iotjs_adc_read(iotjs_adc_t* adc) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_adc_t, adc); const char* device_path = iotjs_string_data(&_this->device); char buffer[ADC_VALUE_BUFFER_SIZE]; if (!iotjs_systemio_open_read_close(device_path, buffer, sizeof(buffer))) { return -1; } return atoi(buffer); } bool iotjs_adc_close(iotjs_adc_t* adc) { return true; } void iotjs_adc_open_worker(uv_work_t* work_req) { ADC_WORKER_INIT; IOTJS_VALIDATED_STRUCT_METHOD(iotjs_adc_t, adc); DDDLOG("%s()", __func__); const char* device_path = iotjs_string_data(&_this->device); // Check if ADC interface exists. req_data->result = iotjs_systemio_check_path(device_path); } #endif /* IOTJS_MODULE_ADC_LINUX_GENERAL_INL_H */ iotjs-1.0/src/platform/linux/iotjs_module_blehcisocket-linux.c000066400000000000000000000304341312466455500250100ustar00rootroot00000000000000/* Copyright 2017-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* Copyright (C) 2015 Sandeep Mistry sandeep.mistry@gmail.com * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #ifndef IOTJS_MODULE_BLE_HCI_SOCKET_LINUX_GENERAL_INL_H #define IOTJS_MODULE_BLE_HCI_SOCKET_LINUX_GENERAL_INL_H #include #include #include #include #include #include #include "iotjs_def.h" #include "modules/iotjs_module_blehcisocket.h" #include "modules/iotjs_module_buffer.h" #define BTPROTO_L2CAP 0 #define BTPROTO_HCI 1 #define SOL_HCI 0 #define HCI_FILTER 2 #define HCIGETDEVLIST _IOR('H', 210, int) #define HCIGETDEVINFO _IOR('H', 211, int) #define HCI_CHANNEL_RAW 0 #define HCI_CHANNEL_USER 1 #define HCI_CHANNEL_CONTROL 3 #define HCI_DEV_NONE 0xffff #define HCI_MAX_DEV 16 #define ATT_CID 4 enum { HCI_UP, HCI_INIT, HCI_RUNNING, HCI_PSCAN, HCI_ISCAN, HCI_AUTH, HCI_ENCRYPT, HCI_INQUIRY, HCI_RAW, }; struct sockaddr_hci { sa_family_t hci_family; unsigned short hci_dev; unsigned short hci_channel; }; struct hci_dev_req { uint16_t dev_id; uint32_t dev_opt; }; struct hci_dev_list_req { uint16_t dev_num; struct hci_dev_req dev_req[0]; }; typedef struct hci_dev_list_req hci_dev_list_req_type; typedef struct { uint8_t b[6]; } __attribute__((packed)) bdaddr_t; struct hci_dev_info { uint16_t dev_id; char name[8]; bdaddr_t bdaddr; uint32_t flags; uint8_t type; uint8_t features[8]; uint32_t pkt_type; uint32_t link_policy; uint32_t link_mode; uint16_t acl_mtu; uint16_t acl_pkts; uint16_t sco_mtu; uint16_t sco_pkts; // hci_dev_stats uint32_t err_rx; uint32_t err_tx; uint32_t cmd_tx; uint32_t evt_rx; uint32_t acl_tx; uint32_t acl_rx; uint32_t sco_tx; uint32_t sco_rx; uint32_t byte_rx; uint32_t byte_tx; }; struct sockaddr_l2 { sa_family_t l2_family; unsigned short l2_psm; bdaddr_t l2_bdaddr; unsigned short l2_cid; uint8_t l2_bdaddr_type; }; #define THIS iotjs_blehcisocket_t* blehcisocket void iotjs_blehcisocket_initialize(THIS) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_blehcisocket_t, blehcisocket); _this->_l2socketCount = 0; _this->_socket = socket(AF_BLUETOOTH, SOCK_RAW | SOCK_CLOEXEC, BTPROTO_HCI); uv_loop_t* loop = iotjs_environment_loop(iotjs_environment_get()); uv_poll_init(loop, &(_this->_pollHandle), _this->_socket); _this->_pollHandle.data = blehcisocket; } void iotjs_blehcisocket_close(THIS) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_blehcisocket_t, blehcisocket); uv_close((uv_handle_t*)&(_this->_pollHandle), NULL); close(_this->_socket); } void iotjs_blehcisocket_start(THIS) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_blehcisocket_t, blehcisocket); uv_poll_start(&_this->_pollHandle, UV_READABLE, iotjs_blehcisocket_poll_cb); } int iotjs_blehcisocket_bindRaw(THIS, int* devId) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_blehcisocket_t, blehcisocket); struct sockaddr_hci a; struct hci_dev_info di; memset(&a, 0, sizeof(a)); a.hci_family = AF_BLUETOOTH; a.hci_dev = iotjs_blehcisocket_devIdFor(blehcisocket, devId, true); a.hci_channel = HCI_CHANNEL_RAW; _this->_devId = a.hci_dev; _this->_mode = HCI_CHANNEL_RAW; if (bind(_this->_socket, (struct sockaddr*)&a, sizeof(a)) < 0) { DLOG("ERROR on binding: %s", strerror(errno)); return _this->_devId; } // get the local address and address type memset(&di, 0x00, sizeof(di)); di.dev_id = _this->_devId; memset(_this->_address, 0, sizeof(_this->_address)); _this->_addressType = 0; if (ioctl(_this->_socket, HCIGETDEVINFO, (void*)&di) > -1) { memcpy(_this->_address, &di.bdaddr, sizeof(di.bdaddr)); _this->_addressType = di.type; if (_this->_addressType == 3) { // 3 is a weird type, use 1 (public) instead _this->_addressType = 1; } } return _this->_devId; } int iotjs_blehcisocket_bindUser(THIS, int* devId) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_blehcisocket_t, blehcisocket); struct sockaddr_hci a; memset(&a, 0, sizeof(a)); a.hci_family = AF_BLUETOOTH; a.hci_dev = iotjs_blehcisocket_devIdFor(blehcisocket, devId, false); a.hci_channel = HCI_CHANNEL_USER; _this->_devId = a.hci_dev; _this->_mode = HCI_CHANNEL_USER; if (bind(_this->_socket, (struct sockaddr*)&a, sizeof(a)) < 0) { DLOG("ERROR on binding: %s", strerror(errno)); } return _this->_devId; } void iotjs_blehcisocket_bindControl(THIS) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_blehcisocket_t, blehcisocket); struct sockaddr_hci a; memset(&a, 0, sizeof(a)); a.hci_family = AF_BLUETOOTH; a.hci_dev = HCI_DEV_NONE; a.hci_channel = HCI_CHANNEL_CONTROL; _this->_mode = HCI_CHANNEL_CONTROL; if (bind(_this->_socket, (struct sockaddr*)&a, sizeof(a)) < 0) { DLOG("ERROR on binding: %s", strerror(errno)); } } bool iotjs_blehcisocket_isDevUp(THIS) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_blehcisocket_t, blehcisocket); struct hci_dev_info di; bool isUp = false; memset(&di, 0x00, sizeof(di)); di.dev_id = _this->_devId; if (ioctl(_this->_socket, HCIGETDEVINFO, (void*)&di) > -1) { isUp = (di.flags & (1 << HCI_UP)) != 0; } return isUp; } void iotjs_blehcisocket_setFilter(THIS, char* data, size_t length) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_blehcisocket_t, blehcisocket); if (setsockopt(_this->_socket, SOL_HCI, HCI_FILTER, data, (socklen_t)length) < 0) { iotjs_blehcisocket_emitErrnoError(blehcisocket); } } void iotjs_blehcisocket_poll(THIS) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_blehcisocket_t, blehcisocket); int length = 0; char data[1024]; length = read(_this->_socket, data, sizeof(data)); if (length > 0) { if (_this->_mode == HCI_CHANNEL_RAW) { if (iotjs_blehcisocket_kernelDisconnectWorkArounds(blehcisocket, length, data) < 0) { return; } } iotjs_jval_t* jhcisocket = iotjs_jobjectwrap_jobject(&_this->jobjectwrap); iotjs_jval_t jemit = iotjs_jval_get_property(jhcisocket, "emit"); IOTJS_ASSERT(iotjs_jval_is_function(&jemit)); iotjs_jargs_t jargs = iotjs_jargs_create(2); iotjs_jval_t str = iotjs_jval_create_string_raw("data"); IOTJS_ASSERT(length >= 0); iotjs_jval_t jbuf = iotjs_bufferwrap_create_buffer((size_t)length); iotjs_bufferwrap_t* buf_wrap = iotjs_bufferwrap_from_jbuffer(&jbuf); iotjs_bufferwrap_copy(buf_wrap, data, (size_t)length); iotjs_jargs_append_jval(&jargs, &str); iotjs_jargs_append_jval(&jargs, &jbuf); iotjs_jhelper_call_ok(&jemit, jhcisocket, &jargs); iotjs_jval_destroy(&str); iotjs_jval_destroy(&jbuf); iotjs_jargs_destroy(&jargs); iotjs_jval_destroy(&jemit); } } void iotjs_blehcisocket_stop(THIS) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_blehcisocket_t, blehcisocket); uv_poll_stop(&_this->_pollHandle); } void iotjs_blehcisocket_write(THIS, char* data, size_t length) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_blehcisocket_t, blehcisocket); if (write(_this->_socket, data, length) < 0) { iotjs_blehcisocket_emitErrnoError(blehcisocket); } } void iotjs_blehcisocket_emitErrnoError(THIS) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_blehcisocket_t, blehcisocket); iotjs_jval_t* jhcisocket = iotjs_jobjectwrap_jobject(&_this->jobjectwrap); iotjs_jval_t jemit = iotjs_jval_get_property(jhcisocket, "emit"); IOTJS_ASSERT(iotjs_jval_is_function(&jemit)); iotjs_jargs_t jargs = iotjs_jargs_create(2); iotjs_jval_t str = iotjs_jval_create_string_raw("error"); iotjs_jval_t jerror = iotjs_jval_create_error(strerror(errno)); iotjs_jargs_append_jval(&jargs, &str); iotjs_jargs_append_jval(&jargs, &jerror); iotjs_jhelper_call_ok(&jemit, jhcisocket, &jargs); iotjs_jval_destroy(&str); iotjs_jval_destroy(&jerror); iotjs_jargs_destroy(&jargs); iotjs_jval_destroy(&jemit); } int iotjs_blehcisocket_devIdFor(THIS, int* pDevId, bool isUp) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_blehcisocket_t, blehcisocket); int devId = 0; // default if (pDevId == NULL) { struct hci_dev_list_req* dl; struct hci_dev_req* dr; dl = (struct hci_dev_list_req*)calloc(HCI_MAX_DEV * sizeof(*dr) + sizeof(*dl), 1); dr = dl->dev_req; dl->dev_num = HCI_MAX_DEV; if (ioctl(_this->_socket, HCIGETDEVLIST, dl) > -1) { for (int i = 0; i < dl->dev_num; i++, dr++) { bool devUp = dr->dev_opt & (1 << HCI_UP); bool match = isUp ? devUp : !devUp; if (match) { devId = dr->dev_id; break; } } } free(dl); } else { devId = *pDevId; } return devId; } int iotjs_blehcisocket_kernelDisconnectWorkArounds(THIS, int length, char* data) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_blehcisocket_t, blehcisocket); if (length == 22 && data[0] == 0x04 && data[1] == 0x3e && data[2] == 0x13 && data[3] == 0x01 && data[4] == 0x00) { int l2socket; struct sockaddr_l2 l2a; unsigned short l2cid; unsigned short handle = *((unsigned short*)(&data[5])); #if __BYTE_ORDER == __LITTLE_ENDIAN l2cid = ATT_CID; #elif __BYTE_ORDER == __BIG_ENDIAN l2cid = bswap_16(ATT_CID); #else #error "Unknown byte order" #endif l2socket = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP); if (l2socket < 0) { DLOG("ERROR creating socket: %s", strerror(errno)); return -1; } memset(&l2a, 0, sizeof(l2a)); l2a.l2_family = AF_BLUETOOTH; l2a.l2_cid = l2cid; memcpy(&l2a.l2_bdaddr, _this->_address, sizeof(l2a.l2_bdaddr)); l2a.l2_bdaddr_type = _this->_addressType; if (bind(l2socket, (struct sockaddr*)&l2a, sizeof(l2a)) < 0) { DLOG("ERROR on binding: %s", strerror(errno)); close(l2socket); return -1; } memset(&l2a, 0, sizeof(l2a)); l2a.l2_family = AF_BLUETOOTH; memcpy(&l2a.l2_bdaddr, &data[9], sizeof(l2a.l2_bdaddr)); l2a.l2_cid = l2cid; l2a.l2_bdaddr_type = data[8] + 1; if (connect(l2socket, (struct sockaddr*)&l2a, sizeof(l2a)) < 0) { DLOG("ERROR connecting socket: %s", strerror(errno)); close(l2socket); return -1; } _this->_l2sockets[handle] = l2socket; _this->_l2socketCount++; } else if (length == 7 && data[0] == 0x04 && data[1] == 0x05 && data[2] == 0x04 && data[3] == 0x00) { unsigned short handle = *((unsigned short*)(&data[4])); if (_this->_l2socketCount > 0) { close(_this->_l2sockets[handle]); _this->_l2socketCount--; } } return 0; } #undef THIS void iotjs_blehcisocket_poll_cb(uv_poll_t* handle, int status, int events) { iotjs_blehcisocket_t* blehcisocket = (iotjs_blehcisocket_t*)handle->data; iotjs_blehcisocket_poll(blehcisocket); } #endif /* IOTJS_MODULE_BLE_HCI_SOCKET_LINUX_GENERAL_INL_H */ iotjs-1.0/src/platform/linux/iotjs_module_gpio-linux.c000066400000000000000000000166101312466455500233070ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include #include #include "iotjs_systemio-linux.h" #include "modules/iotjs_module_gpio.h" #define GPIO_INTERFACE "/sys/class/gpio/" #define GPIO_EXPORT "export" #define GPIO_UNEXPORT "unexport" #define GPIO_DIRECTION "direction" #define GPIO_EDGE "edge" #define GPIO_VALUE "value" #define GPIO_PIN_INTERFACE "gpio%d/" #define GPIO_PIN_FORMAT_EXPORT GPIO_INTERFACE "export" #define GPIO_PIN_FORMAT_UNEXPORT GPIO_INTERFACE "unexport" #define GPIO_PIN_FORMAT GPIO_INTERFACE GPIO_PIN_INTERFACE #define GPIO_PIN_FORMAT_DIRECTION GPIO_PIN_FORMAT GPIO_DIRECTION #define GPIO_PIN_FORMAT_EDGE GPIO_PIN_FORMAT GPIO_EDGE #define GPIO_PIN_FORMAT_VALUE GPIO_PIN_FORMAT GPIO_VALUE #define GPIO_PATH_BUFFER_SIZE DEVICE_IO_PATH_BUFFER_SIZE #define GPIO_PIN_BUFFER_SIZE DEVICE_IO_PIN_BUFFER_SIZE #define GPIO_VALUE_BUFFER_SIZE 10 // Implementation used here are based on: // https://www.kernel.org/doc/Documentation/gpio/sysfs.txt static const char* gpio_edge_string[] = { "none", "rising", "falling", "both" }; static int gpio_get_value_fd(iotjs_gpio_t* gpio) { int fd; IOTJS_VALIDATED_STRUCT_METHOD(iotjs_gpio_t, gpio); uv_mutex_lock(&_this->mutex); fd = _this->value_fd; uv_mutex_unlock(&_this->mutex); return fd; } static void gpio_set_value_fd(iotjs_gpio_t* gpio, int fd) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_gpio_t, gpio); uv_mutex_lock(&_this->mutex); _this->value_fd = fd; uv_mutex_unlock(&_this->mutex); } static void gpio_emit_change_event(iotjs_gpio_t* gpio) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_gpio_t, gpio); iotjs_jval_t* jgpio = iotjs_jobjectwrap_jobject(&_this->jobjectwrap); iotjs_jval_t jonChange = iotjs_jval_get_property(jgpio, "onChange"); IOTJS_ASSERT(iotjs_jval_is_function(&jonChange)); iotjs_jhelper_call_ok(&jonChange, jgpio, iotjs_jargs_get_empty()); iotjs_jval_destroy(&jonChange); } static bool gpio_clear_dummy_value(int fd) { char buffer[1]; if (lseek(fd, 0, SEEK_SET) < 0) { DLOG("GPIO Error in lseek"); return false; } if (read(fd, &buffer, 1) < 0) { DLOG("GPIO Error in read"); return false; } return true; } static int gpio_edge_poll(struct pollfd* pollfd) { int ret; // Wait edge if ((ret = poll(pollfd, 1, -1)) > 0) { if (!gpio_clear_dummy_value(pollfd->fd)) return -1; } return ret; } static void gpio_edge_detection_cb(void* data) { int fd; iotjs_gpio_t* gpio = (iotjs_gpio_t*)data; struct pollfd pollfd; if ((fd = gpio_get_value_fd(gpio)) < 0) { DLOG("GPIO Error: cannot start edge detection"); return; } memset(&pollfd, 0, sizeof(pollfd)); pollfd.fd = fd; pollfd.events = POLLPRI | POLLERR; if (!gpio_clear_dummy_value(fd)) return; while (true) { if ((fd = gpio_get_value_fd(gpio)) < 0) return; if (gpio_edge_poll(&pollfd) > 0) { gpio_emit_change_event(gpio); } else { DLOG("GPIO Error on poll: %s", strerror(errno)); } } } static bool gpio_set_direction(uint32_t pin, GpioDirection direction) { IOTJS_ASSERT(direction == kGpioDirectionIn || direction == kGpioDirectionOut); char direction_path[GPIO_PATH_BUFFER_SIZE]; snprintf(direction_path, GPIO_PATH_BUFFER_SIZE, GPIO_PIN_FORMAT_DIRECTION, pin); const char* buffer = (direction == kGpioDirectionIn) ? "in" : "out"; DDDLOG("%s - path: %s, dir: %s", __func__, direction_path, buffer); return iotjs_systemio_open_write_close(direction_path, buffer); } // FIXME: Implement SetPinMode() static bool gpio_set_mode(uint32_t pin, GpioMode mode) { return true; } static bool gpio_set_edge(iotjs_gpio_t* gpio) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_gpio_t, gpio); char edge_path[GPIO_PATH_BUFFER_SIZE]; snprintf(edge_path, GPIO_PATH_BUFFER_SIZE, GPIO_PIN_FORMAT_EDGE, _this->pin); iotjs_systemio_open_write_close(edge_path, gpio_edge_string[_this->edge]); if (_this->direction == kGpioDirectionIn && _this->edge != kGpioEdgeNone) { char value_path[GPIO_PATH_BUFFER_SIZE]; snprintf(value_path, GPIO_PATH_BUFFER_SIZE, GPIO_PIN_FORMAT_VALUE, _this->pin); if ((_this->value_fd = open(value_path, O_RDONLY)) < 0) { DLOG("GPIO Error in open"); return false; } uv_mutex_init(&_this->mutex); // Create edge detection thread // When the GPIO pin is closed, thread is terminated. if (uv_thread_create(&_this->thread, gpio_edge_detection_cb, (void*)gpio) < 0) { DLOG("GPIO Error in uv_thread_create"); } return false; } return true; } bool iotjs_gpio_write(iotjs_gpio_t* gpio, bool value) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_gpio_t, gpio); char value_path[GPIO_PATH_BUFFER_SIZE]; snprintf(value_path, GPIO_PATH_BUFFER_SIZE, GPIO_PIN_FORMAT_VALUE, _this->pin); const char* buffer = value ? "1" : "0"; DDDLOG("%s - pin: %d, value: %d", __func__, _this->pin, value); return iotjs_systemio_open_write_close(value_path, buffer); } int iotjs_gpio_read(iotjs_gpio_t* gpio) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_gpio_t, gpio); char buffer[GPIO_VALUE_BUFFER_SIZE]; char value_path[GPIO_PATH_BUFFER_SIZE]; snprintf(value_path, GPIO_PATH_BUFFER_SIZE, GPIO_PIN_FORMAT_VALUE, _this->pin); if (!iotjs_systemio_open_read_close(value_path, buffer, GPIO_VALUE_BUFFER_SIZE - 1)) { return -1; } return atoi(buffer); } bool iotjs_gpio_close(iotjs_gpio_t* gpio) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_gpio_t, gpio); char buff[GPIO_PIN_BUFFER_SIZE]; snprintf(buff, GPIO_PIN_BUFFER_SIZE, "%d", _this->pin); gpio_set_value_fd(gpio, -1); close(_this->value_fd); return iotjs_systemio_open_write_close(GPIO_PIN_FORMAT_UNEXPORT, buff); } void iotjs_gpio_open_worker(uv_work_t* work_req) { GPIO_WORKER_INIT; IOTJS_VALIDATED_STRUCT_METHOD(iotjs_gpio_t, gpio); DDDLOG("%s - pin: %d, dir: %d, mode: %d", __func__, _this->pin, _this->direction, _this->mode); // Open GPIO pin. char exported_path[GPIO_PATH_BUFFER_SIZE]; snprintf(exported_path, GPIO_PATH_BUFFER_SIZE, GPIO_PIN_FORMAT, _this->pin); const char* created_files[] = { GPIO_DIRECTION, GPIO_EDGE, GPIO_VALUE }; int created_files_length = sizeof(created_files) / sizeof(created_files[0]); if (!iotjs_systemio_device_open(GPIO_PIN_FORMAT_EXPORT, _this->pin, exported_path, created_files, created_files_length)) { req_data->result = false; return; } // Set direction. if (!gpio_set_direction(_this->pin, _this->direction)) { req_data->result = false; return; } // Set mode. if (!gpio_set_mode(_this->pin, _this->mode)) { req_data->result = false; return; } // Set edge if (!gpio_set_edge(gpio)) { req_data->result = false; return; } req_data->result = true; } iotjs-1.0/src/platform/linux/iotjs_module_i2c-linux.c000066400000000000000000000106611312466455500230260ustar00rootroot00000000000000/* The MIT License (MIT) * * Copyright (c) 2005-2014 RoadNarrows LLC. * http://roadnarrows.com * All Rights Reserved * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom * the Software is furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ /* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* Some functions are modified from the RoadNarrows-robotics i2c library. * (distributed under the MIT license.) */ #include #include #include #include #include #include #include #include #include #include "modules/iotjs_module_i2c.h" #define I2C_SLAVE_FORCE 0x0706 #define I2C_SMBUS 0x0720 #define I2C_SMBUS_READ 1 #define I2C_SMBUS_WRITE 0 #define I2C_NOCMD 0 #define I2C_SMBUS_BYTE 1 #define I2C_SMBUS_BLOCK_DATA 5 #define I2C_SMBUS_I2C_BLOCK_DATA 8 #define I2C_SMBUS_BLOCK_MAX 32 #define I2C_MAX_ADDRESS 128 typedef union I2cSmbusDataUnion { uint8_t byte; unsigned short word; uint8_t block[I2C_SMBUS_BLOCK_MAX + 2]; } I2cSmbusData; typedef struct I2cSmbusIoctlDataStruct { uint8_t read_write; uint8_t command; int size; I2cSmbusData* data; } I2cSmbusIoctlData; #define I2C_WORKER_INIT_TEMPLATE \ iotjs_i2c_reqwrap_t* req_wrap = iotjs_i2c_reqwrap_from_request(work_req); \ iotjs_i2c_reqdata_t* req_data = iotjs_i2c_reqwrap_data(req_wrap); void I2cSetAddress(iotjs_i2c_t* i2c, uint8_t address) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_i2c_t, i2c); _this->addr = address; ioctl(_this->device_fd, I2C_SLAVE_FORCE, _this->addr); } void OpenWorker(uv_work_t* work_req) { I2C_WORKER_INIT_TEMPLATE; iotjs_i2c_t* i2c = iotjs_i2c_instance_from_reqwrap(req_wrap); IOTJS_VALIDATED_STRUCT_METHOD(iotjs_i2c_t, i2c); _this->device_fd = open(iotjs_string_data(&req_data->device), O_RDWR); if (_this->device_fd == -1) { req_data->error = kI2cErrOpen; } else { req_data->error = kI2cErrOk; } } void I2cClose(iotjs_i2c_t* i2c) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_i2c_t, i2c); if (_this->device_fd > 0) { close(_this->device_fd); _this->device_fd = -1; } } void WriteWorker(uv_work_t* work_req) { I2C_WORKER_INIT_TEMPLATE; iotjs_i2c_t* i2c = iotjs_i2c_instance_from_reqwrap(req_wrap); IOTJS_VALIDATED_STRUCT_METHOD(iotjs_i2c_t, i2c); uint8_t len = req_data->buf_len; char* data = req_data->buf_data; if (write(_this->device_fd, data, len) != len) { req_data->error = kI2cErrWrite; } if (req_data->buf_data != NULL) { iotjs_buffer_release(req_data->buf_data); } } void ReadWorker(uv_work_t* work_req) { I2C_WORKER_INIT_TEMPLATE; iotjs_i2c_t* i2c = iotjs_i2c_instance_from_reqwrap(req_wrap); IOTJS_VALIDATED_STRUCT_METHOD(iotjs_i2c_t, i2c); uint8_t len = req_data->buf_len; req_data->buf_data = iotjs_buffer_allocate(len); if (read(_this->device_fd, req_data->buf_data, len) != len) { req_data->error = kI2cErrRead; } } iotjs-1.0/src/platform/linux/iotjs_module_pwm-linux.c000066400000000000000000000153701312466455500231560ustar00rootroot00000000000000/* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef IOTJS_MODULE_PWM_LINUX_GENERAL_INL_H #define IOTJS_MODULE_PWM_LINUX_GENERAL_INL_H #include #include #include #include #include "iotjs_systemio-linux.h" #include "modules/iotjs_module_pwm.h" // Generic PWM implementation for linux. #define PWM_INTERFACE "/sys/class/pwm/pwmchip%d/" #define PWM_PIN_INTERFACE "pwm%d/" #define PWM_PIN_FORMAT PWM_INTERFACE PWM_PIN_INTERFACE #define PWM_EXPORT PWM_INTERFACE "export" #define PWM_UNEXPORT PWM_INTERFACE "unexport" #define PWM_PIN_DUTYCYCLE "duty_cycle" #define PWM_PIN_PERIOD "period" #define PWM_PIN_ENABlE "enable" #define PWM_PATH_BUFFER_SIZE 64 #define PWM_VALUE_BUFFER_SIZE 32 // Generate device path for specified PWM device. // The path may include node suffix if passed ('enable', 'period', 'duty_cycle') // Pointer to a allocated string is returned, or null in case of error. // If PWM_PIN_FORMAT format results in an empty string, // NULL is returned (and fileName is ignored). static char* generate_device_subpath(iotjs_string_t* device, const char* fileName) { char* devicePath = NULL; // Do not print anything, only calculate resulting string length. size_t prefixSize = iotjs_string_size(device); if (prefixSize > 0) { size_t suffixSize = fileName ? strlen(fileName) : 0; devicePath = iotjs_buffer_allocate(prefixSize + suffixSize + 1); if (devicePath) { // Do not need to check bounds, the buffer is of exact required size. memcpy(devicePath, iotjs_string_data(device), prefixSize); memcpy(devicePath + prefixSize, fileName, suffixSize); devicePath[prefixSize + suffixSize] = 0; } } return devicePath; } // Limit period to [0..1]s static double adjust_period(double period) { if (period < 0) { return 0.0; } else if (period > 1) { return 1.0; } else { return period; } } void iotjs_pwm_open_worker(uv_work_t* work_req) { PWM_WORKER_INIT; IOTJS_VALIDATED_STRUCT_METHOD(iotjs_pwm_t, pwm); char path[PWM_PATH_BUFFER_SIZE] = { 0 }; if (snprintf(path, PWM_PATH_BUFFER_SIZE, PWM_PIN_FORMAT, _this->chip, _this->pin) < 0) { req_data->result = false; return; } _this->device = iotjs_string_create_with_size(path, strlen(path)); // See if the PWM is already opened. if (!iotjs_systemio_check_path(path)) { // Write exporting PWM path char export_path[PWM_PATH_BUFFER_SIZE] = { 0 }; snprintf(export_path, PWM_PATH_BUFFER_SIZE, PWM_EXPORT, _this->chip); const char* created_files[] = { PWM_PIN_DUTYCYCLE, PWM_PIN_PERIOD, PWM_PIN_ENABlE }; int created_files_length = sizeof(created_files) / sizeof(created_files[0]); if (!iotjs_systemio_device_open(export_path, _this->pin, path, created_files, created_files_length)) { req_data->result = false; return; } } // Set options. if (_this->period >= 0) { if (!iotjs_pwm_set_period(pwm)) { req_data->result = false; return; } if (_this->duty_cycle >= 0) { if (!iotjs_pwm_set_dutycycle(pwm)) { req_data->result = false; return; } } } DDDLOG("%s - path: %s", __func__, path); req_data->result = true; } bool iotjs_pwm_set_period(iotjs_pwm_t* pwm) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_pwm_t, pwm); bool result = false; if (isfinite(_this->period) && _this->period >= 0.0) { char* devicePath = generate_device_subpath(&_this->device, PWM_PIN_PERIOD); if (devicePath) { // Linux API uses nanoseconds, thus 1E9 unsigned int value = (unsigned)(adjust_period(_this->period) * 1.E9); DDLOG("%s - path: %s, value: %fs", __func__, devicePath, 1.E-9 * value); char buf[PWM_VALUE_BUFFER_SIZE]; if (snprintf(buf, sizeof(buf), "%d", value) > 0) { result = iotjs_systemio_open_write_close(devicePath, buf); } free(devicePath); } } return result; } bool iotjs_pwm_set_dutycycle(iotjs_pwm_t* pwm) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_pwm_t, pwm); bool result = false; double dutyCycle = _this->duty_cycle; if (isfinite(_this->period) && _this->period >= 0.0 && isfinite(dutyCycle) && 0.0 <= dutyCycle && dutyCycle <= 1.0) { char* devicePath = generate_device_subpath(&_this->device, PWM_PIN_DUTYCYCLE); if (devicePath) { double period = adjust_period(_this->period); // Linux API uses nanoseconds, thus 1E9 unsigned dutyCycleValue = (unsigned)(period * _this->duty_cycle * 1E9); DDLOG("%s - path: %s, value: %d\n", __func__, devicePath, dutyCycleValue); char buf[PWM_VALUE_BUFFER_SIZE]; if (snprintf(buf, sizeof(buf), "%d", dutyCycleValue) < 0) { return false; } result = iotjs_systemio_open_write_close(devicePath, buf); free(devicePath); } } return result; } bool iotjs_pwm_set_enable(iotjs_pwm_t* pwm) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_pwm_t, pwm); bool result = false; char* devicePath = generate_device_subpath(&_this->device, PWM_PIN_ENABlE); if (devicePath) { char value[4]; if (snprintf(value, sizeof(value), "%d", _this->enable) < 0) { return false; } DDLOG("%s - path: %s, set: %d\n", __func__, devicePath, _this->enable); char buf[PWM_VALUE_BUFFER_SIZE]; if (snprintf(buf, sizeof(buf), "%d", _this->enable) < 0) { return false; } result = iotjs_systemio_open_write_close(devicePath, buf); free(devicePath); } return result; } bool iotjs_pwm_close(iotjs_pwm_t* pwm) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_pwm_t, pwm); char path[PWM_PATH_BUFFER_SIZE] = { 0 }; if (snprintf(path, PWM_PATH_BUFFER_SIZE, PWM_PIN_FORMAT, _this->chip, _this->pin) < 0) { return false; } if (iotjs_systemio_check_path(path)) { // Write exporting pin path char unexport_path[PWM_PATH_BUFFER_SIZE] = { 0 }; if (snprintf(unexport_path, PWM_PATH_BUFFER_SIZE, PWM_UNEXPORT, _this->chip) < 0) { return false; } iotjs_systemio_device_close(unexport_path, _this->pin); } DDDLOG("%s- path: %s", __func__, path); return true; } #endif /* IOTJS_MODULE_PWM_LINUX_GENERAL_INL_H */ iotjs-1.0/src/platform/linux/iotjs_module_spi-linux.c000066400000000000000000000104551312466455500231450ustar00rootroot00000000000000/* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef IOTJS_MODULE_SPI_LINUX_GENERAL_INL_H #define IOTJS_MODULE_SPI_LINUX_GENERAL_INL_H #include #include #include #include "iotjs_def.h" #include "iotjs_systemio-linux.h" #include "modules/iotjs_module_buffer.h" #include "modules/iotjs_module_spi.h" #define ADC_DEVICE_PATH_FORMAT "/dev/spidev%d.%d" #define ADC_DEVICE_PATH_BUFFER_SIZE 16 static bool iotjs_spi_set_configuration(iotjs_spi_t* spi) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_spi_t, spi); int fd = _this->device_fd; if (fd < 0) { return false; } uint8_t data; switch (_this->mode) { case kSpiMode_0: data = SPI_MODE_0; break; case kSpiMode_1: data = SPI_MODE_1; break; case kSpiMode_2: data = SPI_MODE_2; break; case kSpiMode_3: data = SPI_MODE_3; break; default: data = SPI_MODE_0; } if (_this->loopback) { data |= SPI_LOOP; } if (_this->chip_select == kSpiCsHigh) { data |= SPI_CS_HIGH; } if (ioctl(fd, SPI_IOC_WR_MODE, &_this->mode) < 0) { return false; } if (_this->bit_order == kSpiOrderLsb) { data = 1; if (ioctl(fd, SPI_IOC_WR_LSB_FIRST, &data) < 0) { return false; } } if (ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &_this->bits_per_word) < 0) { return false; } if (ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &_this->max_speed) < 0) { return false; } DDLOG( "SPI Options \n mode: %d\n chipSelect: %d\n bitOrder: %d\n " "maxSpeed: %d\n bitPerWord: %d\n loopback: %d", _this->mode, _this->chip_select, _this->bit_order, _this->max_speed, _this->bits_per_word, _this->loopback); return true; } bool iotjs_spi_transfer(iotjs_spi_t* spi) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_spi_t, spi); struct spi_ioc_transfer data = {.tx_buf = (unsigned long)_this->tx_buf_data, .rx_buf = (unsigned long)_this->rx_buf_data, .len = _this->buf_len, .speed_hz = _this->max_speed, .bits_per_word = _this->bits_per_word, .delay_usecs = 0 }; // Transfer data int err = ioctl(_this->device_fd, SPI_IOC_MESSAGE(1), &data); if (err < 1) { DDLOG("%s - transfer failed: %d", __func__, err); return false; } return true; } bool iotjs_spi_close(iotjs_spi_t* spi) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_spi_t, spi); if (_this->device_fd >= 0) { const iotjs_environment_t* env = iotjs_environment_get(); uv_loop_t* loop = iotjs_environment_loop(env); uv_fs_t fs_close_req; int err = uv_fs_close(loop, &fs_close_req, _this->device_fd, NULL); uv_fs_req_cleanup(&fs_close_req); if (err < 0) { DDLOG("%s - close failed: %d", __func__, err); return false; } _this->device_fd = -1; } return true; } void iotjs_spi_open_worker(uv_work_t* work_req) { SPI_WORKER_INIT; IOTJS_VALIDATED_STRUCT_METHOD(iotjs_spi_t, spi); const char* device_path = iotjs_string_data(&_this->device); if (iotjs_systemio_check_path(device_path)) { // Open file const iotjs_environment_t* env = iotjs_environment_get(); uv_loop_t* loop = iotjs_environment_loop(env); uv_fs_t open_req; int result = uv_fs_open(loop, &open_req, device_path, O_RDONLY, 0666, NULL); uv_fs_req_cleanup(&open_req); if (result < 0) { req_data->result = false; } _this->device_fd = open_req.result; // Set options if (!iotjs_spi_set_configuration(spi)) { req_data->result = false; return; } req_data->result = true; } else { req_data->result = false; } } #endif /* IOTJS_MODULE_SPI_LINUX_GENERAL_INL_H */ iotjs-1.0/src/platform/linux/iotjs_module_uart-linux.c000066400000000000000000000066511312466455500233300ustar00rootroot00000000000000/* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef IOTJS_MODULE_UART_LINUX_GENERAL_INL_H #define IOTJS_MODULE_UART_LINUX_GENERAL_INL_H #include #include #include #include #include "modules/iotjs_module_uart.h" static int baud_to_constant(int baudRate) { switch (baudRate) { case 0: return B0; case 50: return B50; case 75: return B75; case 110: return B110; case 134: return B134; case 150: return B150; case 200: return B200; case 300: return B300; case 600: return B600; case 1200: return B1200; case 1800: return B1800; case 2400: return B2400; case 4800: return B4800; case 9600: return B9600; case 19200: return B19200; case 38400: return B38400; case 57600: return B57600; case 115200: return B115200; case 230400: return B230400; } return -1; } static int databits_to_constant(int dataBits) { switch (dataBits) { case 8: return CS8; case 7: return CS7; case 6: return CS6; case 5: return CS5; } return -1; } void iotjs_uart_open_worker(uv_work_t* work_req) { UART_WORKER_INIT; IOTJS_VALIDATED_STRUCT_METHOD(iotjs_uart_t, uart); int fd = open(iotjs_string_data(&_this->device_path), O_RDWR | O_NOCTTY | O_NDELAY); if (fd < 0) { req_data->result = false; return; } struct termios options; tcgetattr(fd, &options); options.c_cflag = CLOCAL | CREAD; options.c_cflag |= (tcflag_t)baud_to_constant(_this->baud_rate); options.c_cflag |= (tcflag_t)databits_to_constant(_this->data_bits); options.c_iflag = IGNPAR; options.c_oflag = 0; options.c_lflag = 0; tcflush(fd, TCIFLUSH); tcsetattr(fd, TCSANOW, &options); _this->device_fd = fd; uv_poll_t* poll_handle = &_this->poll_handle; uv_loop_t* loop = iotjs_environment_loop(iotjs_environment_get()); uv_poll_init(loop, poll_handle, fd); poll_handle->data = uart; uv_poll_start(poll_handle, UV_READABLE, iotjs_uart_read_cb); req_data->result = true; } bool iotjs_uart_write(iotjs_uart_t* uart) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_uart_t, uart); int bytesWritten = 0; unsigned offset = 0; int fd = _this->device_fd; const char* buf_data = iotjs_string_data(&_this->buf_data); DDDLOG("%s - data: %s", __func__, buf_data); do { errno = 0; bytesWritten = write(fd, buf_data + offset, _this->buf_len - offset); tcdrain(fd); DDDLOG("%s - size: %d", __func__, _this->buf_len - offset); if (bytesWritten != -1) { offset += (unsigned)bytesWritten; continue; } if (errno == EINTR) { continue; } return false; } while (_this->buf_len > offset); return true; } #endif /* IOTJS_MODULE_UART_LINUX_GENERAL_INL_H */ iotjs-1.0/src/platform/linux/iotjs_systemio-linux.c000066400000000000000000000123221312466455500226540ustar00rootroot00000000000000/* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include "iotjs_systemio-linux.h" // Checks if given directory exists. bool iotjs_systemio_check_path(const char* path) { const iotjs_environment_t* env = iotjs_environment_get(); DDDLOG("%s - path: %s", __func__, path); // stat for the path. uv_fs_t fs_req; int err = uv_fs_stat(iotjs_environment_loop(env), &fs_req, path, NULL); uv_fs_req_cleanup(&fs_req); // exist? if (err || fs_req.result) { return false; } DDDLOG("%s - path exist", __func__); return true; } bool iotjs_systemio_open_write_close(const char* path, const char* value) { const iotjs_environment_t* env = iotjs_environment_get(); uv_loop_t* loop = iotjs_environment_loop(env); DDDLOG("%s - path %s, value: %s", __func__, path, value); // Open file uv_fs_t fs_req; int fd = uv_fs_open(loop, &fs_req, path, O_WRONLY, 0666, NULL); uv_fs_req_cleanup(&fs_req); if (fd < 0) { DDLOG("%s - open %s failed: %d", __func__, path, fd); return false; } // Write value // We remove const because `uv_buf_init` requires char* for only reading case. uv_buf_t uvbuf = uv_buf_init((char*)value, strlen(value)); int write_err = uv_fs_write(loop, &fs_req, fd, &uvbuf, 1, 0, NULL); uv_fs_req_cleanup(&fs_req); // Close file int close_err = uv_fs_close(loop, &fs_req, fd, NULL); uv_fs_req_cleanup(&fs_req); if (write_err < 0) { DDLOG("%s - write %s %s failed: %d", __func__, path, value, write_err); return false; } if (close_err < 0) { DDLOG("%s - close failed: %d", __func__, close_err); return false; } return true; } bool iotjs_systemio_open_read_close(const char* path, char* buffer, unsigned buffer_len) { const iotjs_environment_t* env = iotjs_environment_get(); uv_loop_t* loop = iotjs_environment_loop(env); DDDLOG("%s - path %s", __func__, path); // Open file uv_fs_t fs_open_req; int fd = uv_fs_open(loop, &fs_open_req, path, O_RDONLY, 0666, NULL); uv_fs_req_cleanup(&fs_open_req); if (fd < 0) { DDLOG("%s - open %s failed: %d", __func__, path, fd); return false; } // Read value uv_fs_t fs_write_req; uv_buf_t uvbuf = uv_buf_init(buffer, buffer_len); int err = uv_fs_read(loop, &fs_write_req, fd, &uvbuf, 1, 0, NULL); uv_fs_req_cleanup(&fs_write_req); if (err < 0) { DDLOG("%s - read failed: %d", __func__, err); return false; } DDDLOG("%s - read value: %s", __func__, buffer); // Close file uv_fs_t fs_close_req; err = uv_fs_close(loop, &fs_close_req, fd, NULL); uv_fs_req_cleanup(&fs_close_req); if (err < 0) { DDLOG("%s - close failed: %d", __func__, err); return false; } return true; } // Device Open bool iotjs_systemio_device_open(const char* export_path, uint32_t value, const char* exported_path, const char** created_files, int created_files_length) { // Be already exported if (iotjs_systemio_check_path(exported_path)) { return true; } DDLOG("%s - path: %s", __func__, export_path); // Write export pin. char buff[DEVICE_IO_PIN_BUFFER_SIZE] = { 0 }; snprintf(buff, DEVICE_IO_PIN_BUFFER_SIZE - 1, "%d", value); if (!iotjs_systemio_open_write_close(export_path, buff)) { return false; } // Wait for directory creation. int count = 0; int count_limit = created_files_length * 10; char buffer[DEVICE_IO_PIN_BUFFER_SIZE]; char path[DEVICE_IO_PATH_BUFFER_SIZE] = { 0 }; char check_format[DEVICE_IO_PATH_BUFFER_SIZE] = { 0 }; while (!iotjs_systemio_check_path(exported_path) && count < count_limit) { usleep(100 * 1000); // sleep 100 miliseconds. count++; } strcat(check_format, exported_path); strcat(check_format, "%s"); for (int i = 0; i < created_files_length; i++) { snprintf(path, DEVICE_IO_PATH_BUFFER_SIZE - 1, check_format, created_files[i]); DDLOG("%s - created file: %s", __func__, path); while (!iotjs_systemio_open_read_close(path, buffer, DEVICE_IO_PIN_BUFFER_SIZE) && count < count_limit) { usleep(100 * 1000); // sleep 100 miliseconds. count++; } } usleep(1000 * 100); // sleep another 1000 milisec. return count < count_limit; } // Device close bool iotjs_systemio_device_close(const char* export_path, uint32_t value) { DDDLOG("%s - path: %s", __func__, export_path); char buff[DEVICE_IO_PIN_BUFFER_SIZE]; snprintf(buff, DEVICE_IO_PIN_BUFFER_SIZE - 1, "%d", value); if (!iotjs_systemio_open_write_close(export_path, buff)) { return false; } return true; } iotjs-1.0/src/platform/linux/iotjs_systemio-linux.h000066400000000000000000000026531312466455500226670ustar00rootroot00000000000000/* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef IOTJS_DEVICE_IO_LINUX_GENERAL_H #define IOTJS_DEVICE_IO_LINUX_GENERAL_H #include "iotjs_def.h" #define DEVICE_IO_PATH_BUFFER_SIZE 64 #define DEVICE_IO_PIN_BUFFER_SIZE 10 bool iotjs_systemio_check_path(const char* path); bool iotjs_systemio_open_write_close(const char* path, const char* value); bool iotjs_systemio_open_read_close(const char* path, char* buffer, unsigned buffer_len); bool iotjs_systemio_device_open(const char* export_path, uint32_t value, const char* exported_path, const char** created_files, int created_files_length); bool iotjs_systemio_device_close(const char* export_path, uint32_t value); #endif /* IOTJS_DEVICE_IO_LINUX_GENERAL_H */ iotjs-1.0/src/platform/nuttx/000077500000000000000000000000001312466455500163125ustar00rootroot00000000000000iotjs-1.0/src/platform/nuttx/iotjs_module_adc-nuttx.c000066400000000000000000000065171312466455500231530ustar00rootroot00000000000000/* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #if defined(__NUTTX__) #include #include #include #include "iotjs_def.h" #include "iotjs_systemio-nuttx.h" #include "modules/iotjs_module_adc.h" #include "modules/iotjs_module_stm32f4dis.h" #define ADC_DEVICE_PATH_FORMAT "/dev/adc%d" #define ADC_DEVICE_PATH_BUFFER_SIZE 12 static void iotjs_adc_get_path(char* buffer, int32_t number) { // Create ADC device path snprintf(buffer, ADC_DEVICE_PATH_BUFFER_SIZE - 1, ADC_DEVICE_PATH_FORMAT, number); } static bool iotjs_adc_read_data(uint32_t pin, struct adc_msg_s* msg) { int32_t adc_number = ADC_GET_NUMBER(pin); char path[ADC_DEVICE_PATH_BUFFER_SIZE] = { 0 }; iotjs_adc_get_path(path, adc_number); const iotjs_environment_t* env = iotjs_environment_get(); uv_loop_t* loop = iotjs_environment_loop(env); int result, close_result; // Open file uv_fs_t open_req; result = uv_fs_open(loop, &open_req, path, O_RDONLY, 0666, NULL); uv_fs_req_cleanup(&open_req); if (result < 0) { return false; } // Read value uv_fs_t read_req; uv_buf_t uvbuf = uv_buf_init((char*)msg, sizeof(*msg)); result = uv_fs_read(loop, &read_req, open_req.result, &uvbuf, 1, 0, NULL); uv_fs_req_cleanup(&read_req); // Close file uv_fs_t close_req; close_result = uv_fs_close(loop, &close_req, open_req.result, NULL); uv_fs_req_cleanup(&close_req); if (result < 0 || close_result < 0) { return false; } DDLOG("ADC Read - path: %s, value: %d", path, msg->am_data); return true; } int32_t iotjs_adc_read(iotjs_adc_t* adc) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_adc_t, adc); struct adc_msg_s msg; if (!iotjs_adc_read_data(_this->pin, &msg)) { return -1; } return msg.am_data; } bool iotjs_adc_close(iotjs_adc_t* adc) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_adc_t, adc); uint32_t pin = _this->pin; int32_t adc_number = ADC_GET_NUMBER(pin); char path[ADC_DEVICE_PATH_BUFFER_SIZE] = { 0 }; iotjs_adc_get_path(path, adc_number); // Release driver if (unregister_driver(path) < 0) { return false; } iotjs_gpio_unconfig_nuttx(pin); return true; } void iotjs_adc_open_worker(uv_work_t* work_req) { ADC_WORKER_INIT; IOTJS_VALIDATED_STRUCT_METHOD(iotjs_adc_t, adc); uint32_t pin = _this->pin; int32_t adc_number = ADC_GET_NUMBER(pin); int32_t timer = SYSIO_GET_TIMER(pin); struct adc_dev_s* adc_dev = iotjs_adc_config_nuttx(adc_number, timer, pin); char path[ADC_DEVICE_PATH_BUFFER_SIZE] = { 0 }; iotjs_adc_get_path(path, adc_number); if (adc_register(path, adc_dev) != 0) { req_data->result = false; return; } DDLOG("%s - path: %s, number: %d, timer: %d", __func__, path, adc_number, timer); req_data->result = true; } #endif // __NUTTX__ iotjs-1.0/src/platform/nuttx/iotjs_module_blehcisocket-nuttx.c000066400000000000000000000044351312466455500250600ustar00rootroot00000000000000/* Copyright 2017-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef IOTJS_MODULE_BLE_HCI_SOCKET_LINUX_GENERAL_INL_H #define IOTJS_MODULE_BLE_HCI_SOCKET_LINUX_GENERAL_INL_H #include "iotjs_def.h" #include "modules/iotjs_module_blehcisocket.h" #define THIS iotjs_blehcisocket_t* blehcisocket void iotjs_blehcisocket_initialize(THIS) { IOTJS_ASSERT(!"Not implemented"); } void iotjs_blehcisocket_close(THIS) { IOTJS_ASSERT(!"Not implemented"); } void iotjs_blehcisocket_start(THIS) { IOTJS_ASSERT(!"Not implemented"); } int iotjs_blehcisocket_bindRaw(THIS, int* devId) { IOTJS_ASSERT(!"Not implemented"); return 0; } int iotjs_blehcisocket_bindUser(THIS, int* devId) { IOTJS_ASSERT(!"Not implemented"); return 0; } void iotjs_blehcisocket_bindControl(THIS) { IOTJS_ASSERT(!"Not implemented"); } bool iotjs_blehcisocket_isDevUp(THIS) { IOTJS_ASSERT(!"Not implemented"); return false; } void iotjs_blehcisocket_setFilter(THIS, char* data, size_t length) { IOTJS_ASSERT(!"Not implemented"); } void iotjs_blehcisocket_poll(THIS) { IOTJS_ASSERT(!"Not implemented"); } void iotjs_blehcisocket_stop(THIS) { IOTJS_ASSERT(!"Not implemented"); } void iotjs_blehcisocket_write(THIS, char* data, size_t length) { IOTJS_ASSERT(!"Not implemented"); } void iotjs_blehcisocket_emitErrnoError(THIS) { IOTJS_ASSERT(!"Not implemented"); } int iotjs_blehcisocket_devIdFor(THIS, int* pDevId, bool isUp) { IOTJS_ASSERT(!"Not implemented"); return 0; } int iotjs_blehcisocket_kernelDisconnectWorkArounds(THIS, int length, char* data) { IOTJS_ASSERT(!"Not implemented"); return 0; } #undef THIS #endif /* IOTJS_MODULE_BLE_HCI_SOCKET_LINUX_GENERAL_INL_H */ iotjs-1.0/src/platform/nuttx/iotjs_module_i2c-nuttx.c000066400000000000000000000060001312466455500230640ustar00rootroot00000000000000/* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #if defined(__NUTTX__) #include "iotjs_systemio-nuttx.h" #include "modules/iotjs_module_i2c.h" #define I2C_DEFAULT_FREQUENCY 400000 void I2cSetAddress(iotjs_i2c_t* i2c, uint8_t address) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_i2c_t, i2c); _this->config.address = address; _this->config.addrlen = 7; } #define I2C_WORKER_INIT_TEMPLATE \ iotjs_i2c_reqwrap_t* req_wrap = iotjs_i2c_reqwrap_from_request(work_req); \ iotjs_i2c_reqdata_t* req_data = iotjs_i2c_reqwrap_data(req_wrap); void OpenWorker(uv_work_t* work_req) { I2C_WORKER_INIT_TEMPLATE; iotjs_i2c_t* i2c = iotjs_i2c_instance_from_reqwrap(req_wrap); IOTJS_VALIDATED_STRUCT_METHOD(iotjs_i2c_t, i2c); _this->i2c_master = iotjs_i2c_config_nuttx(req_data->device); if (!_this->i2c_master) { DDLOG("I2C OpenWorker : cannot open"); req_data->error = kI2cErrOpen; return; } _this->config.frequency = I2C_DEFAULT_FREQUENCY; req_data->error = kI2cErrOk; } void I2cClose(iotjs_i2c_t* i2c) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_i2c_t, i2c); iotjs_i2c_unconfig_nuttx(_this->i2c_master); } void WriteWorker(uv_work_t* work_req) { I2C_WORKER_INIT_TEMPLATE; iotjs_i2c_t* i2c = iotjs_i2c_instance_from_reqwrap(req_wrap); IOTJS_VALIDATED_STRUCT_METHOD(iotjs_i2c_t, i2c); uint8_t len = req_data->buf_len; uint8_t* data = (uint8_t*)req_data->buf_data; IOTJS_ASSERT(_this->i2c_master); IOTJS_ASSERT(len > 0); int ret = i2c_write(_this->i2c_master, &_this->config, data, len); if (ret < 0) { DDLOG("I2C WriteWorker : cannot write - %d", ret); req_data->error = kI2cErrWrite; } else { req_data->error = kI2cErrOk; } if (req_data->buf_data != NULL) { iotjs_buffer_release(req_data->buf_data); } req_data->error = kI2cErrOk; } void ReadWorker(uv_work_t* work_req) { I2C_WORKER_INIT_TEMPLATE; iotjs_i2c_t* i2c = iotjs_i2c_instance_from_reqwrap(req_wrap); IOTJS_VALIDATED_STRUCT_METHOD(iotjs_i2c_t, i2c); uint8_t len = req_data->buf_len; req_data->buf_data = iotjs_buffer_allocate(len); IOTJS_ASSERT(_this->i2c_master); IOTJS_ASSERT(len > 0); int ret = i2c_read(_this->i2c_master, &_this->config, (uint8_t*)req_data->buf_data, len); if (ret != 0) { DDLOG("I2C ReadWorker : cannot read - %d", ret); req_data->error = kI2cErrRead; return; } req_data->error = kI2cErrOk; } #endif // __NUTTX__ iotjs-1.0/src/platform/nuttx/iotjs_module_pwm-nuttx.c000066400000000000000000000076311312466455500232250ustar00rootroot00000000000000/* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #if defined(__NUTTX__) #include #include #include #include "iotjs_def.h" #include "iotjs_systemio-nuttx.h" #include "modules/iotjs_module_pwm.h" #define PWM_DEVICE_PATH_FORMAT "/dev/pwm%d" #define PWM_DEVICE_PATH_BUFFER_SIZE 12 static bool iotjs_pwm_set_options(iotjs_pwm_t* pwm) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_pwm_t, pwm); int fd = _this->device_fd; if (fd < 0) { DDLOG("%s - file open failed", __func__); return false; } struct pwm_info_s info; // Clamp so that the value inverted fits into uint32 if (_this->period < 2.33E-10) _this->period = 2.33E-10; info.frequency = (uint32_t)(1.0 / _this->period); double duty_value = _this->duty_cycle * (1 << 16); // 16 bit timer if (duty_value > 0xffff) duty_value = 0xffff; else if (duty_value < 1) duty_value = 1; info.duty = (ub16_t)duty_value; DDDLOG("%s - frequency: %d, duty: %d", __func__, info.frequency, info.duty); // Set Pwm info if (ioctl(fd, PWMIOC_SETCHARACTERISTICS, (unsigned long)((uintptr_t)&info)) < 0) { return false; } return true; } void iotjs_pwm_open_worker(uv_work_t* work_req) { PWM_WORKER_INIT; IOTJS_VALIDATED_STRUCT_METHOD(iotjs_pwm_t, pwm); int timer = SYSIO_GET_TIMER(_this->pin); char path[PWM_DEVICE_PATH_BUFFER_SIZE] = { 0 }; if (snprintf(path, PWM_DEVICE_PATH_BUFFER_SIZE, PWM_DEVICE_PATH_FORMAT, timer) < 0) { req_data->result = false; return; } struct pwm_lowerhalf_s* pwm_lowerhalf = iotjs_pwm_config_nuttx(timer, _this->pin); DDDLOG("%s - path: %s, timer: %d\n", __func__, path, timer); if (pwm_register(path, pwm_lowerhalf) != 0) { req_data->result = false; return; } // File open _this->device_fd = open(path, O_RDONLY); if (_this->device_fd < 0) { DDLOG("%s - file open failed", __func__); req_data->result = false; return; } if (!iotjs_pwm_set_options(pwm)) { req_data->result = false; } req_data->result = true; } bool iotjs_pwm_set_period(iotjs_pwm_t* pwm) { return iotjs_pwm_set_options(pwm); } bool iotjs_pwm_set_dutycycle(iotjs_pwm_t* pwm) { return iotjs_pwm_set_options(pwm); } bool iotjs_pwm_set_enable(iotjs_pwm_t* pwm) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_pwm_t, pwm); int fd = _this->device_fd; if (fd < 0) { DDLOG("%s - file open failed", __func__); return false; } DDDLOG("%s - enable: %d", __func__, _this->enable); int ret; if (_this->enable) { ret = ioctl(fd, PWMIOC_START, 0); } else { ret = ioctl(fd, PWMIOC_STOP, 0); } if (ret < 0) { DDLOG("%s - setEnable failed", __func__); return false; } return true; } bool iotjs_pwm_close(iotjs_pwm_t* pwm) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_pwm_t, pwm); int fd = _this->device_fd; if (fd < 0) { DDLOG("%s - file not opened", __func__); return false; } DDDLOG("%s", __func__); // Close file close(fd); _this->device_fd = -1; uint32_t timer = SYSIO_GET_TIMER(_this->pin); char path[PWM_DEVICE_PATH_BUFFER_SIZE] = { 0 }; if (snprintf(path, PWM_DEVICE_PATH_BUFFER_SIZE - 1, PWM_DEVICE_PATH_FORMAT, timer) < 0) { return false; } // Release driver unregister_driver(path); iotjs_gpio_unconfig_nuttx(_this->pin); return true; } #endif // __NUTTX__ iotjs-1.0/src/platform/nuttx/iotjs_module_spi-nuttx.c000066400000000000000000000022551312466455500232120ustar00rootroot00000000000000/* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #if defined(__NUTTX__) #include "modules/iotjs_module_spi.h" bool iotjs_spi_transfer(iotjs_spi_t* spi) { IOTJS_ASSERT(!"Not implemented"); return false; } bool iotjs_spi_close(iotjs_spi_t* spi) { IOTJS_ASSERT(!"Not implemented"); return false; } void iotjs_spi_open_worker(uv_work_t* work_req) { IOTJS_ASSERT(!"Not implemented"); } void iotjs_spi_transfer_worker(uv_work_t* work_req) { IOTJS_ASSERT(!"Not implemented"); } void iotjs_spi_close_worker(uv_work_t* work_req) { IOTJS_ASSERT(!"Not implemented"); } #endif // __NUTTX__ iotjs-1.0/src/platform/nuttx/iotjs_module_stm32f4dis-nuttx.c000066400000000000000000000153711312466455500243240ustar00rootroot00000000000000/* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #if defined(__NUTTX__) && TARGET_BOARD == STM32F4DIS #include "iotjs_def.h" #include "iotjs_systemio-nuttx.h" #include "stm32_gpio.h" #include "modules/iotjs_module_stm32f4dis.h" #if ENABLE_MODULE_ADC static void iotjs_pin_initialize_adc(const iotjs_jval_t* jobj) { unsigned int number_bit; // ADC pin name is "ADC.(number)_(timer)". #define SET_ADC_CONSTANT(number, timer) \ number_bit = (GPIO_ADC##number##_IN##timer); \ number_bit |= (ADC_NUMBER(number)); \ number_bit |= (SYSIO_TIMER_NUMBER(timer)); \ iotjs_jval_set_property_number(jobj, "ADC" #number "_" #timer, number_bit); #define SET_ADC_CONSTANT_NUMBER(number) \ SET_ADC_CONSTANT(number, 0); \ SET_ADC_CONSTANT(number, 1); \ SET_ADC_CONSTANT(number, 2); \ SET_ADC_CONSTANT(number, 3); \ SET_ADC_CONSTANT(number, 4); \ SET_ADC_CONSTANT(number, 5); \ SET_ADC_CONSTANT(number, 6); \ SET_ADC_CONSTANT(number, 7); \ SET_ADC_CONSTANT(number, 8); \ SET_ADC_CONSTANT(number, 9); \ SET_ADC_CONSTANT(number, 10); \ SET_ADC_CONSTANT(number, 11); \ SET_ADC_CONSTANT(number, 12); \ SET_ADC_CONSTANT(number, 13); \ SET_ADC_CONSTANT(number, 14); \ SET_ADC_CONSTANT(number, 15); SET_ADC_CONSTANT_NUMBER(1); SET_ADC_CONSTANT_NUMBER(2); SET_ADC_CONSTANT_NUMBER(3); #undef SET_ADC_CONSTANT_NUMBER #undef SET_ADC_CONSTANT } #endif /* ENABLE_MODULE_ADC */ #if ENABLE_MODULE_GPIO static void iotjs_pin_initialize_gpio(const iotjs_jval_t* jobj) { // Set GPIO pin from configuration bits of nuttx. // GPIO pin name is "P(port)(pin)". #define SET_GPIO_CONSTANT(port, pin) \ iotjs_jval_set_property_number(jobj, "P" #port #pin, \ (GPIO_PORT##port | GPIO_PIN##pin)); #define SET_GPIO_CONSTANT_PORT(port) \ SET_GPIO_CONSTANT(port, 0); \ SET_GPIO_CONSTANT(port, 1); \ SET_GPIO_CONSTANT(port, 2); \ SET_GPIO_CONSTANT(port, 3); \ SET_GPIO_CONSTANT(port, 4); \ SET_GPIO_CONSTANT(port, 5); \ SET_GPIO_CONSTANT(port, 6); \ SET_GPIO_CONSTANT(port, 7); \ SET_GPIO_CONSTANT(port, 8); \ SET_GPIO_CONSTANT(port, 9); \ SET_GPIO_CONSTANT(port, 10); \ SET_GPIO_CONSTANT(port, 11); \ SET_GPIO_CONSTANT(port, 12); \ SET_GPIO_CONSTANT(port, 13); \ SET_GPIO_CONSTANT(port, 14); \ SET_GPIO_CONSTANT(port, 15); SET_GPIO_CONSTANT_PORT(A); SET_GPIO_CONSTANT_PORT(B); SET_GPIO_CONSTANT_PORT(C); SET_GPIO_CONSTANT_PORT(D); SET_GPIO_CONSTANT_PORT(E); SET_GPIO_CONSTANT(H, 0); SET_GPIO_CONSTANT(H, 1); #undef SET_GPIO_CONSTANT_PORT #undef SET_GPIO_CONSTANT } #endif /* ENABLE_MODULE_GPIO */ #if ENABLE_MODULE_PWM static void iotjs_pin_initialize_pwm(const iotjs_jval_t* jobj) { unsigned int timer_bit; // Set PWM pin from configuration bits of nuttx. // PWM pin name is "PWM(timer).CH(channel)_(n)". #define SET_GPIO_CONSTANT(timer, channel, order) \ timer_bit = (GPIO_TIM##timer##_CH##channel##OUT_##order); \ timer_bit |= (SYSIO_TIMER_NUMBER(timer)); \ iotjs_jval_set_property_number(&jtim##timer, "CH" #channel "_" #order, \ timer_bit); #define SET_GPIO_CONSTANT_CHANNEL(timer, channel) \ SET_GPIO_CONSTANT(timer, channel, 1); \ SET_GPIO_CONSTANT(timer, channel, 2); #define SET_GPIO_CONSTANT_TIM(timer) \ iotjs_jval_t jtim##timer = iotjs_jval_create_object(); \ iotjs_jval_set_property_jval(jobj, "PWM" #timer, &jtim##timer); #define SET_GPIO_CONSTANT_TIM_1(timer) \ SET_GPIO_CONSTANT_TIM(timer); \ SET_GPIO_CONSTANT_CHANNEL(timer, 1); #define SET_GPIO_CONSTANT_TIM_2(timer) \ SET_GPIO_CONSTANT_TIM(timer); \ SET_GPIO_CONSTANT_CHANNEL(timer, 1); \ SET_GPIO_CONSTANT_CHANNEL(timer, 2); #define SET_GPIO_CONSTANT_TIM_4(timer) \ SET_GPIO_CONSTANT_TIM(timer); \ SET_GPIO_CONSTANT_CHANNEL(timer, 1); \ SET_GPIO_CONSTANT_CHANNEL(timer, 2); \ SET_GPIO_CONSTANT_CHANNEL(timer, 3); \ SET_GPIO_CONSTANT_CHANNEL(timer, 4); SET_GPIO_CONSTANT_TIM_4(1); // PA8, PE9, PA9, PE11, PA10, PE13, PA11, PE14 iotjs_jval_destroy(&jtim1); SET_GPIO_CONSTANT_TIM_4(2); // PA0, PA15, PA1, PB3, PA2, PB10, PA3, PB11 iotjs_jval_set_property_number(&jtim2, "CH1_3", GPIO_TIM2_CH1OUT_3); // PA5 iotjs_jval_destroy(&jtim2); SET_GPIO_CONSTANT_TIM_4(3); // PA6, PB4, PA7, PB5, PB0, PC8, PB1, PC9 iotjs_jval_set_property_number(&jtim3, "CH1_3", GPIO_TIM3_CH1OUT_3); // PC6 iotjs_jval_set_property_number(&jtim3, "CH2_3", GPIO_TIM3_CH2OUT_3); // PC7 iotjs_jval_destroy(&jtim3); SET_GPIO_CONSTANT_TIM_4(4); // PB6, PD12, PB7, PD13, PB8, PD14, PB9, PD15 iotjs_jval_destroy(&jtim4); SET_GPIO_CONSTANT_TIM_4(5); // PA0, PH10, PA1, PH11, PA2, PH12, PA3, PI0 iotjs_jval_destroy(&jtim5); SET_GPIO_CONSTANT_TIM_4(8); // PC6, PI5, PC7, PI6, PC8, PI7, PC9, PI2 iotjs_jval_destroy(&jtim8); SET_GPIO_CONSTANT_TIM_2(9); // PA2, PE5, PA3, PE6 iotjs_jval_destroy(&jtim9); SET_GPIO_CONSTANT_TIM_1(10); // PB8, PF6 iotjs_jval_destroy(&jtim10); SET_GPIO_CONSTANT_TIM_1(11); // PB9, PF7 iotjs_jval_destroy(&jtim11); SET_GPIO_CONSTANT_TIM_2(12); // PH6, PB14, PB15, PH9 iotjs_jval_destroy(&jtim12); SET_GPIO_CONSTANT_TIM_1(13); // PA6, PF8 iotjs_jval_destroy(&jtim13); SET_GPIO_CONSTANT_TIM_1(14); // PA7, PF9 iotjs_jval_destroy(&jtim14); #undef SET_GPIO_CONSTANT_TIM_4 #undef SET_GPIO_CONSTANT_TIM_2 #undef SET_GPIO_CONSTANT_TIM_1 #undef SET_GPIO_CONSTANT_TIM #undef SET_GPIO_CONSTANT_CHANNEL #undef SET_GPIO_CONSTANT } #endif /* ENABLE_MODULE_PWM */ void iotjs_stm32f4dis_pin_initialize(const iotjs_jval_t* jobj) { iotjs_jval_t jpin = iotjs_jval_create_object(); iotjs_jval_set_property_jval(jobj, "pin", &jpin); #if ENABLE_MODULE_ADC iotjs_pin_initialize_adc(&jpin); #endif /* ENABLE_MODULE_ADC */ #if ENABLE_MODULE_GPIO iotjs_pin_initialize_gpio(&jpin); #endif /* ENABLE_MODULE_GPIO */ #if ENABLE_MODULE_PWM iotjs_pin_initialize_pwm(&jpin); #endif /* ENABLE_MODULE_PWM */ iotjs_jval_destroy(&jpin); } #endif // __NUTTX__ iotjs-1.0/src/platform/nuttx/iotjs_module_uart-nuttx.c000066400000000000000000000037041312466455500233720ustar00rootroot00000000000000/* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #if defined(__NUTTX__) #include "modules/iotjs_module_uart.h" void iotjs_uart_open_worker(uv_work_t* work_req) { UART_WORKER_INIT; IOTJS_VALIDATED_STRUCT_METHOD(iotjs_uart_t, uart); int fd = open(iotjs_string_data(&_this->device_path), O_RDWR | O_NOCTTY | O_NDELAY); if (fd < 0) { req_data->result = false; return; } _this->device_fd = fd; uv_poll_t* poll_handle = &_this->poll_handle; uv_loop_t* loop = iotjs_environment_loop(iotjs_environment_get()); uv_poll_init(loop, poll_handle, fd); poll_handle->data = uart; uv_poll_start(poll_handle, UV_READABLE, iotjs_uart_read_cb); req_data->result = true; } bool iotjs_uart_write(iotjs_uart_t* uart) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_uart_t, uart); int bytesWritten = 0; unsigned offset = 0; int fd = _this->device_fd; const char* buf_data = iotjs_string_data(&_this->buf_data); DDDLOG("%s - data: %s", __func__, buf_data); do { errno = 0; bytesWritten = write(fd, buf_data + offset, _this->buf_len - offset); DDDLOG("%s - size: %d", __func__, _this->buf_len - offset); if (bytesWritten != -1) { offset += (unsigned)bytesWritten; continue; } if (errno == EINTR) { continue; } return false; } while (_this->buf_len > offset); return true; } #endif // __NUTTX__ iotjs-1.0/src/platform/nuttx/iotjs_systemio-nuttx.h000066400000000000000000000035541312466455500227360ustar00rootroot00000000000000/* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef IOTJS_SYSTEMIO_ARM_NUTTX_H #define IOTJS_SYSTEMIO_ARM_NUTTX_H #include void iotjs_gpio_unconfig_nuttx(uint32_t pin); #if ENABLE_MODULE_ADC || ENABLE_MODULE_PWM #define SYSIO_TIMER_PIN_SHIFT 21 /* Bits 21-24: Timer number */ #define SYSIO_TIMER_PIN_MASK 15 #define SYSIO_TIMER_NUMBER(n) ((n) << SYSIO_TIMER_PIN_SHIFT) #define SYSIO_GET_TIMER(n) \ (((n) >> SYSIO_TIMER_PIN_SHIFT) & SYSIO_TIMER_PIN_MASK) #endif /* ENABLE_MODULE_ADC || ENABLE_MODULE_PWM */ #if ENABLE_MODULE_ADC #include #define ADC_NUMBER_SHIFT 25 /* Bits 25-26: ADC number */ #define ADC_NUMBER_MASK 3 #define ADC_NUMBER(n) ((n) << ADC_NUMBER_SHIFT) #define ADC_GET_NUMBER(n) (((n) >> ADC_NUMBER_SHIFT) & ADC_NUMBER_MASK) struct adc_dev_s* iotjs_adc_config_nuttx(int number, int timer, uint32_t pin); #endif /* ENABLE_MODULE_ADC */ #if ENABLE_MODULE_I2C #include struct i2c_master_s* iotjs_i2c_config_nuttx(int port); int iotjs_i2c_unconfig_nuttx(struct i2c_master_s* i2c); #endif /* ENABLE_MODULE_I2C */ #if ENABLE_MODULE_PWM #include struct pwm_lowerhalf_s* iotjs_pwm_config_nuttx(int timer, uint32_t pin); #endif /* ENABLE_MODULE_PWM */ #endif /* IOTJS_SYSTEMIO_ARM_NUTTX_H */ iotjs-1.0/src/platform/nuttx/stm32f4dis/000077500000000000000000000000001312466455500202145ustar00rootroot00000000000000iotjs-1.0/src/platform/nuttx/stm32f4dis/iotjs_module_gpio-nuttx-stm32f4dis.c000066400000000000000000000040001312466455500271450ustar00rootroot00000000000000/* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "modules/iotjs_module_gpio.h" #include "stm32_gpio.h" #define GPIO_FREQUENCY_DEFAULT GPIO_SPEED_25MHz #define GPIO_PINCNT_IN_NUTTXPORT 16 #define GPIO_CONFIG_OK 0 uint32_t gpioDirection[] = { GPIO_INPUT, GPIO_OUTPUT | GPIO_OUTPUT_SET | GPIO_FREQUENCY_DEFAULT, }; uint32_t gpioMode[] = { 0, // none GPIO_PULLUP, GPIO_PULLDOWN, GPIO_FLOAT, GPIO_PUSHPULL, GPIO_OPENDRAIN, }; bool iotjs_gpio_write(iotjs_gpio_t* gpio, bool value) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_gpio_t, gpio); DDDLOG("%s - pin: %d, value: %d", __func__, _this->pin, value); stm32_gpiowrite(_this->pin, value); return true; } int iotjs_gpio_read(iotjs_gpio_t* gpio) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_gpio_t, gpio); DDDLOG("%s - pin: %d", __func__, _this->pin); return stm32_gpioread(_this->pin); } bool iotjs_gpio_close(iotjs_gpio_t* gpio) { iotjs_gpio_write(gpio, 0); return true; } void iotjs_gpio_open_worker(uv_work_t* work_req) { GPIO_WORKER_INIT; IOTJS_VALIDATED_STRUCT_METHOD(iotjs_gpio_t, gpio); DDDLOG("%s - pin: %d, dir: %d, mode: %d", __func__, _this->pin, _this->direction, _this->mode); uint32_t cfgset = 0; // Set pin direction and mode cfgset = gpioDirection[_this->direction] | gpioMode[_this->mode] | _this->pin; if (stm32_configgpio(cfgset) != GPIO_CONFIG_OK) { req_data->result = false; return; } req_data->result = true; } iotjs-1.0/src/platform/nuttx/stm32f4dis/iotjs_systemio-nuttx-stm32f4dis.c000066400000000000000000000032571312466455500265330ustar00rootroot00000000000000/* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #if defined(__NUTTX__) && TARGET_BOARD == STM32F4DIS #include #include "../iotjs_systemio-nuttx.h" #include "stm32_gpio.h" void iotjs_gpio_unconfig_nuttx(uint32_t pin) { stm32_unconfiggpio(pin); } #if ENABLE_MODULE_ADC #include "stm32_adc.h" struct adc_dev_s* iotjs_adc_config_nuttx(int number, int timer, uint32_t pin) { stm32_configgpio(pin); uint8_t channel_list[1] = { timer }; return stm32_adcinitialize(number, channel_list, 1); } #endif /* ENABLE_MODULE_ADC */ #if ENABLE_MODULE_I2C #include "stm32_i2c.h" struct i2c_master_s* iotjs_i2c_config_nuttx(int port) { return stm32_i2cbus_initialize(port); } int iotjs_i2c_unconfig_nuttx(struct i2c_master_s* i2c) { return stm32_i2cbus_uninitialize(i2c); } #endif /* ENABLE_MODULE_I2C */ #if ENABLE_MODULE_PWM #include "stm32_pwm.h" struct pwm_lowerhalf_s* iotjs_pwm_config_nuttx(int timer, uint32_t pin) { // Set alternative function stm32_configgpio(pin); // PWM initialize return stm32_pwminitialize(timer); } #endif /* ENABLE_MODULE_PWM */ #endif // __NUTTX__ iotjs-1.0/src/platform/tizenrt/000077500000000000000000000000001312466455500166275ustar00rootroot00000000000000iotjs-1.0/src/platform/tizenrt/iotjs_module_gpio-tizenrt.c000066400000000000000000000040331312466455500242030ustar00rootroot00000000000000/* Copyright 2017-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "modules/iotjs_module_gpio.h" void iotjs_gpio_open_worker(uv_work_t* work_req) { GPIO_WORKER_INIT; IOTJS_VALIDATED_STRUCT_METHOD(iotjs_gpio_t, gpio); DDDLOG("%s - pin: %d, direction: %d, mode: %d", __func__, _this->pin, _this->direction, _this->mode); // Open gpio pin _this->gpio_context = iotbus_gpio_open(_this->pin); if (_this->gpio_context == NULL) { req_data->result = false; return; } // Set direction iotbus_gpio_direction_e direction; if (_this->direction == kGpioDirectionIn) { direction = IOTBUS_GPIO_DIRECTION_IN; } else if (_this->direction == kGpioDirectionOut) { direction = IOTBUS_GPIO_DIRECTION_OUT; } else { direction = IOTBUS_GPIO_DIRECTION_NONE; } if (iotbus_gpio_set_direction(_this->gpio_context, direction) < 0) { req_data->result = false; return; } req_data->result = true; } bool iotjs_gpio_write(iotjs_gpio_t* gpio, bool value) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_gpio_t, gpio); if (iotbus_gpio_write(_this->gpio_context, value) < 0) { return false; } return true; } int iotjs_gpio_read(iotjs_gpio_t* gpio) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_gpio_t, gpio); return iotbus_gpio_read(_this->gpio_context); } bool iotjs_gpio_close(iotjs_gpio_t* gpio) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_gpio_t, gpio); if (iotbus_gpio_close(_this->gpio_context) < 0) { return false; } return true; } iotjs-1.0/src/platform/tizenrt/iotjs_module_pwm-tizenrt.c000066400000000000000000000062511312466455500240540ustar00rootroot00000000000000/* Copyright 2017-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #if defined(__TIZENRT__) #include #include #include #include #include "modules/iotjs_module_pwm.h" static bool iotjs_pwm_set_options(iotjs_pwm_t* pwm) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_pwm_t, pwm); iotbus_pwm_context_h ctx = _this->ctx; if (ctx == NULL) { DDLOG("%s - file open failed", __func__); return false; } DDDLOG("%s - period: %d, duty: %d", __func__, (int)_this->period, (int)(_this->duty_cycle * 100)); return iotjs_pwm_set_dutycycle(pwm) && iotjs_pwm_set_period(pwm); } void iotjs_pwm_open_worker(uv_work_t* work_req) { PWM_WORKER_INIT; IOTJS_VALIDATED_STRUCT_METHOD(iotjs_pwm_t, pwm); _this->ctx = iotbus_pwm_open(0, (int)_this->pin); if (_this->ctx == NULL) { DDLOG("%s - file open failed", __func__); req_data->result = false; return; } if (!iotjs_pwm_set_options(pwm)) { req_data->result = false; return; } req_data->result = true; } bool iotjs_pwm_set_period(iotjs_pwm_t* pwm) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_pwm_t, pwm); iotbus_pwm_context_h ctx = _this->ctx; if (ctx == NULL) { DDLOG("%s - file open failed", __func__); return false; } uint32_t period_us = (uint32_t)(1000000 * _this->period); return iotbus_pwm_set_period(ctx, period_us) == 0; } bool iotjs_pwm_set_dutycycle(iotjs_pwm_t* pwm) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_pwm_t, pwm); iotbus_pwm_context_h ctx = _this->ctx; if (ctx == NULL) { DDLOG("%s - file open failed", __func__); return false; } uint32_t duty_cycle_per_cent = (uint32_t)(_this->duty_cycle * 100); return iotbus_pwm_set_duty_cycle(ctx, duty_cycle_per_cent) == 0; } bool iotjs_pwm_set_enable(iotjs_pwm_t* pwm) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_pwm_t, pwm); iotbus_pwm_context_h ctx = _this->ctx; if (ctx == NULL) { DDLOG("%s - file open failed", __func__); return false; } DDDLOG("%s - enable: %d", __func__, _this->enable); int ret; if (_this->enable) { ret = iotbus_pwm_set_enabled(ctx, IOTBUS_PWM_ENABLE); } else { ret = iotbus_pwm_set_enabled(ctx, IOTBUS_PWM_DISABLE); } if (ret < 0) { DDLOG("%s - setEnable failed", __func__); return false; } return true; } bool iotjs_pwm_close(iotjs_pwm_t* pwm) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_pwm_t, pwm); iotbus_pwm_context_h ctx = _this->ctx; if (ctx == NULL) { DDLOG("%s - file not opened", __func__); return false; } DDDLOG("%s", __func__); iotbus_pwm_close(ctx); _this->ctx = NULL; return true; } #endif // __TIZENRT__ iotjs-1.0/src/platform/tizenrt/iotjs_module_uart-tizenrt.c000066400000000000000000000037071312466455500242270ustar00rootroot00000000000000/* Copyright 2017-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #if defined(__TIZENRT__) #include "modules/iotjs_module_uart.h" void iotjs_uart_open_worker(uv_work_t* work_req) { UART_WORKER_INIT; IOTJS_VALIDATED_STRUCT_METHOD(iotjs_uart_t, uart); int fd = open(iotjs_string_data(&_this->device_path), O_RDWR | O_NOCTTY | O_NDELAY); if (fd < 0) { req_data->result = false; return; } _this->device_fd = fd; uv_poll_t* poll_handle = &_this->poll_handle; uv_loop_t* loop = iotjs_environment_loop(iotjs_environment_get()); uv_poll_init(loop, poll_handle, fd); poll_handle->data = uart; uv_poll_start(poll_handle, UV_READABLE, iotjs_uart_read_cb); req_data->result = true; } bool iotjs_uart_write(iotjs_uart_t* uart) { IOTJS_VALIDATED_STRUCT_METHOD(iotjs_uart_t, uart); int bytesWritten = 0; unsigned offset = 0; int fd = _this->device_fd; const char* buf_data = iotjs_string_data(&_this->buf_data); DDDLOG("%s - data: %s", __func__, buf_data); do { errno = 0; bytesWritten = write(fd, buf_data + offset, _this->buf_len - offset); DDDLOG("%s - size: %d", __func__, _this->buf_len - offset); if (bytesWritten != -1) { offset += (unsigned)bytesWritten; continue; } if (errno == EINTR) { continue; } return false; } while (_this->buf_len > offset); return true; } #endif // __TIZENRT__ iotjs-1.0/test/000077500000000000000000000000001312466455500134745ustar00rootroot00000000000000iotjs-1.0/test/node/000077500000000000000000000000001312466455500144215ustar00rootroot00000000000000iotjs-1.0/test/node/common.js000066400000000000000000000365321312466455500162600ustar00rootroot00000000000000/* Copyright 2017-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ // Copyright Joyent, Inc. and other Node contributors. // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to permit // persons to whom the Software is furnished to do so, subject to the // following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. /* eslint-disable required-modules */ 'use strict'; var fs = require('fs'); var assert = require('assert'); var stream = require('stream'); var util = require('util'); var __dirname = process.cwd(); var testRoot = __dirname; // PORT should match the definition in test/testpy/__init__.py. exports.PORT = +process.env.NODE_COMMON_PORT || 12346; exports.isWindows = process.platform === 'win32'; exports.isWOW64 = exports.isWindows && (process.env.PROCESSOR_ARCHITEW6432 !== undefined); exports.isAix = process.platform === 'aix'; exports.isLinuxPPCBE = (process.platform === 'linux') && (process.arch === 'ppc64') && (os.endianness() === 'BE'); exports.isSunOS = process.platform === 'sunos'; exports.isFreeBSD = process.platform === 'freebsd'; exports.isLinux = process.platform === 'linux'; exports.isOSX = process.platform === 'darwin'; exports.enoughTestMem = false; exports.enoughTestCpu = false; exports.rootDir = exports.isWindows ? 'c:\\' : '/'; var dirsep = exports.isWindows ? '\\' : '/'; exports.fixturesDir = __dirname + dirsep + 'fixtures'; exports.tmpDirName = 'tmp'; function rimrafSync(p) { var st; try { st = fs.lstatSync(p); } catch (e) { if (e.code === 'ENOENT') return; } try { if (st && st.isDirectory()) rmdirSync(p, null); else fs.unlinkSync(p); } catch (e) { if (e.code === 'ENOENT') return; if (e.code === 'EPERM') return rmdirSync(p, e); if (e.code !== 'EISDIR') throw e; rmdirSync(p, e); } } function rmdirSync(p, originalEr) { try { fs.rmdirSync(p); } catch (e) { if (e.code === 'ENOTDIR') throw originalEr; if (e.code === 'ENOTEMPTY' || e.code === 'EEXIST' || e.code === 'EPERM') { var enc = exports.isLinux ? 'buffer' : 'utf8'; fs.readdirSync(p, enc).forEach(function(f) { if (f instanceof Buffer) { var buf = Buffer.concat([Buffer.from(p), Buffer.from(path.sep), f]); rimrafSync(buf); } else { rimrafSync(path.join(p, f)); } }); fs.rmdirSync(p); } } } exports.refreshTmpDir = function() { rimrafSync(exports.tmpDir); fs.mkdirSync(exports.tmpDir); }; if (process.env.TEST_THREAD_ID) { exports.PORT += process.env.TEST_THREAD_ID * 100; exports.tmpDirName += '.' + process.env.TEST_THREAD_ID; } exports.tmpDir = testRoot + dirsep + exports.tmpDirName; var opensslCli = null; var inFreeBSDJail = null; var localhostIPv4 = null; exports.localIPv6Hosts = ['localhost']; if (exports.isLinux) { exports.localIPv6Hosts = [ // Debian/Ubuntu 'ip6-localhost', 'ip6-loopback', // SUSE 'ipv6-localhost', 'ipv6-loopback', // Typically universal 'localhost', ]; } Object.defineProperty(exports, 'inFreeBSDJail', { get: function() { if (inFreeBSDJail !== null) return inFreeBSDJail; if (exports.isFreeBSD && child_process.execSync('sysctl -n security.jail.jailed').toString() === '1\n') { inFreeBSDJail = true; } else { inFreeBSDJail = false; } return inFreeBSDJail; } }); Object.defineProperty(exports, 'localhostIPv4', { get: function() { if (localhostIPv4 !== null) return localhostIPv4; if (exports.inFreeBSDJail) { // Jailed network interfaces are a bit special - since we need to jump // through loops, as well as this being an exception case, assume the // user will provide this instead. if (process.env.LOCALHOST) { localhostIPv4 = process.env.LOCALHOST; } else { console.error('Looks like we\'re in a FreeBSD Jail. ' + 'Please provide your default interface address ' + 'as LOCALHOST or expect some tests to fail.'); } } if (localhostIPv4 === null) localhostIPv4 = '127.0.0.1'; return localhostIPv4; } }); Object.defineProperty(exports, 'hasCrypto', { get: function() { return process.versions.openssl ? true : false; } }); Object.defineProperty(exports, 'hasFipsCrypto', { get: function() { return exports.hasCrypto && require('crypto').fips; } }); if (exports.isWindows) { exports.PIPE = '\\\\.\\pipe\\libuv-test'; if (process.env.TEST_THREAD_ID) { exports.PIPE += '.' + process.env.TEST_THREAD_ID; } } else { exports.PIPE = exports.tmpDir + '/test.sock'; } exports.hasIPv6 = false; /* * Check that when running a test with * `$node --abort-on-uncaught-exception $file child` * the process aborts. */ exports.childShouldThrowAndAbort = function() { var testCmd = ''; if (!exports.isWindows) { // Do not create core files, as it can take a lot of disk space on // continuous testing and developers' machines testCmd += 'ulimit -c 0 && '; } testCmd += process.argv[0] + ' --abort-on-uncaught-exception '; testCmd += process.argv[1] + ' child'; var child = child_process.exec(testCmd); child.on('exit', function onExit(exitCode, signal) { var errMsg = 'Test should have aborted ' + 'but instead exited with exit code ' + exitCode + ' and signal ' + signal; assert(exports.nodeProcessAborted(exitCode, signal), errMsg); }); }; exports.ddCommand = function(filename, kilobytes) { if (exports.isWindows) { var p = path.resolve(exports.fixturesDir, 'create-file.js'); return '"' + process.argv[0] + '" "' + p + '" "' + filename + '" ' + (kilobytes * 1024); } else { return 'dd if=/dev/zero of="' + filename + '" bs=1024 count=' + kilobytes; } }; exports.spawnCat = function(options) { var spawn = require('child_process').spawn; if (exports.isWindows) { return spawn('more', [], options); } else { return spawn('cat', [], options); } }; exports.spawnSyncCat = function(options) { var spawnSync = require('child_process').spawnSync; if (exports.isWindows) { return spawnSync('more', [], options); } else { return spawnSync('cat', [], options); } }; exports.spawnPwd = function(options) { var spawn = require('child_process').spawn; if (exports.isWindows) { return spawn('cmd.exe', ['/c', 'cd'], options); } else { return spawn('pwd', [], options); } }; exports.spawnSyncPwd = function(options) { var spawnSync = require('child_process').spawnSync; if (exports.isWindows) { return spawnSync('cmd.exe', ['/c', 'cd'], options); } else { return spawnSync('pwd', [], options); } }; exports.platformTimeout = function(ms) { if (process.config.target_defaults.default_configuration === 'Debug') ms = 2 * ms; if (exports.isAix) return 2 * ms; // default localhost speed is slower on AIX if (process.arch !== 'arm') return ms; var armv = process.config.variables.arm_version; if (armv === '6') return 7 * ms; // ARMv6 if (armv === '7') return 2 * ms; // ARMv7 return ms; // ARMv8+ }; var knownGlobals = [ Buffer, clearInterval, clearTimeout, console, constructor, // Enumerable in V8 3.21. global, process, setInterval, setTimeout ]; if (global.gc) { knownGlobals.push(global.gc); } if (global.DTRACE_HTTP_SERVER_RESPONSE) { knownGlobals.push(DTRACE_HTTP_SERVER_RESPONSE); knownGlobals.push(DTRACE_HTTP_SERVER_REQUEST); knownGlobals.push(DTRACE_HTTP_CLIENT_RESPONSE); knownGlobals.push(DTRACE_HTTP_CLIENT_REQUEST); knownGlobals.push(DTRACE_NET_STREAM_END); knownGlobals.push(DTRACE_NET_SERVER_CONNECTION); } if (global.COUNTER_NET_SERVER_CONNECTION) { knownGlobals.push(COUNTER_NET_SERVER_CONNECTION); knownGlobals.push(COUNTER_NET_SERVER_CONNECTION_CLOSE); knownGlobals.push(COUNTER_HTTP_SERVER_REQUEST); knownGlobals.push(COUNTER_HTTP_SERVER_RESPONSE); knownGlobals.push(COUNTER_HTTP_CLIENT_REQUEST); knownGlobals.push(COUNTER_HTTP_CLIENT_RESPONSE); } if (global.LTTNG_HTTP_SERVER_RESPONSE) { knownGlobals.push(LTTNG_HTTP_SERVER_RESPONSE); knownGlobals.push(LTTNG_HTTP_SERVER_REQUEST); knownGlobals.push(LTTNG_HTTP_CLIENT_RESPONSE); knownGlobals.push(LTTNG_HTTP_CLIENT_REQUEST); knownGlobals.push(LTTNG_NET_STREAM_END); knownGlobals.push(LTTNG_NET_SERVER_CONNECTION); } if (global.ArrayBuffer) { knownGlobals.push(ArrayBuffer); knownGlobals.push(Int8Array); knownGlobals.push(Uint8Array); knownGlobals.push(Uint8ClampedArray); knownGlobals.push(Int16Array); knownGlobals.push(Uint16Array); knownGlobals.push(Int32Array); knownGlobals.push(Uint32Array); knownGlobals.push(Float32Array); knownGlobals.push(Float64Array); knownGlobals.push(DataView); } // Harmony features. if (global.Proxy) { knownGlobals.push(Proxy); } if (global.Symbol) { knownGlobals.push(Symbol); } function allowGlobals() { knownGlobals = knownGlobals.concat(arguments); } exports.allowGlobals = allowGlobals; function leakedGlobals() { var leaked = []; for (var val in global) { if (knownGlobals.indexOf(global[val]) == -1) leaked.push(val); } return leaked; } exports.leakedGlobals = leakedGlobals; // TODO: fix the knownGlobal list // Turn this on if the test should check for global leaks. exports.globalCheck = false; process.on('exit', function() { if (!exports.globalCheck) return; var leaked = leakedGlobals(); if (leaked.length > 0) { console.error('Unexpected global(s) found: ' + leaked.join(', ')); } }); var mustCallChecks = []; function runCallChecks(exitCode) { if (exitCode !== 0) return; var failed = mustCallChecks.filter(function(context) { return context.actual !== context.expected; }); failed.forEach(function(context) { console.log('Mismatched %s function calls. Expected %d, actual %d.', context.name, context.expected, context.actual); console.log(context.stack.split('\n').slice(2).join('\n')); }); if (failed.length) process.exit(1); } exports.mustCall = function(fn, expected) { if (expected === undefined) expected = 1; else if (typeof expected !== 'number') throw new TypeError('Invalid expected value: ' + expected); var context = { expected: expected, actual: 0, stack: (new Error()).stack, name: fn.name || '' }; // add the exit listener only once to avoid listener leak warnings if (mustCallChecks.length === 0) process.on('exit', runCallChecks); mustCallChecks.push(context); return function() { context.actual++; return fn.apply(this, arguments); }; }; exports.hasMultiLocalhost = function hasMultiLocalhost() { var TCP = process.binding('tcp_wrap').TCP; var t = new TCP(); var ret = t.bind('127.0.0.2', exports.PORT); t.close(); return ret === 0; }; exports.fileExists = function(pathname) { try { fs.accessSync(pathname); return true; } catch (err) { return false; } }; function fail(msg) { assert.fail(null, null, msg); } exports.fail = fail; exports.skip = function(msg) { console.log('1..0 # Skipped: ' + msg); }; // A stream to push an array into a REPL function ArrayStream() { this.run = function(data) { data.forEach(function(line) { this.emit('data', line + '\n'); }); }; } util.inherits(ArrayStream, stream.Stream); exports.ArrayStream = ArrayStream; ArrayStream.prototype.readable = true; ArrayStream.prototype.writable = true; ArrayStream.prototype.pause = function() {}; ArrayStream.prototype.resume = function() {}; ArrayStream.prototype.write = function() {}; // Returns true if the exit code "exitCode" and/or signal name "signal" // represent the exit code and/or signal name of a node process that aborted, // false otherwise. exports.nodeProcessAborted = function nodeProcessAborted(exitCode, signal) { // Depending on the compiler used, node will exit with either // exit code 132 (SIGILL), 133 (SIGTRAP) or 134 (SIGABRT). var expectedExitCodes = [132, 133, 134]; // On platforms using KSH as the default shell (like SmartOS), // when a process aborts, KSH exits with an exit code that is // greater than 256, and thus the exit code emitted with the 'exit' // event is null and the signal is set to either SIGILL, SIGTRAP, // or SIGABRT (depending on the compiler). var expectedSignals = ['SIGILL', 'SIGTRAP', 'SIGABRT']; // On Windows, v8's base::OS::Abort triggers an access violation, // which corresponds to exit code 3221225477 (0xC0000005) if (exports.isWindows) expectedExitCodes = [3221225477]; // When using --abort-on-uncaught-exception, V8 will use // base::OS::Abort to terminate the process. // Depending on the compiler used, the shell or other aspects of // the platform used to build the node binary, this will actually // make V8 exit by aborting or by raising a signal. In any case, // one of them (exit code or signal) needs to be set to one of // the expected exit codes or signals. if (signal !== null) { return expectedSignals.includes(signal); } else { return expectedExitCodes.includes(exitCode); } }; exports.busyLoop = function busyLoop(time) { var startTime = Date.now(); var stopTime = startTime + time; while (Date.now() < stopTime) {} }; exports.isAlive = function isAlive(pid) { try { process.kill(pid, 'SIGCONT'); return true; } catch (e) { return false; } }; exports.expectWarning = function(name, expected) { if (typeof expected === 'string') expected = [expected]; process.on('warning', exports.mustCall(function(warning) { assert.strictEqual(warning.name, name); assert.ok(expected.includes(warning.message), 'unexpected error message: "' + warning.message + '"'); // Remove a warning message after it is seen so that we guarantee that we // get each message only once. expected.splice(expected.indexOf(warning.message), 1); }, expected.length)); }; // IoT.js extensions assert.ok = function(value, message) { assert.equal(!!value, true, message); } iotjs-1.0/test/node/parallel/000077500000000000000000000000001312466455500162155ustar00rootroot00000000000000iotjs-1.0/test/node/parallel/test-assert.js000066400000000000000000000142721312466455500210370ustar00rootroot00000000000000/* Copyright 2017-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ // Copyright Joyent, Inc. and other Node contributors. // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to permit // persons to whom the Software is furnished to do so, subject to the // following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. 'use strict'; require('node/common'); var assert = require('assert'); var a = require('assert'); // Test starts here function makeBlock(f) { var args = Array.prototype.slice.call(arguments, 1); return function() { return f.apply(this, args); }; } assert.ok(a.AssertionError.prototype instanceof Error, 'a.AssertionError instanceof Error'); assert.throws(makeBlock(a, false), a.AssertionError, 'ok(false)'); assert.doesNotThrow(makeBlock(a, true), a.AssertionError, 'ok(true)'); assert.doesNotThrow(makeBlock(a, 'test', 'ok(\'test\')')); assert.throws(makeBlock(a.ok, false), a.AssertionError, 'ok(false)'); assert.doesNotThrow(makeBlock(a.ok, true), a.AssertionError, 'ok(true)'); assert.doesNotThrow(makeBlock(a.ok, 'test'), 'ok(\'test\')'); assert.throws(makeBlock(a.equal, true, false), a.AssertionError, 'equal(true, false)'); assert.doesNotThrow(makeBlock(a.equal, null, null), 'equal(null, null)'); assert.doesNotThrow(makeBlock(a.equal, undefined, undefined), 'equal(undefined, undefined)'); assert.doesNotThrow(makeBlock(a.equal, null, undefined), 'equal(null, undefined)'); assert.doesNotThrow(makeBlock(a.equal, true, true), 'equal(true, true)'); assert.doesNotThrow(makeBlock(a.equal, 2, '2'), 'equal(2, \'2\')'); assert.doesNotThrow(makeBlock(a.notEqual, true, false), 'notEqual(true, false)'); assert.throws(makeBlock(a.notEqual, true, true), a.AssertionError, 'notEqual(true, true)'); assert.throws(makeBlock(a.strictEqual, 2, '2'), a.AssertionError, 'strictEqual(2, \'2\')'); assert.throws(makeBlock(a.strictEqual, null, undefined), a.AssertionError, 'strictEqual(null, undefined)'); assert.throws(makeBlock(a.notStrictEqual, 2, 2), a.AssertionError, 'notStrictEqual(2, 2)'); assert.doesNotThrow(makeBlock(a.notStrictEqual, 2, '2'), 'notStrictEqual(2, \'2\')'); // Testing the throwing function thrower(errorConstructor) { throw new errorConstructor('test'); } // the basic calls work assert.throws(makeBlock(thrower, a.AssertionError), a.AssertionError, 'message'); assert.throws(makeBlock(thrower, a.AssertionError), a.AssertionError); assert.throws(makeBlock(thrower, a.AssertionError)); // if not passing an error, catch all. assert.throws(makeBlock(thrower, TypeError)); // when passing a type, only catch errors of the appropriate type var threw = false; try { a.throws(makeBlock(thrower, TypeError), a.AssertionError); } catch (e) { threw = true; assert.ok(e instanceof TypeError, 'type'); } assert.strictEqual(true, threw, 'a.throws with an explicit error is eating extra errors', a.AssertionError); threw = false; // key difference is that throwing our correct error makes an assertion error try { a.doesNotThrow(makeBlock(thrower, TypeError), TypeError); } catch (e) { threw = true; assert.ok(e instanceof a.AssertionError); } assert.strictEqual(true, threw, 'a.doesNotThrow is not catching type matching errors'); var circular = {y: 1}; circular.x = circular; function testAssertionMessage(actual, expected) { try { assert.strictEqual(actual, ''); } catch (e) { assert.ok(e.toString()); } } testAssertionMessage(undefined, 'undefined'); testAssertionMessage(null, 'null'); testAssertionMessage(true, 'true'); testAssertionMessage(false, 'false'); testAssertionMessage(0, '0'); testAssertionMessage(100, '100'); testAssertionMessage(NaN, 'NaN'); testAssertionMessage(Infinity, 'Infinity'); testAssertionMessage(-Infinity, '-Infinity'); testAssertionMessage('', '""'); testAssertionMessage('foo', '\'foo\''); testAssertionMessage([], '[]'); testAssertionMessage([1, 2, 3], '[ 1, 2, 3 ]'); testAssertionMessage(/a/, '/a/'); testAssertionMessage(/abc/gim, '/abc/gim'); testAssertionMessage(function f() {}, '[Function: f]'); testAssertionMessage(function() {}, '[Function]'); testAssertionMessage({}, '{}'); testAssertionMessage(circular, '{ y: 1, x: [Circular] }'); testAssertionMessage({a: undefined, b: null}, '{ a: undefined, b: null }'); testAssertionMessage({a: NaN, b: Infinity, c: -Infinity}, '{ a: NaN, b: Infinity, c: -Infinity }'); // #2893 try { assert.throws(function() { assert.ifError(null); }); } catch (e) { threw = true; assert.strictEqual(e.message, 'Missing expected exception..'); } assert.ok(threw); console.log('All OK'); iotjs-1.0/test/node/parallel/test-http-status-message.js000066400000000000000000000046741312466455500234650ustar00rootroot00000000000000/* Copyright 2017-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ // Copyright Joyent, Inc. and other Node contributors. // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to permit // persons to whom the Software is furnished to do so, subject to the // following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. 'use strict'; require('node/common'); var assert = require('assert'); var http = require('http'); var net = require('net'); var s = http.createServer(function (req, res) { res.statusCode = 200; res.statusMessage = 'Custom Message'; res.end(''); }); s.listen(0, test); function test() { var bufs = []; var client = net.connect(this.address().port, function () { client.write('GET / HTTP/1.1\r\nConnection: close\r\n\r\n'); }); client.on('data', function (chunk) { bufs.push(chunk); }); client.on('end', function () { var head = Buffer.concat(bufs).toString().split('\r\n')[0]; assert.strictEqual('HTTP/1.1 200 Custom Message', head); console.log('ok'); s.close(); }); } iotjs-1.0/test/node/parallel/test-http-write-head.js000066400000000000000000000062021312466455500225360ustar00rootroot00000000000000/* Copyright 2017-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ // Copyright Joyent, Inc. and other Node contributors. // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to permit // persons to whom the Software is furnished to do so, subject to the // following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. 'use strict'; var common = require('node/common'); var assert = require('assert'); var http = require('http'); // Verify that ServerResponse.writeHead() works as setHeader. // Issue 5036 on github. var s = http.createServer(common.mustCall(function (req, res) { res.setHeader('test', '1'); // toLowerCase() is used on the name argument, so it must be a string. var threw = false; try { res.setHeader(0xf00, 'bar'); } catch (e) { assert.ok(e instanceof TypeError); threw = true; } assert.ok(threw, 'Non-string names should throw'); // undefined value should throw, via 979d0ca8 threw = false; try { res.setHeader('foo', undefined); } catch (e) { assert.ok(e instanceof Error); assert.strictEqual(e.message, 'value required in setHeader(foo, value)'); threw = true; } assert.ok(threw, 'Undefined value should throw'); res.writeHead(200, { Test: '2' }); // assert.throws(function () { assert.doesNotThrow(function () { res.writeHead(100, {}); }); res.end(); })); s.listen(0, common.mustCall(runTest)); function runTest() { http.get({ port: this.address().port }, common.mustCall(function (response) { response.on('end', common.mustCall(function () { assert.strictEqual(response.headers['test'], '1' /*'2'*/); // assert.notStrictEqual(response.rawHeaders.indexOf('Test'), -1); s.close(); })); response.resume(); })); } iotjs-1.0/test/node/parallel/test-net-after-close.js000066400000000000000000000045531312466455500225270ustar00rootroot00000000000000/* Copyright 2017-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ // Copyright Joyent, Inc. and other Node contributors. // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to permit // persons to whom the Software is furnished to do so, subject to the // following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. 'use strict'; var common = require('node/common'); var assert = require('assert'); var net = require('net'); var server = net.createServer(function(s) { console.error('SERVER: got connection'); s.end(); }); server.listen(0, common.mustCall(function() { var c = net.createConnection(this.address().port); c.on('close', common.mustCall(function() { console.error('connection closed'); assert.strictEqual(c._handle, null); assert.doesNotThrow(function() { c.setKeepAlive(); c.pause(); c.resume(); c.address(); c.remoteAddress; c.remotePort; }); server.close(); })); })); iotjs-1.0/test/node/parallel/test-net-bind-twice.js000066400000000000000000000044561312466455500223520ustar00rootroot00000000000000/* Copyright 2017-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ // Copyright Joyent, Inc. and other Node contributors. // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to permit // persons to whom the Software is furnished to do so, subject to the // following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. 'use strict'; var common = require('node/common'); var assert = require('assert'); var net = require('net'); var server1 = net.createServer(common.fail); server1.listen(0, '127.0.0.1', common.mustCall(function() { var server2 = net.createServer(common.fail); server2.on('error', common.mustCall(function(e) { // EADDRINUSE have different value on OSX. if (common.isOSX) { assert.strictEqual(e, -48); } else { assert.strictEqual(e, -98); } server1.close(); })); server2.listen(this.address().port, '127.0.0.1', common.fail); })); iotjs-1.0/test/node/parallel/test-net-end-without-connect.js000066400000000000000000000035561312466455500242230ustar00rootroot00000000000000/* Copyright 2017-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ // Copyright Joyent, Inc. and other Node contributors. // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to permit // persons to whom the Software is furnished to do so, subject to the // following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. 'use strict'; require('node/common'); var net = require('net'); var sock = new net.Socket(); sock.end(); // Should not throw. iotjs-1.0/test/node/parallel/test-net-keepalive.js000077500000000000000000000047511312466455500222730ustar00rootroot00000000000000/* Copyright 2017-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ // Copyright Joyent, Inc. and other Node contributors. // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to permit // persons to whom the Software is furnished to do so, subject to the // following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. 'use strict'; var common = require('node/common'); var assert = require('assert'); var net = require('net'); var serverConnection; var clientConnection; var echoServer = net.createServer(function(connection) { serverConnection = connection; setTimeout(function() { serverConnection.end(); clientConnection.end(); echoServer.close(); }, 100); connection.setTimeout(0); assert.notStrictEqual(connection.setKeepAlive, undefined); // send a keepalive packet after 50 ms connection.setKeepAlive(true, 50); connection.on('end', function() { connection.end(); }); }); echoServer.listen(0); echoServer.on('listening', function() { clientConnection = net.createConnection(this.address().port); clientConnection.setTimeout(0); }); iotjs-1.0/test/node/parallel/test-timers-clear-null-does-not-throw-error.js000066400000000000000000000043441312466455500271120ustar00rootroot00000000000000/* Copyright 2017-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ // Copyright Joyent, Inc. and other Node contributors. // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to permit // persons to whom the Software is furnished to do so, subject to the // following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. 'use strict'; require('node/common'); var assert = require('assert'); // This test makes sure clearing timers with // 'null' or no input does not throw error assert.doesNotThrow(function() { clearInterval(null) }); assert.doesNotThrow(function() { clearInterval() }); assert.doesNotThrow(function() { clearTimeout(null) }); assert.doesNotThrow(function() { clearTimeout() }); // assert.doesNotThrow(function() { clearImmediate(null) }); // assert.doesNotThrow(function() { clearImmediate() }); iotjs-1.0/test/resources/000077500000000000000000000000001312466455500155065ustar00rootroot00000000000000iotjs-1.0/test/resources/greeting.txt000066400000000000000000000000161312466455500200500ustar00rootroot00000000000000Hello IoT.js!!iotjs-1.0/test/resources/process/000077500000000000000000000000001312466455500171645ustar00rootroot00000000000000iotjs-1.0/test/resources/process/package.json000066400000000000000000000012311312466455500214470ustar00rootroot00000000000000{ "version": "2.9.1", "name": "npm", "description": "a package manager for JavaScript", "config": { "publishtest": false }, "homepage": "https://docs.npmjs.com/", "repository": { "type": "git", "url": "https://github.com/npm/npm" }, "bugs": { "url": "http://github.com/npm/npm/issues" }, "directories": { "doc": "./doc", "man": "./man", "lib": "./lib", "bin": "./bin" }, "main": "./lib/npm.js", "bin": "./bin/npm-cli.js", "scripts": { "test-legacy": "node ./test/run.js", "test": "tap --timeout 240 test/tap/*.js", "tap": "tap --timeout 240 test/tap/*.js" }, "license": "Artistic-2.0" } iotjs-1.0/test/resources/readdir/000077500000000000000000000000001312466455500171205ustar00rootroot00000000000000iotjs-1.0/test/resources/readdir/DO_NOT_MODIFY_THIS_FOLDER000066400000000000000000000000001312466455500230040ustar00rootroot00000000000000iotjs-1.0/test/resources/readdir/This_is_a_directory/000077500000000000000000000000001312466455500231065ustar00rootroot00000000000000iotjs-1.0/test/resources/readdir/This_is_a_directory/.gitkeep000066400000000000000000000000001312466455500245250ustar00rootroot00000000000000iotjs-1.0/test/resources/readdir/This_is_another_directory/000077500000000000000000000000001312466455500243265ustar00rootroot00000000000000iotjs-1.0/test/resources/readdir/This_is_another_directory/.gitkeep000066400000000000000000000000001312466455500257450ustar00rootroot00000000000000iotjs-1.0/test/resources/readdir/regular.txt000066400000000000000000000000161312466455500213170ustar00rootroot00000000000000Hello IoT.js!!iotjs-1.0/test/resources/rename.txt000066400000000000000000000000161312466455500175130ustar00rootroot00000000000000Hello IoT.js!!iotjs-1.0/test/resources/test1.txt000066400000000000000000000000271312466455500173060ustar00rootroot00000000000000TEST File Read & Write iotjs-1.0/test/resources/test2.txt000066400000000000000000000000001312466455500172760ustar00rootroot00000000000000iotjs-1.0/test/resources/test_console_stdout.txt000066400000000000000000000000601312466455500223460ustar00rootroot00000000000000Hello IoT.js!! 1 2 3 13 1,2,3 1 2 3 a 1 b 2 c 3 iotjs-1.0/test/resources/tobeornottobe.txt000066400000000000000000000030141312466455500211320ustar00rootroot00000000000000To be, or not to be, that is the Question: Whether ’tis Nobler in the mind to Å¿uffer The Slings and Arrows of outragious Fortune, Or to take Armes against a Sea of troubles, And by opposing end them: to dye, to Å¿leepe No more; and by a sleep, to say we end The Heart-ake, and the thouÅ¿and Naturall Å¿hockes That Flesh is there too? "Tis a consummation Deuoutly to be wiÅ¿h'd. To dye to sleepe, To sleep, perchance to Dream; I, there's the rub, For in that sleep of death, what dreams may come, When we haue Å¿hufflel’d off this mortall coile, MuÅ¿t giue us pause. There's the respect That makes Calamity of long life: For who would beare the Whips and Scornes of time, The Oppreſſors wrong, the poore mans Contumely, The pangs of diÅ¿priz’d Loue, the Lawes delay, The inÅ¿olence of Office, and the Spurnes That patient merit of the vnworthy takes, When he himÅ¿elfe might his Quietus make With a bare Bodkin? Who would theÅ¿e Fardles beare To grunt and Å¿weat vnder a weary life, But that the dread of Å¿omething after death, The vndiÅ¿couered Countrey, from whoÅ¿e Borne No Traueller returnes, Puzels the will, And makes vs rather beare those illes we haue, Then flye to others that we know not of. Thus ConÅ¿cience does make Cowards of vs all, And thus the Natiue hew of Resolution Is Å¿icklied o’re, with the pale caÅ¿t of Thought, And enterprizes of great pith and moment, With this regard their Currants turne away, And looÅ¿e the name of Action. Soft you now, The faire Ophelia? Nimph, in thy Orizons Be all my Å¿innes remembred.iotjs-1.0/test/run_fail/000077500000000000000000000000001312466455500152735ustar00rootroot00000000000000iotjs-1.0/test/run_fail/test_assert_equal.js000066400000000000000000000012671312466455500213660ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var assert = require('assert'); assert.equal(1, 2); iotjs-1.0/test/run_fail/test_assert_fail.js000066400000000000000000000012621312466455500211650ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var assert = require('assert'); assert.fail(); iotjs-1.0/test/run_fail/test_assert_notequal.js000066400000000000000000000012721312466455500221030ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var assert = require('assert'); assert.notEqual(1, 1); iotjs-1.0/test/run_fail/test_events_emit_error.js000066400000000000000000000013461312466455500224270ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var EventEmitter = require('events').EventEmitter; var ee = new EventEmitter(); ee.emit('error'); iotjs-1.0/test/run_fail/test_fs_callbacks_called.js000066400000000000000000000023721312466455500226070ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var assert = require('assert') var invocation_count = 0; var callback_count = 13; var callback = function () { if (++invocation_count == callback_count) { assert.fail("pass") // All the callbacks were called } } var fs = require('fs'); fs.open("", "r", callback); fs.close(0, callback); fs.read(0, Buffer(1), 0, 0, 0, callback); fs.write(0, Buffer(1), 0, 0, 0, callback); fs.readFile("", callback); fs.writeFile("", Buffer(1), callback); fs.rename("", "", callback); fs.stat("", callback); fs.exists("", callback); fs.unlink("", callback); fs.mkdir("", callback); fs.rmdir("", callback); fs.readdir("", callback); iotjs-1.0/test/run_fail/test_iotjs_runtime_error.js000066400000000000000000000012501312466455500227720ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var a = null; a.no_exist_function(); iotjs-1.0/test/run_fail/test_iotjs_syntax_error.js000066400000000000000000000012221312466455500226340ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ for syntax error iotjs-1.0/test/run_fail/test_module_require_invalid_file.js000066400000000000000000000012411312466455500244140ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ require('no exist file path'); iotjs-1.0/test/run_fail/test_process_exitcode_arg.js000066400000000000000000000014071312466455500230650ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var assert = require('assert'); process.on('exit', function(code) { assert.equal(1, code); assert.fail(); }); process.exit(1); iotjs-1.0/test/run_fail/test_process_exitcode_var.js000066400000000000000000000014401312466455500231010ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var assert = require('assert'); process.on('exit', function(code) { assert.equal(2, code); assert.fail(); }); process.exitCode = 2; process.exit(); iotjs-1.0/test/run_fail/test_process_explicit_exit.js000066400000000000000000000013511312466455500233000ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var assert = require('assert'); process.on('exit', function() { assert.fail(); }); process.exit(); iotjs-1.0/test/run_fail/test_process_implicit_exit.js000066400000000000000000000013301312466455500232660ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var assert = require('assert'); process.on('exit', function() { assert.fail(); }); iotjs-1.0/test/run_pass/000077500000000000000000000000001312466455500153265ustar00rootroot00000000000000iotjs-1.0/test/run_pass/issue/000077500000000000000000000000001312466455500164565ustar00rootroot00000000000000iotjs-1.0/test/run_pass/issue/issue-133.js000066400000000000000000000012471312466455500204540ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ // FIX: issue #133. console.log(""); iotjs-1.0/test/run_pass/issue/issue-137.js000066400000000000000000000022571312466455500204620ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ // FIX: issue #137. console.log('hello world'); console.log(1); console.log(9 + 10); console.log(null); console.log(true); console.log(false); console.log(undefined); console.log(0.09); console.log(NaN); console.log(function () {}); console.log(function f() { return 0; }); console.log({}); console.log({a:1, b:2}); console.log([]); console.log([1,2,3]); console.log("%s=%d", "1+10", 1 + 10); console.log("%s+%s=%d", 2, 10, 2 + 10); console.log("%d+%d=%d", 3, 10, 3 + 10); console.log("%s+%s=%s", 4, 10, 4 + 10); console.log("%d+%d=%d", "5", "10", 5 + 10); iotjs-1.0/test/run_pass/issue/issue-198.js000066400000000000000000000013741312466455500204700ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var assert = require('assert'); assert.throws( function() { process.binding("builtin not exist"); } , Error ); iotjs-1.0/test/run_pass/issue/issue-223.js000066400000000000000000000014261312466455500204530ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var assert = require('assert'); var net = require("net"); assert.throws( function() { net.Server.prototype._createTCP(375); }, Error ); iotjs-1.0/test/run_pass/issue/issue-266.js000066400000000000000000000022041312466455500204550ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var net = require('net'); var assert = require('assert'); var server = net.createServer(); var port = 30266; server.listen(port); server.on('connection', function(socket) { socket.on('data', function(data) { server.close() }); socket.on('finish', function() { socket.destroy(); socket.destroy(); socket.destroy(); }); }); var socket = new net.Socket(); socket.connect(port, "127.0.0.1"); socket.end('test'); process.on('exit', function() { assert.equal(server._socketCount, 0); }); iotjs-1.0/test/run_pass/issue/issue-323.js000066400000000000000000000016071312466455500204550ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var fs = require('fs'); var assert = require('assert'); var fileName = ""; assert.throws( function() { var stats1 = fs.statSync(fileName); }, Error ); assert.throws( function() { var open1 = fs.openSync(fileName, 'r'); }, Error ); iotjs-1.0/test/run_pass/issue/issue-816.js000066400000000000000000000016701312466455500204640ustar00rootroot00000000000000/* Copyright 2017-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var Buffer = require('buffer'); var assert = require('assert'); assert.throws(function () { var buf = new Buffer("ABCDEF"); var o = { _builtin: { compare: function () { buf._builtin.compare.call(this, arguments); } }, compare: buf.compare }; o.compare(buf); }, Error); iotjs-1.0/test/run_pass/require1/000077500000000000000000000000001312466455500170635ustar00rootroot00000000000000iotjs-1.0/test/run_pass/require1/module_cache.js000066400000000000000000000012451312466455500220330ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** @NOTEST */ exports.i = -100; iotjs-1.0/test/run_pass/require1/require_add.js000066400000000000000000000013041312466455500217030ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* @NOTEST */ exports.add = function(a, b) { return a + b; }; iotjs-1.0/test/run_pass/require1/test_index/000077500000000000000000000000001312466455500212315ustar00rootroot00000000000000iotjs-1.0/test/run_pass/require1/test_index/add2.js000066400000000000000000000013041312466455500223770ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* @NOTEST */ exports.add2 = function(a, b) { return a + b; } iotjs-1.0/test/run_pass/require1/test_index/index.js000066400000000000000000000014261312466455500227010ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* @NOTEST */ exports.add = function(a, b) { return a + b; }; var x = require("lib/multi.js"); exports.multi = x.multi; exports.add2 = x.add2; iotjs-1.0/test/run_pass/require1/test_index/lib/000077500000000000000000000000001312466455500217775ustar00rootroot00000000000000iotjs-1.0/test/run_pass/require1/test_index/lib/multi.js000066400000000000000000000013571312466455500234750ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* @NOTEST */ exports.multi = function(a, b) { return a * b; }; exports.add2 = require('../add2').add2; iotjs-1.0/test/run_pass/require1/test_index/package.json000066400000000000000000000000331312466455500235130ustar00rootroot00000000000000{ "main": "index_test" } iotjs-1.0/test/run_pass/require1/test_pkg/000077500000000000000000000000001312466455500207035ustar00rootroot00000000000000iotjs-1.0/test/run_pass/require1/test_pkg/add2.js000066400000000000000000000013041312466455500220510ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* @NOTEST */ exports.add2 = function(a, b) { return a + b; } iotjs-1.0/test/run_pass/require1/test_pkg/lib/000077500000000000000000000000001312466455500214515ustar00rootroot00000000000000iotjs-1.0/test/run_pass/require1/test_pkg/lib/multi.js000066400000000000000000000013571312466455500231470ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* @NOTEST */ exports.multi = function(a, b) { return a * b; }; exports.add2 = require('../add2').add2; iotjs-1.0/test/run_pass/require1/test_pkg/main.js000066400000000000000000000014261312466455500221700ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* @NOTEST */ exports.add = function(a, b) { return a + b; }; var x = require("lib/multi.js"); exports.multi = x.multi; exports.add2 = x.add2; iotjs-1.0/test/run_pass/require1/test_pkg/package.json000066400000000000000000000000301312466455500231620ustar00rootroot00000000000000{ "main": "main.js" } iotjs-1.0/test/run_pass/test_adc.js000066400000000000000000000044361312466455500174610ustar00rootroot00000000000000/* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var Adc = require('adc'); var assert = require('assert'); var adc = new Adc(); var configuration = {}; if (process.platform === 'linux') { configuration.device = '/sys/devices/12d10000.adc/iio:device0/in_voltage0_raw'; } else if (process.platform === 'nuttx') { configuration.pin = require('stm32f4dis').pin.ADC1_3; } else { assert.fail(); } asyncTest(); // read async test function asyncTest() { var adc0 = adc.open(configuration, function(err) { console.log('ADC initialized'); if (err) { assert.fail(); } var loopCnt = 5; console.log('test1 start(read async test)'); var test1Loop = setInterval(function() { if (--loopCnt < 0) { console.log('test1 complete'); clearInterval(test1Loop); adc0.closeSync(); syncTestst(); } else { adc0.read(function(err, value) { if (err) { console.log('read failed'); assert.fail(); } console.log(value); }); } }, 1000); }); } // read sync test function syncTestst() { var adc0 = adc.open(configuration, function(err) { console.log('ADC initialized'); if (err) { assert.fail(); } var loopCnt = 5, value = -1; console.log('test2 start(read sync test)'); var test2Loop = setInterval(function() { if (--loopCnt < 0) { console.log('test2 complete'); clearInterval(test2Loop); adc0.close(); } else { value = adc0.readSync(); if (value < 0) { console.log('read failed'); assert.fail(); } else { console.log(value); } } }, 1000); }); } iotjs-1.0/test/run_pass/test_assert.js000066400000000000000000000052221312466455500202250ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var assert = require('assert'); assert.assert(1 == 1); assert.equal(1, 1); assert.notEqual(1, 2); assert.strictEqual(0, 0); assert.throws(function() { assert.strictEqual(1, 0); }, assert.AssertionError); assert.throws(function() { assert.notStrictEqual(true, true); }, assert.AssertionError); assert.throws(function() { assert.notStrictEqual(true, true); }, assert.AssertionError, "something"); assert.throws(function() { assert.throws(function() {}); }, assert.AssertionError); assert.throws(function() { assert.throws(function() { assert.strictEqual(1, 0); }, TypeError); }, assert.AssertionError); assert.doesNotThrow(function() { assert.strictEqual(1, 1); }, "something"); assert.throws(function() { assert.strictEqual(1, 0); }, assert.AssertionError, assert.AssertionError.name="something"); assert.equal(0, false); assert.notStrictEqual(0, false); assert.throws( function() { assert.equal(1, 2); }, assert.AssertionError ); assert.throws( function() { assert.assert(1 == 2); }, assert.AssertionError ); assert.doesNotThrow( function() { assert.assert(1 == 1); } ); assert.throws( function() { assert.doesNotThrow( function() { assert.assert(1 == 2); } ); }, assert.AssertionError ); try { assert.assert(false, 'assert test'); } catch (e) { assert.equal(e.name, 'AssertionError'); assert.equal(e.actual, false); assert.equal(e.expected, true); assert.equal(e.operator, '=='); assert.equal(e.message, 'assert test'); } try { assert.equal(1, 2, 'assert.equal test'); } catch (e) { assert.equal(e.name, 'AssertionError'); assert.equal(e.actual, 1); assert.equal(e.expected, 2); assert.equal(e.operator, '=='); assert.equal(e.message, 'assert.equal test'); } try { assert.fail('actual', 'expected', 'message', 'operator'); } catch (e) { assert.equal(e.name, 'AssertionError'); assert.equal(e.actual, 'actual'); assert.equal(e.expected, 'expected'); assert.equal(e.operator, 'operator'); assert.equal(e.message, 'message'); } iotjs-1.0/test/run_pass/test_ble_advertisement.js000066400000000000000000000023401312466455500224160ustar00rootroot00000000000000/* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var ble = require('ble'); ble.on('stateChange', function(state){ console.log('onStateChange: ' + state); if (state == 'poweredOn') { ble.startAdvertising('iotjs', ['180F'], function(err) { if (err) console.log(err); else { setTimeout(function() { ble.stopAdvertising(function(err) { if (err) console.log(err); else console.log('stop advertising.'); }); }, 5000); } }); } else { ble.stopAdvertising(function(err) { if (err) console.log(err); else console.log('stop advertising.'); }); } }); iotjs-1.0/test/run_pass/test_ble_setservices.js000066400000000000000000000072501312466455500221100ustar00rootroot00000000000000/* Copyright 2017-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* Copyright (C) 2015 Sandeep Mistry sandeep.mistry@gmail.com * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ var ble = require('ble'); var BlenoPrimaryService = ble.PrimaryService; var BlenoCharacteristic = ble.Characteristic; var util = require('util'); var EchoCharacteristic = function() { BlenoCharacteristic.call(this, { uuid: 'ec0e', properties: ['read', 'write', 'notify'], value: null }); this._value = new Buffer(0); this._updateValueCallback = null; }; util.inherits(EchoCharacteristic, BlenoCharacteristic); EchoCharacteristic.prototype.onReadRequest = function(offset, callback) { console.log('EchoCharacteristic - onReadRequest: value = ' + this._value.toString('hex')); callback(this.RESULT_SUCCESS, this._value); }; EchoCharacteristic.prototype.onWriteRequest = function(data, offset, withoutResponse, callback) { this._value = data; console.log('EchoCharacteristic - onWriteRequest: value = ' + this._value.toString('hex')); if (this._updateValueCallback) { console.log('EchoCharacteristic - onWriteRequest: notifying'); this._updateValueCallback(this._value); } callback(this.RESULT_SUCCESS); }; EchoCharacteristic.prototype.onSubscribe = function(maxValueSize, updateValueCallback) { console.log('EchoCharacteristic - onSubscribe'); this._updateValueCallback = updateValueCallback; }; EchoCharacteristic.prototype.onUnsubscribe = function() { console.log('EchoCharacteristic - onUnsubscribe'); this._updateValueCallback = null; }; console.log('ble - echo'); ble.on('stateChange', function(state) { console.log('on -> stateChange: ' + state); if (state === 'poweredOn') { ble.startAdvertising('iotjs_echo', ['ec00']); } else { ble.stopAdvertising(); } }); ble.on('advertisingStart', function(error) { console.log('on -> advertisingStart: ' + (error ? 'error ' + error : 'success')); if (!error) { ble.setServices([ new BlenoPrimaryService({ uuid: 'ec00', characteristics: [ new EchoCharacteristic() ] }) ]); } }); iotjs-1.0/test/run_pass/test_ble_setservices_central.js000066400000000000000000000105611312466455500236170ustar00rootroot00000000000000/* Copyright 2017-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* Copyright (C) 2015 Sandeep Mistry sandeep.mistry@gmail.com * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ var noble = require('../..'); var echoServiceUuid = 'ec00'; var echoCharacteristicUuid = 'ec0e'; noble.on('stateChange', function(state) { if (state === 'poweredOn') { // // Once the BLE radio has been powered on, it is possible // to begin scanning for services. Pass an empty array to // scan for all services (uses more time and power). // console.log('scanning...'); noble.startScanning([echoServiceUuid], false); } else { noble.stopScanning(); } }) var echoService = null; var echoCharacteristic = null; noble.on('discover', function(peripheral) { // we found a peripheral, stop scanning noble.stopScanning(); // // The advertisment data contains a name, power level (if available), // certain advertised service uuids, as well as manufacturer data, // which could be formatted as an iBeacon. // console.log('found peripheral:', peripheral.advertisement); // // Once the peripheral has been discovered, then connect to it. // It can also be constructed if the uuid is already known. /// peripheral.connect(function(err) { // // Once the peripheral has been connected, then discover the // services and characteristics of interest. // peripheral.discoverServices([echoServiceUuid], function(err, services) { services.forEach(function(service) { // // This must be the service we were looking for. // console.log('found service:', service.uuid); // // So, discover its characteristics. // service.discoverCharacteristics([], function(err, characteristics) { characteristics.forEach(function(characteristic) { // // Loop through each characteristic and match them to the // UUIDs that we know about. // console.log('found characteristic:', characteristic.uuid); if (echoCharacteristicUuid == characteristic.uuid) { echoCharacteristic = characteristic; } }) // // Check to see if we found all of our characteristics. // if (echoCharacteristic) { bakePizza(); } else { console.log('missing characteristics'); } }) }) }) }) }) function bakePizza() { var crust = new Buffer("Hello BLE Service."); echoCharacteristic.write(crust, false, function(err) { if (!err) { echoCharacteristic.read(function (err, buffer) { if (!err) { console.log('BLE says' + buffer.toString()); } }); } else { console.log('crust error'); } }) } iotjs-1.0/test/run_pass/test_buffer.js000066400000000000000000000137351312466455500202050ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var assert = require('assert'); var buff1 = new Buffer("test"); assert.equal(buff1.toString(), "test"); assert.equal(buff1.toString(0, 0), ""); assert.equal(buff1.toString(0, 1), "t"); assert.equal(buff1.toString(0, 2), "te"); assert.equal(buff1.toString(0, 3), "tes"); assert.equal(buff1.toString(0, 4), "test"); assert.equal(buff1.toString(1, 4), "est"); assert.equal(buff1.toString(2, 4), "st"); assert.equal(buff1.toString(3, 4), "t"); assert.equal(buff1.toString(4, 4), ""); assert.equal(buff1.length, 4); var buff2 = new Buffer(10); buff2.write("abcde"); assert.equal(buff2.toString(), "abcde"); assert.equal(buff2.length ,10); buff2.write("fgh", 5); assert.equal(buff2.toString(), "abcdefgh"); assert.equal(buff2.length ,10); assert.throws(function() { buff2.write("ijk", -1); }, RangeError); assert.throws(function() { buff2.write("ijk", 10); }, RangeError); var buff3 = Buffer.concat([buff1, buff2]); assert.equal(buff3.toString(), "testabcdefgh"); assert.equal(buff3.length ,14); var buff4 = new Buffer(10); var buff5 = new Buffer('a1b2c3'); buff5.copy(buff4); assert.equal(buff4.toString(), 'a1b2c3'); buff5.copy(buff4, 4, 2); assert.equal(buff4.toString(), 'a1b2b2c3'); assert.throws(function() { buff5.copy(buff4, -1); }, RangeError); assert.throws(function() { buff2.write(null, 0, 0);}, TypeError); assert.throws(function() { buff5.copy(null); }, TypeError); assert.throws(function() { buff5.compare(null); }, TypeError); assert.throws(function() { buff5.equals(null); }, TypeError); assert.throws(function() { Buffer.concat([buff1, null]);}, TypeError); assert.throws(function() {Buffer.concat(null, null); }, TypeError); assert.throws(function() {var buff_err = new Buffer(null); }, TypeError); var buffer_err = new Buffer(-1); var buff_1 = new Buffer("asd"); var buff_2 = new Buffer(2); buff_1.copy(buff_2, 0, 0, 2); buff_2.write("asd", 0, 3); assert.throws(function() {var buff_3 = new Buffer('asd', 'hex'); }, TypeError); var buff_3 = new Buffer(4); assert.throws(function() {buff_3.writeUInt8(10000, 0); }, TypeError); var buff_4 = new Buffer(4); assert.throws(function() {buff_4.writeUInt8(0x11, 3000); }, RangeError); var buff_5 = new Buffer(4); assert.throws(function() {buff_5.readUInt8(3000); }, RangeError); var buff_6 = buff_5.slice(undefined, 2); buff_5.fill("asd"); buff_5.readInt8(3, true); buff_5.writeUInt32LE(0, 0, true); buff_5.writeUInt8(0, 0, true); buff_5.writeUInt16LE(0, 0, true); var buff6 = buff3.slice(1); assert.equal(buff6.toString(), 'estabcdefgh'); assert.equal(buff6.length, 13); var buff7 = buff6.slice(3, 5); assert.equal(buff7.toString(), 'ab'); assert.equal(buff7.length, 2); var buff8 = new Buffer(buff5); assert.equal(buff8.toString(), 'a1b2c3'); assert.equal(buff8.equals(buff5), true); assert.equal(buff8.equals(buff6), false); var buff9 = new Buffer('abcabcabcd'); var buff10 = buff9.slice(0, 3); var buff11 = buff9.slice(3, 6); var buff12 = buff9.slice(6); assert.equal(buff10.equals(buff11), true); assert.equal(buff11.equals(buff10), true); assert.equal(buff11.equals(buff12), false); assert.equal(buff10.compare(buff11), 0); assert.equal(buff11.compare(buff10), 0); assert.equal(buff11.compare(buff12), -1); assert.equal(buff12.compare(buff11), 1); assert.equal(buff9.slice(-2).toString(), 'cd'); assert.equal(buff9.slice(-3, -2).toString(), 'b'); assert.equal(buff9.slice(0, -2).toString(), 'abcabcab'); assert.equal(Buffer.isBuffer(buff9), true); assert.equal(Buffer.isBuffer(1), false); assert.equal(Buffer.isBuffer({}), false); assert.equal(Buffer.isBuffer('1'), false); assert.equal(Buffer.isBuffer([1]), false); assert.equal(Buffer.isBuffer([buff1]), false); assert.equal(Buffer.isBuffer({obj:buff1}), false); assert.equal(buff3.toString(), 'testabcdefgh'); var buff13 = new Buffer(4); buff13.writeUInt8(0x11, 0); assert.equal(buff13.readUInt8(0), 0x11); buff13.writeUInt16LE(0x3456, 1); assert.equal(buff13.readUInt8(1), 0x56); assert.equal(buff13.readUInt8(2), 0x34); assert.equal(buff13.readUInt16LE(1), 0x3456); buff13.writeUInt32LE(0x89abcdef, 0); assert.equal(buff13.readUInt8(0), 0xef); assert.equal(buff13.readUInt8(1), 0xcd); assert.equal(buff13.readUInt8(2), 0xab); assert.equal(buff13.readUInt8(3), 0x89); assert.equal(buff13.readUInt16LE(0), 0xcdef); assert.equal(buff13.readUInt16LE(2), 0x89ab); var buff14 = new Buffer([0x01, 0xa1, 0xfb]); assert.equal(buff14.readUInt8(0), 0x01); assert.equal(buff14.readUInt8(1), 0xa1); assert.equal(buff14.readUInt8(2), 0xfb); assert.equal(buff14.readInt8(2), -5); assert.equal(buff14.toString('hex'), '01a1fb'); var buff15 = new Buffer('7456a9', 'hex'); assert.equal(buff15.length, 3); assert.equal(buff15.readUInt8(0), 0x74); assert.equal(buff15.readUInt8(1), 0x56); assert.equal(buff15.readUInt8(2), 0xa9); assert.equal(buff15.toString('hex'), '7456a9'); var buff16 = new Buffer(4); var ret = buff16.fill(7); assert.equal(buff16.readInt8(0), 7); assert.equal(buff16.readInt8(1), 7); assert.equal(buff16.readInt8(2), 7); assert.equal(buff16.readInt8(3), 7); assert.equal(buff16, ret); buff16.fill(13+1024); assert.equal(buff16.readInt8(0), 13); assert.equal(buff16.readInt8(1), 13); assert.equal(buff16.readInt8(2), 13); assert.equal(buff16.readInt8(3), 13); assert.equal(Buffer(new Array()).toString(), ''); assert.equal(new Buffer(1).readUInt8(1, true), 0); assert.equal(new Buffer(1).readUInt16LE({}, true), 0); var buff17 = new Buffer("a"); assert.throws(function() { buff17.fill(8071).toString(); }, TypeError); iotjs-1.0/test/run_pass/test_buffer_builtin.js000066400000000000000000000071371312466455500217320ustar00rootroot00000000000000/* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var assert = require('assert'); var buff1 = new Buffer("test"); assert.equal(buff1._builtin.toString(0, 0), ""); assert.equal(buff1._builtin.toString(0, 1), "t"); assert.equal(buff1._builtin.toString(0, 2), "te"); assert.equal(buff1._builtin.toString(0, 3), "tes"); assert.equal(buff1._builtin.toString(0, 4), "test"); assert.equal(buff1._builtin.toString(1, 4), "est"); assert.equal(buff1._builtin.toString(2, 4), "st"); assert.equal(buff1._builtin.toString(3, 4), "t"); assert.equal(buff1._builtin.toString(4, 4), ""); assert.equal(buff1._builtin.toString(-1, 5), "test"); assert.equal(buff1._builtin.toString(-1, 2), "te"); assert.equal(buff1._builtin.toString(2, 5), "st"); var buff2 = new Buffer(10); buff2._builtin.write("abcde", 0, 5); assert.equal(buff2.toString(), "abcde"); assert.equal(buff2.length, 10); buff2._builtin.write("fgh", 5, 3); assert.equal(buff2.toString(), "abcdefgh"); assert.equal(buff2.length, 10); buff2._builtin.write("AB", 0, 10); assert.equal(buff2.toString(), "ABcdefgh"); assert.equal(buff2.length, 10); buff2._builtin.write("ab", -1, 11); assert.equal(buff2.toString(), "abcdefgh"); assert.equal(buff2.length, 10); buff2._builtin.write("ijklmnopqrstu", 8, 5); assert.equal(buff2.toString(), "abcdefghij"); assert.equal(buff2.length, 10); buff2._builtin.write("\0\0", 8, 2); assert.equal(buff2.toString(), "abcdefgh"); assert.equal(buff2.length, 10); var buff3 = Buffer.concat([buff1, buff2]); var buff4 = new Buffer(10); var buff5 = new Buffer('a1b2c3'); buff5._builtin.copy(buff4, 0, 0, 6); assert.equal(buff4.toString(), 'a1b2c3'); buff5._builtin.copy(buff4, 4, 2, 6); assert.equal(buff4.toString(), 'a1b2b2c3'); var buff6 = buff3._builtin.slice(1, buff3.length); assert.equal(buff6.toString(), 'estabcdefgh'); assert.equal(buff6.length, 13); var buff7 = buff6._builtin.slice(3, 5); assert.equal(buff7.toString(), 'ab'); assert.equal(buff7.length, 2); var buff8 = new Buffer(buff5); assert.equal(buff8.toString(), 'a1b2c3'); assert.equal(buff8.equals(buff5), true); assert.equal(buff8.equals(buff6), false); var buff9 = new Buffer('abcabcabcd'); var buff10 = buff9._builtin.slice(0, 3); var buff11 = buff9._builtin.slice(3, 6); var buff12 = buff9._builtin.slice(6, buff9.length); assert.equal(buff10.equals(buff11), true); assert.equal(buff11.equals(buff10), true); assert.equal(buff11.equals(buff12), false); assert.equal(buff10.compare(buff11), 0); assert.equal(buff11.compare(buff10), 0); assert.equal(buff11.compare(buff12), -1); assert.equal(buff12.compare(buff11), 1); assert.equal(buff9._builtin.slice(-2, buff9.length).toString(), 'cd'); assert.equal(buff9._builtin.slice(-3, -2).toString(), 'b'); assert.equal(buff9._builtin.slice(0, -2).toString(), 'abcabcab'); assert.equal(buff3.toString(), 'testabcdefgh'); assert.equal(Buffer.byteLength('\u007F'), 1); assert.equal(Buffer.byteLength('\u008F'), 2); assert.equal(Buffer.byteLength('\u08FF'), 3); assert.equal(Buffer.byteLength('abc'), 'abc'.length); assert.notEqual(Buffer.byteLength('\u2040'), '\u2040'.length); iotjs-1.0/test/run_pass/test_console.js000066400000000000000000000021071312466455500203650ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var console = require('console'); console.log("Hello IoT.js!!"); console.log(1); console.log(2); console.log(3); console.log(3+5*2); console.log([1, 2, 3]); console.log(1, 2, 3); console.log('a', 1, 'b', 2, 'c', 3); console.log("test", null, undefined); console.error("Hello IoT.js!!"); console.error(1); console.error(2); console.error(3); console.error(3+5*2); console.error([1, 2, 3]); console.error(1, 2, 3); console.error('a', 1, 'b', 2, 'c', 3); iotjs-1.0/test/run_pass/test_dgram_1_server_1_client.js000066400000000000000000000037241312466455500234070ustar00rootroot00000000000000/* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var assert = require('assert'); var dgram = require('dgram'); var port = 41234; var msg = 'Hello IoT.js'; var server = dgram.createSocket('udp4'); server.on('error', function(err) { assert.fail(); server.close(); }); server.on('message', function(data, rinfo) { console.log('server got data : ' + data); console.log('client address : ' + rinfo.address); console.log('client port : ' + rinfo.port); console.log('client family : ' + rinfo.family); assert.equal(data, msg); server.send(msg, rinfo.port, 'localhost', function (err, len) { assert.equal(err, null); assert.equal(len, msg.length); server.close(); }); }); server.on('listening', function() { console.log('listening'); }); server.bind(port); var client = dgram.createSocket('udp4'); client.send(msg, port, 'localhost', function(err, len) { assert.equal(err, null); assert.equal(len, msg.length); }); client.on('error', function(err) { assert.fail(); client.close(); }); client.on('message', function(data, rinfo) { console.log('client got data : ' + data); console.log('server address : ' + rinfo.address); console.log('server port : ' + rinfo.port); console.log('server family : ' + rinfo.family); assert.equal(port, rinfo.port); assert.equal(data, msg); client.close(); }); process.on('exit', function(code) { assert.equal(code, 0); }); iotjs-1.0/test/run_pass/test_dgram_1_server_n_clients.js000066400000000000000000000035201312466455500236610ustar00rootroot00000000000000/* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var assert = require('assert'); var dgram = require('dgram'); var port = 41235; var msg = ''; var sockcount = 5; var sendcount = 0; var server = dgram.createSocket('udp4'); server.on('error', function(err) { assert.fail(); server.close(); }); server.on('message', function(data, rinfo) { console.log('server got data : ' + data); msg += data; server.send(data, rinfo.port, 'localhost', function (err, len) { sendcount++; if (sendcount >= sockcount) { server.close(); } }); }); server.bind(port); for (var i = 0; i < sockcount; i++) { (function sendAndRecieve(i) { var client = dgram.createSocket('udp4'); client.send(i.toString(), port, 'localhost'); client.on('error', function(err) { assert.fail(); client.close(); }); client.on('message', function(data, rinfo) { console.log('client got data : ' + data); assert.equal(port, rinfo.port); assert.equal(data, i.toString()); client.close(); }); })(i); } process.on('exit', function(code) { assert.equal(msg.length, sockcount); for (var i = 0; i < sockcount; i++) { if (msg.indexOf(i.toString()) == -1) { assert.fail(); } } assert.equal(code, 0); }); iotjs-1.0/test/run_pass/test_dgram_address.js000066400000000000000000000034211312466455500215220ustar00rootroot00000000000000/* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var assert = require('assert'); var dgram = require('dgram'); var port = 41236; var msg = 'Hello IoT.js'; var client = dgram.createSocket({ type: 'udp4', reuseAddr: true }); var server = dgram.createSocket({ type: 'udp4', reuseAddr: true }); var server_address, server_port, client_address, client_port; server.on('error', function(err) { assert.fail(); server.close(); }); server.on('message', function(data, rinfo) { var address = client.address(); client_address = address.address; client_port = address.port; assert.equal('0.0.0.0', client_address); assert.equal(rinfo.port, client_port); server.send(msg, rinfo.port, 'localhost'); }); server.on('listening', function() { var address = server.address(); server_address = address.address; server_port = address.port; }) server.bind(port); client.send(msg, port, 'localhost'); client.on('error', function(err) { assert.fail(); client.close(); }); client.on('message', function(data, rinfo) { assert.equal('0.0.0.0', server_address); assert.equal(rinfo.port, server_port); client.close(); server.close(); }); process.on('exit', function(code) { assert.equal(code, 0); }); iotjs-1.0/test/run_pass/test_dgram_broadcast.js000066400000000000000000000043341312466455500220430ustar00rootroot00000000000000/* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var assert = require('assert'); var dgram = require('dgram'); var port = 41237; var broadcast_address = '255.255.255.255'; var interval = 100; var msg_count = 0, msg_count2 = 0, msg_count3 = 0, send_count = 0; var msg = 'Hello IoT.js'; var socket = dgram.createSocket({type: 'udp4', reuseAddr: true}); var socket2 = dgram.createSocket({type: 'udp4', reuseAddr: true}); var socket3 = dgram.createSocket({type: 'udp4', reuseAddr: true}); socket.on('error', function(err) { assert.fail(); socket.close(); }); socket2.on('error', function(err) { assert.fail(); socket2.close(); }); socket3.on('error', function(err) { assert.fail(); socket3.close(); }); socket.on('message', function(data, rinfo) { console.log('socket got data : ' + data); msg_count++; if (msg_count == 3) { socket.close(); } }); socket2.on('message', function(data, rinfo) { console.log('socket2 got data : ' + data); msg_count2++; if (msg_count2 == 3) { socket2.close(); } }); socket3.on('message', function(data, rinfo) { console.log('socket3 got data : ' + data); msg_count3++; if (msg_count3 == 3) { socket3.close(); } }); socket.bind(port, function() { socket.setBroadcast(true); var timer = setInterval(function () { send_count++; socket.send(msg, port, broadcast_address); if (send_count == 3) { clearInterval(timer); } }, interval); }); socket2.bind(port); socket3.bind(port); process.on('exit', function(code) { assert.equal(code, 0); assert.equal(msg_count, 3); assert.equal(msg_count2, 3); assert.equal(msg_count3, 3); assert.equal(send_count, 3); }); iotjs-1.0/test/run_pass/test_dgram_multicast_membership.js000066400000000000000000000031461312466455500243210ustar00rootroot00000000000000/* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var assert = require('assert'); var dgram = require('dgram'); var port = 41239; var multicast_address = '230.255.255.250'; var interval = 100; var recv_count = 0, send_count = 0; var msg = 'Hello IoT.js'; var client = dgram.createSocket('udp4'); var server = dgram.createSocket('udp4'); server.on('error', function(err) { assert.fail(); server.close(); }); server.on('message', function(data, rinfo) { console.log('server got data : ' + data); recv_count++; if (recv_count == 1) { server.dropMembership(multicast_address); } }); server.bind(port, function() { server.addMembership(multicast_address); }); var timer = setInterval(function () { send_count++; client.send(msg, port, multicast_address); if (send_count == 3) { clearInterval(timer); } }, interval); setTimeout(function() { server.close(); client.close(); }, 1000); process.on('exit', function(code) { assert.equal(code, 0); assert.equal(recv_count, 1); assert.equal(send_count, 3); }); iotjs-1.0/test/run_pass/test_dgram_multicast_set_multicast_loop.js000066400000000000000000000023261312466455500260760ustar00rootroot00000000000000/* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var assert = require('assert'); var dgram = require('dgram'); var port = 41240; var multicast_address = '230.255.255.250'; var msg = 'Hello IoT.js'; var server = dgram.createSocket('udp4'); server.on('error', function(err) { assert.fail(); }); server.on('message', function(data, rinfo) { assert.fail(); }); server.bind(port, function() { server.setMulticastLoopback(false); server.addMembership(multicast_address); server.send(msg, port, multicast_address); }); setTimeout(function() { server.close(); }, 1000); process.on('exit', function(code) { assert.equal(code, 0); }); iotjs-1.0/test/run_pass/test_dgram_setttl_client.js000066400000000000000000000026441312466455500227600ustar00rootroot00000000000000/* Copyright 2017-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var assert = require('assert'); var dgram = require('dgram'); var port = 41234; var msg = 'Hello IoT.js'; var addr = '192.168.0.1'; // Change to your ip address var server = dgram.createSocket('udp4'); var client = dgram.createSocket('udp4'); client.send(msg, port, addr, function(err, len) { assert.equal(err, null); assert.equal(len, msg.length); }); client.on('error', function(err) { assert.fail(); }); client.on('listening', function(err) { client.setTTL(1); }); client.on('message', function(data, rinfo) { console.log('client got data : ' + data); console.log('server address : ' + rinfo.address); console.log('server port : ' + rinfo.port); console.log('server family : ' + rinfo.family); assert.equal(port, rinfo.port); assert.equal(data, msg); client.close(); }); iotjs-1.0/test/run_pass/test_dgram_setttl_server.js000066400000000000000000000026661312466455500230140ustar00rootroot00000000000000/* Copyright 2017-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var assert = require('assert'); var dgram = require('dgram'); var port = 41234; var msg = 'Hello IoT.js'; var server = dgram.createSocket('udp4'); server.on('error', function(err) { assert.fail(); server.close(); }); server.on('message', function(data, rinfo) { console.log('server got data : ' + data); console.log('client address : ' + rinfo.address); console.log('client port : ' + rinfo.port); console.log('client family : ' + rinfo.family); assert.equal(data, msg); server.send(msg, rinfo.port, rinfo.address, function (err, len) { assert.equal(err, null); assert.equal(len, msg.length); }); }); server.on('listening', function() { console.log('listening'); }); server.bind(port, function() { server.setTTL(1); }); process.on('exit', function(code) { assert.equal(code, 0); }); iotjs-1.0/test/run_pass/test_dns.js000066400000000000000000000026501312466455500175120ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var net = require('net'); var assert = require('assert'); var server = net.createServer(); var port = 1236; server.listen(port, 5); server.on('connection', function(socket) { socket.on('data', function(data) { socket.end('Hello IoT.js'); }); socket.on('close', function() { server.close(); }); }); var socket = new net.Socket(); var msg = ""; var lookupHandled = false; socket.on('lookup', function(err, ip, family) { lookupHandled = true; }); socket.connect(port, "localhost"); // connect with hostname socket.write("Hello IoT.js"); socket.on('data', function(data) { msg += data; }); socket.on('end', function() { socket.end(); }); process.on('exit', function(code) { assert.equal(code, 0); assert.equal(msg, "Hello IoT.js"); assert.equal(lookupHandled, true); }); iotjs-1.0/test/run_pass/test_dns_lookup.js000066400000000000000000000061011312466455500210760ustar00rootroot00000000000000/* Copyright 2017-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var dns = require('dns'); var assert = require('assert'); var options = { family: 4, hints: dns.ADDRCONFIG | dns.V4MAPPED, }; function isIPv4(ip) { var IPv4Regex = new RegExp( '^([0-9]{1,3}\.){3}[0-9]{1,3}(\/([0-9]|[1-2][0-9]|3[0-2]))?$' ); return IPv4Regex.test(ip); } dns.lookup('localhost', 4, function(err, ip, family) { assert.equal(err, null); assert.equal(isIPv4(ip), true); assert.equal(ip, '127.0.0.1'); assert.strictEqual(family, 4); }); // Test with IPv4 option. dns.lookup('localhost', 4, function(err, ip, family) { assert.equal(err, null); assert.equal(isIPv4(ip), true); assert.equal(ip, '127.0.0.1'); assert.strictEqual(family, 4); }); // Test without explicit options parameter. dns.lookup('localhost', function(err, ip, family) { assert.equal(err, null); assert.equal(isIPv4(ip), true); assert.equal(ip, '127.0.0.1'); }); // Test with invalid hostname. dns.lookup('invalid', 4, function(err, ip, family) { assert.notEqual(err, null); assert.equal(err.code == -3008 || err.code == -3007, true); }); // Test with empty hostname. dns.lookup('', 4, function(err, ip, family) { assert.notEqual(err, null); assert.equal(err.code == -3008 || err.code == -3007, true); }); // Test with non string hostname. assert.throws(function() { dns.lookup(5000, options, function(err, ip, family) {}); }, TypeError); // Test without callback function. assert.throws(function() { dns.lookup('localhost', options); }, TypeError); // Test with invalid callback parameter. assert.throws(function() { dns.lookup('localhost', options, 5000); }, TypeError); assert.throws(function() { dns.lookup('localhost', options, 'callback'); }, TypeError); // Test with invalid hints option. options.hints = -1; assert.throws(function() { dns.lookup('localhost', options, function(err, ip, family) {}); }, TypeError); options.hints = 5000; assert.throws(function() { dns.lookup('localhost', options, function(err, ip, family) {}); }, TypeError); // Test with invalid options parameter. assert.throws(function() { dns.lookup('localhost', 'options', function(err, ip, family) {}); }, TypeError); assert.throws(function() { dns.lookup('localhost', '', function(err, ip, family) {}); }, TypeError); // Test with invalid family option. assert.throws(function() { dns.lookup('localhost', 10, function(err, ip, family) {}); }, TypeError); assert.throws(function() { dns.lookup('localhost', -5, function(err, ip, family) {}); }, TypeError); iotjs-1.0/test/run_pass/test_events.js000066400000000000000000000141631312466455500202340ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var EventEmitter = require('events').EventEmitter; var assert = require('assert'); var emitter = new EventEmitter(); var eventCnt1 = 0; var eventCnt2 = 0; var eventCnt3 = 0; var onceCnt = 0; var eventSequence = ""; emitter.once('once', function() { onceCnt += 1; }); assert.equal(onceCnt, 0); emitter.emit('once'); assert.equal(onceCnt, 1); emitter.emit('once'); assert.equal(onceCnt, 1); { var emit_test = new EventEmitter(); emit_test._events = false; emit_test.emit(); } { var emit_test = new EventEmitter(); emit_test._events.error = false; emit_test.emit(null); } { var emit_test = new EventEmitter(); emit_test._events = false; assert.throws(function() { emit_test.addListener(null, null); }, TypeError); } { var emit_test = new EventEmitter(); emit_test._events = false; emit_test.addListener('event', function() { }); } { var emit_test = new EventEmitter(); assert.throws(function() { emit_test.once(null, null); }, TypeError); } { var emit_test = new EventEmitter(); assert.throws(function() { emit_test.removeListener(null, null); }, TypeError); } { var emit_test = new EventEmitter(); emit_test._events = false; emit_test.removeListener('rmtest', function() { }); } emitter.once('once2', function() { onceCnt += 1; assert.equal(arguments.length, 14); assert.equal(arguments[0], 0); assert.equal(arguments[1], 1); assert.equal(arguments[2], 2); assert.equal(arguments[3], 3); assert.equal(arguments[4], 4); assert.equal(arguments[5], 5); assert.equal(arguments[6], 6); assert.equal(arguments[7], 7); assert.equal(arguments[8], 8); assert.equal(arguments[9], 9); assert.equal(arguments[10], "a"); assert.equal(arguments[11], "b"); assert.equal(arguments[12], "c"); assert.equal(arguments[13].a, 123); }); assert.equal(onceCnt, 1); emitter.emit('once2', 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, "a", "b", "c", { a: 123}); assert.equal(onceCnt, 2); emitter.emit('once2', 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, "a", "b", "c", { a: 123}); assert.equal(onceCnt, 2); emitter.addListener('event', function() { eventCnt1 += 1; eventSequence += "1"; }); assert.equal(eventCnt1, 0); emitter.emit('event'); assert.equal(eventCnt1, 1); emitter.addListener('event', function() { eventCnt2 += 1; eventSequence += "2"; }); assert.equal(eventCnt2, 0); emitter.emit('event'); assert.equal(eventCnt1, 2); assert.equal(eventCnt2, 1); emitter.addListener('event', function() { eventCnt3 += 1; eventSequence += "3"; }); assert.equal(eventCnt3, 0); emitter.emit('event'); assert.equal(eventCnt1, 3); assert.equal(eventCnt2, 2); assert.equal(eventCnt3, 1); emitter.emit('event'); assert.equal(eventCnt1, 4); assert.equal(eventCnt2, 3); assert.equal(eventCnt3, 2); emitter.emit('no receiver'); assert.equal(eventCnt1, 4); assert.equal(eventCnt2, 3); assert.equal(eventCnt3, 2); emitter.addListener('args', function() { assert.equal(arguments.length, 14); assert.equal(arguments[0], 0); assert.equal(arguments[1], 1); assert.equal(arguments[2], 2); assert.equal(arguments[3], 3); assert.equal(arguments[4], 4); assert.equal(arguments[5], 5); assert.equal(arguments[6], 6); assert.equal(arguments[7], 7); assert.equal(arguments[8], 8); assert.equal(arguments[9], 9); assert.equal(arguments[10], "a"); assert.equal(arguments[11], "b"); assert.equal(arguments[12], "c"); assert.equal(arguments[13].a, 123); eventSequence += "4"; }); emitter.addListener('args', function() { assert.equal(arguments.length, 14); eventSequence += "5"; }) emitter.emit('args', 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, "a", "b", "c", { a: 123}); var listener1 = function() { eventSequence += '6'; }; emitter.addListener('rmTest', listener1); emitter.emit('rmTest'); emitter.removeListener('rmTest', function() {}); emitter.emit('rmTest'); emitter.removeListener('rmTest', listener1); emitter.emit('rmTest'); var listener2 = function() { eventSequence += '7'; }; emitter.addListener('rmTest', listener2); emitter.addListener('rmTest', listener2); emitter.emit('rmTest'); eventSequence += "|" emitter.removeListener('rmTest', listener2); emitter.emit('rmTest'); eventSequence += "|" emitter.removeListener('rmTest', listener2); emitter.emit('rmTest'); eventSequence += "|" var listener3 = function() { eventSequence += '8'; }; emitter.addListener('rmTest', listener3); emitter.addListener('rmTest', listener3); emitter.emit('rmTest'); eventSequence += "|"; emitter.removeAllListeners('rmTest'); emitter.emit('rmTest'); eventSequence += "|"; emitter.emit('event'); eventSequence += "|"; emitter.removeAllListeners(); emitter.emit('event'); eventSequence += "|"; assert.equal(eventSequence, "112123123456677|7||88||123||"); /* Test if an event listener for a once call can be removed. */ var removableListenerCnt = 0; function removableListener() { removableListenerCnt++; } emitter.once('onceRemove', removableListener); assert.equal(removableListenerCnt, 0); emitter.removeListener('onceRemove', removableListener); emitter.emit('onceRemove'); assert.equal(removableListenerCnt, 0, 'a listener for a "once" typed event should be removable'); /* * Test when the last listener is removed from an object, * the related property doesn't exist anymore. */ var listener1 = function() { }; emitter.addListener('event1', listener1); emitter.removeListener('event1', listener1); var res = emitter.emit('event1'); assert.equal(res, false); emitter.addListener('event2', listener1); emitter.addListener('event2', listener1); emitter.removeAllListeners('event2'); res = emitter.emit('event2'); assert.equal(res, false); iotjs-1.0/test/run_pass/test_events_assert_emit_error.js000066400000000000000000000014641312466455500240440ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var assert = require('assert'); var EventEmitter = require('events').EventEmitter; var ee = new EventEmitter(); assert.throws( function() { ee.emit('error'); }, Error); iotjs-1.0/test/run_pass/test_events_uncaught_error.js000066400000000000000000000020671312466455500233430ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var assert = require('assert'); var EventEmitter = require('events').EventEmitter; var uncaught_error = false; process.on('uncaughtException', function(err) { assert.equal(err.message, "Uncaught 'error' event"); uncaught_error = true; }); process.on('exit', function(code) { process.removeAllListeners('uncaughtException'); assert.equal(code, 0); assert(uncaught_error); }); var ee = new EventEmitter(); ee.emit('error'); iotjs-1.0/test/run_pass/test_fs_event.js000066400000000000000000000031621312466455500205360ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var fs = require('fs'); var assert = require('assert'); var srcFilePath = process.cwd() + "/resources/test1.txt"; var dstFilePath = process.cwd() + "/tmp/test_fs2.txt"; var data; function onWrite(err, written, buffer) { if (err) { throw err; } else { var fd = fs.openSync(dstFilePath, 'r'); var buffer = new Buffer(128); fs.readSync(fd, buffer, 0, buffer.length, 0); var result = 'TEST File Read & Write\n'; assert.equal(buffer.toString(), result); } } function onOpenForWrite(err, fd) { if (err) { throw err; } else { fs.write(fd, data, 0, data.length, onWrite); } } function onRead(err, bytesRead, buffer) { if (err) { throw err; } else { data = new Buffer(buffer.toString()); fs.open(dstFilePath, 'w', onOpenForWrite); } } function onOpenForRead(err, fd) { if (err) { throw err; } else { var buffer = new Buffer(128); fs.read(fd, buffer, 0, buffer.length, 0, onRead); } } fs.open(srcFilePath, 'r', onOpenForRead); iotjs-1.0/test/run_pass/test_fs_exists.js000066400000000000000000000026311312466455500207340ustar00rootroot00000000000000/* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var fs = require('fs'); var assert = require('assert'); { var filePath = process.cwd() + "/resources/tobeornottobe.txt"; fs.exists(filePath, function(exists) { assert.equal(exists, true); }); } { var filePath = ""; assert.doesNotThrow(function(){ fs.exists(filePath); }); } { var filePath = process.cwd() + "/resources/tobeornottobe.txt"; assert.doesNotThrow(function(){ fs.exists(filePath); }); } { var filePath = process.cwd() + "/resources/empty.txt"; fs.exists(filePath, function(exists) { assert.equal(exists, false); }); } { var filePath = ""; fs.exists(filePath, function(exists) { assert.equal(exists, false); }); } { var filePath = " "; fs.exists(filePath, function(exists) { assert.equal(exists, false); }); } iotjs-1.0/test/run_pass/test_fs_exists_sync.js000066400000000000000000000022211312466455500217630ustar00rootroot00000000000000/* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var fs = require('fs'); var assert = require('assert'); { var filePath = process.cwd() + "/resources/tobeornottobe.txt"; var result = fs.existsSync(filePath); assert.equal(result, true); } { var filePath = process.cwd() + "/resources/empty.txt"; var result = fs.existsSync(filePath); assert.equal(result, false); } { var filePath = ""; var result = fs.existsSync(filePath); assert.equal(result, false); } { var filePath = " "; var result = fs.existsSync(filePath); assert.equal(result, false); } iotjs-1.0/test/run_pass/test_fs_fstat.js000066400000000000000000000027641312466455500205450ustar00rootroot00000000000000/* Copyright 2017-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var fs = require('fs'); var assert = require('assert'); var testfile = process.cwd() + "/run_pass/test_fs_fstat.js"; var testdir = process.cwd() + "/resources"; var flags = "r"; // fstat - file fs.open(testfile, flags, function(err, fd) { if (err) { throw err; } fs.fstat(fd, function(err, stat) { if (err) { throw err; } assert.equal(stat.isFile(), true); assert.equal(stat.isDirectory(), false); fs.close(fd, function(err) { if (err) { throw err; } }); }); }); // fstat - directory fs.open(testdir, flags, function(err, fd) { if (err) { throw err; } fs.fstat(fd, function(err, stat) { if (err) { throw err; } assert.equal(stat.isFile(), false); assert.equal(stat.isDirectory(), true); fs.close(fd, function(err) { if (err) { throw err; } }); }); }); iotjs-1.0/test/run_pass/test_fs_fstat_sync.js000066400000000000000000000024151312466455500215720ustar00rootroot00000000000000/* Copyright 2017-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var fs = require('fs'); var assert = require('assert'); var testfile = process.cwd() + "/run_pass/test_fs_fstat_sync.js"; var testdir = process.cwd() + "/resources"; var flags = "r"; // fstatSync - file try { var fd = fs.openSync(testfile, flags); var stat = fs.fstatSync(fd); assert.equal(stat.isFile(), true); assert.equal(stat.isDirectory(), false); fs.closeSync(fd); } catch (err) { throw err; } // fstatSync - directory try { var fd = fs.openSync(testdir, flags); var stat = fs.fstatSync(fd); assert.equal(stat.isFile(), false); assert.equal(stat.isDirectory(), true); fs.closeSync(fd); } catch (err) { throw err; } iotjs-1.0/test/run_pass/test_fs_mkdir_rmdir.js000066400000000000000000000047461312466455500217310ustar00rootroot00000000000000/* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var fs = require('fs'); var assert = require('assert'); function unlink(path) { try { fs.rmdirSync(path); } catch (e) { } assert.equal(fs.existsSync(path), false); } { var root = process.cwd() + "/resources/test_dir"; var sub1 = process.cwd() + "/resources/test_dir/file1"; var sub2 = process.cwd() + "/resources/test_dir/file2"; unlink(sub1); unlink(sub2); unlink(root); fs.mkdir(root, function(err) { assert.equal(err, null); assert.equal(fs.existsSync(root), true); assert.equal(fs.mkdirSync(sub1), undefined); assert.equal(fs.mkdirSync(sub2), undefined); assert.equal(fs.existsSync(sub1), true); assert.equal(fs.existsSync(sub2), true); unlink(sub1); unlink(sub2); fs.rmdir(root, function() { assert.equal(fs.existsSync(root), false); }); var root2 = process.cwd() + "/resources/test_dir2"; fs.mkdir(root2, 777, function(err) { assert.equal(err, null); assert.equal(fs.existsSync(root2), true); fs.rmdir(root2, function(){ assert.equal(fs.existsSync(root2), false); }); // Run read-only directory test only on linux // NuttX does not support read-only attribute. if (process.platform === 'linux') { // Try to create a folder in a read-only directory. fs.mkdir(root, '0444', function(err) { assert.equal(fs.existsSync(root), true); var dirname = root + "/permission_test"; try { fs.mkdirSync(dirname); assert.assert(false); } catch (e) { assert.equal(e instanceof Error, true); assert.equal(e instanceof assert.AssertionError, false); } assert.equal(fs.existsSync(dirname), false); fs.rmdir(root, function() { assert.equal(fs.existsSync(root), false); }); }); } }); }); } iotjs-1.0/test/run_pass/test_fs_open_close.js000066400000000000000000000070641312466455500215500ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var fs = require('fs'); var assert = require('assert'); var fileName = process.cwd() + "/resources/greeting.txt"; // test sync open & close. // test normal sequence. try { var fd = fs.openSync(fileName, 'r'); fs.closeSync(fd); } catch (err) { throw err; } // test trying to open not exist file - expecting exception. try { var fd = fs.openSync('not_exist_file', 'r'); assert.fail('none', 'exception'); } catch (err) { } // test trying to close with bad fd - expecting exception. try { fs.closeSync(-1); assert.fail('none', 'exception'); } catch (err) { } // test async open & close. // test normal sequence. var fs_async_normal_ok = false; fs.open(fileName, 'r', function(err, fd) { if (err) { throw err; } else { fs.close(fd, function(err) { if (err) { throw err; } else { fs_async_normal_ok = true; } }); } }); // test not exist file - expecting exception. var fs_async_open_not_exist_ok = false; fs.open('not_exist_file', 'r', function(err, fd) { if (err) { fs_async_open_not_exist_ok = true; } else { assert.fail('none', 'exception'); } }); // test trying to close with bad fd - expecting exception. var fs_async_close_bad_fd_ok = false; fs.close(-1, function(err) { if (err) { fs_async_close_bad_fd_ok = true; } else { assert.fail('none', 'exception'); } }); var buffer = new Buffer(10); // expect length out of bound assert.throws(function () { fs.readSync(5, buffer, 0, 20); }, RangeError); // expect offset out of bound assert.throws(function () { fs.readSync(5, buffer, -1, 20); }, RangeError); var fs_async_normal_ok2 = false; fs.open(fileName, 'r', '4' ,function(err, fd) { if (err) { throw err; } else { fs.close(fd, function(err) { if (err) { throw err; } else { fs_async_normal_ok2 = true; } }); } }); process.on('exit', function() { assert.equal(fs_async_normal_ok, true); assert.equal(fs_async_normal_ok2, true); assert.equal(fs_async_open_not_exist_ok, true); assert.equal(fs_async_close_bad_fd_ok, true); }); assert.throws (function() { var fd = fs.openSync(null, 123); }, TypeError); assert.throws (function() { var fd = fs.openSync(process.cwd() + '/run_pass/test_fs_stat.js', 'k'); }, TypeError); assert.throws (function() { var fd = fs.openSync(process.cwd() + '/resources/test2.txt', null); }, TypeError); ('rs sr r+ rs+ sr+ a a+') .split(' ').forEach(function (flag){ assert.doesNotThrow(function (){ var fd = fs.openSync(process.cwd() + '/resources/test2.txt', flag); fs.closeSync(fd); }, 'file could not be opened with ' + flag); }); ('wx xw w+ wx+ xw+ ax+ xa+ ax xa') .split(' ').forEach(function (flag){ assert.doesNotThrow(function(){ var file = process.cwd() + '/resources/TEMP' + flag + '.txt'; var fd = fs.openSync(file, flag); fs.unlinkSync(file); fs.closeSync(fd); }, 'file could not be opened with ' + flag); }); iotjs-1.0/test/run_pass/test_fs_open_read.js000066400000000000000000000033651312466455500213560ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var fs = require('fs'); var assert = require('assert'); var fileName = process.cwd() + "/resources/greeting.txt"; var expectedContents = "Hello IoT.js!!"; var flags = "r"; var mode = 438; // test async open & read fs.open(fileName, flags, mode, function(err, fd) { if (err) { throw err; } else { var buffer = new Buffer(64); fs.read(fd, buffer, 0, buffer.length, 0, function(err, bytesRead, buffer) { if (err) { throw err; } else { assert.equal(buffer.toString(), expectedContents); } }); } }); // error test assert.throws( function() { fs.openSync("non_exist_file", flags, mode); }, Error ); // test the position argument of fs.read() fs.open(fileName, flags, function(err, fd) { if (err) { throw err; } var buffer = new Buffer(64); fs.read(fd, buffer, 0, 7, null, function(err, bytesRead, buffer) { if (err) { throw err; } fs.read(fd, buffer, 7, 7, null, function(err, bytesRead, buffer) { if (err) { throw err; } assert.equal(buffer.toString(), expectedContents); fs.closeSync(fd); }); }); }); iotjs-1.0/test/run_pass/test_fs_open_read_sync_1.js000066400000000000000000000030771312466455500226320ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var fs = require('fs'); var assert = require('assert'); var srcFilePath = process.cwd() + "/resources/test1.txt"; var dstFilePath = process.cwd() + "/tmp/test_fs1.txt"; try { var fd1 = fs.openSync(srcFilePath, 'r'); var buffer = new Buffer(128); var bytes1 = fs.readSync(fd1, buffer, 0, buffer.length, 0); fs.closeSync(fd1); var fd2 = fs.openSync(dstFilePath, 'w'); var bytes2 = fs.writeSync(fd2, buffer, 0, bytes1, 0); var bytes4 = fs.writeSync(fd2, buffer, 0, bytes1, null); var bytes5 = fs.writeSync(fd2, buffer, 0, bytes1, undefined); fs.closeSync(fd2); assert.equal(bytes1, bytes2); assert.equal(bytes1, bytes4); assert.equal(bytes1, bytes5); var fd3 = fs.openSync(srcFilePath, 'r'); var bytes3 = fs.readSync(fd3, buffer, 0, buffer.length, 0); fs.closeSync(fd3); assert.equal(bytes1, bytes3); var result = 'TEST File Read & Write\n'; assert.equal(buffer.toString(), result); } catch (err) { throw err; } iotjs-1.0/test/run_pass/test_fs_open_read_sync_2.js000066400000000000000000000020611312466455500226230ustar00rootroot00000000000000/* Copyright 2017-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var fs = require('fs'); var assert = require('assert'); var fileName = process.cwd() + "/resources/greeting.txt"; var expectedContents = "Hello IoT.js!!"; var flags = "r"; var mode = 438; // test sync open & read try { var fd = fs.openSync(fileName, flags, mode); var buffer = new Buffer(64); fs.readSync(fd, buffer, 0, buffer.length, 0); assert.equal(buffer.toString(), expectedContents); } catch (err) { throw err; } iotjs-1.0/test/run_pass/test_fs_open_read_sync_3.js000066400000000000000000000021761312466455500226330ustar00rootroot00000000000000/* Copyright 2017-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var fs = require('fs'); var assert = require('assert'); var fileName = process.cwd() + "/resources/greeting.txt"; var expectedContents = "Hello IoT.js!!"; var flags = "r"; // test the position argument of fs.readSync() try { var buffer = new Buffer(64); var fd = fs.openSync(fileName, flags); var bytes1 = fs.readSync(fd, buffer, 0, 7, null); var bytes2 = fs.readSync(fd, buffer, 7, 7, null); assert.equal(buffer.toString(), expectedContents); fs.closeSync(fd); } catch (err) { throw err; } iotjs-1.0/test/run_pass/test_fs_readdir.js000066400000000000000000000023301312466455500210230ustar00rootroot00000000000000/* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var fs = require('fs'); var assert = require('assert'); var path = process.cwd() + '/resources/readdir' var ans = 'DO_NOT_MODIFY_THIS_FOLDER\n'+ 'This_is_a_directory\n'+ 'This_is_another_directory\n'+ 'regular.txt\n'; var res; var items; res = ""; items = fs.readdirSync(path); items.sort(); for (i = 0; i < items.length; i++) res += items[i] + '\n'; assert.equal(res, ans); res = ""; fs.readdir(path, function(err, items) { assert.equal(err, null); items.sort(); for (i = 0; i < items.length; i++) res += items[i] + '\n'; assert.equal(res, ans); }); iotjs-1.0/test/run_pass/test_fs_readfile.js000066400000000000000000000052241312466455500211710ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var fs = require('fs'); var assert = require('assert'); var filePath = process.cwd() + "/resources/tobeornottobe.txt"; fs.readFile(filePath, function(err, data) { assert.equal(err, null); var result = "To be, or not to be, that is the Question:\n" + "Whether ’tis Nobler in the mind to Å¿uffer\n" + "The Slings and Arrows of outragious Fortune,\n" + "Or to take Armes against a Sea of troubles,\n" + "And by opposing end them: to dye, to Å¿leepe\n" + "No more; and by a sleep, to say we end\n" + "The Heart-ake, and the thouÅ¿and Naturall Å¿hockes\n" + 'That Flesh is there too? "Tis a consummation\n' + "Deuoutly to be wiÅ¿h'd. To dye to sleepe,\n" + "To sleep, perchance to Dream; I, there's the rub,\n" + "For in that sleep of death, what dreams may come,\n" + "When we haue Å¿hufflel’d off this mortall coile,\n" + "MuÅ¿t giue us pause. There's the respect\n" + "That makes Calamity of long life:\n" + "For who would beare the Whips and Scornes of time,\n" + "The Oppreſſors wrong, the poore mans Contumely,\n" + "The pangs of diÅ¿priz’d Loue, the Lawes delay,\n" + "The inÅ¿olence of Office, and the Spurnes\n" + "That patient merit of the vnworthy takes,\n" + "When he himÅ¿elfe might his Quietus make\n" + "With a bare Bodkin? Who would theÅ¿e Fardles beare\n" + "To grunt and Å¿weat vnder a weary life,\n" + "But that the dread of Å¿omething after death,\n" + "The vndiÅ¿couered Countrey, from whoÅ¿e Borne\n" + "No Traueller returnes, Puzels the will,\n" + "And makes vs rather beare those illes we haue,\n" + "Then flye to others that we know not of.\n" + "Thus ConÅ¿cience does make Cowards of vs all,\n" + "And thus the Natiue hew of Resolution\n" + "Is Å¿icklied o’re, with the pale caÅ¿t of Thought,\n" + "And enterprizes of great pith and moment,\n" + "With this regard their Currants turne away,\n" + "And looÅ¿e the name of Action. Soft you now,\n" + "The faire Ophelia? Nimph, in thy Orizons\n" + "Be all my Å¿innes remembred." assert.equal(data, result); }); iotjs-1.0/test/run_pass/test_fs_readfile_sync.js000066400000000000000000000051541312466455500222270ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var fs = require('fs'); var assert = require('assert'); var filePath = process.cwd() + "/resources/tobeornottobe.txt"; var data = fs.readFileSync(filePath); var result = "To be, or not to be, that is the Question:\n" + "Whether ’tis Nobler in the mind to Å¿uffer\n" + "The Slings and Arrows of outragious Fortune,\n" + "Or to take Armes against a Sea of troubles,\n" + "And by opposing end them: to dye, to Å¿leepe\n" + "No more; and by a sleep, to say we end\n" + "The Heart-ake, and the thouÅ¿and Naturall Å¿hockes\n" + 'That Flesh is there too? "Tis a consummation\n' + "Deuoutly to be wiÅ¿h'd. To dye to sleepe,\n" + "To sleep, perchance to Dream; I, there's the rub,\n" + "For in that sleep of death, what dreams may come,\n" + "When we haue Å¿hufflel’d off this mortall coile,\n" + "MuÅ¿t giue us pause. There's the respect\n" + "That makes Calamity of long life:\n" + "For who would beare the Whips and Scornes of time,\n" + "The Oppreſſors wrong, the poore mans Contumely,\n" + "The pangs of diÅ¿priz’d Loue, the Lawes delay,\n" + "The inÅ¿olence of Office, and the Spurnes\n" + "That patient merit of the vnworthy takes,\n" + "When he himÅ¿elfe might his Quietus make\n" + "With a bare Bodkin? Who would theÅ¿e Fardles beare\n" + "To grunt and Å¿weat vnder a weary life,\n" + "But that the dread of Å¿omething after death,\n" + "The vndiÅ¿couered Countrey, from whoÅ¿e Borne\n" + "No Traueller returnes, Puzels the will,\n" + "And makes vs rather beare those illes we haue,\n" + "Then flye to others that we know not of.\n" + "Thus ConÅ¿cience does make Cowards of vs all,\n" + "And thus the Natiue hew of Resolution\n" + "Is Å¿icklied o’re, with the pale caÅ¿t of Thought,\n" + "And enterprizes of great pith and moment,\n" + "With this regard their Currants turne away,\n" + "And looÅ¿e the name of Action. Soft you now,\n" + "The faire Ophelia? Nimph, in thy Orizons\n" + "Be all my Å¿innes remembred." assert.equal(data, result); iotjs-1.0/test/run_pass/test_fs_rename.js000066400000000000000000000021101312466455500206540ustar00rootroot00000000000000/* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* @STDOUT=Pass */ var fs = require('fs'); var assert = require('assert'); var file1 = process.cwd() + "/resources/rename.txt"; var file2 = process.cwd() + "/resources/rename.txt.async"; fs.rename(file1, file2, function(err) { assert.equal(err, null); assert.equal(fs.existsSync(file1), false); assert.equal(fs.existsSync(file2), true); fs.rename(file2, file1, function(err) { assert.equal(err, null); console.log("Pass"); }); }); iotjs-1.0/test/run_pass/test_fs_rename_sync.js000066400000000000000000000016711312466455500217230ustar00rootroot00000000000000/* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var fs = require('fs'); var assert = require('assert'); var file1 = process.cwd() + "/resources/rename.txt"; var file2 = process.cwd() + "/resources/rename.txt.sync"; fs.renameSync(file1, file2); assert.equal(fs.existsSync(file1), false); assert.equal(fs.existsSync(file2), true); fs.renameSync(file2, file1); iotjs-1.0/test/run_pass/test_fs_stat.js000066400000000000000000000032061312466455500203670ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var fs = require('fs'); var assert = require('assert'); var stats1 = fs.statSync(process.cwd() + '/run_pass/test_fs_stat.js'); assert.equal(stats1.isFile(), true); assert.equal(stats1.isDirectory(), false); fs.stat(process.cwd() + '/run_pass/test_fs_stat.js', function(err, stats) { if (!err) { assert.equal(stats.isFile(), true); assert.equal(stats.isDirectory(), false); } else { throw err; } }); var stats2 = fs.statSync(process.cwd() + '/resources'); assert.equal(stats2.isDirectory(), true); assert.equal(stats2.isFile(), false); fs.stat(process.cwd() + '/resources', function(err, stats) { if (!err) { assert.equal(stats.isDirectory(), true); assert.equal(stats.isFile(), false); } else { throw err } }); // fs.statSync throws an exception for a non-existing file. try { var stats3 = fs.statSync(process.cwd() + '/non_existing.js'); assert.assert(false); } catch(e) { assert.equal(e instanceof Error, true); assert.equal(e instanceof assert.AssertionError, false); } iotjs-1.0/test/run_pass/test_fs_write.js000066400000000000000000000031231312466455500205440ustar00rootroot00000000000000/* Copyright 2017-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var fs = require('fs'); var assert = require('assert'); var dstFilePath = process.cwd() + "/tmp/test_fs3.txt"; var buff1 = new Buffer("IoT"); var buff2 = new Buffer(".js"); fs.open(dstFilePath, 'w+', function(err, fd) { if (err) { throw err; } // Test the position argument of fs.write(). fs.write(fd, buff1, 0, buff1.length, undefined, function(err, bytes, buffer) { if (err) { throw err; } fs.write(fd, buff2, 0, buff2.length, null, function(err, bytes, buffer) { if (err) { throw err; } // Check the result. var result = new Buffer(6); fs.read(fd, result, 0, result.length, 0, function(err, bytes, buffer) { if (err) { throw err; } var init_buffers = Buffer.concat([buff1, buff2]); assert.assert(result.equals(init_buffers)); fs.close(fd, function(err) { if (err) { throw err; } }); }); }); }); }); iotjs-1.0/test/run_pass/test_fs_writefile.js000066400000000000000000000032041312466455500214040ustar00rootroot00000000000000/* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* @STDOUT=Pass */ var fs = require('fs'); var assert = require('assert'); var file = process.cwd() + '/resources/test'; var buff1 = new Buffer('test string1'); var str = 'test string2'; var num = 1; fs.writeFile(file, buff1, function (err) { assert.equal(err, null); fs.readFile(file, function (err, buff2) { assert.equal(err, null); assert.equal(buff2.equals(buff1), true); fs.writeFile(file, str, function (err) { assert.equal(err, null); fs.readFile(file, function (err, buff2) { assert.equal(err, null); assert.equal(str.valueOf(), buff2.toString('utf8')); fs.writeFile(file, num, function (err) { assert.equal(err, null); fs.readFile(file, function (err, buff2) { assert.equal(err, null); assert.equal(num, parseInt(buff2.toString('utf8'), 10)); console.log('Pass'); fs.unlinkSync(file); }); }); }); }); }); }); iotjs-1.0/test/run_pass/test_fs_writefile_sync.js000066400000000000000000000023371312466455500224460ustar00rootroot00000000000000 /* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* @STDOUT=Pass */ var fs = require('fs'); var assert = require('assert'); var file = process.cwd() + '/resources/test'; var buff1 = new Buffer('test string1'); var buff2 = null; var str = 'test string2'; var num = 1; fs.writeFileSync(file, buff1); buff2 = fs.readFileSync(file); assert.equal(buff2.equals(buff1), true); fs.writeFileSync(file, str); buff2 = fs.readFileSync(file); assert.equal(str.valueOf(), buff2.toString('utf8')); fs.writeFileSync(file, num); buff2 = fs.readFileSync(file); assert.equal(num, parseInt(buff2.toString('utf8'), 10)); console.log('Pass'); fs.unlinkSync(file); iotjs-1.0/test/run_pass/test_fs_writefile_unlink.js000066400000000000000000000026521312466455500227720ustar00rootroot00000000000000/* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* @STDOUT=Pass */ var fs = require('fs'); var assert = require('assert'); var file1 = process.cwd() + "/resources/tobeornottobe.txt"; var file2 = process.cwd() + "/resources/tobeornottobe_async.txt"; fs.readFile(file1, function(err, buf1) { assert.equal(err, null); fs.writeFile(file2, buf1, function(err) { assert.equal(err, null); fs.exists(file2, function(exists) { assert.equal(exists, true); fs.readFile(file1, function(err, buf2) { assert.equal(err, null); assert.equal(buf1.toString(), buf2.toString()); fs.unlink(file2, function(err) { assert.equal(err, null); fs.exists(file2, function(exists) { assert.equal(exists, false); console.log("Pass"); }); }); }); }); }); }); iotjs-1.0/test/run_pass/test_fs_writefile_unlink_sync.js000066400000000000000000000023411312466455500240210ustar00rootroot00000000000000/* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var fs = require('fs'); var assert = require('assert'); var file1 = process.cwd() + "/resources/tobeornottobe.txt"; var file2 = process.cwd() + "/resources/tobeornottobe_sync.txt"; /* make a new file2 from file1 */ var buf1 = fs.readFileSync(file1); fs.writeFileSync(file2, buf1); /* Does file2 exists ? */ var result = fs.existsSync(file2); assert.equal(result, true); /* Is file2 equal to file1 */ var buf2 = fs.readFileSync(file2); assert(buf1.toString(), buf2.toString()); /* Remove file2 */ fs.unlinkSync(file2); /* Is file2 removed? */ result = fs.existsSync(file2); assert.equal(result, false); iotjs-1.0/test/run_pass/test_gpio_event.js000066400000000000000000000023051312466455500210620ustar00rootroot00000000000000/* Copyright 2017-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var Gpio = require('gpio'); var gpio = new Gpio(); var testGpioInfo = [ { pin: 13, edge: gpio.EDGE.RISING }, { pin: 19, edge: gpio.EDGE.FALLING }, { pin: 26, edge: gpio.EDGE.BOTH } ]; testGpioInfo.forEach(function(info) { var switchGpio = gpio.open({ pin: info.pin, edge: info.edge, direction: gpio.DIRECTION.IN }, function() { switchGpio.on('change', function() { console.log('pin:', info.pin, ', current value:', this.readSync()); }); }); }); setTimeout(function(){ console.log('finish test'); }, 10000); iotjs-1.0/test/run_pass/test_gpio_input.js000066400000000000000000000037541312466455500211110ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var assert = require('assert'); var Gpio = require('gpio'); var gpio = new Gpio(); var ledGpio = null, switchGpio = null; var ledPin, switchPin, ledMode; var SWITCH_ON = false, LED_ON = true, LED_OFF = false; var loopCnt = 0; if (process.platform === 'linux') { ledPin = 20; switchPin = 13; ledMode = gpio.MODE.NONE; } else if (process.platform === 'nuttx') { var pin = require('stm32f4dis').pin; ledPin = pin.PA10; switchPin = pin.PA15; ledMode = gpio.MODE.PUSHPULL; } else if(process.platform === 'tizenrt') { ledPin = 41; switchPin = 39; ledMode = gpio.MODE.NONE; } else { assert.fail(); } ledGpio = gpio.open({ pin: ledPin, direction: gpio.DIRECTION.OUT, mode: ledMode }, function() { this.writeSync(LED_OFF); }); switchGpio = gpio.open({ pin: switchPin, direction: gpio.DIRECTION.IN }); var loop = setInterval(function() { if (!ledGpio || !switchGpio) { return; } if ((++loopCnt) == 10) { clearInterval(loop); ledGpio.closeSync(); switchGpio.closeSync(); ledGpio = switchGpio = null; console.log('finish test'); return; } switchGpio.read(function(err, value) { if (err) { clearInterval(loop); assert.fail(); } if (value === SWITCH_ON) { console.log('led on'); ledGpio.writeSync(LED_ON); } else { ledGpio.writeSync(LED_OFF); } }); }, 500); iotjs-1.0/test/run_pass/test_gpio_output.js000066400000000000000000000043351312466455500213060ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var assert = require('assert'); var Gpio = require('gpio'); var gpio = new Gpio(); var LED_ON = true, LED_OFF = false; var pin, mode; var gpio20; if (process.platform === 'linux') { pin = 20; mode = gpio.MODE.NONE; } else if (process.platform === 'nuttx') { pin = require('stm32f4dis').pin.PA10; mode = gpio.MODE.PUSHPULL; } else if(process.platform === 'tizenrt') { pin = 41; mode = gpio.MODE.NONE; } else { assert.fail(); } test1(); gpio20 = gpio.open({ pin: pin, direction: gpio.DIRECTION.OUT, mode: mode }, test2); function test1() { assert.notEqual(gpio.DIRECTION.IN, undefined); assert.notEqual(gpio.DIRECTION.OUT, undefined); assert.notEqual(gpio.MODE.NONE, undefined); if (process.platform === 'nuttx') { assert.notEqual(gpio.MODE.PULLUP, undefined); assert.notEqual(gpio.MODE.PULLDOWN, undefined); assert.notEqual(gpio.MODE.FLOAT, undefined); assert.notEqual(gpio.MODE.PUSHPULL, undefined); assert.notEqual(gpio.MODE.OPENDRAIN, undefined); } } // turn on LED for 3000ms function test2(err) { assert.equal(err, null); gpio20.write(LED_ON, function(writeErr) { assert.equal(writeErr, null); console.log('gpio write'); gpio20.read(function(readErr, value) { assert.equal(readErr, null); console.log('gpio read:', value); assert.equal(LED_ON, value); setTimeout(function() { gpio20.writeSync(LED_OFF); var value = gpio20.readSync(); console.log('gpio read:', value); assert.equal(LED_OFF, value); gpio20.close(); console.log('finish test'); }, 3000); }); }); } iotjs-1.0/test/run_pass/test_i2c.js000066400000000000000000000026671312466455500174130ustar00rootroot00000000000000/* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* This test is based on Raspberry Pi with GY-30 Sensor. */ var assert = require('assert'); var I2C = require('i2c'); var i2c = new I2C(); var configuration = {}; configuration.address = 0x23; if (process.platform === 'linux') { configuration.device = '/dev/i2c-1'; } else if (process.platform === 'nuttx') { configuration.device = 1; } else { assert.fail(); } var wire = i2c.open(configuration, function(err) { if (err) { throw err; } wire.write([0x10], function(err) { assert.equal(err, null); console.log('write done'); wire.read(2, function(err, res) { assert.equal(err, null); assert.equal(res.length, 2, 'I2C read failed.(length is not equal)'); console.log('read result: '+res[0]+', '+res[1]); wire.close(); console.log('test ok'); }); }); }); iotjs-1.0/test/run_pass/test_iotjs_promise.js000066400000000000000000000021651312466455500216150ustar00rootroot00000000000000/* Copyright 2017-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var assert = require('assert'); var fulfill_ret; var p = new Promise(function(resolve, reject) { // mimic asynchronous operation via setTimeout setTimeout(function() { resolve("Resolved") }, 100);; }); p.then(function (msg) { // Promise does not like throwing error in fulfill handler // So just set the message in global variable. fulfill_ret = msg; }); // If Promise's fulfill worked well, assertion must be valid. setTimeout(function() { assert.equal(fulfill_ret, "Resolved"); }, 200); iotjs-1.0/test/run_pass/test_module_cache.js000066400000000000000000000015321312466455500213340ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var assert = require('assert'); var module_cache = require('run_pass/require1/module_cache.js'); module_cache.i = 100; module_cache = require('run_pass/require1/module_cache.js'); assert.equal(module_cache.i, 100); iotjs-1.0/test/run_pass/test_module_require.js000066400000000000000000000024551312466455500217520ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var assert = require('assert'); var dir = process.cwd() + "/run_pass/require1/"; // Load a JS file. var x = require(dir + "require_add"); assert.equal(x.add(1,4), 5); // Load a package. var pkg1 = require(dir + "test_pkg"); assert.equal(pkg1.add(22, 44), 66); assert.equal(pkg1.multi(22, 44), 968); assert.equal(pkg1.add2(22, 44), 66); var pkg2 = require(dir + "test_index"); assert.equal(pkg2.add(22, 44), 66); assert.equal(pkg2.multi(22, 44), 968); assert.equal(pkg2.add2(22, 44), 66); // Load invalid modules. assert.throws(function() { var test3 = require('run_pass/require1/babel-template'); }, Error); assert.throws(function() { var test4 = require('tmp'); }, Error); iotjs-1.0/test/run_pass/test_net_1.js000066400000000000000000000023511312466455500177320ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var net = require('net'); var assert = require('assert'); var server = net.createServer(); var port = 22701; server.listen(port, 5); server.on('connection', function(socket) { socket.on('data', function(data) { socket.end('Hello IoT.js'); }); socket.on('close', function() { server.close(); }); }); var socket = new net.Socket(); var msg = ""; socket.connect(port, "127.0.0.1"); socket.write("Hello IoT.js"); socket.on('data', function(data) { msg += data; }); socket.on('end', function() { socket.end(); }); process.on('exit', function(code) { assert.equal(msg, "Hello IoT.js"); }); iotjs-1.0/test/run_pass/test_net_10.js000066400000000000000000000025071312466455500200150ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var net = require('net'); var assert = require('assert'); var server = net.createServer(); var port = 22709; var timedout = false; var connected = false; server.listen(port, 1); server.on('connection', function(newSocket) { connected = true; console.log("Connected!"); newSocket.on('error', function() { assert.fail(); }); newSocket.setTimeout(500); newSocket.on('timeout', function() { console.log("Timeout"); timedout = true; newSocket.destroy(); socket.destroy(); server.close(); }); }); var socket = net.createConnection(port); socket.on('error', function() { assert.fail(); }); process.on('exit', function() { assert(timedout); assert(connected); }); iotjs-1.0/test/run_pass/test_net_2.js000066400000000000000000000023751312466455500177410ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var net = require('net'); var assert = require('assert'); var port = 22702; var server = net.createServer({ allowHalfOpen: true }); server.listen(port, 5); server.on('connection', function(socket) { var msg = ''; socket.on('data', function(data) { msg += data; }); socket.on('end', function() { socket.end(msg); server.close(); }); }); var socket = new net.Socket(); var echo_msg = ''; socket.connect(port, '127.0.0.1', function() { socket.end('Hello IoT.js'); }); socket.on('data', function(data) { echo_msg += data; }); socket.on('end', function() { assert.equal(echo_msg, "Hello IoT.js"); }); iotjs-1.0/test/run_pass/test_net_3.js000066400000000000000000000036441312466455500177420ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var net = require('net'); var assert = require('assert'); var port = 22703; var limit = 200; var server = net.createServer(); server.listen({ port: port }); server.on('connection', function(socket) { var i = 0; var writing = function() { var ok; do { ok = socket.write("" + (i % 10)); if (++i == limit) { socket.end(); ok = false; } } while (ok); }; socket.on('drain', writing); writing(); }); var msg1 = ''; var socket1 = net.createConnection(port); socket1.on('data', function(data) { msg1 += data; }); var msg2 = ''; var socket2 = net.createConnection({port: port}); socket2.on('data', function(data) { msg2 += data; }); var msg3 = ''; var socket3 = net.createConnection({port: port, host: '127.0.0.1'}); socket3.on('data', function(data) { msg3 += data; }); var msg4 = ''; var connectListenerCheck = false; var socket4 = net.createConnection({port: port}, function() { connectListenerCheck = true; }); socket4.on('data', function(data) { msg4 += data; }); socket4.on('end', function() { server.close(); }); process.on('exit', function(code) { assert.equal(msg1.length, limit); assert.equal(msg2.length, limit); assert.equal(msg3.length, limit); assert.equal(msg4.length, limit); assert(connectListenerCheck); }); iotjs-1.0/test/run_pass/test_net_4.js000066400000000000000000000025701312466455500177400ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var net = require('net'); var assert = require('assert'); var timers = require('timers'); var server = net.createServer(); var port = 22704; var timeout = 1000; var writeat = 2000; server.listen(port, 5); server.on('connection', function(socket) { socket.setTimeout(timeout, function() { socket.end(); }); socket.on('data', function(data) { socket.end(); }); socket.on('close', function() { server.close(); }); }); var socket = new net.Socket(); socket.connect(port, "127.0.0.1"); socket.on('connect', function() { timers.setTimeout(function() { assert.throws( function() { socket.write('Hello IoT.js'); }, Error); }, writeat); }); process.on('exit', function(code) { assert.equal(code, 0); }); iotjs-1.0/test/run_pass/test_net_5.js000066400000000000000000000026431312466455500177420ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var net = require('net'); var assert = require('assert'); var timers = require('timers'); var server = net.createServer(); var port = 22705; var timeout = 2000; var writeat = 1000; var msg = ''; server.listen(port, 5); server.on('connection', function(socket) { socket.setTimeout(timeout, function() { assert.equal(msg, 'Hello IoT.js'); socket.end(); }); socket.on('data', function(data) { msg = data; }); socket.on('close', function() { server.close(); }); }); var socket = new net.Socket(); socket.connect(port, "127.0.0.1"); socket.on('end', function() { socket.end(); }); socket.on('connect', function() { timers.setTimeout(function() { socket.write('Hello IoT.js'); }, writeat); }); process.on('exit', function(code) { assert.equal(code, 0); }); iotjs-1.0/test/run_pass/test_net_6.js000066400000000000000000000031561312466455500177430ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var net = require('net'); var assert = require('assert'); var timers = require('timers'); var server = net.createServer(); var port = 22706; server.listen(port, 5); server.on('connection', function(socket) { socket.on('data', function(data) { msg += data; socket.end(); }); socket.on('close', function() { server.close(); }); // as soon as connection established, pause the socket socket.pause(); // resume after 2 secs timers.setTimeout(function() { socket.resume(); }, 2000); }); var socket = new net.Socket(); var msg = ""; socket.connect(port, "127.0.0.1"); socket.on('connect', function() { // client writes "1" first, but server is paused for 2 secs // server gets "1" after 2 secs socket.write("1"); // "2" is appended to msg before "1" timers.setTimeout(function() { msg += "2"; }, 1000); }); socket.on('end', function() { socket.end(); }); process.on('exit', function(code) { assert.equal(code, 0); assert.equal(msg, "21"); }); iotjs-1.0/test/run_pass/test_net_7.js000066400000000000000000000032041312466455500177360ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var net = require('net'); var assert = require('assert'); var timers = require('timers'); var port = 22707; var count = 40; var check = []; function serverListen() { var server = net.createServer({ allowHalfOpen: true }); var cnt = 0; server.listen(port); server.on('connection', function(socket) { var msg = ''; socket.on('data', function(data) { msg += data; }); socket.on('end', function() { socket.end(msg); cnt++; if (cnt == count) { server.close(); } }); }); } serverListen(); for (var i = 0; i < count; ++i) { (function(i) { var socket = new net.Socket(); var msg = ""; socket.connect(port, "localhost"); socket.on('connect', function() { socket.end(i.toString()); }); socket.on('data', function(data) { check[data] = true; }); })(i); } process.on('exit', function(code) { assert.equal(code, 0); for (var i = 0; i < count; ++i) { if (!check[i]) { assert.fail(); } } }); iotjs-1.0/test/run_pass/test_net_8.js000066400000000000000000000030631312466455500177420ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var net = require('net'); var assert = require('assert'); var timers = require('timers'); var port = 22708; var server = net.createServer(); server.listen(port, 5); server.on('close', function() { assert.equal(msg, '12'); }); server.on('connection', function(socket) { socket.on('data', function(data) { socket.end(data); }); socket.on('close', function() { server.close(); }); }); var sock1 = new net.Socket(); var sock2 = new net.Socket(); var msg = ''; sock1.connect(port, 'localhost'); sock2.connect(port, 'localhost'); sock1.on('data', function(data) { msg += data; }); sock1.on('end', function() { sock1.end(); }); sock2.on('data', function(data) { msg += data; }); sock2.on('end', function() { sock2.end(); }); timers.setTimeout(function() { sock1.write('1'); }, 1000); timers.setTimeout(function() { sock2.write('2'); }, 2000); process.on('exit', function(code) { assert.equal(code, 0); }); iotjs-1.0/test/run_pass/test_net_9.js000066400000000000000000000024501312466455500177420ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var net = require('net'); var assert = require('assert'); var server = net.createServer(); var port = 22709; server.listen(port, 5); server.on('close', function() { }); server.on('connection', function(socket) { socket.on('data', function(data) { socket.end('Hello IoT.js'); }); socket.on('close', function() { server.close(); }); }); var socket = new net.Socket(); var msg = ""; socket.connect(port, "127.0.0.1"); socket.write("Hello IoT.js"); socket.on('data', function(data) { msg += data; }); socket.on('end', function() { socket.end(); }); process.on('exit', function(code) { assert.equal(code, 0); assert.equal(msg, "Hello IoT.js"); }); iotjs-1.0/test/run_pass/test_net_connect.js000066400000000000000000000024251312466455500212250ustar00rootroot00000000000000/* Copyright 2017-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var assert = require('assert'); var net = require('net'); var host = '127.0.0.1'; var port = 5696; var msg = 'Hello IoT.js'; var server = net.createServer({ allowHalfOpen: true, }, function(socket) { server.close(); } ).listen(port); server.on('connection', function(socket) { var data = ''; socket.on('data', function(chuck) { data += chuck; }); socket.on('end', function() { socket.end(data); }); }); var socket = net.connect(port, host, function() { var data = ''; socket.on('data', function(chuck) { data += chuck; }); socket.on('end', function() { assert.equal(data, msg); }); socket.end(msg); }); iotjs-1.0/test/run_pass/test_net_headers.js000066400000000000000000000045251312466455500212120ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var assert = require('assert'); var http = require('http'); var checkReqFinish = false; // server side code // Server just ends after sending with some headers. var server = http.createServer(function (req, res) { req.on('data', function (chunk) { body += chunk; }); var endHandler = function () { // this should return. res.removeHeader('h1'); res.setHeader('h1','h1'); res.setHeader('h2','h2'); res.setHeader('h3','h3'); res.removeHeader('h2'); if (res.getHeader('h3') == 'h3') { res.setHeader('h3','h3prime'); // h3 value should be overwrited } // final res.headers = { 'h1' : 'h1', 'h3': 'h3prime' } var responseSize; if (process.platform === 'linux') { // For Desktop and RPI, test with large header. responseSize = 500; } else { // NuttX and TizenRt cannot handle large header. responseSize = 10; } for (var i = 0; i < responseSize; i++) { res.setHeader('h' + (5 + i), 'h' + (5 + i)); } res.end(function(){ server.close(); }); }; req.on('end', endHandler); }); server.listen(3045, 3); // client req code var options = { method : 'GET', port : 3045 }; var postResponseHandler = function (res) { var res_body = ''; assert.equal(200, res.statusCode); assert.equal(res.headers['h1'], 'h1'); assert.equal(res.headers['h2'], undefined); assert.equal(res.headers['h3'], 'h3prime'); var endHandler = function(){ checkReqFinish = true; }; res.on('end', endHandler); res.on('data', function(chunk){ res_body += chunk.toString(); }); }; var req = http.request(options, postResponseHandler); req.end(); process.on('exit', function() { assert.equal(checkReqFinish, true); }); iotjs-1.0/test/run_pass/test_net_http_get.js000066400000000000000000000041611312466455500214110ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var assert = require('assert'); var http = require('http'); var server = http.createServer(function (req, res) { var body = ''; var url = req.url; req.on('data', function (chunk) { body += chunk; }); var endHandler = function () { res.writeHead(200, { 'Connection' : 'close', 'Content-Length' : body.length }); res.write(body); res.end(function(){ if(body == 'close server') server.close(); }); }; req.on('end', endHandler); }); server.listen(3005,5); // 1. GET req options = { method : 'GET', port : 3005 }; var getResponseHandler = function (res) { var res_body = ''; assert.equal(200, res.statusCode); var endHandler = function(){ // GET msg, no received body assert.equal('', res_body); }; res.on('end', endHandler); res.on('data', function(chunk){ res_body += chunk.toString(); }); }; http.get(options, getResponseHandler); // 2. close server req var finalMsg = 'close server'; var finalOptions = { method : 'POST', port : 3005, headers : {'Content-Length': finalMsg.length} }; var finalResponseHandler = function (res) { var res_body = ''; assert.equal(200, res.statusCode); var endHandler = function(){ assert.equal(finalMsg, res_body); }; res.on('end', endHandler); res.on('data', function(chunk){ res_body += chunk.toString(); }); }; var finalReq = http.request(finalOptions, finalResponseHandler); finalReq.write(finalMsg); finalReq.end(); iotjs-1.0/test/run_pass/test_net_http_request_response.js000066400000000000000000000113421312466455500242370ustar00rootroot00000000000000/* Copyright 2017-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var assert = require('assert'); var http = require('http'); var net = require('net'); // Messages for further requests. var message = 'Hello IoT.js'; // Options for further requests. var options = { method: 'POST', port: 3005, path: '/', headers : {'Content-Length': message.length} }; var server1 = http.createServer(function(request, response) { var str = ''; request.on('data', function (chunk) { str += chunk.toString(); }); request.on('end', function() { assert.equal(str, message); response.end(); }); }); server1.listen(3005, 5); // Simple request with valid utf-8 message. var isRequest1Finished = false; var request1 = http.request(options, function(response) { var str = ''; response.on('data', function(chunk) { str += chunk.toString(); }); response.on('end', function() { isRequest1Finished = true; server1.close(); }); }); request1.end(message, 'utf-8'); var server2 = http.createServer(function(request, response) { response.end(); }); server2.listen(3006, 5); // Simple request with end callback. var isRequest2Finished = false; options.port = 3006; var request2 = http.request(options); request2.end(message, function() { server2.close(); isRequest2Finished = true; }); // Call the request2 end again to test the finish state. request2.end(message, function() { // This clabback should never be called. assert.equal(isRequest2Finished, false); }); var server3 = http.createServer(function(request, response) { var str = ''; request.on('data', function(chunk) { str += chunk; }); request.on('end', function() { // Check if we got the proper message. assert.equal(str, message); response.end(); }); }); server3.listen(3007, 5); // Simple request with buffer chunk as message parameter. options.port = 3007; var isRequest3Finished = false; var request3 = http.request(options, function(response) { var str = ''; response.on('data', function(chunk) { str += chunk; }); response.on('end', function() { isRequest3Finished = true; server3.close(); }); }); request3.end(new Buffer(message)); // This test is to make sure that when the HTTP server // responds to a HEAD request, it does not send any body. var server4 = http.createServer(function(request, response) { response.writeHead(200); response.end(); }); server4.listen(3008, 5); var isRequest4Finished = false; var request4 = http.request({ method: 'HEAD', port: 3008, path: '/' }, function(response) { response.on('end', function() { isRequest4Finished = true; assert.equal(response.statusCode, 200); server4.close(); }); }); request4.end(); // Write a header twice in the server response. var server5 = http.createServer(function(request, response) { var str = ''; request.on('data', function(chunk) { str += chunk; }); request.on('end', function() { response.writeHead(200, 'OK', {'Connection' : 'close1'}); // Wrote the same head twice. response.writeHead(200, 'OK', {'Connection' : 'close2'}); // Wrote a new head. response.writeHead(200, {'Head' : 'Value'}); response.end(); }); }); server5.listen(3009, 5); options.port = 3009; options.headers = null; var isRequest5Finished = false; var request5 = http.request(options, function(response) { response.on('end', function() { isRequest5Finished = true; assert.equal(response.headers['Connection'], 'close2'); assert.equal(response.headers['Head'], 'Value'); server5.close(); }); }); request5.end(); // Test the IncomingMessage read function. var readRequest = http.request({ host: 'localhost', port: 80, path: '/', method: 'GET' }); readRequest.end(); readRequest.on('response', function(incomingMessage) { incomingMessage.on('readable', function() { var inc = incomingMessage.read(); assert.equal(inc instanceof Buffer, true); assert(inc.toString('utf8').length > 0); }); }); process.on('exit', function() { assert.equal(isRequest1Finished, true); assert.equal(isRequest2Finished, true); assert.equal(isRequest3Finished, true); assert.equal(isRequest4Finished, true); assert.equal(isRequest5Finished, true); }); iotjs-1.0/test/run_pass/test_net_http_response_twice.js000066400000000000000000000032561312466455500236670ustar00rootroot00000000000000/* Copyright 2017-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var assert = require('assert'); var http = require('http'); var net = require('net'); var body = 'Hello IoT.js\r\n'; var fullResponse = 'HTTP/1.1 500 Internal Server Error\r\n' + 'Content-Length: ' + body.length + '\r\n' + 'Content-Type: text/plain\r\n' + 'Date: Fri + 5 May 2017 10:22:45 GMT\r\n' + 'Host: 127.0.0.1\r\n' + 'Access-Control-Allow-Credentials: true\r\n' + 'Server: badly broken/0.1 (OS NAME)\r\n' + '\r\n' + body; var server = net.createServer(function(socket) { var postBody = ''; socket.on('data', function(chunk) { postBody += chunk; if (postBody.indexOf('\r\n') > -1) { socket.write(fullResponse); // Wrote the response twice. socket.end(fullResponse); } }); socket.on('error', function(err) {}); }); server.listen(3085, function() { http.get({ port: 3085 }, function(response) { var buffer = ''; response.on('data', function(chunk) { buffer += chunk; }); response.on('end', function() { assert.equal(body, buffer); server.close(); }); }); }); iotjs-1.0/test/run_pass/test_net_http_status_codes.js000066400000000000000000000042601312466455500233320ustar00rootroot00000000000000 /* Copyright 2017-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var assert = require('assert'); var http = require('http'); var codes = ["100", "150", "199", "200", "204", "304", "404", "510"]; var responses = []; var completedResponses = 0; var server = http.createServer(function (request, response) { var str = ''; request.on('data', function (chunk) { str += chunk; }); request.on('end', function() { if (codes.indexOf(str) > -1) { response.writeHead(parseInt(str)); } response.write(str); response.end(function() { if(str == 'close server') { server.close(); } }); }); }); server.listen(3008, 5); var options = { method: 'POST', port: 3008, headers: {'Content-Length': 3} }; for (var i = 0; i < codes.length; i++) { var request = http.request(options, function(response) { responses.push(response.statusCode); completedResponses++; if (completedResponses == codes.length) { // Done with downloads. for (var j = 0; j < codes.length; j++) { assert(responses.indexOf(parseInt(codes[j])) > -1); } } }).end(codes[i]); } var closeMessage = 'close server'; var closeOptions = { method : 'POST', port : 3008, headers : {'Content-Length': closeMessage.length} }; var closeHandler = function(response) { var str = ''; assert.equal(200, response.statusCode); response.on('end', function() { assert.equal(closeMessage, str); }); response.on('data', function(chunk) { str += chunk; }); }; closeRequest = http.request(closeOptions, closeHandler); closeRequest.write(closeMessage); closeRequest.end(); iotjs-1.0/test/run_pass/test_net_httpclient_error.js000066400000000000000000000031041312466455500231560ustar00rootroot00000000000000/* Copyright 2017-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var assert = require('assert'); var http = require('http'); var recievedResponse = false; var server = http.createServer(function(request, response) { var str = ''; request.on('data', function (chunk) { str += chunk; }); request.on('end', function() { response.end(); }); }); server.listen(20004, 5); // Connection refusal: The request will try to connect to a server, // however the connection can not be created because the port is invalid. var req = http.request({ host: 'localhost', port: 20002, path: '/', method: 'GET' }, function(response) { var str = ''; response.on('data', function(chunk) { str += chunk; }); response.on('end', function() { recievedResponse = true; server.close(); }); }); req.on('error', function() { recievedResponse = false; server.close(); }); req.setTimeout(100, function(){ req.end(); }); process.on('exit', function() { assert.equal(recievedResponse, false); }); iotjs-1.0/test/run_pass/test_net_httpclient_parse_error.js000066400000000000000000000024141312466455500243530ustar00rootroot00000000000000/* Copyright 2017-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var assert = require('assert'); var http = require('http'); var net = require('net'); var errors = 0; // Create a TCP server var server = net.createServer(function(socket) { socket.end('Bad http\r\n\r\n'); // This should trigger the Parse Error. server.close(); }); server.listen(3085, '127.0.0.1'); // Create a simple get request. var request = http.request({ host: '127.0.0.1', port: 3085, method: 'GET', path: '/' }); request.on('error', function(err) { errors++; }); request.end(); process.on('exit', function() { // The first error is a Parse Error. // The second error is the socket hang up. assert.equal(errors, 2); }); iotjs-1.0/test/run_pass/test_net_httpclient_timeout_1.js000066400000000000000000000033371312466455500237430ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var assert = require('assert'); var http = require('http'); var IncomingMessage = require('http_incoming').IncomingMessage; var OutgoingMessage = require('http_outgoing').OutgoingMessage; var net = require('net'); var timeouted = false; var options = { method: 'GET', port: 3002 }; var incTimeout = 0; var outTimeout = 0; var socket = new net.Socket(); var inc = new IncomingMessage(socket); inc.setTimeout(100, function() { incTimeout++; }); var out = new OutgoingMessage(); out.setTimeout(100, function() { outTimeout++; }); out.emit('timeout'); var server = http.createServer(function(req, res) { // do nothing }); server.listen(options.port, function() { var req = http.request(options, function(res) { }); req.on('close', function() { server.close(); }); var destroyer = function() { timeouted = true; req.socket.destroy(); } req.setTimeout(100, destroyer); req.on('error', function(){}); req.end(); }); process.on('exit', function(code) { assert.equal(code,0); assert.equal(timeouted, true); assert.equal(incTimeout, 1); assert.equal(outTimeout, 1); }); iotjs-1.0/test/run_pass/test_net_httpclient_timeout_2.js000066400000000000000000000027011312466455500237360ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var assert = require('assert'); var http = require('http'); var timeouted = false; var options = { method: 'GET', port: 3004 }; var server = http.createServer(function(req, res) { res.write("."); }); server.listen(options.port, function() { var req = http.request(options, function(res) { var destroyer = function() { timeouted = true; req.socket.destroy(); server.close(); } res.on('data', function() { // after connection established req.setTimeout(100, destroyer); }); }); req.on('close', function() { server.close(); }); var before = function(){ /* this handler must not be called */ }; req.setTimeout(1000, before); req.on('error', function(){}); req.end(); }); process.on('exit', function(code) { assert.equal(timeouted, true); }); iotjs-1.0/test/run_pass/test_net_httpserver.js000066400000000000000000000102551312466455500220020ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var assert = require('assert'); var Server = require('http_server').Server; var http = require('http'); var responseCheck = ''; var connectionEvent = 0; var serverCloseEvent = 0; var requestEvent = 0; var responseEvent = 0; var socketEvent = 0; // server side code // server will return the received msg from client // and shutdown var server = http.createServer(function (req, res) { var body = ''; var url = req.url; req.on('data', function (chunk) { body += chunk; }); var endHandler = function () { res.writeHead(200, { 'Connection' : 'close', 'Content-Length' : body.length }); res.write(body); res.end(function(){ if(body == 'close server') { server.close(); } }); }; req.on('end', endHandler); }); server.on('request', function() { requestEvent++; }); server.on('connection', function() { connectionEvent++; }); server.on('close', function() { serverCloseEvent++; }); server.listen(3001, 3); // client side code // 1. send POST req to server and check response msg // 2. send GET req to server and check response msg // 3. send 'close server' msg // 1. POST req var msg = 'http request test msg'; var options = { method : 'POST', port : 3001, headers : {'Content-Length': msg.length} }; var postResponseHandler = function (res) { var res_body = ''; assert.equal(200, res.statusCode); var endHandler = function(){ assert.equal(msg, res_body); responseCheck += '1'; }; res.on('end', endHandler); res.on('data', function(chunk){ res_body += chunk.toString(); }); }; var req = http.request(options, postResponseHandler); req.on('response', function() { responseEvent++; }); req.on('socket', function() { socketEvent++; }); req.write(msg); req.end(); // 2. GET req options = { method : 'GET', port : 3001 }; var getResponseHandler = function (res) { var res_body = ''; assert.equal(200, res.statusCode); var endHandler = function(){ // GET msg, no received body assert.equal('', res_body); responseCheck += '2'; }; res.on('end', endHandler); res.on('data', function(chunk){ res_body += chunk.toString(); }); }; var getReq = http.request(options, getResponseHandler); getReq.on('response', function() { responseEvent++; }); getReq.on('socket', function() { socketEvent++; }); getReq.end(); // 3. close server req var finalMsg = 'close server'; var finalOptions = { method : 'POST', port : 3001, headers : {'Content-Length': finalMsg.length} }; var finalResponseHandler = function (res) { var res_body = ''; assert.equal(200, res.statusCode); var endHandler = function(){ assert.equal(finalMsg, res_body); responseCheck += '3'; }; res.on('end', endHandler); res.on('data', function(chunk){ res_body += chunk.toString(); }); }; var finalReq = http.request(finalOptions, finalResponseHandler); finalReq.on('response', function() { responseEvent++; }); finalReq.on('socket', function() { socketEvent++; }); finalReq.write(finalMsg); finalReq.end(); // Create server without requestListener. var server2 = http.createServer(); // Create server instance without new keyword. var server3 = Server(function(request, response) {}); process.on('exit', function() { assert.equal(responseCheck.length, 3); assert.equal(connectionEvent, 3); assert.equal(serverCloseEvent, 1); assert.equal(requestEvent, 3); assert.equal(responseEvent, 3); assert.equal(socketEvent, 3); assert.equal(server2 instanceof Server, true); assert.equal(server3 instanceof Server, true); }); iotjs-1.0/test/run_pass/test_net_httpserver_timeout.js000066400000000000000000000022621312466455500235470ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var assert = require('assert'); var http = require('http'); var timeouted = false; var server = http.createServer(function(req, res) { // do nothing }); server.listen(3003); server.setTimeout(100, function(socket) { timeouted = true; socket.destroy(); server.close(); }); // client will connect to server, and do nothing. var options = { method : 'GET', port : 3003 }; var getReq = http.request(options); getReq.on('error', function() {}); process.on('exit', function(code) { assert.equal(timeouted, true); assert.equal(code, 0); }); iotjs-1.0/test/run_pass/test_process.js000066400000000000000000000015001312466455500203750ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var assert = require('assert'); var sequence = ''; process.nextTick(function() { sequence += '2' }); sequence = '1'; process.on('exit', function() { assert.equal(sequence, '12'); }); iotjs-1.0/test/run_pass/test_process_chdir.js000066400000000000000000000015201312466455500215500ustar00rootroot00000000000000/* Copyright 2017-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var assert = require('assert'); var currentPath = process.cwd(); try { process.chdir('/'); } catch (err) { console.log('invalid path'); } assert.equal(process.cwd(), '/'); process.chdir(currentPath); iotjs-1.0/test/run_pass/test_process_cwd.js000066400000000000000000000012361312466455500212400ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ console.log(process.cwd()); iotjs-1.0/test/run_pass/test_process_exit.js000066400000000000000000000012231312466455500214300ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ process.exit(0); iotjs-1.0/test/run_pass/test_process_experimental_off.js000066400000000000000000000013321312466455500240070ustar00rootroot00000000000000/* Copyright 2017-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var assert = require('assert'); assert.notEqual(process.env.IOTJS_ENV, 'experimental'); iotjs-1.0/test/run_pass/test_process_experimental_on.js000066400000000000000000000013271312466455500236550ustar00rootroot00000000000000/* Copyright 2017-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var assert = require('assert'); assert.equal(process.env.IOTJS_ENV, 'experimental'); iotjs-1.0/test/run_pass/test_process_next_tick.js000066400000000000000000000021511312466455500224500ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var assert = require('assert'); var tickTrace = ""; process.nextTick(function() { tickTrace += "1"; process.nextTick(function() { tickTrace += "2"; process.nextTick(function() { tickTrace += "3"; process.nextTick(function() { tickTrace += "4"; process.nextTick(function() { tickTrace += "5"; }); }); }); }); }); process.on('exit', function(code) { assert.equal(code, 0); assert.equal(tickTrace, "12345"); }); iotjs-1.0/test/run_pass/test_process_readsource.js000066400000000000000000000017321312466455500226200ustar00rootroot00000000000000/* Copyright 2017-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var assert = require('assert'); var json_file = process.cwd() + "/resources/process/package.json"; // Load a JSON file. var str = process.readSource(json_file); var json = JSON.parse(str); assert.equal(json.version, "2.9.1"); assert.equal(json.name, "npm"); assert.equal(json.main, "./lib/npm.js"); assert.equal(json.repository.type, "git"); iotjs-1.0/test/run_pass/test_process_uncaught_order.js000066400000000000000000000020151312466455500234700ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var assert = require('assert'); var trace = ''; process.on('uncaughtException', function (err) { trace += 'A'; }); process.on('uncaughtException', function (err) { trace += 'B'; }); process.on('exit', function() { trace += 'C'; process.removeAllListeners('uncaughtException'); assert.equal(trace, 'ABABC'); }); process.nextTick(function() { assert.fail(); }); assert.fail(); iotjs-1.0/test/run_pass/test_process_uncaught_simple.js000066400000000000000000000017031312466455500236510ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var assert = require('assert'); var trace = ''; process.on('uncaughtException', function (err) { trace += 'A'; }); process.on('exit', function() { process.removeAllListeners('uncaughtException'); assert.equal(trace, 'AB'); }); setTimeout(function() { trace += 'B' }, 500); nonexistentFunc(); trace += 'C'; iotjs-1.0/test/run_pass/test_pwm.js000066400000000000000000000064661312466455500175420ustar00rootroot00000000000000/* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var assert = require('assert'); var Pwm = require('pwm'); var pwm = new Pwm(); var configuration = { period: 0.001 // 1kHz }; if (process.platform === 'linux') { configuration.pin = 0; } else if (process.platform === 'nuttx') { configuration.pin = require('stm32f4dis').pin.PWM1.CH1_1; } else if (process.platform === 'tizenrt') { configuration.pin = 0; } else { assert.fail(); } var periodOptions = { dutyCycle: 0.5, // The platform PWM is tested on (artik10/tizen 3.0) has an upper limit // of 75.2 Hz of PWM0 frequency. //values: [0.2, 0.4, 0.6, 0.8, 1] values: [ 0.5 ] }; var dutyOptions = { period: 0.5, values: [ 0, 0.1, 0.5, 0.9, 1 ] }; var testCb = function (err) { if (err) { assert.fail(); } }; var pwm0; testPeriods(); function testPeriods() { pwm0 = pwm.open(configuration, function (err) { console.log('PWM initialized'); if (err) { console.log('Have an error: ' + err.message); assert.fail(); } pwm0.setEnable(1, function(err) { testCb(err); var options = periodOptions; console.log('PWM: period test start '); var idx = 0; var period = options.values[idx++]; console.log("Period(%d)", period); pwm0.setFrequencySync(1.0 / period); pwm0.setDutyCycleSync(options.dutyCycle); var loop = setInterval(function () { if (idx == options.values.length) { clearInterval(loop); console.log('PWM period test complete'); pwm0.setPeriodSync(options.values[0]); pwm0.setEnableSync(0); pwm0.closeSync(); testDutyCycles(); } else { period = options.values[idx++]; console.log("Period(%d)", period); pwm0.setPeriod(period, testCb); } }, 1000); }); }); } function testDutyCycles() { var options = dutyOptions; console.log('PWM: duty cycle test start'); pwm0 = pwm.open(configuration, function (err) { console.log('PWM initialized'); if (err) { console.log('Have an error: ' + err.message); assert.fail(); } pwm0.setPeriod(options.period, function(err) { testCb(err); pwm0.setEnableSync(1, testCb); pwm0.setFrequency(1.0 / options.period, function(err) { testCb(err); var idx = 0; var loop = setInterval(function () { console.log('Duty cycle %d', options.values[idx]); pwm0.setDutyCycle(options.values[idx], testCb); if (++idx == options.values.length) { clearInterval(loop); pwm0.setEnableSync(0); pwm0.close(testCb.bind(err)); console.log('PWM duty cycle test complete'); } }, 1000); }); }); }); } iotjs-1.0/test/run_pass/test_spi_buffer.js000066400000000000000000000026021312466455500210470ustar00rootroot00000000000000/* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var assert = require('assert'); var Spi = require('spi'); var spi = new Spi(); // Buffer test var spi1 = spi.open({device: '/dev/spidev0.0'}, function() { var data = 'Hello IoTjs'; var tx = new Buffer(data); var rx = new Buffer(11); this.transferSync(tx, rx); var value = ''; for (var i = 0; i < 11; i++) { value += String.fromCharCode(rx[i]); } console.log(value); assert.equal(value, data); setTimeout(function() { spi1.transfer(tx, rx, function(err) { assert.equal(err, null); assert.equal(rx.length, 11); var value = ''; for (var i = 0; i < 11; i++) { value += String.fromCharCode(rx[i]); } console.log(value); assert.equal(value, data); spi1.close(); }); }, 500); }); iotjs-1.0/test/run_pass/test_spi_mcp3008.js000066400000000000000000000025321312466455500206720ustar00rootroot00000000000000/* Copyright 2017-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var assert = require('assert'); var Spi = require('spi'); var spi = new Spi(); // mcp3008 test var channel = 0; var spi0 = spi.open({ device: '/dev/spidev0.0' }, function() { var mode = (8 + channel) << 4; var tx = [1, mode, 0]; var rx = [0, 0, 0]; spi0.transferSync(tx, rx); console.log(((rx[1] & 0x03) << 8) + rx[2]); var loopCnt = 10; var loop = setInterval(function() { spi0.transfer(tx, rx, function(err) { assert.equal(err, null); assert.equal(rx.length, 3); var value = ((rx[1] & 0x03) << 8) + rx[2]; console.log(value); if (--loopCnt < 0) { spi0.closeSync(); clearInterval(loop); console.log('finish test'); } }); }, 500); }); iotjs-1.0/test/run_pass/test_stream.js000066400000000000000000000070551312466455500202250ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var Readable = require('stream').Readable; var assert = require('assert'); var readable1 = new Readable(); var d = ""; var e = ""; readable1.on('error', function(err) { e += "."; }); readable1.on('data', function(data) { d += data.toString(); }); readable1.on('end', function() { e += 'e'; }); readable1.pause(); readable1.push('abcde'); readable1.push('12345'); assert.equal(d, ''); assert.equal(e, ''); readable1.resume(); assert.equal(d, 'abcde12345'); assert.equal(e, ''); readable1.push('a'); readable1.push('1'); readable1.push('b'); readable1.push('2'); assert.equal(d, 'abcde12345a1b2'); assert.equal(e, ''); assert.equal(readable1.isPaused(), false); readable1.pause(); assert.equal(d, 'abcde12345a1b2'); assert.equal(e, ''); assert.equal(readable1.isPaused(), true); // Pause the readable again. This should do nothing. readable1.pause(); assert.equal(readable1.isPaused(), true); readable1.push('c'); readable1.push('3'); readable1.push('d'); readable1.push('4'); assert.equal(d, 'abcde12345a1b2'); assert.equal(e, ''); readable1.resume(); assert.equal(d, 'abcde12345a1b2c3d4'); assert.equal(e, ''); readable1.push(null); assert.equal(d, 'abcde12345a1b2c3d4'); assert.equal(e, 'e'); readable1.push('push after eof'); assert.equal(d, 'abcde12345a1b2c3d4'); assert.equal(e, 'e.'); // Create a readable stream without the new keyword. var readable2 = Readable({encoding: 'utf8'}); // Push an invalid chunk into it. assert.throws(function() { readable2.push(undefined); }, TypeError); assert.throws(function() { readable2.push(5001); }, TypeError); assert.throws(function() { readable2.push(5001.5); }, TypeError); assert.throws(function() { readable2.push([]); }, TypeError); assert.throws(function() { readable2.push([5001, 'string']); }, TypeError); assert.throws(function() { readable2.push({}); }, TypeError); assert.throws(function() { readable2.push({obj: 'string', second: 5001}); }, TypeError); // Read with irregular parameters from an empty stream. assert.equal(readable2.read(-2), null); assert.equal(readable2.read(0), null); readable2.push('qwerty'); assert.equal(readable2.read(6), 'qwerty'); // Throw not implemented Error when we trying to read less length data. readable2.push('new-data'); assert.throws(function() { readable2.read(1); }, Error); var readable3 = new Readable(); var readable3End = false; var paused = false; var str = 'test'; readable3.on('data', function(data) { assert.equal(paused, true); assert.equal(data, str); }); readable3.on('end', function() { readable3End = true; }); readable3.pause(); readable3.push(str); readable3.push(null); setTimeout(function() { paused = true; readable3.resume(); }, 1000); // End on non-EOF stream var readable4 = new Readable(); readable4.length = 10; assert.throws(function() { readable4.push(null); }, Error); process.on('exit', function() { assert.equal(readable2 instanceof Readable, true); assert.equal(readable3End, true); }); iotjs-1.0/test/run_pass/test_stream_duplex.js000066400000000000000000000021521312466455500215770ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var assert = require('assert'); var Duplex = require('stream').Duplex; var duplex = Duplex({ highWaterMark: 0 }); assert(duplex instanceof Duplex); assert(duplex.write); assert(duplex.read); var msg1 = 'message 1'; var msg2 = 'message 2'; duplex._write = function(chunk, callback) { assert.equal(chunk == msg1, true); duplex.push(msg2); duplex.end(); } duplex._readyToWrite(); duplex.write(msg1); process.on('exit', function() { assert.equal(duplex.read() == msg2, true); }); iotjs-1.0/test/run_pass/test_timers_arguments.js000066400000000000000000000030051312466455500223110ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var assert = require('assert'); var util = require('util'); var timerFired = false; var shouldnotFired = false; setTimeout(function(a, b, c) { assert.equal(arguments.length, 3); assert.equal(arguments[0], 1); assert.equal(arguments[1], 2); assert.equal(arguments[2], 3); assert.equal(a, 1); assert.equal(b, 2); assert.equal(c, 3); timerFired = true; }, 100, 1, 2, 3); var i = 0; setInterval(function(list) { assert.equal(arguments.length, 1); assert(util.isArray(list)); assert.equal(list.length, 5); if (i >= list.length) { clearInterval(this); } else { assert.equal(list[i], i * i); i++; } }, 100, [0, 1, 4, 9, 16]); var t = setTimeout(function() { shouldnotFired = true; }, 100); clearTimeout(t); process.on('exit', function(code) { assert.equal(code, 0); assert(timerFired); assert.equal(i, 5); assert.equal(shouldnotFired, false); }); iotjs-1.0/test/run_pass/test_timers_error.js000066400000000000000000000055711312466455500214470ustar00rootroot00000000000000/* Copyright 2017-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var assert = require('assert'); // Timeout without callback function. assert.throws(function() { setTimeout(1000); }, TypeError); // Timeout with invalid callback function parameter. assert.throws(function() { setTimeout({function: null}, 1000); }, TypeError); assert.throws(function() { setTimeout({function: null, value: function() {}}, 1000); }, TypeError); assert.throws(function() { setTimeout(null, 1000); }, TypeError); assert.throws(function() { setTimeout(undefined, 1000); }, TypeError); assert.throws(function() { setTimeout([10, 100, 1000], 1000); }, TypeError); assert.throws(function() { setTimeout('callback', 1000); }, TypeError); // ClearTimeout without timeout parameter. assert.doesNotThrow(function() { clearTimeout(); }); assert.throws(function() { clearTimeout('timeout'); }, Error); assert.throws(function() { clearTimeout(1000); }, Error); assert.doesNotThrow(function() { clearTimeout(null); }); assert.doesNotThrow(function() { clearTimeout(undefined); }); assert.throws(function() { clearTimeout({timeout: 1000}); }, Error); // SetInterval without callback function. assert.throws(function() { setInterval(10); }, TypeError); // SetInterval with invalid callback function parameter. assert.throws(function() { setInterval(1000, 10); }, TypeError); assert.throws(function() { setInterval('callback', 10); }, TypeError); assert.throws(function() { setInterval({function: null, value: function() {}}, 10); }, TypeError); assert.throws(function() { setInterval(null, 10); }, TypeError); assert.throws(function() { setInterval(undefined, 10); }, TypeError); assert.throws(function() { setInterval([10, 100, 1000], 10); }, TypeError); // ClearInterval without interval parameter. assert.doesNotThrow(function() { clearInterval(); }); // ClearInterval with invalid interval parameter. assert.doesNotThrow(function() { clearInterval(null); }); assert.doesNotThrow(function() { clearInterval(undefined); }); assert.throws(function() { clearInterval('interval'); }, Error); assert.throws(function() { clearInterval(1000); }, Error); assert.throws(function() { clearInterval([interval, 1000]); }, Error); assert.throws(function() { clearInterval({interval: function() {}, value: 1000}); }, Error); iotjs-1.0/test/run_pass/test_timers_simple.js000066400000000000000000000024541312466455500216040ustar00rootroot00000000000000/* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var assert = require('assert'); var timerACnt = 0; var timerBCnt = 0; var timerCCnt = 0; var timerSequence = ''; var timerA = setTimeout(function() { timerSequence += 'A'; timerACnt++; }, 1000); var timerB = setInterval(function() { timerSequence += 'B'; timerBCnt++; if (timerBCnt > 5) { clearInterval(timerB); } }, 300); var timerC = setInterval(function() { timerSequence += 'C'; timerCCnt++; if (timerCCnt > 10) { clearInterval(timerC); } }, 0); process.on('exit', function(code) { assert.equal(code, 0); assert.equal(timerACnt, 1); assert.equal(timerBCnt, 6); assert.equal(timerCCnt, 11); assert.equal(timerSequence.length, 18); }); iotjs-1.0/test/run_pass/test_uart.js000066400000000000000000000036661312466455500177110ustar00rootroot00000000000000/* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var assert = require('assert'); var Uart = require('uart'); var uart = new Uart(); var configuration = { baudRate: 115200, dataBits: 8 }; if (process.platform === 'linux') { configuration.device = '/dev/ttyS0'; } else if (process.platform === 'nuttx') { configuration.device = '/dev/ttyS1'; } else if (process.platform === 'tizenrt') { configuration.device = '/dev/ttyDBG'; } else { assert.fail(); } writeTest(); function writeTest() { var serial = uart.open(configuration, function(err) { assert.equal(err, null); console.log('open done'); serial.writeSync("Hello IoT.js.\n\r"); serial.closeSync(); console.log('close done'); writeReadTest(); }); } function writeReadTest() { var read = 0; var write = 0; var serial = uart.open(configuration, function(err) { assert.equal(err, null); console.log('open done'); serial.on('data', function(data) { console.log('read result: ' + data.toString()); read = 1; if (read && write) { serial.close(); console.log('close done'); } }); serial.write("Hello there?\n\r", function(err) { assert.equal(err, null); console.log('write done'); write = 1; if (read && write) { serial.close(); console.log('close done'); } }); }); } iotjs-1.0/test/run_pass/test_util.js000066400000000000000000000143111312466455500177000ustar00rootroot00000000000000/* Copyright 2017-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var util = require('util'); var assert = require('assert'); assert.equal(util.isNull(null), true); assert.equal(util.isNull(0), false); assert.equal(util.isNull('null'), false); assert.equal(util.isUndefined(undefined), true); assert.equal(util.isUndefined(0), false); assert.equal(util.isUndefined('undefined'), false); assert.equal(util.isNumber(0), true); assert.equal(util.isNumber(5001), true); assert.equal(util.isNumber(3.14), true); assert.equal(util.isNumber(-5001), true); assert.equal(util.isNumber('5000'), false); assert.equal(util.isNumber(null), false); assert.equal(util.isNumber([0,1,2,3,4,5]), false); assert.equal(util.isFinite(5001), true); assert.equal(util.isFinite(-5001), true); assert.equal(util.isFinite(3.14), true); assert.equal(util.isFinite(-3.14), true); assert.equal(util.isFinite(0), true); assert.equal(util.isFinite(Infinity), false); assert.equal(util.isBoolean(true), true); assert.equal(util.isBoolean(false), true); assert.equal(util.isBoolean(Boolean(5001)), true); assert.equal(util.isBoolean(Boolean(0)), true); assert.equal(util.isBoolean(Boolean(-5001)), true); assert.equal(util.isBoolean(Boolean('Hello IoT.js')), true); assert.equal(util.isString('Hello IoT.js'), true); assert.equal(util.isString(['Hello IoT.js']), false); assert.equal(util.isString(-5001), false); assert.equal(util.isString(5001), false); assert.equal(util.isString(null), false); var object = { value1: 0, value2: 5001, value3: -5001, value4: 3.14, value5: 'Hello IoT.js' }; assert.equal(util.isObject(object), true); assert.equal(util.isObject({obj: 5001}), true); assert.equal(util.isObject({obj: object}), true); assert.equal(util.isObject({}), true); assert.equal(util.isObject([5001]), true); assert.equal(util.isObject(['Hello IoT.js']), true); assert.equal(util.isObject(null), false); assert.equal(util.isObject(5001), false); assert.equal(util.isObject('Hello IoT.js'), false); var func1 = function() {}; assert.equal(util.isFunction(func1), true); assert.equal(util.isFunction(function(arg) {/*do nothing*/}), true); assert.equal(util.isFunction(null), false); assert.equal(util.isFunction(5001), false); assert.equal(util.isFunction([5001]), false); assert.equal(util.isFunction([func1]), false); assert.equal(util.isFunction({}), false); assert.equal(util.isFunction('Hello IoT.js'), false); var buff = new Buffer('Hello IoT.js'); assert.equal(util.isBuffer(buff), true); assert.equal(util.isBuffer(new Buffer(5001)), true); assert.equal(util.isBuffer(5001), false); assert.equal(util.isBuffer({}), false); assert.equal(util.isBuffer('5001'), false); assert.equal(util.isBuffer([5001]), false); assert.equal(util.isBuffer([buff]), false); assert.equal(util.isBuffer({obj: buff}), false); function Parent() {} function Child() {} util.inherits(Child, Parent); var child = new Child(); assert.equal(child instanceof Parent, true); assert.equal(child instanceof Buffer, false); assert.equal(util.format(), ''); assert.equal(util.format(''), ''); assert.equal(util.format(null), 'null'); assert.equal(util.format(true), 'true'); assert.equal(util.format(false), 'false'); assert.equal(util.format('Hello IoT.js'), 'Hello IoT.js'); assert.equal(util.format(5001), '5001'); assert.equal(util.format('%d', 5001.5), '5001.5'); assert.equal(util.format('Hello IoT.js - %d', 5001), 'Hello IoT.js - 5001'); assert.equal( util.format('%s IoT.js - %d', 'Hello', 5001), 'Hello IoT.js - 5001' ); assert.equal(util.format('%d%%', 5001), '5001%'); var json = { "first":"1st", "second":"2nd" }; assert.equal( util.format('%s: %j', 'Object', json), 'Object: {"first":"1st","second":"2nd"}' ); assert.equal( util.format('%d-%j-%s', 5001, json, 'IoT.js', 'end'), '5001-{"first":"1st","second":"2nd"}-IoT.js end' ); json.json = json; assert.equal(util.format('%j', json), '[Circular]'); assert.equal(util.format('%s', '5001'), '5001'); assert.equal(util.format('%j', '5001'), '"5001"'); assert.equal(util.format('%d%d', 5001), '5001%d'); assert.equal(util.format('%s%d%s%d', 'IoT.js ', 5001), 'IoT.js 5001%s%d'); assert.equal(util.format('%d%% %s', 100, 'IoT.js'), '100% IoT.js'); assert.equal(util.format(new Error('format')), 'Error: format'); var err1 = util.errnoException(3008, 'syscall', 'original message'); assert.equal(err1 instanceof Error, true); assert.equal(err1, 'Error: syscall error original message'); assert.equal(err1.code, 'error'); assert.equal(err1.errno, 'error'); assert.equal(err1.syscall, 'syscall'); var err2 = util.errnoException(1, 'getSyscall'); assert.equal(err2 instanceof Error, true); assert.equal(err2, 'Error: getSyscall error'); assert.equal(err2.code, 'error'); assert.equal(err2.errno, 'error'); assert.equal(err2.syscall, 'getSyscall'); var err3 = util.exceptionWithHostPort(1, 'syscall', '127.0.0.1', 5001, 'additional info'); assert.equal(err3 instanceof Error, true); assert.equal( err3, 'Error: syscall error 127.0.0.1:5001 - Local (additional info)' ); assert.equal(err3.code, 'error'); assert.equal(err3.errno, 'error'); assert.equal(err3.syscall, 'syscall'); assert.equal(err3.address, '127.0.0.1'); assert.equal(err3.port, 5001); var err4 = util.exceptionWithHostPort(3008, 'getSyscall', '127.0.0.1'); assert.equal(err4 instanceof Error, true); assert.equal( err4, 'Error: getSyscall error 127.0.0.1' ); assert.equal(err4.code, 'error'); assert.equal(err4.errno, 'error'); assert.equal(err4.syscall, 'getSyscall'); assert.equal(err4.address, '127.0.0.1'); iotjs-1.0/test/testsets.json000066400000000000000000000173161312466455500162550ustar00rootroot00000000000000{ "run_pass": [ { "name": "test_adc.js", "skip": ["all"], "reason": "need to setup test environment" }, { "name": "test_assert.js" }, { "name": "test_ble_advertisement.js", "skip": ["all"], "reason": "need to setup test environment" }, { "name": "test_ble_setservices.js", "skip": ["all"], "reason": "need to setup test environment" }, { "name": "test_ble_setservices_central.js", "skip": ["all"], "reason": "run it with nodejs after running test_ble_setservices.js" }, { "name": "test_buffer_builtin.js" }, { "name": "test_buffer.js" }, { "name": "test_console.js" }, { "name": "test_dgram_1_server_1_client.js", "skip": ["all"], "reason": "need to setup test environment" }, { "name": "test_dgram_1_server_n_clients.js", "skip": ["all"], "reason": "need to setup test environment" }, { "name": "test_dgram_address.js", "skip": ["all"], "reason": "need to setup test environment" }, { "name": "test_dgram_broadcast.js", "skip": ["all"], "reason": "need to setup test environment" }, { "name": "test_dgram_multicast_membership.js", "skip": ["all"], "reason": "need to setup test environment" }, { "name": "test_dgram_multicast_set_multicast_loop.js", "skip": ["all"], "reason": "need to setup test environment" }, { "name": "test_dgram_setttl_client.js", "skip": ["all"], "reason": "need to setup test environment" }, { "name": "test_dgram_setttl_server.js", "skip": ["all"], "reason": "need to setup test environment" }, { "name": "test_dns.js" }, { "name": "test_dns_lookup.js", "skip": ["nuttx"], "reason": "not implemented for nuttx" }, { "name": "test_events.js" }, { "name": "test_events_assert_emit_error.js", "uncaught": true }, { "name": "test_events_uncaught_error.js", "uncaught": true }, { "name": "test_fs_exists.js" }, { "name": "test_fs_exists_sync.js" }, { "name": "test_fs_fstat.js", "skip": ["nuttx"], "reason": "not implemented for nuttx" }, { "name": "test_fs_fstat_sync.js", "skip": ["nuttx"], "reason": "not implemented for nuttx" }, { "name": "test_fs_mkdir_rmdir.js", "skip": ["nuttx"], "reason": "implemented, run manually in default configuration" }, { "name": "test_fs_open_close.js", "skip": ["nuttx"], "reason": "not implemented for nuttx" }, { "name": "test_fs_readdir.js", "skip": ["nuttx"], "reason": "not implemented for nuttx" }, { "name": "test_fs_readfile.js" }, { "name": "test_fs_readfile_sync.js" }, { "name": "test_fs_rename.js" }, { "name": "test_fs_rename_sync.js" }, { "name": "test_fs_stat.js" }, { "name": "test_fs_write.js", "skip": ["nuttx"], "reason": "not implemented for nuttx" }, { "name": "test_fs_writefile.js" }, { "name": "test_fs_writefile_sync.js" }, { "name": "test_fs_writefile_unlink.js" }, { "name": "test_fs_writefile_unlink_sync.js" }, { "name": "test_fs_event.js", "skip": ["nuttx"], "reason": "not implemented for nuttx" }, { "name": "test_fs_open_read.js" }, { "name": "test_fs_open_read_sync_1.js", "skip": ["nuttx"], "reason": "not implemented for nuttx" }, { "name": "test_fs_open_read_sync_2.js" }, { "name": "test_fs_open_read_sync_3.js" }, { "name": "test_gpio_input.js", "skip": ["all"], "reason": "needs hardware" }, { "name": "test_gpio_output.js", "skip": ["all"], "reason": "need user input"}, { "name": "test_i2c.js", "skip": ["all"], "reason": "need to setup test environment" }, { "name": "test_iotjs_promise.js", "skip": ["all"], "reason": "es2015 is off by default" }, { "name": "test_module_cache.js", "skip": ["nuttx"], "reason": "not implemented for nuttx" }, { "name": "test_module_require.js", "skip": ["nuttx"], "reason": "not implemented for nuttx" }, { "name": "test_net_1.js" }, { "name": "test_net_2.js" }, { "name": "test_net_3.js", "timeout": 100, "skip": ["nuttx"], "reason": "requires too many socket descriptors and too large buffers" }, { "name": "test_net_4.js" }, { "name": "test_net_5.js" }, { "name": "test_net_6.js" }, { "name": "test_net_7.js", "skip": ["nuttx"], "reason": "requires too many socket descriptors" }, { "name": "test_net_8.js" }, { "name": "test_net_9.js" }, { "name": "test_net_10.js" }, { "name": "test_net_connect.js", "timeout": 10 }, { "name": "test_net_headers.js" }, { "name": "test_net_http_get.js", "timeout": 20 }, { "name": "test_net_http_response_twice.js", "timeout": 10 }, { "name": "test_net_http_request_response.js", "timeout": 10, "skip": ["nuttx"], "reason": "not implemented for nuttx" }, { "name": "test_net_http_status_codes.js", "timeout": 20, "skip": ["nuttx"], "reason": "not implemented for nuttx" }, { "name": "test_net_httpclient_error.js", "timeout": 10, "skip": ["nuttx"], "reason": "not implemented for nuttx" }, { "name": "test_net_httpclient_parse_error.js", "timeout": 10 }, { "name": "test_net_httpclient_timeout_1.js", "timeout": 10 }, { "name": "test_net_httpclient_timeout_2.js", "timeout": 15 }, { "name": "test_net_httpserver_timeout.js", "timeout": 10 }, { "name": "test_net_httpserver.js", "timeout": 20, "skip": ["nuttx"], "reason": "not implemented for nuttx" }, { "name": "test_process.js" }, { "name": "test_process_chdir.js" }, { "name": "test_process_cwd.js" }, { "name": "test_process_exit.js" }, { "name": "test_process_experimental_off.js", "skip": ["experimental"], "reason": "needed if testing stablity is set with stable" }, { "name": "test_process_experimental_on.js", "skip": ["stable"], "reason": "needed if testing stablity is set with experimental" }, { "name": "test_process_next_tick.js" }, { "name": "test_process_readsource.js" }, { "name": "test_process_uncaught_order.js", "uncaught": true }, { "name": "test_process_uncaught_simple.js", "uncaught": true }, { "name": "test_pwm.js", "skip": ["all"], "reason": "need to setup test environment" }, { "name": "test_spi.js", "skip": ["all"], "reason": "need to setup test environment" }, { "name": "test_stream.js" }, { "name": "test_stream_duplex.js"}, { "name": "test_timers_arguments.js" }, { "name": "test_timers_error.js" }, { "name": "test_timers_simple.js", "timeout": 10 }, { "name": "test_uart.js", "skip": ["all"], "reason": "need to setup test environment" }, { "name": "test_util.js" } ], "run_pass/issue": [ { "name": "issue-133.js" }, { "name": "issue-137.js" }, { "name": "issue-198.js" }, { "name": "issue-223.js" }, { "name": "issue-266.js" }, { "name": "issue-323.js" }, { "name": "issue-816.js" } ], "run_fail": [ { "name": "test_assert_equal.js", "expected-failure": true }, { "name": "test_assert_fail.js", "expected-failure": true }, { "name": "test_assert_notequal.js", "expected-failure": true }, { "name": "test_events_emit_error.js", "expected-failure": true }, { "name": "test_fs_callbacks_called.js", "expected-failure": true }, { "name": "test_iotjs_runtime_error.js", "expected-failure": true }, { "name": "test_iotjs_syntax_error.js", "expected-failure": true }, { "name": "test_module_require_invalid_file.js", "expected-failure": true }, { "name": "test_process_exitcode_arg.js", "expected-failure": true }, { "name": "test_process_exitcode_var.js", "expected-failure": true }, { "name": "test_process_explicit_exit.js", "expected-failure": true }, { "name": "test_process_implicit_exit.js", "expected-failure": true } ], "node/parallel": [ { "name": "test-assert.js" }, { "name": "test-http-status-message.js" }, { "name": "test-http-write-head.js" }, { "name": "test-net-bind-twice.js" }, { "name": "test-net-end-without-connect.js" }, { "name": "test-net-keepalive.js" }, { "name": "test-timers-clear-null-does-not-throw-error.js" } ] } iotjs-1.0/test/tmp/000077500000000000000000000000001312466455500142745ustar00rootroot00000000000000iotjs-1.0/test/tmp/README000066400000000000000000000001131312466455500151470ustar00rootroot00000000000000This directory is for temporary files will be generated during build test. iotjs-1.0/tools/000077500000000000000000000000001312466455500136555ustar00rootroot00000000000000iotjs-1.0/tools/__init__.py000066400000000000000000000001001312466455500157550ustar00rootroot00000000000000# Required for Python to search this directory for module files iotjs-1.0/tools/apt-get-install-arm.sh000077500000000000000000000013431312466455500177770ustar00rootroot00000000000000#!/bin/bash # Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. sudo apt-get update -q sudo apt-get install -q -y \ gcc-arm-linux-gnueabihf libc6-dev-armhf-cross iotjs-1.0/tools/apt-get-install-deps.sh000077500000000000000000000013311312466455500201500ustar00rootroot00000000000000#!/bin/bash # Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. sudo apt-get update -q sudo apt-get install -q -y \ cmake gcc valgrind clang-format-3.8 iotjs-1.0/tools/apt-get-install-nuttx.sh000077500000000000000000000014701312466455500204030ustar00rootroot00000000000000#!/bin/bash # Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. sudo apt-get update -q sudo apt-get install -q -y \ autoconf libtool gperf flex bison autoconf2.13 \ cmake libncurses-dev libusb-1.0-0-dev \ libsgutils2-dev gcc-arm-none-eabi iotjs-1.0/tools/apt-get-install-tizen.sh000077500000000000000000000017561312466455500203610ustar00rootroot00000000000000#!/bin/bash # Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. wget https://releases.linaro.org/components/\ toolchain/binaries/4.9-2017.01/arm-linux-gnueabi/\ gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabi.tar.xz tar Jxf gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabi.tar.xz mv gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabi arm-linux-gnueabi export PATH=$(pwd)/arm-linux-gnueabi/bin:$PATH arm-linux-gnueabi-gcc --version iotjs-1.0/tools/apt-get-install-travis-i686.sh000077500000000000000000000013531312466455500212230ustar00rootroot00000000000000#!/bin/bash # Copyright 2017-present Samsung Electronics Co., Ltd. and other contributors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. sudo dpkg --add-architecture i386 sudo apt-get update -q sudo apt-get install -q -y \ linux-libc-dev:i386 iotjs-1.0/tools/brew-install-deps.sh000077500000000000000000000014251312466455500175520ustar00rootroot00000000000000#!/bin/bash # Copyright 2017-present Samsung Electronics Co., Ltd. and other contributors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. brew update PKGS=" cmake " for pkg in $PKGS do if ! ( brew list -1 | grep -q "^${pkg}\$" ) then brew install $pkg fi done iotjs-1.0/tools/build.py000077500000000000000000000441151312466455500153360ustar00rootroot00000000000000#!/usr/bin/env python # Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. from __future__ import print_function try: basestring except: # in Python 3.x there is no basestring just str basestring = str import argparse import json import sys import re import os from js2c import js2c from module_analyzer import resolve_modules, analyze_module_dependency from common_py import path from common_py.system.filesystem import FileSystem as fs from common_py.system.executor import Executor as ex from common_py.system.platform import Platform platform = Platform() # Initialize build options. def init_options(): # Check config options. arg_config = list(filter(lambda x: x.startswith('--config='), sys.argv)) config_path = path.BUILD_CONFIG_PATH if arg_config: config_path = arg_config[-1].split('=', 1)[1] # Read config file and apply it to argv. argv = [] with open(config_path, 'rb') as f: config = json.loads(f.read().decode('ascii')) config_option = config['build_option'] for opt_key in config_option: opt_val = config_option[opt_key] if isinstance(opt_val, basestring) and opt_val != '': argv.append('--%s=%s' % (opt_key, opt_val)) elif isinstance(opt_val, bool): if opt_val: argv.append('--%s' % opt_key) elif isinstance(opt_val, int): argv.append('--%s=%s' % (opt_key, opt_val)) elif isinstance(opt_val, list): for val in opt_val: argv.append('--%s=%s' % (opt_key, val)) # Apply command line argument to argv. argv = argv + sys.argv[1:] # Prepare argument parser. parser = argparse.ArgumentParser() parser.add_argument('--buildtype', choices=['debug', 'release'], default='debug', help='Specify the build type: %(choices)s (default: %(default)s)') parser.add_argument('--builddir', default=path.BUILD_ROOT, help='Specify the build directory (default: %(default)s)') parser.add_argument('--buildlib', action='store_true', default=False, help='Build IoT.js library only (default: %(default)s)') parser.add_argument('--clean', action='store_true', default=False, help='Clean build directory before build (default: %(default)s)') parser.add_argument('--config', default=path.BUILD_CONFIG_PATH, help='Specify the config file (default: %(default)s)', dest='config_path') parser.add_argument('--target-arch', choices=['arm', 'x86', 'i686', 'x86_64', 'x64'], default=platform.arch(), help='Specify the target architecture: ' '%(choices)s (default: %(default)s)') parser.add_argument('--target-os', choices=['linux', 'darwin', 'osx', 'nuttx', 'tizen', 'tizenrt'], default=platform.os(), help='Specify the target os: %(choices)s (default: %(default)s)') parser.add_argument('--target-board', choices=['none', 'artik10', 'stm32f4dis', 'rpi2', 'artik05x'], default='none', help='Specify the targeted board (if needed): ' '%(choices)s (default: %(default)s)') parser.add_argument('--nuttx-home', default=None, dest='sysroot', help='Specify the NuttX base directory (required for NuttX build)') parser.add_argument('--cross-compile', dest='cross_compile', action='store', help='Specify the cross compilation toolkit prefix.') parser.add_argument('--sysroot', action='store', help='The location of the development tree root directory (sysroot).' 'Must be compatible with used toolchain.') parser.add_argument('--cmake-param', action='append', default=[], help='Specify additional cmake parameters ' '(can be used multiple times)') parser.add_argument('--compile-flag', action='append', default=[], help='Specify additional compile flags (can be used multiple times)') parser.add_argument('--link-flag', action='append', default=[], help='Specify additional linker flags (can be used multiple times)') parser.add_argument('--external-include-dir', action='append', default=[], help='Specify additional external include directory ' '(can be used multiple times)') parser.add_argument('--external-static-lib', action='append', default=[], help='Specify additional external static library ' '(can be used multiple times)') parser.add_argument('--external-shared-lib', action='append', default=[], help='Specify additional external shared library ' '(can be used multiple times)') parser.add_argument('--iotjs-include-module', action='store', default=set(), type=lambda x: set(x.split(',')), help='Specify iotjs modules which should be included ' '(format: module_1,module_2,...)') parser.add_argument('--iotjs-exclude-module', action='store', default=set(), type=lambda x: set(x.split(',')), help='Specify iotjs modules which should be excluded ' '(format: module_1,module_2,...)') parser.add_argument('--iotjs-minimal-profile', action='store_true', default=False, help='Build IoT.js with minimal profile') parser.add_argument('--jerry-cmake-param', action='append', default=[], help='Specify additional cmake parameters for JerryScript ' '(can be used multiple times') parser.add_argument('--jerry-compile-flag', action='append', default=[], help='Specify additional compile flags for JerryScript ' '(can be used multiple times') parser.add_argument('--jerry-lto', action='store_true', default=False, help='Build JerryScript with LTO enabled') parser.add_argument('--jerry-heap-section', action='store', default=None, help='Specify the name of the JerryScript heap section') parser.add_argument('--jerry-heaplimit', type=int, default=config['build_option']['jerry-heaplimit'], help='Specify the size of the JerryScript max heap size ' '(default: %(default)s)') parser.add_argument('--jerry-memstat', action='store_true', default=False, help='Enable JerryScript heap statistics') parser.add_argument('--jerry-profile', choices=['es5.1', 'es2015-subset'], default='es5.1', help='Specify the profile for JerryScript: %(choices)s' ' (default: %(default)s)') parser.add_argument('--jerry-debugger', action='store_true', default=False, help='Enable JerryScript-debugger') parser.add_argument('--jerry-debugger-port', type=int, default=5001, help='Specify the port of JerryScript-debugger (default: %(default)s)') parser.add_argument('--no-init-submodule', action='store_true', default=False, help='Disable initialization of git submodules') parser.add_argument('--no-check-valgrind', action='store_true', default=False, help='Disable test execution with valgrind after build') parser.add_argument('--no-check-test', action='store_true', default=False, help='Disable test exection after build') parser.add_argument('--no-parallel-build', action='store_true', default=False, help='Disable parallel build') parser.add_argument('--no-snapshot', action='store_true', default=False, help='Disable snapshot generation for IoT.js') parser.add_argument('-e', '--experimental', action='store_true', default=False, help='Enable to build experimental features') options = parser.parse_args(argv) options.config = config return options def adjust_options(options): # First fix some option inconsistencies. if options.target_os in ['nuttx', 'tizenrt']: options.buildlib = True if not options.sysroot: ex.fail('--sysroot needed for nuttx target') options.sysroot = fs.abspath(options.sysroot) if not fs.exists(options.sysroot): ex.fail('NuttX sysroot %s does not exist' % options.sysroot) if options.target_arch == 'x86': options.target_arch = 'i686' if options.target_arch == 'x64': options.target_arch = 'x86_64' if options.target_os == 'darwin': options.no_check_valgrind = True if options.target_board in ['rpi2', 'artik10', 'artik05x']: options.no_check_valgrind = True elif options.target_board == 'none': options.target_board = None if options.iotjs_minimal_profile: options.no_check_test = True # Then add calculated options. options.host_tuple = '%s-%s' % (platform.arch(), platform.os()) options.target_tuple = '%s-%s' % (options.target_arch, options.target_os) options.host_build_root = fs.join(path.PROJECT_ROOT, options.builddir, 'host', options.host_tuple, options.buildtype) options.host_build_bins = fs.join(options.host_build_root, 'bin') options.build_root = fs.join(path.PROJECT_ROOT, options.builddir, options.target_tuple, options.buildtype) options.build_bins = fs.join(options.build_root, 'bin') options.build_libs = fs.join(options.build_root, 'lib') cmake_path = fs.join(path.PROJECT_ROOT, 'cmake', 'config', '%s.cmake') options.cmake_toolchain_file = cmake_path % options.target_tuple options.host_cmake_toolchain_file = cmake_path % options.host_tuple # Specify the file of JerryScript profile. options.jerry_profile = fs.join(path.JERRY_PROFILE_ROOT, options.jerry_profile + '.profile') def print_build_option(options): print('=================================================') option_vars = vars(options) for opt in option_vars: print(' --%s: %s' % (opt, option_vars[opt])) print() def print_progress(msg): print('==> %s\n' % msg) def init_submodule(): ex.check_run_cmd('git', ['submodule', 'init']) ex.check_run_cmd('git', ['submodule', 'update']) def build_cmake_args(options, for_jerry=False): cmake_args = [] # compile flags compile_flags = [] config_compile_flags = options.config['compile_flags'] compile_flags += config_compile_flags['os'][options.target_os] compile_flags += config_compile_flags['arch'][options.target_arch] compile_flags += config_compile_flags['buildtype'][options.buildtype] if options.target_board: compile_flags += config_compile_flags['board'][options.target_board] compile_flags += options.compile_flag compile_flags += options.jerry_compile_flag if for_jerry else [] cmake_args.append("-DCMAKE_C_FLAGS='%s'" % (' '.join(compile_flags))) # link flags link_flags = [] config_link_flags = options.config['link_flags'] link_flags += config_link_flags['os'][options.target_os] link_flags += options.link_flag if options.jerry_lto: link_flags.append('-flto') cmake_args.append("-DCMAKE_EXE_LINKER_FLAGS='%s'" % (' '.join(link_flags))) # external include dir include_dirs = [] if options.target_os in ['nuttx', 'tizenrt'] and options.sysroot: include_dirs.append('%s/include' % options.sysroot) if options.target_board == 'stm32f4dis': include_dirs.append('%s/arch/arm/src/stm32' % options.sysroot) if options.target_os == 'tizenrt': include_dirs.append('%s/../framework/include/iotbus' % options.sysroot) include_dirs.extend(options.external_include_dir) cmake_args.append("-DEXTERNAL_INCLUDE_DIR='%s'" % (' '.join(include_dirs))) return cmake_args def run_make(options, build_home, *args): make_opt = ['-C', build_home] make_opt.extend(args) if not options.no_parallel_build: make_opt.append('-j') ex.check_run_cmd('make', make_opt) def get_on_off(boolean_value): if boolean_value: return 'ON' return 'OFF' def build_iotjs(options): print_progress('Build IoT.js') # Set IoT.js cmake options. cmake_opt = [ '-B%s' % options.build_root, '-H%s' % path.PROJECT_ROOT, "-DCMAKE_TOOLCHAIN_FILE='%s'" % options.cmake_toolchain_file, '-DCMAKE_BUILD_TYPE=%s' % options.buildtype.capitalize(), '-DTARGET_OS=%s' % options.target_os, '-DTARGET_BOARD=%s' % options.target_board, '-DPLATFORM_DESCRIPTOR=%s' % options.target_tuple, '-DENABLE_LTO=%s' % get_on_off(options.jerry_lto), # --jerry-lto '-DENABLE_SNAPSHOT=%s' % get_on_off(not options.no_snapshot), '-DENABLE_MINIMAL=%s' % get_on_off(options.iotjs_minimal_profile), '-DBUILD_LIB_ONLY=%s' % get_on_off(options.buildlib), # --build-lib # --jerry-memstat '-DFEATURE_MEM_STATS=%s' % get_on_off(options.jerry_memstat), # --iotjs-include-module "-DIOTJS_INCLUDE_MODULE='%s'" % ','.join(options.iotjs_include_module), # --iotjs-exclude-module "-DIOTJS_EXCLUDE_MODULE='%s'" % ','.join(options.iotjs_exclude_module), # --jerry-profile "-DFEATURE_PROFILE='%s'" % options.jerry_profile, ] if options.target_os in ['nuttx', 'tizenrt']: cmake_opt.append("-DEXTERNAL_LIBC_INTERFACE='%s'" % fs.join(options.sysroot, 'include')) cmake_opt.append("-DTARGET_SYSTEMROOT='%s'" % options.sysroot) cmake_opt.append("-DEXTERNAL_CMAKE_SYSTEM_PROCESSOR=arm") # --jerry-heaplimit if options.jerry_heaplimit: cmake_opt.append('-DMEM_HEAP_SIZE_KB=%d' % options.jerry_heaplimit) # --jerry-heap-section if options.jerry_heap_section: cmake_opt.append("-DJERRY_HEAP_SECTION_ATTR='%s'" % options.jerry_heap_section) # --jerry-debugger if options.jerry_debugger: cmake_opt.append('-DFEATURE_DEBUGGER=ON') cmake_opt.append('-DFEATURE_DEBUGGER_PORT=%d' % options.jerry_debugger_port) # --cmake-param cmake_opt.extend(options.cmake_param) # --external-static-lib cmake_opt.append("-DEXTERNAL_STATIC_LIB='%s'" % (' '.join(options.external_static_lib))) # --external-shared-lib shared_libs = [] shared_libs.extend(options.external_shared_lib) shared_libs.extend(options.config['shared_libs']['os'][options.target_os]) cmake_opt.append("-DEXTERNAL_SHARED_LIB='%s'" % (' '.join(shared_libs))) # --jerry-cmake-param if options.jerry_cmake_param: cmake_opt.append("-DEXTRA_JERRY_CMAKE_PARAMS='%s'" % ' '.join(options.jerry_cmake_param)) # --experimental if options.experimental: options.compile_flag.append('-DEXPERIMENTAL') # Add common cmake options. cmake_opt.extend(build_cmake_args(options)) # Run cmake. ex.check_run_cmd('cmake', cmake_opt) run_make(options, options.build_root) def process_modules(options): print_progress('Analyze modules') includes, excludes = resolve_modules(options) modules = analyze_module_dependency(includes, excludes) print('Selected js modules: %s' % ', '.join(modules['js'])) print('Selected native modules: %s' % ', '.join(modules['native'])) options.js_modules = modules['js'] options.native_modules = modules['native'] options.iotjs_exclude_module = excludes def run_checktest(options): checktest_quiet = 'yes' if os.getenv('TRAVIS') == "true": checktest_quiet = 'no' # IoT.js executable iotjs = fs.join(options.build_root, 'bin', 'iotjs') build_args = ['quiet=' + checktest_quiet] if options.iotjs_exclude_module: skip_module = ','.join(options.iotjs_exclude_module) build_args.append('skip-module=' + skip_module) # experimental if options.experimental: build_args.append('experimental=' + 'yes'); fs.chdir(path.PROJECT_ROOT) code = ex.run_cmd(iotjs, [path.CHECKTEST_PATH] + build_args) if code != 0: ex.fail('Failed to pass unit tests') if not options.no_check_valgrind: code = ex.run_cmd('valgrind', ['--leak-check=full', '--error-exitcode=5', '--undef-value-errors=no', iotjs, path.CHECKTEST_PATH] + build_args) if code == 5: ex.fail('Failed to pass valgrind test') if code != 0: ex.fail('Failed to pass unit tests in valgrind environment') if __name__ == '__main__': # Initialize build option object. options = init_options() adjust_options(options) print_build_option(options) if options.clean: print_progress('Clear build directory') fs.rmtree(options.build_root) fs.rmtree(options.host_build_root) process_modules(options) # Perform init-submodule. if not options.no_init_submodule: print_progress('Initialize submodule') init_submodule() build_iotjs(options) # Run tests. if not options.no_check_test: print_progress('Run tests') if options.buildlib: print("Skip unit tests - build target is library\n") elif (options.host_tuple == options.target_tuple or (options.host_tuple == 'x86_64-linux' and options.target_tuple == 'i686-linux')): run_checktest(options) else: print("Skip unit tests - target-host pair is not allowed\n") print("\n%sIoT.js Build Succeeded!!%s\n" % (ex._TERM_GREEN, ex._TERM_EMPTY)) iotjs-1.0/tools/check_license.py000077500000000000000000000030631312466455500170130ustar00rootroot00000000000000#!/usr/bin/env python # Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import re class CheckLicenser(object): _license = re.compile( u"""((#|//|\*) Copyright .* Samsung Electronics Co., Ltd. and other contribu.*)+ \s?\\2 \s?\\2 Licensed under the Apache License, Version 2.0 \(the "License"\); \s?\\2 you may not use this file except in compliance with the License. \s?\\2 You may obtain a copy of the License at \s?\\2 \s?\\2 http://www.apache.org/licenses/LICENSE-2.0 \s?\\2 \s?\\2 Unless required by applicable law or agreed to in writing, software \s?\\2 distributed under the License is distributed on an "AS IS" BASIS \s?\\2 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. \s?\\2 See the License for the specific language governing permissions and \s?\\2 limitations under the License.""") @staticmethod def check(filename): with open(filename, 'r') as f: contents = f.read() return bool(CheckLicenser._license.search(contents)) iotjs-1.0/tools/check_signed_off.sh000077500000000000000000000066621312466455500174660ustar00rootroot00000000000000#!/bin/bash # Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors # Copyright 2016 University of Szeged # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Usage function print_usage { echo "Usage: $0 [--help] [--tolerant] [--travis]" } function print_help { echo "$0: Check Signed-off-by message of the latest commit" echo "" print_usage echo "" echo "Optional arguments:" echo " --help print this help message" echo " --tolerant check the existence of the message only but don't" echo " require the name and email address to match the author" echo " of the commit" echo " --travis perform check in tolerant mode if on Travis CI and not" echo " checking a pull request, perform strict check otherwise" echo "" echo "The last line of every commit message must follow the form of:" echo "'IoT.js-DCO-1.0-Signed-off-by: NAME EMAIL', where NAME and EMAIL must" echo "match the name and email address of the author of the commit (unless in" echo "tolerant mode)." } # Processing command line TOLERANT="no" while [ "$#" -gt 0 ] do if [ "$1" == "--help" ] then print_help exit 0 elif [ "$1" == "--tolerant" ] then TOLERANT="yes" shift elif [ "$1" == "--travis" ] then if [ "$TRAVIS_PULL_REQUEST" == "" ] then echo -e "\e[1;33mWarning! Travis-tolerant mode requested but not running on Travis CI! \e[0m" elif [ "$TRAVIS_PULL_REQUEST" == "false" ] then TOLERANT="yes" else TOLERANT="no" fi shift else print_usage exit 1 fi done # Determining latest commit parent_hashes=(`git show -s --format=%p HEAD | head -1`) if [ "${#parent_hashes[@]}" -eq 1 ] then commit_hash=`git show -s --format=%h HEAD | head -1` elif [ "${#parent_hashes[@]}" -eq 2 ] then commit_hash=${parent_hashes[1]} else echo "$0: cannot handle commit with ${#parent_hashes[@]} parents ${parent_hashes[@]}" exit 1 fi # Checking the last line actual_signed_off_by_line=`git show -s --format=%B $commit_hash | sed '/^$/d' | tr -d '\015' | tail -n 1` if [ "$TOLERANT" == "no" ] then author_name=`git show -s --format=%an $commit_hash` author_email=`git show -s --format=%ae $commit_hash` required_signed_off_by_line="IoT.js-DCO-1.0-Signed-off-by: $author_name $author_email" if [ "$actual_signed_off_by_line" != "$required_signed_off_by_line" ] then echo -e "\e[1;33mSigned-off-by message is incorrect. The following line should be at the end of the $commit_hash commit's message: '$required_signed_off_by_line'. \e[0m" exit 1 fi else echo -e "\e[1;33mWarning! The name and email address of the author of the $commit_hash commit is not checked in tolerant mode! \e[0m" if echo "$actual_signed_off_by_line" | grep -q -v '^IoT.js-DCO-1.0-Signed-off-by:' then echo -e "\e[1;33mSigned-off-by message is incorrect. The following line should be at the end of the $commit_hash commit's message: '$required_signed_off_by_line'. \e[0m" exit 1 fi fi exit 0 iotjs-1.0/tools/check_test.js000066400000000000000000000160251312466455500163330ustar00rootroot00000000000000/* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var fs = require('fs'); var Runner = require('test_runner').Runner; var Logger = require('common_js/logger').Logger; var OptionParser = require('common_js/option_parser').OptionParser; var util = require('common_js/util'); var EventEmitter = require('events').EventEmitter; var root = 'test'; var parent = '..'; function Driver() { this.results = { pass: 0, fail: 0, skip: 0, timeout: 0, }; this.emitter = new EventEmitter(); this.emitter.addListener('nextTest', function(driver, status, test) { if (driver.runner) { driver.runner.cleanup(); } var filename = test['name']; if (status == 'pass') { driver.results.pass++; driver.logger.message('PASS : ' + filename, status); } else if (status == 'fail') { driver.results.fail++; driver.logger.message('FAIL : ' + filename, status); } else if (status == 'skip') { driver.results.skip++; driver.logger.message('SKIP : ' + filename + ' (reason : ' + test.reason + ")", status); } else if (status == 'timeout') { driver.results.timeout++; driver.logger.message('TIMEOUT : ' + filename, status); } driver.fIdx++; driver.runNextTest(); }); this.os = process.platform; this.board = process.iotjs.board; this.root = util.absolutePath(root); process.chdir(this.root); return this; } Driver.prototype.config = function() { var parser = new OptionParser(); parser.addOption('start-from', "", "", "a test case file name where the driver starts."); parser.addOption('quiet', "yes|no", "yes", "a flag that indicates if the driver suppresses " + "console outputs of test case"); parser.addOption('output-file', "", "", "a file name where the driver leaves output"); parser.addOption('skip-module', "", "", "a module list to skip test of specific modules"); parser.addOption('output-coverage', "yes|no", "no", "output coverage information"); parser.addOption('experimental', "yes|no", "no", "a flag that indicates if tests for experimental are needed"); var options = parser.parse(); if (options == null) { parser.printHelp(); return false; } var output = options['output-file']; if (output) { if (this.os == 'nuttx') { var path = util.join('/mnt/sdcard', output); } else { var path = util.join(this.root, '..', output); } fs.writeFileSync(path, new Buffer('')); } var skipModule = options['skip-module']; if (skipModule) { this.skipModule = skipModule.split(','); } var experimental = options['experimental']; if (experimental == 'no') { this.stability = 'stable'; } else { this.stability = 'experimental'; } this.logger = new Logger(path); this.options = options; var testfile = util.join(this.root, 'testsets.json'); var testsets = fs.readFileSync(testfile).toString(); this.tests = JSON.parse(testsets); this.dIdx = 0; this.dLength = Object.keys(this.tests).length; var skipped = this.skipTestSet(options['start-from']); this.nextTestSet(skipped); return true; }; Driver.prototype.runNextTest = function() { if (this.dIdx == this.dLength) { this.finish(); } else { if (this.fIdx == this.fLength) { this.dIdx++; if (this.dIdx == this.dLength) { this.finish(); } else { this.nextTestSet(); this.runNextTest(); } } else { this.runner = new Runner(this); this.runner.run(); } } }; Driver.prototype.skipTestSet = function(filename) { if (!filename) return false; var dLength = this.dLength; for (var dIdx = 0; dIdx < dLength; dIdx++) { var dirname = Object.keys(this.tests)[dIdx]; var dir = this.tests[dirname]; var fLength = dir.length; for (var fIdx = 0; fIdx < fLength; fIdx++) { if (dir[fIdx]['name'] == filename) { this.fIdx = fIdx; this.dIdx = dIdx; return true; } } } return false; }; Driver.prototype.nextTestSet = function(skipped) { if (!skipped) { this.fIdx = 0; } var dirname = this.dirname(); this.fLength = this.tests[dirname].length; this.logger.message("\n"); this.logger.message(">>>> " + dirname, "summary"); }; Driver.prototype.dirname = function() { return Object.keys(this.tests)[this.dIdx] }; Driver.prototype.currentTest = function() { var dirname = this.dirname(); return this.tests[dirname][this.fIdx]; }; Driver.prototype.test = function() { var test = this.currentTest(); var dirname = this.dirname(); var testfile = util.absolutePath(util.join(dirname, test['name'])); return fs.readFileSync(testfile).toString(); }; Driver.prototype.finish = function() { this.logger.message('\n\nfinish all tests', this.logger.status.summary); this.logger.message('PASS : ' + this.results.pass, this.logger.status.pass); this.logger.message('FAIL : ' + this.results.fail, this.logger.status.fail); this.logger.message('TIMEOUT : ' + this.results.timeout, this.logger.status.timeout); this.logger.message('SKIP : ' + this.results.skip, this.logger.status.skip); if (this.options["output-coverage"] == "yes" && typeof __coverage__ !== "undefined") { data = JSON.stringify(__coverage__); if (!fs.existsSync("../.coverage_output/")) { fs.mkdirSync("../.coverage_output/"); } fs.writeFileSync("../.coverage_output/js_coverage.data", Buffer(data)); } else if (this.results.fail > 0 || this.results.timeout > 0) { originalExit(1); } originalExit(0); }; var driver = new Driver(); var originalExit = process.exit; process.exit = function(code) { // this function is called when the following happens. // 1. the test case is finished normally. // 2. assertion inside the callback function is failed. var should_fail = driver.runner.test['expected-failure']; try { process.emitExit(code); } catch(e) { // when assertion inside the process.on('exit', function { ... }) is failed, // this procedure is executed. process.removeAllListeners('exit'); if (should_fail) { driver.runner.finish('pass'); } else { console.error(e); driver.runner.finish('fail'); } } finally { process.removeAllListeners('exit'); if (code != 0 && !should_fail) { driver.runner.finish('fail'); } else if (code == 0 && should_fail) { driver.runner.finish('fail'); } else { driver.runner.finish('pass'); } } }; var conf = driver.config(); if (conf) { driver.runNextTest(); } iotjs-1.0/tools/check_tidy.py000077500000000000000000000161251312466455500163450ustar00rootroot00000000000000#!/usr/bin/env python # Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. from __future__ import print_function import argparse import fileinput import functools import os import subprocess import tempfile from distutils import spawn from check_license import CheckLicenser from common_py.system.filesystem import FileSystem as fs from common_py.system.executor import Executor as ex def parse_option(): parser = argparse.ArgumentParser() parser.add_argument('--autoedit', action='store_true', default=False, help='Automatically edit the detected clang format errors.' 'No diffs will be displayed') option = parser.parse_args() return option class StyleChecker(object): column_limit = 80 def __init__(self): self.count_lines = 0 self.count_empty_lines = 0 self.errors = [] @property def error_count(self): return len(self.errors) @property def count_valid_lines(self): return self.count_lines - self.count_empty_lines def report_error(self, msg): name = fileinput.filename() line = fileinput.filelineno() self.errors.append("%s:%d: %s" % (name, line, msg)) def check(self, files): for line in fileinput.input(files): if '\t' in line: self.report_error('TAB character') if '\r' in line: self.report_error('CR character') if line.endswith(' \n') or line.endswith('\t\n'): self.report_error('trailing whitespace') if not line.endswith('\n'): self.report_error('line ends without NEW LINE character') if len(line) - 1 > StyleChecker.column_limit: self.report_error('line exceeds %d characters' % StyleChecker.column_limit) if fileinput.isfirstline(): if not CheckLicenser.check(fileinput.filename()): self.report_error('incorrect license') self.count_lines += 1 if not line.strip(): self.count_empty_lines += 1 class ClangFormat(object): def __init__(self, extensions, skip_files=None, options=None): self.diffs = [] self._extensions = extensions self._skip_files = skip_files self._options = options self._check_clang_format("clang-format-3.8") def _check_clang_format(self, base): clang_format = spawn.find_executable(base) if not clang_format: clang_format = spawn.find_executable("clang-format") if clang_format: print("%sUsing %s instead of %s%s" % (ex._TERM_YELLOW, clang_format, base, ex._TERM_EMPTY)) else: print("%sNo %s found, skipping checks!%s" % (ex._TERM_RED, base, ex._TERM_EMPTY)) self._clang_format = clang_format @property def error_count(self): return len(self.diffs) def is_checked_by_clang(self, file): _, ext = fs.splitext(file) return ext in self._extensions and file not in self._skip_files def check(self, files): if not self._clang_format: return for file in filter(self.is_checked_by_clang, files): args = ['-style=file', file] if self._options and self._options.autoedit: args.append('-i') output = ex.run_cmd_output(self._clang_format, args, quiet=True) if output: with tempfile.NamedTemporaryFile() as temp: temp.write(output) temp.flush() # just to be really safe self._diff(file, temp.name) def _diff(self, original, formatted): try: subprocess.check_output(['diff', '-u', original, formatted]) except subprocess.CalledProcessError as error: # if there is a difference between the two files # this error will be generated and we can extract # the diff from that it. Otherwise nothing to do. self.diffs.append(error.output.decode()) class FileFilter(object): def __init__(self, allowed_exts, allowed_files, skip_files): self._allowed_exts = allowed_exts self._allowed_files = allowed_files self._skip_files = skip_files def __call__(self, dir_path, file): if file in self._allowed_files: return True if file in self._skip_files: return False _, ext = fs.splitext(file) return ext in self._allowed_exts def check_tidy(src_dir, options=None): allowed_exts = ['.c', '.h', '.js', '.py', '.sh', '.cmake'] allowed_files = ['CMakeLists.txt'] clang_format_exts = ['.c', '.h'] skip_dirs = ['deps', 'build', '.git', 'node_modules', 'coverage'] skip_files = ['check_signed_off.sh', '__init__.py', 'iotjs_js.c', 'iotjs_js.h', 'iotjs_string_ext.inl.h', 'ble.js', 'ble_hci_socket_acl_stream.js', 'ble_hci_socket_smp.js', 'ble_hci_socket_hci.js', 'ble_hci_socket_gap.js', 'ble_hci_socket_gatt.js', 'ble_hci_socket_mgmt.js', 'ble_hci_socket_bindings.js', 'ble_characteristic.js', 'test_ble_setservices.js', ] style = StyleChecker() clang = ClangFormat(clang_format_exts, skip_files, options) file_filter = FileFilter(allowed_exts, allowed_files, skip_files) files = fs.files_under(src_dir, skip_dirs, file_filter) clang.check(files) style.check(files) if clang.error_count: print("Detected clang-format problems:") print("".join(clang.diffs)) print() if style.error_count: print("Detected style problems:") print("\n".join(style.errors)) print() total_errors = style.error_count + clang.error_count print("* total lines of code: %d" % style.count_lines) print("* total non-blank lines of code: %d" % style.count_valid_lines) print("* style errors: %d" % style.error_count) print("* clang-format errors: %d" % clang.error_count) msg_color = ex._TERM_RED if total_errors > 0 else ex._TERM_GREEN print("%s* total errors: %d%s" % (msg_color, total_errors, ex._TERM_EMPTY)) print() return total_errors == 0 if __name__ == '__main__': from common_py import path options = parse_option() check_tidy(path.PROJECT_ROOT, options) iotjs-1.0/tools/common_js/000077500000000000000000000000001312466455500156415ustar00rootroot00000000000000iotjs-1.0/tools/common_js/logger.js000066400000000000000000000034601312466455500174610ustar00rootroot00000000000000/* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var fs = require('fs'); function Logger(path) { this.text_colors = { red: "\033[1;31m", yellow: "\033[1;33m", green: "\033[1;32m", blue: "\033[1;34m", empty: "\033[0m", }; this.status = { pass: "pass", skip: "skip", fail: "fail", timeout: "timeout", summary: "summary" } this.path = path; return this; } Logger.prototype.message = function (msg, status) { if (this.path) { // FIXME : After fs.appendFile is implemented, it should be replaced. var data = fs.readFileSync(this.path); var newData = data + msg + "\n"; fs.writeFileSync(this.path, new Buffer(newData)); } if (status == this.status.pass) { console.log(this.text_colors.green + msg + this.text_colors.empty); } else if (status == this.status.skip) { console.log(this.text_colors.yellow + msg + this.text_colors.empty); } else if (status == this.status.fail || status == this.status.timeout){ console.log(this.text_colors.red + msg + this.text_colors.empty); } else if (status == this.status.summary){ console.log(this.text_colors.blue + msg + this.text_colors.empty); } else { console.log(msg); } } module.exports.Logger = Logger; iotjs-1.0/tools/common_js/module/000077500000000000000000000000001312466455500171265ustar00rootroot00000000000000iotjs-1.0/tools/common_js/module/console.js000066400000000000000000000015511312466455500211300ustar00rootroot00000000000000/* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var fs = require('fs'); function Console() { return this; } Console.prototype.log = Console.prototype.info = Console.prototype.warn = Console.prototype.error = function() { /* Do Nothing */ }; module.exports = new Console(); iotjs-1.0/tools/common_js/option_parser.js000066400000000000000000000043031312466455500210630ustar00rootroot00000000000000/* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ function Option(arg, value, default_value, help) { this.arg = arg; this.value = value; this.default_value = default_value; this.help = help; return this; } Option.prototype.printHelp = function() { console.log("\t" + this.arg + "=[" + this.value + "](default: " + this.default_value + ") : " + this.help); } function OptionParser() { this.options = []; return this; } OptionParser.prototype.addOption = function(arg, value, default_value, help) { var option = new Option(arg, value, default_value, help); this.options.push(option); } OptionParser.prototype.parse = function() { var options = {}; for (var idx in this.options) { var option = this.options[idx]; var default_value = option.default_value; if (default_value !== "") { options[option.arg] = default_value; } } for (var aIdx = 2; aIdx < process.argv.length; aIdx++) { var option = process.argv[aIdx]; var arg_val = option.split("="); if (arg_val.length != 2 || !arg_val[0] || !arg_val[1]) { return null; } var arg = arg_val[0]; var val = arg_val[1]; var found = false; for (var oIdx in this.options) { if (arg == this.options[oIdx].arg) { options[arg] = val; found = true; break; } } if (!found) return null; } return options; } OptionParser.prototype.printHelp = function() { console.log(process.argv[1]); console.log("\noptional arguments"); for (var idx in this.options) { this.options[idx].printHelp(); } } module.exports.OptionParser = OptionParser; iotjs-1.0/tools/common_js/util.js000066400000000000000000000020211312466455500171470ustar00rootroot00000000000000/* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ function absolutePath(path) { // FIXME: On NuttX side, when dealing with file, path should be absolute. // So workaround this problem, test driver converts relative path // to absolute one. return process.cwd() + '/' + path; } function join() { var path = Array.prototype.join.call(arguments, '/'); return path; } module.exports.absolutePath = absolutePath; module.exports.join = join; iotjs-1.0/tools/common_py/000077500000000000000000000000001312466455500156555ustar00rootroot00000000000000iotjs-1.0/tools/common_py/__init__.py000066400000000000000000000001001312466455500177550ustar00rootroot00000000000000# Required for Python to search this directory for module files iotjs-1.0/tools/common_py/path.py000066400000000000000000000034761312466455500171750ustar00rootroot00000000000000# Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """ common path for scripts """ from common_py.system.filesystem import FileSystem as fs # Root directory for the project. PROJECT_ROOT = fs.abspath(fs.join(fs.dirname(__file__), fs.pardir, fs.pardir)) # Source code directory. SRC_ROOT = fs.join(PROJECT_ROOT, 'src') # Root Build directory. BUILD_ROOT = fs.join(PROJECT_ROOT, 'build') # Root Build directory. TOOLS_ROOT = fs.join(PROJECT_ROOT, 'tools') # Root directory for dependencies. DEPS_ROOT = fs.join(PROJECT_ROOT, 'deps') # Root directory for test. TEST_ROOT = fs.join(PROJECT_ROOT, 'test') RUN_PASS_DIR = fs.join(TEST_ROOT, 'run_pass') RUN_FAIL_DIR = fs.join(TEST_ROOT, 'run_fail') RESOURCE_DIR = fs.join(TEST_ROOT, 'resources') # Root directory for JerryScript submodule. JERRY_ROOT = fs.join(DEPS_ROOT, 'jerry') # Root directory of JerryScript profiles. JERRY_PROFILE_ROOT = fs.join(JERRY_ROOT, 'jerry-core', 'profiles') # Root directory for libtuv submodule. TUV_ROOT = fs.join(DEPS_ROOT, 'libtuv') # Root directory for http-parser submodule. HTTPPARSER_ROOT = fs.join(DEPS_ROOT, 'http-parser') # checktest CHECKTEST_PATH = fs.join(TOOLS_ROOT, 'check_test.js') # Build configuration file path. BUILD_CONFIG_PATH = fs.join(PROJECT_ROOT, 'build.config') iotjs-1.0/tools/common_py/system/000077500000000000000000000000001312466455500172015ustar00rootroot00000000000000iotjs-1.0/tools/common_py/system/__init__.py000066400000000000000000000001001312466455500213010ustar00rootroot00000000000000# Required for Python to search this directory for module files iotjs-1.0/tools/common_py/system/executor.py000066400000000000000000000042051312466455500214120ustar00rootroot00000000000000# Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. from __future__ import print_function import subprocess class Executor(object): _TERM_RED = "\033[1;31m" _TERM_YELLOW = "\033[1;33m" _TERM_GREEN = "\033[1;32m" _TERM_BLUE = "\033[1;34m" _TERM_EMPTY = "\033[0m" @staticmethod def cmd_line(cmd, args=[]): return ' '.join([cmd] + args) @staticmethod def print_cmd_line(cmd, args=[]): print("%s%s%s" % (Executor._TERM_BLUE, Executor.cmd_line(cmd, args), Executor._TERM_EMPTY)) print() @staticmethod def fail(msg): print() print("%s%s%s" % (Executor._TERM_RED, msg, Executor._TERM_EMPTY)) print() exit(1) @staticmethod def run_cmd(cmd, args=[], quiet=False): if not quiet: Executor.print_cmd_line(cmd, args) try: return subprocess.call([cmd] + args) except OSError as e: Executor.fail("[Failed - %s] %s" % (cmd, e.strerror)) @staticmethod def run_cmd_output(cmd, args=[], quiet=False): if not quiet: Executor.print_cmd_line(cmd, args) try: return subprocess.check_output([cmd] + args) except OSError as e: Executor.fail("[Failed - %s] %s" % (cmd, e.strerror)) @staticmethod def check_run_cmd(cmd, args=[], quiet=False): retcode = Executor.run_cmd(cmd, args, quiet) if retcode != 0: Executor.fail("[Failed - %d] %s" % (retcode, Executor.cmd_line(cmd, args))) iotjs-1.0/tools/common_py/system/filesystem.py000066400000000000000000000305401312466455500217410ustar00rootroot00000000000000# Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Copyright (C) 2010 Google Inc. All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are # met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimecd r. # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following disclaimer # in the documentation and/or other materials provided with the # distribution. # * Neither the name of Google Inc. nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. """ Wrapper object for the file system """ import codecs import errno import filecmp import glob import hashlib import os import shutil import sys import tempfile import time try: import exceptions except ImportError: class exceptions(object): OSError = OSError class FileSystem(object): """FileSystem interface for IoT.js. Unless otherwise noted, all paths are allowed to be either absolute or relative.""" sep = os.sep pardir = os.pardir @staticmethod def abspath(path): # FIXME: This gross hack is needed while we transition from Cygwin # to native Windows, because we have some mixing of file conventions # from different tools: if sys.platform == 'cygwin': path = os.path.normpath(path) path_components = path.split(os.sep) if (path_components and len(path_components[0]) == 2 and path_components[0][1] == ':'): path_components[0] = path_components[0][0] path = os.path.join('/', 'cygdrive', *path_components) return os.path.abspath(path) @staticmethod def realpath(path): return os.path.realpath(path) @staticmethod def path_to_module(module_name): """A wrapper for all calls to __file__ to allow easy unit testing.""" # FIXME: This is the only use of sys in this file. It's possible this # function should move elsewhere. # __file__ is always an absolute path. return sys.modules[module_name].__file__ @staticmethod def expanduser(path): return os.path.expanduser(path) @staticmethod def basename(path): return os.path.basename(path) @staticmethod def chdir(path): return os.chdir(path) @staticmethod def copy(source, destination): shutil.copy(source, destination) @staticmethod def copyfile(source, destination): shutil.copyfile(source, destination) @staticmethod def dirname(path): return os.path.dirname(path) @staticmethod def exists(path): return os.path.exists(path) @staticmethod def dirs_under(path, dir_filter=None): """Return the list of all directories under the given path in topdown order. Args: dir_filter: if not None, the filter will be invoked with the filesystem object and the path of each dirfound. The dir is included in the result if the callback returns True. """ def filter_all(dirpath): return True dir_filter = dir_filter or filter_all dirs = [] for (dirpath, dirnames, filenames) in os.walk(path): if dir_filter(dirpath): dirs.append(dirpath) return dirs @staticmethod def files_under(path, dirs_to_skip=[], file_filter=None): """Return the list of all files under the given path in topdown order. Args: dirs_to_skip: a list of directories to skip over during the traversal (e.g., .svn, resources, etc.) file_filter: if not None, the filter will be invoked with the filesystem object and the dirname and basename of each file found. The file is included in the result if the callback returns True. """ def filter_all(dirpath, basename): return True file_filter = file_filter or filter_all files = [] if FileSystem.isfile(path): if file_filter(dirname(path), FileSystem.basename(path)): files.append(path) return files if FileSystem.basename(path) in dirs_to_skip: return [] for (dirpath, dirnames, filenames) in os.walk(path): for d in dirs_to_skip: if d in dirnames: dirnames.remove(d) for filename in filenames: if file_filter(dirpath, filename): files.append(FileSystem.join(dirpath, filename)) return files @staticmethod def getcwd(): return os.getcwd() @staticmethod def glob(path): return glob.glob(path) @staticmethod def isabs(path): return os.path.isabs(path) @staticmethod def isfile(path): return os.path.isfile(path) @staticmethod def getsize(path): return os.path.getsize(path) @staticmethod def isdir(path): return os.path.isdir(path) @staticmethod def join(*comps): return os.path.join(*comps) @staticmethod def listdir(path): return os.listdir(path) @staticmethod def mkdtemp(**kwargs): """Create and return a uniquely named directory. This is like tempfile.mkdtemp, but if used in a with statement the directory will self-delete at the end of the block (if the directory is empty; non-empty directories raise errors). The directory can be safely deleted inside the block as well, if so desired. Note that the object returned is not a string and does not support all of the string methods. If you need a string, coerce the object to a string and go from there. """ class TemporaryDirectory(object): def __init__(self, **kwargs): self._kwargs = kwargs self._directory_path = tempfile.mkdtemp(**self._kwargs) def __str__(self): return self._directory_path def __enter__(self): return self._directory_path def __exit__(self, type, value, traceback): # Only self-delete if necessary. # FIXME: Should we delete non-empty directories? if os.path.exists(self._directory_path): os.rmdir(self._directory_path) return TemporaryDirectory(**kwargs) @staticmethod def maybe_make_directory(*path): """Create the specified directory if it doesn't already exist.""" try: os.makedirs(FileSystem.join(*path)) except OSError as e: if e.errno != errno.EEXIST: raise @staticmethod def move(source, destination): shutil.move(source, destination) @staticmethod def mtime(path): return os.stat(path).st_mtime @staticmethod def normpath(path): return os.path.normpath(path) @staticmethod def open_binary_tempfile(suffix): """Create, open, and return a binary temp file. Returns a tuple of the file and the name.""" temp_fd, temp_name = tempfile.mkstemp(suffix) f = os.fdopen(temp_fd, 'wb') return f, temp_name @staticmethod def open_binary_file_for_reading(path): return codecs.open(path, 'rb') @staticmethod def read_binary_file(path): """Return the contents of the file at the given path as a byte string.""" with file(path, 'rb') as f: return f.read() @staticmethod def write_binary_file(path, contents): with file(path, 'wb') as f: f.write(contents) @staticmethod def open_text_file_for_reading(path, errors='strict'): # Note: There appears to be an issue with the returned file objects # not being seekable. See http://stackoverflow.com/questions/1510188/ # can-seek-and-tell-work-with-utf-8-encoded-documents-in-python . return codecs.open(path, 'r', 'utf8', errors) @staticmethod def open_text_file_for_writing(path): return codecs.open(path, 'w', 'utf8') @staticmethod def open_stdin(): return codecs.StreamReaderWriter(sys.stdin, codecs.getreader('utf8'), codecs.getwriter('utf8'), 'replace') @staticmethod def read_text_file(path): """Return the contents of the file at the given path as a Unicode string. The file is read assuming it is a UTF-8 encoded file with no BOM.""" with codecs.open(path, 'r', 'utf8') as f: return f.read() @staticmethod def write_text_file(path, contents): """Write the contents to the file at the given location. The file is written encoded as UTF-8 with no BOM.""" with codecs.open(path, 'w', 'utf-8') as f: f.write(contents.decode('utf-8') if type(contents) == str else contents) @staticmethod def sha1(path): contents = FileSystem.read_binary_file(path) return hashlib.sha1(contents).hexdigest() @staticmethod def relpath(path, start='.'): return os.path.relpath(path, start) class _WindowsError(exceptions.OSError): """Fake exception for Linux and Mac.""" pass @staticmethod def remove(path, osremove=os.remove): """On Windows, if a process was recently killed and it held on to a file, the OS will hold on to the file for a short while. This makes attempts to delete the file fail. To work around that, this method will retry for a few seconds until Windows is done with the file.""" try: exceptions.WindowsError except AttributeError: exceptions.WindowsError = FileSystem._WindowsError retry_timeout_sec = 3.0 sleep_interval = 0.1 while True: try: osremove(path) return True except exceptions.WindowsError as e: time.sleep(sleep_interval) retry_timeout_sec -= sleep_interval if retry_timeout_sec < 0: raise e @staticmethod def rmtree(path): """Delete the directory rooted at path, whether empty or not.""" shutil.rmtree(path, ignore_errors=True) @staticmethod def copytree(source, destination): shutil.copytree(source, destination) @staticmethod def split(path): """Return (dirname, basename + '.' + ext)""" return os.path.split(path) @staticmethod def splitext(path): """Return (dirname + os.sep + basename, '.' + ext)""" return os.path.splitext(path) @staticmethod def compare(path1, path2): return filecmp.cmp(path1, path2) iotjs-1.0/tools/common_py/system/platform.py000066400000000000000000000020151312466455500213750ustar00rootroot00000000000000# Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import os class Platform(object): def __init__(self): _os, _, _, _, _arch = os.uname() self._os = _os self._arch = _arch def os(self): """ Retrieve host OS name. """ return self._os.lower() def arch(self): """ Retrieve host arch name. """ arch = self._arch.lower() if arch in ["armv7l"]: arch = "arm" return arch iotjs-1.0/tools/js2c.py000077500000000000000000000224111312466455500150730ustar00rootroot00000000000000#!/usr/bin/env python # Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # # This file converts src/js/*.js to a C-array in src/iotjs_js.[h|c] file. # And this file also generates magic string list in src/iotjs_string_ext.inl.h # file to reduce JerryScript heap usage. import re import subprocess import struct from common_py.system.filesystem import FileSystem as fs from common_py import path def regroup(l, n): return [l[i:i+n] for i in range(0, len(l), n)] def remove_comments(code): pattern = r'(\".*?\"|\'.*?\')|(/\*.*?\*/|//[^\r\n]*$)' regex = re.compile(pattern, re.MULTILINE | re.DOTALL) def _replacer(match): if match.group(2) is not None: return "" else: return match.group(1) return regex.sub(_replacer, code) def remove_whitespaces(code): return re.sub('\n+', '\n', re.sub('\n +', '\n', code)) def force_str(string): if not isinstance(string, str): return string.decode('utf-8') else: return string def parse_literals(code): JERRY_SNAPSHOT_VERSION = 7 literals = set() header = struct.unpack('IIII', code[0:16]) if header[0] != JERRY_SNAPSHOT_VERSION : print ('Please check jerry snapshot version (Last confirmed: %d)' % JERRY_SNAPSHOT_VERSION) exit(1) code_ptr = header[1] + 8 while code_ptr < len(code): length = struct.unpack('H', code[code_ptr : code_ptr + 2])[0] code_ptr = code_ptr + 2 if length == 0: continue if length < 32: item = struct.unpack('%ds' % length, code[code_ptr : code_ptr + length]) literals.add(force_str(item[0])) code_ptr = code_ptr + length + (length % 2) return literals LICENSE = ''' /* Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the \"License\"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an \"AS IS\" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * This file is generated by tools/js2c.py * Do not modify this. */ ''' HEADER1 = '''#ifndef IOTJS_JS_H #define IOTJS_JS_H ''' FOOTER1 = ''' #endif ''' HEADER2 = '''#include #include #include "iotjs_js.h" ''' EMPTY_LINE = '\n' MAGIC_STRINGS_HEADER = '#define JERRY_MAGIC_STRING_ITEMS \\\n' MODULE_VARIABLES_H = ''' extern const char {NAME}_n[]; extern const uint8_t {NAME}_s[]; extern const size_t {NAME}_l; ''' MODULE_VARIABLES_C = ''' #define SIZE_{NAME_UPPER} {SIZE} const size_t {NAME}_l = SIZE_{NAME_UPPER}; const char {NAME}_n[] = "{NAME}"; const uint8_t {NAME}_s[] = {{ {CODE} }}; ''' NATIVE_STRUCT_H = ''' typedef struct { const char* name; const void* code; const size_t length; } iotjs_js_module; extern const iotjs_js_module natives[]; ''' NATIVE_STRUCT_C = ''' const iotjs_js_module natives[] = {{ {MODULES} }}; ''' def hex_format(ch): if isinstance(ch, str): ch = ord(ch) return "0x{:02x}".format(ch) def format_code(code, indent): lines = [] # convert all characters to hex format converted_code = map(hex_format, code) # 10 hex number per line for line in regroup(", ".join(converted_code), 10 * 6): lines.append((' ' * indent) + line.strip()) return "\n".join(lines) def get_snapshot_contents(module_name, snapshot_generator): """ Convert the given module with the snapshot generator and return the resulting bytes. """ js_path = fs.join(path.SRC_ROOT, 'js', module_name + '.js') wrapped_path = js_path + ".wrapped" snapshot_path = js_path + ".snapshot" with open(wrapped_path, 'w') as fwrapped, open(js_path, "r") as fmodule: if module_name != "iotjs": fwrapped.write("(function(exports, require, module) {\n") fwrapped.write(fmodule.read()) if module_name != "iotjs": fwrapped.write("});\n") ret = subprocess.call([snapshot_generator, "--save-snapshot-for-eval", snapshot_path, wrapped_path]) if ret != 0: msg = "Failed to dump %s: - %d" % (js_path, ret) print("%s%s%s" % ("\033[1;31m", msg, "\033[0m")) exit(1) with open(snapshot_path, 'rb') as snapshot: code = snapshot.read() fs.remove(wrapped_path) fs.remove(snapshot_path) return code def get_js_contents(name, is_debug_mode=False): """ Read the contents of the given js module. """ js_path = fs.join(path.SRC_ROOT, 'js', name + '.js') with open(js_path, "r") as f: code = f.read() # minimize code when in release mode if not is_debug_mode: code = remove_comments(code) code = remove_whitespaces(code) return code def js2c(buildtype, no_snapshot, js_modules, js_dumper, verbose=False): is_debug_mode = buildtype == "debug" magic_string_set = set() str_const_regex = re.compile('^#define IOTJS_MAGIC_STRING_\w+\s+"(\w+)"$') with open(fs.join(path.SRC_ROOT, 'iotjs_magic_strings.h'), 'r') as fin_h: for line in fin_h: result = str_const_regex.search(line) if result: magic_string_set.add(result.group(1)) # generate the code for the modules with open(fs.join(path.SRC_ROOT, 'iotjs_js.h'), 'w') as fout_h, \ open(fs.join(path.SRC_ROOT, 'iotjs_js.c'), 'w') as fout_c: fout_h.write(LICENSE) fout_h.write(HEADER1) fout_c.write(LICENSE) fout_c.write(HEADER2) for name in sorted(js_modules): if verbose: print('Processing module: %s' % name) if no_snapshot: code = get_js_contents(name, is_debug_mode) else: code = get_snapshot_contents(name, js_dumper) magic_string_set |= parse_literals(code) code_string = format_code(code, 1) fout_h.write(MODULE_VARIABLES_H.format(NAME=name)) fout_c.write(MODULE_VARIABLES_C.format(NAME=name, NAME_UPPER=name.upper(), SIZE=len(code), CODE=code_string)) fout_h.write(NATIVE_STRUCT_H) fout_h.write(FOOTER1) modules_struct = [ ' {{ {0}_n, {0}_s, SIZE_{1} }},'.format(name, name.upper()) for name in sorted(js_modules) ] modules_struct.append(' { NULL, NULL, 0 }') fout_c.write(NATIVE_STRUCT_C.format(MODULES="\n".join(modules_struct))) fout_c.write(EMPTY_LINE) # Write out the external magic strings magic_str_path = fs.join(path.SRC_ROOT, 'iotjs_string_ext.inl.h') with open(magic_str_path, 'w') as fout_magic_str: fout_magic_str.write(LICENSE) fout_magic_str.write(MAGIC_STRINGS_HEADER) sorted_strings = sorted(magic_string_set, key=lambda x: (len(x), x)) for idx, magic_string in enumerate(sorted_strings): magic_text = repr(magic_string)[1:-1] fout_magic_str.write(' MAGICSTR_EX_DEF(MAGIC_STR_%d, "%s") \\\n' % (idx, magic_text)) # an empty line is required to avoid compile warning fout_magic_str.write(EMPTY_LINE) if __name__ == "__main__": import argparse parser = argparse.ArgumentParser() parser.add_argument('--buildtype', choices=['debug', 'release'], default='debug', help='Specify the build type: %(choices)s (default: %(default)s)') parser.add_argument('--modules', required=True, help='List of JS modules to process. Format: ,,...') parser.add_argument('--snapshot-generator', default=None, help='Executable to use for generating snapshots from the JS files. ' 'If not specified the JS files will be directly processed.') parser.add_argument('-v', '--verbose', default=False, help='Enable verbose output.') options = parser.parse_args() if not options.snapshot_generator: print('Converting JS modules to C arrays (no snapshot)') no_snapshot = True else: print('Using "%s" as snapshot generator' % options.snapshot_generator) no_snapshot = False modules = options.modules.replace(',', ' ').split() js2c(options.buildtype, no_snapshot, modules, options.snapshot_generator, options.verbose) iotjs-1.0/tools/measure_coverage.sh000077500000000000000000000110261312466455500175300ustar00rootroot00000000000000#!/bin/bash # Copyright 2017-present Samsung Electronics Co., Ltd. and other contributors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. print_dep() { echo "The following dependencies are required:" echo " sudo apt install lcov gcc-multilib" echo "" } print_nvm_dep() { echo "The nvm (node version manager) is required to install node and npm." echo "Use the following command to install nvm:" echo " curl \ https://raw.githubusercontent.com/creationix/nvm/v0.33.1/install.sh | bash" echo "" } print_npm_dep() { echo "The following node dependencies are required: " echo " npm install babel-cli nyc babel-plugin-istanbul merge-source-map" echo "" } check_architecture() { architecture=$(uname -m) case $architecture in i386|i686|x86_32) ;; *) echo "Error: You can measure test coverage only on x86 32-bit." exit 1 esac } if [ "$#" -gt "0" ] && ( [ "$1" == "-h" ] || [ "$1" == "--help" ] ); then echo "Measure JavaScript and C coverage and create a html report" echo "out of the results" echo "" echo "Usage: $0 [NODE_MODULES_DIR]" echo "" echo "Optional Arguments:" echo " NODE_MODULES_DIR Specifies the node_module directory, where" echo " the nodejs dependencies are installed." echo "" echo "The created html reports can be found in the 'coverage' directory," echo "which will be created in the IoT.js project source dir. The C and" echo "JavaScript coverage reports are in the 'c' and 'js' subdirectories" echo "respectively. The reports can be viewed by opening the 'index.html'" echo "file in a web browser of your choice." echo "" echo "Running the script will require some additional dependencies." echo "" print_dep print_nvm_dep print_npm_dep exit 0 fi # Don't run this script on x86_64 architecture, only on x86_32 check_architecture tools_dir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" iotjs_root=$(readlink -f "$tools_dir/..") test -e ~/.nvm if [ "$?" -ne "0" ]; then print_nvm_dep exit 1 fi # Make available the nvm command. . ~/.nvm/nvm.sh . ~/.profile # Istanbul and babel require node version > 4.0. nvm install 6.11.0 dpkg -l lcov >> /dev/null 2>&1 && \ dpkg -l gcc-multilib >> /dev/null 2>&1 if [ "$?" -ne "0" ]; then print_dep exit 1 fi modules_dir=$(readlink -f "$(npm bin)/..") if [ "$#" -gt "0" ]; then path=$(readlink -f $1) if [ ! -d "$path" ] || [ $(basename "$path") != "node_modules" ]; then echo "'$1' is not a node_modules directory" exit 1 fi test -e $path/.bin/nyc && \ test -e $path/.bin/babel if [ "$?" -ne "0" ]; then print_npm_dep exit 1 fi modules_dir="$path" else test -e $modules_dir/.bin/nyc && \ test -e $modules_dir/.bin/babel if [ "$?" -ne "0" ]; then print_npm_dep exit 1 fi fi cd $iotjs_root # Transpile JS files to provide line counters $modules_dir/.bin/babel --plugins="babel-plugin-istanbul" \ src/js/ --out-dir src/cover_js/ # Backup original module files, and replace them with the transpiled files mv src/js src/orig_js mv src/cover_js src/js # Build iot.js # We need to use the system allocator to have enough memory, for now this can # only be done with a 32-bit build tools/build.py --jerry-cmake-param="-DFEATURE_SYSTEM_ALLOCATOR=ON" \ --target-arch=x86 --compile-flag="-coverage" --no-snapshot --no-check-test # Run tests build/i686-linux/debug/bin/iotjs tools/check_test.js -- output-coverage=yes # Revert to original module files rm -rf src/js mv src/orig_js src/js # Generate js coverage report mkdir -p .coverage_output $modules_dir/.bin/nyc report --reporter=lcov \ --report-dir=coverage --temp-directory=.coverage_output rm -rf .coverage_output rm -rf coverage/js mv coverage/lcov-report coverage/js # Generate c coverage report lcov -t "c_coverage" -o ".c-coverage.info" -c -d build/i686-linux/debug/ lcov --remove ".c-coverage.info" 'iotjs/deps/*' -o ".c-coverage.info" genhtml -o coverage/c .c-coverage.info rm .c-coverage.info cd - iotjs-1.0/tools/measure_js_heap.py000077500000000000000000000044531312466455500173720ustar00rootroot00000000000000#!/usr/bin/env python # Copyright 2017-present Samsung Electronics Co., Ltd. and other contributors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. from __future__ import print_function import argparse import os import re import subprocess import sys from common_py import path from common_py.system.filesystem import FileSystem as fs def get_arguments(): parser = argparse.ArgumentParser() parser.add_argument('--base', required=True, help='Path to the base IoT.js binary') parser.add_argument('--new', required=True, help='Path to the new IoT.js binary') script_args = parser.parse_args() return script_args def run_iotjs(cmd): pattern = re.compile(r'Peak allocated = (\d+) bytes') try: output = subprocess.check_output(cmd, stderr=subprocess.STDOUT) except subprocess.CalledProcessError as err: return "" match = pattern.search(str(output)) if match: return match.group(1) else: return "" if __name__ == "__main__": script_args = get_arguments() print("**JS heap peak (bytes)**\n") print("| {0:^40} | {1:^10} | {2:^10} |".format("Test file", "base", "new")) print("| {0} | {1} | {2} |".format("-"*40, "-"*10, "-"*10)) for test_file in os.listdir(path.RUN_PASS_DIR): if test_file.endswith(".js"): line = "| " + test_file + " | " cmd = [script_args.base, '--memstat', os.path.join(path.RUN_PASS_DIR, test_file) ] base_out = run_iotjs(cmd) cmd = [script_args.new, '--memstat', os.path.join(path.RUN_PASS_DIR, test_file) ] new_out = run_iotjs(cmd) if base_out or new_out: print("| {0:40} | {1:^10} | {2:^10} |" .format(test_file, base_out, new_out)) iotjs-1.0/tools/mem_stats.sh000077500000000000000000000066721312466455500162230ustar00rootroot00000000000000#!/bin/bash # Copyright 2015-present Samsung Electronics Co., Ltd. and other contributors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Usage if [ "$#" -lt 3 ] then echo "$0: Benchmark memory usage of IoT.js" echo "" echo "Usage: $0 [-d] IOTJS IOTJS_MEMSTATS BENCHMARK..." echo "" echo "Positional arguments:" echo " IOTJS path to IoT.js engine built without memory" echo " statistics support" echo " IOTJS_MEMSTATS path to IoT.js engine built with memory statistics" echo " support" echo " BENCHMARK... paths to JavaScript programs to be used as the" echo " benchmark suite" echo "" echo "Optional arguments:" echo " -d generate semicolon-delimited output (default:" echo " formatted human-readable output)" echo "" echo "The tool benchmarks the memory usage of IoT.js with the help of two" echo "different builds and a suite of JavaScript programs. Each benchmark" echo "script is executed by both builds: the \"memstats\" build reports" echo "statistics retrieved from JerryScript, while the \"normal\" build" echo "reports RSS results." exit 1 fi # Choosing table or semicolon-separated output mode if [ "$1" == "-d" ] then TABLE="no" PRINT_TEST_NAME_AWK_SCRIPT='{printf "%s;", $1}' PRINT_TOTAL_AWK_SCRIPT='{printf "%d;%d\n", $1, $2 * 1024}' shift else PRINT_TEST_NAME_AWK_SCRIPT='{printf "%30s", $1}' PRINT_TOTAL_AWK_SCRIPT='{printf "%25d%25d\n", $1, $2 * 1024}' TABLE="yes" fi function fail_msg { echo "$1" exit 1 } # Engine # Check if the specified build supports memory statistics options function is_mem_stats_build { [ -x "$1" ] || fail_msg "Engine '$1' is not executable" tmpfile=`mktemp` "$1" --memstat $tmpfile 2>&1 | \ grep -- "Ignoring memory statistics option" 2>&1 > /dev/null code=$? rm $tmpfile return $code } IOTJS=$(readlink -f "$1") shift is_mem_stats_build "$IOTJS" || fail_msg \ "First engine specified should be built without memory statistics support" IOTJS_MEM_STATS=$(readlink -f "$1") shift is_mem_stats_build "$IOTJS_MEM_STATS" && fail_msg \ "Second engine specified should be built with memory statistics support" # Benchmarks list BENCHMARKS="" while [ $# -ne 0 ] do BENCHMARKS="$BENCHMARKS $1" shift done # Running if [ "$TABLE" == "yes" ] then awk 'BEGIN {printf "%30s%25s%25s\n", "Test name", "Peak Heap (jerry)", \ "Maximum RSS"}' echo fi STARTDIR=$(pwd) for bench in $BENCHMARKS do bench_name=$(basename -s '.js' $bench) bench_canon=$(readlink -f $bench) cd `dirname $bench_canon` echo "$bench_name" | awk "$PRINT_TEST_NAME_AWK_SCRIPT" MEM_STATS=$("$IOTJS_MEM_STATS" --memstat $bench_canon | \ grep -e "Peak allocated =" | grep -o "[0-9]*") RSS=$($STARTDIR/deps/jerry/tools/rss-measure.sh "$IOTJS" $bench_canon | \ tail -n 1 | grep -o "[0-9]*") echo $MEM_STATS $RSS | xargs | awk "$PRINT_TOTAL_AWK_SCRIPT" cd $STARTDIR done iotjs-1.0/tools/module_analyzer.py000066400000000000000000000177051312466455500174330ustar00rootroot00000000000000#!/usr/bin/env python # Copyright 2017-present Samsung Electronics Co., Ltd. and other contributors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. from __future__ import print_function import re from common_py.system.filesystem import FileSystem as fs from common_py.system.executor import Executor as ex from common_py.system.platform import Platform from common_py import path platform = Platform() def resolve_modules(options): """ Resolve include/exclude module lists based on command line arguments and build config. """ # Load the modules which are always enabled and the include/exclude sets build_modules_always = set(options.config['module']['always']) build_modules_includes = set(options.config['module']['include']) build_modules_excludes = set(options.config['module']['exclude']['all']) if options.target_os: system_os = options.target_os if system_os == 'tizen': system_os = 'linux' build_modules_excludes |= set( options.config['module']['exclude'][system_os]) # Build options has higher priority than defaults build_modules_excludes -= options.iotjs_include_module # By default the target included modules are: # - always module set from the build config # - modules specified by the command line argument include_modules = set() | build_modules_always include_modules |= options.iotjs_include_module if not options.iotjs_minimal_profile: # Add the include set from the build config to # the target include modules set include_modules |= build_modules_includes # Check if there are any modules which are not allowed to be excluded impossible_to_exclude = options.iotjs_exclude_module & build_modules_always if impossible_to_exclude: ex.fail('Cannot exclude modules which are always enabled: %s' % ', '.join(impossible_to_exclude)) # Finally build up the excluded module set: # - use the command line exclude set # - use the exclude set from the build config exclude_modules = options.iotjs_exclude_module | build_modules_excludes # Remove the excluded modules from the included modules set include_modules -= exclude_modules return include_modules, exclude_modules def analyze_module_dependency(include_modules, exclude_modules): analyze_queue = set(include_modules) # copy the set analyze_queue.add('iotjs') js_modules = { 'native' } native_modules = { 'process' } while analyze_queue: item = analyze_queue.pop() js_modules.add(item) js_module_path = fs.join(path.PROJECT_ROOT, 'src', 'js', item + '.js') if not fs.exists(js_module_path): ex.fail('Cannot read file "%s"' % js_module_path) with open(js_module_path) as module: content = module.read() # Pretend to ignore comments in JavaScript re_js_comments = "\/\/.*|\/\*.*\*\/"; content = re.sub(re_js_comments, "", content) # Get all required modules re_js_module = 'require\([\'\"](.*?)[\'\"]\)' required_modules = set(re.findall(re_js_module, content)) # Check if there is any required modules in the exclude set problem_modules = required_modules & exclude_modules if problem_modules: ex.fail('Cannot exclude module(s) "%s" since "%s" requires them' % (', '.join(problem_modules), item)) # Add all modules to analytze queue which are not yet analyzed analyze_queue |= required_modules - js_modules # Get all native modules re_native_module = 'process.binding\(process.binding.(.*?)\)' native_modules |= set(re.findall(re_native_module, content)) js_modules.remove('native') modules = {'js': sorted(js_modules), 'native': sorted(native_modules)} return modules def _normalize_module_set(argument): """ Split up argument via commas and make sure they have a valid value """ return set([module.strip() for module in argument.split(',') if module.strip()]) def _load_options(argv): try: basestring except: # in Python 3.x there is no basestring just str basestring = str # Specify the allowed options for the script opts = [ {'name': 'iotjs-minimal-profile', 'args': dict(action='store_true', default=False, help='Build IoT.js with minimal profile') }, {'name': 'iotjs-include-module', 'args': dict(action='store', default=set(), type=_normalize_module_set, help='Specify iotjs modules which should be included ' '(format: module_1,module_2,...)') }, {'name': 'iotjs-exclude-module', 'args': dict(action='store', default=set(), type=_normalize_module_set, help='Specify iotjs modules which should be excluded ' '(format: module_1,module_2,...)') }, {'name': 'target-os', 'args': dict(choices=['linux', 'darwin', 'nuttx', 'tizen', 'tizenrt'], default=platform.os, type=str.lower, help='Specify the target os: %(choices)s (default: %(default)s)') }, {'name': 'mode', 'args': dict(choices=['verbose', 'cmake-dump'], default='verbose', help='Execution mode of the script. Choices: %(choices)s ' '(default: %(default)s)' ), }, ] allowed_options = [opt['name'] for opt in opts] arg_config = list(filter(lambda x: x.startswith('--config='), argv)) config_path = path.BUILD_CONFIG_PATH if arg_config: config_path = arg_config[-1].split('=', 1)[1] # Read config file and apply it to argv. with open(config_path, 'rb') as f: config = json.loads(f.read().decode('ascii')) loaded_argv = [] for opt_key, opt_value in config['build_option'].items(): if opt_key not in allowed_options: continue # ignore any option that is not for us if isinstance(opt_value, basestring) and opt_value: loaded_argv.append('--%s=%s' % (opt_key, opt_value)) elif isinstance(opt_value, bool): if opt_value: loaded_argv.append('--%s' % opt_key) elif isinstance(opt_value, int): loaded_argv.append('--%s=%s' % (opt_key, opt_value)) elif isinstance(opt_value, list): for val in opt_value: loaded_argv.append('--%s=%s' % (opt_key, val)) # Apply command line argument to argv. loaded_argv.extend([arg for arg in argv[1:] if not arg.startswith('--config=')]) # Build up the argument parser and process the args parser = argparse.ArgumentParser() for opt in opts: parser.add_argument('--%s' % opt['name'], **opt['args']) options = parser.parse_args(loaded_argv) options.config = config return options def _main(): options = _load_options(sys.argv) includes, excludes = resolve_modules(options) modules = analyze_module_dependency(includes, excludes) if options.mode == 'cmake-dump': print('IOTJS_JS_MODULES=' + ';'.join(modules['js'])) print('IOTJS_NATIVE_MODULES=' + ';'.join(modules['native'])) else: print('Selected js modules: %s' % ', '.join(modules['js'])) print('Selected native modules: %s' % ', '.join(modules['native'])) if __name__ == '__main__': import argparse import json import sys _main() iotjs-1.0/tools/precommit.py000077500000000000000000000161031312466455500162320ustar00rootroot00000000000000#!/usr/bin/env python # Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. from __future__ import print_function import argparse import sys import os import json from common_py import path from common_py.system.filesystem import FileSystem as fs from common_py.system.executor import Executor as ex from common_py.system.platform import Platform from check_tidy import check_tidy TESTS=['host-linux', 'host-darwin', 'rpi2', 'nuttx', 'misc', 'artik10', 'coverity'] BUILDTYPES=['debug', 'release'] NUTTXTAG = 'nuttx-7.19' def get_config(): config_path = path.BUILD_CONFIG_PATH with open(config_path, 'r') as f: config = json.loads(f.read().encode('ascii')) return config def parse_option(): parser = argparse.ArgumentParser( description='IoT.js pre-commit script.', epilog='If no arguments are given, runs full test.') parser.add_argument('--test', choices=TESTS, action='append') parser.add_argument('--buildtype', choices=BUILDTYPES, action='append') parser.add_argument('--buildoptions', action='store', default='', help='A comma separated list of extra buildoptions') option = parser.parse_args(sys.argv[1:]) if option.test is None: option.test = TESTS if option.buildtype is None: option.buildtype = BUILDTYPES return option def setup_nuttx_root(nuttx_root): # Step 1 fs.maybe_make_directory(nuttx_root) fs.chdir(nuttx_root) if not fs.exists('nuttx'): ex.check_run_cmd('git', ['clone', 'https://bitbucket.org/nuttx/nuttx.git']) fs.chdir('nuttx') ex.check_run_cmd('git', ['checkout', NUTTXTAG]) fs.chdir('..') if not fs.exists('apps'): ex.check_run_cmd('git', ['clone', 'https://bitbucket.org/nuttx/apps.git']) fs.chdir('apps') ex.check_run_cmd('git', ['checkout', NUTTXTAG]) fs.chdir('..') # Step 2 fs.maybe_make_directory(fs.join(nuttx_root, 'apps', 'system', 'iotjs')) for file in fs.listdir(fs.join(path.PROJECT_ROOT, 'config', 'nuttx', 'stm32f4dis','app')): fs.copy(fs.join(path.PROJECT_ROOT, 'config', 'nuttx', 'stm32f4dis', 'app', file), fs.join(nuttx_root, 'apps', 'system', 'iotjs')) # Step 3 fs.chdir(fs.join(nuttx_root, 'nuttx', 'tools')) ex.check_run_cmd('./configure.sh', ['stm32f4discovery/usbnsh']) fs.chdir('..') fs.copy(fs.join(path.PROJECT_ROOT, 'config', 'nuttx', 'stm32f4dis', '.config.travis'), '.config') def build_nuttx(nuttx_root, buildtype, maketarget): fs.chdir(fs.join(nuttx_root, 'nuttx')) if buildtype == "release": rflag = 'R=1' else: rflag = 'R=0' ex.check_run_cmd('make', [maketarget, 'IOTJS_ROOT_DIR=' + path.PROJECT_ROOT, rflag]) def setup_tizen_root(tizen_root): if fs.exists(tizen_root): fs.chdir(tizen_root) ex.check_run_cmd('git', ['pull']) fs.chdir(path.PROJECT_ROOT) else: ex.check_run_cmd('git', ['clone', 'https://github.com/pmarcinkiew/tizen3.0_rootstrap.git', tizen_root]) def build(buildtype, args=[]): fs.chdir(path.PROJECT_ROOT) ex.check_run_cmd('./tools/build.py', ['--buildtype=' + buildtype] + args) def get_os_dependency_exclude_module(exclude_module): os_dependency_module = {} all_module = set(exclude_module['all']) for os_name in exclude_module.keys(): if not os_name == 'all': os_dependency_module[os_name] = \ list(all_module | set(exclude_module[os_name])) return os_dependency_module option = parse_option() config = get_config() os_dependency_module = \ get_os_dependency_exclude_module(config['module']['exclude']) # Excluded modules are also included in the build test. # Travis will test all implemented modules. for os_name in os_dependency_module: if os_dependency_module[os_name]: os_dependency_module[os_name] = \ ['--iotjs-include-module=' + ','.join(os_dependency_module[os_name])] build_args = [] if option.buildoptions: build_args.extend(option.buildoptions.split(',')) for test in option.test: if test == "host-linux": for buildtype in option.buildtype: build(buildtype, os_dependency_module['linux'] + build_args) if test == "host-darwin": for buildtype in option.buildtype: build(buildtype, os_dependency_module['darwin'] + build_args) elif test == "rpi2": for buildtype in option.buildtype: build(buildtype, ['--target-arch=arm', '--target-board=rpi2'] + os_dependency_module['linux'] + build_args) elif test == "artik10": for buildtype in option.buildtype: tizen_root = fs.join(path.PROJECT_ROOT, 'deps', 'tizen') setup_tizen_root(tizen_root) build(buildtype, ['--target-arch=arm', '--target-os=tizen', '--target-board=artik10', '--compile-flag=--sysroot=' + tizen_root ] + os_dependency_module['linux'] + build_args) elif test == "nuttx": current_dir = os.getcwd() for buildtype in option.buildtype: nuttx_root=fs.join(path.PROJECT_ROOT, 'deps', 'nuttx') setup_nuttx_root(nuttx_root) build_nuttx(nuttx_root, buildtype, 'context') build(buildtype, ['--target-arch=arm', '--target-os=nuttx', '--nuttx-home=' + fs.join(nuttx_root, 'nuttx'), '--target-board=stm32f4dis', '--jerry-heaplimit=78'] + os_dependency_module['nuttx'] + build_args) build_nuttx(nuttx_root, buildtype, 'all') fs.chdir(current_dir) elif test == "misc": args = [] if os.getenv('TRAVIS') != None: args = ['--travis'] ex.check_run_cmd('tools/check_signed_off.sh', args) if not check_tidy(path.PROJECT_ROOT): ex.fail("Failed tidy check") build("debug", build_args) build("debug", ['--no-snapshot', '--jerry-lto'] + os_dependency_module['linux'] + build_args) build("debug", ['--iotjs-minimal-profile'] + build_args) elif test == "coverity": build("debug", os_dependency_module['linux'] + build_args) iotjs-1.0/tools/test_runner.js000066400000000000000000000100661312466455500165660ustar00rootroot00000000000000/* Copyright 2016-present Samsung Electronics Co., Ltd. and other contributors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var testdriver = require('testdriver'); var console_wrapper = require('common_js/module/console'); var builtin_modules = Object.keys(process.native_sources).concat(Object.keys(process.binding)); function Runner(driver) { process._exiting = false; this.driver = driver; this.test = driver.currentTest(); this.finished = false; if (driver.skipModule) { this.skipModule = driver.skipModule; this.skipModuleLength = this.skipModule.length; } else { this.skipModuleLength = 0; } if (driver.options.quiet == 'yes') { this.console = console; console = console_wrapper; } return this; } Runner.prototype.cleanup = function() { if (this.driver.options.quiet == 'yes') { console = this.console; } this.driver = null; this.attr = null; if (this.timer != null) { clearTimeout(this.timer); this.timer = null; } }; Runner.prototype.spin = function() { var that = this; setTimeout(function() { var timerOnlyAlive = !testdriver.isAliveExceptFor(that.timer); if (timerOnlyAlive) { timerOnlyAlive = !process._onNextTick(); } if (timerOnlyAlive) { process.exit(0); } else { if (!that.finished) { that.spin(); } } }, 0); }; Runner.prototype.checkSkipModule = function() { for (var i = 0; i < this.skipModuleLength; i++) { if (this.test['name'].indexOf(this.skipModule[i]) >= 0) { return true; } } return false; }; Runner.prototype.checkSupportedModule = function() { // Cut off the '.js' ending var name = this.test['name'].slice(0, -3); // test_mod_smt -> [test, mod, smt] // test_modsmt -> [test, modsmt] var parts = name.split('_'); if (parts[0] != 'test') { // test filename does not start with 'test_' so we'll just // assume we support it. return true; } // The second part of the array contains the module // which is under test var tested_module = parts[1]; for (var i = 0; i < builtin_modules.length; i++) { if (tested_module == builtin_modules[i]) { return true; } } // In any other case we do not support this js file. return false; } Runner.prototype.run = function() { if (!this.checkSupportedModule()) { this.test.reason = 'unsupported module by iotjs build'; this.finish('skip'); return; } var skip = this.test['skip']; if (skip) { if ((skip.indexOf('all') >= 0) || (skip.indexOf(this.driver.os) >= 0) || (skip.indexOf(this.driver.stability) >= 0)) { this.finish('skip'); return; } } if (this.skipModuleLength && this.checkSkipModule()) { this.test.reason = 'exclude module'; this.finish('skip'); return; } this.timer = null; if (this.test['timeout']) { var timeout = this.test['timeout']; if (timeout) { var that = this; this.timer = setTimeout(function () { that.finish('timeout'); }, timeout * 1000); } } try { var source = this.driver.test(); eval(source); } catch(e) { if (this.test['expected-failure']) { this.finish('pass'); } else if (this.test['uncaught']) { throw e; } else { console.error(e); this.finish('fail'); } } finally { if (!this.finished) { this.spin(); } } }; Runner.prototype.finish = function(status) { if (this.finished) return; this.finished = true; this.driver.emitter.emit('nextTest', this.driver, status, this.test); }; module.exports.Runner = Runner; iotjs-1.0/tools/zlib-Makefile.patch000066400000000000000000000016221312466455500173520ustar00rootroot00000000000000--- Makefile 2016-12-05 19:10:42.985931000 +0900 +++ Makefile.patched 2016-12-05 19:19:14.437931000 +0900 @@ -16,7 +16,7 @@ # To install in $HOME instead of /usr/local, use: # make install prefix=$HOME -CC=gcc +CC=arm-linux-gnueabihf-gcc CFLAGS=-O3 -D_LARGEFILE64_SOURCE=1 -DHAVE_HIDDEN #CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7 @@ -27,8 +27,8 @@ SFLAGS=-O3 -fPIC -D_LARGEFILE64_SOURCE=1 -DHAVE_HIDDEN LDFLAGS= TEST_LDFLAGS=-L. libz.a -LDSHARED=gcc -shared -Wl,-soname,libz.so.1,--version-script,zlib.map -CPP=gcc -E +LDSHARED=arm-linux-gnueabihf-gcc -shared -Wl,-soname,libz.so.1,--version-script,zlib.map +CPP=arm-linux-gnueabihf-gcc -E STATICLIB=libz.a SHAREDLIB=libz.so @@ -36,9 +36,9 @@ SHAREDLIBM=libz.so.1 LIBS=$(STATICLIB) $(SHAREDLIBV) -AR=ar +AR=arm-linux-gnueabihf-ar ARFLAGS=rc -RANLIB=ranlib +RANLIB=arm-linux-gnueabihf-ranlib LDCONFIG=ldconfig LDSHAREDLIBC=-lc TAR=tar pax_global_header00006660000000000000000000000064130735630560014522gustar00rootroot0000000000000052 comment=d6a49efe3ff667a35145119b504f1f583d56ea57 iotjs-1.0/deps/http-parser/000077500000000000000000000000001307356305600157165ustar00rootroot00000000000000iotjs-1.0/deps/http-parser/.gitignore000066400000000000000000000003611307356305600177060ustar00rootroot00000000000000/out/ core tags *.o test test_g test_fast bench url_parser parsertrace parsertrace_g *.mk *.Makefile *.so.* *.a # Visual Studio uglies *.suo *.sln *.vcxproj *.vcxproj.filters *.vcxproj.user *.opensdf *.ncrunchsolution* *.sdf *.vsp *.psess iotjs-1.0/deps/http-parser/.mailmap000066400000000000000000000007401307356305600173400ustar00rootroot00000000000000# update AUTHORS with: # git log --all --reverse --format='%aN <%aE>' | perl -ne 'BEGIN{print "# Authors ordered by first contribution.\n"} print unless $h{$_}; $h{$_} = 1' > AUTHORS Ryan Dahl Salman Haq Simon Zimmermann Thomas LE ROUX LE ROUX Thomas Thomas LE ROUX Thomas LE ROUX Fedor Indutny iotjs-1.0/deps/http-parser/.travis.yml000066400000000000000000000002041307356305600200230ustar00rootroot00000000000000language: c compiler: - clang - gcc script: - "make" notifications: email: false irc: - "irc.freenode.net#node-ci" iotjs-1.0/deps/http-parser/AUTHORS000066400000000000000000000046441307356305600167760ustar00rootroot00000000000000# Authors ordered by first contribution. Ryan Dahl Jeremy Hinegardner Sergey Shepelev Joe Damato tomika Phoenix Sol Cliff Frey Ewen Cheslack-Postava Santiago Gala Tim Becker Jeff Terrace Ben Noordhuis Nathan Rajlich Mark Nottingham Aman Gupta Tim Becker Sean Cunningham Peter Griess Salman Haq Cliff Frey Jon Kolb Fouad Mardini Paul Querna Felix Geisendörfer koichik Andre Caron Ivo Raisr James McLaughlin David Gwynne Thomas LE ROUX Randy Rizun Andre Louis Caron Simon Zimmermann Erik Dubbelboer Martell Malone Bertrand Paquet BogDan Vatra Peter Faiman Corey Richardson Tóth Tamás Cam Swords Chris Dickinson Uli Köhler Charlie Somerville Patrik Stutz Fedor Indutny runner Alexis Campailla David Wragg Vinnie Falco Alex Butum Rex Feng Alex Kocharin Mark Koopman Helge Heß Alexis La Goutte George Miroshnykov Maciej MaÅ‚ecki Marc O'Morain Jeff Pinner Timothy J Fontaine Akagi201 Romain Giraud Jay Satiro Arne Steen Kjell Schubert iotjs-1.0/deps/http-parser/CMakeLists.txt000066400000000000000000000014671307356305600204660ustar00rootroot00000000000000cmake_minimum_required(VERSION 2.8) PROJECT(http-parser C) set(targetName httpparser) INCLUDE_DIRECTORIES(./) if("${OS}" MATCHES "NUTTX|TIZENRT") set(TARGET_INCLUDE "${NUTTX_HOME}/include") set(TARGET_INCLUDE ${TARGET_INCLUDE} "${NUTTX_HOME}/include/cxx") INCLUDE_DIRECTORIES(./ ${TARGET_INCLUDE}) endif() if("${CMAKE_BUILD_TYPE}" MATCHES "Release|MinSizeRel") # If we are building for release modify it to MinSizeRel for -Os option. set(CMAKE_BUILD_TYPE "MinSizeRel") else() # Any other case just assume debug build. set(CMAKE_BUILD_TYPE "Debug") endif() message("HTTP Parser configured with:") message(STATUS "CMAKE_BUILD_TYPE ${CMAKE_BUILD_TYPE}") message(STATUS "OS ${OS}") message(STATUS "NUTTX_HOME ${NUTTX_HOME}") ADD_LIBRARY(${targetName} STATIC http_parser.c) iotjs-1.0/deps/http-parser/LICENSE-MIT000066400000000000000000000023431307356305600173540ustar00rootroot00000000000000http_parser.c is based on src/http/ngx_http_parse.c from NGINX copyright Igor Sysoev. Additional changes are licensed under the same terms as NGINX and copyright Joyent, Inc. and other Node contributors. All rights reserved. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. iotjs-1.0/deps/http-parser/Makefile000066400000000000000000000110051307356305600173530ustar00rootroot00000000000000# Copyright Joyent, Inc. and other Node contributors. All rights reserved. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS # IN THE SOFTWARE. PLATFORM ?= $(shell sh -c 'uname -s | tr "[A-Z]" "[a-z]"') ifeq (darwin,$(PLATFORM)) SONAME ?= libhttp_parser.2.5.0.dylib SOEXT ?= dylib else SONAME ?= libhttp_parser.so.2.5.0 SOEXT ?= so endif CC?=gcc AR?=ar CPPFLAGS ?= LDFLAGS ?= CPPFLAGS += -I. CPPFLAGS_DEBUG = $(CPPFLAGS) -DHTTP_PARSER_STRICT=1 CPPFLAGS_DEBUG += $(CPPFLAGS_DEBUG_EXTRA) CPPFLAGS_FAST = $(CPPFLAGS) -DHTTP_PARSER_STRICT=0 CPPFLAGS_FAST += $(CPPFLAGS_FAST_EXTRA) CPPFLAGS_BENCH = $(CPPFLAGS_FAST) CFLAGS += -Wall -Wextra -Werror CFLAGS_DEBUG = $(CFLAGS) -O0 -g $(CFLAGS_DEBUG_EXTRA) CFLAGS_FAST = $(CFLAGS) -O3 $(CFLAGS_FAST_EXTRA) CFLAGS_BENCH = $(CFLAGS_FAST) -Wno-unused-parameter CFLAGS_LIB = $(CFLAGS_FAST) -fPIC LDFLAGS_LIB = $(LDFLAGS) -shared INSTALL ?= install PREFIX ?= $(DESTDIR)/usr/local LIBDIR = $(PREFIX)/lib INCLUDEDIR = $(PREFIX)/include ifneq (darwin,$(PLATFORM)) # TODO(bnoordhuis) The native SunOS linker expects -h rather than -soname... LDFLAGS_LIB += -Wl,-soname=$(SONAME) endif test: test_g test_fast ./test_g ./test_fast test_g: http_parser_g.o test_g.o $(CC) $(CFLAGS_DEBUG) $(LDFLAGS) http_parser_g.o test_g.o -o $@ test_g.o: test.c http_parser.h Makefile $(CC) $(CPPFLAGS_DEBUG) $(CFLAGS_DEBUG) -c test.c -o $@ http_parser_g.o: http_parser.c http_parser.h Makefile $(CC) $(CPPFLAGS_DEBUG) $(CFLAGS_DEBUG) -c http_parser.c -o $@ test_fast: http_parser.o test.o http_parser.h $(CC) $(CFLAGS_FAST) $(LDFLAGS) http_parser.o test.o -o $@ test.o: test.c http_parser.h Makefile $(CC) $(CPPFLAGS_FAST) $(CFLAGS_FAST) -c test.c -o $@ bench: http_parser.o bench.o $(CC) $(CFLAGS_BENCH) $(LDFLAGS) http_parser.o bench.o -o $@ bench.o: bench.c http_parser.h Makefile $(CC) $(CPPFLAGS_BENCH) $(CFLAGS_BENCH) -c bench.c -o $@ http_parser.o: http_parser.c http_parser.h Makefile $(CC) $(CPPFLAGS_FAST) $(CFLAGS_FAST) -c http_parser.c test-run-timed: test_fast while(true) do time ./test_fast > /dev/null; done test-valgrind: test_g valgrind ./test_g libhttp_parser.o: http_parser.c http_parser.h Makefile $(CC) $(CPPFLAGS_FAST) $(CFLAGS_LIB) -c http_parser.c -o libhttp_parser.o library: libhttp_parser.o $(CC) $(LDFLAGS_LIB) -o $(SONAME) $< package: http_parser.o $(AR) rcs libhttp_parser.a http_parser.o url_parser: http_parser.o contrib/url_parser.c $(CC) $(CPPFLAGS_FAST) $(CFLAGS_FAST) $^ -o $@ url_parser_g: http_parser_g.o contrib/url_parser.c $(CC) $(CPPFLAGS_DEBUG) $(CFLAGS_DEBUG) $^ -o $@ parsertrace: http_parser.o contrib/parsertrace.c $(CC) $(CPPFLAGS_FAST) $(CFLAGS_FAST) $^ -o parsertrace parsertrace_g: http_parser_g.o contrib/parsertrace.c $(CC) $(CPPFLAGS_DEBUG) $(CFLAGS_DEBUG) $^ -o parsertrace_g tags: http_parser.c http_parser.h test.c ctags $^ install: library $(INSTALL) -D http_parser.h $(INCLUDEDIR)/http_parser.h $(INSTALL) -D $(SONAME) $(LIBDIR)/$(SONAME) ln -s $(LIBDIR)/$(SONAME) $(LIBDIR)/libhttp_parser.$(SOEXT) install-strip: library $(INSTALL) -D http_parser.h $(INCLUDEDIR)/http_parser.h $(INSTALL) -D -s $(SONAME) $(LIBDIR)/$(SONAME) ln -s $(LIBDIR)/$(SONAME) $(LIBDIR)/libhttp_parser.$(SOEXT) uninstall: rm $(INCLUDEDIR)/http_parser.h rm $(LIBDIR)/$(SONAME) rm $(LIBDIR)/libhttp_parser.so clean: rm -f *.o *.a tags test test_fast test_g \ http_parser.tar libhttp_parser.so.* \ url_parser url_parser_g parsertrace parsertrace_g contrib/url_parser.c: http_parser.h contrib/parsertrace.c: http_parser.h .PHONY: clean package test-run test-run-timed test-valgrind install install-strip uninstall iotjs-1.0/deps/http-parser/README.md000066400000000000000000000163311307356305600172010ustar00rootroot00000000000000HTTP Parser =========== [![Build Status](https://travis-ci.org/joyent/http-parser.png?branch=master)](https://travis-ci.org/joyent/http-parser) This is a parser for HTTP messages written in C. It parses both requests and responses. The parser is designed to be used in performance HTTP applications. It does not make any syscalls nor allocations, it does not buffer data, it can be interrupted at anytime. Depending on your architecture, it only requires about 40 bytes of data per message stream (in a web server that is per connection). Features: * No dependencies * Handles persistent streams (keep-alive). * Decodes chunked encoding. * Upgrade support * Defends against buffer overflow attacks. The parser extracts the following information from HTTP messages: * Header fields and values * Content-Length * Request method * Response status code * Transfer-Encoding * HTTP version * Request URL * Message body Usage ----- One `http_parser` object is used per TCP connection. Initialize the struct using `http_parser_init()` and set the callbacks. That might look something like this for a request parser: ```c http_parser_settings settings; settings.on_url = my_url_callback; settings.on_header_field = my_header_field_callback; /* ... */ http_parser *parser = malloc(sizeof(http_parser)); http_parser_init(parser, HTTP_REQUEST); parser->data = my_socket; ``` When data is received on the socket execute the parser and check for errors. ```c size_t len = 80*1024, nparsed; char buf[len]; ssize_t recved; recved = recv(fd, buf, len, 0); if (recved < 0) { /* Handle error. */ } /* Start up / continue the parser. * Note we pass recved==0 to signal that EOF has been received. */ nparsed = http_parser_execute(parser, &settings, buf, recved); if (parser->upgrade) { /* handle new protocol */ } else if (nparsed != recved) { /* Handle error. Usually just close the connection. */ } ``` HTTP needs to know where the end of the stream is. For example, sometimes servers send responses without Content-Length and expect the client to consume input (for the body) until EOF. To tell http_parser about EOF, give `0` as the fourth parameter to `http_parser_execute()`. Callbacks and errors can still be encountered during an EOF, so one must still be prepared to receive them. Scalar valued message information such as `status_code`, `method`, and the HTTP version are stored in the parser structure. This data is only temporally stored in `http_parser` and gets reset on each new message. If this information is needed later, copy it out of the structure during the `headers_complete` callback. The parser decodes the transfer-encoding for both requests and responses transparently. That is, a chunked encoding is decoded before being sent to the on_body callback. The Special Problem of Upgrade ------------------------------ HTTP supports upgrading the connection to a different protocol. An increasingly common example of this is the Web Socket protocol which sends a request like GET /demo HTTP/1.1 Upgrade: WebSocket Connection: Upgrade Host: example.com Origin: http://example.com WebSocket-Protocol: sample followed by non-HTTP data. (See http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-75 for more information the Web Socket protocol.) To support this, the parser will treat this as a normal HTTP message without a body, issuing both on_headers_complete and on_message_complete callbacks. However http_parser_execute() will stop parsing at the end of the headers and return. The user is expected to check if `parser->upgrade` has been set to 1 after `http_parser_execute()` returns. Non-HTTP data begins at the buffer supplied offset by the return value of `http_parser_execute()`. Callbacks --------- During the `http_parser_execute()` call, the callbacks set in `http_parser_settings` will be executed. The parser maintains state and never looks behind, so buffering the data is not necessary. If you need to save certain data for later usage, you can do that from the callbacks. There are two types of callbacks: * notification `typedef int (*http_cb) (http_parser*);` Callbacks: on_message_begin, on_headers_complete, on_message_complete. * data `typedef int (*http_data_cb) (http_parser*, const char *at, size_t length);` Callbacks: (requests only) on_url, (common) on_header_field, on_header_value, on_body; Callbacks must return 0 on success. Returning a non-zero value indicates error to the parser, making it exit immediately. In case you parse HTTP message in chunks (i.e. `read()` request line from socket, parse, read half headers, parse, etc) your data callbacks may be called more than once. Http-parser guarantees that data pointer is only valid for the lifetime of callback. You can also `read()` into a heap allocated buffer to avoid copying memory around if this fits your application. Reading headers may be a tricky task if you read/parse headers partially. Basically, you need to remember whether last header callback was field or value and apply the following logic: (on_header_field and on_header_value shortened to on_h_*) ------------------------ ------------ -------------------------------------------- | State (prev. callback) | Callback | Description/action | ------------------------ ------------ -------------------------------------------- | nothing (first call) | on_h_field | Allocate new buffer and copy callback data | | | | into it | ------------------------ ------------ -------------------------------------------- | value | on_h_field | New header started. | | | | Copy current name,value buffers to headers | | | | list and allocate new buffer for new name | ------------------------ ------------ -------------------------------------------- | field | on_h_field | Previous name continues. Reallocate name | | | | buffer and append callback data to it | ------------------------ ------------ -------------------------------------------- | field | on_h_value | Value for current header started. Allocate | | | | new buffer and copy callback data to it | ------------------------ ------------ -------------------------------------------- | value | on_h_value | Value continues. Reallocate value buffer | | | | and append callback data to it | ------------------------ ------------ -------------------------------------------- Parsing URLs ------------ A simplistic zero-copy URL parser is provided as `http_parser_parse_url()`. Users of this library may wish to use it to parse URLs constructed from consecutive `on_url` callbacks. See examples of reading in headers: * [partial example](http://gist.github.com/155877) in C * [from http-parser tests](http://github.com/joyent/http-parser/blob/37a0ff8/test.c#L403) in C * [from Node library](http://github.com/joyent/node/blob/842eaf4/src/http.js#L284) in Javascript iotjs-1.0/deps/http-parser/bench.c000066400000000000000000000065101307356305600171430ustar00rootroot00000000000000/* Copyright Fedor Indutny. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to * deal in the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. */ #include "http_parser.h" #include #include #include #include static const char data[] = "POST /joyent/http-parser HTTP/1.1\r\n" "Host: github.com\r\n" "DNT: 1\r\n" "Accept-Encoding: gzip, deflate, sdch\r\n" "Accept-Language: ru-RU,ru;q=0.8,en-US;q=0.6,en;q=0.4\r\n" "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) " "AppleWebKit/537.36 (KHTML, like Gecko) " "Chrome/39.0.2171.65 Safari/537.36\r\n" "Accept: text/html,application/xhtml+xml,application/xml;q=0.9," "image/webp,*/*;q=0.8\r\n" "Referer: https://github.com/joyent/http-parser\r\n" "Connection: keep-alive\r\n" "Transfer-Encoding: chunked\r\n" "Cache-Control: max-age=0\r\n\r\nb\r\nhello world\r\n0\r\n\r\n"; static const size_t data_len = sizeof(data) - 1; static int on_info(http_parser* p) { return 0; } static int on_data(http_parser* p, const char *at, size_t length) { return 0; } static http_parser_settings settings = { .on_message_begin = on_info, .on_headers_complete = on_info, .on_message_complete = on_info, .on_header_field = on_data, .on_header_value = on_data, .on_url = on_data, .on_status = on_data, .on_body = on_data }; int bench(int iter_count, int silent) { struct http_parser parser; int i; int err; struct timeval start; struct timeval end; float rps; if (!silent) { err = gettimeofday(&start, NULL); assert(err == 0); } for (i = 0; i < iter_count; i++) { size_t parsed; http_parser_init(&parser, HTTP_REQUEST); parsed = http_parser_execute(&parser, &settings, data, data_len); assert(parsed == data_len); } if (!silent) { err = gettimeofday(&end, NULL); assert(err == 0); fprintf(stdout, "Benchmark result:\n"); rps = (float) (end.tv_sec - start.tv_sec) + (end.tv_usec - start.tv_usec) * 1e-6f; fprintf(stdout, "Took %f seconds to run\n", rps); rps = (float) iter_count / rps; fprintf(stdout, "%f req/sec\n", rps); fflush(stdout); } return 0; } int main(int argc, char** argv) { if (argc == 2 && strcmp(argv[1], "infinite") == 0) { for (;;) bench(5000000, 1); return 0; } else { return bench(5000000, 0); } } iotjs-1.0/deps/http-parser/contrib/000077500000000000000000000000001307356305600173565ustar00rootroot00000000000000iotjs-1.0/deps/http-parser/contrib/parsertrace.c000066400000000000000000000104001307356305600220300ustar00rootroot00000000000000/* Based on src/http/ngx_http_parse.c from NGINX copyright Igor Sysoev * * Additional changes are licensed under the same terms as NGINX and * copyright Joyent, Inc. and other Node contributors. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to * deal in the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. */ /* Dump what the parser finds to stdout as it happen */ #include "http_parser.h" #include #include #include int on_message_begin(http_parser* _) { (void)_; printf("\n***MESSAGE BEGIN***\n\n"); return 0; } int on_headers_complete(http_parser* _) { (void)_; printf("\n***HEADERS COMPLETE***\n\n"); return 0; } int on_message_complete(http_parser* _) { (void)_; printf("\n***MESSAGE COMPLETE***\n\n"); return 0; } int on_url(http_parser* _, const char* at, size_t length) { (void)_; printf("Url: %.*s\n", (int)length, at); return 0; } int on_header_field(http_parser* _, const char* at, size_t length) { (void)_; printf("Header field: %.*s\n", (int)length, at); return 0; } int on_header_value(http_parser* _, const char* at, size_t length) { (void)_; printf("Header value: %.*s\n", (int)length, at); return 0; } int on_body(http_parser* _, const char* at, size_t length) { (void)_; printf("Body: %.*s\n", (int)length, at); return 0; } void usage(const char* name) { fprintf(stderr, "Usage: %s $type $filename\n" " type: -x, where x is one of {r,b,q}\n" " parses file as a Response, reQuest, or Both\n", name); exit(EXIT_FAILURE); } int main(int argc, char* argv[]) { enum http_parser_type file_type; if (argc != 3) { usage(argv[0]); } char* type = argv[1]; if (type[0] != '-') { usage(argv[0]); } switch (type[1]) { /* in the case of "-", type[1] will be NUL */ case 'r': file_type = HTTP_RESPONSE; break; case 'q': file_type = HTTP_REQUEST; break; case 'b': file_type = HTTP_BOTH; break; default: usage(argv[0]); } char* filename = argv[2]; FILE* file = fopen(filename, "r"); if (file == NULL) { perror("fopen"); goto fail; } fseek(file, 0, SEEK_END); long file_length = ftell(file); if (file_length == -1) { perror("ftell"); goto fail; } fseek(file, 0, SEEK_SET); char* data = malloc(file_length); if (fread(data, 1, file_length, file) != (size_t)file_length) { fprintf(stderr, "couldn't read entire file\n"); free(data); goto fail; } http_parser_settings settings; memset(&settings, 0, sizeof(settings)); settings.on_message_begin = on_message_begin; settings.on_url = on_url; settings.on_header_field = on_header_field; settings.on_header_value = on_header_value; settings.on_headers_complete = on_headers_complete; settings.on_body = on_body; settings.on_message_complete = on_message_complete; http_parser parser; http_parser_init(&parser, file_type); size_t nparsed = http_parser_execute(&parser, &settings, data, file_length); free(data); if (nparsed != (size_t)file_length) { fprintf(stderr, "Error: %s (%s)\n", http_errno_description(HTTP_PARSER_ERRNO(&parser)), http_errno_name(HTTP_PARSER_ERRNO(&parser))); goto fail; } return EXIT_SUCCESS; fail: fclose(file); return EXIT_FAILURE; } iotjs-1.0/deps/http-parser/contrib/url_parser.c000066400000000000000000000021421307356305600216770ustar00rootroot00000000000000#include "http_parser.h" #include #include void dump_url (const char *url, const struct http_parser_url *u) { unsigned int i; printf("\tfield_set: 0x%x, port: %u\n", u->field_set, u->port); for (i = 0; i < UF_MAX; i++) { if ((u->field_set & (1 << i)) == 0) { printf("\tfield_data[%u]: unset\n", i); continue; } printf("\tfield_data[%u]: off: %u, len: %u, part: %.*s\n", i, u->field_data[i].off, u->field_data[i].len, u->field_data[i].len, url + u->field_data[i].off); } } int main(int argc, char ** argv) { struct http_parser_url u; int len, connect, result; if (argc != 3) { printf("Syntax : %s connect|get url\n", argv[0]); return 1; } len = strlen(argv[2]); connect = strcmp("connect", argv[1]) == 0 ? 1 : 0; printf("Parsing %s, connect %d\n", argv[2], connect); result = http_parser_parse_url(argv[2], len, connect, &u); if (result != 0) { printf("Parse error : %d\n", result); return result; } printf("Parse ok, result : \n"); dump_url(argv[2], &u); return 0; }iotjs-1.0/deps/http-parser/http_parser.c000066400000000000000000002114301307356305600204160ustar00rootroot00000000000000/* Based on src/http/ngx_http_parse.c from NGINX copyright Igor Sysoev * * Additional changes are licensed under the same terms as NGINX and * copyright Joyent, Inc. and other Node contributors. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to * deal in the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. */ #include "http_parser.h" #include #include #include #include #include #include #ifndef ULLONG_MAX # define ULLONG_MAX ((uint64_t) -1) /* 2^64-1 */ #endif #ifndef MIN # define MIN(a,b) ((a) < (b) ? (a) : (b)) #endif #ifndef ARRAY_SIZE # define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) #endif #ifndef BIT_AT # define BIT_AT(a, i) \ (!!((unsigned int) (a)[(unsigned int) (i) >> 3] & \ (1 << ((unsigned int) (i) & 7)))) #endif #ifndef ELEM_AT # define ELEM_AT(a, i, v) ((unsigned int) (i) < ARRAY_SIZE(a) ? (a)[(i)] : (v)) #endif #define SET_ERRNO(e) \ do { \ parser->http_errno = (e); \ } while(0) #define CURRENT_STATE() p_state #define UPDATE_STATE(V) p_state = (enum state) (V); #define RETURN(V) \ do { \ parser->state = CURRENT_STATE(); \ return (V); \ } while (0); #define REEXECUTE() \ goto reexecute; \ #ifdef __GNUC__ # define LIKELY(X) __builtin_expect(!!(X), 1) # define UNLIKELY(X) __builtin_expect(!!(X), 0) #else # define LIKELY(X) (X) # define UNLIKELY(X) (X) #endif /* Run the notify callback FOR, returning ER if it fails */ #define CALLBACK_NOTIFY_(FOR, ER) \ do { \ assert(HTTP_PARSER_ERRNO(parser) == HPE_OK); \ \ if (LIKELY(settings->on_##FOR)) { \ parser->state = CURRENT_STATE(); \ if (UNLIKELY(0 != settings->on_##FOR(parser))) { \ SET_ERRNO(HPE_CB_##FOR); \ } \ UPDATE_STATE(parser->state); \ \ /* We either errored above or got paused; get out */ \ if (UNLIKELY(HTTP_PARSER_ERRNO(parser) != HPE_OK)) { \ return (ER); \ } \ } \ } while (0) /* Run the notify callback FOR and consume the current byte */ #define CALLBACK_NOTIFY(FOR) CALLBACK_NOTIFY_(FOR, p - data + 1) /* Run the notify callback FOR and don't consume the current byte */ #define CALLBACK_NOTIFY_NOADVANCE(FOR) CALLBACK_NOTIFY_(FOR, p - data) /* Run data callback FOR with LEN bytes, returning ER if it fails */ #define CALLBACK_DATA_(FOR, LEN, ER) \ do { \ assert(HTTP_PARSER_ERRNO(parser) == HPE_OK); \ \ if (FOR##_mark) { \ if (LIKELY(settings->on_##FOR)) { \ parser->state = CURRENT_STATE(); \ if (UNLIKELY(0 != \ settings->on_##FOR(parser, FOR##_mark, (LEN)))) { \ SET_ERRNO(HPE_CB_##FOR); \ } \ UPDATE_STATE(parser->state); \ \ /* We either errored above or got paused; get out */ \ if (UNLIKELY(HTTP_PARSER_ERRNO(parser) != HPE_OK)) { \ return (ER); \ } \ } \ FOR##_mark = NULL; \ } \ } while (0) /* Run the data callback FOR and consume the current byte */ #define CALLBACK_DATA(FOR) \ CALLBACK_DATA_(FOR, p - FOR##_mark, p - data + 1) /* Run the data callback FOR and don't consume the current byte */ #define CALLBACK_DATA_NOADVANCE(FOR) \ CALLBACK_DATA_(FOR, p - FOR##_mark, p - data) /* Set the mark FOR; non-destructive if mark is already set */ #define MARK(FOR) \ do { \ if (!FOR##_mark) { \ FOR##_mark = p; \ } \ } while (0) /* Don't allow the total size of the HTTP headers (including the status * line) to exceed HTTP_MAX_HEADER_SIZE. This check is here to protect * embedders against denial-of-service attacks where the attacker feeds * us a never-ending header that the embedder keeps buffering. * * This check is arguably the responsibility of embedders but we're doing * it on the embedder's behalf because most won't bother and this way we * make the web a little safer. HTTP_MAX_HEADER_SIZE is still far bigger * than any reasonable request or response so this should never affect * day-to-day operation. */ #define COUNT_HEADER_SIZE(V) \ do { \ parser->nread += (V); \ if (UNLIKELY(parser->nread > (HTTP_MAX_HEADER_SIZE))) { \ SET_ERRNO(HPE_HEADER_OVERFLOW); \ goto error; \ } \ } while (0) #define PROXY_CONNECTION "proxy-connection" #define CONNECTION "connection" #define CONTENT_LENGTH "content-length" #define TRANSFER_ENCODING "transfer-encoding" #define UPGRADE "upgrade" #define CHUNKED "chunked" #define KEEP_ALIVE "keep-alive" #define CLOSE "close" static const char *method_strings[] = { #define XX(num, name, string) #string, HTTP_METHOD_MAP(XX) #undef XX }; /* Tokens as defined by rfc 2616. Also lowercases them. * token = 1* * separators = "(" | ")" | "<" | ">" | "@" * | "," | ";" | ":" | "\" | <"> * | "/" | "[" | "]" | "?" | "=" * | "{" | "}" | SP | HT */ static const char tokens[256] = { /* 0 nul 1 soh 2 stx 3 etx 4 eot 5 enq 6 ack 7 bel */ 0, 0, 0, 0, 0, 0, 0, 0, /* 8 bs 9 ht 10 nl 11 vt 12 np 13 cr 14 so 15 si */ 0, 0, 0, 0, 0, 0, 0, 0, /* 16 dle 17 dc1 18 dc2 19 dc3 20 dc4 21 nak 22 syn 23 etb */ 0, 0, 0, 0, 0, 0, 0, 0, /* 24 can 25 em 26 sub 27 esc 28 fs 29 gs 30 rs 31 us */ 0, 0, 0, 0, 0, 0, 0, 0, /* 32 sp 33 ! 34 " 35 # 36 $ 37 % 38 & 39 ' */ 0, '!', 0, '#', '$', '%', '&', '\'', /* 40 ( 41 ) 42 * 43 + 44 , 45 - 46 . 47 / */ 0, 0, '*', '+', 0, '-', '.', 0, /* 48 0 49 1 50 2 51 3 52 4 53 5 54 6 55 7 */ '0', '1', '2', '3', '4', '5', '6', '7', /* 56 8 57 9 58 : 59 ; 60 < 61 = 62 > 63 ? */ '8', '9', 0, 0, 0, 0, 0, 0, /* 64 @ 65 A 66 B 67 C 68 D 69 E 70 F 71 G */ 0, 'a', 'b', 'c', 'd', 'e', 'f', 'g', /* 72 H 73 I 74 J 75 K 76 L 77 M 78 N 79 O */ 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', /* 80 P 81 Q 82 R 83 S 84 T 85 U 86 V 87 W */ 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', /* 88 X 89 Y 90 Z 91 [ 92 \ 93 ] 94 ^ 95 _ */ 'x', 'y', 'z', 0, 0, 0, '^', '_', /* 96 ` 97 a 98 b 99 c 100 d 101 e 102 f 103 g */ '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', /* 104 h 105 i 106 j 107 k 108 l 109 m 110 n 111 o */ 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', /* 112 p 113 q 114 r 115 s 116 t 117 u 118 v 119 w */ 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', /* 120 x 121 y 122 z 123 { 124 | 125 } 126 ~ 127 del */ 'x', 'y', 'z', 0, '|', 0, '~', 0 }; static const int8_t unhex[256] = {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 , 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,-1,-1,-1,-1,-1 ,-1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1 ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 ,-1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1 ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 }; #if HTTP_PARSER_STRICT # define T(v) 0 #else # define T(v) v #endif static const uint8_t normal_url_char[32] = { /* 0 nul 1 soh 2 stx 3 etx 4 eot 5 enq 6 ack 7 bel */ 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0, /* 8 bs 9 ht 10 nl 11 vt 12 np 13 cr 14 so 15 si */ 0 | T(2) | 0 | 0 | T(16) | 0 | 0 | 0, /* 16 dle 17 dc1 18 dc2 19 dc3 20 dc4 21 nak 22 syn 23 etb */ 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0, /* 24 can 25 em 26 sub 27 esc 28 fs 29 gs 30 rs 31 us */ 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0, /* 32 sp 33 ! 34 " 35 # 36 $ 37 % 38 & 39 ' */ 0 | 2 | 4 | 0 | 16 | 32 | 64 | 128, /* 40 ( 41 ) 42 * 43 + 44 , 45 - 46 . 47 / */ 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, /* 48 0 49 1 50 2 51 3 52 4 53 5 54 6 55 7 */ 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, /* 56 8 57 9 58 : 59 ; 60 < 61 = 62 > 63 ? */ 1 | 2 | 4 | 8 | 16 | 32 | 64 | 0, /* 64 @ 65 A 66 B 67 C 68 D 69 E 70 F 71 G */ 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, /* 72 H 73 I 74 J 75 K 76 L 77 M 78 N 79 O */ 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, /* 80 P 81 Q 82 R 83 S 84 T 85 U 86 V 87 W */ 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, /* 88 X 89 Y 90 Z 91 [ 92 \ 93 ] 94 ^ 95 _ */ 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, /* 96 ` 97 a 98 b 99 c 100 d 101 e 102 f 103 g */ 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, /* 104 h 105 i 106 j 107 k 108 l 109 m 110 n 111 o */ 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, /* 112 p 113 q 114 r 115 s 116 t 117 u 118 v 119 w */ 1 | 2 | 4 | 8 | 16 | 32 | 64 | 128, /* 120 x 121 y 122 z 123 { 124 | 125 } 126 ~ 127 del */ 1 | 2 | 4 | 8 | 16 | 32 | 64 | 0, }; #undef T enum state { s_dead = 1 /* important that this is > 0 */ , s_start_req_or_res , s_res_or_resp_H , s_start_res , s_res_H , s_res_HT , s_res_HTT , s_res_HTTP , s_res_first_http_major , s_res_http_major , s_res_first_http_minor , s_res_http_minor , s_res_first_status_code , s_res_status_code , s_res_status_start , s_res_status , s_res_line_almost_done , s_start_req , s_req_method , s_req_spaces_before_url , s_req_schema , s_req_schema_slash , s_req_schema_slash_slash , s_req_server_start , s_req_server , s_req_server_with_at , s_req_path , s_req_query_string_start , s_req_query_string , s_req_fragment_start , s_req_fragment , s_req_http_start , s_req_http_H , s_req_http_HT , s_req_http_HTT , s_req_http_HTTP , s_req_first_http_major , s_req_http_major , s_req_first_http_minor , s_req_http_minor , s_req_line_almost_done , s_header_field_start , s_header_field , s_header_value_discard_ws , s_header_value_discard_ws_almost_done , s_header_value_discard_lws , s_header_value_start , s_header_value , s_header_value_lws , s_header_almost_done , s_chunk_size_start , s_chunk_size , s_chunk_parameters , s_chunk_size_almost_done , s_headers_almost_done , s_headers_done /* Important: 's_headers_done' must be the last 'header' state. All * states beyond this must be 'body' states. It is used for overflow * checking. See the PARSING_HEADER() macro. */ , s_chunk_data , s_chunk_data_almost_done , s_chunk_data_done , s_body_identity , s_body_identity_eof , s_message_done }; #define PARSING_HEADER(state) (state <= s_headers_done) enum header_states { h_general = 0 , h_C , h_CO , h_CON , h_matching_connection , h_matching_proxy_connection , h_matching_content_length , h_matching_transfer_encoding , h_matching_upgrade , h_connection , h_content_length , h_transfer_encoding , h_upgrade , h_matching_transfer_encoding_chunked , h_matching_connection_token_start , h_matching_connection_keep_alive , h_matching_connection_close , h_matching_connection_upgrade , h_matching_connection_token , h_transfer_encoding_chunked , h_connection_keep_alive , h_connection_close , h_connection_upgrade }; enum http_host_state { s_http_host_dead = 1 , s_http_userinfo_start , s_http_userinfo , s_http_host_start , s_http_host_v6_start , s_http_host , s_http_host_v6 , s_http_host_v6_end , s_http_host_port_start , s_http_host_port }; /* Macros for character classes; depends on strict-mode */ #define CR '\r' #define LF '\n' #define LOWER(c) (unsigned char)(c | 0x20) #define IS_ALPHA(c) (LOWER(c) >= 'a' && LOWER(c) <= 'z') #define IS_NUM(c) ((c) >= '0' && (c) <= '9') #define IS_ALPHANUM(c) (IS_ALPHA(c) || IS_NUM(c)) #define IS_HEX(c) (IS_NUM(c) || (LOWER(c) >= 'a' && LOWER(c) <= 'f')) #define IS_MARK(c) ((c) == '-' || (c) == '_' || (c) == '.' || \ (c) == '!' || (c) == '~' || (c) == '*' || (c) == '\'' || (c) == '(' || \ (c) == ')') #define IS_USERINFO_CHAR(c) (IS_ALPHANUM(c) || IS_MARK(c) || (c) == '%' || \ (c) == ';' || (c) == ':' || (c) == '&' || (c) == '=' || (c) == '+' || \ (c) == '$' || (c) == ',') #define STRICT_TOKEN(c) (tokens[(unsigned char)c]) #if HTTP_PARSER_STRICT #define TOKEN(c) (tokens[(unsigned char)c]) #define IS_URL_CHAR(c) (BIT_AT(normal_url_char, (unsigned char)c)) #define IS_HOST_CHAR(c) (IS_ALPHANUM(c) || (c) == '.' || (c) == '-') #else #define TOKEN(c) ((c == ' ') ? ' ' : tokens[(unsigned char)c]) #define IS_URL_CHAR(c) \ (BIT_AT(normal_url_char, (unsigned char)c) || ((c) & 0x80)) #define IS_HOST_CHAR(c) \ (IS_ALPHANUM(c) || (c) == '.' || (c) == '-' || (c) == '_') #endif #define start_state (parser->type == HTTP_REQUEST ? s_start_req : s_start_res) #if HTTP_PARSER_STRICT # define STRICT_CHECK(cond) \ do { \ if (cond) { \ SET_ERRNO(HPE_STRICT); \ goto error; \ } \ } while (0) # define NEW_MESSAGE() (http_should_keep_alive(parser) ? start_state : s_dead) #else # define STRICT_CHECK(cond) # define NEW_MESSAGE() start_state #endif /* Map errno values to strings for human-readable output */ #define HTTP_STRERROR_GEN(n, s) { "HPE_" #n, s }, static struct { const char *name; const char *description; } http_strerror_tab[] = { HTTP_ERRNO_MAP(HTTP_STRERROR_GEN) }; #undef HTTP_STRERROR_GEN int http_message_needs_eof(const http_parser *parser); /* Our URL parser. * * This is designed to be shared by http_parser_execute() for URL validation, * hence it has a state transition + byte-for-byte interface. In addition, it * is meant to be embedded in http_parser_parse_url(), which does the dirty * work of turning state transitions URL components for its API. * * This function should only be invoked with non-space characters. It is * assumed that the caller cares about (and can detect) the transition between * URL and non-URL states by looking for these. */ static enum state parse_url_char(enum state s, const char ch) { if (ch == ' ' || ch == '\r' || ch == '\n') { return s_dead; } #if HTTP_PARSER_STRICT if (ch == '\t' || ch == '\f') { return s_dead; } #endif switch (s) { case s_req_spaces_before_url: /* Proxied requests are followed by scheme of an absolute URI (alpha). * All methods except CONNECT are followed by '/' or '*'. */ if (ch == '/' || ch == '*') { return s_req_path; } if (IS_ALPHA(ch)) { return s_req_schema; } break; case s_req_schema: if (IS_ALPHA(ch)) { return s; } if (ch == ':') { return s_req_schema_slash; } break; case s_req_schema_slash: if (ch == '/') { return s_req_schema_slash_slash; } break; case s_req_schema_slash_slash: if (ch == '/') { return s_req_server_start; } break; case s_req_server_with_at: if (ch == '@') { return s_dead; } /* FALLTHROUGH */ case s_req_server_start: case s_req_server: if (ch == '/') { return s_req_path; } if (ch == '?') { return s_req_query_string_start; } if (ch == '@') { return s_req_server_with_at; } if (IS_USERINFO_CHAR(ch) || ch == '[' || ch == ']') { return s_req_server; } break; case s_req_path: if (IS_URL_CHAR(ch)) { return s; } switch (ch) { case '?': return s_req_query_string_start; case '#': return s_req_fragment_start; } break; case s_req_query_string_start: case s_req_query_string: if (IS_URL_CHAR(ch)) { return s_req_query_string; } switch (ch) { case '?': /* allow extra '?' in query string */ return s_req_query_string; case '#': return s_req_fragment_start; } break; case s_req_fragment_start: if (IS_URL_CHAR(ch)) { return s_req_fragment; } switch (ch) { case '?': return s_req_fragment; case '#': return s; } break; case s_req_fragment: if (IS_URL_CHAR(ch)) { return s; } switch (ch) { case '?': case '#': return s; } break; default: break; } /* We should never fall out of the switch above unless there's an error */ return s_dead; } size_t http_parser_execute (http_parser *parser, const http_parser_settings *settings, const char *data, size_t len) { char c, ch; int8_t unhex_val; const char *p = data; const char *header_field_mark = 0; const char *header_value_mark = 0; const char *url_mark = 0; const char *body_mark = 0; const char *status_mark = 0; enum state p_state = (enum state) parser->state; /* We're in an error state. Don't bother doing anything. */ if (HTTP_PARSER_ERRNO(parser) != HPE_OK) { return 0; } if (len == 0) { switch (CURRENT_STATE()) { case s_body_identity_eof: /* Use of CALLBACK_NOTIFY() here would erroneously return 1 byte read if * we got paused. */ CALLBACK_NOTIFY_NOADVANCE(message_complete); return 0; case s_dead: case s_start_req_or_res: case s_start_res: case s_start_req: return 0; default: SET_ERRNO(HPE_INVALID_EOF_STATE); return 1; } } if (CURRENT_STATE() == s_header_field) header_field_mark = data; if (CURRENT_STATE() == s_header_value) header_value_mark = data; switch (CURRENT_STATE()) { case s_req_path: case s_req_schema: case s_req_schema_slash: case s_req_schema_slash_slash: case s_req_server_start: case s_req_server: case s_req_server_with_at: case s_req_query_string_start: case s_req_query_string: case s_req_fragment_start: case s_req_fragment: url_mark = data; break; case s_res_status: status_mark = data; break; default: break; } for (p=data; p != data + len; p++) { ch = *p; if (PARSING_HEADER(CURRENT_STATE())) COUNT_HEADER_SIZE(1); reexecute: switch (CURRENT_STATE()) { case s_dead: /* this state is used after a 'Connection: close' message * the parser will error out if it reads another message */ if (LIKELY(ch == CR || ch == LF)) break; SET_ERRNO(HPE_CLOSED_CONNECTION); goto error; case s_start_req_or_res: { if (ch == CR || ch == LF) break; parser->flags = 0; parser->content_length = ULLONG_MAX; if (ch == 'H') { UPDATE_STATE(s_res_or_resp_H); CALLBACK_NOTIFY(message_begin); } else { parser->type = HTTP_REQUEST; UPDATE_STATE(s_start_req); REEXECUTE(); } break; } case s_res_or_resp_H: if (ch == 'T') { parser->type = HTTP_RESPONSE; UPDATE_STATE(s_res_HT); } else { if (UNLIKELY(ch != 'E')) { SET_ERRNO(HPE_INVALID_CONSTANT); goto error; } parser->type = HTTP_REQUEST; parser->method = HTTP_HEAD; parser->index = 2; UPDATE_STATE(s_req_method); } break; case s_start_res: { parser->flags = 0; parser->content_length = ULLONG_MAX; switch (ch) { case 'H': UPDATE_STATE(s_res_H); break; case CR: case LF: break; default: SET_ERRNO(HPE_INVALID_CONSTANT); goto error; } CALLBACK_NOTIFY(message_begin); break; } case s_res_H: STRICT_CHECK(ch != 'T'); UPDATE_STATE(s_res_HT); break; case s_res_HT: STRICT_CHECK(ch != 'T'); UPDATE_STATE(s_res_HTT); break; case s_res_HTT: STRICT_CHECK(ch != 'P'); UPDATE_STATE(s_res_HTTP); break; case s_res_HTTP: STRICT_CHECK(ch != '/'); UPDATE_STATE(s_res_first_http_major); break; case s_res_first_http_major: if (UNLIKELY(ch < '0' || ch > '9')) { SET_ERRNO(HPE_INVALID_VERSION); goto error; } parser->http_major = ch - '0'; UPDATE_STATE(s_res_http_major); break; /* major HTTP version or dot */ case s_res_http_major: { if (ch == '.') { UPDATE_STATE(s_res_first_http_minor); break; } if (!IS_NUM(ch)) { SET_ERRNO(HPE_INVALID_VERSION); goto error; } parser->http_major *= 10; parser->http_major += ch - '0'; if (UNLIKELY(parser->http_major > 999)) { SET_ERRNO(HPE_INVALID_VERSION); goto error; } break; } /* first digit of minor HTTP version */ case s_res_first_http_minor: if (UNLIKELY(!IS_NUM(ch))) { SET_ERRNO(HPE_INVALID_VERSION); goto error; } parser->http_minor = ch - '0'; UPDATE_STATE(s_res_http_minor); break; /* minor HTTP version or end of request line */ case s_res_http_minor: { if (ch == ' ') { UPDATE_STATE(s_res_first_status_code); break; } if (UNLIKELY(!IS_NUM(ch))) { SET_ERRNO(HPE_INVALID_VERSION); goto error; } parser->http_minor *= 10; parser->http_minor += ch - '0'; if (UNLIKELY(parser->http_minor > 999)) { SET_ERRNO(HPE_INVALID_VERSION); goto error; } break; } case s_res_first_status_code: { if (!IS_NUM(ch)) { if (ch == ' ') { break; } SET_ERRNO(HPE_INVALID_STATUS); goto error; } parser->status_code = ch - '0'; UPDATE_STATE(s_res_status_code); break; } case s_res_status_code: { if (!IS_NUM(ch)) { switch (ch) { case ' ': UPDATE_STATE(s_res_status_start); break; case CR: UPDATE_STATE(s_res_line_almost_done); break; case LF: UPDATE_STATE(s_header_field_start); break; default: SET_ERRNO(HPE_INVALID_STATUS); goto error; } break; } parser->status_code *= 10; parser->status_code += ch - '0'; if (UNLIKELY(parser->status_code > 999)) { SET_ERRNO(HPE_INVALID_STATUS); goto error; } break; } case s_res_status_start: { if (ch == CR) { UPDATE_STATE(s_res_line_almost_done); break; } if (ch == LF) { UPDATE_STATE(s_header_field_start); break; } MARK(status); UPDATE_STATE(s_res_status); parser->index = 0; break; } case s_res_status: if (ch == CR) { UPDATE_STATE(s_res_line_almost_done); CALLBACK_DATA(status); break; } if (ch == LF) { UPDATE_STATE(s_header_field_start); CALLBACK_DATA(status); break; } break; case s_res_line_almost_done: STRICT_CHECK(ch != LF); UPDATE_STATE(s_header_field_start); break; case s_start_req: { if (ch == CR || ch == LF) break; parser->flags = 0; parser->content_length = ULLONG_MAX; if (UNLIKELY(!IS_ALPHA(ch))) { SET_ERRNO(HPE_INVALID_METHOD); goto error; } parser->method = (enum http_method) 0; parser->index = 1; switch (ch) { case 'C': parser->method = HTTP_CONNECT; /* or COPY, CHECKOUT */ break; case 'D': parser->method = HTTP_DELETE; break; case 'G': parser->method = HTTP_GET; break; case 'H': parser->method = HTTP_HEAD; break; case 'L': parser->method = HTTP_LOCK; break; case 'M': parser->method = HTTP_MKCOL; /* or MOVE, MKACTIVITY, MERGE, M-SEARCH, MKCALENDAR */ break; case 'N': parser->method = HTTP_NOTIFY; break; case 'O': parser->method = HTTP_OPTIONS; break; case 'P': parser->method = HTTP_POST; /* or PROPFIND|PROPPATCH|PUT|PATCH|PURGE */ break; case 'R': parser->method = HTTP_REPORT; break; case 'S': parser->method = HTTP_SUBSCRIBE; /* or SEARCH */ break; case 'T': parser->method = HTTP_TRACE; break; case 'U': parser->method = HTTP_UNLOCK; /* or UNSUBSCRIBE */ break; default: SET_ERRNO(HPE_INVALID_METHOD); goto error; } UPDATE_STATE(s_req_method); CALLBACK_NOTIFY(message_begin); break; } case s_req_method: { const char *matcher; if (UNLIKELY(ch == '\0')) { SET_ERRNO(HPE_INVALID_METHOD); goto error; } matcher = method_strings[parser->method]; if (ch == ' ' && matcher[parser->index] == '\0') { UPDATE_STATE(s_req_spaces_before_url); } else if (ch == matcher[parser->index]) { ; /* nada */ } else if (parser->method == HTTP_CONNECT) { if (parser->index == 1 && ch == 'H') { parser->method = HTTP_CHECKOUT; } else if (parser->index == 2 && ch == 'P') { parser->method = HTTP_COPY; } else { SET_ERRNO(HPE_INVALID_METHOD); goto error; } } else if (parser->method == HTTP_MKCOL) { if (parser->index == 1 && ch == 'O') { parser->method = HTTP_MOVE; } else if (parser->index == 1 && ch == 'E') { parser->method = HTTP_MERGE; } else if (parser->index == 1 && ch == '-') { parser->method = HTTP_MSEARCH; } else if (parser->index == 2 && ch == 'A') { parser->method = HTTP_MKACTIVITY; } else if (parser->index == 3 && ch == 'A') { parser->method = HTTP_MKCALENDAR; } else { SET_ERRNO(HPE_INVALID_METHOD); goto error; } } else if (parser->method == HTTP_SUBSCRIBE) { if (parser->index == 1 && ch == 'E') { parser->method = HTTP_SEARCH; } else { SET_ERRNO(HPE_INVALID_METHOD); goto error; } } else if (parser->index == 1 && parser->method == HTTP_POST) { if (ch == 'R') { parser->method = HTTP_PROPFIND; /* or HTTP_PROPPATCH */ } else if (ch == 'U') { parser->method = HTTP_PUT; /* or HTTP_PURGE */ } else if (ch == 'A') { parser->method = HTTP_PATCH; } else { SET_ERRNO(HPE_INVALID_METHOD); goto error; } } else if (parser->index == 2) { if (parser->method == HTTP_PUT) { if (ch == 'R') { parser->method = HTTP_PURGE; } else { SET_ERRNO(HPE_INVALID_METHOD); goto error; } } else if (parser->method == HTTP_UNLOCK) { if (ch == 'S') { parser->method = HTTP_UNSUBSCRIBE; } else { SET_ERRNO(HPE_INVALID_METHOD); goto error; } } else { SET_ERRNO(HPE_INVALID_METHOD); goto error; } } else if (parser->index == 4 && parser->method == HTTP_PROPFIND && ch == 'P') { parser->method = HTTP_PROPPATCH; } else { SET_ERRNO(HPE_INVALID_METHOD); goto error; } ++parser->index; break; } case s_req_spaces_before_url: { if (ch == ' ') break; MARK(url); if (parser->method == HTTP_CONNECT) { UPDATE_STATE(s_req_server_start); } UPDATE_STATE(parse_url_char(CURRENT_STATE(), ch)); if (UNLIKELY(CURRENT_STATE() == s_dead)) { SET_ERRNO(HPE_INVALID_URL); goto error; } break; } case s_req_schema: case s_req_schema_slash: case s_req_schema_slash_slash: case s_req_server_start: { switch (ch) { /* No whitespace allowed here */ case ' ': case CR: case LF: SET_ERRNO(HPE_INVALID_URL); goto error; default: UPDATE_STATE(parse_url_char(CURRENT_STATE(), ch)); if (UNLIKELY(CURRENT_STATE() == s_dead)) { SET_ERRNO(HPE_INVALID_URL); goto error; } } break; } case s_req_server: case s_req_server_with_at: case s_req_path: case s_req_query_string_start: case s_req_query_string: case s_req_fragment_start: case s_req_fragment: { switch (ch) { case ' ': UPDATE_STATE(s_req_http_start); CALLBACK_DATA(url); break; case CR: case LF: parser->http_major = 0; parser->http_minor = 9; UPDATE_STATE((ch == CR) ? s_req_line_almost_done : s_header_field_start); CALLBACK_DATA(url); break; default: UPDATE_STATE(parse_url_char(CURRENT_STATE(), ch)); if (UNLIKELY(CURRENT_STATE() == s_dead)) { SET_ERRNO(HPE_INVALID_URL); goto error; } } break; } case s_req_http_start: switch (ch) { case 'H': UPDATE_STATE(s_req_http_H); break; case ' ': break; default: SET_ERRNO(HPE_INVALID_CONSTANT); goto error; } break; case s_req_http_H: STRICT_CHECK(ch != 'T'); UPDATE_STATE(s_req_http_HT); break; case s_req_http_HT: STRICT_CHECK(ch != 'T'); UPDATE_STATE(s_req_http_HTT); break; case s_req_http_HTT: STRICT_CHECK(ch != 'P'); UPDATE_STATE(s_req_http_HTTP); break; case s_req_http_HTTP: STRICT_CHECK(ch != '/'); UPDATE_STATE(s_req_first_http_major); break; /* first digit of major HTTP version */ case s_req_first_http_major: if (UNLIKELY(ch < '1' || ch > '9')) { SET_ERRNO(HPE_INVALID_VERSION); goto error; } parser->http_major = ch - '0'; UPDATE_STATE(s_req_http_major); break; /* major HTTP version or dot */ case s_req_http_major: { if (ch == '.') { UPDATE_STATE(s_req_first_http_minor); break; } if (UNLIKELY(!IS_NUM(ch))) { SET_ERRNO(HPE_INVALID_VERSION); goto error; } parser->http_major *= 10; parser->http_major += ch - '0'; if (UNLIKELY(parser->http_major > 999)) { SET_ERRNO(HPE_INVALID_VERSION); goto error; } break; } /* first digit of minor HTTP version */ case s_req_first_http_minor: if (UNLIKELY(!IS_NUM(ch))) { SET_ERRNO(HPE_INVALID_VERSION); goto error; } parser->http_minor = ch - '0'; UPDATE_STATE(s_req_http_minor); break; /* minor HTTP version or end of request line */ case s_req_http_minor: { if (ch == CR) { UPDATE_STATE(s_req_line_almost_done); break; } if (ch == LF) { UPDATE_STATE(s_header_field_start); break; } /* XXX allow spaces after digit? */ if (UNLIKELY(!IS_NUM(ch))) { SET_ERRNO(HPE_INVALID_VERSION); goto error; } parser->http_minor *= 10; parser->http_minor += ch - '0'; if (UNLIKELY(parser->http_minor > 999)) { SET_ERRNO(HPE_INVALID_VERSION); goto error; } break; } /* end of request line */ case s_req_line_almost_done: { if (UNLIKELY(ch != LF)) { SET_ERRNO(HPE_LF_EXPECTED); goto error; } UPDATE_STATE(s_header_field_start); break; } case s_header_field_start: { if (ch == CR) { UPDATE_STATE(s_headers_almost_done); break; } if (ch == LF) { /* they might be just sending \n instead of \r\n so this would be * the second \n to denote the end of headers*/ UPDATE_STATE(s_headers_almost_done); REEXECUTE(); } c = TOKEN(ch); if (UNLIKELY(!c)) { SET_ERRNO(HPE_INVALID_HEADER_TOKEN); goto error; } MARK(header_field); parser->index = 0; UPDATE_STATE(s_header_field); switch (c) { case 'c': parser->header_state = h_C; break; case 'p': parser->header_state = h_matching_proxy_connection; break; case 't': parser->header_state = h_matching_transfer_encoding; break; case 'u': parser->header_state = h_matching_upgrade; break; default: parser->header_state = h_general; break; } break; } case s_header_field: { const char* start = p; for (; p != data + len; p++) { ch = *p; c = TOKEN(ch); if (!c) break; switch (parser->header_state) { case h_general: break; case h_C: parser->index++; parser->header_state = (c == 'o' ? h_CO : h_general); break; case h_CO: parser->index++; parser->header_state = (c == 'n' ? h_CON : h_general); break; case h_CON: parser->index++; switch (c) { case 'n': parser->header_state = h_matching_connection; break; case 't': parser->header_state = h_matching_content_length; break; default: parser->header_state = h_general; break; } break; /* connection */ case h_matching_connection: parser->index++; if (parser->index > sizeof(CONNECTION)-1 || c != CONNECTION[parser->index]) { parser->header_state = h_general; } else if (parser->index == sizeof(CONNECTION)-2) { parser->header_state = h_connection; } break; /* proxy-connection */ case h_matching_proxy_connection: parser->index++; if (parser->index > sizeof(PROXY_CONNECTION)-1 || c != PROXY_CONNECTION[parser->index]) { parser->header_state = h_general; } else if (parser->index == sizeof(PROXY_CONNECTION)-2) { parser->header_state = h_connection; } break; /* content-length */ case h_matching_content_length: parser->index++; if (parser->index > sizeof(CONTENT_LENGTH)-1 || c != CONTENT_LENGTH[parser->index]) { parser->header_state = h_general; } else if (parser->index == sizeof(CONTENT_LENGTH)-2) { parser->header_state = h_content_length; } break; /* transfer-encoding */ case h_matching_transfer_encoding: parser->index++; if (parser->index > sizeof(TRANSFER_ENCODING)-1 || c != TRANSFER_ENCODING[parser->index]) { parser->header_state = h_general; } else if (parser->index == sizeof(TRANSFER_ENCODING)-2) { parser->header_state = h_transfer_encoding; } break; /* upgrade */ case h_matching_upgrade: parser->index++; if (parser->index > sizeof(UPGRADE)-1 || c != UPGRADE[parser->index]) { parser->header_state = h_general; } else if (parser->index == sizeof(UPGRADE)-2) { parser->header_state = h_upgrade; } break; case h_connection: case h_content_length: case h_transfer_encoding: case h_upgrade: if (ch != ' ') parser->header_state = h_general; break; default: assert(0 && "Unknown header_state"); break; } } COUNT_HEADER_SIZE(p - start); if (p == data + len) { --p; break; } if (ch == ':') { UPDATE_STATE(s_header_value_discard_ws); CALLBACK_DATA(header_field); break; } SET_ERRNO(HPE_INVALID_HEADER_TOKEN); goto error; } case s_header_value_discard_ws: if (ch == ' ' || ch == '\t') break; if (ch == CR) { UPDATE_STATE(s_header_value_discard_ws_almost_done); break; } if (ch == LF) { UPDATE_STATE(s_header_value_discard_lws); break; } /* FALLTHROUGH */ case s_header_value_start: { MARK(header_value); UPDATE_STATE(s_header_value); parser->index = 0; c = LOWER(ch); switch (parser->header_state) { case h_upgrade: parser->flags |= F_UPGRADE; parser->header_state = h_general; break; case h_transfer_encoding: /* looking for 'Transfer-Encoding: chunked' */ if ('c' == c) { parser->header_state = h_matching_transfer_encoding_chunked; } else { parser->header_state = h_general; } break; case h_content_length: if (UNLIKELY(!IS_NUM(ch))) { SET_ERRNO(HPE_INVALID_CONTENT_LENGTH); goto error; } parser->content_length = ch - '0'; break; case h_connection: /* looking for 'Connection: keep-alive' */ if (c == 'k') { parser->header_state = h_matching_connection_keep_alive; /* looking for 'Connection: close' */ } else if (c == 'c') { parser->header_state = h_matching_connection_close; } else if (c == 'u') { parser->header_state = h_matching_connection_upgrade; } else { parser->header_state = h_matching_connection_token; } break; /* Multi-value `Connection` header */ case h_matching_connection_token_start: break; default: parser->header_state = h_general; break; } break; } case s_header_value: { const char* start = p; enum header_states h_state = (enum header_states) parser->header_state; for (; p != data + len; p++) { ch = *p; if (ch == CR) { UPDATE_STATE(s_header_almost_done); parser->header_state = h_state; CALLBACK_DATA(header_value); break; } if (ch == LF) { UPDATE_STATE(s_header_almost_done); COUNT_HEADER_SIZE(p - start); parser->header_state = h_state; CALLBACK_DATA_NOADVANCE(header_value); REEXECUTE(); } c = LOWER(ch); switch (h_state) { case h_general: { const char* p_cr; const char* p_lf; size_t limit = data + len - p; limit = MIN(limit, HTTP_MAX_HEADER_SIZE); p_cr = (const char*) memchr(p, CR, limit); p_lf = (const char*) memchr(p, LF, limit); if (p_cr != NULL) { if (p_lf != NULL && p_cr >= p_lf) p = p_lf; else p = p_cr; } else if (UNLIKELY(p_lf != NULL)) { p = p_lf; } else { p = data + len; } --p; break; } case h_connection: case h_transfer_encoding: assert(0 && "Shouldn't get here."); break; case h_content_length: { uint64_t t; if (ch == ' ') break; if (UNLIKELY(!IS_NUM(ch))) { SET_ERRNO(HPE_INVALID_CONTENT_LENGTH); parser->header_state = h_state; goto error; } t = parser->content_length; t *= 10; t += ch - '0'; /* Overflow? Test against a conservative limit for simplicity. */ if (UNLIKELY((ULLONG_MAX - 10) / 10 < parser->content_length)) { SET_ERRNO(HPE_INVALID_CONTENT_LENGTH); parser->header_state = h_state; goto error; } parser->content_length = t; break; } /* Transfer-Encoding: chunked */ case h_matching_transfer_encoding_chunked: parser->index++; if (parser->index > sizeof(CHUNKED)-1 || c != CHUNKED[parser->index]) { h_state = h_general; } else if (parser->index == sizeof(CHUNKED)-2) { h_state = h_transfer_encoding_chunked; } break; case h_matching_connection_token_start: /* looking for 'Connection: keep-alive' */ if (c == 'k') { h_state = h_matching_connection_keep_alive; /* looking for 'Connection: close' */ } else if (c == 'c') { h_state = h_matching_connection_close; } else if (c == 'u') { h_state = h_matching_connection_upgrade; } else if (STRICT_TOKEN(c)) { h_state = h_matching_connection_token; } else if (c == ' ' || c == '\t') { /* Skip lws */ } else { h_state = h_general; } break; /* looking for 'Connection: keep-alive' */ case h_matching_connection_keep_alive: parser->index++; if (parser->index > sizeof(KEEP_ALIVE)-1 || c != KEEP_ALIVE[parser->index]) { h_state = h_matching_connection_token; } else if (parser->index == sizeof(KEEP_ALIVE)-2) { h_state = h_connection_keep_alive; } break; /* looking for 'Connection: close' */ case h_matching_connection_close: parser->index++; if (parser->index > sizeof(CLOSE)-1 || c != CLOSE[parser->index]) { h_state = h_matching_connection_token; } else if (parser->index == sizeof(CLOSE)-2) { h_state = h_connection_close; } break; /* looking for 'Connection: upgrade' */ case h_matching_connection_upgrade: parser->index++; if (parser->index > sizeof(UPGRADE) - 1 || c != UPGRADE[parser->index]) { h_state = h_matching_connection_token; } else if (parser->index == sizeof(UPGRADE)-2) { h_state = h_connection_upgrade; } break; case h_matching_connection_token: if (ch == ',') { h_state = h_matching_connection_token_start; parser->index = 0; } break; case h_transfer_encoding_chunked: if (ch != ' ') h_state = h_general; break; case h_connection_keep_alive: case h_connection_close: case h_connection_upgrade: if (ch == ',') { if (h_state == h_connection_keep_alive) { parser->flags |= F_CONNECTION_KEEP_ALIVE; } else if (h_state == h_connection_close) { parser->flags |= F_CONNECTION_CLOSE; } else if (h_state == h_connection_upgrade) { parser->flags |= F_CONNECTION_UPGRADE; } h_state = h_matching_connection_token_start; parser->index = 0; } else if (ch != ' ') { h_state = h_matching_connection_token; } break; default: UPDATE_STATE(s_header_value); h_state = h_general; break; } } parser->header_state = h_state; COUNT_HEADER_SIZE(p - start); if (p == data + len) --p; break; } case s_header_almost_done: { STRICT_CHECK(ch != LF); UPDATE_STATE(s_header_value_lws); break; } case s_header_value_lws: { if (ch == ' ' || ch == '\t') { UPDATE_STATE(s_header_value_start); REEXECUTE(); } /* finished the header */ switch (parser->header_state) { case h_connection_keep_alive: parser->flags |= F_CONNECTION_KEEP_ALIVE; break; case h_connection_close: parser->flags |= F_CONNECTION_CLOSE; break; case h_transfer_encoding_chunked: parser->flags |= F_CHUNKED; break; case h_connection_upgrade: parser->flags |= F_CONNECTION_UPGRADE; break; default: break; } UPDATE_STATE(s_header_field_start); REEXECUTE(); } case s_header_value_discard_ws_almost_done: { STRICT_CHECK(ch != LF); UPDATE_STATE(s_header_value_discard_lws); break; } case s_header_value_discard_lws: { if (ch == ' ' || ch == '\t') { UPDATE_STATE(s_header_value_discard_ws); break; } else { switch (parser->header_state) { case h_connection_keep_alive: parser->flags |= F_CONNECTION_KEEP_ALIVE; break; case h_connection_close: parser->flags |= F_CONNECTION_CLOSE; break; case h_connection_upgrade: parser->flags |= F_CONNECTION_UPGRADE; break; case h_transfer_encoding_chunked: parser->flags |= F_CHUNKED; break; default: break; } /* header value was empty */ MARK(header_value); UPDATE_STATE(s_header_field_start); CALLBACK_DATA_NOADVANCE(header_value); REEXECUTE(); } } case s_headers_almost_done: { STRICT_CHECK(ch != LF); if (parser->flags & F_TRAILING) { /* End of a chunked request */ UPDATE_STATE(s_message_done); CALLBACK_NOTIFY_NOADVANCE(chunk_complete); REEXECUTE(); } UPDATE_STATE(s_headers_done); /* Set this here so that on_headers_complete() callbacks can see it */ parser->upgrade = ((parser->flags & (F_UPGRADE | F_CONNECTION_UPGRADE)) == (F_UPGRADE | F_CONNECTION_UPGRADE) || parser->method == HTTP_CONNECT); /* Here we call the headers_complete callback. This is somewhat * different than other callbacks because if the user returns 1, we * will interpret that as saying that this message has no body. This * is needed for the annoying case of recieving a response to a HEAD * request. * * We'd like to use CALLBACK_NOTIFY_NOADVANCE() here but we cannot, so * we have to simulate it by handling a change in errno below. */ if (settings->on_headers_complete) { switch (settings->on_headers_complete(parser)) { case 0: break; case 1: parser->flags |= F_SKIPBODY; break; default: SET_ERRNO(HPE_CB_headers_complete); RETURN(p - data); /* Error */ } } if (HTTP_PARSER_ERRNO(parser) != HPE_OK) { RETURN(p - data); } REEXECUTE(); } case s_headers_done: { STRICT_CHECK(ch != LF); parser->nread = 0; int hasBody = parser->flags & F_CHUNKED || (parser->content_length > 0 && parser->content_length != ULLONG_MAX); if (parser->upgrade && (parser->method == HTTP_CONNECT || (parser->flags & F_SKIPBODY) || !hasBody)) { /* Exit, the rest of the message is in a different protocol. */ UPDATE_STATE(NEW_MESSAGE()); CALLBACK_NOTIFY(message_complete); RETURN((p - data) + 1); } if (parser->flags & F_SKIPBODY) { UPDATE_STATE(NEW_MESSAGE()); CALLBACK_NOTIFY(message_complete); } else if (parser->flags & F_CHUNKED) { /* chunked encoding - ignore Content-Length header */ UPDATE_STATE(s_chunk_size_start); } else { if (parser->content_length == 0) { /* Content-Length header given but zero: Content-Length: 0\r\n */ UPDATE_STATE(NEW_MESSAGE()); CALLBACK_NOTIFY(message_complete); } else if (parser->content_length != ULLONG_MAX) { /* Content-Length header given and non-zero */ UPDATE_STATE(s_body_identity); } else { if (!http_message_needs_eof(parser)) { /* Assume content-length 0 - read the next */ UPDATE_STATE(NEW_MESSAGE()); CALLBACK_NOTIFY(message_complete); } else { /* Read body until EOF */ UPDATE_STATE(s_body_identity_eof); } } } break; } case s_body_identity: { uint64_t to_read = MIN(parser->content_length, (uint64_t) ((data + len) - p)); assert(parser->content_length != 0 && parser->content_length != ULLONG_MAX); /* The difference between advancing content_length and p is because * the latter will automaticaly advance on the next loop iteration. * Further, if content_length ends up at 0, we want to see the last * byte again for our message complete callback. */ MARK(body); parser->content_length -= to_read; p += to_read - 1; if (parser->content_length == 0) { UPDATE_STATE(s_message_done); /* Mimic CALLBACK_DATA_NOADVANCE() but with one extra byte. * * The alternative to doing this is to wait for the next byte to * trigger the data callback, just as in every other case. The * problem with this is that this makes it difficult for the test * harness to distinguish between complete-on-EOF and * complete-on-length. It's not clear that this distinction is * important for applications, but let's keep it for now. */ CALLBACK_DATA_(body, p - body_mark + 1, p - data); REEXECUTE(); } break; } /* read until EOF */ case s_body_identity_eof: MARK(body); p = data + len - 1; break; case s_message_done: UPDATE_STATE(NEW_MESSAGE()); CALLBACK_NOTIFY(message_complete); if (parser->upgrade) { /* Exit, the rest of the message is in a different protocol. */ RETURN((p - data) + 1); } break; case s_chunk_size_start: { assert(parser->nread == 1); assert(parser->flags & F_CHUNKED); unhex_val = unhex[(unsigned char)ch]; if (UNLIKELY(unhex_val == -1)) { SET_ERRNO(HPE_INVALID_CHUNK_SIZE); goto error; } parser->content_length = unhex_val; UPDATE_STATE(s_chunk_size); break; } case s_chunk_size: { uint64_t t; assert(parser->flags & F_CHUNKED); if (ch == CR) { UPDATE_STATE(s_chunk_size_almost_done); break; } unhex_val = unhex[(unsigned char)ch]; if (unhex_val == -1) { if (ch == ';' || ch == ' ') { UPDATE_STATE(s_chunk_parameters); break; } SET_ERRNO(HPE_INVALID_CHUNK_SIZE); goto error; } t = parser->content_length; t *= 16; t += unhex_val; /* Overflow? Test against a conservative limit for simplicity. */ if (UNLIKELY((ULLONG_MAX - 16) / 16 < parser->content_length)) { SET_ERRNO(HPE_INVALID_CONTENT_LENGTH); goto error; } parser->content_length = t; break; } case s_chunk_parameters: { assert(parser->flags & F_CHUNKED); /* just ignore this shit. TODO check for overflow */ if (ch == CR) { UPDATE_STATE(s_chunk_size_almost_done); break; } break; } case s_chunk_size_almost_done: { assert(parser->flags & F_CHUNKED); STRICT_CHECK(ch != LF); parser->nread = 0; if (parser->content_length == 0) { parser->flags |= F_TRAILING; UPDATE_STATE(s_header_field_start); } else { UPDATE_STATE(s_chunk_data); } CALLBACK_NOTIFY(chunk_header); break; } case s_chunk_data: { uint64_t to_read = MIN(parser->content_length, (uint64_t) ((data + len) - p)); assert(parser->flags & F_CHUNKED); assert(parser->content_length != 0 && parser->content_length != ULLONG_MAX); /* See the explanation in s_body_identity for why the content * length and data pointers are managed this way. */ MARK(body); parser->content_length -= to_read; p += to_read - 1; if (parser->content_length == 0) { UPDATE_STATE(s_chunk_data_almost_done); } break; } case s_chunk_data_almost_done: assert(parser->flags & F_CHUNKED); assert(parser->content_length == 0); STRICT_CHECK(ch != CR); UPDATE_STATE(s_chunk_data_done); CALLBACK_DATA(body); break; case s_chunk_data_done: assert(parser->flags & F_CHUNKED); STRICT_CHECK(ch != LF); parser->nread = 0; UPDATE_STATE(s_chunk_size_start); CALLBACK_NOTIFY(chunk_complete); break; default: assert(0 && "unhandled state"); SET_ERRNO(HPE_INVALID_INTERNAL_STATE); goto error; } } /* Run callbacks for any marks that we have leftover after we ran our of * bytes. There should be at most one of these set, so it's OK to invoke * them in series (unset marks will not result in callbacks). * * We use the NOADVANCE() variety of callbacks here because 'p' has already * overflowed 'data' and this allows us to correct for the off-by-one that * we'd otherwise have (since CALLBACK_DATA() is meant to be run with a 'p' * value that's in-bounds). */ assert(((header_field_mark ? 1 : 0) + (header_value_mark ? 1 : 0) + (url_mark ? 1 : 0) + (body_mark ? 1 : 0) + (status_mark ? 1 : 0)) <= 1); CALLBACK_DATA_NOADVANCE(header_field); CALLBACK_DATA_NOADVANCE(header_value); CALLBACK_DATA_NOADVANCE(url); CALLBACK_DATA_NOADVANCE(body); CALLBACK_DATA_NOADVANCE(status); RETURN(len); error: if (HTTP_PARSER_ERRNO(parser) == HPE_OK) { SET_ERRNO(HPE_UNKNOWN); } RETURN(p - data); } /* Does the parser need to see an EOF to find the end of the message? */ int http_message_needs_eof (const http_parser *parser) { if (parser->type == HTTP_REQUEST) { return 0; } /* See RFC 2616 section 4.4 */ if (parser->status_code / 100 == 1 || /* 1xx e.g. Continue */ parser->status_code == 204 || /* No Content */ parser->status_code == 304 || /* Not Modified */ parser->flags & F_SKIPBODY) { /* response to a HEAD request */ return 0; } if ((parser->flags & F_CHUNKED) || parser->content_length != ULLONG_MAX) { return 0; } return 1; } int http_should_keep_alive (const http_parser *parser) { if (parser->http_major > 0 && parser->http_minor > 0) { /* HTTP/1.1 */ if (parser->flags & F_CONNECTION_CLOSE) { return 0; } } else { /* HTTP/1.0 or earlier */ if (!(parser->flags & F_CONNECTION_KEEP_ALIVE)) { return 0; } } return !http_message_needs_eof(parser); } const char * http_method_str (enum http_method m) { return ELEM_AT(method_strings, m, ""); } void http_parser_init (http_parser *parser, enum http_parser_type t) { void *data = parser->data; /* preserve application data */ memset(parser, 0, sizeof(*parser)); parser->data = data; parser->type = t; parser->state = (t == HTTP_REQUEST ? s_start_req : (t == HTTP_RESPONSE ? s_start_res : s_start_req_or_res)); parser->http_errno = HPE_OK; } void http_parser_settings_init(http_parser_settings *settings) { memset(settings, 0, sizeof(*settings)); } const char * http_errno_name(enum http_errno err) { assert(((size_t) err) < (sizeof(http_strerror_tab) / sizeof(http_strerror_tab[0]))); return http_strerror_tab[err].name; } const char * http_errno_description(enum http_errno err) { assert(((size_t) err) < (sizeof(http_strerror_tab) / sizeof(http_strerror_tab[0]))); return http_strerror_tab[err].description; } static enum http_host_state http_parse_host_char(enum http_host_state s, const char ch) { switch(s) { case s_http_userinfo: case s_http_userinfo_start: if (ch == '@') { return s_http_host_start; } if (IS_USERINFO_CHAR(ch)) { return s_http_userinfo; } break; case s_http_host_start: if (ch == '[') { return s_http_host_v6_start; } if (IS_HOST_CHAR(ch)) { return s_http_host; } break; case s_http_host: if (IS_HOST_CHAR(ch)) { return s_http_host; } /* FALLTHROUGH */ case s_http_host_v6_end: if (ch == ':') { return s_http_host_port_start; } break; case s_http_host_v6: if (ch == ']') { return s_http_host_v6_end; } /* FALLTHROUGH */ case s_http_host_v6_start: if (IS_HEX(ch) || ch == ':' || ch == '.') { return s_http_host_v6; } break; case s_http_host_port: case s_http_host_port_start: if (IS_NUM(ch)) { return s_http_host_port; } break; default: break; } return s_http_host_dead; } static int http_parse_host(const char * buf, struct http_parser_url *u, int found_at) { assert(u->field_set & (1 << UF_HOST)); enum http_host_state s; const char *p; size_t buflen = u->field_data[UF_HOST].off + u->field_data[UF_HOST].len; u->field_data[UF_HOST].len = 0; s = found_at ? s_http_userinfo_start : s_http_host_start; for (p = buf + u->field_data[UF_HOST].off; p < buf + buflen; p++) { enum http_host_state new_s = http_parse_host_char(s, *p); if (new_s == s_http_host_dead) { return 1; } switch(new_s) { case s_http_host: if (s != s_http_host) { u->field_data[UF_HOST].off = p - buf; } u->field_data[UF_HOST].len++; break; case s_http_host_v6: if (s != s_http_host_v6) { u->field_data[UF_HOST].off = p - buf; } u->field_data[UF_HOST].len++; break; case s_http_host_port: if (s != s_http_host_port) { u->field_data[UF_PORT].off = p - buf; u->field_data[UF_PORT].len = 0; u->field_set |= (1 << UF_PORT); } u->field_data[UF_PORT].len++; break; case s_http_userinfo: if (s != s_http_userinfo) { u->field_data[UF_USERINFO].off = p - buf ; u->field_data[UF_USERINFO].len = 0; u->field_set |= (1 << UF_USERINFO); } u->field_data[UF_USERINFO].len++; break; default: break; } s = new_s; } /* Make sure we don't end somewhere unexpected */ switch (s) { case s_http_host_start: case s_http_host_v6_start: case s_http_host_v6: case s_http_host_port_start: case s_http_userinfo: case s_http_userinfo_start: return 1; default: break; } return 0; } int http_parser_parse_url(const char *buf, size_t buflen, int is_connect, struct http_parser_url *u) { enum state s; const char *p; enum http_parser_url_fields uf, old_uf; int found_at = 0; u->port = u->field_set = 0; s = is_connect ? s_req_server_start : s_req_spaces_before_url; old_uf = UF_MAX; for (p = buf; p < buf + buflen; p++) { s = parse_url_char(s, *p); /* Figure out the next field that we're operating on */ switch (s) { case s_dead: return 1; /* Skip delimeters */ case s_req_schema_slash: case s_req_schema_slash_slash: case s_req_server_start: case s_req_query_string_start: case s_req_fragment_start: continue; case s_req_schema: uf = UF_SCHEMA; break; case s_req_server_with_at: found_at = 1; /* FALLTROUGH */ case s_req_server: uf = UF_HOST; break; case s_req_path: uf = UF_PATH; break; case s_req_query_string: uf = UF_QUERY; break; case s_req_fragment: uf = UF_FRAGMENT; break; default: assert(!"Unexpected state"); return 1; } /* Nothing's changed; soldier on */ if (uf == old_uf) { u->field_data[uf].len++; continue; } u->field_data[uf].off = p - buf; u->field_data[uf].len = 1; u->field_set |= (1 << uf); old_uf = uf; } /* host must be present if there is a schema */ /* parsing http:///toto will fail */ if ((u->field_set & (1 << UF_SCHEMA)) && (u->field_set & (1 << UF_HOST)) == 0) { return 1; } if (u->field_set & (1 << UF_HOST)) { if (http_parse_host(buf, u, found_at) != 0) { return 1; } } /* CONNECT requests can only contain "hostname:port" */ if (is_connect && u->field_set != ((1 << UF_HOST)|(1 << UF_PORT))) { return 1; } if (u->field_set & (1 << UF_PORT)) { /* Don't bother with endp; we've already validated the string */ unsigned long v = strtoul(buf + u->field_data[UF_PORT].off, NULL, 10); /* Ports have a max value of 2^16 */ if (v > 0xffff) { return 1; } u->port = (uint16_t) v; } return 0; } void http_parser_pause(http_parser *parser, int paused) { /* Users should only be pausing/unpausing a parser that is not in an error * state. In non-debug builds, there's not much that we can do about this * other than ignore it. */ if (HTTP_PARSER_ERRNO(parser) == HPE_OK || HTTP_PARSER_ERRNO(parser) == HPE_PAUSED) { SET_ERRNO((paused) ? HPE_PAUSED : HPE_OK); } else { assert(0 && "Attempting to pause parser in error state"); } } int http_body_is_final(const struct http_parser *parser) { return parser->state == s_message_done; } unsigned long http_parser_version(void) { return HTTP_PARSER_VERSION_MAJOR * 0x10000 | HTTP_PARSER_VERSION_MINOR * 0x00100 | HTTP_PARSER_VERSION_PATCH * 0x00001; } iotjs-1.0/deps/http-parser/http_parser.gyp000066400000000000000000000054471307356305600210040ustar00rootroot00000000000000# This file is used with the GYP meta build system. # http://code.google.com/p/gyp/ # To build try this: # svn co http://gyp.googlecode.com/svn/trunk gyp # ./gyp/gyp -f make --depth=`pwd` http_parser.gyp # ./out/Debug/test { 'target_defaults': { 'default_configuration': 'Debug', 'configurations': { # TODO: hoist these out and put them somewhere common, because # RuntimeLibrary MUST MATCH across the entire project 'Debug': { 'defines': [ 'DEBUG', '_DEBUG' ], 'cflags': [ '-Wall', '-Wextra', '-O0', '-g', '-ftrapv' ], 'msvs_settings': { 'VCCLCompilerTool': { 'RuntimeLibrary': 1, # static debug }, }, }, 'Release': { 'defines': [ 'NDEBUG' ], 'cflags': [ '-Wall', '-Wextra', '-O3' ], 'msvs_settings': { 'VCCLCompilerTool': { 'RuntimeLibrary': 0, # static release }, }, } }, 'msvs_settings': { 'VCCLCompilerTool': { }, 'VCLibrarianTool': { }, 'VCLinkerTool': { 'GenerateDebugInformation': 'true', }, }, 'conditions': [ ['OS == "win"', { 'defines': [ 'WIN32' ], }] ], }, 'targets': [ { 'target_name': 'http_parser', 'type': 'static_library', 'include_dirs': [ '.' ], 'direct_dependent_settings': { 'defines': [ 'HTTP_PARSER_STRICT=0' ], 'include_dirs': [ '.' ], }, 'defines': [ 'HTTP_PARSER_STRICT=0' ], 'sources': [ './http_parser.c', ], 'conditions': [ ['OS=="win"', { 'msvs_settings': { 'VCCLCompilerTool': { # Compile as C++. http_parser.c is actually C99, but C++ is # close enough in this case. 'CompileAs': 2, }, }, }] ], }, { 'target_name': 'http_parser_strict', 'type': 'static_library', 'include_dirs': [ '.' ], 'direct_dependent_settings': { 'defines': [ 'HTTP_PARSER_STRICT=1' ], 'include_dirs': [ '.' ], }, 'defines': [ 'HTTP_PARSER_STRICT=1' ], 'sources': [ './http_parser.c', ], 'conditions': [ ['OS=="win"', { 'msvs_settings': { 'VCCLCompilerTool': { # Compile as C++. http_parser.c is actually C99, but C++ is # close enough in this case. 'CompileAs': 2, }, }, }] ], }, { 'target_name': 'test-nonstrict', 'type': 'executable', 'dependencies': [ 'http_parser' ], 'sources': [ 'test.c' ] }, { 'target_name': 'test-strict', 'type': 'executable', 'dependencies': [ 'http_parser_strict' ], 'sources': [ 'test.c' ] } ] } iotjs-1.0/deps/http-parser/http_parser.h000066400000000000000000000312771307356305600204340ustar00rootroot00000000000000/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to * deal in the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. */ #ifndef http_parser_h #define http_parser_h #ifdef __cplusplus extern "C" { #endif /* Also update SONAME in the Makefile whenever you change these. */ #define HTTP_PARSER_VERSION_MAJOR 2 #define HTTP_PARSER_VERSION_MINOR 5 #define HTTP_PARSER_VERSION_PATCH 0 #include #if defined(_WIN32) && !defined(__MINGW32__) && (!defined(_MSC_VER) || _MSC_VER<1600) #include #include typedef __int8 int8_t; typedef unsigned __int8 uint8_t; typedef __int16 int16_t; typedef unsigned __int16 uint16_t; typedef __int32 int32_t; typedef unsigned __int32 uint32_t; typedef __int64 int64_t; typedef unsigned __int64 uint64_t; #else #include #endif /* Compile with -DHTTP_PARSER_STRICT=0 to make less checks, but run * faster */ #ifndef HTTP_PARSER_STRICT # define HTTP_PARSER_STRICT 1 #endif /* Maximium header size allowed. If the macro is not defined * before including this header then the default is used. To * change the maximum header size, define the macro in the build * environment (e.g. -DHTTP_MAX_HEADER_SIZE=). To remove * the effective limit on the size of the header, define the macro * to a very large number (e.g. -DHTTP_MAX_HEADER_SIZE=0x7fffffff) */ #ifndef HTTP_MAX_HEADER_SIZE # define HTTP_MAX_HEADER_SIZE (80*1024) #endif typedef struct http_parser http_parser; typedef struct http_parser_settings http_parser_settings; /* Callbacks should return non-zero to indicate an error. The parser will * then halt execution. * * The one exception is on_headers_complete. In a HTTP_RESPONSE parser * returning '1' from on_headers_complete will tell the parser that it * should not expect a body. This is used when receiving a response to a * HEAD request which may contain 'Content-Length' or 'Transfer-Encoding: * chunked' headers that indicate the presence of a body. * * http_data_cb does not return data chunks. It will be called arbitrarily * many times for each string. E.G. you might get 10 callbacks for "on_url" * each providing just a few characters more data. */ typedef int (*http_data_cb) (http_parser*, const char *at, size_t length); typedef int (*http_cb) (http_parser*); /* Request Methods */ #define HTTP_METHOD_MAP(XX) \ XX(0, DELETE, DELETE) \ XX(1, GET, GET) \ XX(2, HEAD, HEAD) \ XX(3, POST, POST) \ XX(4, PUT, PUT) \ /* pathological */ \ XX(5, CONNECT, CONNECT) \ XX(6, OPTIONS, OPTIONS) \ XX(7, TRACE, TRACE) \ /* webdav */ \ XX(8, COPY, COPY) \ XX(9, LOCK, LOCK) \ XX(10, MKCOL, MKCOL) \ XX(11, MOVE, MOVE) \ XX(12, PROPFIND, PROPFIND) \ XX(13, PROPPATCH, PROPPATCH) \ XX(14, SEARCH, SEARCH) \ XX(15, UNLOCK, UNLOCK) \ /* subversion */ \ XX(16, REPORT, REPORT) \ XX(17, MKACTIVITY, MKACTIVITY) \ XX(18, CHECKOUT, CHECKOUT) \ XX(19, MERGE, MERGE) \ /* upnp */ \ XX(20, MSEARCH, M-SEARCH) \ XX(21, NOTIFY, NOTIFY) \ XX(22, SUBSCRIBE, SUBSCRIBE) \ XX(23, UNSUBSCRIBE, UNSUBSCRIBE) \ /* RFC-5789 */ \ XX(24, PATCH, PATCH) \ XX(25, PURGE, PURGE) \ /* CalDAV */ \ XX(26, MKCALENDAR, MKCALENDAR) \ enum http_method { #define XX(num, name, string) HTTP_##name = num, HTTP_METHOD_MAP(XX) #undef XX }; enum http_parser_type { HTTP_REQUEST, HTTP_RESPONSE, HTTP_BOTH }; /* Flag values for http_parser.flags field */ enum flags { F_CHUNKED = 1 << 0 , F_CONNECTION_KEEP_ALIVE = 1 << 1 , F_CONNECTION_CLOSE = 1 << 2 , F_CONNECTION_UPGRADE = 1 << 3 , F_TRAILING = 1 << 4 , F_UPGRADE = 1 << 5 , F_SKIPBODY = 1 << 6 }; /* Map for errno-related constants * * The provided argument should be a macro that takes 2 arguments. */ #define HTTP_ERRNO_MAP(XX) \ /* No error */ \ XX(OK, "success") \ \ /* Callback-related errors */ \ XX(CB_message_begin, "the on_message_begin callback failed") \ XX(CB_url, "the on_url callback failed") \ XX(CB_header_field, "the on_header_field callback failed") \ XX(CB_header_value, "the on_header_value callback failed") \ XX(CB_headers_complete, "the on_headers_complete callback failed") \ XX(CB_body, "the on_body callback failed") \ XX(CB_message_complete, "the on_message_complete callback failed") \ XX(CB_status, "the on_status callback failed") \ XX(CB_chunk_header, "the on_chunk_header callback failed") \ XX(CB_chunk_complete, "the on_chunk_complete callback failed") \ \ /* Parsing-related errors */ \ XX(INVALID_EOF_STATE, "stream ended at an unexpected time") \ XX(HEADER_OVERFLOW, \ "too many header bytes seen; overflow detected") \ XX(CLOSED_CONNECTION, \ "data received after completed connection: close message") \ XX(INVALID_VERSION, "invalid HTTP version") \ XX(INVALID_STATUS, "invalid HTTP status code") \ XX(INVALID_METHOD, "invalid HTTP method") \ XX(INVALID_URL, "invalid URL") \ XX(INVALID_HOST, "invalid host") \ XX(INVALID_PORT, "invalid port") \ XX(INVALID_PATH, "invalid path") \ XX(INVALID_QUERY_STRING, "invalid query string") \ XX(INVALID_FRAGMENT, "invalid fragment") \ XX(LF_EXPECTED, "LF character expected") \ XX(INVALID_HEADER_TOKEN, "invalid character in header") \ XX(INVALID_CONTENT_LENGTH, \ "invalid character in content-length header") \ XX(INVALID_CHUNK_SIZE, \ "invalid character in chunk size header") \ XX(INVALID_CONSTANT, "invalid constant string") \ XX(INVALID_INTERNAL_STATE, "encountered unexpected internal state")\ XX(STRICT, "strict mode assertion failed") \ XX(PAUSED, "parser is paused") \ XX(UNKNOWN, "an unknown error occurred") /* Define HPE_* values for each errno value above */ #define HTTP_ERRNO_GEN(n, s) HPE_##n, enum http_errno { HTTP_ERRNO_MAP(HTTP_ERRNO_GEN) }; #undef HTTP_ERRNO_GEN /* Get an http_errno value from an http_parser */ #define HTTP_PARSER_ERRNO(p) ((enum http_errno) (p)->http_errno) struct http_parser { /** PRIVATE **/ unsigned int type : 2; /* enum http_parser_type */ unsigned int flags : 7; /* F_* values from 'flags' enum; semi-public */ unsigned int state : 7; /* enum state from http_parser.c */ unsigned int header_state : 8; /* enum header_state from http_parser.c */ unsigned int index : 8; /* index into current matcher */ uint32_t nread; /* # bytes read in various scenarios */ uint64_t content_length; /* # bytes in body (0 if no Content-Length header) */ /** READ-ONLY **/ unsigned short http_major; unsigned short http_minor; unsigned int status_code : 16; /* responses only */ unsigned int method : 8; /* requests only */ unsigned int http_errno : 7; /* 1 = Upgrade header was present and the parser has exited because of that. * 0 = No upgrade header present. * Should be checked when http_parser_execute() returns in addition to * error checking. */ unsigned int upgrade : 1; /** PUBLIC **/ void *data; /* A pointer to get hook to the "connection" or "socket" object */ }; struct http_parser_settings { http_cb on_message_begin; http_data_cb on_url; http_data_cb on_status; http_data_cb on_header_field; http_data_cb on_header_value; http_cb on_headers_complete; http_data_cb on_body; http_cb on_message_complete; /* When on_chunk_header is called, the current chunk length is stored * in parser->content_length. */ http_cb on_chunk_header; http_cb on_chunk_complete; }; enum http_parser_url_fields { UF_SCHEMA = 0 , UF_HOST = 1 , UF_PORT = 2 , UF_PATH = 3 , UF_QUERY = 4 , UF_FRAGMENT = 5 , UF_USERINFO = 6 , UF_MAX = 7 }; /* Result structure for http_parser_parse_url(). * * Callers should index into field_data[] with UF_* values iff field_set * has the relevant (1 << UF_*) bit set. As a courtesy to clients (and * because we probably have padding left over), we convert any port to * a uint16_t. */ struct http_parser_url { uint16_t field_set; /* Bitmask of (1 << UF_*) values */ uint16_t port; /* Converted UF_PORT string */ struct { uint16_t off; /* Offset into buffer in which field starts */ uint16_t len; /* Length of run in buffer */ } field_data[UF_MAX]; }; /* Returns the library version. Bits 16-23 contain the major version number, * bits 8-15 the minor version number and bits 0-7 the patch level. * Usage example: * * unsigned long version = http_parser_version(); * unsigned major = (version >> 16) & 255; * unsigned minor = (version >> 8) & 255; * unsigned patch = version & 255; * printf("http_parser v%u.%u.%u\n", major, minor, patch); */ unsigned long http_parser_version(void); void http_parser_init(http_parser *parser, enum http_parser_type type); /* Initialize http_parser_settings members to 0 */ void http_parser_settings_init(http_parser_settings *settings); /* Executes the parser. Returns number of parsed bytes. Sets * `parser->http_errno` on error. */ size_t http_parser_execute(http_parser *parser, const http_parser_settings *settings, const char *data, size_t len); /* If http_should_keep_alive() in the on_headers_complete or * on_message_complete callback returns 0, then this should be * the last message on the connection. * If you are the server, respond with the "Connection: close" header. * If you are the client, close the connection. */ int http_should_keep_alive(const http_parser *parser); /* Returns a string version of the HTTP method. */ const char *http_method_str(enum http_method m); /* Return a string name of the given error */ const char *http_errno_name(enum http_errno err); /* Return a string description of the given error */ const char *http_errno_description(enum http_errno err); /* Parse a URL; return nonzero on failure */ int http_parser_parse_url(const char *buf, size_t buflen, int is_connect, struct http_parser_url *u); /* Pause or un-pause the parser; a nonzero value pauses */ void http_parser_pause(http_parser *parser, int paused); /* Checks if this is the final chunk of the body. */ int http_body_is_final(const http_parser *parser); #ifdef __cplusplus } #endif #endif iotjs-1.0/deps/http-parser/test.c000066400000000000000000003111671307356305600170520ustar00rootroot00000000000000/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to * deal in the Software without restriction, including without limitation the * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. */ #include "http_parser.h" #include #include #include #include /* rand */ #include #include #if defined(__APPLE__) # undef strlcat # undef strlncpy # undef strlcpy #endif /* defined(__APPLE__) */ #undef TRUE #define TRUE 1 #undef FALSE #define FALSE 0 #define MAX_HEADERS 13 #define MAX_ELEMENT_SIZE 2048 #define MAX_CHUNKS 16 #define MIN(a,b) ((a) < (b) ? (a) : (b)) static http_parser *parser; struct message { const char *name; // for debugging purposes const char *raw; enum http_parser_type type; enum http_method method; int status_code; char response_status[MAX_ELEMENT_SIZE]; char request_path[MAX_ELEMENT_SIZE]; char request_url[MAX_ELEMENT_SIZE]; char fragment[MAX_ELEMENT_SIZE]; char query_string[MAX_ELEMENT_SIZE]; char body[MAX_ELEMENT_SIZE]; size_t body_size; const char *host; const char *userinfo; uint16_t port; int num_headers; enum { NONE=0, FIELD, VALUE } last_header_element; char headers [MAX_HEADERS][2][MAX_ELEMENT_SIZE]; int should_keep_alive; int num_chunks; int num_chunks_complete; int chunk_lengths[MAX_CHUNKS]; const char *upgrade; // upgraded body unsigned short http_major; unsigned short http_minor; int message_begin_cb_called; int headers_complete_cb_called; int message_complete_cb_called; int message_complete_on_eof; int body_is_final; }; static int currently_parsing_eof; static struct message messages[5]; static int num_messages; static http_parser_settings *current_pause_parser; /* * R E Q U E S T S * */ const struct message requests[] = #define CURL_GET 0 { {.name= "curl get" ,.type= HTTP_REQUEST ,.raw= "GET /test HTTP/1.1\r\n" "User-Agent: curl/7.18.0 (i486-pc-linux-gnu) libcurl/7.18.0 OpenSSL/0.9.8g zlib/1.2.3.3 libidn/1.1\r\n" "Host: 0.0.0.0=5000\r\n" "Accept: */*\r\n" "\r\n" ,.should_keep_alive= TRUE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 1 ,.method= HTTP_GET ,.query_string= "" ,.fragment= "" ,.request_path= "/test" ,.request_url= "/test" ,.num_headers= 3 ,.headers= { { "User-Agent", "curl/7.18.0 (i486-pc-linux-gnu) libcurl/7.18.0 OpenSSL/0.9.8g zlib/1.2.3.3 libidn/1.1" } , { "Host", "0.0.0.0=5000" } , { "Accept", "*/*" } } ,.body= "" } #define FIREFOX_GET 1 , {.name= "firefox get" ,.type= HTTP_REQUEST ,.raw= "GET /favicon.ico HTTP/1.1\r\n" "Host: 0.0.0.0=5000\r\n" "User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9) Gecko/2008061015 Firefox/3.0\r\n" "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8\r\n" "Accept-Language: en-us,en;q=0.5\r\n" "Accept-Encoding: gzip,deflate\r\n" "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7\r\n" "Keep-Alive: 300\r\n" "Connection: keep-alive\r\n" "\r\n" ,.should_keep_alive= TRUE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 1 ,.method= HTTP_GET ,.query_string= "" ,.fragment= "" ,.request_path= "/favicon.ico" ,.request_url= "/favicon.ico" ,.num_headers= 8 ,.headers= { { "Host", "0.0.0.0=5000" } , { "User-Agent", "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9) Gecko/2008061015 Firefox/3.0" } , { "Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8" } , { "Accept-Language", "en-us,en;q=0.5" } , { "Accept-Encoding", "gzip,deflate" } , { "Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.7" } , { "Keep-Alive", "300" } , { "Connection", "keep-alive" } } ,.body= "" } #define DUMBFUCK 2 , {.name= "dumbfuck" ,.type= HTTP_REQUEST ,.raw= "GET /dumbfuck HTTP/1.1\r\n" "aaaaaaaaaaaaa:++++++++++\r\n" "\r\n" ,.should_keep_alive= TRUE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 1 ,.method= HTTP_GET ,.query_string= "" ,.fragment= "" ,.request_path= "/dumbfuck" ,.request_url= "/dumbfuck" ,.num_headers= 1 ,.headers= { { "aaaaaaaaaaaaa", "++++++++++" } } ,.body= "" } #define FRAGMENT_IN_URI 3 , {.name= "fragment in url" ,.type= HTTP_REQUEST ,.raw= "GET /forums/1/topics/2375?page=1#posts-17408 HTTP/1.1\r\n" "\r\n" ,.should_keep_alive= TRUE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 1 ,.method= HTTP_GET ,.query_string= "page=1" ,.fragment= "posts-17408" ,.request_path= "/forums/1/topics/2375" /* XXX request url does include fragment? */ ,.request_url= "/forums/1/topics/2375?page=1#posts-17408" ,.num_headers= 0 ,.body= "" } #define GET_NO_HEADERS_NO_BODY 4 , {.name= "get no headers no body" ,.type= HTTP_REQUEST ,.raw= "GET /get_no_headers_no_body/world HTTP/1.1\r\n" "\r\n" ,.should_keep_alive= TRUE ,.message_complete_on_eof= FALSE /* would need Connection: close */ ,.http_major= 1 ,.http_minor= 1 ,.method= HTTP_GET ,.query_string= "" ,.fragment= "" ,.request_path= "/get_no_headers_no_body/world" ,.request_url= "/get_no_headers_no_body/world" ,.num_headers= 0 ,.body= "" } #define GET_ONE_HEADER_NO_BODY 5 , {.name= "get one header no body" ,.type= HTTP_REQUEST ,.raw= "GET /get_one_header_no_body HTTP/1.1\r\n" "Accept: */*\r\n" "\r\n" ,.should_keep_alive= TRUE ,.message_complete_on_eof= FALSE /* would need Connection: close */ ,.http_major= 1 ,.http_minor= 1 ,.method= HTTP_GET ,.query_string= "" ,.fragment= "" ,.request_path= "/get_one_header_no_body" ,.request_url= "/get_one_header_no_body" ,.num_headers= 1 ,.headers= { { "Accept" , "*/*" } } ,.body= "" } #define GET_FUNKY_CONTENT_LENGTH 6 , {.name= "get funky content length body hello" ,.type= HTTP_REQUEST ,.raw= "GET /get_funky_content_length_body_hello HTTP/1.0\r\n" "conTENT-Length: 5\r\n" "\r\n" "HELLO" ,.should_keep_alive= FALSE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 0 ,.method= HTTP_GET ,.query_string= "" ,.fragment= "" ,.request_path= "/get_funky_content_length_body_hello" ,.request_url= "/get_funky_content_length_body_hello" ,.num_headers= 1 ,.headers= { { "conTENT-Length" , "5" } } ,.body= "HELLO" } #define POST_IDENTITY_BODY_WORLD 7 , {.name= "post identity body world" ,.type= HTTP_REQUEST ,.raw= "POST /post_identity_body_world?q=search#hey HTTP/1.1\r\n" "Accept: */*\r\n" "Transfer-Encoding: identity\r\n" "Content-Length: 5\r\n" "\r\n" "World" ,.should_keep_alive= TRUE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 1 ,.method= HTTP_POST ,.query_string= "q=search" ,.fragment= "hey" ,.request_path= "/post_identity_body_world" ,.request_url= "/post_identity_body_world?q=search#hey" ,.num_headers= 3 ,.headers= { { "Accept", "*/*" } , { "Transfer-Encoding", "identity" } , { "Content-Length", "5" } } ,.body= "World" } #define POST_CHUNKED_ALL_YOUR_BASE 8 , {.name= "post - chunked body: all your base are belong to us" ,.type= HTTP_REQUEST ,.raw= "POST /post_chunked_all_your_base HTTP/1.1\r\n" "Transfer-Encoding: chunked\r\n" "\r\n" "1e\r\nall your base are belong to us\r\n" "0\r\n" "\r\n" ,.should_keep_alive= TRUE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 1 ,.method= HTTP_POST ,.query_string= "" ,.fragment= "" ,.request_path= "/post_chunked_all_your_base" ,.request_url= "/post_chunked_all_your_base" ,.num_headers= 1 ,.headers= { { "Transfer-Encoding" , "chunked" } } ,.body= "all your base are belong to us" ,.num_chunks_complete= 2 ,.chunk_lengths= { 0x1e } } #define TWO_CHUNKS_MULT_ZERO_END 9 , {.name= "two chunks ; triple zero ending" ,.type= HTTP_REQUEST ,.raw= "POST /two_chunks_mult_zero_end HTTP/1.1\r\n" "Transfer-Encoding: chunked\r\n" "\r\n" "5\r\nhello\r\n" "6\r\n world\r\n" "000\r\n" "\r\n" ,.should_keep_alive= TRUE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 1 ,.method= HTTP_POST ,.query_string= "" ,.fragment= "" ,.request_path= "/two_chunks_mult_zero_end" ,.request_url= "/two_chunks_mult_zero_end" ,.num_headers= 1 ,.headers= { { "Transfer-Encoding", "chunked" } } ,.body= "hello world" ,.num_chunks_complete= 3 ,.chunk_lengths= { 5, 6 } } #define CHUNKED_W_TRAILING_HEADERS 10 , {.name= "chunked with trailing headers. blech." ,.type= HTTP_REQUEST ,.raw= "POST /chunked_w_trailing_headers HTTP/1.1\r\n" "Transfer-Encoding: chunked\r\n" "\r\n" "5\r\nhello\r\n" "6\r\n world\r\n" "0\r\n" "Vary: *\r\n" "Content-Type: text/plain\r\n" "\r\n" ,.should_keep_alive= TRUE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 1 ,.method= HTTP_POST ,.query_string= "" ,.fragment= "" ,.request_path= "/chunked_w_trailing_headers" ,.request_url= "/chunked_w_trailing_headers" ,.num_headers= 3 ,.headers= { { "Transfer-Encoding", "chunked" } , { "Vary", "*" } , { "Content-Type", "text/plain" } } ,.body= "hello world" ,.num_chunks_complete= 3 ,.chunk_lengths= { 5, 6 } } #define CHUNKED_W_BULLSHIT_AFTER_LENGTH 11 , {.name= "with bullshit after the length" ,.type= HTTP_REQUEST ,.raw= "POST /chunked_w_bullshit_after_length HTTP/1.1\r\n" "Transfer-Encoding: chunked\r\n" "\r\n" "5; ihatew3;whatthefuck=aretheseparametersfor\r\nhello\r\n" "6; blahblah; blah\r\n world\r\n" "0\r\n" "\r\n" ,.should_keep_alive= TRUE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 1 ,.method= HTTP_POST ,.query_string= "" ,.fragment= "" ,.request_path= "/chunked_w_bullshit_after_length" ,.request_url= "/chunked_w_bullshit_after_length" ,.num_headers= 1 ,.headers= { { "Transfer-Encoding", "chunked" } } ,.body= "hello world" ,.num_chunks_complete= 3 ,.chunk_lengths= { 5, 6 } } #define WITH_QUOTES 12 , {.name= "with quotes" ,.type= HTTP_REQUEST ,.raw= "GET /with_\"stupid\"_quotes?foo=\"bar\" HTTP/1.1\r\n\r\n" ,.should_keep_alive= TRUE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 1 ,.method= HTTP_GET ,.query_string= "foo=\"bar\"" ,.fragment= "" ,.request_path= "/with_\"stupid\"_quotes" ,.request_url= "/with_\"stupid\"_quotes?foo=\"bar\"" ,.num_headers= 0 ,.headers= { } ,.body= "" } #define APACHEBENCH_GET 13 /* The server receiving this request SHOULD NOT wait for EOF * to know that content-length == 0. * How to represent this in a unit test? message_complete_on_eof * Compare with NO_CONTENT_LENGTH_RESPONSE. */ , {.name = "apachebench get" ,.type= HTTP_REQUEST ,.raw= "GET /test HTTP/1.0\r\n" "Host: 0.0.0.0:5000\r\n" "User-Agent: ApacheBench/2.3\r\n" "Accept: */*\r\n\r\n" ,.should_keep_alive= FALSE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 0 ,.method= HTTP_GET ,.query_string= "" ,.fragment= "" ,.request_path= "/test" ,.request_url= "/test" ,.num_headers= 3 ,.headers= { { "Host", "0.0.0.0:5000" } , { "User-Agent", "ApacheBench/2.3" } , { "Accept", "*/*" } } ,.body= "" } #define QUERY_URL_WITH_QUESTION_MARK_GET 14 /* Some clients include '?' characters in query strings. */ , {.name = "query url with question mark" ,.type= HTTP_REQUEST ,.raw= "GET /test.cgi?foo=bar?baz HTTP/1.1\r\n\r\n" ,.should_keep_alive= TRUE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 1 ,.method= HTTP_GET ,.query_string= "foo=bar?baz" ,.fragment= "" ,.request_path= "/test.cgi" ,.request_url= "/test.cgi?foo=bar?baz" ,.num_headers= 0 ,.headers= {} ,.body= "" } #define PREFIX_NEWLINE_GET 15 /* Some clients, especially after a POST in a keep-alive connection, * will send an extra CRLF before the next request */ , {.name = "newline prefix get" ,.type= HTTP_REQUEST ,.raw= "\r\nGET /test HTTP/1.1\r\n\r\n" ,.should_keep_alive= TRUE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 1 ,.method= HTTP_GET ,.query_string= "" ,.fragment= "" ,.request_path= "/test" ,.request_url= "/test" ,.num_headers= 0 ,.headers= { } ,.body= "" } #define UPGRADE_REQUEST 16 , {.name = "upgrade request" ,.type= HTTP_REQUEST ,.raw= "GET /demo HTTP/1.1\r\n" "Host: example.com\r\n" "Connection: Upgrade\r\n" "Sec-WebSocket-Key2: 12998 5 Y3 1 .P00\r\n" "Sec-WebSocket-Protocol: sample\r\n" "Upgrade: WebSocket\r\n" "Sec-WebSocket-Key1: 4 @1 46546xW%0l 1 5\r\n" "Origin: http://example.com\r\n" "\r\n" "Hot diggity dogg" ,.should_keep_alive= TRUE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 1 ,.method= HTTP_GET ,.query_string= "" ,.fragment= "" ,.request_path= "/demo" ,.request_url= "/demo" ,.num_headers= 7 ,.upgrade="Hot diggity dogg" ,.headers= { { "Host", "example.com" } , { "Connection", "Upgrade" } , { "Sec-WebSocket-Key2", "12998 5 Y3 1 .P00" } , { "Sec-WebSocket-Protocol", "sample" } , { "Upgrade", "WebSocket" } , { "Sec-WebSocket-Key1", "4 @1 46546xW%0l 1 5" } , { "Origin", "http://example.com" } } ,.body= "" } #define CONNECT_REQUEST 17 , {.name = "connect request" ,.type= HTTP_REQUEST ,.raw= "CONNECT 0-home0.netscape.com:443 HTTP/1.0\r\n" "User-agent: Mozilla/1.1N\r\n" "Proxy-authorization: basic aGVsbG86d29ybGQ=\r\n" "\r\n" "some data\r\n" "and yet even more data" ,.should_keep_alive= FALSE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 0 ,.method= HTTP_CONNECT ,.query_string= "" ,.fragment= "" ,.request_path= "" ,.request_url= "0-home0.netscape.com:443" ,.num_headers= 2 ,.upgrade="some data\r\nand yet even more data" ,.headers= { { "User-agent", "Mozilla/1.1N" } , { "Proxy-authorization", "basic aGVsbG86d29ybGQ=" } } ,.body= "" } #define REPORT_REQ 18 , {.name= "report request" ,.type= HTTP_REQUEST ,.raw= "REPORT /test HTTP/1.1\r\n" "\r\n" ,.should_keep_alive= TRUE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 1 ,.method= HTTP_REPORT ,.query_string= "" ,.fragment= "" ,.request_path= "/test" ,.request_url= "/test" ,.num_headers= 0 ,.headers= {} ,.body= "" } #define NO_HTTP_VERSION 19 , {.name= "request with no http version" ,.type= HTTP_REQUEST ,.raw= "GET /\r\n" "\r\n" ,.should_keep_alive= FALSE ,.message_complete_on_eof= FALSE ,.http_major= 0 ,.http_minor= 9 ,.method= HTTP_GET ,.query_string= "" ,.fragment= "" ,.request_path= "/" ,.request_url= "/" ,.num_headers= 0 ,.headers= {} ,.body= "" } #define MSEARCH_REQ 20 , {.name= "m-search request" ,.type= HTTP_REQUEST ,.raw= "M-SEARCH * HTTP/1.1\r\n" "HOST: 239.255.255.250:1900\r\n" "MAN: \"ssdp:discover\"\r\n" "ST: \"ssdp:all\"\r\n" "\r\n" ,.should_keep_alive= TRUE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 1 ,.method= HTTP_MSEARCH ,.query_string= "" ,.fragment= "" ,.request_path= "*" ,.request_url= "*" ,.num_headers= 3 ,.headers= { { "HOST", "239.255.255.250:1900" } , { "MAN", "\"ssdp:discover\"" } , { "ST", "\"ssdp:all\"" } } ,.body= "" } #define LINE_FOLDING_IN_HEADER 21 , {.name= "line folding in header value" ,.type= HTTP_REQUEST ,.raw= "GET / HTTP/1.1\r\n" "Line1: abc\r\n" "\tdef\r\n" " ghi\r\n" "\t\tjkl\r\n" " mno \r\n" "\t \tqrs\r\n" "Line2: \t line2\t\r\n" "Line3:\r\n" " line3\r\n" "Line4: \r\n" " \r\n" "Connection:\r\n" " close\r\n" "\r\n" ,.should_keep_alive= FALSE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 1 ,.method= HTTP_GET ,.query_string= "" ,.fragment= "" ,.request_path= "/" ,.request_url= "/" ,.num_headers= 5 ,.headers= { { "Line1", "abc\tdef ghi\t\tjkl mno \t \tqrs" } , { "Line2", "line2\t" } , { "Line3", "line3" } , { "Line4", "" } , { "Connection", "close" }, } ,.body= "" } #define QUERY_TERMINATED_HOST 22 , {.name= "host terminated by a query string" ,.type= HTTP_REQUEST ,.raw= "GET http://hypnotoad.org?hail=all HTTP/1.1\r\n" "\r\n" ,.should_keep_alive= TRUE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 1 ,.method= HTTP_GET ,.query_string= "hail=all" ,.fragment= "" ,.request_path= "" ,.request_url= "http://hypnotoad.org?hail=all" ,.host= "hypnotoad.org" ,.num_headers= 0 ,.headers= { } ,.body= "" } #define QUERY_TERMINATED_HOSTPORT 23 , {.name= "host:port terminated by a query string" ,.type= HTTP_REQUEST ,.raw= "GET http://hypnotoad.org:1234?hail=all HTTP/1.1\r\n" "\r\n" ,.should_keep_alive= TRUE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 1 ,.method= HTTP_GET ,.query_string= "hail=all" ,.fragment= "" ,.request_path= "" ,.request_url= "http://hypnotoad.org:1234?hail=all" ,.host= "hypnotoad.org" ,.port= 1234 ,.num_headers= 0 ,.headers= { } ,.body= "" } #define SPACE_TERMINATED_HOSTPORT 24 , {.name= "host:port terminated by a space" ,.type= HTTP_REQUEST ,.raw= "GET http://hypnotoad.org:1234 HTTP/1.1\r\n" "\r\n" ,.should_keep_alive= TRUE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 1 ,.method= HTTP_GET ,.query_string= "" ,.fragment= "" ,.request_path= "" ,.request_url= "http://hypnotoad.org:1234" ,.host= "hypnotoad.org" ,.port= 1234 ,.num_headers= 0 ,.headers= { } ,.body= "" } #define PATCH_REQ 25 , {.name = "PATCH request" ,.type= HTTP_REQUEST ,.raw= "PATCH /file.txt HTTP/1.1\r\n" "Host: www.example.com\r\n" "Content-Type: application/example\r\n" "If-Match: \"e0023aa4e\"\r\n" "Content-Length: 10\r\n" "\r\n" "cccccccccc" ,.should_keep_alive= TRUE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 1 ,.method= HTTP_PATCH ,.query_string= "" ,.fragment= "" ,.request_path= "/file.txt" ,.request_url= "/file.txt" ,.num_headers= 4 ,.headers= { { "Host", "www.example.com" } , { "Content-Type", "application/example" } , { "If-Match", "\"e0023aa4e\"" } , { "Content-Length", "10" } } ,.body= "cccccccccc" } #define CONNECT_CAPS_REQUEST 26 , {.name = "connect caps request" ,.type= HTTP_REQUEST ,.raw= "CONNECT HOME0.NETSCAPE.COM:443 HTTP/1.0\r\n" "User-agent: Mozilla/1.1N\r\n" "Proxy-authorization: basic aGVsbG86d29ybGQ=\r\n" "\r\n" ,.should_keep_alive= FALSE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 0 ,.method= HTTP_CONNECT ,.query_string= "" ,.fragment= "" ,.request_path= "" ,.request_url= "HOME0.NETSCAPE.COM:443" ,.num_headers= 2 ,.upgrade="" ,.headers= { { "User-agent", "Mozilla/1.1N" } , { "Proxy-authorization", "basic aGVsbG86d29ybGQ=" } } ,.body= "" } #if !HTTP_PARSER_STRICT #define UTF8_PATH_REQ 27 , {.name= "utf-8 path request" ,.type= HTTP_REQUEST ,.raw= "GET /δ¶/δt/pope?q=1#narf HTTP/1.1\r\n" "Host: github.com\r\n" "\r\n" ,.should_keep_alive= TRUE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 1 ,.method= HTTP_GET ,.query_string= "q=1" ,.fragment= "narf" ,.request_path= "/δ¶/δt/pope" ,.request_url= "/δ¶/δt/pope?q=1#narf" ,.num_headers= 1 ,.headers= { {"Host", "github.com" } } ,.body= "" } #define HOSTNAME_UNDERSCORE 28 , {.name = "hostname underscore" ,.type= HTTP_REQUEST ,.raw= "CONNECT home_0.netscape.com:443 HTTP/1.0\r\n" "User-agent: Mozilla/1.1N\r\n" "Proxy-authorization: basic aGVsbG86d29ybGQ=\r\n" "\r\n" ,.should_keep_alive= FALSE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 0 ,.method= HTTP_CONNECT ,.query_string= "" ,.fragment= "" ,.request_path= "" ,.request_url= "home_0.netscape.com:443" ,.num_headers= 2 ,.upgrade="" ,.headers= { { "User-agent", "Mozilla/1.1N" } , { "Proxy-authorization", "basic aGVsbG86d29ybGQ=" } } ,.body= "" } #endif /* !HTTP_PARSER_STRICT */ /* see https://github.com/ry/http-parser/issues/47 */ #define EAT_TRAILING_CRLF_NO_CONNECTION_CLOSE 29 , {.name = "eat CRLF between requests, no \"Connection: close\" header" ,.raw= "POST / HTTP/1.1\r\n" "Host: www.example.com\r\n" "Content-Type: application/x-www-form-urlencoded\r\n" "Content-Length: 4\r\n" "\r\n" "q=42\r\n" /* note the trailing CRLF */ ,.should_keep_alive= TRUE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 1 ,.method= HTTP_POST ,.query_string= "" ,.fragment= "" ,.request_path= "/" ,.request_url= "/" ,.num_headers= 3 ,.upgrade= 0 ,.headers= { { "Host", "www.example.com" } , { "Content-Type", "application/x-www-form-urlencoded" } , { "Content-Length", "4" } } ,.body= "q=42" } /* see https://github.com/ry/http-parser/issues/47 */ #define EAT_TRAILING_CRLF_WITH_CONNECTION_CLOSE 30 , {.name = "eat CRLF between requests even if \"Connection: close\" is set" ,.raw= "POST / HTTP/1.1\r\n" "Host: www.example.com\r\n" "Content-Type: application/x-www-form-urlencoded\r\n" "Content-Length: 4\r\n" "Connection: close\r\n" "\r\n" "q=42\r\n" /* note the trailing CRLF */ ,.should_keep_alive= FALSE ,.message_complete_on_eof= FALSE /* input buffer isn't empty when on_message_complete is called */ ,.http_major= 1 ,.http_minor= 1 ,.method= HTTP_POST ,.query_string= "" ,.fragment= "" ,.request_path= "/" ,.request_url= "/" ,.num_headers= 4 ,.upgrade= 0 ,.headers= { { "Host", "www.example.com" } , { "Content-Type", "application/x-www-form-urlencoded" } , { "Content-Length", "4" } , { "Connection", "close" } } ,.body= "q=42" } #define PURGE_REQ 31 , {.name = "PURGE request" ,.type= HTTP_REQUEST ,.raw= "PURGE /file.txt HTTP/1.1\r\n" "Host: www.example.com\r\n" "\r\n" ,.should_keep_alive= TRUE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 1 ,.method= HTTP_PURGE ,.query_string= "" ,.fragment= "" ,.request_path= "/file.txt" ,.request_url= "/file.txt" ,.num_headers= 1 ,.headers= { { "Host", "www.example.com" } } ,.body= "" } #define SEARCH_REQ 32 , {.name = "SEARCH request" ,.type= HTTP_REQUEST ,.raw= "SEARCH / HTTP/1.1\r\n" "Host: www.example.com\r\n" "\r\n" ,.should_keep_alive= TRUE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 1 ,.method= HTTP_SEARCH ,.query_string= "" ,.fragment= "" ,.request_path= "/" ,.request_url= "/" ,.num_headers= 1 ,.headers= { { "Host", "www.example.com" } } ,.body= "" } #define PROXY_WITH_BASIC_AUTH 33 , {.name= "host:port and basic_auth" ,.type= HTTP_REQUEST ,.raw= "GET http://a%12:b!&*$@hypnotoad.org:1234/toto HTTP/1.1\r\n" "\r\n" ,.should_keep_alive= TRUE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 1 ,.method= HTTP_GET ,.fragment= "" ,.request_path= "/toto" ,.request_url= "http://a%12:b!&*$@hypnotoad.org:1234/toto" ,.host= "hypnotoad.org" ,.userinfo= "a%12:b!&*$" ,.port= 1234 ,.num_headers= 0 ,.headers= { } ,.body= "" } #define LINE_FOLDING_IN_HEADER_WITH_LF 34 , {.name= "line folding in header value" ,.type= HTTP_REQUEST ,.raw= "GET / HTTP/1.1\n" "Line1: abc\n" "\tdef\n" " ghi\n" "\t\tjkl\n" " mno \n" "\t \tqrs\n" "Line2: \t line2\t\n" "Line3:\n" " line3\n" "Line4: \n" " \n" "Connection:\n" " close\n" "\n" ,.should_keep_alive= FALSE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 1 ,.method= HTTP_GET ,.query_string= "" ,.fragment= "" ,.request_path= "/" ,.request_url= "/" ,.num_headers= 5 ,.headers= { { "Line1", "abc\tdef ghi\t\tjkl mno \t \tqrs" } , { "Line2", "line2\t" } , { "Line3", "line3" } , { "Line4", "" } , { "Connection", "close" }, } ,.body= "" } #define CONNECTION_MULTI 35 , {.name = "multiple connection header values with folding" ,.type= HTTP_REQUEST ,.raw= "GET /demo HTTP/1.1\r\n" "Host: example.com\r\n" "Connection: Something,\r\n" " Upgrade, ,Keep-Alive\r\n" "Sec-WebSocket-Key2: 12998 5 Y3 1 .P00\r\n" "Sec-WebSocket-Protocol: sample\r\n" "Upgrade: WebSocket\r\n" "Sec-WebSocket-Key1: 4 @1 46546xW%0l 1 5\r\n" "Origin: http://example.com\r\n" "\r\n" "Hot diggity dogg" ,.should_keep_alive= TRUE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 1 ,.method= HTTP_GET ,.query_string= "" ,.fragment= "" ,.request_path= "/demo" ,.request_url= "/demo" ,.num_headers= 7 ,.upgrade="Hot diggity dogg" ,.headers= { { "Host", "example.com" } , { "Connection", "Something, Upgrade, ,Keep-Alive" } , { "Sec-WebSocket-Key2", "12998 5 Y3 1 .P00" } , { "Sec-WebSocket-Protocol", "sample" } , { "Upgrade", "WebSocket" } , { "Sec-WebSocket-Key1", "4 @1 46546xW%0l 1 5" } , { "Origin", "http://example.com" } } ,.body= "" } #define CONNECTION_MULTI_LWS 36 , {.name = "multiple connection header values with folding and lws" ,.type= HTTP_REQUEST ,.raw= "GET /demo HTTP/1.1\r\n" "Connection: keep-alive, upgrade\r\n" "Upgrade: WebSocket\r\n" "\r\n" "Hot diggity dogg" ,.should_keep_alive= TRUE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 1 ,.method= HTTP_GET ,.query_string= "" ,.fragment= "" ,.request_path= "/demo" ,.request_url= "/demo" ,.num_headers= 2 ,.upgrade="Hot diggity dogg" ,.headers= { { "Connection", "keep-alive, upgrade" } , { "Upgrade", "WebSocket" } } ,.body= "" } #define CONNECTION_MULTI_LWS_CRLF 37 , {.name = "multiple connection header values with folding and lws" ,.type= HTTP_REQUEST ,.raw= "GET /demo HTTP/1.1\r\n" "Connection: keep-alive, \r\n upgrade\r\n" "Upgrade: WebSocket\r\n" "\r\n" "Hot diggity dogg" ,.should_keep_alive= TRUE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 1 ,.method= HTTP_GET ,.query_string= "" ,.fragment= "" ,.request_path= "/demo" ,.request_url= "/demo" ,.num_headers= 2 ,.upgrade="Hot diggity dogg" ,.headers= { { "Connection", "keep-alive, upgrade" } , { "Upgrade", "WebSocket" } } ,.body= "" } #define UPGRADE_POST_REQUEST 38 , {.name = "upgrade post request" ,.type= HTTP_REQUEST ,.raw= "POST /demo HTTP/1.1\r\n" "Host: example.com\r\n" "Connection: Upgrade\r\n" "Upgrade: HTTP/2.0\r\n" "Content-Length: 15\r\n" "\r\n" "sweet post body" "Hot diggity dogg" ,.should_keep_alive= TRUE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 1 ,.method= HTTP_POST ,.request_path= "/demo" ,.request_url= "/demo" ,.num_headers= 4 ,.upgrade="Hot diggity dogg" ,.headers= { { "Host", "example.com" } , { "Connection", "Upgrade" } , { "Upgrade", "HTTP/2.0" } , { "Content-Length", "15" } } ,.body= "sweet post body" } #define CONNECT_WITH_BODY_REQUEST 39 , {.name = "connect with body request" ,.type= HTTP_REQUEST ,.raw= "CONNECT foo.bar.com:443 HTTP/1.0\r\n" "User-agent: Mozilla/1.1N\r\n" "Proxy-authorization: basic aGVsbG86d29ybGQ=\r\n" "Content-Length: 10\r\n" "\r\n" "blarfcicle" ,.should_keep_alive= FALSE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 0 ,.method= HTTP_CONNECT ,.request_url= "foo.bar.com:443" ,.num_headers= 3 ,.upgrade="blarfcicle" ,.headers= { { "User-agent", "Mozilla/1.1N" } , { "Proxy-authorization", "basic aGVsbG86d29ybGQ=" } , { "Content-Length", "10" } } ,.body= "" } , {.name= NULL } /* sentinel */ }; /* * R E S P O N S E S * */ const struct message responses[] = #define GOOGLE_301 0 { {.name= "google 301" ,.type= HTTP_RESPONSE ,.raw= "HTTP/1.1 301 Moved Permanently\r\n" "Location: http://www.google.com/\r\n" "Content-Type: text/html; charset=UTF-8\r\n" "Date: Sun, 26 Apr 2009 11:11:49 GMT\r\n" "Expires: Tue, 26 May 2009 11:11:49 GMT\r\n" "X-$PrototypeBI-Version: 1.6.0.3\r\n" /* $ char in header field */ "Cache-Control: public, max-age=2592000\r\n" "Server: gws\r\n" "Content-Length: 219 \r\n" "\r\n" "\n" "301 Moved\n" "

301 Moved

\n" "The document has moved\n" "here.\r\n" "\r\n" ,.should_keep_alive= TRUE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 1 ,.status_code= 301 ,.response_status= "Moved Permanently" ,.num_headers= 8 ,.headers= { { "Location", "http://www.google.com/" } , { "Content-Type", "text/html; charset=UTF-8" } , { "Date", "Sun, 26 Apr 2009 11:11:49 GMT" } , { "Expires", "Tue, 26 May 2009 11:11:49 GMT" } , { "X-$PrototypeBI-Version", "1.6.0.3" } , { "Cache-Control", "public, max-age=2592000" } , { "Server", "gws" } , { "Content-Length", "219 " } } ,.body= "\n" "301 Moved\n" "

301 Moved

\n" "The document has moved\n" "here.\r\n" "\r\n" } #define NO_CONTENT_LENGTH_RESPONSE 1 /* The client should wait for the server's EOF. That is, when content-length * is not specified, and "Connection: close", the end of body is specified * by the EOF. * Compare with APACHEBENCH_GET */ , {.name= "no content-length response" ,.type= HTTP_RESPONSE ,.raw= "HTTP/1.1 200 OK\r\n" "Date: Tue, 04 Aug 2009 07:59:32 GMT\r\n" "Server: Apache\r\n" "X-Powered-By: Servlet/2.5 JSP/2.1\r\n" "Content-Type: text/xml; charset=utf-8\r\n" "Connection: close\r\n" "\r\n" "\n" "\n" " \n" " \n" " SOAP-ENV:Client\n" " Client Error\n" " \n" " \n" "" ,.should_keep_alive= FALSE ,.message_complete_on_eof= TRUE ,.http_major= 1 ,.http_minor= 1 ,.status_code= 200 ,.response_status= "OK" ,.num_headers= 5 ,.headers= { { "Date", "Tue, 04 Aug 2009 07:59:32 GMT" } , { "Server", "Apache" } , { "X-Powered-By", "Servlet/2.5 JSP/2.1" } , { "Content-Type", "text/xml; charset=utf-8" } , { "Connection", "close" } } ,.body= "\n" "\n" " \n" " \n" " SOAP-ENV:Client\n" " Client Error\n" " \n" " \n" "" } #define NO_HEADERS_NO_BODY_404 2 , {.name= "404 no headers no body" ,.type= HTTP_RESPONSE ,.raw= "HTTP/1.1 404 Not Found\r\n\r\n" ,.should_keep_alive= FALSE ,.message_complete_on_eof= TRUE ,.http_major= 1 ,.http_minor= 1 ,.status_code= 404 ,.response_status= "Not Found" ,.num_headers= 0 ,.headers= {} ,.body_size= 0 ,.body= "" } #define NO_REASON_PHRASE 3 , {.name= "301 no response phrase" ,.type= HTTP_RESPONSE ,.raw= "HTTP/1.1 301\r\n\r\n" ,.should_keep_alive = FALSE ,.message_complete_on_eof= TRUE ,.http_major= 1 ,.http_minor= 1 ,.status_code= 301 ,.response_status= "" ,.num_headers= 0 ,.headers= {} ,.body= "" } #define TRAILING_SPACE_ON_CHUNKED_BODY 4 , {.name="200 trailing space on chunked body" ,.type= HTTP_RESPONSE ,.raw= "HTTP/1.1 200 OK\r\n" "Content-Type: text/plain\r\n" "Transfer-Encoding: chunked\r\n" "\r\n" "25 \r\n" "This is the data in the first chunk\r\n" "\r\n" "1C\r\n" "and this is the second one\r\n" "\r\n" "0 \r\n" "\r\n" ,.should_keep_alive= TRUE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 1 ,.status_code= 200 ,.response_status= "OK" ,.num_headers= 2 ,.headers= { {"Content-Type", "text/plain" } , {"Transfer-Encoding", "chunked" } } ,.body_size = 37+28 ,.body = "This is the data in the first chunk\r\n" "and this is the second one\r\n" ,.num_chunks_complete= 3 ,.chunk_lengths= { 0x25, 0x1c } } #define NO_CARRIAGE_RET 5 , {.name="no carriage ret" ,.type= HTTP_RESPONSE ,.raw= "HTTP/1.1 200 OK\n" "Content-Type: text/html; charset=utf-8\n" "Connection: close\n" "\n" "these headers are from http://news.ycombinator.com/" ,.should_keep_alive= FALSE ,.message_complete_on_eof= TRUE ,.http_major= 1 ,.http_minor= 1 ,.status_code= 200 ,.response_status= "OK" ,.num_headers= 2 ,.headers= { {"Content-Type", "text/html; charset=utf-8" } , {"Connection", "close" } } ,.body= "these headers are from http://news.ycombinator.com/" } #define PROXY_CONNECTION 6 , {.name="proxy connection" ,.type= HTTP_RESPONSE ,.raw= "HTTP/1.1 200 OK\r\n" "Content-Type: text/html; charset=UTF-8\r\n" "Content-Length: 11\r\n" "Proxy-Connection: close\r\n" "Date: Thu, 31 Dec 2009 20:55:48 +0000\r\n" "\r\n" "hello world" ,.should_keep_alive= FALSE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 1 ,.status_code= 200 ,.response_status= "OK" ,.num_headers= 4 ,.headers= { {"Content-Type", "text/html; charset=UTF-8" } , {"Content-Length", "11" } , {"Proxy-Connection", "close" } , {"Date", "Thu, 31 Dec 2009 20:55:48 +0000"} } ,.body= "hello world" } #define UNDERSTORE_HEADER_KEY 7 // shown by // curl -o /dev/null -v "http://ad.doubleclick.net/pfadx/DARTSHELLCONFIGXML;dcmt=text/xml;" , {.name="underscore header key" ,.type= HTTP_RESPONSE ,.raw= "HTTP/1.1 200 OK\r\n" "Server: DCLK-AdSvr\r\n" "Content-Type: text/xml\r\n" "Content-Length: 0\r\n" "DCLK_imp: v7;x;114750856;0-0;0;17820020;0/0;21603567/21621457/1;;~okv=;dcmt=text/xml;;~cs=o\r\n\r\n" ,.should_keep_alive= TRUE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 1 ,.status_code= 200 ,.response_status= "OK" ,.num_headers= 4 ,.headers= { {"Server", "DCLK-AdSvr" } , {"Content-Type", "text/xml" } , {"Content-Length", "0" } , {"DCLK_imp", "v7;x;114750856;0-0;0;17820020;0/0;21603567/21621457/1;;~okv=;dcmt=text/xml;;~cs=o" } } ,.body= "" } #define BONJOUR_MADAME_FR 8 /* The client should not merge two headers fields when the first one doesn't * have a value. */ , {.name= "bonjourmadame.fr" ,.type= HTTP_RESPONSE ,.raw= "HTTP/1.0 301 Moved Permanently\r\n" "Date: Thu, 03 Jun 2010 09:56:32 GMT\r\n" "Server: Apache/2.2.3 (Red Hat)\r\n" "Cache-Control: public\r\n" "Pragma: \r\n" "Location: http://www.bonjourmadame.fr/\r\n" "Vary: Accept-Encoding\r\n" "Content-Length: 0\r\n" "Content-Type: text/html; charset=UTF-8\r\n" "Connection: keep-alive\r\n" "\r\n" ,.should_keep_alive= TRUE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 0 ,.status_code= 301 ,.response_status= "Moved Permanently" ,.num_headers= 9 ,.headers= { { "Date", "Thu, 03 Jun 2010 09:56:32 GMT" } , { "Server", "Apache/2.2.3 (Red Hat)" } , { "Cache-Control", "public" } , { "Pragma", "" } , { "Location", "http://www.bonjourmadame.fr/" } , { "Vary", "Accept-Encoding" } , { "Content-Length", "0" } , { "Content-Type", "text/html; charset=UTF-8" } , { "Connection", "keep-alive" } } ,.body= "" } #define RES_FIELD_UNDERSCORE 9 /* Should handle spaces in header fields */ , {.name= "field underscore" ,.type= HTTP_RESPONSE ,.raw= "HTTP/1.1 200 OK\r\n" "Date: Tue, 28 Sep 2010 01:14:13 GMT\r\n" "Server: Apache\r\n" "Cache-Control: no-cache, must-revalidate\r\n" "Expires: Mon, 26 Jul 1997 05:00:00 GMT\r\n" ".et-Cookie: PlaxoCS=1274804622353690521; path=/; domain=.plaxo.com\r\n" "Vary: Accept-Encoding\r\n" "_eep-Alive: timeout=45\r\n" /* semantic value ignored */ "_onnection: Keep-Alive\r\n" /* semantic value ignored */ "Transfer-Encoding: chunked\r\n" "Content-Type: text/html\r\n" "Connection: close\r\n" "\r\n" "0\r\n\r\n" ,.should_keep_alive= FALSE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 1 ,.status_code= 200 ,.response_status= "OK" ,.num_headers= 11 ,.headers= { { "Date", "Tue, 28 Sep 2010 01:14:13 GMT" } , { "Server", "Apache" } , { "Cache-Control", "no-cache, must-revalidate" } , { "Expires", "Mon, 26 Jul 1997 05:00:00 GMT" } , { ".et-Cookie", "PlaxoCS=1274804622353690521; path=/; domain=.plaxo.com" } , { "Vary", "Accept-Encoding" } , { "_eep-Alive", "timeout=45" } , { "_onnection", "Keep-Alive" } , { "Transfer-Encoding", "chunked" } , { "Content-Type", "text/html" } , { "Connection", "close" } } ,.body= "" ,.num_chunks_complete= 1 ,.chunk_lengths= {} } #define NON_ASCII_IN_STATUS_LINE 10 /* Should handle non-ASCII in status line */ , {.name= "non-ASCII in status line" ,.type= HTTP_RESPONSE ,.raw= "HTTP/1.1 500 Oriëntatieprobleem\r\n" "Date: Fri, 5 Nov 2010 23:07:12 GMT+2\r\n" "Content-Length: 0\r\n" "Connection: close\r\n" "\r\n" ,.should_keep_alive= FALSE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 1 ,.status_code= 500 ,.response_status= "Oriëntatieprobleem" ,.num_headers= 3 ,.headers= { { "Date", "Fri, 5 Nov 2010 23:07:12 GMT+2" } , { "Content-Length", "0" } , { "Connection", "close" } } ,.body= "" } #define HTTP_VERSION_0_9 11 /* Should handle HTTP/0.9 */ , {.name= "http version 0.9" ,.type= HTTP_RESPONSE ,.raw= "HTTP/0.9 200 OK\r\n" "\r\n" ,.should_keep_alive= FALSE ,.message_complete_on_eof= TRUE ,.http_major= 0 ,.http_minor= 9 ,.status_code= 200 ,.response_status= "OK" ,.num_headers= 0 ,.headers= {} ,.body= "" } #define NO_CONTENT_LENGTH_NO_TRANSFER_ENCODING_RESPONSE 12 /* The client should wait for the server's EOF. That is, when neither * content-length nor transfer-encoding is specified, the end of body * is specified by the EOF. */ , {.name= "neither content-length nor transfer-encoding response" ,.type= HTTP_RESPONSE ,.raw= "HTTP/1.1 200 OK\r\n" "Content-Type: text/plain\r\n" "\r\n" "hello world" ,.should_keep_alive= FALSE ,.message_complete_on_eof= TRUE ,.http_major= 1 ,.http_minor= 1 ,.status_code= 200 ,.response_status= "OK" ,.num_headers= 1 ,.headers= { { "Content-Type", "text/plain" } } ,.body= "hello world" } #define NO_BODY_HTTP10_KA_200 13 , {.name= "HTTP/1.0 with keep-alive and EOF-terminated 200 status" ,.type= HTTP_RESPONSE ,.raw= "HTTP/1.0 200 OK\r\n" "Connection: keep-alive\r\n" "\r\n" ,.should_keep_alive= FALSE ,.message_complete_on_eof= TRUE ,.http_major= 1 ,.http_minor= 0 ,.status_code= 200 ,.response_status= "OK" ,.num_headers= 1 ,.headers= { { "Connection", "keep-alive" } } ,.body_size= 0 ,.body= "" } #define NO_BODY_HTTP10_KA_204 14 , {.name= "HTTP/1.0 with keep-alive and a 204 status" ,.type= HTTP_RESPONSE ,.raw= "HTTP/1.0 204 No content\r\n" "Connection: keep-alive\r\n" "\r\n" ,.should_keep_alive= TRUE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 0 ,.status_code= 204 ,.response_status= "No content" ,.num_headers= 1 ,.headers= { { "Connection", "keep-alive" } } ,.body_size= 0 ,.body= "" } #define NO_BODY_HTTP11_KA_200 15 , {.name= "HTTP/1.1 with an EOF-terminated 200 status" ,.type= HTTP_RESPONSE ,.raw= "HTTP/1.1 200 OK\r\n" "\r\n" ,.should_keep_alive= FALSE ,.message_complete_on_eof= TRUE ,.http_major= 1 ,.http_minor= 1 ,.status_code= 200 ,.response_status= "OK" ,.num_headers= 0 ,.headers={} ,.body_size= 0 ,.body= "" } #define NO_BODY_HTTP11_KA_204 16 , {.name= "HTTP/1.1 with a 204 status" ,.type= HTTP_RESPONSE ,.raw= "HTTP/1.1 204 No content\r\n" "\r\n" ,.should_keep_alive= TRUE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 1 ,.status_code= 204 ,.response_status= "No content" ,.num_headers= 0 ,.headers={} ,.body_size= 0 ,.body= "" } #define NO_BODY_HTTP11_NOKA_204 17 , {.name= "HTTP/1.1 with a 204 status and keep-alive disabled" ,.type= HTTP_RESPONSE ,.raw= "HTTP/1.1 204 No content\r\n" "Connection: close\r\n" "\r\n" ,.should_keep_alive= FALSE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 1 ,.status_code= 204 ,.response_status= "No content" ,.num_headers= 1 ,.headers= { { "Connection", "close" } } ,.body_size= 0 ,.body= "" } #define NO_BODY_HTTP11_KA_CHUNKED_200 18 , {.name= "HTTP/1.1 with chunked endocing and a 200 response" ,.type= HTTP_RESPONSE ,.raw= "HTTP/1.1 200 OK\r\n" "Transfer-Encoding: chunked\r\n" "\r\n" "0\r\n" "\r\n" ,.should_keep_alive= TRUE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 1 ,.status_code= 200 ,.response_status= "OK" ,.num_headers= 1 ,.headers= { { "Transfer-Encoding", "chunked" } } ,.body_size= 0 ,.body= "" ,.num_chunks_complete= 1 } #if !HTTP_PARSER_STRICT #define SPACE_IN_FIELD_RES 19 /* Should handle spaces in header fields */ , {.name= "field space" ,.type= HTTP_RESPONSE ,.raw= "HTTP/1.1 200 OK\r\n" "Server: Microsoft-IIS/6.0\r\n" "X-Powered-By: ASP.NET\r\n" "en-US Content-Type: text/xml\r\n" /* this is the problem */ "Content-Type: text/xml\r\n" "Content-Length: 16\r\n" "Date: Fri, 23 Jul 2010 18:45:38 GMT\r\n" "Connection: keep-alive\r\n" "\r\n" "hello" /* fake body */ ,.should_keep_alive= TRUE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 1 ,.status_code= 200 ,.response_status= "OK" ,.num_headers= 7 ,.headers= { { "Server", "Microsoft-IIS/6.0" } , { "X-Powered-By", "ASP.NET" } , { "en-US Content-Type", "text/xml" } , { "Content-Type", "text/xml" } , { "Content-Length", "16" } , { "Date", "Fri, 23 Jul 2010 18:45:38 GMT" } , { "Connection", "keep-alive" } } ,.body= "hello" } #endif /* !HTTP_PARSER_STRICT */ #define AMAZON_COM 20 , {.name= "amazon.com" ,.type= HTTP_RESPONSE ,.raw= "HTTP/1.1 301 MovedPermanently\r\n" "Date: Wed, 15 May 2013 17:06:33 GMT\r\n" "Server: Server\r\n" "x-amz-id-1: 0GPHKXSJQ826RK7GZEB2\r\n" "p3p: policyref=\"http://www.amazon.com/w3c/p3p.xml\",CP=\"CAO DSP LAW CUR ADM IVAo IVDo CONo OTPo OUR DELi PUBi OTRi BUS PHY ONL UNI PUR FIN COM NAV INT DEM CNT STA HEA PRE LOC GOV OTC \"\r\n" "x-amz-id-2: STN69VZxIFSz9YJLbz1GDbxpbjG6Qjmmq5E3DxRhOUw+Et0p4hr7c/Q8qNcx4oAD\r\n" "Location: http://www.amazon.com/Dan-Brown/e/B000AP9DSU/ref=s9_pop_gw_al1?_encoding=UTF8&refinementId=618073011&pf_rd_m=ATVPDKIKX0DER&pf_rd_s=center-2&pf_rd_r=0SHYY5BZXN3KR20BNFAY&pf_rd_t=101&pf_rd_p=1263340922&pf_rd_i=507846\r\n" "Vary: Accept-Encoding,User-Agent\r\n" "Content-Type: text/html; charset=ISO-8859-1\r\n" "Transfer-Encoding: chunked\r\n" "\r\n" "1\r\n" "\n\r\n" "0\r\n" "\r\n" ,.should_keep_alive= TRUE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 1 ,.status_code= 301 ,.response_status= "MovedPermanently" ,.num_headers= 9 ,.headers= { { "Date", "Wed, 15 May 2013 17:06:33 GMT" } , { "Server", "Server" } , { "x-amz-id-1", "0GPHKXSJQ826RK7GZEB2" } , { "p3p", "policyref=\"http://www.amazon.com/w3c/p3p.xml\",CP=\"CAO DSP LAW CUR ADM IVAo IVDo CONo OTPo OUR DELi PUBi OTRi BUS PHY ONL UNI PUR FIN COM NAV INT DEM CNT STA HEA PRE LOC GOV OTC \"" } , { "x-amz-id-2", "STN69VZxIFSz9YJLbz1GDbxpbjG6Qjmmq5E3DxRhOUw+Et0p4hr7c/Q8qNcx4oAD" } , { "Location", "http://www.amazon.com/Dan-Brown/e/B000AP9DSU/ref=s9_pop_gw_al1?_encoding=UTF8&refinementId=618073011&pf_rd_m=ATVPDKIKX0DER&pf_rd_s=center-2&pf_rd_r=0SHYY5BZXN3KR20BNFAY&pf_rd_t=101&pf_rd_p=1263340922&pf_rd_i=507846" } , { "Vary", "Accept-Encoding,User-Agent" } , { "Content-Type", "text/html; charset=ISO-8859-1" } , { "Transfer-Encoding", "chunked" } } ,.body= "\n" ,.num_chunks_complete= 2 ,.chunk_lengths= { 1 } } #define EMPTY_REASON_PHRASE_AFTER_SPACE 20 , {.name= "empty reason phrase after space" ,.type= HTTP_RESPONSE ,.raw= "HTTP/1.1 200 \r\n" "\r\n" ,.should_keep_alive= FALSE ,.message_complete_on_eof= TRUE ,.http_major= 1 ,.http_minor= 1 ,.status_code= 200 ,.response_status= "" ,.num_headers= 0 ,.headers= {} ,.body= "" } , {.name= NULL } /* sentinel */ }; /* strnlen() is a POSIX.2008 addition. Can't rely on it being available so * define it ourselves. */ size_t strnlen(const char *s, size_t maxlen) { const char *p; p = memchr(s, '\0', maxlen); if (p == NULL) return maxlen; return p - s; } size_t strlncat(char *dst, size_t len, const char *src, size_t n) { size_t slen; size_t dlen; size_t rlen; size_t ncpy; slen = strnlen(src, n); dlen = strnlen(dst, len); if (dlen < len) { rlen = len - dlen; ncpy = slen < rlen ? slen : (rlen - 1); memcpy(dst + dlen, src, ncpy); dst[dlen + ncpy] = '\0'; } assert(len > slen + dlen); return slen + dlen; } size_t strlcat(char *dst, const char *src, size_t len) { return strlncat(dst, len, src, (size_t) -1); } size_t strlncpy(char *dst, size_t len, const char *src, size_t n) { size_t slen; size_t ncpy; slen = strnlen(src, n); if (len > 0) { ncpy = slen < len ? slen : (len - 1); memcpy(dst, src, ncpy); dst[ncpy] = '\0'; } assert(len > slen); return slen; } size_t strlcpy(char *dst, const char *src, size_t len) { return strlncpy(dst, len, src, (size_t) -1); } int request_url_cb (http_parser *p, const char *buf, size_t len) { assert(p == parser); strlncat(messages[num_messages].request_url, sizeof(messages[num_messages].request_url), buf, len); return 0; } int header_field_cb (http_parser *p, const char *buf, size_t len) { assert(p == parser); struct message *m = &messages[num_messages]; if (m->last_header_element != FIELD) m->num_headers++; strlncat(m->headers[m->num_headers-1][0], sizeof(m->headers[m->num_headers-1][0]), buf, len); m->last_header_element = FIELD; return 0; } int header_value_cb (http_parser *p, const char *buf, size_t len) { assert(p == parser); struct message *m = &messages[num_messages]; strlncat(m->headers[m->num_headers-1][1], sizeof(m->headers[m->num_headers-1][1]), buf, len); m->last_header_element = VALUE; return 0; } void check_body_is_final (const http_parser *p) { if (messages[num_messages].body_is_final) { fprintf(stderr, "\n\n *** Error http_body_is_final() should return 1 " "on last on_body callback call " "but it doesn't! ***\n\n"); assert(0); abort(); } messages[num_messages].body_is_final = http_body_is_final(p); } int body_cb (http_parser *p, const char *buf, size_t len) { assert(p == parser); strlncat(messages[num_messages].body, sizeof(messages[num_messages].body), buf, len); messages[num_messages].body_size += len; check_body_is_final(p); // printf("body_cb: '%s'\n", requests[num_messages].body); return 0; } int count_body_cb (http_parser *p, const char *buf, size_t len) { assert(p == parser); assert(buf); messages[num_messages].body_size += len; check_body_is_final(p); return 0; } int message_begin_cb (http_parser *p) { assert(p == parser); messages[num_messages].message_begin_cb_called = TRUE; return 0; } int headers_complete_cb (http_parser *p) { assert(p == parser); messages[num_messages].method = parser->method; messages[num_messages].status_code = parser->status_code; messages[num_messages].http_major = parser->http_major; messages[num_messages].http_minor = parser->http_minor; messages[num_messages].headers_complete_cb_called = TRUE; messages[num_messages].should_keep_alive = http_should_keep_alive(parser); return 0; } int message_complete_cb (http_parser *p) { assert(p == parser); if (messages[num_messages].should_keep_alive != http_should_keep_alive(parser)) { fprintf(stderr, "\n\n *** Error http_should_keep_alive() should have same " "value in both on_message_complete and on_headers_complete " "but it doesn't! ***\n\n"); assert(0); abort(); } if (messages[num_messages].body_size && http_body_is_final(p) && !messages[num_messages].body_is_final) { fprintf(stderr, "\n\n *** Error http_body_is_final() should return 1 " "on last on_body callback call " "but it doesn't! ***\n\n"); assert(0); abort(); } messages[num_messages].message_complete_cb_called = TRUE; messages[num_messages].message_complete_on_eof = currently_parsing_eof; num_messages++; return 0; } int response_status_cb (http_parser *p, const char *buf, size_t len) { assert(p == parser); strlncat(messages[num_messages].response_status, sizeof(messages[num_messages].response_status), buf, len); return 0; } int chunk_header_cb (http_parser *p) { assert(p == parser); int chunk_idx = messages[num_messages].num_chunks; messages[num_messages].num_chunks++; if (chunk_idx < MAX_CHUNKS) { messages[num_messages].chunk_lengths[chunk_idx] = p->content_length; } return 0; } int chunk_complete_cb (http_parser *p) { assert(p == parser); /* Here we want to verify that each chunk_header_cb is matched by a * chunk_complete_cb, so not only should the total number of calls to * both callbacks be the same, but they also should be interleaved * properly */ assert(messages[num_messages].num_chunks == messages[num_messages].num_chunks_complete + 1); messages[num_messages].num_chunks_complete++; return 0; } /* These dontcall_* callbacks exist so that we can verify that when we're * paused, no additional callbacks are invoked */ int dontcall_message_begin_cb (http_parser *p) { if (p) { } // gcc fprintf(stderr, "\n\n*** on_message_begin() called on paused parser ***\n\n"); abort(); } int dontcall_header_field_cb (http_parser *p, const char *buf, size_t len) { if (p || buf || len) { } // gcc fprintf(stderr, "\n\n*** on_header_field() called on paused parser ***\n\n"); abort(); } int dontcall_header_value_cb (http_parser *p, const char *buf, size_t len) { if (p || buf || len) { } // gcc fprintf(stderr, "\n\n*** on_header_value() called on paused parser ***\n\n"); abort(); } int dontcall_request_url_cb (http_parser *p, const char *buf, size_t len) { if (p || buf || len) { } // gcc fprintf(stderr, "\n\n*** on_request_url() called on paused parser ***\n\n"); abort(); } int dontcall_body_cb (http_parser *p, const char *buf, size_t len) { if (p || buf || len) { } // gcc fprintf(stderr, "\n\n*** on_body_cb() called on paused parser ***\n\n"); abort(); } int dontcall_headers_complete_cb (http_parser *p) { if (p) { } // gcc fprintf(stderr, "\n\n*** on_headers_complete() called on paused " "parser ***\n\n"); abort(); } int dontcall_message_complete_cb (http_parser *p) { if (p) { } // gcc fprintf(stderr, "\n\n*** on_message_complete() called on paused " "parser ***\n\n"); abort(); } int dontcall_response_status_cb (http_parser *p, const char *buf, size_t len) { if (p || buf || len) { } // gcc fprintf(stderr, "\n\n*** on_status() called on paused parser ***\n\n"); abort(); } int dontcall_chunk_header_cb (http_parser *p) { if (p) { } // gcc fprintf(stderr, "\n\n*** on_chunk_header() called on paused parser ***\n\n"); exit(1); } int dontcall_chunk_complete_cb (http_parser *p) { if (p) { } // gcc fprintf(stderr, "\n\n*** on_chunk_complete() " "called on paused parser ***\n\n"); exit(1); } static http_parser_settings settings_dontcall = {.on_message_begin = dontcall_message_begin_cb ,.on_header_field = dontcall_header_field_cb ,.on_header_value = dontcall_header_value_cb ,.on_url = dontcall_request_url_cb ,.on_status = dontcall_response_status_cb ,.on_body = dontcall_body_cb ,.on_headers_complete = dontcall_headers_complete_cb ,.on_message_complete = dontcall_message_complete_cb ,.on_chunk_header = dontcall_chunk_header_cb ,.on_chunk_complete = dontcall_chunk_complete_cb }; /* These pause_* callbacks always pause the parser and just invoke the regular * callback that tracks content. Before returning, we overwrite the parser * settings to point to the _dontcall variety so that we can verify that * the pause actually did, you know, pause. */ int pause_message_begin_cb (http_parser *p) { http_parser_pause(p, 1); *current_pause_parser = settings_dontcall; return message_begin_cb(p); } int pause_header_field_cb (http_parser *p, const char *buf, size_t len) { http_parser_pause(p, 1); *current_pause_parser = settings_dontcall; return header_field_cb(p, buf, len); } int pause_header_value_cb (http_parser *p, const char *buf, size_t len) { http_parser_pause(p, 1); *current_pause_parser = settings_dontcall; return header_value_cb(p, buf, len); } int pause_request_url_cb (http_parser *p, const char *buf, size_t len) { http_parser_pause(p, 1); *current_pause_parser = settings_dontcall; return request_url_cb(p, buf, len); } int pause_body_cb (http_parser *p, const char *buf, size_t len) { http_parser_pause(p, 1); *current_pause_parser = settings_dontcall; return body_cb(p, buf, len); } int pause_headers_complete_cb (http_parser *p) { http_parser_pause(p, 1); *current_pause_parser = settings_dontcall; return headers_complete_cb(p); } int pause_message_complete_cb (http_parser *p) { http_parser_pause(p, 1); *current_pause_parser = settings_dontcall; return message_complete_cb(p); } int pause_response_status_cb (http_parser *p, const char *buf, size_t len) { http_parser_pause(p, 1); *current_pause_parser = settings_dontcall; return response_status_cb(p, buf, len); } int pause_chunk_header_cb (http_parser *p) { http_parser_pause(p, 1); *current_pause_parser = settings_dontcall; return chunk_header_cb(p); } int pause_chunk_complete_cb (http_parser *p) { http_parser_pause(p, 1); *current_pause_parser = settings_dontcall; return chunk_complete_cb(p); } static http_parser_settings settings_pause = {.on_message_begin = pause_message_begin_cb ,.on_header_field = pause_header_field_cb ,.on_header_value = pause_header_value_cb ,.on_url = pause_request_url_cb ,.on_status = pause_response_status_cb ,.on_body = pause_body_cb ,.on_headers_complete = pause_headers_complete_cb ,.on_message_complete = pause_message_complete_cb ,.on_chunk_header = pause_chunk_header_cb ,.on_chunk_complete = pause_chunk_complete_cb }; static http_parser_settings settings = {.on_message_begin = message_begin_cb ,.on_header_field = header_field_cb ,.on_header_value = header_value_cb ,.on_url = request_url_cb ,.on_status = response_status_cb ,.on_body = body_cb ,.on_headers_complete = headers_complete_cb ,.on_message_complete = message_complete_cb ,.on_chunk_header = chunk_header_cb ,.on_chunk_complete = chunk_complete_cb }; static http_parser_settings settings_count_body = {.on_message_begin = message_begin_cb ,.on_header_field = header_field_cb ,.on_header_value = header_value_cb ,.on_url = request_url_cb ,.on_status = response_status_cb ,.on_body = count_body_cb ,.on_headers_complete = headers_complete_cb ,.on_message_complete = message_complete_cb ,.on_chunk_header = chunk_header_cb ,.on_chunk_complete = chunk_complete_cb }; static http_parser_settings settings_null = {.on_message_begin = 0 ,.on_header_field = 0 ,.on_header_value = 0 ,.on_url = 0 ,.on_status = 0 ,.on_body = 0 ,.on_headers_complete = 0 ,.on_message_complete = 0 ,.on_chunk_header = 0 ,.on_chunk_complete = 0 }; void parser_init (enum http_parser_type type) { num_messages = 0; assert(parser == NULL); parser = malloc(sizeof(http_parser)); http_parser_init(parser, type); memset(&messages, 0, sizeof messages); } void parser_free () { assert(parser); free(parser); parser = NULL; } size_t parse (const char *buf, size_t len) { size_t nparsed; currently_parsing_eof = (len == 0); nparsed = http_parser_execute(parser, &settings, buf, len); return nparsed; } size_t parse_count_body (const char *buf, size_t len) { size_t nparsed; currently_parsing_eof = (len == 0); nparsed = http_parser_execute(parser, &settings_count_body, buf, len); return nparsed; } size_t parse_pause (const char *buf, size_t len) { size_t nparsed; http_parser_settings s = settings_pause; currently_parsing_eof = (len == 0); current_pause_parser = &s; nparsed = http_parser_execute(parser, current_pause_parser, buf, len); return nparsed; } static inline int check_str_eq (const struct message *m, const char *prop, const char *expected, const char *found) { if ((expected == NULL) != (found == NULL)) { printf("\n*** Error: %s in '%s' ***\n\n", prop, m->name); printf("expected %s\n", (expected == NULL) ? "NULL" : expected); printf(" found %s\n", (found == NULL) ? "NULL" : found); return 0; } if (expected != NULL && 0 != strcmp(expected, found)) { printf("\n*** Error: %s in '%s' ***\n\n", prop, m->name); printf("expected '%s'\n", expected); printf(" found '%s'\n", found); return 0; } return 1; } static inline int check_num_eq (const struct message *m, const char *prop, int expected, int found) { if (expected != found) { printf("\n*** Error: %s in '%s' ***\n\n", prop, m->name); printf("expected %d\n", expected); printf(" found %d\n", found); return 0; } return 1; } #define MESSAGE_CHECK_STR_EQ(expected, found, prop) \ if (!check_str_eq(expected, #prop, expected->prop, found->prop)) return 0 #define MESSAGE_CHECK_NUM_EQ(expected, found, prop) \ if (!check_num_eq(expected, #prop, expected->prop, found->prop)) return 0 #define MESSAGE_CHECK_URL_EQ(u, expected, found, prop, fn) \ do { \ char ubuf[256]; \ \ if ((u)->field_set & (1 << (fn))) { \ memcpy(ubuf, (found)->request_url + (u)->field_data[(fn)].off, \ (u)->field_data[(fn)].len); \ ubuf[(u)->field_data[(fn)].len] = '\0'; \ } else { \ ubuf[0] = '\0'; \ } \ \ check_str_eq(expected, #prop, expected->prop, ubuf); \ } while(0) int message_eq (int index, const struct message *expected) { int i; struct message *m = &messages[index]; MESSAGE_CHECK_NUM_EQ(expected, m, http_major); MESSAGE_CHECK_NUM_EQ(expected, m, http_minor); if (expected->type == HTTP_REQUEST) { MESSAGE_CHECK_NUM_EQ(expected, m, method); } else { MESSAGE_CHECK_NUM_EQ(expected, m, status_code); MESSAGE_CHECK_STR_EQ(expected, m, response_status); } MESSAGE_CHECK_NUM_EQ(expected, m, should_keep_alive); MESSAGE_CHECK_NUM_EQ(expected, m, message_complete_on_eof); assert(m->message_begin_cb_called); assert(m->headers_complete_cb_called); assert(m->message_complete_cb_called); MESSAGE_CHECK_STR_EQ(expected, m, request_url); /* Check URL components; we can't do this w/ CONNECT since it doesn't * send us a well-formed URL. */ if (*m->request_url && m->method != HTTP_CONNECT) { struct http_parser_url u; if (http_parser_parse_url(m->request_url, strlen(m->request_url), 0, &u)) { fprintf(stderr, "\n\n*** failed to parse URL %s ***\n\n", m->request_url); abort(); } if (expected->host) { MESSAGE_CHECK_URL_EQ(&u, expected, m, host, UF_HOST); } if (expected->userinfo) { MESSAGE_CHECK_URL_EQ(&u, expected, m, userinfo, UF_USERINFO); } m->port = (u.field_set & (1 << UF_PORT)) ? u.port : 0; MESSAGE_CHECK_URL_EQ(&u, expected, m, query_string, UF_QUERY); MESSAGE_CHECK_URL_EQ(&u, expected, m, fragment, UF_FRAGMENT); MESSAGE_CHECK_URL_EQ(&u, expected, m, request_path, UF_PATH); MESSAGE_CHECK_NUM_EQ(expected, m, port); } if (expected->body_size) { MESSAGE_CHECK_NUM_EQ(expected, m, body_size); } else { MESSAGE_CHECK_STR_EQ(expected, m, body); } assert(m->num_chunks == m->num_chunks_complete); MESSAGE_CHECK_NUM_EQ(expected, m, num_chunks_complete); for (i = 0; i < m->num_chunks && i < MAX_CHUNKS; i++) { MESSAGE_CHECK_NUM_EQ(expected, m, chunk_lengths[i]); } MESSAGE_CHECK_NUM_EQ(expected, m, num_headers); int r; for (i = 0; i < m->num_headers; i++) { r = check_str_eq(expected, "header field", expected->headers[i][0], m->headers[i][0]); if (!r) return 0; r = check_str_eq(expected, "header value", expected->headers[i][1], m->headers[i][1]); if (!r) return 0; } MESSAGE_CHECK_STR_EQ(expected, m, upgrade); return 1; } /* Given a sequence of varargs messages, return the number of them that the * parser should successfully parse, taking into account that upgraded * messages prevent all subsequent messages from being parsed. */ size_t count_parsed_messages(const size_t nmsgs, ...) { size_t i; va_list ap; va_start(ap, nmsgs); for (i = 0; i < nmsgs; i++) { struct message *m = va_arg(ap, struct message *); if (m->upgrade) { va_end(ap); return i + 1; } } va_end(ap); return nmsgs; } /* Given a sequence of bytes and the number of these that we were able to * parse, verify that upgrade bodies are correct. */ void upgrade_message_fix(char *body, const size_t nread, const size_t nmsgs, ...) { va_list ap; size_t i; size_t off = 0; va_start(ap, nmsgs); for (i = 0; i < nmsgs; i++) { struct message *m = va_arg(ap, struct message *); off += strlen(m->raw); if (m->upgrade) { off -= strlen(m->upgrade); /* Check the portion of the response after its specified upgrade */ if (!check_str_eq(m, "upgrade", body + off, body + nread)) { abort(); } /* Fix up the response so that message_eq() will verify the beginning * of the upgrade */ *(body + nread + strlen(m->upgrade)) = '\0'; messages[num_messages -1 ].upgrade = body + nread; va_end(ap); return; } } va_end(ap); printf("\n\n*** Error: expected a message with upgrade ***\n"); abort(); } static void print_error (const char *raw, size_t error_location) { fprintf(stderr, "\n*** %s ***\n\n", http_errno_description(HTTP_PARSER_ERRNO(parser))); int this_line = 0, char_len = 0; size_t i, j, len = strlen(raw), error_location_line = 0; for (i = 0; i < len; i++) { if (i == error_location) this_line = 1; switch (raw[i]) { case '\r': char_len = 2; fprintf(stderr, "\\r"); break; case '\n': fprintf(stderr, "\\n\n"); if (this_line) goto print; error_location_line = 0; continue; default: char_len = 1; fputc(raw[i], stderr); break; } if (!this_line) error_location_line += char_len; } fprintf(stderr, "[eof]\n"); print: for (j = 0; j < error_location_line; j++) { fputc(' ', stderr); } fprintf(stderr, "^\n\nerror location: %u\n", (unsigned int)error_location); } void test_preserve_data (void) { char my_data[] = "application-specific data"; http_parser parser; parser.data = my_data; http_parser_init(&parser, HTTP_REQUEST); if (parser.data != my_data) { printf("\n*** parser.data not preserved accross http_parser_init ***\n\n"); abort(); } } struct url_test { const char *name; const char *url; int is_connect; struct http_parser_url u; int rv; }; const struct url_test url_tests[] = { {.name="proxy request" ,.url="http://hostname/" ,.is_connect=0 ,.u= {.field_set=(1 << UF_SCHEMA) | (1 << UF_HOST) | (1 << UF_PATH) ,.port=0 ,.field_data= {{ 0, 4 } /* UF_SCHEMA */ ,{ 7, 8 } /* UF_HOST */ ,{ 0, 0 } /* UF_PORT */ ,{ 15, 1 } /* UF_PATH */ ,{ 0, 0 } /* UF_QUERY */ ,{ 0, 0 } /* UF_FRAGMENT */ ,{ 0, 0 } /* UF_USERINFO */ } } ,.rv=0 } , {.name="proxy request with port" ,.url="http://hostname:444/" ,.is_connect=0 ,.u= {.field_set=(1 << UF_SCHEMA) | (1 << UF_HOST) | (1 << UF_PORT) | (1 << UF_PATH) ,.port=444 ,.field_data= {{ 0, 4 } /* UF_SCHEMA */ ,{ 7, 8 } /* UF_HOST */ ,{ 16, 3 } /* UF_PORT */ ,{ 19, 1 } /* UF_PATH */ ,{ 0, 0 } /* UF_QUERY */ ,{ 0, 0 } /* UF_FRAGMENT */ ,{ 0, 0 } /* UF_USERINFO */ } } ,.rv=0 } , {.name="CONNECT request" ,.url="hostname:443" ,.is_connect=1 ,.u= {.field_set=(1 << UF_HOST) | (1 << UF_PORT) ,.port=443 ,.field_data= {{ 0, 0 } /* UF_SCHEMA */ ,{ 0, 8 } /* UF_HOST */ ,{ 9, 3 } /* UF_PORT */ ,{ 0, 0 } /* UF_PATH */ ,{ 0, 0 } /* UF_QUERY */ ,{ 0, 0 } /* UF_FRAGMENT */ ,{ 0, 0 } /* UF_USERINFO */ } } ,.rv=0 } , {.name="CONNECT request but not connect" ,.url="hostname:443" ,.is_connect=0 ,.rv=1 } , {.name="proxy ipv6 request" ,.url="http://[1:2::3:4]/" ,.is_connect=0 ,.u= {.field_set=(1 << UF_SCHEMA) | (1 << UF_HOST) | (1 << UF_PATH) ,.port=0 ,.field_data= {{ 0, 4 } /* UF_SCHEMA */ ,{ 8, 8 } /* UF_HOST */ ,{ 0, 0 } /* UF_PORT */ ,{ 17, 1 } /* UF_PATH */ ,{ 0, 0 } /* UF_QUERY */ ,{ 0, 0 } /* UF_FRAGMENT */ ,{ 0, 0 } /* UF_USERINFO */ } } ,.rv=0 } , {.name="proxy ipv6 request with port" ,.url="http://[1:2::3:4]:67/" ,.is_connect=0 ,.u= {.field_set=(1 << UF_SCHEMA) | (1 << UF_HOST) | (1 << UF_PORT) | (1 << UF_PATH) ,.port=67 ,.field_data= {{ 0, 4 } /* UF_SCHEMA */ ,{ 8, 8 } /* UF_HOST */ ,{ 18, 2 } /* UF_PORT */ ,{ 20, 1 } /* UF_PATH */ ,{ 0, 0 } /* UF_QUERY */ ,{ 0, 0 } /* UF_FRAGMENT */ ,{ 0, 0 } /* UF_USERINFO */ } } ,.rv=0 } , {.name="CONNECT ipv6 address" ,.url="[1:2::3:4]:443" ,.is_connect=1 ,.u= {.field_set=(1 << UF_HOST) | (1 << UF_PORT) ,.port=443 ,.field_data= {{ 0, 0 } /* UF_SCHEMA */ ,{ 1, 8 } /* UF_HOST */ ,{ 11, 3 } /* UF_PORT */ ,{ 0, 0 } /* UF_PATH */ ,{ 0, 0 } /* UF_QUERY */ ,{ 0, 0 } /* UF_FRAGMENT */ ,{ 0, 0 } /* UF_USERINFO */ } } ,.rv=0 } , {.name="ipv4 in ipv6 address" ,.url="http://[2001:0000:0000:0000:0000:0000:1.9.1.1]/" ,.is_connect=0 ,.u= {.field_set=(1 << UF_SCHEMA) | (1 << UF_HOST) | (1 << UF_PATH) ,.port=0 ,.field_data= {{ 0, 4 } /* UF_SCHEMA */ ,{ 8, 37 } /* UF_HOST */ ,{ 0, 0 } /* UF_PORT */ ,{ 46, 1 } /* UF_PATH */ ,{ 0, 0 } /* UF_QUERY */ ,{ 0, 0 } /* UF_FRAGMENT */ ,{ 0, 0 } /* UF_USERINFO */ } } ,.rv=0 } , {.name="extra ? in query string" ,.url="http://a.tbcdn.cn/p/fp/2010c/??fp-header-min.css,fp-base-min.css," "fp-channel-min.css,fp-product-min.css,fp-mall-min.css,fp-category-min.css," "fp-sub-min.css,fp-gdp4p-min.css,fp-css3-min.css,fp-misc-min.css?t=20101022.css" ,.is_connect=0 ,.u= {.field_set=(1<field_set, u->port); for (i = 0; i < UF_MAX; i++) { if ((u->field_set & (1 << i)) == 0) { printf("\tfield_data[%u]: unset\n", i); continue; } printf("\tfield_data[%u]: off: %u len: %u part: \"%.*s\n\"", i, u->field_data[i].off, u->field_data[i].len, u->field_data[i].len, url + u->field_data[i].off); } } void test_parse_url (void) { struct http_parser_url u; const struct url_test *test; unsigned int i; int rv; for (i = 0; i < (sizeof(url_tests) / sizeof(url_tests[0])); i++) { test = &url_tests[i]; memset(&u, 0, sizeof(u)); rv = http_parser_parse_url(test->url, strlen(test->url), test->is_connect, &u); if (test->rv == 0) { if (rv != 0) { printf("\n*** http_parser_parse_url(\"%s\") \"%s\" test failed, " "unexpected rv %d ***\n\n", test->url, test->name, rv); abort(); } if (memcmp(&u, &test->u, sizeof(u)) != 0) { printf("\n*** http_parser_parse_url(\"%s\") \"%s\" failed ***\n", test->url, test->name); printf("target http_parser_url:\n"); dump_url(test->url, &test->u); printf("result http_parser_url:\n"); dump_url(test->url, &u); abort(); } } else { /* test->rv != 0 */ if (rv == 0) { printf("\n*** http_parser_parse_url(\"%s\") \"%s\" test failed, " "unexpected rv %d ***\n\n", test->url, test->name, rv); abort(); } } } } void test_method_str (void) { assert(0 == strcmp("GET", http_method_str(HTTP_GET))); assert(0 == strcmp("", http_method_str(1337))); } void test_message (const struct message *message) { size_t raw_len = strlen(message->raw); size_t msg1len; for (msg1len = 0; msg1len < raw_len; msg1len++) { parser_init(message->type); size_t read; const char *msg1 = message->raw; const char *msg2 = msg1 + msg1len; size_t msg2len = raw_len - msg1len; if (msg1len) { read = parse(msg1, msg1len); if (message->upgrade && parser->upgrade && num_messages > 0) { messages[num_messages - 1].upgrade = msg1 + read; goto test; } if (read != msg1len) { print_error(msg1, read); abort(); } } read = parse(msg2, msg2len); if (message->upgrade && parser->upgrade) { messages[num_messages - 1].upgrade = msg2 + read; goto test; } if (read != msg2len) { print_error(msg2, read); abort(); } read = parse(NULL, 0); if (read != 0) { print_error(message->raw, read); abort(); } test: if (num_messages != 1) { printf("\n*** num_messages != 1 after testing '%s' ***\n\n", message->name); abort(); } if(!message_eq(0, message)) abort(); parser_free(); } } void test_message_count_body (const struct message *message) { parser_init(message->type); size_t read; size_t l = strlen(message->raw); size_t i, toread; size_t chunk = 4024; for (i = 0; i < l; i+= chunk) { toread = MIN(l-i, chunk); read = parse_count_body(message->raw + i, toread); if (read != toread) { print_error(message->raw, read); abort(); } } read = parse_count_body(NULL, 0); if (read != 0) { print_error(message->raw, read); abort(); } if (num_messages != 1) { printf("\n*** num_messages != 1 after testing '%s' ***\n\n", message->name); abort(); } if(!message_eq(0, message)) abort(); parser_free(); } void test_simple (const char *buf, enum http_errno err_expected) { parser_init(HTTP_REQUEST); enum http_errno err; parse(buf, strlen(buf)); err = HTTP_PARSER_ERRNO(parser); parse(NULL, 0); parser_free(); /* In strict mode, allow us to pass with an unexpected HPE_STRICT as * long as the caller isn't expecting success. */ #if HTTP_PARSER_STRICT if (err_expected != err && err_expected != HPE_OK && err != HPE_STRICT) { #else if (err_expected != err) { #endif fprintf(stderr, "\n*** test_simple expected %s, but saw %s ***\n\n%s\n", http_errno_name(err_expected), http_errno_name(err), buf); abort(); } } void test_header_overflow_error (int req) { http_parser parser; http_parser_init(&parser, req ? HTTP_REQUEST : HTTP_RESPONSE); size_t parsed; const char *buf; buf = req ? "GET / HTTP/1.1\r\n" : "HTTP/1.0 200 OK\r\n"; parsed = http_parser_execute(&parser, &settings_null, buf, strlen(buf)); assert(parsed == strlen(buf)); buf = "header-key: header-value\r\n"; size_t buflen = strlen(buf); int i; for (i = 0; i < 10000; i++) { parsed = http_parser_execute(&parser, &settings_null, buf, buflen); if (parsed != buflen) { //fprintf(stderr, "error found on iter %d\n", i); assert(HTTP_PARSER_ERRNO(&parser) == HPE_HEADER_OVERFLOW); return; } } fprintf(stderr, "\n*** Error expected but none in header overflow test ***\n"); abort(); } void test_header_nread_value () { http_parser parser; http_parser_init(&parser, HTTP_REQUEST); size_t parsed; const char *buf; buf = "GET / HTTP/1.1\r\nheader: value\nhdr: value\r\n"; parsed = http_parser_execute(&parser, &settings_null, buf, strlen(buf)); assert(parsed == strlen(buf)); assert(parser.nread == strlen(buf)); } static void test_content_length_overflow (const char *buf, size_t buflen, int expect_ok) { http_parser parser; http_parser_init(&parser, HTTP_RESPONSE); http_parser_execute(&parser, &settings_null, buf, buflen); if (expect_ok) assert(HTTP_PARSER_ERRNO(&parser) == HPE_OK); else assert(HTTP_PARSER_ERRNO(&parser) == HPE_INVALID_CONTENT_LENGTH); } void test_header_content_length_overflow_error (void) { #define X(size) \ "HTTP/1.1 200 OK\r\n" \ "Content-Length: " #size "\r\n" \ "\r\n" const char a[] = X(1844674407370955160); /* 2^64 / 10 - 1 */ const char b[] = X(18446744073709551615); /* 2^64-1 */ const char c[] = X(18446744073709551616); /* 2^64 */ #undef X test_content_length_overflow(a, sizeof(a) - 1, 1); /* expect ok */ test_content_length_overflow(b, sizeof(b) - 1, 0); /* expect failure */ test_content_length_overflow(c, sizeof(c) - 1, 0); /* expect failure */ } void test_chunk_content_length_overflow_error (void) { #define X(size) \ "HTTP/1.1 200 OK\r\n" \ "Transfer-Encoding: chunked\r\n" \ "\r\n" \ #size "\r\n" \ "..." const char a[] = X(FFFFFFFFFFFFFFE); /* 2^64 / 16 - 1 */ const char b[] = X(FFFFFFFFFFFFFFFF); /* 2^64-1 */ const char c[] = X(10000000000000000); /* 2^64 */ #undef X test_content_length_overflow(a, sizeof(a) - 1, 1); /* expect ok */ test_content_length_overflow(b, sizeof(b) - 1, 0); /* expect failure */ test_content_length_overflow(c, sizeof(c) - 1, 0); /* expect failure */ } void test_no_overflow_long_body (int req, size_t length) { http_parser parser; http_parser_init(&parser, req ? HTTP_REQUEST : HTTP_RESPONSE); size_t parsed; size_t i; char buf1[3000]; size_t buf1len = sprintf(buf1, "%s\r\nConnection: Keep-Alive\r\nContent-Length: %lu\r\n\r\n", req ? "POST / HTTP/1.0" : "HTTP/1.0 200 OK", (unsigned long)length); parsed = http_parser_execute(&parser, &settings_null, buf1, buf1len); if (parsed != buf1len) goto err; for (i = 0; i < length; i++) { char foo = 'a'; parsed = http_parser_execute(&parser, &settings_null, &foo, 1); if (parsed != 1) goto err; } parsed = http_parser_execute(&parser, &settings_null, buf1, buf1len); if (parsed != buf1len) goto err; return; err: fprintf(stderr, "\n*** error in test_no_overflow_long_body %s of length %lu ***\n", req ? "REQUEST" : "RESPONSE", (unsigned long)length); abort(); } void test_multiple3 (const struct message *r1, const struct message *r2, const struct message *r3) { int message_count = count_parsed_messages(3, r1, r2, r3); char total[ strlen(r1->raw) + strlen(r2->raw) + strlen(r3->raw) + 1 ]; total[0] = '\0'; strcat(total, r1->raw); strcat(total, r2->raw); strcat(total, r3->raw); parser_init(r1->type); size_t read; read = parse(total, strlen(total)); if (parser->upgrade) { upgrade_message_fix(total, read, 3, r1, r2, r3); goto test; } if (read != strlen(total)) { print_error(total, read); abort(); } read = parse(NULL, 0); if (read != 0) { print_error(total, read); abort(); } test: if (message_count != num_messages) { fprintf(stderr, "\n\n*** Parser didn't see 3 messages only %d *** \n", num_messages); abort(); } if (!message_eq(0, r1)) abort(); if (message_count > 1 && !message_eq(1, r2)) abort(); if (message_count > 2 && !message_eq(2, r3)) abort(); parser_free(); } /* SCAN through every possible breaking to make sure the * parser can handle getting the content in any chunks that * might come from the socket */ void test_scan (const struct message *r1, const struct message *r2, const struct message *r3) { char total[80*1024] = "\0"; char buf1[80*1024] = "\0"; char buf2[80*1024] = "\0"; char buf3[80*1024] = "\0"; strcat(total, r1->raw); strcat(total, r2->raw); strcat(total, r3->raw); size_t read; int total_len = strlen(total); int total_ops = 2 * (total_len - 1) * (total_len - 2) / 2; int ops = 0 ; size_t buf1_len, buf2_len, buf3_len; int message_count = count_parsed_messages(3, r1, r2, r3); int i,j,type_both; for (type_both = 0; type_both < 2; type_both ++ ) { for (j = 2; j < total_len; j ++ ) { for (i = 1; i < j; i ++ ) { if (ops % 1000 == 0) { printf("\b\b\b\b%3.0f%%", 100 * (float)ops /(float)total_ops); fflush(stdout); } ops += 1; parser_init(type_both ? HTTP_BOTH : r1->type); buf1_len = i; strlncpy(buf1, sizeof(buf1), total, buf1_len); buf1[buf1_len] = 0; buf2_len = j - i; strlncpy(buf2, sizeof(buf1), total+i, buf2_len); buf2[buf2_len] = 0; buf3_len = total_len - j; strlncpy(buf3, sizeof(buf1), total+j, buf3_len); buf3[buf3_len] = 0; read = parse(buf1, buf1_len); if (parser->upgrade) goto test; if (read != buf1_len) { print_error(buf1, read); goto error; } read += parse(buf2, buf2_len); if (parser->upgrade) goto test; if (read != buf1_len + buf2_len) { print_error(buf2, read); goto error; } read += parse(buf3, buf3_len); if (parser->upgrade) goto test; if (read != buf1_len + buf2_len + buf3_len) { print_error(buf3, read); goto error; } parse(NULL, 0); test: if (parser->upgrade) { upgrade_message_fix(total, read, 3, r1, r2, r3); } if (message_count != num_messages) { fprintf(stderr, "\n\nParser didn't see %d messages only %d\n", message_count, num_messages); goto error; } if (!message_eq(0, r1)) { fprintf(stderr, "\n\nError matching messages[0] in test_scan.\n"); goto error; } if (message_count > 1 && !message_eq(1, r2)) { fprintf(stderr, "\n\nError matching messages[1] in test_scan.\n"); goto error; } if (message_count > 2 && !message_eq(2, r3)) { fprintf(stderr, "\n\nError matching messages[2] in test_scan.\n"); goto error; } parser_free(); } } } puts("\b\b\b\b100%"); return; error: fprintf(stderr, "i=%d j=%d\n", i, j); fprintf(stderr, "buf1 (%u) %s\n\n", (unsigned int)buf1_len, buf1); fprintf(stderr, "buf2 (%u) %s\n\n", (unsigned int)buf2_len , buf2); fprintf(stderr, "buf3 (%u) %s\n", (unsigned int)buf3_len, buf3); abort(); } // user required to free the result // string terminated by \0 char * create_large_chunked_message (int body_size_in_kb, const char* headers) { int i; size_t wrote = 0; size_t headers_len = strlen(headers); size_t bufsize = headers_len + (5+1024+2)*body_size_in_kb + 6; char * buf = malloc(bufsize); memcpy(buf, headers, headers_len); wrote += headers_len; for (i = 0; i < body_size_in_kb; i++) { // write 1kb chunk into the body. memcpy(buf + wrote, "400\r\n", 5); wrote += 5; memset(buf + wrote, 'C', 1024); wrote += 1024; strcpy(buf + wrote, "\r\n"); wrote += 2; } memcpy(buf + wrote, "0\r\n\r\n", 6); wrote += 6; assert(wrote == bufsize); return buf; } /* Verify that we can pause parsing at any of the bytes in the * message and still get the result that we're expecting. */ void test_message_pause (const struct message *msg) { char *buf = (char*) msg->raw; size_t buflen = strlen(msg->raw); size_t nread; parser_init(msg->type); do { nread = parse_pause(buf, buflen); // We can only set the upgrade buffer once we've gotten our message // completion callback. if (messages[0].message_complete_cb_called && msg->upgrade && parser->upgrade) { messages[0].upgrade = buf + nread; goto test; } if (nread < buflen) { // Not much do to if we failed a strict-mode check if (HTTP_PARSER_ERRNO(parser) == HPE_STRICT) { parser_free(); return; } assert (HTTP_PARSER_ERRNO(parser) == HPE_PAUSED); } buf += nread; buflen -= nread; http_parser_pause(parser, 0); } while (buflen > 0); nread = parse_pause(NULL, 0); assert (nread == 0); test: if (num_messages != 1) { printf("\n*** num_messages != 1 after testing '%s' ***\n\n", msg->name); abort(); } if(!message_eq(0, msg)) abort(); parser_free(); } int main (void) { parser = NULL; int i, j, k; int request_count; int response_count; unsigned long version; unsigned major; unsigned minor; unsigned patch; version = http_parser_version(); major = (version >> 16) & 255; minor = (version >> 8) & 255; patch = version & 255; printf("http_parser v%u.%u.%u (0x%06lx)\n", major, minor, patch, version); printf("sizeof(http_parser) = %u\n", (unsigned int)sizeof(http_parser)); for (request_count = 0; requests[request_count].name; request_count++); for (response_count = 0; responses[response_count].name; response_count++); //// API test_preserve_data(); test_parse_url(); test_method_str(); //// NREAD test_header_nread_value(); //// OVERFLOW CONDITIONS test_header_overflow_error(HTTP_REQUEST); test_no_overflow_long_body(HTTP_REQUEST, 1000); test_no_overflow_long_body(HTTP_REQUEST, 100000); test_header_overflow_error(HTTP_RESPONSE); test_no_overflow_long_body(HTTP_RESPONSE, 1000); test_no_overflow_long_body(HTTP_RESPONSE, 100000); test_header_content_length_overflow_error(); test_chunk_content_length_overflow_error(); //// RESPONSES for (i = 0; i < response_count; i++) { test_message(&responses[i]); } for (i = 0; i < response_count; i++) { test_message_pause(&responses[i]); } for (i = 0; i < response_count; i++) { if (!responses[i].should_keep_alive) continue; for (j = 0; j < response_count; j++) { if (!responses[j].should_keep_alive) continue; for (k = 0; k < response_count; k++) { test_multiple3(&responses[i], &responses[j], &responses[k]); } } } test_message_count_body(&responses[NO_HEADERS_NO_BODY_404]); test_message_count_body(&responses[TRAILING_SPACE_ON_CHUNKED_BODY]); // test very large chunked response { char * msg = create_large_chunked_message(31337, "HTTP/1.0 200 OK\r\n" "Transfer-Encoding: chunked\r\n" "Content-Type: text/plain\r\n" "\r\n"); struct message large_chunked = {.name= "large chunked" ,.type= HTTP_RESPONSE ,.raw= msg ,.should_keep_alive= FALSE ,.message_complete_on_eof= FALSE ,.http_major= 1 ,.http_minor= 0 ,.status_code= 200 ,.response_status= "OK" ,.num_headers= 2 ,.headers= { { "Transfer-Encoding", "chunked" } , { "Content-Type", "text/plain" } } ,.body_size= 31337*1024 ,.num_chunks_complete= 31338 }; for (i = 0; i < MAX_CHUNKS; i++) { large_chunked.chunk_lengths[i] = 1024; } test_message_count_body(&large_chunked); free(msg); } printf("response scan 1/2 "); test_scan( &responses[TRAILING_SPACE_ON_CHUNKED_BODY] , &responses[NO_BODY_HTTP10_KA_204] , &responses[NO_REASON_PHRASE] ); printf("response scan 2/2 "); test_scan( &responses[BONJOUR_MADAME_FR] , &responses[UNDERSTORE_HEADER_KEY] , &responses[NO_CARRIAGE_RET] ); puts("responses okay"); /// REQUESTS test_simple("GET / HTP/1.1\r\n\r\n", HPE_INVALID_VERSION); // Well-formed but incomplete test_simple("GET / HTTP/1.1\r\n" "Content-Type: text/plain\r\n" "Content-Length: 6\r\n" "\r\n" "fooba", HPE_OK); static const char *all_methods[] = { "DELETE", "GET", "HEAD", "POST", "PUT", //"CONNECT", //CONNECT can't be tested like other methods, it's a tunnel "OPTIONS", "TRACE", "COPY", "LOCK", "MKCOL", "MOVE", "PROPFIND", "PROPPATCH", "UNLOCK", "REPORT", "MKACTIVITY", "CHECKOUT", "MERGE", "M-SEARCH", "NOTIFY", "SUBSCRIBE", "UNSUBSCRIBE", "PATCH", 0 }; const char **this_method; for (this_method = all_methods; *this_method; this_method++) { char buf[200]; sprintf(buf, "%s / HTTP/1.1\r\n\r\n", *this_method); test_simple(buf, HPE_OK); } static const char *bad_methods[] = { "ASDF", "C******", "COLA", "GEM", "GETA", "M****", "MKCOLA", "PROPPATCHA", "PUN", "PX", "SA", "hello world", 0 }; for (this_method = bad_methods; *this_method; this_method++) { char buf[200]; sprintf(buf, "%s / HTTP/1.1\r\n\r\n", *this_method); test_simple(buf, HPE_INVALID_METHOD); } // illegal header field name line folding test_simple("GET / HTTP/1.1\r\n" "name\r\n" " : value\r\n" "\r\n", HPE_INVALID_HEADER_TOKEN); const char *dumbfuck2 = "GET / HTTP/1.1\r\n" "X-SSL-Bullshit: -----BEGIN CERTIFICATE-----\r\n" "\tMIIFbTCCBFWgAwIBAgICH4cwDQYJKoZIhvcNAQEFBQAwcDELMAkGA1UEBhMCVUsx\r\n" "\tETAPBgNVBAoTCGVTY2llbmNlMRIwEAYDVQQLEwlBdXRob3JpdHkxCzAJBgNVBAMT\r\n" "\tAkNBMS0wKwYJKoZIhvcNAQkBFh5jYS1vcGVyYXRvckBncmlkLXN1cHBvcnQuYWMu\r\n" "\tdWswHhcNMDYwNzI3MTQxMzI4WhcNMDcwNzI3MTQxMzI4WjBbMQswCQYDVQQGEwJV\r\n" "\tSzERMA8GA1UEChMIZVNjaWVuY2UxEzARBgNVBAsTCk1hbmNoZXN0ZXIxCzAJBgNV\r\n" "\tBAcTmrsogriqMWLAk1DMRcwFQYDVQQDEw5taWNoYWVsIHBhcmQYJKoZIhvcNAQEB\r\n" "\tBQADggEPADCCAQoCggEBANPEQBgl1IaKdSS1TbhF3hEXSl72G9J+WC/1R64fAcEF\r\n" "\tW51rEyFYiIeZGx/BVzwXbeBoNUK41OK65sxGuflMo5gLflbwJtHBRIEKAfVVp3YR\r\n" "\tgW7cMA/s/XKgL1GEC7rQw8lIZT8RApukCGqOVHSi/F1SiFlPDxuDfmdiNzL31+sL\r\n" "\t0iwHDdNkGjy5pyBSB8Y79dsSJtCW/iaLB0/n8Sj7HgvvZJ7x0fr+RQjYOUUfrePP\r\n" "\tu2MSpFyf+9BbC/aXgaZuiCvSR+8Snv3xApQY+fULK/xY8h8Ua51iXoQ5jrgu2SqR\r\n" "\twgA7BUi3G8LFzMBl8FRCDYGUDy7M6QaHXx1ZWIPWNKsCAwEAAaOCAiQwggIgMAwG\r\n" "\tA1UdEwEB/wQCMAAwEQYJYIZIAYb4QgHTTPAQDAgWgMA4GA1UdDwEB/wQEAwID6DAs\r\n" "\tBglghkgBhvhCAQ0EHxYdVUsgZS1TY2llbmNlIFVzZXIgQ2VydGlmaWNhdGUwHQYD\r\n" "\tVR0OBBYEFDTt/sf9PeMaZDHkUIldrDYMNTBZMIGaBgNVHSMEgZIwgY+AFAI4qxGj\r\n" "\tloCLDdMVKwiljjDastqooXSkcjBwMQswCQYDVQQGEwJVSzERMA8GA1UEChMIZVNj\r\n" "\taWVuY2UxEjAQBgNVBAsTCUF1dGhvcml0eTELMAkGA1UEAxMCQ0ExLTArBgkqhkiG\r\n" "\t9w0BCQEWHmNhLW9wZXJhdG9yQGdyaWQtc3VwcG9ydC5hYy51a4IBADApBgNVHRIE\r\n" "\tIjAggR5jYS1vcGVyYXRvckBncmlkLXN1cHBvcnQuYWMudWswGQYDVR0gBBIwEDAO\r\n" "\tBgwrBgEEAdkvAQEBAQYwPQYJYIZIAYb4QgEEBDAWLmh0dHA6Ly9jYS5ncmlkLXN1\r\n" "\tcHBvcnQuYWMudmT4sopwqlBWsvcHViL2NybC9jYWNybC5jcmwwPQYJYIZIAYb4QgEDBDAWLmh0\r\n" "\tdHA6Ly9jYS5ncmlkLXN1cHBvcnQuYWMudWsvcHViL2NybC9jYWNybC5jcmwwPwYD\r\n" "\tVR0fBDgwNjA0oDKgMIYuaHR0cDovL2NhLmdyaWQt5hYy51ay9wdWIv\r\n" "\tY3JsL2NhY3JsLmNybDANBgkqhkiG9w0BAQUFAAOCAQEAS/U4iiooBENGW/Hwmmd3\r\n" "\tXCy6Zrt08YjKCzGNjorT98g8uGsqYjSxv/hmi0qlnlHs+k/3Iobc3LjS5AMYr5L8\r\n" "\tUO7OSkgFFlLHQyC9JzPfmLCAugvzEbyv4Olnsr8hbxF1MbKZoQxUZtMVu29wjfXk\r\n" "\thTeApBv7eaKCWpSp7MCbvgzm74izKhu3vlDk9w6qVrxePfGgpKPqfHiOoGhFnbTK\r\n" "\twTC6o2xq5y0qZ03JonF7OJspEd3I5zKY3E+ov7/ZhW6DqT8UFvsAdjvQbXyhV8Eu\r\n" "\tYhixw1aKEPzNjNowuIseVogKOLXxWI5vAi5HgXdS0/ES5gDGsABo4fqovUKlgop3\r\n" "\tRA==\r\n" "\t-----END CERTIFICATE-----\r\n" "\r\n"; test_simple(dumbfuck2, HPE_OK); const char *corrupted_connection = "GET / HTTP/1.1\r\n" "Host: www.example.com\r\n" "Connection\r\033\065\325eep-Alive\r\n" "Accept-Encoding: gzip\r\n" "\r\n"; test_simple(corrupted_connection, HPE_INVALID_HEADER_TOKEN); const char *corrupted_header_name = "GET / HTTP/1.1\r\n" "Host: www.example.com\r\n" "X-Some-Header\r\033\065\325eep-Alive\r\n" "Accept-Encoding: gzip\r\n" "\r\n"; test_simple(corrupted_header_name, HPE_INVALID_HEADER_TOKEN); #if 0 // NOTE(Wed Nov 18 11:57:27 CET 2009) this seems okay. we just read body // until EOF. // // no content-length // error if there is a body without content length const char *bad_get_no_headers_no_body = "GET /bad_get_no_headers_no_body/world HTTP/1.1\r\n" "Accept: */*\r\n" "\r\n" "HELLO"; test_simple(bad_get_no_headers_no_body, 0); #endif /* TODO sending junk and large headers gets rejected */ /* check to make sure our predefined requests are okay */ for (i = 0; requests[i].name; i++) { test_message(&requests[i]); } for (i = 0; i < request_count; i++) { test_message_pause(&requests[i]); } for (i = 0; i < request_count; i++) { if (!requests[i].should_keep_alive) continue; for (j = 0; j < request_count; j++) { if (!requests[j].should_keep_alive) continue; for (k = 0; k < request_count; k++) { test_multiple3(&requests[i], &requests[j], &requests[k]); } } } printf("request scan 1/4 "); test_scan( &requests[GET_NO_HEADERS_NO_BODY] , &requests[GET_ONE_HEADER_NO_BODY] , &requests[GET_NO_HEADERS_NO_BODY] ); printf("request scan 2/4 "); test_scan( &requests[POST_CHUNKED_ALL_YOUR_BASE] , &requests[POST_IDENTITY_BODY_WORLD] , &requests[GET_FUNKY_CONTENT_LENGTH] ); printf("request scan 3/4 "); test_scan( &requests[TWO_CHUNKS_MULT_ZERO_END] , &requests[CHUNKED_W_TRAILING_HEADERS] , &requests[CHUNKED_W_BULLSHIT_AFTER_LENGTH] ); printf("request scan 4/4 "); test_scan( &requests[QUERY_URL_WITH_QUESTION_MARK_GET] , &requests[PREFIX_NEWLINE_GET ] , &requests[CONNECT_REQUEST] ); puts("requests okay"); return 0; } pax_global_header00006660000000000000000000000064131210211740014502gustar00rootroot0000000000000052 comment=7cc9d65c095c6631bb547d863dfeadc470d8dfc6 iotjs-1.0/deps/jerry/000077500000000000000000000000001312102117400145605ustar00rootroot00000000000000iotjs-1.0/deps/jerry/.gitignore000066400000000000000000000007701312102117400165540ustar00rootroot00000000000000# Produced files .mbedignore build/* # IDE related files nbproject *.sublime-project *.sublime-workspace .idea # Random Trash *.swp *.swo *~ core vgcore.* *.orig *.directory *.patch .tags* cscope.* __pycache__ *.pyc .DS_Store # ctags and ID database tags ID # targets jerry-targetjs.h targets/mbed/libjerry targets/mbed/build targets/mbed/yotta_modules targets/mbed/yotta_targets .output targets/esp8266/output.map targets/esp8266/libs # Generated documentation docs/doxygen # Tests tests/test262/ iotjs-1.0/deps/jerry/.travis.yml000066400000000000000000000117711312102117400167000ustar00rootroot00000000000000language: c os: linux dist: trusty sudo: required env: matrix: - OPTS="--check-signed-off-travis --check-cppcheck --check-doxygen --check-vera --check-license --check-magic-strings" - OPTS="--jerry-debugger" - OPTS="--jerry-tests --jerry-test-suite" - OPTS="--jerry-tests --jerry-test-suite --toolchain=cmake/toolchain_linux_armv7l.cmake" TIMEOUT=300 INSTALL_QEMU_ARM=yes - OPTS="--buildoption-test" - OPTS="--jerry-tests --jerry-test-suite --buildoptions=--jerry-libc=off,--compile-flag=-m32,--cpointer-32bit=on" - OPTS="--unittests" - OPTS="--test262" - OPTS="--check-pylint" global: # The next declaration is the encrypted COVERITY_SCAN_TOKEN, created # via the "travis encrypt" command using the project repo's public key - secure: "V7BdXv3FCVkFGEfKfWto6I+Sytou1zTCGyn49xurkBfKNsG/3vbkXfsbK1m6lCZxmY7W/1odpfjixpAPZgy2L4FgPZK6/UyVvC8pIFjDOubcEniN48haleSvm/ZFPLDifxDL2+VVFtK1oRYPtDBzzSoUCcfwovgk+Wy+tSBnhnyRLqO/WaI6PqFof7ECYMTRlJVjioZARVP4YmkBruIPmGDdR/3EvwowlxfuiFoPheix61ug4x3tpTBW2qWgvFjDyCZXFz4pJrBQPTAIbyKMxHcBykJjl9eR+dWAOsvE1Uw48tFOJxjKDfUttVQUPsyKFllmcCVS0fDYB5pzZOmRUPxJmox1jt8J1FY85Ri1PGY0THBPM2H7to4Yf2418Y3539epbN8p+79dwaM7e2OiJ2owukbWI7PoNqIz5DV5zxpIKsOQfeWuNLJOgsBePEIU7lz133Si/2d5W/7If46B1d+hZRBJfSYksgDqDU6G/voZkPf0K5bKe2O2BxiIW1DYk4yQ1ecZAkqGjZ8jG3zYGMG3mSF4VyuU4UGFG1Pg8fw7Ap5zuHxSVY1H9dtu4T6JQG3aj/x1omlzfw48DjgkwxVhf7Xvl3yfR7pzydYheLX3MZYtcVo7rWnglZFZoUjWDK1StbmzsvPftvwWtoDTWlzo4xeSXhahSJvJyc4U8Wc=" matrix: include: - os: osx env: OPTS="--jerry-tests --jerry-test-suite --unittests" - os: linux before_install: - tools/apt-get-install-deps.sh - echo -n | openssl s_client -connect scan.coverity.com:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' | sudo tee -a /etc/ssl/certs/ca- addons: coverity_scan: project: name: "jerryscript-project/jerryscript" description: "Ultra-lightweight JavaScript engine for the Internet of Things." notification_email: rsipka.uszeged@partner.samsung.com build_command: "tools/build.py --clean" branch_pattern: master env: OPTS="" - compiler: gcc-5 addons: apt: sources: - ubuntu-toolchain-r-test packages: - gcc-5 - gcc-5-multilib env: OPTS="--jerry-tests --jerry-test-suite --skip-list=parser-oom.js --buildoptions=--compile-flag=-fsanitize=address,--compile-flag=-m32,--compile-flag=-fno-omit-frame-pointer,--compile-flag=-fno-common,--compile-flag=-O2,--debug,--jerry-libc=off,--static-link=off,--system-allocator=on,--linker-flag=-fuse-ld=gold" ASAN_OPTIONS=detect_stack_use_after_return=1:check_initialization_order=true:strict_init_order=true TIMEOUT=600 - compiler: gcc-5 addons: apt: sources: - ubuntu-toolchain-r-test packages: - gcc-5 - gcc-5-multilib env: OPTS="--jerry-tests --jerry-test-suite --skip-list=parser-oom.js --buildoptions=--compile-flag=-fsanitize=undefined,--compile-flag=-m32,--compile-flag=-fno-omit-frame-pointer,--compile-flag=-fno-common,--debug,--jerry-libc=off,--static-link=off,--system-allocator=on,--linker-flag=-fuse-ld=gold" UBSAN_OPTIONS=print_stacktrace=1 TIMEOUT=600 allow_failures: - env: OPTS="--check-pylint" fast_finish: true before_install: - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then tools/apt-get-install-deps.sh; fi - if [[ "$TRAVIS_OS_NAME" == "linux" ]] && [[ "$INSTALL_QEMU_ARM" == "yes" ]]; then tools/apt-get-install-qemu-arm.sh; fi - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then tools/brew-install-deps.sh; fi - if [[ "$OPTS" == "--test262" ]]; then sudo timedatectl set-timezone America/Los_Angeles; fi - if [[ "$OPTS" == *"--check-pylint"* ]]; then pip install pylint==1.6.5; fi install: script: if [[ -n "$OPTS" ]]; then tools/run-tests.py $OPTS; fi # The channel name "chat.freenode.net#jerryscript" # is encrypted against Samsung/jerryscript # to prevent IRC spam of forks # # travis encrypt -r "Samsung/jerryscript" "chat.freenode.net#jerryscript" notifications: irc: channels: - secure: "4kML4uZywOPaT3r/bHCvZCeQWooyzZumESmKuHG2Y8/B29WtMBobsoRQZRfOmlUP5kshfjh0Itp5WFpdACiBCoorHch/8z3VT7fIbKF4UnxrAvNiFArqxXC0OWGIu93e7uyyXJCsQ/JiOXU7bD31Mh8LbnfS1z3wBAMXi+AwcaGiVVH4VTL6O8sR3ij5WmsqpECWhyWTgTP3MiLquZ+09Lv9mp5GGciEemq4p8VnaQt2BdyEBmUJJ1EAyMCJlKNObQudegOzYsY3CVON9C87dCuHf7DYstsxb8AzwRAKn8LHiaWhYaWLfvHqoXmc4w1ZgN0HZ5Qyx8KMkZkXKUiHxuCSoXDxNAHWTGQBsTDid5drZeqOFucOHEKJzkqaWSUKUF3pY/hq/h2kjAn230DlBNkJt+ikSxwy6Mm8GG8LnH5gRMl37zHDHrtyRsKR8GIst9B1B95LAOLA5t8U/ucGKXqLsohS8glXaM4jjh69it3GeHj6NhB8NbC/LsmRrhjKzV+VnjPI6gZvN+5tDiuxMbsMal+0DdWVNCst/aO3Jz0iaA5ahyo2ZwBb2efw3CekRLMKmHtnjqB0SWWXT3/t2+5zNoM6gBjo4RPOg7k5eTOXcfk8okWtQ5d3n8UtvZ5rSiDl3rssHwp1yHuuC8rGGov74DLvyDlpM6p/dmtu2o8=" on_success: always on_failure: always use_notice: true template: - "%{repository_name} (%{branch}@%{commit}): %{author} - %{commit_subject} [%{result}]" - "Commit: %{compare_url}" - "Build: %{build_url}" iotjs-1.0/deps/jerry/CMakeLists.txt000066400000000000000000000175731312102117400173350ustar00rootroot00000000000000# Copyright JS Foundation and other contributors, http://js.foundation # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. cmake_minimum_required (VERSION 2.8.12) project (Jerry C ASM) # Determining platform set(PLATFORM "${CMAKE_SYSTEM_NAME}") string(TOUPPER "${PLATFORM}" PLATFORM) # Determining compiler if(CMAKE_C_COMPILER_ID MATCHES "GNU") set(USING_GCC 1) endif() if(CMAKE_C_COMPILER_ID MATCHES "Clang") set(USING_CLANG 1) endif() if(CMAKE_C_COMPILER_ID MATCHES "TI") set(USING_TI 1) endif() # Determining build type if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE "MinSizeRel") endif() # Optional components set(JERRY_CMDLINE ON CACHE BOOL "Build jerry command line tool?") set(JERRY_CMDLINE_MINIMAL OFF CACHE BOOL "Build jerry minimal command line tool?") set(JERRY_PORT_DEFAULT ON CACHE BOOL "Build default jerry port implementation?") set(JERRY_EXT ON CACHE BOOL "Build jerry-ext?") set(JERRY_LIBC ON CACHE BOOL "Build and use jerry-libc?") set(JERRY_LIBM ON CACHE BOOL "Build and use jerry-libm?") set(UNITTESTS OFF CACHE BOOL "Build unit tests?") # Optional build settings set(ENABLE_ALL_IN_ONE OFF CACHE BOOL "Enable all-in-one build?") set(ENABLE_LTO ON CACHE BOOL "Enable LTO build?") set(ENABLE_STATIC_LINK ON CACHE BOOL "Enable static linking?") set(ENABLE_STRIP ON CACHE BOOL "Enable stripping all symbols from release binary?") # Option overrides if(JERRY_CMDLINE OR JERRY_CMDLINE_MINIMAL) set(JERRY_PORT_DEFAULT ON) set(JERRY_PORT_DEFAULT_MESSAGE " (FORCED BY CMDLINE)") endif() if(JERRY_CMDLINE) set(JERRY_EXT ON) set(JERRY_EXT_MESSAGE " (FORCED BY CMDLINE)") endif() if("${PLATFORM}" STREQUAL "DARWIN") set(JERRY_LIBC OFF) set(JERRY_LIBM OFF) set(ENABLE_ALL_IN_ONE ON) set(ENABLE_LTO OFF) set(ENABLE_STATIC_LINK OFF) set(ENABLE_STRIP OFF) set(JERRY_LIBC_MESSAGE " (FORCED BY PLATFORM)") set(JERRY_LIBM_MESSAGE " (FORCED BY PLATFORM)") set(ENABLE_ALL_IN_ONE_MESSAGE " (FORCED BY PLATFORM)") set(ENABLE_LTO_MESSAGE " (FORCED BY PLATFORM)") set(ENABLE_STATIC_LINK_MESSAGE " (FORCED BY PLATFORM)") set(ENABLE_STRIP_MESSAGE " (FORCED BY PLATFORM)") endif() if(USING_TI) set(ENABLE_STATIC_LINK ON) set(ENABLE_STRIP OFF) set(ENABLE_STATIC_LINK_MESSAGE " (FORCED BY COMPILER)") set(ENABLE_STRIP_MESSAGE " (FORCED BY COMPILER)") endif() # Status messages message(STATUS "CMAKE_BUILD_TYPE " ${CMAKE_BUILD_TYPE}) message(STATUS "CMAKE_SYSTEM_NAME " ${CMAKE_SYSTEM_NAME}) message(STATUS "CMAKE_SYSTEM_PROCESSOR " ${CMAKE_SYSTEM_PROCESSOR}) message(STATUS "ENABLE_ALL_IN_ONE " ${ENABLE_ALL_IN_ONE} ${ENABLE_ALL_IN_ONE_MESSAGE}) message(STATUS "ENABLE_LTO " ${ENABLE_LTO} ${ENABLE_LTO_MESSAGE}) message(STATUS "ENABLE_STATIC_LINK " ${ENABLE_STATIC_LINK} ${ENABLE_STATIC_LINK_MESSAGE}) message(STATUS "ENABLE_STRIP " ${ENABLE_STRIP} ${ENABLE_STRIP_MESSAGE}) message(STATUS "JERRY_CMDLINE " ${JERRY_CMDLINE}) message(STATUS "JERRY_CMDLINE_MINIMAL " ${JERRY_CMDLINE_MINIMAL}) message(STATUS "JERRY_PORT_DEFAULT " ${JERRY_PORT_DEFAULT} ${JERRY_PORT_DEFAULT_MESSAGE}) message(STATUS "JERRY_EXT " ${JERRY_EXT} ${JERRY_EXT_MESSAGE}) message(STATUS "JERRY_LIBC " ${JERRY_LIBC} ${JERRY_LIBC_MESSAGE}) message(STATUS "JERRY_LIBM " ${JERRY_LIBM} ${JERRY_LIBM_MESSAGE}) message(STATUS "UNITTESTS " ${UNITTESTS}) # Setup directories # Project binary dir set(PROJECT_BINARY_DIR "${CMAKE_BINARY_DIR}") # Library output directory set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib/") # Executable output directory set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin/") # Archive targets output Directory set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib/") # Remove rdynamic option set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS ) # Compile/link flags # Helper macros macro(jerry_add_flags VAR) foreach(_flag ${ARGN}) set(${VAR} "${${VAR}} ${_flag}") endforeach() endmacro() macro(jerry_add_compile_flags) jerry_add_flags(CMAKE_C_FLAGS ${ARGV}) endmacro() macro(jerry_add_compile_warnings) foreach(_warning ${ARGV}) jerry_add_compile_flags(-W${_warning}) if(USING_GCC) jerry_add_compile_flags(-Werror=${_warning}) endif() endforeach() endmacro() macro(jerry_add_link_flags) jerry_add_flags(LINKER_FLAGS_COMMON ${ARGV}) endmacro() # Architecture-specific compile/link flags jerry_add_compile_flags(${FLAGS_COMMON_ARCH}) jerry_add_flags(CMAKE_EXE_LINKER_FLAGS ${FLAGS_COMMON_ARCH}) # Enable static build if(ENABLE_STATIC_LINK) if (USING_GCC OR USING_CLANG) jerry_add_link_flags("-static") endif() endif() # LTO if(ENABLE_LTO) if (USING_GCC OR USING_CLANG) jerry_add_compile_flags(-flto) jerry_add_link_flags(-flto) endif() if(USING_GCC) jerry_add_compile_flags(-fno-fat-lto-objects) # Use gcc-ar and gcc-ranlib to support LTO set(CMAKE_AR "gcc-ar") set(CMAKE_RANLIB "gcc-ranlib") endif() if(USING_TI) jerry_add_link_flags(-lto) endif() endif() # Compiler / Linker flags if (USING_GCC OR USING_CLANG) jerry_add_compile_flags(-fno-builtin) endif() if(("${PLATFORM}" STREQUAL "DARWIN")) jerry_add_link_flags(-lSystem) else() jerry_add_link_flags(-Wl,-z,noexecstack) endif() # Turn off linking to compiler's default libc, in case jerry-libc is used if(JERRY_LIBC) jerry_add_link_flags(-nostdlib) endif() # Turn off stack protector if (USING_GCC OR USING_CLANG) jerry_add_compile_flags(-fno-stack-protector) endif() if (USING_GCC OR USING_CLANG) jerry_add_compile_warnings(all extra format-nonliteral init-self conversion sign-conversion format-security missing-declarations shadow strict-prototypes undef old-style-definition) jerry_add_compile_flags(-Wno-stack-protector -Wno-attributes) endif() if(USING_GCC) jerry_add_compile_warnings(logical-op) elseif(USING_CLANG) jerry_add_compile_flags(-Wno-nested-anon-types -Wno-static-in-inline) endif() if(JERRY_LIBC) jerry_add_compile_flags(-Werror) endif() # C if (USING_GCC OR USING_CLANG) jerry_add_compile_flags(-std=c99 -pedantic) elseif(USING_TI) jerry_add_compile_flags(--c99) endif() # Strip binary if(ENABLE_STRIP AND NOT CMAKE_BUILD_TYPE STREQUAL "Debug") jerry_add_link_flags(-s) endif() # TODO: Remove workaround for gcc 7 bug if the # fallthrough comment detection is fixed. if (USING_GCC AND CMAKE_C_COMPILER_VERSION VERSION_GREATER 7.0) jerry_add_compile_flags(-Wno-implicit-fallthrough) endif() # External compiler & linker flags if(DEFINED EXTERNAL_COMPILE_FLAGS) jerry_add_compile_flags(${EXTERNAL_COMPILE_FLAGS}) endif() if(DEFINED EXTERNAL_LINKER_FLAGS) jerry_add_link_flags(${EXTERNAL_LINKER_FLAGS}) endif() # Jerry's libc if(JERRY_LIBC) add_subdirectory(jerry-libc) endif() # Jerry's libm if(JERRY_LIBM) add_subdirectory(jerry-libm) endif() # Jerry's core add_subdirectory(jerry-core) # Jerry's default port implementation if(JERRY_PORT_DEFAULT) add_subdirectory(jerry-port/default) endif() # Jerry's extension tools if(JERRY_EXT) add_subdirectory(jerry-ext) endif() # Jerry command line tool if(JERRY_CMDLINE OR JERRY_CMDLINE_MINIMAL) add_subdirectory(jerry-main) endif() # Unittests if(UNITTESTS) add_subdirectory(tests/unit-core) if(JERRY_LIBM) add_subdirectory(tests/unit-libm) endif() if(JERRY_EXT) add_subdirectory(tests/unit-ext) endif() endif() iotjs-1.0/deps/jerry/CONTRIBUTING.md000066400000000000000000000145261312102117400170210ustar00rootroot00000000000000# Contribution Guidelines ## Patch Submission Process The following guidelines on the submission process are provided to help you be more effective when submitting code to the JerryScript project. When development is complete, a patch set should be submitted via GitHub pull requests. A review of the patch set will take place. When accepted, the patch set will be integrated into the master branch, verified, and tested. It is then the responsibility of the authoring developer to maintain the code throughout its lifecycle. Please submit all patches in public by opening a pull request. Patches sent privately to Maintainers and Committers will not be considered. Because the JerryScript Project is an Open Source project, be prepared for feedback and criticism-it happens to everyone-. If asked to rework your code, be persistent and resubmit after making changes. ### 1. Scope the patch Smaller patches are generally easier to understand and test, so please submit changes in the smallest increments possible, within reason. Smaller patches are less likely to have unintended consequences, and if they do, getting to the root cause is much easier for you and the Maintainers and Committers. Additionally, smaller patches are much more likely to be accepted. ### 2. Ensure all files have a proper license header and copyright notice Any code that you want to contribute to the project must be licensed under the [Apache License 2.0](LICENSE). Contributions under a different license can not be accepted. Each file should start with the following header: ```c /* Copyright JS Foundation and other contributors, http://js.foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ ``` Adding copyright notices other than the project-wide notice ("Copyright JS Foundation and other contributors, http://js.foundation") is not permitted. The only exception is adding third-party code which requires copyright notices to be preserved. Adding third-party code to the project generally requires a strong justification. ### 3. Sign your work with the JerryScript [Developer's Certificate of Origin](DCO.md) The sign-off is a simple line at the end of the commit message of the patch, which certifies that you wrote it or otherwise have the right to pass it on as an Open Source patch. The sign-off is required for a patch to be accepted. We have the same requirements for using the signed-off-by process as the Linux kernel. In short, you need to include a signed-off-by tag in every patch. You should use your real name and email address in the format below: > JerryScript-DCO-1.0-Signed-off-by: Random J Developer random@developer.example.org "JerryScript-DCO-1.0-Signed-off-by:" this is a developer's certification that he or she has the right to submit the patch for inclusion into the project. It is an agreement to the JerryScript [Developer's Certificate of Origin](DCO.md). **Code without a proper signoff cannot be merged into the mainline.** ### 4. Open a GitHub [pull request](https://github.com/jerryscript-project/jerryscript/pulls) You can find instructions about opening a pull request [here](https://help.github.com/articles/creating-a-pull-request). ### 5. What if my patch is rejected? It happens all the time, for many reasons, and not necessarily because the code is bad. Take the feedback, adapt your code, and try again. Remember, the ultimate goal is to preserve the quality of the code and maintain the focus of the Project through intensive review. Maintainers and Committers typically have to process a lot of submissions, and the time for any individual response is generally limited. If the reason for rejection is unclear, please ask for more information from the Maintainers and Committers. If you have a solid technical reason to disagree with feedback and you feel that reason has been overlooked, take the time to thoroughly explain it in your response. ### 6. Code review Code review can be performed by all the members of the Project (not just Maintainers and Committers). Members can review code changes and share their opinion through comments guided by the following principles: * Discuss code; never discuss the code's author * Respect and acknowledge contributions, suggestions, and comments * Listen and be open to all different opinions * Help each other Changes are submitted via pull requests and only the Maintainers and Committers should approve or reject the pull request (note that only Maintainers can give binding review scores). Changes should be reviewed in reasonable amount of time. Maintainers and Committers should leave changes open for some time (at least 1 full business day) so others can offer feedback. Review times increase with the complexity of the review. ## Tips on GitHub Pull Requests * [Fork](https://guides.github.com/activities/forking) the GitHub repository and clone it locally * Connect your local repository to the original upstream repository by adding it as a remote * Create a [branch](https://guides.github.com/introduction/flow) for your edits * Pull in upstream changes often to stay up-to-date so that when you submit your pull request, merge conflicts will be less likely For more details, see the GitHub [fork syncing](https://help.github.com/articles/syncing-a-fork) guidelines. ## How to add the DCO line to every single commit automatically It is easy to forget adding the DCO line to the end of every commit message. Fortunately there is a nice way to do it automatically. Once you've cloned the repository into your local machine, you can add `prepare commit message hook` in `.git/hooks` directory like this: ``` #!/usr/bin/env python import sys commit_msg_filepath = sys.argv[1] with open(commit_msg_filepath, "r+") as f: content = f.read() f.seek(0, 0) f.write("%s\n\nJerryScript-DCO-1.0-Signed-off-by: " % content) ``` Please refer [Git Hooks](http://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks) for more information. iotjs-1.0/deps/jerry/DCO.md000066400000000000000000000034671312102117400155210ustar00rootroot00000000000000# JerryScript Developer's Certificate of Origin The JerryScript project uses the signed-off-by language and process to give us a clear chain of trust for every patch received. > By making a contribution to this project, I certify that: > (a) The contribution was created in whole or in part by me and I have the right to submit it under the open source license indicated in the file; or > (b) The contribution is based upon previous work that, to the best of my knowledge, is covered under an appropriate open source license and I have the right under that license to submit that work with modifications, whether created in whole or in part by me, under the same open source license (unless I am permitted to submit under a different license), as indicated in the file; or > (c) The contribution was provided directly to me by some other person who certified (a), (b) or (c) and I have not modified it. > (d) I understand and agree that this project and the contribution are public and that a record of the contribution (including all personal information I submit with it, including my sign-off) is maintained indefinitely and may be redistributed consistent with this project, under the same open source license. We have the same requirements for using the signed-off-by process as the Linux kernel. In short, you need to include a signed-off-by tag in the commit message of every patch. You should use your real name and email address in the format below: > JerryScript-DCO-1.0-Signed-off-by: Random J Developer random@developer.example.org "JerryScript-DCO-1.0-Signed-off-by:" this is a developer's certification that he or she has the right to submit the patch for inclusion into the project. It is an agreement to the Developer's Certificate of Origin (above). **Code without a proper signoff cannot be merged into the mainline.** iotjs-1.0/deps/jerry/Doxyfile000066400000000000000000003133211312102117400162710ustar00rootroot00000000000000# Doxyfile 1.8.9.1 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project. # # All text after a double hash (##) is considered a comment and is placed in # front of the TAG it is preceding. # # All text after a single hash (#) is considered a comment and will be ignored. # The format is: # TAG = value [value, ...] # For lists, items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (\" \"). #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # This tag specifies the encoding used for all characters in the config file # that follow. The default is UTF-8 which is also the encoding used for all text # before the first occurrence of this tag. Doxygen uses libiconv (or the iconv # built into libc) for the transcoding. See http://www.gnu.org/software/libiconv # for the list of possible encodings. # The default value is: UTF-8. DOXYFILE_ENCODING = UTF-8 # The PROJECT_NAME tag is a single word (or a sequence of words surrounded by # double-quotes, unless you are using Doxywizard) that should identify the # project for which the documentation is generated. This name is used in the # title of most generated pages and in a few other places. # The default value is: My Project. PROJECT_NAME = "JerryScript" # The PROJECT_NUMBER tag can be used to enter a project or revision number. This # could be handy for archiving the generated documentation or if some version # control system is used. PROJECT_NUMBER = # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a # quick idea about the purpose of the project. Keep the description short. PROJECT_BRIEF = "JavaScript Engine for Internet of Things" # With the PROJECT_LOGO tag one can specify a logo or an icon that is included # in the documentation. The maximum height of the logo should not exceed 55 # pixels and the maximum width should not exceed 200 pixels. Doxygen will copy # the logo to the output directory. PROJECT_LOGO = # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path # into which the generated documentation will be written. If a relative path is # entered, it will be relative to the location where doxygen was started. If # left blank the current directory will be used. OUTPUT_DIRECTORY = "docs/doxygen" # If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub- # directories (in 2 levels) under the output directory of each output format and # will distribute the generated files over these directories. Enabling this # option can be useful when feeding doxygen a huge amount of source files, where # putting all generated files in the same directory would otherwise causes # performance problems for the file system. # The default value is: NO. CREATE_SUBDIRS = NO # If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII # characters to appear in the names of generated files. If set to NO, non-ASCII # characters will be escaped, for example _xE3_x81_x84 will be used for Unicode # U+3044. # The default value is: NO. # ALLOW_UNICODE_NAMES = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese, # Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States), # Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian, # Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages), # Korean, Korean-en (Korean with English messages), Latvian, Lithuanian, # Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian, # Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish, # Ukrainian and Vietnamese. # The default value is: English. OUTPUT_LANGUAGE = English # If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member # descriptions after the members that are listed in the file and class # documentation (similar to Javadoc). Set to NO to disable this. # The default value is: YES. BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief # description of a member or function before the detailed description # # Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. # The default value is: YES. REPEAT_BRIEF = YES # This tag implements a quasi-intelligent brief description abbreviator that is # used to form the text in various listings. Each string in this list, if found # as the leading text of the brief description, will be stripped from the text # and the result, after processing the whole list, is used as the annotated # text. Otherwise, the brief description is used as-is. If left blank, the # following values are used ($name is automatically replaced with the name of # the entity):The $name class, The $name widget, The $name file, is, provides, # specifies, contains, represents, a, an and the. ABBREVIATE_BRIEF = # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # doxygen will generate a detailed section even if there is only a brief # description. # The default value is: NO. ALWAYS_DETAILED_SEC = YES # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. # The default value is: NO. INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path # before files name in the file list and in the header files. If set to NO the # shortest path that makes the file name unique will be used # The default value is: YES. FULL_PATH_NAMES = YES # The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. # Stripping is only done if one of the specified strings matches the left-hand # part of the path. The tag can be used to show relative paths in the file list. # If left blank the directory from which doxygen is run is used as the path to # strip. # # Note that you can specify absolute paths here, but also relative paths, which # will be relative from the directory where doxygen is started. # This tag requires that the tag FULL_PATH_NAMES is set to YES. STRIP_FROM_PATH = # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the # path mentioned in the documentation of a class, which tells the reader which # header file to include in order to use a class. If left blank only the name of # the header file containing the class definition is used. Otherwise one should # specify the list of include paths that are normally passed to the compiler # using the -I flag. STRIP_FROM_INC_PATH = # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but # less readable) file names. This can be useful is your file systems doesn't # support long names like on DOS, Mac, or CD-ROM. # The default value is: NO. SHORT_NAMES = NO # If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the # first line (until the first dot) of a Javadoc-style comment as the brief # description. If set to NO, the Javadoc-style will behave just like regular Qt- # style comments (thus requiring an explicit @brief command for a brief # description.) # The default value is: NO. JAVADOC_AUTOBRIEF = YES # If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first # line (until the first dot) of a Qt-style comment as the brief description. If # set to NO, the Qt-style will behave just like regular Qt-style comments (thus # requiring an explicit \brief command for a brief description.) # The default value is: NO. QT_AUTOBRIEF = NO # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a # multi-line C++ special comment block (i.e. a block of //! or /// comments) as # a brief description. This used to be the default behavior. The new default is # to treat a multi-line C++ comment block as a detailed description. Set this # tag to YES if you prefer the old behavior instead. # # Note that setting this tag to YES also means that rational rose comments are # not recognized any more. # The default value is: NO. MULTILINE_CPP_IS_BRIEF = NO # If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the # documentation from any documented member that it re-implements. # The default value is: YES. INHERIT_DOCS = YES # If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new # page for each member. If set to NO, the documentation of a member will be part # of the file/class/namespace that contains it. # The default value is: NO. SEPARATE_MEMBER_PAGES = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen # uses this value to replace tabs by spaces in code fragments. # Minimum value: 1, maximum value: 16, default value: 4. TAB_SIZE = 2 # This tag can be used to specify a number of aliases that act as commands in # the documentation. An alias has the form: # name=value # For example adding # "sideeffect=@par Side Effects:\n" # will allow you to put the command \sideeffect (or @sideeffect) in the # documentation, which will result in a user-defined paragraph with heading # "Side Effects:". You can put \n's in the value part of an alias to insert # newlines. ALIASES = # This tag can be used to specify a number of word-keyword mappings (TCL only). # A mapping has the form "name=value". For example adding "class=itcl::class" # will allow you to use the command class in the itcl::class meaning. TCL_SUBST = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources # only. Doxygen will then generate output that is more tailored for C. For # instance, some of the names that are used will be different. The list of all # members will be omitted, etc. # The default value is: NO. OPTIMIZE_OUTPUT_FOR_C = YES # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or # Python sources only. Doxygen will then generate output that is more tailored # for that language. For instance, namespaces will be presented as packages, # qualified scopes will look different, etc. # The default value is: NO. OPTIMIZE_OUTPUT_JAVA = NO # Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran # sources. Doxygen will then generate output that is tailored for Fortran. # The default value is: NO. OPTIMIZE_FOR_FORTRAN = NO # Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL # sources. Doxygen will then generate output that is tailored for VHDL. # The default value is: NO. OPTIMIZE_OUTPUT_VHDL = NO # Doxygen selects the parser to use depending on the extension of the files it # parses. With this tag you can assign which parser to use for a given # extension. Doxygen has a built-in mapping, but you can override or extend it # using this tag. The format is ext=language, where ext is a file extension, and # language is one of the parsers supported by doxygen: IDL, Java, Javascript, # C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran: # FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran: # Fortran. In the later case the parser tries to guess whether the code is fixed # or free formatted code, this is the default for Fortran type files), VHDL. For # instance to make doxygen treat .inc files as Fortran files (default is PHP), # and .f files as C (default is Fortran), use: inc=Fortran f=C. # # Note: For files without extension you can use no_extension as a placeholder. # # Note that for custom extensions you also need to set FILE_PATTERNS otherwise # the files are not read by doxygen. EXTENSION_MAPPING = # If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments # according to the Markdown format, which allows for more readable # documentation. See http://daringfireball.net/projects/markdown/ for details. # The output of markdown processing is further processed by doxygen, so you can # mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in # case of backward compatibilities issues. # The default value is: YES. MARKDOWN_SUPPORT = YES # When enabled doxygen tries to link words that correspond to documented # classes, or namespaces to their corresponding documentation. Such a link can # be prevented in individual cases by putting a % sign in front of the word or # globally by setting AUTOLINK_SUPPORT to NO. # The default value is: YES. AUTOLINK_SUPPORT = YES # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want # to include (a tag file for) the STL sources as input, then you should set this # tag to YES in order to let doxygen match functions declarations and # definitions whose arguments contain STL classes (e.g. func(std::string); # versus func(std::string) {}). This also make the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. # The default value is: NO. BUILTIN_STL_SUPPORT = NO # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. # The default value is: NO. CPP_CLI_SUPPORT = NO # Set the SIP_SUPPORT tag to YES if your project consists of sip (see: # http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen # will parse them like normal C++ but will assume all classes use public instead # of private inheritance when no explicit protection keyword is present. # The default value is: NO. SIP_SUPPORT = NO # For Microsoft's IDL there are propget and propput attributes to indicate # getter and setter methods for a property. Setting this option to YES will make # doxygen to replace the get and set methods by a property in the documentation. # This will only work if the methods are indeed getting or setting a simple # type. If this is not the case, or you want to show the methods anyway, you # should set this option to NO. # The default value is: YES. IDL_PROPERTY_SUPPORT = YES # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. # The default value is: NO. DISTRIBUTE_GROUP_DOC = NO # Set the SUBGROUPING tag to YES to allow class member groups of the same type # (for instance a group of public functions) to be put as a subgroup of that # type (e.g. under the Public Functions section). Set it to NO to prevent # subgrouping. Alternatively, this can be done per class using the # \nosubgrouping command. # The default value is: YES. SUBGROUPING = YES # When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions # are shown inside the group in which they are included (e.g. using \ingroup) # instead of on a separate page (for HTML and Man pages) or section (for LaTeX # and RTF). # # Note that this feature does not work in combination with # SEPARATE_MEMBER_PAGES. # The default value is: NO. INLINE_GROUPED_CLASSES = NO # When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions # with only public data fields or simple typedef fields will be shown inline in # the documentation of the scope in which they are defined (i.e. file, # namespace, or group documentation), provided this scope is documented. If set # to NO, structs, classes, and unions are shown on a separate page (for HTML and # Man pages) or section (for LaTeX and RTF). # The default value is: NO. INLINE_SIMPLE_STRUCTS = NO # When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or # enum is documented as struct, union, or enum with the name of the typedef. So # typedef struct TypeS {} TypeT, will appear in the documentation as a struct # with name TypeT. When disabled the typedef will appear as a member of a file, # namespace, or class. And the struct will be named TypeS. This can typically be # useful for C code in case the coding convention dictates that all compound # types are typedef'ed and only the typedef is referenced, never the tag name. # The default value is: NO. TYPEDEF_HIDES_STRUCT = NO # The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This # cache is used to resolve symbols given their name and scope. Since this can be # an expensive process and often the same symbol appears multiple times in the # code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small # doxygen will become slower. If the cache is too large, memory is wasted. The # cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range # is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 # symbols. At the end of a run doxygen will report the cache usage and suggest # the optimal cache size from a speed point of view. # Minimum value: 0, maximum value: 9, default value: 0. LOOKUP_CACHE_SIZE = 0 #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in # documentation are documented, even if no documentation was available. Private # class members and static file members will be hidden unless the # EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. # Note: This will also disable the warnings about undocumented members that are # normally produced when WARNINGS is set to YES. # The default value is: NO. EXTRACT_ALL = YES # If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will # be included in the documentation. # The default value is: NO. EXTRACT_PRIVATE = YES # If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal # scope will be included in the documentation. # The default value is: NO. EXTRACT_PACKAGE = NO # If the EXTRACT_STATIC tag is set to YES, all static members of a file will be # included in the documentation. # The default value is: NO. EXTRACT_STATIC = YES # If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined # locally in source files will be included in the documentation. If set to NO, # only classes defined in header files are included. Does not have any effect # for Java sources. # The default value is: YES. EXTRACT_LOCAL_CLASSES = YES # This flag is only useful for Objective-C code. If set to YES, local methods, # which are defined in the implementation section but not in the interface are # included in the documentation. If set to NO, only methods in the interface are # included. # The default value is: NO. EXTRACT_LOCAL_METHODS = YES # If this flag is set to YES, the members of anonymous namespaces will be # extracted and appear in the documentation as a namespace called # 'anonymous_namespace{file}', where file will be replaced with the base name of # the file that contains the anonymous namespace. By default anonymous namespace # are hidden. # The default value is: NO. EXTRACT_ANON_NSPACES = NO # If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all # undocumented members inside documented classes or files. If set to NO these # members will be included in the various overviews, but no documentation # section is generated. This option has no effect if EXTRACT_ALL is enabled. # The default value is: NO. HIDE_UNDOC_MEMBERS = NO # If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. If set # to NO, these classes will be included in the various overviews. This option # has no effect if EXTRACT_ALL is enabled. # The default value is: NO. HIDE_UNDOC_CLASSES = NO # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend # (class|struct|union) declarations. If set to NO, these declarations will be # included in the documentation. # The default value is: NO. HIDE_FRIEND_COMPOUNDS = NO # If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any # documentation blocks found inside the body of a function. If set to NO, these # blocks will be appended to the function's detailed documentation block. # The default value is: NO. HIDE_IN_BODY_DOCS = NO # The INTERNAL_DOCS tag determines if documentation that is typed after a # \internal command is included. If the tag is set to NO then the documentation # will be excluded. Set it to YES to include the internal documentation. # The default value is: NO. INTERNAL_DOCS = NO # If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file # names in lower-case letters. If set to YES, upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. # The default value is: system dependent. CASE_SENSE_NAMES = YES # If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with # their full class and namespace scopes in the documentation. If set to YES, the # scope will be hidden. # The default value is: NO. HIDE_SCOPE_NAMES = NO # If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will # append additional text to a page's title, such as Class Reference. If set to # YES the compound reference will be hidden. # The default value is: NO. # HIDE_COMPOUND_REFERENCE= NO # If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of # the files that are included by a file in the documentation of that file. # The default value is: YES. SHOW_INCLUDE_FILES = YES # If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each # grouped member an include statement to the documentation, telling the reader # which file to include in order to use the member. # The default value is: NO. SHOW_GROUPED_MEMB_INC = NO # If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include # files with double quotes in the documentation rather than with sharp brackets. # The default value is: NO. FORCE_LOCAL_INCLUDES = NO # If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the # documentation for inline members. # The default value is: YES. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the # (detailed) documentation of file and class members alphabetically by member # name. If set to NO, the members will appear in declaration order. # The default value is: YES. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief # descriptions of file, namespace and class members alphabetically by member # name. If set to NO, the members will appear in declaration order. Note that # this will also influence the order of the classes in the class list. # The default value is: NO. SORT_BRIEF_DOCS = YES # If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the # (brief and detailed) documentation of class members so that constructors and # destructors are listed first. If set to NO the constructors will appear in the # respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS. # Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief # member documentation. # Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting # detailed member documentation. # The default value is: NO. SORT_MEMBERS_CTORS_1ST = NO # If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy # of group names into alphabetical order. If set to NO the group names will # appear in their defined order. # The default value is: NO. SORT_GROUP_NAMES = NO # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by # fully-qualified names, including namespaces. If set to NO, the class list will # be sorted only by class name, not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. # Note: This option applies only to the class list, not to the alphabetical # list. # The default value is: NO. SORT_BY_SCOPE_NAME = NO # If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper # type resolution of all parameters of a function it will reject a match between # the prototype and the implementation of a member function even if there is # only one candidate or it is obvious which candidate to choose by doing a # simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still # accept a match between prototype and implementation in such cases. # The default value is: NO. STRICT_PROTO_MATCHING = NO # The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo # list. This list is created by putting \todo commands in the documentation. # The default value is: YES. GENERATE_TODOLIST = YES # The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test # list. This list is created by putting \test commands in the documentation. # The default value is: YES. GENERATE_TESTLIST = YES # The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug # list. This list is created by putting \bug commands in the documentation. # The default value is: YES. GENERATE_BUGLIST = YES # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO) # the deprecated list. This list is created by putting \deprecated commands in # the documentation. # The default value is: YES. GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional documentation # sections, marked by \if ... \endif and \cond # ... \endcond blocks. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the # initial value of a variable or macro / define can have for it to appear in the # documentation. If the initializer consists of more lines than specified here # it will be hidden. Use a value of 0 to hide initializers completely. The # appearance of the value of individual variables and macros / defines can be # controlled using \showinitializer or \hideinitializer command in the # documentation regardless of this setting. # Minimum value: 0, maximum value: 10000, default value: 30. MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated at # the bottom of the documentation of classes and structs. If set to YES, the # list will mention the files that were used to generate the documentation. # The default value is: YES. SHOW_USED_FILES = YES # Set the SHOW_FILES tag to NO to disable the generation of the Files page. This # will remove the Files entry from the Quick Index and from the Folder Tree View # (if specified). # The default value is: YES. SHOW_FILES = YES # Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces # page. This will remove the Namespaces entry from the Quick Index and from the # Folder Tree View (if specified). # The default value is: YES. SHOW_NAMESPACES = YES # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from # the version control system). Doxygen will invoke the program by executing (via # popen()) the command command input-file, where command is the value of the # FILE_VERSION_FILTER tag, and input-file is the name of an input file provided # by doxygen. Whatever the program writes to standard output is used as the file # version. For an example see the documentation. FILE_VERSION_FILTER = # The LAYOUT_FILE tag can be used to specify a layout file which will be parsed # by doxygen. The layout file controls the global structure of the generated # output files in an output format independent way. To create the layout file # that represents doxygen's defaults, run doxygen with the -l option. You can # optionally specify a file name after the option, if omitted DoxygenLayout.xml # will be used as the name of the layout file. # # Note that if you run doxygen from a directory containing a file called # DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE # tag is left empty. LAYOUT_FILE = # The CITE_BIB_FILES tag can be used to specify one or more bib files containing # the reference definitions. This must be a list of .bib files. The .bib # extension is automatically appended if omitted. This requires the bibtex tool # to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info. # For LaTeX the style of the bibliography can be controlled using # LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the # search path. See also \cite for info how to create references. CITE_BIB_FILES = #--------------------------------------------------------------------------- # Configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated to # standard output by doxygen. If QUIET is set to YES this implies that the # messages are off. # The default value is: NO. QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are # generated to standard error (stderr) by doxygen. If WARNINGS is set to YES # this implies that the warnings are on. # # Tip: Turn warnings on while writing the documentation. # The default value is: YES. WARNINGS = YES # If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate # warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag # will automatically be disabled. # The default value is: YES. WARN_IF_UNDOCUMENTED = YES # If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as not documenting some parameters # in a documented function, or documenting parameters that don't exist or using # markup commands wrongly. # The default value is: YES. WARN_IF_DOC_ERROR = YES # This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that # are documented, but have no documentation for their parameters or return # value. If set to NO, doxygen will only warn about wrong or incomplete # parameter documentation, but not about the absence of documentation. # The default value is: NO. WARN_NO_PARAMDOC = YES # The WARN_FORMAT tag determines the format of the warning messages that doxygen # can produce. The string should contain the $file, $line, and $text tags, which # will be replaced by the file and line number from which the warning originated # and the warning text. Optionally the format may contain $version, which will # be replaced by the version of the file (if it could be obtained via # FILE_VERSION_FILTER) # The default value is: $file:$line: $text. WARN_FORMAT = "$file:$line: $text" # The WARN_LOGFILE tag can be used to specify a file to which warning and error # messages should be written. If left blank the output is written to standard # error (stderr). WARN_LOGFILE = #--------------------------------------------------------------------------- # Configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag is used to specify the files and/or directories that contain # documented source files. You may enter file names like myfile.cpp or # directories like /usr/src/myproject. Separate the files or directories with # spaces. # Note: If this tag is empty the current directory is searched. INPUT = jerry-core jerry-libc # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses # libiconv (or the iconv built into libc) for the transcoding. See the libiconv # documentation (see: http://www.gnu.org/software/libiconv) for the list of # possible encodings. # The default value is: UTF-8. INPUT_ENCODING = UTF-8 # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and # *.h) to filter out the source-files in the directories. If left blank the # following patterns are tested:*.c, *.cc, *.cxx, *.cpp, *.c++, *.java, *.ii, # *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, *.hh, *.hxx, *.hpp, # *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, *.m, *.markdown, # *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf, # *.qsf, *.as and *.js. FILE_PATTERNS = *.h, *.c # The RECURSIVE tag can be used to specify whether or not subdirectories should # be searched for input files as well. # The default value is: NO. RECURSIVE = YES # The EXCLUDE tag can be used to specify files and/or directories that should be # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. # # Note that relative paths are relative to the directory from which doxygen is # run. EXCLUDE = # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or # directories that are symbolic links (a Unix file system feature) are excluded # from the input. # The default value is: NO. EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude # certain files from those directories. # # Note that the wildcards are matched against the file with absolute path, so to # exclude all test directories for example use the pattern */test/* EXCLUDE_PATTERNS = # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the # output. The symbol name can be a fully qualified name, a word, or if the # wildcard * is used, a substring. Examples: ANamespace, AClass, # AClass::ANamespace, ANamespace::*Test # # Note that the wildcards are matched against the file with absolute path, so to # exclude all test directories use the pattern */test/* EXCLUDE_SYMBOLS = # The EXAMPLE_PATH tag can be used to specify one or more files or directories # that contain example code fragments that are included (see the \include # command). EXAMPLE_PATH = # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and # *.h) to filter out the source-files in the directories. If left blank all # files are included. EXAMPLE_PATTERNS = # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude commands # irrespective of the value of the RECURSIVE tag. # The default value is: NO. EXAMPLE_RECURSIVE = NO # The IMAGE_PATH tag can be used to specify one or more files or directories # that contain images that are to be included in the documentation (see the # \image command). IMAGE_PATH = # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command: # # # # where is the value of the INPUT_FILTER tag, and is the # name of an input file. Doxygen will then use the output that the filter # program writes to standard output. If FILTER_PATTERNS is specified, this tag # will be ignored. # # Note that the filter must not add or remove lines; it is applied before the # code is scanned, but not when the output code is generated. If lines are added # or removed, the anchors will not be placed correctly. INPUT_FILTER = # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. Doxygen will compare the file name with each pattern and apply the # filter if there is a match. The filters are a list of the form: pattern=filter # (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how # filters are used. If the FILTER_PATTERNS tag is empty or if none of the # patterns match the file name, INPUT_FILTER is applied. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will also be used to filter the input files that are used for # producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). # The default value is: NO. FILTER_SOURCE_FILES = NO # The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file # pattern. A pattern will override the setting for FILTER_PATTERN (if any) and # it is also possible to disable source filtering for a specific pattern using # *.ext= (so without naming a filter). # This tag requires that the tag FILTER_SOURCE_FILES is set to YES. FILTER_SOURCE_PATTERNS = # If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that # is part of the input, its contents will be placed on the main page # (index.html). This can be useful if you have a project on for instance GitHub # and want to reuse the introduction page also for the doxygen output. USE_MDFILE_AS_MAINPAGE = #--------------------------------------------------------------------------- # Configuration options related to source browsing #--------------------------------------------------------------------------- # If the SOURCE_BROWSER tag is set to YES then a list of source files will be # generated. Documented entities will be cross-referenced with these sources. # # Note: To get rid of all source code in the generated output, make sure that # also VERBATIM_HEADERS is set to NO. # The default value is: NO. SOURCE_BROWSER = YES # Setting the INLINE_SOURCES tag to YES will include the body of functions, # classes and enums directly into the documentation. # The default value is: NO. INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any # special comment blocks from generated source code fragments. Normal C, C++ and # Fortran comments will always remain visible. # The default value is: YES. STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES then for each documented # function all documented functions referencing it will be listed. # The default value is: NO. REFERENCED_BY_RELATION = NO # If the REFERENCES_RELATION tag is set to YES then for each documented function # all documented entities called/used by that function will be listed. # The default value is: NO. REFERENCES_RELATION = NO # If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set # to YES then the hyperlinks from functions in REFERENCES_RELATION and # REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will # link to the documentation. # The default value is: YES. REFERENCES_LINK_SOURCE = YES # If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the # source code will show a tooltip with additional information such as prototype, # brief description and links to the definition and documentation. Since this # will make the HTML file larger and loading of large files a bit slower, you # can opt to disable this feature. # The default value is: YES. # This tag requires that the tag SOURCE_BROWSER is set to YES. SOURCE_TOOLTIPS = YES # If the USE_HTAGS tag is set to YES then the references to source code will # point to the HTML generated by the htags(1) tool instead of doxygen built-in # source browser. The htags tool is part of GNU's global source tagging system # (see http://www.gnu.org/software/global/global.html). You will need version # 4.8.6 or higher. # # To use it do the following: # - Install the latest version of global # - Enable SOURCE_BROWSER and USE_HTAGS in the config file # - Make sure the INPUT points to the root of the source tree # - Run doxygen as normal # # Doxygen will invoke htags (and that will in turn invoke gtags), so these # tools must be available from the command line (i.e. in the search path). # # The result: instead of the source browser generated by doxygen, the links to # source code will now point to the output of htags. # The default value is: NO. # This tag requires that the tag SOURCE_BROWSER is set to YES. USE_HTAGS = NO # If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a # verbatim copy of the header file for each class for which an include is # specified. Set to NO to disable this. # See also: Section \class. # The default value is: YES. VERBATIM_HEADERS = YES # If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the # clang parser (see: http://clang.llvm.org/) for more accurate parsing at the # cost of reduced performance. This can be particularly helpful with template # rich C++ code for which doxygen's built-in parser lacks the necessary type # information. # Note: The availability of this option depends on whether or not doxygen was # compiled with the --with-libclang option. # The default value is: NO. # CLANG_ASSISTED_PARSING = NO # If clang assisted parsing is enabled you can provide the compiler with command # line options that you would normally use when invoking the compiler. Note that # the include paths will already be set by doxygen for the files and directories # specified with INPUT and INCLUDE_PATH. # This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES. # CLANG_OPTIONS = #--------------------------------------------------------------------------- # Configuration options related to the alphabetical class index #--------------------------------------------------------------------------- # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all # compounds will be generated. Enable this if the project contains a lot of # classes, structs, unions or interfaces. # The default value is: YES. ALPHABETICAL_INDEX = YES # The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in # which the alphabetical index list will be split. # Minimum value: 1, maximum value: 20, default value: 5. # This tag requires that the tag ALPHABETICAL_INDEX is set to YES. COLS_IN_ALPHA_INDEX = 5 # In case all classes in a project start with a common prefix, all classes will # be put under the same header in the alphabetical index. The IGNORE_PREFIX tag # can be used to specify a prefix (or a list of prefixes) that should be ignored # while generating the index headers. # This tag requires that the tag ALPHABETICAL_INDEX is set to YES. IGNORE_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output # The default value is: YES. GENERATE_HTML = YES # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a # relative path is entered the value of OUTPUT_DIRECTORY will be put in front of # it. # The default directory is: html. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_OUTPUT = html # The HTML_FILE_EXTENSION tag can be used to specify the file extension for each # generated HTML page (for example: .htm, .php, .asp). # The default value is: .html. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a user-defined HTML header file for # each generated HTML page. If the tag is left blank doxygen will generate a # standard header. # # To get valid HTML the header file that includes any scripts and style sheets # that doxygen needs, which is dependent on the configuration options used (e.g. # the setting GENERATE_TREEVIEW). It is highly recommended to start with a # default header using # doxygen -w html new_header.html new_footer.html new_stylesheet.css # YourConfigFile # and then modify the file new_header.html. See also section "Doxygen usage" # for information on how to generate the default header that doxygen normally # uses. # Note: The header is subject to change so you typically have to regenerate the # default header when upgrading to a newer version of doxygen. For a description # of the possible markers and block names see the documentation. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_HEADER = # The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each # generated HTML page. If the tag is left blank doxygen will generate a standard # footer. See HTML_HEADER for more information on how to generate a default # footer and what special commands can be used inside the footer. See also # section "Doxygen usage" for information on how to generate the default footer # that doxygen normally uses. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_FOOTER = # The HTML_STYLESHEET tag can be used to specify a user-defined cascading style # sheet that is used by each HTML page. It can be used to fine-tune the look of # the HTML output. If left blank doxygen will generate a default style sheet. # See also section "Doxygen usage" for information on how to generate the style # sheet that doxygen normally uses. # Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as # it is more robust and this tag (HTML_STYLESHEET) will in the future become # obsolete. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_STYLESHEET = # The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined # cascading style sheets that are included after the standard style sheets # created by doxygen. Using this option one can overrule certain style aspects. # This is preferred over using HTML_STYLESHEET since it does not replace the # standard style sheet and is therefore more robust against future updates. # Doxygen will copy the style sheet files to the output directory. # Note: The order of the extra style sheet files is of importance (e.g. the last # style sheet in the list overrules the setting of the previous ones in the # list). For an example see the documentation. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_EXTRA_STYLESHEET = # The HTML_EXTRA_FILES tag can be used to specify one or more extra images or # other source files which should be copied to the HTML output directory. Note # that these files will be copied to the base HTML output directory. Use the # $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these # files. In the HTML_STYLESHEET file, use the file name only. Also note that the # files will be copied as-is; there are no commands or markers available. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_EXTRA_FILES = # The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen # will adjust the colors in the style sheet and background images according to # this color. Hue is specified as an angle on a colorwheel, see # http://en.wikipedia.org/wiki/Hue for more information. For instance the value # 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 # purple, and 360 is red again. # Minimum value: 0, maximum value: 359, default value: 220. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_COLORSTYLE_HUE = 220 # The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors # in the HTML output. For a value of 0 the output will use grayscales only. A # value of 255 will produce the most vivid colors. # Minimum value: 0, maximum value: 255, default value: 100. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_COLORSTYLE_SAT = 100 # The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the # luminance component of the colors in the HTML output. Values below 100 # gradually make the output lighter, whereas values above 100 make the output # darker. The value divided by 100 is the actual gamma applied, so 80 represents # a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not # change the gamma. # Minimum value: 40, maximum value: 240, default value: 80. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_COLORSTYLE_GAMMA = 80 # If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML # page will contain the date and time when the page was generated. Setting this # to YES can help to show when doxygen was last run and thus if the # documentation is up to date. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_TIMESTAMP = NO # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the # page has loaded. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_DYNAMIC_SECTIONS = YES # With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries # shown in the various tree structured indices initially; the user can expand # and collapse entries dynamically later on. Doxygen will expand the tree to # such a level that at most the specified number of entries are visible (unless # a fully collapsed tree already exceeds this amount). So setting the number of # entries 1 will produce a full collapsed tree by default. 0 is a special value # representing an infinite number of entries and will result in a full expanded # tree by default. # Minimum value: 0, maximum value: 9999, default value: 100. # This tag requires that the tag GENERATE_HTML is set to YES. HTML_INDEX_NUM_ENTRIES = 100 # If the GENERATE_DOCSET tag is set to YES, additional index files will be # generated that can be used as input for Apple's Xcode 3 integrated development # environment (see: http://developer.apple.com/tools/xcode/), introduced with # OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a # Makefile in the HTML output directory. Running make will produce the docset in # that directory and running make install will install the docset in # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at # startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html # for more information. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_DOCSET = NO # This tag determines the name of the docset feed. A documentation feed provides # an umbrella under which multiple documentation sets from a single provider # (such as a company or product suite) can be grouped. # The default value is: Doxygen generated docs. # This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_FEEDNAME = "Doxygen generated docs" # This tag specifies a string that should uniquely identify the documentation # set bundle. This should be a reverse domain-name style string, e.g. # com.mycompany.MyDocSet. Doxygen will append .docset to the name. # The default value is: org.doxygen.Project. # This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_BUNDLE_ID = org.doxygen.Project # The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify # the documentation publisher. This should be a reverse domain-name style # string, e.g. com.mycompany.MyDocSet.documentation. # The default value is: org.doxygen.Publisher. # This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_PUBLISHER_ID = org.doxygen.Publisher # The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. # The default value is: Publisher. # This tag requires that the tag GENERATE_DOCSET is set to YES. DOCSET_PUBLISHER_NAME = Publisher # If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three # additional HTML index files: index.hhp, index.hhc, and index.hhk. The # index.hhp is a project file that can be read by Microsoft's HTML Help Workshop # (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on # Windows. # # The HTML Help Workshop contains a compiler that can convert all HTML output # generated by doxygen into a single compiled HTML file (.chm). Compiled HTML # files are now used as the Windows 98 help format, and will replace the old # Windows help format (.hlp) on all Windows platforms in the future. Compressed # HTML files also contain an index, a table of contents, and you can search for # words in the documentation. The HTML workshop also contains a viewer for # compressed HTML files. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_HTMLHELP = NO # The CHM_FILE tag can be used to specify the file name of the resulting .chm # file. You can add a path in front of the file if the result should not be # written to the html output directory. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. CHM_FILE = # The HHC_LOCATION tag can be used to specify the location (absolute path # including file name) of the HTML help compiler (hhc.exe). If non-empty, # doxygen will try to run the HTML help compiler on the generated index.hhp. # The file has to be specified with full path. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. HHC_LOCATION = # The GENERATE_CHI flag controls if a separate .chi index file is generated # (YES) or that it should be included in the master .chm file (NO). # The default value is: NO. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. GENERATE_CHI = NO # The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc) # and project file content. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. CHM_INDEX_ENCODING = # The BINARY_TOC flag controls whether a binary table of contents is generated # (YES) or a normal table of contents (NO) in the .chm file. Furthermore it # enables the Previous and Next buttons. # The default value is: NO. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members to # the table of contents of the HTML help documentation and to the tree view. # The default value is: NO. # This tag requires that the tag GENERATE_HTMLHELP is set to YES. TOC_EXPAND = NO # If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and # QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that # can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help # (.qch) of the generated HTML documentation. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_QHP = NO # If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify # the file name of the resulting .qch file. The path specified is relative to # the HTML output folder. # This tag requires that the tag GENERATE_QHP is set to YES. QCH_FILE = # The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help # Project output. For more information please see Qt Help Project / Namespace # (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace). # The default value is: org.doxygen.Project. # This tag requires that the tag GENERATE_QHP is set to YES. QHP_NAMESPACE = org.doxygen.Project # The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt # Help Project output. For more information please see Qt Help Project / Virtual # Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual- # folders). # The default value is: doc. # This tag requires that the tag GENERATE_QHP is set to YES. QHP_VIRTUAL_FOLDER = doc # If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom # filter to add. For more information please see Qt Help Project / Custom # Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- # filters). # This tag requires that the tag GENERATE_QHP is set to YES. QHP_CUST_FILTER_NAME = # The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the # custom filter to add. For more information please see Qt Help Project / Custom # Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- # filters). # This tag requires that the tag GENERATE_QHP is set to YES. QHP_CUST_FILTER_ATTRS = # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this # project's filter section matches. Qt Help Project / Filter Attributes (see: # http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes). # This tag requires that the tag GENERATE_QHP is set to YES. QHP_SECT_FILTER_ATTRS = # The QHG_LOCATION tag can be used to specify the location of Qt's # qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the # generated .qhp file. # This tag requires that the tag GENERATE_QHP is set to YES. QHG_LOCATION = # If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be # generated, together with the HTML files, they form an Eclipse help plugin. To # install this plugin and make it available under the help contents menu in # Eclipse, the contents of the directory containing the HTML and XML files needs # to be copied into the plugins directory of eclipse. The name of the directory # within the plugins directory should be the same as the ECLIPSE_DOC_ID value. # After copying Eclipse needs to be restarted before the help appears. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_ECLIPSEHELP = NO # A unique identifier for the Eclipse help plugin. When installing the plugin # the directory name containing the HTML and XML files should also have this # name. Each documentation set should have its own identifier. # The default value is: org.doxygen.Project. # This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES. ECLIPSE_DOC_ID = org.doxygen.Project # If you want full control over the layout of the generated HTML pages it might # be necessary to disable the index and replace it with your own. The # DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top # of each HTML page. A value of NO enables the index and the value YES disables # it. Since the tabs in the index contain the same information as the navigation # tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. DISABLE_INDEX = YES # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index # structure should be generated to display hierarchical information. If the tag # value is set to YES, a side panel will be generated containing a tree-like # index structure (just like the one that is generated for HTML Help). For this # to work a browser that supports JavaScript, DHTML, CSS and frames is required # (i.e. any modern browser). Windows users are probably better off using the # HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can # further fine-tune the look of the index. As an example, the default style # sheet generated by doxygen has an example that shows how to put an image at # the root of the tree instead of the PROJECT_NAME. Since the tree basically has # the same information as the tab index, you could consider setting # DISABLE_INDEX to YES when enabling this option. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. GENERATE_TREEVIEW = YES # The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that # doxygen will group on one line in the generated HTML documentation. # # Note that a value of 0 will completely suppress the enum values from appearing # in the overview section. # Minimum value: 0, maximum value: 20, default value: 4. # This tag requires that the tag GENERATE_HTML is set to YES. ENUM_VALUES_PER_LINE = 4 # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used # to set the initial width (in pixels) of the frame in which the tree is shown. # Minimum value: 0, maximum value: 1500, default value: 250. # This tag requires that the tag GENERATE_HTML is set to YES. TREEVIEW_WIDTH = 250 # If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to # external symbols imported via tag files in a separate window. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. EXT_LINKS_IN_WINDOW = NO # Use this tag to change the font size of LaTeX formulas included as images in # the HTML documentation. When you change the font size after a successful # doxygen run you need to manually remove any form_*.png images from the HTML # output directory to force them to be regenerated. # Minimum value: 8, maximum value: 50, default value: 10. # This tag requires that the tag GENERATE_HTML is set to YES. FORMULA_FONTSIZE = 10 # Use the FORMULA_TRANPARENT tag to determine whether or not the images # generated for formulas are transparent PNGs. Transparent PNGs are not # supported properly for IE 6.0, but are supported on all modern browsers. # # Note that when changing this option you need to delete any form_*.png files in # the HTML output directory before the changes have effect. # The default value is: YES. # This tag requires that the tag GENERATE_HTML is set to YES. FORMULA_TRANSPARENT = YES # Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see # http://www.mathjax.org) which uses client side Javascript for the rendering # instead of using pre-rendered bitmaps. Use this if you do not have LaTeX # installed or if you want to formulas look prettier in the HTML output. When # enabled you may also need to install MathJax separately and configure the path # to it using the MATHJAX_RELPATH option. # The default value is: NO. # This tag requires that the tag GENERATE_HTML is set to YES. USE_MATHJAX = NO # When MathJax is enabled you can set the default output format to be used for # the MathJax output. See the MathJax site (see: # http://docs.mathjax.org/en/latest/output.html) for more details. # Possible values are: HTML-CSS (which is slower, but has the best # compatibility), NativeMML (i.e. MathML) and SVG. # The default value is: HTML-CSS. # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_FORMAT = HTML-CSS # When MathJax is enabled you need to specify the location relative to the HTML # output directory using the MATHJAX_RELPATH option. The destination directory # should contain the MathJax.js script. For instance, if the mathjax directory # is located at the same level as the HTML output directory, then # MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax # Content Delivery Network so you can quickly see the result without installing # MathJax. However, it is strongly recommended to install a local copy of # MathJax from http://www.mathjax.org before deployment. # The default value is: http://cdn.mathjax.org/mathjax/latest. # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest # The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax # extension names that should be enabled during MathJax rendering. For example # MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_EXTENSIONS = # The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces # of code that will be used on startup of the MathJax code. See the MathJax site # (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an # example see the documentation. # This tag requires that the tag USE_MATHJAX is set to YES. MATHJAX_CODEFILE = # When the SEARCHENGINE tag is enabled doxygen will generate a search box for # the HTML output. The underlying search engine uses javascript and DHTML and # should work on any modern browser. Note that when using HTML help # (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) # there is already a search function so this one should typically be disabled. # For large projects the javascript based search engine can be slow, then # enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to # search using the keyboard; to jump to the search box use + S # (what the is depends on the OS and browser, but it is typically # , /