Update Iot.js
authorSumin Lim <sumin.lim@samsung.com>
Fri, 7 Apr 2017 04:59:07 +0000 (13:59 +0900)
committerSumin Lim <sumin.lim@samsung.com>
Fri, 7 Apr 2017 04:59:07 +0000 (13:59 +0900)
721 files changed:
CMakeLists.txt [new file with mode: 0644]
LICENSE [new file with mode: 0644]
README.md [new file with mode: 0644]
build.config [new file with mode: 0644]
cmake/config/arm-linux.cmake [new file with mode: 0644]
cmake/config/arm-nuttx.cmake [new file with mode: 0644]
cmake/config/arm-tizen.cmake [new file with mode: 0644]
cmake/config/arm-tizenrt.cmake [new file with mode: 0644]
cmake/config/i686-linux.cmake [new file with mode: 0644]
cmake/config/x86_64-darwin.cmake [new file with mode: 0644]
cmake/config/x86_64-linux.cmake [new file with mode: 0644]
cmake/http-parser.cmake [new file with mode: 0644]
cmake/iotjs.cmake [new file with mode: 0644]
cmake/jerry.cmake [new file with mode: 0644]
cmake/libtuv.cmake [new file with mode: 0644]
docs/License.md [new file with mode: 0644]
docs/README.md [new file with mode: 0644]
docs/api/IoT.js-API-ADC.md [new file with mode: 0644]
docs/api/IoT.js-API-Assert.md [new file with mode: 0644]
docs/api/IoT.js-API-BLE.md [new file with mode: 0644]
docs/api/IoT.js-API-Buffer.md [new file with mode: 0644]
docs/api/IoT.js-API-DGRAM.md [new file with mode: 0644]
docs/api/IoT.js-API-DNS.md [new file with mode: 0644]
docs/api/IoT.js-API-Events.md [new file with mode: 0644]
docs/api/IoT.js-API-File-System.md [new file with mode: 0644]
docs/api/IoT.js-API-GPIO.md [new file with mode: 0644]
docs/api/IoT.js-API-HTTP.md [new file with mode: 0644]
docs/api/IoT.js-API-I2C.md [new file with mode: 0644]
docs/api/IoT.js-API-Module.md [new file with mode: 0644]
docs/api/IoT.js-API-Net.md [new file with mode: 0644]
docs/api/IoT.js-API-PWM.md [new file with mode: 0644]
docs/api/IoT.js-API-Process.md [new file with mode: 0644]
docs/api/IoT.js-API-SPI.md [new file with mode: 0644]
docs/api/IoT.js-API-Stream.md [new file with mode: 0644]
docs/api/IoT.js-API-Timers.md [new file with mode: 0644]
docs/api/IoT.js-API-UART.md [new file with mode: 0644]
docs/api/IoT.js-API-reference.md [new file with mode: 0644]
docs/build/Build-Script.md [new file with mode: 0644]
docs/build/Build-for-ARTIK.md [new file with mode: 0644]
docs/build/Build-for-Linux.md [new file with mode: 0644]
docs/build/Build-for-NuttX.md [new file with mode: 0644]
docs/build/Build-for-RPi2.md [new file with mode: 0644]
docs/devs/Enabling-Experimental-Feature.md [new file with mode: 0644]
docs/devs/Inside-IoT.js-Validated-Struct.md [new file with mode: 0644]
docs/devs/Inside-IoT.js.md [new file with mode: 0644]
docs/devs/IoT.js-Package-(outdated).md [new file with mode: 0644]
docs/devs/Logging-IoT.js-execution.md [new file with mode: 0644]
docs/devs/Memory-savings-with-libtuv.md [new file with mode: 0644]
docs/devs/Optimization-Tips.md [new file with mode: 0644]
docs/devs/Writing-New-Builtin-Module.md [new file with mode: 0644]
docs/help/Assigned-people.md [new file with mode: 0644]
docs/help/Coding-Style-Guideline.md [new file with mode: 0644]
docs/help/Community-Guidelines.md [new file with mode: 0644]
docs/help/Developer's-Guide.md [new file with mode: 0644]
docs/help/Developer-Tutorial.md [new file with mode: 0644]
docs/help/Development-Process.md [new file with mode: 0644]
docs/help/Extended-API-Guideline.md [new file with mode: 0644]
docs/help/Getting-Started.md [new file with mode: 0644]
docs/help/Getting-involved.md [new file with mode: 0644]
docs/help/Governance.md [new file with mode: 0644]
docs/help/IoT.js-Developer's-Certificate-of-Origin-1.0.md [new file with mode: 0644]
docs/help/Patch-Submission-Process.md [new file with mode: 0644]
include/iotjs.h [new file with mode: 0644]
iotjs_linux.c [new file with mode: 0644]
src/iotjs.c [new file with mode: 0644]
src/iotjs_binding.c [new file with mode: 0644]
src/iotjs_binding.h [new file with mode: 0644]
src/iotjs_binding_helper.c [new file with mode: 0644]
src/iotjs_binding_helper.h [new file with mode: 0644]
src/iotjs_debuglog.c [new file with mode: 0644]
src/iotjs_debuglog.h [new file with mode: 0644]
src/iotjs_def.h [new file with mode: 0644]
src/iotjs_env.c [new file with mode: 0644]
src/iotjs_env.h [new file with mode: 0644]
src/iotjs_exception.c [new file with mode: 0644]
src/iotjs_exception.h [new file with mode: 0644]
src/iotjs_handlewrap.c [new file with mode: 0644]
src/iotjs_handlewrap.h [new file with mode: 0644]
src/iotjs_magic_strings.h [new file with mode: 0644]
src/iotjs_module.c [new file with mode: 0644]
src/iotjs_module.h [new file with mode: 0644]
src/iotjs_objectwrap.c [new file with mode: 0644]
src/iotjs_objectwrap.h [new file with mode: 0644]
src/iotjs_reqwrap.c [new file with mode: 0644]
src/iotjs_reqwrap.h [new file with mode: 0644]
src/iotjs_string.c [new file with mode: 0644]
src/iotjs_string.h [new file with mode: 0644]
src/iotjs_string_ext.c [new file with mode: 0644]
src/iotjs_string_ext.h [new file with mode: 0644]
src/iotjs_util.c [new file with mode: 0644]
src/iotjs_util.h [new file with mode: 0644]
src/js/adc.js [new file with mode: 0644]
src/js/assert.js [new file with mode: 0644]
src/js/ble.js [new file with mode: 0644]
src/js/ble_characteristic.js [new file with mode: 0644]
src/js/ble_descriptor.js [new file with mode: 0644]
src/js/ble_hci_socket.js [new file with mode: 0644]
src/js/ble_hci_socket_acl_stream.js [new file with mode: 0644]
src/js/ble_hci_socket_bindings.js [new file with mode: 0644]
src/js/ble_hci_socket_crypto.js [new file with mode: 0644]
src/js/ble_hci_socket_gap.js [new file with mode: 0644]
src/js/ble_hci_socket_gatt.js [new file with mode: 0644]
src/js/ble_hci_socket_hci.js [new file with mode: 0644]
src/js/ble_hci_socket_hci_status.js [new file with mode: 0644]
src/js/ble_hci_socket_mgmt.js [new file with mode: 0644]
src/js/ble_hci_socket_smp.js [new file with mode: 0644]
src/js/ble_primary_service.js [new file with mode: 0644]
src/js/ble_uuid_util.js [new file with mode: 0644]
src/js/buffer.js [new file with mode: 0644]
src/js/console.js [new file with mode: 0644]
src/js/constants.js [new file with mode: 0644]
src/js/dgram.js [new file with mode: 0644]
src/js/dns.js [new file with mode: 0644]
src/js/events.js [new file with mode: 0644]
src/js/fs.js [new file with mode: 0644]
src/js/gpio.js [new file with mode: 0644]
src/js/http.js [new file with mode: 0644]
src/js/http_client.js [new file with mode: 0644]
src/js/http_common.js [new file with mode: 0644]
src/js/http_incoming.js [new file with mode: 0644]
src/js/http_outgoing.js [new file with mode: 0644]
src/js/http_server.js [new file with mode: 0644]
src/js/i2c.js [new file with mode: 0644]
src/js/iotjs.js [new file with mode: 0644]
src/js/module.js [new file with mode: 0644]
src/js/net.js [new file with mode: 0644]
src/js/pwm.js [new file with mode: 0644]
src/js/spi.js [new file with mode: 0644]
src/js/stm32f4dis.js [new file with mode: 0644]
src/js/stream.js [new file with mode: 0644]
src/js/stream_duplex.js [new file with mode: 0644]
src/js/stream_readable.js [new file with mode: 0644]
src/js/stream_writable.js [new file with mode: 0644]
src/js/testdriver.js [new file with mode: 0644]
src/js/timers.js [new file with mode: 0644]
src/js/uart.js [new file with mode: 0644]
src/js/util.js [new file with mode: 0644]
src/module/iotjs_module_adc.c [new file with mode: 0644]
src/module/iotjs_module_adc.h [new file with mode: 0644]
src/module/iotjs_module_blehcisocket.c [new file with mode: 0644]
src/module/iotjs_module_blehcisocket.h [new file with mode: 0644]
src/module/iotjs_module_buffer.c [new file with mode: 0644]
src/module/iotjs_module_buffer.h [new file with mode: 0644]
src/module/iotjs_module_console.c [new file with mode: 0644]
src/module/iotjs_module_constants.c [new file with mode: 0644]
src/module/iotjs_module_dns.c [new file with mode: 0644]
src/module/iotjs_module_dns.h [new file with mode: 0644]
src/module/iotjs_module_fs.c [new file with mode: 0644]
src/module/iotjs_module_fs.h [new file with mode: 0644]
src/module/iotjs_module_gpio.c [new file with mode: 0644]
src/module/iotjs_module_gpio.h [new file with mode: 0644]
src/module/iotjs_module_httpparser.c [new file with mode: 0644]
src/module/iotjs_module_httpparser.h [new file with mode: 0644]
src/module/iotjs_module_i2c.c [new file with mode: 0644]
src/module/iotjs_module_i2c.h [new file with mode: 0644]
src/module/iotjs_module_process.c [new file with mode: 0644]
src/module/iotjs_module_pwm.c [new file with mode: 0644]
src/module/iotjs_module_pwm.h [new file with mode: 0644]
src/module/iotjs_module_spi.c [new file with mode: 0644]
src/module/iotjs_module_spi.h [new file with mode: 0644]
src/module/iotjs_module_stm32f4dis.c [new file with mode: 0644]
src/module/iotjs_module_stm32f4dis.h [new file with mode: 0644]
src/module/iotjs_module_tcp.c [new file with mode: 0644]
src/module/iotjs_module_tcp.h [new file with mode: 0644]
src/module/iotjs_module_testdriver.c [new file with mode: 0644]
src/module/iotjs_module_timer.c [new file with mode: 0644]
src/module/iotjs_module_timer.h [new file with mode: 0644]
src/module/iotjs_module_uart.c [new file with mode: 0644]
src/module/iotjs_module_uart.h [new file with mode: 0644]
src/module/iotjs_module_udp.c [new file with mode: 0644]
src/module/iotjs_module_udp.h [new file with mode: 0644]
src/platform/arm-linux/iotjs_module_adc-arm-linux.c [new file with mode: 0644]
src/platform/arm-linux/iotjs_module_blehcisocket-arm-linux.c [new file with mode: 0644]
src/platform/arm-linux/iotjs_module_gpio-arm-linux.c [new file with mode: 0644]
src/platform/arm-linux/iotjs_module_i2c-arm-linux.c [new file with mode: 0644]
src/platform/arm-linux/iotjs_module_pwm-arm-linux.c [new file with mode: 0644]
src/platform/arm-linux/iotjs_module_spi-arm-linux.c [new file with mode: 0644]
src/platform/arm-linux/iotjs_module_uart-arm-linux.c [new file with mode: 0644]
src/platform/arm-nuttx/iotjs_module_adc-arm-nuttx.c [new file with mode: 0644]
src/platform/arm-nuttx/iotjs_module_blehcisocket-arm-nuttx.c [new file with mode: 0644]
src/platform/arm-nuttx/iotjs_module_gpio-arm-nuttx-general.inl.h [new file with mode: 0644]
src/platform/arm-nuttx/iotjs_module_gpio-arm-nuttx-stm32.inl.h [new file with mode: 0644]
src/platform/arm-nuttx/iotjs_module_gpio-arm-nuttx.c [new file with mode: 0644]
src/platform/arm-nuttx/iotjs_module_i2c-arm-nuttx.c [new file with mode: 0644]
src/platform/arm-nuttx/iotjs_module_pwm-arm-nuttx.c [new file with mode: 0644]
src/platform/arm-nuttx/iotjs_module_spi-arm-nuttx.c [new file with mode: 0644]
src/platform/arm-nuttx/iotjs_module_stm32f4dis-arm-nuttx.c [new file with mode: 0644]
src/platform/arm-nuttx/iotjs_module_uart-arm-nuttx.c [new file with mode: 0644]
src/platform/arm-nuttx/iotjs_systemio-arm-nuttx-stm32.c [new file with mode: 0644]
src/platform/arm-nuttx/iotjs_systemio-arm-nuttx.h [new file with mode: 0644]
src/platform/i686-linux/iotjs_module_adc-i686-linux.c [new file with mode: 0644]
src/platform/i686-linux/iotjs_module_blehcisocket-i686-linux.c [new file with mode: 0644]
src/platform/i686-linux/iotjs_module_gpio-i686-linux.c [new file with mode: 0644]
src/platform/i686-linux/iotjs_module_i2c-i686-linux.c [new file with mode: 0644]
src/platform/i686-linux/iotjs_module_pwm-i686-linux.c [new file with mode: 0644]
src/platform/i686-linux/iotjs_module_spi-i686-linux.c [new file with mode: 0644]
src/platform/i686-linux/iotjs_module_uart-i686-linux.c [new file with mode: 0644]
src/platform/iotjs_module_adc-linux-general.inl.h [new file with mode: 0644]
src/platform/iotjs_module_blehcisocket-linux-general.inl.h [new file with mode: 0644]
src/platform/iotjs_module_gpio-linux-general.inl.h [new file with mode: 0644]
src/platform/iotjs_module_i2c-linux-general.inl.h [new file with mode: 0644]
src/platform/iotjs_module_pwm-linux-general.inl.h [new file with mode: 0644]
src/platform/iotjs_module_spi-linux-general.inl.h [new file with mode: 0644]
src/platform/iotjs_module_uart-linux-general.inl.h [new file with mode: 0644]
src/platform/iotjs_systemio-linux.c [new file with mode: 0644]
src/platform/iotjs_systemio-linux.h [new file with mode: 0644]
src/platform/x86_64-darwin/iotjs_module_adc-x86_64-darwin.c [new file with mode: 0644]
src/platform/x86_64-darwin/iotjs_module_blehcisocket-x86_64-darwin.c [new file with mode: 0644]
src/platform/x86_64-darwin/iotjs_module_gpio-x86_64-darwin.c [new file with mode: 0644]
src/platform/x86_64-darwin/iotjs_module_i2c-x86_64-darwin.c [new file with mode: 0644]
src/platform/x86_64-darwin/iotjs_module_pwm-x86_64-darwin.c [new file with mode: 0644]
src/platform/x86_64-darwin/iotjs_module_spi-x86_64-darwin.c [new file with mode: 0644]
src/platform/x86_64-darwin/iotjs_module_uart-x86_64-darwin.c [new file with mode: 0644]
src/platform/x86_64-darwin/iotjs_module_unimplemented.inl.h [new file with mode: 0644]
src/platform/x86_64-linux/iotjs_module_adc-x86_64-linux.c [new file with mode: 0644]
src/platform/x86_64-linux/iotjs_module_blehcisocket-x86_64-linux.c [new file with mode: 0644]
src/platform/x86_64-linux/iotjs_module_gpio-x86_64-linux.c [new file with mode: 0644]
src/platform/x86_64-linux/iotjs_module_i2c-x86_64-linux.c [new file with mode: 0644]
src/platform/x86_64-linux/iotjs_module_pwm-x86_64-linux.c [new file with mode: 0644]
src/platform/x86_64-linux/iotjs_module_spi-x86_64-linux.c [new file with mode: 0644]
src/platform/x86_64-linux/iotjs_module_uart-x86_64-linux.c [new file with mode: 0644]
targets/nuttx-stm32f4/README.md [new file with mode: 0644]
targets/nuttx-stm32f4/Stm32f4dis.md [new file with mode: 0644]
targets/nuttx-stm32f4/app/Kconfig [new file with mode: 0644]
targets/nuttx-stm32f4/app/Make.defs [new file with mode: 0644]
targets/nuttx-stm32f4/app/Makefile [new file with mode: 0644]
targets/nuttx-stm32f4/app/iotjs_main.cxx [new file with mode: 0644]
targets/nuttx-stm32f4/nuttx/.config.default [new file with mode: 0644]
targets/nuttx-stm32f4/nuttx/.config.travis [new file with mode: 0644]
targets/nuttx-stm32f4/nuttx/patch [new file with mode: 0644]
targets/tizenrt-artik05x/app/README.md [new file with mode: 0644]
targets/tizenrt-artik05x/app/iotjs/.gitignore [new file with mode: 0644]
targets/tizenrt-artik05x/app/iotjs/Kconfig [new file with mode: 0644]
targets/tizenrt-artik05x/app/iotjs/Kconfig_ENTRY [new file with mode: 0644]
targets/tizenrt-artik05x/app/iotjs/Make.defs [new file with mode: 0644]
targets/tizenrt-artik05x/app/iotjs/Makefile [new file with mode: 0644]
targets/tizenrt-artik05x/app/iotjs/iotjs_main.c [new file with mode: 0644]
test/resources/greeting.txt [new file with mode: 0644]
test/resources/readdir/DO_NOT_MODIFY_THIS_FOLDER [new file with mode: 0644]
test/resources/readdir/This_is_a_directory/.gitkeep [new file with mode: 0644]
test/resources/readdir/This_is_another_directory/.gitkeep [new file with mode: 0644]
test/resources/readdir/regular.txt [new file with mode: 0644]
test/resources/rename.txt [new file with mode: 0644]
test/resources/test1.txt [new file with mode: 0644]
test/resources/test_console_stdout.txt [new file with mode: 0644]
test/resources/tobeornottobe.txt [new file with mode: 0644]
test/run_fail/assert_fail1.js [new file with mode: 0644]
test/run_fail/assert_fail2.js [new file with mode: 0644]
test/run_fail/assert_fail3.js [new file with mode: 0644]
test/run_fail/fs_callbacks_called.js [new file with mode: 0644]
test/run_fail/process_exit1.js [new file with mode: 0644]
test/run_fail/process_exit2.js [new file with mode: 0644]
test/run_fail/process_exitcode1.js [new file with mode: 0644]
test/run_fail/process_exitcode2.js [new file with mode: 0644]
test/run_fail/require_fail1.js [new file with mode: 0644]
test/run_fail/runtime_error1.js [new file with mode: 0644]
test/run_fail/syntax_fail1.js [new file with mode: 0644]
test/run_fail/uncaught_error_event.js [new file with mode: 0644]
test/run_pass/issue/issue-133.js [new file with mode: 0644]
test/run_pass/issue/issue-137.js [new file with mode: 0644]
test/run_pass/issue/issue-198.js [new file with mode: 0644]
test/run_pass/issue/issue-223.js [new file with mode: 0644]
test/run_pass/issue/issue-266.js [new file with mode: 0644]
test/run_pass/issue/issue-323.js [new file with mode: 0644]
test/run_pass/require1/module_cache.js [new file with mode: 0644]
test/run_pass/require1/node_modules/test_index/add2.js [new file with mode: 0644]
test/run_pass/require1/node_modules/test_index/index.js [new file with mode: 0644]
test/run_pass/require1/node_modules/test_index/lib/multi.js [new file with mode: 0644]
test/run_pass/require1/node_modules/test_index/package.json [new file with mode: 0644]
test/run_pass/require1/node_modules/test_pkg/add2.js [new file with mode: 0644]
test/run_pass/require1/node_modules/test_pkg/lib/multi.js [new file with mode: 0644]
test/run_pass/require1/node_modules/test_pkg/main.js [new file with mode: 0644]
test/run_pass/require1/node_modules/test_pkg/package.json [new file with mode: 0644]
test/run_pass/require1/package.json [new file with mode: 0644]
test/run_pass/require1/require_add.js [new file with mode: 0644]
test/run_pass/require1/test_require.js [new file with mode: 0644]
test/run_pass/test_adc.js [new file with mode: 0644]
test/run_pass/test_assert.js [new file with mode: 0644]
test/run_pass/test_ble_advertisement.js [new file with mode: 0644]
test/run_pass/test_ble_setservices.js [new file with mode: 0644]
test/run_pass/test_buffer.js [new file with mode: 0644]
test/run_pass/test_buffer_builtin.js [new file with mode: 0644]
test/run_pass/test_console.js [new file with mode: 0644]
test/run_pass/test_cwd.js [new file with mode: 0644]
test/run_pass/test_dgram_1_server_1_client.js [new file with mode: 0644]
test/run_pass/test_dgram_1_server_n_clients.js [new file with mode: 0644]
test/run_pass/test_dgram_address.js [new file with mode: 0644]
test/run_pass/test_dgram_broadcast.js [new file with mode: 0644]
test/run_pass/test_dgram_multicast_membership.js [new file with mode: 0644]
test/run_pass/test_dgram_multicast_set_multicast_loop.js [new file with mode: 0644]
test/run_pass/test_dns.js [new file with mode: 0644]
test/run_pass/test_dns_lookup.js [new file with mode: 0644]
test/run_pass/test_events.js [new file with mode: 0644]
test/run_pass/test_exit.js [new file with mode: 0644]
test/run_pass/test_experimental_off.js [new file with mode: 0644]
test/run_pass/test_experimental_on.js [new file with mode: 0644]
test/run_pass/test_fs.js [new file with mode: 0644]
test/run_pass/test_fs1.js [new file with mode: 0644]
test/run_pass/test_fs2.js [new file with mode: 0644]
test/run_pass/test_fs_exists.js [new file with mode: 0644]
test/run_pass/test_fs_existssync.js [new file with mode: 0644]
test/run_pass/test_fs_mkdir_rmdir.js [new file with mode: 0644]
test/run_pass/test_fs_open_close.js [new file with mode: 0644]
test/run_pass/test_fs_readdir.js [new file with mode: 0644]
test/run_pass/test_fs_readfile.js [new file with mode: 0644]
test/run_pass/test_fs_readfilesync.js [new file with mode: 0644]
test/run_pass/test_fs_rename.js [new file with mode: 0644]
test/run_pass/test_fs_rename_sync.js [new file with mode: 0644]
test/run_pass/test_fs_stat.js [new file with mode: 0644]
test/run_pass/test_fs_writefile_unlink.js [new file with mode: 0644]
test/run_pass/test_fs_writefile_unlink_sync.js [new file with mode: 0644]
test/run_pass/test_gpio1.js [new file with mode: 0644]
test/run_pass/test_gpio2.js [new file with mode: 0644]
test/run_pass/test_http_get.js [new file with mode: 0644]
test/run_pass/test_http_header.js [new file with mode: 0644]
test/run_pass/test_httpclient_timeout.js [new file with mode: 0644]
test/run_pass/test_httpclient_timeout2.js [new file with mode: 0644]
test/run_pass/test_httpserver.js [new file with mode: 0644]
test/run_pass/test_httpserver_timeout.js [new file with mode: 0644]
test/run_pass/test_i2c.js [new file with mode: 0644]
test/run_pass/test_module_cache.js [new file with mode: 0644]
test/run_pass/test_net1.js [new file with mode: 0644]
test/run_pass/test_net10.js [new file with mode: 0644]
test/run_pass/test_net2.js [new file with mode: 0644]
test/run_pass/test_net3.js [new file with mode: 0644]
test/run_pass/test_net4.js [new file with mode: 0644]
test/run_pass/test_net5.js [new file with mode: 0644]
test/run_pass/test_net6.js [new file with mode: 0644]
test/run_pass/test_net7.js [new file with mode: 0644]
test/run_pass/test_net8.js [new file with mode: 0644]
test/run_pass/test_net9.js [new file with mode: 0644]
test/run_pass/test_next_tick.js [new file with mode: 0644]
test/run_pass/test_process.js [new file with mode: 0644]
test/run_pass/test_pwm.js [new file with mode: 0644]
test/run_pass/test_spi.js [new file with mode: 0644]
test/run_pass/test_stream.js [new file with mode: 0644]
test/run_pass/test_timers.js [new file with mode: 0644]
test/run_pass/test_timers2.js [new file with mode: 0644]
test/run_pass/test_uart.js [new file with mode: 0644]
test/run_pass/test_uncaught1.js [new file with mode: 0644]
test/run_pass/test_uncaught2.js [new file with mode: 0644]
test/run_pass/test_uncaught_error1.js [new file with mode: 0644]
test/run_pass/test_uncaught_error2.js [new file with mode: 0644]
test/test_stat.js [new file with mode: 0644]
test/testsets.json [new file with mode: 0644]
test/tmp/README [new file with mode: 0644]
tools/CMakeLists.txt [new file with mode: 0644]
tools/LICENSE [new file with mode: 0644]
tools/README.md [new file with mode: 0644]
tools/__init__.py [new file with mode: 0644]
tools/apt-get-install-arm.sh [new file with mode: 0755]
tools/apt-get-install-deps.sh [new file with mode: 0755]
tools/apt-get-install-nuttx.sh [new file with mode: 0755]
tools/apt-get-install-tizen.sh [new file with mode: 0755]
tools/apt-get-install-travis-i686.sh [new file with mode: 0755]
tools/brew-install-deps.sh [new file with mode: 0755]
tools/build.config [new file with mode: 0644]
tools/build.py [new file with mode: 0755]
tools/check_license.py [new file with mode: 0755]
tools/check_signed_off.sh [new file with mode: 0755]
tools/check_test.js [new file with mode: 0644]
tools/check_tidy.py [new file with mode: 0755]
tools/cmake/config/arm-linux.cmake [new file with mode: 0644]
tools/cmake/config/arm-nuttx.cmake [new file with mode: 0644]
tools/cmake/config/arm-tizen.cmake [new file with mode: 0644]
tools/cmake/config/arm-tizenrt.cmake [new file with mode: 0644]
tools/cmake/config/i686-linux.cmake [new file with mode: 0644]
tools/cmake/config/x86_64-darwin.cmake [new file with mode: 0644]
tools/cmake/config/x86_64-linux.cmake [new file with mode: 0644]
tools/cmake/http-parser.cmake [new file with mode: 0644]
tools/cmake/iotjs.cmake [new file with mode: 0644]
tools/cmake/jerry.cmake [new file with mode: 0644]
tools/cmake/libtuv.cmake [new file with mode: 0644]
tools/common_js/logger.js [new file with mode: 0644]
tools/common_js/module/console.js [new file with mode: 0644]
tools/common_js/option_parser.js [new file with mode: 0644]
tools/common_js/util.js [new file with mode: 0644]
tools/common_py/__init__.py [new file with mode: 0644]
tools/common_py/path.py [new file with mode: 0644]
tools/common_py/system/__init__.py [new file with mode: 0644]
tools/common_py/system/executor.py [new file with mode: 0644]
tools/common_py/system/filesystem.py [new file with mode: 0644]
tools/common_py/system/platform.py [new file with mode: 0644]
tools/docs/License.md [new file with mode: 0644]
tools/docs/README.md [new file with mode: 0644]
tools/docs/api/IoT.js-API-ADC.md [new file with mode: 0644]
tools/docs/api/IoT.js-API-Assert.md [new file with mode: 0644]
tools/docs/api/IoT.js-API-BLE.md [new file with mode: 0644]
tools/docs/api/IoT.js-API-Buffer.md [new file with mode: 0644]
tools/docs/api/IoT.js-API-DGRAM.md [new file with mode: 0644]
tools/docs/api/IoT.js-API-DNS.md [new file with mode: 0644]
tools/docs/api/IoT.js-API-Events.md [new file with mode: 0644]
tools/docs/api/IoT.js-API-File-System.md [new file with mode: 0644]
tools/docs/api/IoT.js-API-GPIO.md [new file with mode: 0644]
tools/docs/api/IoT.js-API-HTTP.md [new file with mode: 0644]
tools/docs/api/IoT.js-API-I2C.md [new file with mode: 0644]
tools/docs/api/IoT.js-API-Module.md [new file with mode: 0644]
tools/docs/api/IoT.js-API-Net.md [new file with mode: 0644]
tools/docs/api/IoT.js-API-PWM.md [new file with mode: 0644]
tools/docs/api/IoT.js-API-Process.md [new file with mode: 0644]
tools/docs/api/IoT.js-API-SPI.md [new file with mode: 0644]
tools/docs/api/IoT.js-API-Stream.md [new file with mode: 0644]
tools/docs/api/IoT.js-API-Timers.md [new file with mode: 0644]
tools/docs/api/IoT.js-API-UART.md [new file with mode: 0644]
tools/docs/api/IoT.js-API-reference.md [new file with mode: 0644]
tools/docs/build/Build-Script.md [new file with mode: 0644]
tools/docs/build/Build-for-ARTIK.md [new file with mode: 0644]
tools/docs/build/Build-for-Linux.md [new file with mode: 0644]
tools/docs/build/Build-for-NuttX.md [new file with mode: 0644]
tools/docs/build/Build-for-RPi2.md [new file with mode: 0644]
tools/docs/devs/Enabling-Experimental-Feature.md [new file with mode: 0644]
tools/docs/devs/Inside-IoT.js-Validated-Struct.md [new file with mode: 0644]
tools/docs/devs/Inside-IoT.js.md [new file with mode: 0644]
tools/docs/devs/IoT.js-Package-(outdated).md [new file with mode: 0644]
tools/docs/devs/Logging-IoT.js-execution.md [new file with mode: 0644]
tools/docs/devs/Memory-savings-with-libtuv.md [new file with mode: 0644]
tools/docs/devs/Optimization-Tips.md [new file with mode: 0644]
tools/docs/devs/Writing-New-Builtin-Module.md [new file with mode: 0644]
tools/docs/help/Assigned-people.md [new file with mode: 0644]
tools/docs/help/Coding-Style-Guideline.md [new file with mode: 0644]
tools/docs/help/Community-Guidelines.md [new file with mode: 0644]
tools/docs/help/Developer's-Guide.md [new file with mode: 0644]
tools/docs/help/Developer-Tutorial.md [new file with mode: 0644]
tools/docs/help/Development-Process.md [new file with mode: 0644]
tools/docs/help/Extended-API-Guideline.md [new file with mode: 0644]
tools/docs/help/Getting-Started.md [new file with mode: 0644]
tools/docs/help/Getting-involved.md [new file with mode: 0644]
tools/docs/help/Governance.md [new file with mode: 0644]
tools/docs/help/IoT.js-Developer's-Certificate-of-Origin-1.0.md [new file with mode: 0644]
tools/docs/help/Patch-Submission-Process.md [new file with mode: 0644]
tools/include/iotjs.h [new file with mode: 0644]
tools/iotjs_linux.c [new file with mode: 0644]
tools/js2c.py [new file with mode: 0755]
tools/measure_coverage.sh [new file with mode: 0755]
tools/mem_stats.sh [new file with mode: 0755]
tools/module_analyzer.py [new file with mode: 0644]
tools/precommit.py [new file with mode: 0755]
tools/src/iotjs.c [new file with mode: 0644]
tools/src/iotjs_binding.c [new file with mode: 0644]
tools/src/iotjs_binding.h [new file with mode: 0644]
tools/src/iotjs_binding_helper.c [new file with mode: 0644]
tools/src/iotjs_binding_helper.h [new file with mode: 0644]
tools/src/iotjs_debuglog.c [new file with mode: 0644]
tools/src/iotjs_debuglog.h [new file with mode: 0644]
tools/src/iotjs_def.h [new file with mode: 0644]
tools/src/iotjs_env.c [new file with mode: 0644]
tools/src/iotjs_env.h [new file with mode: 0644]
tools/src/iotjs_exception.c [new file with mode: 0644]
tools/src/iotjs_exception.h [new file with mode: 0644]
tools/src/iotjs_handlewrap.c [new file with mode: 0644]
tools/src/iotjs_handlewrap.h [new file with mode: 0644]
tools/src/iotjs_magic_strings.h [new file with mode: 0644]
tools/src/iotjs_module.c [new file with mode: 0644]
tools/src/iotjs_module.h [new file with mode: 0644]
tools/src/iotjs_objectwrap.c [new file with mode: 0644]
tools/src/iotjs_objectwrap.h [new file with mode: 0644]
tools/src/iotjs_reqwrap.c [new file with mode: 0644]
tools/src/iotjs_reqwrap.h [new file with mode: 0644]
tools/src/iotjs_string.c [new file with mode: 0644]
tools/src/iotjs_string.h [new file with mode: 0644]
tools/src/iotjs_string_ext.c [new file with mode: 0644]
tools/src/iotjs_string_ext.h [new file with mode: 0644]
tools/src/iotjs_util.c [new file with mode: 0644]
tools/src/iotjs_util.h [new file with mode: 0644]
tools/src/js/adc.js [new file with mode: 0644]
tools/src/js/assert.js [new file with mode: 0644]
tools/src/js/ble.js [new file with mode: 0644]
tools/src/js/ble_characteristic.js [new file with mode: 0644]
tools/src/js/ble_descriptor.js [new file with mode: 0644]
tools/src/js/ble_hci_socket.js [new file with mode: 0644]
tools/src/js/ble_hci_socket_acl_stream.js [new file with mode: 0644]
tools/src/js/ble_hci_socket_bindings.js [new file with mode: 0644]
tools/src/js/ble_hci_socket_crypto.js [new file with mode: 0644]
tools/src/js/ble_hci_socket_gap.js [new file with mode: 0644]
tools/src/js/ble_hci_socket_gatt.js [new file with mode: 0644]
tools/src/js/ble_hci_socket_hci.js [new file with mode: 0644]
tools/src/js/ble_hci_socket_hci_status.js [new file with mode: 0644]
tools/src/js/ble_hci_socket_mgmt.js [new file with mode: 0644]
tools/src/js/ble_hci_socket_smp.js [new file with mode: 0644]
tools/src/js/ble_primary_service.js [new file with mode: 0644]
tools/src/js/ble_uuid_util.js [new file with mode: 0644]
tools/src/js/buffer.js [new file with mode: 0644]
tools/src/js/console.js [new file with mode: 0644]
tools/src/js/constants.js [new file with mode: 0644]
tools/src/js/dgram.js [new file with mode: 0644]
tools/src/js/dns.js [new file with mode: 0644]
tools/src/js/events.js [new file with mode: 0644]
tools/src/js/fs.js [new file with mode: 0644]
tools/src/js/gpio.js [new file with mode: 0644]
tools/src/js/http.js [new file with mode: 0644]
tools/src/js/http_client.js [new file with mode: 0644]
tools/src/js/http_common.js [new file with mode: 0644]
tools/src/js/http_incoming.js [new file with mode: 0644]
tools/src/js/http_outgoing.js [new file with mode: 0644]
tools/src/js/http_server.js [new file with mode: 0644]
tools/src/js/i2c.js [new file with mode: 0644]
tools/src/js/iotjs.js [new file with mode: 0644]
tools/src/js/module.js [new file with mode: 0644]
tools/src/js/net.js [new file with mode: 0644]
tools/src/js/pwm.js [new file with mode: 0644]
tools/src/js/spi.js [new file with mode: 0644]
tools/src/js/stm32f4dis.js [new file with mode: 0644]
tools/src/js/stream.js [new file with mode: 0644]
tools/src/js/stream_duplex.js [new file with mode: 0644]
tools/src/js/stream_readable.js [new file with mode: 0644]
tools/src/js/stream_writable.js [new file with mode: 0644]
tools/src/js/testdriver.js [new file with mode: 0644]
tools/src/js/timers.js [new file with mode: 0644]
tools/src/js/uart.js [new file with mode: 0644]
tools/src/js/util.js [new file with mode: 0644]
tools/src/module/iotjs_module_adc.c [new file with mode: 0644]
tools/src/module/iotjs_module_adc.h [new file with mode: 0644]
tools/src/module/iotjs_module_blehcisocket.c [new file with mode: 0644]
tools/src/module/iotjs_module_blehcisocket.h [new file with mode: 0644]
tools/src/module/iotjs_module_buffer.c [new file with mode: 0644]
tools/src/module/iotjs_module_buffer.h [new file with mode: 0644]
tools/src/module/iotjs_module_console.c [new file with mode: 0644]
tools/src/module/iotjs_module_constants.c [new file with mode: 0644]
tools/src/module/iotjs_module_dns.c [new file with mode: 0644]
tools/src/module/iotjs_module_dns.h [new file with mode: 0644]
tools/src/module/iotjs_module_fs.c [new file with mode: 0644]
tools/src/module/iotjs_module_fs.h [new file with mode: 0644]
tools/src/module/iotjs_module_gpio.c [new file with mode: 0644]
tools/src/module/iotjs_module_gpio.h [new file with mode: 0644]
tools/src/module/iotjs_module_httpparser.c [new file with mode: 0644]
tools/src/module/iotjs_module_httpparser.h [new file with mode: 0644]
tools/src/module/iotjs_module_i2c.c [new file with mode: 0644]
tools/src/module/iotjs_module_i2c.h [new file with mode: 0644]
tools/src/module/iotjs_module_process.c [new file with mode: 0644]
tools/src/module/iotjs_module_pwm.c [new file with mode: 0644]
tools/src/module/iotjs_module_pwm.h [new file with mode: 0644]
tools/src/module/iotjs_module_spi.c [new file with mode: 0644]
tools/src/module/iotjs_module_spi.h [new file with mode: 0644]
tools/src/module/iotjs_module_stm32f4dis.c [new file with mode: 0644]
tools/src/module/iotjs_module_stm32f4dis.h [new file with mode: 0644]
tools/src/module/iotjs_module_tcp.c [new file with mode: 0644]
tools/src/module/iotjs_module_tcp.h [new file with mode: 0644]
tools/src/module/iotjs_module_testdriver.c [new file with mode: 0644]
tools/src/module/iotjs_module_timer.c [new file with mode: 0644]
tools/src/module/iotjs_module_timer.h [new file with mode: 0644]
tools/src/module/iotjs_module_uart.c [new file with mode: 0644]
tools/src/module/iotjs_module_uart.h [new file with mode: 0644]
tools/src/module/iotjs_module_udp.c [new file with mode: 0644]
tools/src/module/iotjs_module_udp.h [new file with mode: 0644]
tools/src/platform/arm-linux/iotjs_module_adc-arm-linux.c [new file with mode: 0644]
tools/src/platform/arm-linux/iotjs_module_blehcisocket-arm-linux.c [new file with mode: 0644]
tools/src/platform/arm-linux/iotjs_module_gpio-arm-linux.c [new file with mode: 0644]
tools/src/platform/arm-linux/iotjs_module_i2c-arm-linux.c [new file with mode: 0644]
tools/src/platform/arm-linux/iotjs_module_pwm-arm-linux.c [new file with mode: 0644]
tools/src/platform/arm-linux/iotjs_module_spi-arm-linux.c [new file with mode: 0644]
tools/src/platform/arm-linux/iotjs_module_uart-arm-linux.c [new file with mode: 0644]
tools/src/platform/arm-nuttx/iotjs_module_adc-arm-nuttx.c [new file with mode: 0644]
tools/src/platform/arm-nuttx/iotjs_module_blehcisocket-arm-nuttx.c [new file with mode: 0644]
tools/src/platform/arm-nuttx/iotjs_module_gpio-arm-nuttx-general.inl.h [new file with mode: 0644]
tools/src/platform/arm-nuttx/iotjs_module_gpio-arm-nuttx-stm32.inl.h [new file with mode: 0644]
tools/src/platform/arm-nuttx/iotjs_module_gpio-arm-nuttx.c [new file with mode: 0644]
tools/src/platform/arm-nuttx/iotjs_module_i2c-arm-nuttx.c [new file with mode: 0644]
tools/src/platform/arm-nuttx/iotjs_module_pwm-arm-nuttx.c [new file with mode: 0644]
tools/src/platform/arm-nuttx/iotjs_module_spi-arm-nuttx.c [new file with mode: 0644]
tools/src/platform/arm-nuttx/iotjs_module_stm32f4dis-arm-nuttx.c [new file with mode: 0644]
tools/src/platform/arm-nuttx/iotjs_module_uart-arm-nuttx.c [new file with mode: 0644]
tools/src/platform/arm-nuttx/iotjs_systemio-arm-nuttx-stm32.c [new file with mode: 0644]
tools/src/platform/arm-nuttx/iotjs_systemio-arm-nuttx.h [new file with mode: 0644]
tools/src/platform/i686-linux/iotjs_module_adc-i686-linux.c [new file with mode: 0644]
tools/src/platform/i686-linux/iotjs_module_blehcisocket-i686-linux.c [new file with mode: 0644]
tools/src/platform/i686-linux/iotjs_module_gpio-i686-linux.c [new file with mode: 0644]
tools/src/platform/i686-linux/iotjs_module_i2c-i686-linux.c [new file with mode: 0644]
tools/src/platform/i686-linux/iotjs_module_pwm-i686-linux.c [new file with mode: 0644]
tools/src/platform/i686-linux/iotjs_module_spi-i686-linux.c [new file with mode: 0644]
tools/src/platform/i686-linux/iotjs_module_uart-i686-linux.c [new file with mode: 0644]
tools/src/platform/iotjs_module_adc-linux-general.inl.h [new file with mode: 0644]
tools/src/platform/iotjs_module_blehcisocket-linux-general.inl.h [new file with mode: 0644]
tools/src/platform/iotjs_module_gpio-linux-general.inl.h [new file with mode: 0644]
tools/src/platform/iotjs_module_i2c-linux-general.inl.h [new file with mode: 0644]
tools/src/platform/iotjs_module_pwm-linux-general.inl.h [new file with mode: 0644]
tools/src/platform/iotjs_module_spi-linux-general.inl.h [new file with mode: 0644]
tools/src/platform/iotjs_module_uart-linux-general.inl.h [new file with mode: 0644]
tools/src/platform/iotjs_systemio-linux.c [new file with mode: 0644]
tools/src/platform/iotjs_systemio-linux.h [new file with mode: 0644]
tools/src/platform/x86_64-darwin/iotjs_module_adc-x86_64-darwin.c [new file with mode: 0644]
tools/src/platform/x86_64-darwin/iotjs_module_blehcisocket-x86_64-darwin.c [new file with mode: 0644]
tools/src/platform/x86_64-darwin/iotjs_module_gpio-x86_64-darwin.c [new file with mode: 0644]
tools/src/platform/x86_64-darwin/iotjs_module_i2c-x86_64-darwin.c [new file with mode: 0644]
tools/src/platform/x86_64-darwin/iotjs_module_pwm-x86_64-darwin.c [new file with mode: 0644]
tools/src/platform/x86_64-darwin/iotjs_module_spi-x86_64-darwin.c [new file with mode: 0644]
tools/src/platform/x86_64-darwin/iotjs_module_uart-x86_64-darwin.c [new file with mode: 0644]
tools/src/platform/x86_64-darwin/iotjs_module_unimplemented.inl.h [new file with mode: 0644]
tools/src/platform/x86_64-linux/iotjs_module_adc-x86_64-linux.c [new file with mode: 0644]
tools/src/platform/x86_64-linux/iotjs_module_blehcisocket-x86_64-linux.c [new file with mode: 0644]
tools/src/platform/x86_64-linux/iotjs_module_gpio-x86_64-linux.c [new file with mode: 0644]
tools/src/platform/x86_64-linux/iotjs_module_i2c-x86_64-linux.c [new file with mode: 0644]
tools/src/platform/x86_64-linux/iotjs_module_pwm-x86_64-linux.c [new file with mode: 0644]
tools/src/platform/x86_64-linux/iotjs_module_spi-x86_64-linux.c [new file with mode: 0644]
tools/src/platform/x86_64-linux/iotjs_module_uart-x86_64-linux.c [new file with mode: 0644]
tools/targets/nuttx-stm32f4/README.md [new file with mode: 0644]
tools/targets/nuttx-stm32f4/Stm32f4dis.md [new file with mode: 0644]
tools/targets/nuttx-stm32f4/app/Kconfig [new file with mode: 0644]
tools/targets/nuttx-stm32f4/app/Make.defs [new file with mode: 0644]
tools/targets/nuttx-stm32f4/app/Makefile [new file with mode: 0644]
tools/targets/nuttx-stm32f4/app/iotjs_main.cxx [new file with mode: 0644]
tools/targets/nuttx-stm32f4/nuttx/.config.default [new file with mode: 0644]
tools/targets/nuttx-stm32f4/nuttx/.config.travis [new file with mode: 0644]
tools/targets/nuttx-stm32f4/nuttx/patch [new file with mode: 0644]
tools/targets/tizenrt-artik05x/app/README.md [new file with mode: 0644]
tools/targets/tizenrt-artik05x/app/iotjs/.gitignore [new file with mode: 0644]
tools/targets/tizenrt-artik05x/app/iotjs/Kconfig [new file with mode: 0644]
tools/targets/tizenrt-artik05x/app/iotjs/Kconfig_ENTRY [new file with mode: 0644]
tools/targets/tizenrt-artik05x/app/iotjs/Make.defs [new file with mode: 0644]
tools/targets/tizenrt-artik05x/app/iotjs/Makefile [new file with mode: 0644]
tools/targets/tizenrt-artik05x/app/iotjs/iotjs_main.c [new file with mode: 0644]
tools/test/resources/greeting.txt [new file with mode: 0644]
tools/test/resources/readdir/DO_NOT_MODIFY_THIS_FOLDER [new file with mode: 0644]
tools/test/resources/readdir/This_is_a_directory/.gitkeep [new file with mode: 0644]
tools/test/resources/readdir/This_is_another_directory/.gitkeep [new file with mode: 0644]
tools/test/resources/readdir/regular.txt [new file with mode: 0644]
tools/test/resources/rename.txt [new file with mode: 0644]
tools/test/resources/test1.txt [new file with mode: 0644]
tools/test/resources/test_console_stdout.txt [new file with mode: 0644]
tools/test/resources/tobeornottobe.txt [new file with mode: 0644]
tools/test/run_fail/assert_fail1.js [new file with mode: 0644]
tools/test/run_fail/assert_fail2.js [new file with mode: 0644]
tools/test/run_fail/assert_fail3.js [new file with mode: 0644]
tools/test/run_fail/fs_callbacks_called.js [new file with mode: 0644]
tools/test/run_fail/process_exit1.js [new file with mode: 0644]
tools/test/run_fail/process_exit2.js [new file with mode: 0644]
tools/test/run_fail/process_exitcode1.js [new file with mode: 0644]
tools/test/run_fail/process_exitcode2.js [new file with mode: 0644]
tools/test/run_fail/require_fail1.js [new file with mode: 0644]
tools/test/run_fail/runtime_error1.js [new file with mode: 0644]
tools/test/run_fail/syntax_fail1.js [new file with mode: 0644]
tools/test/run_fail/uncaught_error_event.js [new file with mode: 0644]
tools/test/run_pass/issue/issue-133.js [new file with mode: 0644]
tools/test/run_pass/issue/issue-137.js [new file with mode: 0644]
tools/test/run_pass/issue/issue-198.js [new file with mode: 0644]
tools/test/run_pass/issue/issue-223.js [new file with mode: 0644]
tools/test/run_pass/issue/issue-266.js [new file with mode: 0644]
tools/test/run_pass/issue/issue-323.js [new file with mode: 0644]
tools/test/run_pass/require1/module_cache.js [new file with mode: 0644]
tools/test/run_pass/require1/node_modules/test_index/add2.js [new file with mode: 0644]
tools/test/run_pass/require1/node_modules/test_index/index.js [new file with mode: 0644]
tools/test/run_pass/require1/node_modules/test_index/lib/multi.js [new file with mode: 0644]
tools/test/run_pass/require1/node_modules/test_index/package.json [new file with mode: 0644]
tools/test/run_pass/require1/node_modules/test_pkg/add2.js [new file with mode: 0644]
tools/test/run_pass/require1/node_modules/test_pkg/lib/multi.js [new file with mode: 0644]
tools/test/run_pass/require1/node_modules/test_pkg/main.js [new file with mode: 0644]
tools/test/run_pass/require1/node_modules/test_pkg/package.json [new file with mode: 0644]
tools/test/run_pass/require1/package.json [new file with mode: 0644]
tools/test/run_pass/require1/require_add.js [new file with mode: 0644]
tools/test/run_pass/require1/test_require.js [new file with mode: 0644]
tools/test/run_pass/test_adc.js [new file with mode: 0644]
tools/test/run_pass/test_assert.js [new file with mode: 0644]
tools/test/run_pass/test_ble_advertisement.js [new file with mode: 0644]
tools/test/run_pass/test_ble_setservices.js [new file with mode: 0644]
tools/test/run_pass/test_buffer.js [new file with mode: 0644]
tools/test/run_pass/test_buffer_builtin.js [new file with mode: 0644]
tools/test/run_pass/test_console.js [new file with mode: 0644]
tools/test/run_pass/test_cwd.js [new file with mode: 0644]
tools/test/run_pass/test_dgram_1_server_1_client.js [new file with mode: 0644]
tools/test/run_pass/test_dgram_1_server_n_clients.js [new file with mode: 0644]
tools/test/run_pass/test_dgram_address.js [new file with mode: 0644]
tools/test/run_pass/test_dgram_broadcast.js [new file with mode: 0644]
tools/test/run_pass/test_dgram_multicast_membership.js [new file with mode: 0644]
tools/test/run_pass/test_dgram_multicast_set_multicast_loop.js [new file with mode: 0644]
tools/test/run_pass/test_dns.js [new file with mode: 0644]
tools/test/run_pass/test_dns_lookup.js [new file with mode: 0644]
tools/test/run_pass/test_events.js [new file with mode: 0644]
tools/test/run_pass/test_exit.js [new file with mode: 0644]
tools/test/run_pass/test_experimental_off.js [new file with mode: 0644]
tools/test/run_pass/test_experimental_on.js [new file with mode: 0644]
tools/test/run_pass/test_fs.js [new file with mode: 0644]
tools/test/run_pass/test_fs1.js [new file with mode: 0644]
tools/test/run_pass/test_fs2.js [new file with mode: 0644]
tools/test/run_pass/test_fs_exists.js [new file with mode: 0644]
tools/test/run_pass/test_fs_existssync.js [new file with mode: 0644]
tools/test/run_pass/test_fs_mkdir_rmdir.js [new file with mode: 0644]
tools/test/run_pass/test_fs_open_close.js [new file with mode: 0644]
tools/test/run_pass/test_fs_readdir.js [new file with mode: 0644]
tools/test/run_pass/test_fs_readfile.js [new file with mode: 0644]
tools/test/run_pass/test_fs_readfilesync.js [new file with mode: 0644]
tools/test/run_pass/test_fs_rename.js [new file with mode: 0644]
tools/test/run_pass/test_fs_rename_sync.js [new file with mode: 0644]
tools/test/run_pass/test_fs_stat.js [new file with mode: 0644]
tools/test/run_pass/test_fs_writefile_unlink.js [new file with mode: 0644]
tools/test/run_pass/test_fs_writefile_unlink_sync.js [new file with mode: 0644]
tools/test/run_pass/test_gpio1.js [new file with mode: 0644]
tools/test/run_pass/test_gpio2.js [new file with mode: 0644]
tools/test/run_pass/test_http_get.js [new file with mode: 0644]
tools/test/run_pass/test_http_header.js [new file with mode: 0644]
tools/test/run_pass/test_httpclient_timeout.js [new file with mode: 0644]
tools/test/run_pass/test_httpclient_timeout2.js [new file with mode: 0644]
tools/test/run_pass/test_httpserver.js [new file with mode: 0644]
tools/test/run_pass/test_httpserver_timeout.js [new file with mode: 0644]
tools/test/run_pass/test_i2c.js [new file with mode: 0644]
tools/test/run_pass/test_module_cache.js [new file with mode: 0644]
tools/test/run_pass/test_net1.js [new file with mode: 0644]
tools/test/run_pass/test_net10.js [new file with mode: 0644]
tools/test/run_pass/test_net2.js [new file with mode: 0644]
tools/test/run_pass/test_net3.js [new file with mode: 0644]
tools/test/run_pass/test_net4.js [new file with mode: 0644]
tools/test/run_pass/test_net5.js [new file with mode: 0644]
tools/test/run_pass/test_net6.js [new file with mode: 0644]
tools/test/run_pass/test_net7.js [new file with mode: 0644]
tools/test/run_pass/test_net8.js [new file with mode: 0644]
tools/test/run_pass/test_net9.js [new file with mode: 0644]
tools/test/run_pass/test_next_tick.js [new file with mode: 0644]
tools/test/run_pass/test_process.js [new file with mode: 0644]
tools/test/run_pass/test_pwm.js [new file with mode: 0644]
tools/test/run_pass/test_spi.js [new file with mode: 0644]
tools/test/run_pass/test_stream.js [new file with mode: 0644]
tools/test/run_pass/test_timers.js [new file with mode: 0644]
tools/test/run_pass/test_timers2.js [new file with mode: 0644]
tools/test/run_pass/test_uart.js [new file with mode: 0644]
tools/test/run_pass/test_uncaught1.js [new file with mode: 0644]
tools/test/run_pass/test_uncaught2.js [new file with mode: 0644]
tools/test/run_pass/test_uncaught_error1.js [new file with mode: 0644]
tools/test/run_pass/test_uncaught_error2.js [new file with mode: 0644]
tools/test/test_stat.js [new file with mode: 0644]
tools/test/testsets.json [new file with mode: 0644]
tools/test/tmp/README [new file with mode: 0644]
tools/test_runner.js [new file with mode: 0644]
tools/zlib-Makefile.patch [new file with mode: 0644]

diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644 (file)
index 0000000..5bb57af
--- /dev/null
@@ -0,0 +1,73 @@
+# 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: <arch>-<os>)")
+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)
+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
+  -std=gnu99
+)
+
+include(ExternalProject)
+
+# Include external projects
+include(cmake/jerry.cmake)
+include(cmake/http-parser.cmake)
+include(cmake/libtuv.cmake)
+
+include(cmake/iotjs.cmake)
+
diff --git a/LICENSE b/LICENSE
new file mode 100644 (file)
index 0000000..5146304
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,218 @@
+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.
+
+
+                                 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:
+
diff --git a/README.md b/README.md
new file mode 100644 (file)
index 0000000..c6ca04a
--- /dev/null
+++ b/README.md
@@ -0,0 +1,66 @@
+# 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)
+
+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)
+
+## 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.
+
+> 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:
diff --git a/build.config b/build.config
new file mode 100644 (file)
index 0000000..4f1c14c
--- /dev/null
@@ -0,0 +1,111 @@
+{
+  "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": ["-O2"],
+      "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": ["adc", "ble", "dgram", "gpio", "i2c", "pwm", "spi", 
+                "stm32f4dis", "uart"]
+  }
+}
diff --git a/cmake/config/arm-linux.cmake b/cmake/config/arm-linux.cmake
new file mode 100644 (file)
index 0000000..974b541
--- /dev/null
@@ -0,0 +1,22 @@
+# 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)
diff --git a/cmake/config/arm-nuttx.cmake b/cmake/config/arm-nuttx.cmake
new file mode 100644 (file)
index 0000000..6ad88b8
--- /dev/null
@@ -0,0 +1,22 @@
+# 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 EXTERNAL)
+set(CMAKE_SYSTEM_PROCESSOR armv7l)
+
+set(EXTERNAL_CMAKE_C_COMPILER arm-none-eabi-gcc)
+
+CMAKE_FORCE_C_COMPILER(${EXTERNAL_CMAKE_C_COMPILER} GNU)
diff --git a/cmake/config/arm-tizen.cmake b/cmake/config/arm-tizen.cmake
new file mode 100644 (file)
index 0000000..cf41e48
--- /dev/null
@@ -0,0 +1,32 @@
+# 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()
diff --git a/cmake/config/arm-tizenrt.cmake b/cmake/config/arm-tizenrt.cmake
new file mode 100644 (file)
index 0000000..39611ef
--- /dev/null
@@ -0,0 +1,22 @@
+# 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 EXTERNAL)
+set(CMAKE_SYSTEM_PROCESSOR armv7l)
+
+set(EXTERNAL_CMAKE_C_COMPILER arm-none-eabi-gcc)
+
+CMAKE_FORCE_C_COMPILER(${EXTERNAL_CMAKE_C_COMPILER} GNU)
diff --git a/cmake/config/i686-linux.cmake b/cmake/config/i686-linux.cmake
new file mode 100644 (file)
index 0000000..c4c7f56
--- /dev/null
@@ -0,0 +1,18 @@
+# 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)
diff --git a/cmake/config/x86_64-darwin.cmake b/cmake/config/x86_64-darwin.cmake
new file mode 100644 (file)
index 0000000..e3c4bc4
--- /dev/null
@@ -0,0 +1,18 @@
+# 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)
diff --git a/cmake/config/x86_64-linux.cmake b/cmake/config/x86_64-linux.cmake
new file mode 100644 (file)
index 0000000..79cf370
--- /dev/null
@@ -0,0 +1,18 @@
+# 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)
diff --git a/cmake/http-parser.cmake b/cmake/http-parser.cmake
new file mode 100644 (file)
index 0000000..67128c3
--- /dev/null
@@ -0,0 +1,47 @@
+# 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}
+    -DBUILDTYPE=${CMAKE_BUILD_TYPE} # TODO: use CMAKE_BUILD_TYPE in sub-project
+    -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})
diff --git a/cmake/iotjs.cmake b/cmake/iotjs.cmake
new file mode 100644 (file)
index 0000000..5cf0ad7
--- /dev/null
@@ -0,0 +1,283 @@
+# 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
+set(IOTJS_PLATFORM_SRC)
+if("${CMAKE_SYSTEM_NAME}" MATCHES "Linux|Tizen")
+  file(GLOB IOTJS_PLATFORM_LINUX_SRC
+       ${IOTJS_SOURCE_DIR}/platform/iotjs_*-linux.c)
+  list(APPEND IOTJS_PLATFORM_SRC ${IOTJS_PLATFORM_LINUX_SRC})
+  # in case of Tizen force the platform to Linux
+  string(REGEX REPLACE "tizen$" "linux"
+         PLATFORM_DESCRIPTOR "${PLATFORM_DESCRIPTOR}")
+endif()
+
+# Board Configuration (not module)
+if(DEFINED TARGET_BOARD)
+  string(TOLOWER "${TARGET_BOARD}" BOARD_DESCRIPTOR)
+
+  if("${BOARD_DESCRIPTOR}" STREQUAL "stm32f4dis")
+    set(BOARD_DESCRIPTOR stm32)
+  endif()
+
+  set(BOARD_SRC ${IOTJS_SOURCE_DIR}/platform/${PLATFORM_DESCRIPTOR})
+  set(BOARD_SRC ${BOARD_SRC}/iotjs_[^module]*${BOARD_DESCRIPTOR}.c)
+  file(GLOB IOTJS_BOARD_SRC ${BOARD_SRC})
+  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
+          --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}/module/*.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}/module/iotjs_module_${module}.c)
+  if(EXISTS "${BASE_MODULE_SRC}")
+    list(APPEND IOTJS_MODULE_SRC ${BASE_MODULE_SRC})
+  endif()
+
+  # check if there is an extra platform support code for the module
+  # PLATFORM_DESCRIPTOR is <arch>-<os>  (eg.: x86_64-linux)
+  # ../platform/<arch>-<os>/iotjs_module_<module> ...
+  set(PLATFORM_MODULE_BASE ${PLATFORM_SRC}_${module}-${PLATFORM_DESCRIPTOR})
+  set(PLATFORM_MODULE_SRC ${PLATFORM_MODULE_BASE}.c)
+  if(VERBOSE)
+    message("Checking platform file: ${PLATFORM_MODULE_SRC}")
+  endif()
+  if(EXISTS "${PLATFORM_MODULE_SRC}")
+    list(APPEND IOTJS_MODULE_SRC ${PLATFORM_MODULE_SRC})
+    list(APPEND IOTJS_PLATFORM_SUPPORT ${MODULE})
+  endif()
+
+  # check if there is an extra board support code for the module
+  # BOARD_DESCRIPTOR is eg.: stm32
+  if(DEFINED BOARD_DESCRIPTOR)
+    set(BOARD_MODULE_SRC "${PLATFORM_MODULE_BASE}-${BOARD_DESCRIPTOR}.c")
+    if(VERBOSE)
+      message("Checking module file: ${BOARD_MODULE_SRC}")
+    endif()
+    if(EXISTS "${BOARD_MODULE_SRC}")
+      list(APPEND IOTJS_MODULE_SRC ${BOARD_MODULE_SRC})
+      list(APPEND IOTJS_MODULE_SUPPORT ${MODULE})
+    endif()
+  endif()
+  string(TOUPPER ${module} module)
+
+  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 BOARD_DESCRIPTOR)
+      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}
+  ${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()
diff --git a/cmake/jerry.cmake b/cmake/jerry.cmake
new file mode 100644 (file)
index 0000000..891b5bf
--- /dev/null
@@ -0,0 +1,143 @@
+# 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_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<KEY>=<KEY_Value>
+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)
+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 "LINUX|TIZEN|DARWIN")
+  list(APPEND JERRY_LIBS m)
+  list(APPEND DEPS_LIB_JERRY_ARGS
+    -DJERRY_LIBC=OFF
+    -DJERRY_LIBM=OFF)
+elseif("${TARGET_OS}" MATCHES "TIZENRT")
+  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}
+  )
+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()
+
+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 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)
+
+set(JERRY_PORT_DIR ${DEPS_LIB_JERRY_SRC}/targets/default)
+set(JERRY_INCLUDE_DIR ${DEPS_LIB_JERRY}/jerry-core)
diff --git a/cmake/libtuv.cmake b/cmake/libtuv.cmake
new file mode 100644 (file)
index 0000000..40eb22a
--- /dev/null
@@ -0,0 +1,55 @@
+# 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()
diff --git a/docs/License.md b/docs/License.md
new file mode 100644 (file)
index 0000000..3ef9f7d
--- /dev/null
@@ -0,0 +1,14 @@
+### 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)
diff --git a/docs/README.md b/docs/README.md
new file mode 100644 (file)
index 0000000..c131ac0
--- /dev/null
@@ -0,0 +1,18 @@
+Welcome 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)
+<br>
+
+
+### [Getting Started](help/Getting-Started.md) - Developer guide
+### [Getting Involved](help/Getting-involved.md)
+### Roadmap(TBD)
diff --git a/docs/api/IoT.js-API-ADC.md b/docs/api/IoT.js-API-ADC.md
new file mode 100644 (file)
index 0000000..e755836
--- /dev/null
@@ -0,0 +1,130 @@
+### Platform Support
+
+The following shows ADC module APIs available for each platform.
+
+|  | Linux<br/>(Ubuntu) | Raspbian<br/>(Raspberry Pi) | Nuttx<br/>(STM32F4-Discovery) |
+| :---: | :---: | :---: | :---: |
+| adc.open | O | O | O |
+| adcpin.read | O | O | O |
+| adcpin.readSync | O | O | O |
+| adcpin.close | O | O | O |
+| adcpin.closeSync | O | O | O |
+
+
+## Contents
+* [Pin](#pin)
+* [ADC](#adc)
+  * [Constructor](#adc-constructor)
+    * [`new ADC()`](#adc-new)
+  * [Prototype methods](#adc-prototype-methods)
+    * [`adc.open(configuration[, callback])`](#adc-open)
+* [ADCPin](#adcpin)
+  * [Prototype methods](#adcpin-prototype-methods)
+    * [`adcpin.read([callback])`](#adcpin-read)
+    * [`adcpin.readSync()`](#adcpin-read-sync)
+    * [`adcpin.close([callback])`](#adcpin-close)
+    * [`adcpin.closeSync()`](#adcpin-close-sync)
+
+## `pin` <a name="pin"></a>
+On Nuttx, you have to know pin number that is defined in target board module. For more module information, please see below list.
+  * [STM32F4-discovery](../../targets/nuttx-stm32f4/Stm32f4dis.md#adc-pin)
+
+## Class: ADC <a name="adc"></a>
+
+
+## Constructor <a name="adc-constructor"></a>
+
+
+### `new ADC()` <a name="adc-new"></a>
+
+Returns a new ADC object which can open ADC pin.
+
+
+## Prototype methods <a name="adc-prototype-methods"></a>
+
+
+### `adc.open(configuration[, callback])` <a name="adc-open"></a>
+* `configuration <Object>`
+  * `device <String>`, mandatory configuration on Linux
+  * `pin <Number>`, mandatory configuration on Nuttx
+* `callback <Function(err: Error | null)>`
+* Returns: `<ADCPin>`
+
+Opens 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 <a name="adcpin"></a>
+
+
+## Prototype methods <a name="adcpin-prototype-methods"></a>
+
+
+### `adcpin.read([callback])` <a name="adcpin-read"></a>
+* `callback <Function(err: Error | null, value: Number)>`
+
+Reads the analog value from pin asynchronously.
+
+`callback` will be called after read the analog value.
+
+**Example**
+```js
+adc0.read(function(err, value) {
+  if (err) {
+    throw err;
+  }
+  console.log('value:', value);
+});
+```
+
+
+### `adcpin.readSync()` <a name="adcpin-read-sync"></a>
+* Return: `<Number>`, analog value
+
+Reads the analog value from pin synchronously.
+
+**Example**
+```js
+var value = adc0.readSync();
+console.log('value:', value);
+```
+
+
+### `adcpin.close([callback])` <a name="adcpin-close"></a>
+* `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.clsoe(function(err) {
+  if (err) {
+    throw err;
+  }
+});
+```
+
+
+### `adcpin.closeSync()` <a name="adcpin-close-sync"></a>
+
+Closes ADC pin synchronously. This function must be called after the work of ADC finished.
+
+**Example**
+```js
+adc0.clsoeSync();
+console.log('adc pin is closed');
+```
diff --git a/docs/api/IoT.js-API-Assert.md b/docs/api/IoT.js-API-Assert.md
new file mode 100644 (file)
index 0000000..eaa1a33
--- /dev/null
@@ -0,0 +1,64 @@
+## Module: Assert
+
+Assert module is for writing test for applications.
+
+## AssertionError
+Assert module will produce `AssertionError` in case of assertion failure. `AssertionError` inherits standard `Error` thus it has properties provided by `Error` object including additional properties.
+
+### Properties
+
+
+#### actual
+This property contains the actual value.
+
+
+#### message
+The error message.
+
+
+#### expected
+This property contains the expected value.
+
+
+#### name
+The name of `AssertionError` is 'AssertionError` this is fixed.
+
+
+#### operator
+This property contains the operator used for evaluating `actual` with `expected`.
+
+
+## Assert
+You can get assert module by `require('assert')` the module provide.
+
+
+#### assert(value, message)
+Test if `value` is true, it throws an `AssertionError` exception if `value` evaluates `false`.
+
+
+#### assert.doesNotThrows(block, message)
+Test if the given `block` does not throw any exception, if not, it throws an exception.
+
+
+#### assert.equal(actual, expected, message)
+Test if `actual == expected` is evaluated to `true`, if not, it throws an exception.
+
+
+#### assert.fail(actual, expected, message, operator)
+Throw an `AssertionError` exception.
+
+
+#### assert.notEqual(actual, expected, message)
+Test if `actual != expected` is evaluated to `true`, if not, it throws an exception.
+
+
+#### assert.notStrictEqual(actual, expected, message)
+Test if `actual !== expected` is evaluated to `true`, if not, it throws an exception.
+
+
+#### assert.strictEqual(actual, expected, message)
+Test if `actual === expected` is evaluated to `true`, if not, it throws an exception.
+
+
+#### assert.throws(block, expected, message)
+Test if the given `block` throws an `expected` error, if not, it throws an exception.
diff --git a/docs/api/IoT.js-API-BLE.md b/docs/api/IoT.js-API-BLE.md
new file mode 100644 (file)
index 0000000..b0695fb
--- /dev/null
@@ -0,0 +1,42 @@
+## Module: ble
+
+### Platform Support
+
+The following shows ble module APIs available for each platform.
+
+|  | Linux<br/>(Ubuntu) | Raspbian<br/>(Raspberry Pi) | Nuttx<br/>(STM32F4-Discovery) |
+| :---: | :---: | :---: | :---: |
+| ble.startAdvertising | O | O | X |
+| ble.stopAdvertising | O | O | X |
+| ble.setServices | O | O | X |
+
+### Events
+
+#### `'stateChange'`
+* `callback: Function(state)`
+
+  * `state: String` - "unknown" | "resetting" | "unsupported" | "unauthorized" | "poweredOff" | "poweredOn"
+
+Emitted when adapter state is changed.
+
+
+### Methods
+
+#### ble.startAdvertising(name, serviceUuids[, callback(error)])
+* `name: String` - maximum 26 bytes
+* `serviceUuids: Array`
+  * 1 128-bit service UUID
+  * 1 128-bit service UUID + 2 16-bit service UUIDs
+  * 7 16-bit service UUID
+* `callback: Function(error)`
+
+Start advertising.
+
+ble.state must be poweredOn before advertising is started. 
+ble.on('stateChange', callback(state)); can be used register for state change events.
+
+
+#### ble.stopAdvertising(callback)
+* `callback: Function()`
+
+Stop advertising.
diff --git a/docs/api/IoT.js-API-Buffer.md b/docs/api/IoT.js-API-Buffer.md
new file mode 100644 (file)
index 0000000..9b16c06
--- /dev/null
@@ -0,0 +1,507 @@
+## Contents
+
+* [Buffer](#buffer)
+  * [Constructor](#constructor)
+    * [`new Buffer(size)`](#new-buffer-size)
+    * [`new Buffer(buffer)`](#new-buffer-buffer)
+    * [`new Buffer(str[, encoding]))`](#new-buffer-str)
+    * [`new Buffer(array)`](#new-buffer-array)
+  * [Class Methods](#class-methods)
+    * [`Buffer.byteLength(str[, encoding])`](#buffer-byte-length)
+    * [`Buffer.concat(list)`](#buffer-concat)
+    * [`Buffer.isBuffer(obj)`](#buffer-isbuffer)
+  * [Properties](#properties)
+    * [`buf.length`](#buf-length)
+  * [Prototype methods](#prototype-methods)
+    * [`buf.compare(otherBuffer)`](#buf-compare)
+    * [`buf.copy(targetBuffer[,targetStart[,sourceStart[,sourceEnd]]])`](#buf-copy)
+    * [`buf.equals(otherBuffer)`](#buf-equals)
+    * [`buf.fill(value)`](#buf-fill)
+    * [`buf.slice([start[,end]])`](#buf-slice)
+    * [`buf.toString([start[,end]])`](#buf-to-string)
+    * [`buf.write(string[,offset[,length]])`](#buf-write)
+    * [`buf.writeUInt8(value, offset[, noAssert])`](#buf-write-uint8)
+    * [`buf.writeUInt16LE(value, offset[, noAssert])`](#buf-write-uint16le)
+    * [`buf.writeUInt32LE(value, offset[, noAssert])`](#buf-write-uint32le)
+    * [`buf.readInt8(offset[, noAssert])`](#buf-read-int8)
+    * [`buf.readUInt8(offset[, noAssert])`](#buf-read-uint8)
+    * [`buf.readUInt16LE(offset[, noAssert])`](#buf-read-uint16)
+
+
+## Class: Buffer <a name="buffer"></a>
+
+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 <a name="constructor"></a>
+
+
+### `new Buffer(size)` <a name="new-buffer-size"></a>
+* `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)` <a name="new-buffer-buffer"></a>
+* `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]))` <a name="new-buffer-str"></a>
+* `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))
+console.log(buffer); // prints 1
+var buffer = new Buffer(String.fromCharCode(128))
+console.log(buffer); // prints 2
+var buffer = new Buffer(String.fromCharCode(2048))
+console.log(buffer); // prints 3
+
+var buffer = new Buffer('4142', 'hex')
+console.log(buffer); // prints AB
+```
+
+
+### `new Buffer(array)` <a name="new-buffer-array"></a>
+* `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])
+console.log(buffer); // prints AAAA
+```
+
+
+## Class Methods <a name="class-methods"></a>
+
+
+### `Buffer.byteLength(str[, encoding])` <a name="buffer-byte-length"></a>
+* `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)` <a name="buffer-concat"></a>
+* `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)` <a name="buffer-isbuffer"></a>
+* `obj <Object>`, a generic object
+* Returns: `<Boolean>`
+
+Returns `true` if `obj` is an instance of `Buffer`. Returns
+`false` otherwise.
+
+**Example**
+
+```js
+var Buffer = require('buffer');
+
+console.log(Buffer.isBuffer(new Buffer(1))); // prints true
+console.log(Buffer.isBuffer('str')); // prints false
+```
+
+
+## Properties <a name="properties"></a>
+
+
+### `buf.length` <a name="buf-length"></a>
+* `<Integer>`, 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
+```
+
+
+## Prototype methods <a name="prototype-methods"></a>
+
+
+### `buf.compare(otherBuffer)` <a name="buf-compare"></a>
+* `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');
+
+console.log(buffer1.compare(buffer1)); // prints 0
+console.log(buffer1.compare(buffer2)); // prints 1
+console.log(buffer1.compare(buffer3)); // prints -1
+```
+
+
+### `buf.copy(targetBuffer[,targetStart[,sourceStart[,sourceEnd]]])` <a name="buf-copy"></a>
+* `targetBuffer <Buffer>`, modified buffer
+* `targetStart <Number>`, Default: `0`
+* `sourceStart <Number>`, Default: `0`
+* `sourceEnd <Number>`, Default: `buf.length`
+
+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('<JS>');
+
+buffer2.copy(buffer1, 6, 1, 3);
+
+console.log(buffer1); // prints Hello JS world!
+```
+
+
+### `buf.equals(otherBuffer)` <a name="buf-equals"></a>
+* `otherBuffer <Buffer>`, the right-hand side of the comparison
+* Return: `<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');
+
+console.log(buffer1.equals(buffer2)); // prints true
+console.log(buffer1.equals(buffer3)); // prints false
+```
+
+
+### `buf.fill(value)` <a name="buf-fill"></a>
+* `value <Integer>`, all bytes are set to this value
+* Return: `<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);
+console.log(buffer); // prints AAAAA
+buffer.fill(66 - 256);
+console.log(buffer); // prints BBBBB
+```
+
+
+### `buf.slice([start[,end]])` <a name="buf-slice"></a>
+* `start <Integer>`, Default: `0`
+* `end <Integer>`, Default: `buf.length`
+* Return: `<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!!!');
+
+console.log(buffer.slice(8, 18)); // prints JavaScript
+```
+
+
+### `buf.toString([start[,end]])` <a name="buf-to-string"></a>
+* `start <Integer>`, Default: `0`
+* `end <Integer>`, Default: `buffer.length`
+* Return: `<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");
+
+console.log(buffer.toString(1, 3)); // prints EF
+console.log(buffer.toString('hex')); // prints 44454647
+```
+
+
+### `buf.write(string[,offset[,length]])` <a name="buf-write"></a>
+* `string <String>`, data to be written to buffer
+* `offset <Integer>`, start position of buffer for writing. Default: `0`
+* `length <Integer>`, maximum length to be written. Default: `buffer.length - offset`.
+* Return: `<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);
+
+console.log(buffer); // prints AB.XY.
+
+var buffer = new Buffer("......");
+buffer.write("ABCDEF", 1, 3);
+
+console.log(buffer); // prints .ABC..
+```
+
+
+### `buf.writeUInt8(value, offset[, noAssert])` <a name="buf-write-uint8"></a>
+* `value <Integer>`, number to be written into the buffer
+* `offset <Integer>`, start position of the writing
+* `noAssert <Boolean>, skip argument validation. Default: `false`
+* Return: `<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.
+
+**Example**
+
+```js
+var Buffer = require('buffer');
+
+var buffer = new Buffer("....");
+
+console.log(buffer.writeUInt8(65, 2)); // prints 3
+console.log(buffer); // prints ..A.
+```
+
+
+### `buf.writeUInt16LE(value, offset[, noAssert])` <a name="buf-write-uint16le"></a>
+* `value <Integer>`, number to be written into the buffer
+* `offset <Integer>`, start position of the writing
+* `noAssert <Boolean>`, skip argument validation. Default: `false`
+* Return: `<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.
+
+**Example**
+
+```js
+var Buffer = require('buffer');
+
+var buffer = new Buffer("......");
+
+print(buffer.wrrteUInt16LE(0x4142, 1)); // prints 3
+print(buffer); // prints .BA...
+```
+
+
+### `buf.writeUInt32LE(value, offset[, noAssert])` <a name="buf-write-uint32le"></a>
+* `value <Integer>`, number to be written into the buffer
+* `offset <Integer>`, start position of the writing
+* `noAssert <Boolean>`, skip argument validation. Default: `false`
+* Return: `<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.
+
+**Example**
+
+```js
+var Buffer = require('buffer');
+
+var buffer = new Buffer("......");
+
+print(buffer.wrrteUInt32LE(0x41424344, 1)); // prints 5
+print(buffer); // prints .DCBA.
+```
+
+
+### `buf.readInt8(offset[, noAssert])` <a name="buf-read-int8"></a>
+* `offset: Number` - start position of buffer for reading.
+* `noAssert: Boolean`, Default: false - skip offset validation.
+* Return: `Number`
+
+Reads a signed 8-bit integer from `buf` buffer starting from
+`offset` position.
+
+**Example**
+
+```js
+var Buffer = require('buffer');
+
+var buffer = new Buffer("ABCDEF");
+
+print(buffer.readUInt8(1).toString(16)); // prints 42
+```
+
+
+### `buf.readUInt8(offset[, noAssert])` <a name="buf-read-uint8"></a>
+* `offset <Integer>`, start position of the reading
+* `noAssert <Boolean>`, skip argument validation. Default: `false`
+* Return: `Number`
+
+Reads an unsigned 8-bit integer from `buf` buffer starting from
+`offset` position.
+
+**Example**
+
+```js
+var Buffer = require('buffer');
+
+var buffer = new Buffer("ABCDEF");
+
+print(buffer.readUInt8(1).toString(16)); // prints 42
+```
+
+
+### `buf.readUInt16LE(offset[, noAssert])` <a name="buf-read-uint16"></a>
+* `offset: Number` - start position of buffer for reading.
+* `noAssert: Boolean`, Default: false - skip offset validation.
+* Return: `Number`
+
+Reads an unsigned 16-bit integer from `buf` buffer starting from
+`offset` position with little endian format.
+
+**Example**
+
+```js
+var Buffer = require('buffer');
+
+var buffer = new Buffer("ABCDEF");
+
+print(buffer.readUInt16LE(1).toString(16)); // prints 4342
+```
+
diff --git a/docs/api/IoT.js-API-DGRAM.md b/docs/api/IoT.js-API-DGRAM.md
new file mode 100644 (file)
index 0000000..e70c244
--- /dev/null
@@ -0,0 +1,174 @@
+## Module: dgram
+
+### Platform Support
+
+The following shows dgram module APIs available for each platform.
+
+|  | Linux<br/>(Ubuntu) | Raspbian<br/>(Raspberry Pi) | Nuttx<br/>(STM32F4-Discovery) |
+| :---: | :---: | :---: | :---: |
+| dgram.createSocket | O | O | O |
+| dgram.Socket.bind | O | O | O |
+| dgram.Socket.close | O | O | O |
+| dgram.Socket.send | O | O | O |
+| dgram.Socket.address | O | O | X |
+| dgram.Socket.setBroadcast | O | O | X |
+| dgram.Socket.setTTL | O | O | X |
+| dgram.Socket.addMembership | O | O | X |
+| dgram.Socket.dropMembership | O | O | X |
+| dgram.Socket.setMulticastLoopback | O | O | X |
+| dgram.Socket.setMulticastTTL | X | X | X |
+
+IoT.js provides udp connections through Dgram module.
+
+You can use this module with `require('dgram')` and create sockets.
+
+
+### Module Functions
+
+
+#### dgram.createSocket(options[, createListener])
+#### dgram.createSocket(type[, createListener])
+* `options: Object`
+ * `type: String`: it indicates an address family either `udp4` or `udp6`.
+ * `reuseAddr: Boolean`: it indicates to allow socket to bind the address and port used previously.
+
+* `type: String`: it indicates an address family either 'udp4' or 'udp6'.
+
+* `createListener: Function(msg, rinfo)`
+ * `msg: Buffer`
+ * `rinfo: Object`
+   * `address: String`
+   * `family: String`: it indicates an address family either `IPv4` or `IPv6`
+   * `port: Number`
+
+Creates a `dgram.Socket` according to `options` or `type`. (Currently we only accept `type`, `udp4`.)
+
+`createListener` is automatically registered as `message` event listener.
+
+
+***
+
+
+## class: dgram.Socket
+
+You can create `dgram.Socket` instance with `dgram.createSocket()`.
+
+
+### Events
+
+
+#### `'close'`
+* `callback: Function()`
+
+Emitted when socket closed.
+
+
+#### `'error'`
+* `callback: Function()`
+
+Emitted when an error occurs.
+
+
+#### `'listening'`
+* `callback: Function()`
+
+Emitted when socket is ready to receive data.
+
+
+#### `'message'`
+* `callback: Function(msg, rinfo)`
+ * `msg: Buffer`
+ * `rinfo: Object`
+   * `address: String`
+   * `family: String`: it indicates an address family either `IPv4` or `IPv6`
+   * `port: Number`
+
+Emitted when message comes to the socket.
+
+
+
+### Methods
+
+
+#### socket.address()
+
+Returns an object with the properties `address`, `port` and `family`. Basically the returned object is same with the object `rinfo` mentioned above.
+
+
+#### socket.addMembership(multicastAddress[, multicastInterface])
+* `multicastAddress: String`
+* `multicastInterface: String`
+
+Joins for socket the given multicast group with given `multicastAddress` and `multicastInterface`.
+
+
+#### socket.dropMembership(multicastAddress[, multicastInterface])
+* `multicastAddress: String`
+* `multicastInterface: String`
+
+Leaves for socket the given multicast group with given `multicastAddress` and `multicastInterface`.
+
+
+#### socket.bind([port][, address][, bindListener])
+#### socket.bind(options[, bindListener])
+* `port: Number`, if it is not specified, OS will bind socket with a random port.
+* `options: Object`
+ * `port: Number`
+ * `address: String`, Default: `0.0.0.0`
+* `bindListener: Function()`
+
+Binds `net.Socket` with given `address` and `port`.
+
+`bindListener` is automatically registered as `listening` event listener.
+
+
+#### socket.close([closeListener])
+* `closeListener: Function()`
+
+Stops listening data.
+
+`closeListener` is registered as `close` event listener.
+
+
+#### socket.setBroadcast(flag)
+* `flag: Boolean`
+
+Sets or clears the `SO_BROADCAST` socket option.
+
+
+#### socket.setTTL(ttl)
+* `ttl: Number`, it should be between 1 and 255.
+
+Sets the `IP_TTL` socket option.
+
+
+#### socket.send(msg, [offset, length], port, address[, sendListener])
+* `msg: Buffer | String | Array`
+* `offset: Number`, is is only valid when `msg` is Buffer.
+* `length: Number`, is is only valid when `msg` is Buffer.
+* `port: Number`
+* `address: String`, Default: `127.0.0.1` or `::1`
+* `sendListener: Function(err, length)`
+ * `err: Null | Error`
+   * `code: String`, temporally, it is just a String of *"error"*.
+   * `errno: String`, it is same with `code`
+   * `syscall: Number`
+   * `address: String`
+   * `port: Number`
+ * `length: Number`, it indicates the length of data.
+
+Sends the message to the destination with given `address` and `port`.
+
+If send operation is successfully completed, `sendListener` will be called with Null and the length of data, otherwise with Error object and the length of data.
+
+
+#### socket.setMulticastLoopback(flag)
+* `flag: Boolean`
+
+Sets or clears the `IP_MULTICAST_LOOP` socket option.
+
+
+#### socket.setMulticastTTL(ttl)
+* `ttl: Number`, it should be between 0 and 255.
+
+Sets the `IP_MULTICAST_TTL` socket option.
diff --git a/docs/api/IoT.js-API-DNS.md b/docs/api/IoT.js-API-DNS.md
new file mode 100644 (file)
index 0000000..6c361ef
--- /dev/null
@@ -0,0 +1,23 @@
+## Module: dns
+
+### Platform Support
+
+The following shows dns module APIs available for each platform.
+
+|  | Linux<br/>(Ubuntu) | Raspbian<br/>(Raspberry Pi) | Nuttx<br/>(STM32F4-Discovery) |
+| :---: | :---: | :---: | :---: |
+| dns.lookup | O | O | X |
+
+※ dns.lookup on `nuttx` works but due to lack of `nuttx` implementation, internally it only allows valid `ip4` address,
+but we are going to support `ip6` address, soon.
+
+IoT.js provides dns module.
+
+### Methods
+
+#### dns.lookup(hostname[, options], callback)
+* `hostname: String`
+* `options: Object | Number`
+* `callback: Function(err: Error, address: String, family: Number)`
+
+Resolves a hostname into the first found A (IPv4) or AAAA (IPv6) record.
diff --git a/docs/api/IoT.js-API-Events.md b/docs/api/IoT.js-API-Events.md
new file mode 100644 (file)
index 0000000..17a5ad3
--- /dev/null
@@ -0,0 +1,55 @@
+The application programming model of IoT.js is based on event-driven programming. Thus many objects in IoT.js emit events. `events.EventEmitter` plays a role as base class for such objects.
+
+
+## Class: EventEmitter
+User application would not directly create an instance of `EventEmitter` since `EventEmitter` is an abstract trait which defines its behavior and grants to sub-classes.
+
+
+### Methods
+
+
+#### emitter.addListener(event, listener)
+#### emitter.on(event, listener)
+* `event: String`
+* `listener: Function([args..])`
+* Returns emitter
+
+Adds `listener` to the end of list of event listeners for `event`.
+
+
+#### emitter.emit(event[, arg1[, arg2[...]]])
+* `event: String`
+* Returns `Boolean`
+
+Invokes each of listener with supplied arguments.
+
+Returns `true` if there were listeners, `false` otherwise.
+
+
+#### emitter.once(event, listener)
+* `event: String`
+* `listener: Function([args..])`
+* Returns emitter
+
+Adds `listener` for one time listener for `event`.
+
+The listener will be invoked at the next event and removed.
+
+
+#### emitter.removeListener(event, listener)
+* `event: String`
+* `listener: Function([args..])`
+* Returns emitter
+
+Removes listener from the list of event listeners.
+
+If you add the same listener multiple times, this removes only one instance of them.
+
+
+#### emitter.removeAllListener([event])
+* `event: String`
+* Returns emitter
+
+Removes all listeners.
+
+If `event` was specified, it only removes listeners for that event.
diff --git a/docs/api/IoT.js-API-File-System.md b/docs/api/IoT.js-API-File-System.md
new file mode 100644 (file)
index 0000000..e6b1139
--- /dev/null
@@ -0,0 +1,227 @@
+## Module: fs
+
+### Platform Support
+
+The following shows fs module APIs available for each platform.
+
+|  | Linux<br/>(Ubuntu) | Raspbian<br/>(Raspberry Pi) | Nuttx<br/>(STM32F4-Discovery) |
+| :---: | :---: | :---: | :---: |
+| fs.close | O | O | O |
+| fs.closeSync | 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.stat | O | O | O |
+| fs.statSync | O | O | O |
+| fs.fstat | O | O | O |
+| fs.fstatSync | O | O | O |
+| fs.write | O | O | O |
+| fs.writeSync | O | O | O |
+| fs.writeFile | O | O | O |
+| fs.writeFileSync | O | O | O |
+| fs.unlink | O | O | O |
+| fs.unlinkSync | O | O | O |
+
+※ On `nuttx` path should be passed with a form of **absolute path**.
+
+
+### Methods
+
+#### fs.close(fd, callback)
+
+* `fd: Int` - file descriptor.
+* `callback: Function(err) `
+ * `err: Error`
+
+Closes the file of fd asynchronously.
+
+
+#### fs.closeSync(fd)
+
+* `fd: Int` - file descriptor.
+
+Closes the file of fd synchronously.
+
+
+#### fs.open(path, flags[, mode], callback)
+
+* `path: String` - file path to be opened.
+* `flags: String` - open flags.
+* `mode: Number`, Default: `0666` - permission mode.
+* `callback: Function(err, fd)`
+ * `err: Error` - `Error` object if there was something wrong, otherwise `null`.
+ * `fd: Number` - file descriptor.
+
+
+#### fs.openSync(path, flags[, mode])
+
+* `path: String` - file path to be opened.
+* `flags: String` - open flags.
+* `mode: Number`, Default: `0666` - permission mode.
+
+
+#### fs.read(fd, buffer, offset, length, position, callback)
+
+* `fd: Int` - 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`, read from current position.
+* `callback: Function(err, bytesRead, buffer) `
+ * `err: Error`
+ * `bytesRead: Number`
+ * `buffer: Buffer`
+
+
+#### fs.readSync(fd, buffer, offset, length, position)
+
+* `fd: Int` - 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`, read from current position.
+
+
+#### fs.readFile(path[, options], callback)
+
+* `path: String` - file path to be opened.
+* `options: Object` - options for the operation.
+ * `encoding: String`, Default: `null` - encoding of the file.
+ * `flag: String`, Default: `r` - file open flag.
+* `callback: Function(err, data)` - callback function.
+ * `err: Error`
+ * `data: Buffer`
+
+Reads entire file asynchronously.
+
+
+#### fs.readFileSync(path[, options])
+
+* `path: String` - file path to be opened.
+* `options: Object` - options for the operation.
+ * `encoding: String`, Default: `null` - encoding of the file.
+ * `flag: String`, Default: `r` - file open flag.
+
+Reads entire file synchronously.
+
+
+#### fs.rename(oldPath, newPath, callback)
+
+* `oldPath: String` - old file path
+* `newPath: String` - new file path
+* `callback: Function(err)` - callback function.
+ * `err: Error`
+
+Renames `oldPath` to `newPath` asynchronously.
+
+
+#### fs.renameSync(oldPath, newPath)
+
+* `oldPath: String` - old file path
+* `newPath: String` - new file path
+
+Renames `oldPath` to `newPath` synchronously.
+
+
+#### fs.stat(path, callback)
+
+* `path: String` - file path to be stated
+* callback: Function(err, stat)` - callback function.
+ * `err: Error`
+ * `stat: Object`
+
+
+#### fs.statSync(path)
+
+* `path: String` - file path to be stated
+
+
+#### fs.fstat(fd, callback)
+
+* `fd: Number` - file descriptor to be stated
+* callback: Function(err, stat)` - callback function.
+ * `err: Error`
+ * `stat: Object`
+
+
+#### fs.fstatSync(fd)
+
+* `fd: Number` - file descriptor to be stated
+
+ ### Class: fs.Stats
+
+ fs.Stats class is a object returned from ```fs.stat()```,```fs.fstat()``` and their synchronous counterparts.
+
+ ### Methods
+
+ #### stats.isDirectory()
+
+ Returns true if stated file is a directory
+
+ #### stats.isFile()
+
+ Returns true if stated file is a file
+
+
+#### fs.write(fd, buffer, offset, length, position, callback)
+
+* `fd: Int` - 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`, read from current position.
+* callback: Function(err, bytesWrite)` - callback function.
+ * `err: Error`
+ * `byteWrite: Int`
+
+
+#### fs.writeSync(fd, buffer, offset, length, position)
+
+* `fd: Int` - 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`, read from current position.
+
+
+#### fs.writeFile(path, data, [, options], callback)
+
+* `path: String` - file path that the `data` will be written
+* `data: Buffer` - buffer that contains data
+* `options: Object` - options for the operation
+* `callback: Function(err)` - callback function
+ * `err: Error`
+
+Writes entire `data` to the file specified by `path` asynchronously.
+
+
+#### fs.writeFileSync(path, data, [, options])
+
+* `path: String` - file path that the `data` will be written
+* `data: Buffer` - buffer that contains data
+* `options: Object` - options for the operation
+
+Writes entire `data` to the file specified by `path` synchronously.
+
+
+#### fs.unlink(path, callback)
+
+* `path: String` - file path to be removed
+* `callback: Function(err) `
+ * `err: Error`
+
+Removes the file specified by `path` asynchronously.
+
+
+#### fs.unlinkSync(path)
+
+* `path: String` - file path to be removed
+
+Removes the file specified by `path` synchronously.
diff --git a/docs/api/IoT.js-API-GPIO.md b/docs/api/IoT.js-API-GPIO.md
new file mode 100644 (file)
index 0000000..487abfa
--- /dev/null
@@ -0,0 +1,194 @@
+### Platform Support
+
+The following shows GPIO module APIs available for each platform.
+
+|  | Linux<br/>(Ubuntu) | Raspbian<br/>(Raspberry Pi) | Nuttx<br/>(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 |
+
+
+## Contents
+* [Pin](#pin)
+* [GPIO](#gpio)
+  * [Constructor](#gpio-constructor)
+    * [`new GPIO()`](#gpio-new)
+  * [Properties](#gpio-properties)
+    * [`DIRECTION`](#gpio-direction)
+    * [`MODE`](#gpio-mode)
+  * [Prototype methods](#gpio-prototype-methods)
+    * [`gpio.open(configuration[, callback])`](#gpio-open)
+* [GPIOPin](#gpiopin)
+  * [Prototype methods](#gpiopin-prototype-methods)
+    * [`gpiopin.write(value[, callback])`](#gpiopin-write)
+    * [`gpiopin.writeSync(value)`](#gpiopin-write-sync)
+    * [`gpiopin.read([callback])`](#gpiopin-read)
+    * [`gpiopin.readSync()`](#gpiopin-read-sync)
+    * [`gpiopin.close([callback])`](#gpiopin-close)
+    * [`gpiopin.closeSync()`](#gpiopin-close-sync)
+
+
+## `Pin` <a name="pin"></a>
+
+* On Linux, pin number is logical number starts from 1. Thus logical pin number *k* is not necessarily bound to physical pin number *k* in your board.
+* On Nuttx, you have to know pin number. The pin number is defined in target board module. For more module information, please see below list.
+  * [STM32F4-discovery](../../targets/nuttx-stm32f4/Stm32f4dis.md#gpio-pin)
+
+
+## Class: GPIO <a name="gpio"></a>
+
+
+## Constructor <a name="gpio-constructor"></a>
+
+
+### `new GPIO()` <a name="gpio-new"></a>
+
+Returns a new GPIO object which can open all GPIO pins.
+
+
+## Properties <a name="gpio-properties"></a>
+
+
+### `DIRECTION`<a name="gpio-direction"></a>
+* `IN` - I/O input
+* `OUT` - I/O output
+
+
+### `MODE` <a name="gpio-mode"></a>
+* `NONE` - none
+* `PULLUP` - pull-up (only mode is input)
+* `PULLDOWN` - pull-down (only mode is input)
+* `FLOAT` - float (only mode is output)
+* `PUSHPULL` - push-pull (only mode is output)
+* `OPENDRAIN` - open drain (only mode is output)
+
+
+## Prototype methods <a name="gpio-prototype-methods"></a>
+
+
+### `gpio.open(configuration[, callback])` <a name="gpio-open"></a>
+* `configuration <Object>`
+  * `pin <Number>`, pin number to configure, mandatory configuration
+  * `direction <GPIO.DIRECTION>`, direction of the pin, Default: `GPIO.DIRECTION.OUT`
+  * `mode <GPIO.MODE>`, pin mode, Default: `GPIO.MODE.NONE`
+* `callback <Function(err: Error | null)>`
+* Returns: `<GPIOPin>`
+
+Opens the specified GPIO pin and sets GPIO pin configuration.
+
+The mode option is not supported on Linux.
+
+`callback` will be called with the value. `err` is null on success, or Error on failure.
+
+ **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 <a name="gpiopin"></a>
+
+
+### Prototype methods <a name="gpiopin-prototype-methods"></a>
+
+
+### `gpiopin.write(value[, callback])` <a name="gpiopin-write"></a>
+* `value <Boolean>`
+* `callback <Function(err: Error | null)>`
+
+Writes out a boolean value to a GPIO pin asynchronously.
+
+`callback` will be called with the value. `err` is null on success, or Error on failure.
+
+**Example**
+```js
+gpio10.write(1, function(err) {
+  if (err) {
+    throw err;
+  }
+});
+```
+
+
+### `gpiopin.writeSync(value)` <a name="gpiopin-write-sync"></a>
+* `value <Boolean>`
+
+Writes out a boolean value to a GPIO pin synchronously.
+
+**Example**
+```js
+gpio10.writeSync(1);
+```
+
+
+### `gpiopin.read([callback])` <a name="gpiopin-read"></a>
+* `callback <Function(err: Error | null, value: Boolean)>`
+
+Reads a boolean value from a GPIO pin asynchronously.
+
+`callback` will be called with the value. `err` is null on success, or Error on failure.
+
+**Example**
+```js
+gpio10.read(function(err, value) {
+  if (err) {
+    throw err;
+  }
+  console.log('value:', value);
+});
+```
+
+
+### `gpiopin.readSync()` <a name="gpiopin-read-sync"></a>
+* Returns: `<Boolean>`
+
+Returns a boolean value from a GPIO pin synchronously.
+
+**Example**
+```js
+console.log('value:', gpio10.readSync());
+```
+
+
+### `gpiopin.close([callback])` <a name="gpiopin-close"></a>
+* `callback <Function(err: Error | null)>`
+
+Closes a GPIO pin asynchronously.
+
+`callback` will be called with the value. `err` is null on success, or Error on failure.
+
+**Example**
+```js
+gpio10.close(function(err) {
+  if (err) {
+    throw err;
+  }
+  console.log('gpio pin is closed');
+});
+```
+
+
+### `gpiopin.closeSync()` <a name="gpiopin-close-sync"></a>
+
+Closes a GPIO pin synchronously.
+
+**Example**
+```js
+gpio10.closeSync();
+console.log('gpio pin is closed');
+```
diff --git a/docs/api/IoT.js-API-HTTP.md b/docs/api/IoT.js-API-HTTP.md
new file mode 100644 (file)
index 0000000..0f45203
--- /dev/null
@@ -0,0 +1,219 @@
+# Module: http
+
+IoT.js provides HTTP to support HTTP server and client enabling users to receive/send HTTP request easily.
+
+## Methods
+### http.createServer(requestListener)
+* `requestListener: Function`
+* Return: `http.Server` instance
+
+
+### http.request(options[, callback])
+* `options: Object`
+* `callback: Function`
+* Return: `http.ClientRequest` instance
+
+### http.get(options[, callback])
+* `options: Object`
+* `callback: Function`
+* Return: `http.ClientRequest` instance
+
+Same as http.request except that `http.get` automatically call `req.end()` at the end.
+
+
+## Class: http.Server
+
+### Event
+
+#### 'request'
+* `request: http.IncomingMessage` instance.
+* `response: http.ServerResponse` instance.
+After request header is parsed, this event will be fired.
+
+#### 'connection'
+This event is emitted when new TCP connection is established.
+
+#### 'close'
+This event is emitted when server is closed.
+
+### Method
+
+#### 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.
+`callback` will be called when server has been bound.
+
+#### 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.
+
+#### 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.
+
+### Member Variable
+#### timeout
+Server's timeout value. Default value is 2 minutes.
+
+
+## Class: http.ClientRequest
+### Event
+
+#### 'response'
+* `response: http.IncomingMessage` instance
+
+This event is emitted when server's response header is parsed. ` http.IncomingMessage` object is passed as argument to handler.
+
+
+#### 'socket'
+* `Net.socket` instance
+
+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.
+
+### Method
+
+#### write(data[, callback])
+* `data: Buffer|String`
+* `callback: Function`
+
+Sends `data` as a request body. `callback` will be called when data is flushed.
+
+
+#### 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.
+
+
+
+#### 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.
+
+
+## Class: http.ServerResponse
+### Event
+#### 'end'
+This event is fired when no more data to be sent.
+
+#### 'close'
+When underlying connection is closed, 'close' event is emitted.
+
+#### 'finish'
+This event is emitted when the response has been sent. It does not guarantee that client has received data yet.
+
+### Method
+#### writeHead(statusCode[, statusMessage][, headers])
+* `statusCode: Number`
+* `statusMessage: String`
+* `headers: Object`
+
+Sets response's header. `headers` is a map between field and value in header.
+
+#### setHeader(name, value)
+* `name: String`
+* `value: `
+
+Sets response's header field(`name`) to `value`. If the field exists, it overwrites the existing value.
+
+#### getHeader(name)
+* `name: String`
+
+Returns `name` field of response's header
+
+#### removeHeader(name)
+* `name: String`
+
+Removes `name` field from response's header
+
+#### write(data[, callback])
+* `data: Buffer|String`
+* `callback: Function`
+
+Sends `data` as a response body. `callback` will be called when data is flushed.
+
+#### 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.
+
+#### 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.
+
+
+
+## Class: http.IncomingMessage
+
+http.IncomingMessage inherits [`Stream.readable`](IoT.js-API-Stream.md)
+
+### Event
+#### 'end'
+This event is fired when no more data to be received.
+
+#### 'close'
+When underlying connection is closed, 'close' event is emitted.
+
+### Method
+#### 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.
+
+
+
+### Member Variable
+#### headers
+HTTP header object.
+
+#### method
+Requests method as `String`
+
+#### url
+Requests URL as `String`
+
+#### statusCode
+HTTP response status code as `Number` of 3-digit.
+
+#### statusMessage
+HTTP response status message as `String`
+
+#### socket
+Underlying socket
diff --git a/docs/api/IoT.js-API-I2C.md b/docs/api/IoT.js-API-I2C.md
new file mode 100644 (file)
index 0000000..23e83fc
--- /dev/null
@@ -0,0 +1,234 @@
+## Platform Support
+
+The following shows i2c module APIs available for each platform.
+
+|  | Linux<br/>(Ubuntu) | Raspbian<br/>(Raspberry Pi) | Nuttx<br/>(STM32F4-Discovery) |
+| :---: | :---: | :---: | :---: |
+| i2c.open | O | O | O |
+| i2cbus.read | O | O | O |
+| i2cbus.readByte | O | O | O |
+| i2cbus.readBytes | O | O | O |
+| i2cbus.write | O | O | O |
+| i2cbus.writeByte | O | O | O |
+| i2cbus.writeBytes | O | O | O |
+| i2cbus.close | O | O | O |
+
+
+## Contents
+
+  * [I2C](#i2c)
+    * [Constructor](#constructor)
+      * [`new I2C()`](#new-i2c)
+    * [Prototype Methods](#i2c-prototype-methods)
+      * [`i2c.open(configurable[, callback])`](#i2c-open)
+  * [I2CBus](#i2cbus)
+    * [Prototype Methods](#i2cbus-prototype-methods)
+      * [i2cbus.read(length[, callback])](#i2cbus-read)
+      * [i2cbus.readByte([callback])](#i2cbus-readbyte)
+      * [i2cbus.readBytes(cmd, length[, callback])](#i2cbus-readbytes)
+      * [i2cbus.write(array[, callback])](#i2cbus-write)
+      * [i2cbus.writeByte(byte[, callback])](#i2cbus-writebyte)
+      * [i2cbus.writeBytes(cmd, array[, callback])](#i2cbus-writebytes)
+      * [i2cbus.close()](#i2cbus-close)
+
+
+## Class: I2C <a name="i2c"></a>
+
+The I2C class supports the I2C protocol. I2C bus has two signals - SDA and SCL.
+
+
+## Constructor <a name="constructor"></a>
+
+
+### `new I2C()` <a name="new-i2c"></a>
+
+Create I2C object.
+
+**Example**
+
+```js
+var I2C = require('i2c');
+
+var i2c = new I2C();
+```
+
+
+## Prototype Methods <a name="i2c-prototype-methods"></a>
+
+
+### `i2c.open(configuration[, callback])` <a name="i2c-open"></a>
+* `configuration <Object>`, configuration for open I2CBus
+  * `device <String(linux)|Number(nuttx)>`, device path
+  * `address <Number>`
+* `callback <Function(err: Error)>`
+* Returns: `<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 <a name="i2cbus"></a>
+
+
+## Prototype Methods <a name="i2cbus-prototype-methods"></a>
+
+
+### `i2cbus.read(length[, callback])` <a name="i2cbus-read"></a>
+* `length <Number>`, the number of bytes.
+* `callback <Function(err: Error, res: Array)>`, `res` contains an 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.readByte([callback])` <a name="i2cbus-readbyte"></a>
+* `callback <Function(err: Error, res: Array)>`, `res` contains an array of bytes.
+
+Read one byte 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.readByte(function(err, res) {
+  if(!err) {
+    console.log('readByte result: ' + res);
+  }
+});
+```
+
+
+### `i2cbus.readBytes(cmd, length[, callback])` <a name="i2cbus-readbytes"></a>
+* `command <Number>`
+* `length <Number>`, the number of bytes
+* `callback <Function(err: Error, res: Array)>`, `res` contains an array of bytes.
+
+Read bytes from I2C device with command.
+
+**Example**
+
+```js
+var I2C = require('i2c');
+
+var i2c = new I2C();
+var i2c_bus = i2c.open({device: '/dev/i2c-1', address: 0x23});
+
+i2c_bus.readBytes(0x20, 2, function(err, res) {
+  if(!err) {
+    console.log('readBytes result: ' + res);
+  }
+});
+```
+
+
+### `i2cbus.write(array[, callback])` <a name="i2cbus-write"></a>
+* `bytes <Array>`, an array of numbers
+* `callback <Function(err: Error)>`
+
+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.writeByte(byte[, callback])` <a name="i2cbus-writebyte"></a>
+ * `byte <Number>`
+ * `callback <Function(err: Error)>`
+
+Write one byte 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.writeByte(0x10, function(err) {
+  if(!err) {
+    console.log('writeByte done');
+  } 
+});
+```
+
+
+### `i2cbus.writeBytes(cmd, array[, callback])` <a name="i2cbus-writebytes"></a>
+ * `command <Number>`
+ * `bytes <Array>`, an array of numbers
+ * `callback <Function(err: Error)>`
+
+Write bytes to I2C device with command.
+
+**Example**
+
+```js
+var I2C = require('i2c');
+
+var i2c = new I2C();
+var i2c_bus = i2c.open({device: '/dev/i2c-1', address: 0x23});
+
+i2c_bus.writeBytes(0x10, [0x10], function(err) {
+  if(!err) {
+    console.log('writeBytes done');
+  }
+});
+```
+
+
+### `i2cbus.close()` <a name="i2cbus-close"></a>
+
+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();
+```
diff --git a/docs/api/IoT.js-API-Module.md b/docs/api/IoT.js-API-Module.md
new file mode 100644 (file)
index 0000000..38ac4c1
--- /dev/null
@@ -0,0 +1,35 @@
+## Module
+``` module ``` implements ``` require ``` function.
+Since ``` require ``` function is implicitly passed to user code, user do not need to import it explicitly.
+
+### Methods
+
+#### require(id)
+* ``` id : String ``` - module name to be loaded
+
+Loads the module named 'id'
+
+
+### Module Loading by ``` require ``` function
+
+#### ``` require ``` search paths
+``` require ``` function finds modules in the order of
+
+1. current working directory
+2. node_modules directory under current working directory
+3. $HOME/node_modules
+4. $NODE_PATH/node_modules
+
+
+#### ``` require('id') ``` works as follows:
+For each directory in search paths above,
+
+0. If native module named 'id' exists, load it and return.
+1. If id.js file exists, load it and return.
+2. If a directory id exists, load it as an package and return.
+
+#### ``` require('id') ``` as a package
+For a given id, if a directory id exists, module system consider the directory as a package.
+
+0. if 'id/node_modules/package.json' contains 'main' property, load the file named main property.
+1. if either id/node_modules/package.json or main property exists, load index.js
diff --git a/docs/api/IoT.js-API-Net.md b/docs/api/IoT.js-API-Net.md
new file mode 100644 (file)
index 0000000..401b4e5
--- /dev/null
@@ -0,0 +1,256 @@
+## Module: net
+
+### Platform Support
+
+The following shows net module APIs available for each platform.
+
+|  | Linux<br/>(Ubuntu) | Raspbian<br/>(Raspberry Pi) | Nuttx<br/>(STM32F4-Discovery) |
+| :---: | :---: | :---: | :---: |
+| net.createServer | O | O | O |
+| net.connect | O | O | O |
+| net.createConnection | O | O | O |
+| net.Server.listen | O | O | O |
+| net.Server.close | O | O | O |
+| net.Socket.connect | O | O | O |
+| net.Socket.write | O | O | O |
+| net.Socket.end | O | O | O |
+| net.Socket.destroy | O | O | O |
+| net.Socket.pause | O | O | O |
+| net.Socket.resume | O | O | O |
+| net.Socket.setTimeout | O | O | O |
+| net.Socket.setKeepAlive | X | X | X |
+
+※ 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.
+
+IoT.js provides asynchronous networking through Net module.
+
+You can use this module with `require('net')` and create both servers and clients.
+
+### Module Functions
+
+#### net.connect(options[, connectListener])
+#### net.connect(port[, host][, connectListener])
+#### net.createConnection(options[, connectListener])
+#### net.createConnection(port[, host][, connectListener])
+* `options: Object`
+* `port: Number`
+* `host: String`, Default: `localhost`
+* `connectListener: Function()`
+
+Creates a `net.Socket` and connects to the supplied host.
+
+It is equivalent to `new net.Socket()` followed by `socket.connect()`.
+
+
+#### net.createServer([options][, connectionListener])
+* `options: Object`
+* `connectionListener: Function(connection: net.Socket)`
+
+Creates a TCP server according to `options`.
+
+`connectionListener` is automatically registered as `connection` event listener.
+
+
+***
+
+## class: net.Server
+
+You can create `net.Server` instance with `net.createServer()`.
+
+
+### Events
+
+#### `'close'`
+* `callback: Function()`
+
+Emitted when server closed.
+
+Note that this event will be emitted after all existing connections are closed.
+
+
+#### `'connection(socket)'`
+* `callback: Function(socket)`
+ * `socket: net.Socket`
+
+Emitted when new connection is established.
+
+
+#### `'error'`
+* `callback: Function()`
+
+Emitted when an error occurs.
+
+
+#### `'listening'`
+* `callback: Function()`
+
+Emitted when server has been started listening.
+
+
+### Methods
+
+#### server.close([closeListener])
+* `closeListener: Function()`
+
+Stops listening new arriving connection.
+
+Server socket will finally close when all existing connections are closed, then emit 'close' event.
+
+`closeListener` is registered as `close` event listener.
+
+
+#### server.listen(port[, host][, backlog][, listenListener])
+#### server.listen(options[, listenListener])
+* `port: Number`
+* `host: String`
+* `backlog: Number`
+* `listenListener: Function()`
+
+Starts listening and accepting connections on specified port and host.
+
+
+***
+
+## class: net.Socket
+
+net.Socket inherits [`Stream.Duplex`](IoT.js-API-Stream.md)
+
+### Constructor
+
+#### new net.Socket([options])
+* `options: Object`
+
+Creates a new socket object.
+
+`options` is an object specifying following information:
+
+* `allowHalfOpen: Boolean`
+
+
+
+### Events
+
+
+#### `'connect'`
+* `callback: Function()`
+
+Emitted after connection is established.
+
+
+#### `'close'`
+* `callback: Function()`
+
+Emitted when the socket closed.
+
+
+#### `'data'`
+* `callback: Function(data)`
+ * `data: Buffer | String`
+
+Emitted when data is received from the connection.
+
+
+#### `'drain'`
+* `callback: Function()`
+
+Emitted when the write buffer becomes empty.
+
+
+#### `'end'`
+* `callback: Function()`
+
+Emitted when FIN packet received.
+
+
+#### `'error'`
+* `callback: Function()`
+
+Emitted when an error occurs.
+
+
+#### `'lookup'`
+* `callback: Function(err, address, family)`
+ * `err: Error | Null`
+ * `address: String`
+ * `family: String | Null`
+
+Emitted after resolving hostname.
+
+
+#### `'timeout'`
+* `callback: Function()`
+
+Emitted when the connection remains idle for specified timeout.
+
+
+### Methods
+
+#### socket.connect(options[, connectListener])
+#### socket.connect(port[, host][, connectListener])
+* `options: Object`
+* `port: Number`
+* 'host: String`, Default: `'localhost'`
+
+Opens the connection with supplied port and host.
+
+`options` is an object specifying following information:
+* `port: Number` - port connect to (required)
+* `host: String` - host connect to (optional, default: `'127.0.0.1'`)
+
+`connectionListener` is automatically registered as `connect` event listener which will be emitted when the connection is established.
+
+
+#### socket.destroy()
+
+Destroys the socket.
+
+
+#### socket.end([data][, callback])
+
+* `data: String | Buffer`
+* `callback: Function()`
+
+Half-closes the socket.
+
+If `data` is given it is equivalent to `socket.write(data)` followed by `socket.end()`.
+
+* `data: String | Buffer`
+
+
+#### socket.pause()
+
+Pauses reading data.
+
+
+#### socket.resume()
+
+Resumes reading data after a call to `pause()`.
+
+
+#### socket.setKeepAlive([enable][, initialDelay])
+
+* `enable: Boolean`
+* `initialDelay: Number`, Default: `0`
+
+Enables or disables keep-alive functionality.
+
+
+#### socket.setTimeout(timeout[, callback])
+* `timeout: Number`
+* `callback: Function()`
+
+Sets timeout for the socket.
+
+If the socket is inactive for `timeout` milliseconds, `'timeout'` event will emit.
+
+`callback` is registered as `timeout` event listener.
+
+
+#### socket.write(data[, callback])
+* `data: String | Buffer`
+* `callback: Function()`
+
+Sends `data` on the socket.
+
+`callback` function will be called after given data is flushed through the connection.
diff --git a/docs/api/IoT.js-API-PWM.md b/docs/api/IoT.js-API-PWM.md
new file mode 100644 (file)
index 0000000..4edfbb3
--- /dev/null
@@ -0,0 +1,247 @@
+### Platform Support
+
+The following shows PWM module APIs available for each platform.
+
+|  | Linux<br/>(Ubuntu) | Raspbian<br/>(Raspberry Pi) | Nuttx<br/>(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 |
+
+
+## Contents
+* [Pin](#pin)
+* [PWM](#pwm)
+  * [Constructor](#pwm-constructor)
+    * [`new PWM()`](#pwm-new)
+  * [Prototype methods](#pwm-prototype-methods)
+    * [`pwm.open(configuration[, callback])`](#pwm-open)
+* [PWMPin](#pwmpin)
+  * [Prototype methods](#pwmpin-prototype-methods)
+    * [`pwmpin.setPeriod(period[, callback])`](#pwmpin-period)
+    * [`pwmpin.setPeriodSync(period)`](#pwmpin-period-sync)
+    * [`pwmpin.setFrequency(frequency[, callback])`](#pwmpin-frequency)
+    * [`pwmpin.setFrequencySync(frequency)`](#pwmpin-frequency-sync)
+    * [`pwmpin.setDutyCycle(dutyCycle[, callback])`](#pwmpin-dutycycle)
+    * [`pwmpin.setDutyCycleSync(dutyCycle)`](#pwmpin-dutycycle-sync)
+    * [`pwmpin.setEnable(enable[, callback])`](#pwmpin-enable)
+    * [`pwmpin.setEnableSync(enable)`](#pwmpin-enable-sync)
+    * [`pwmpin.close([callback])`](#pwmpin-close)
+    * [`pwmpin.closeSync()`](#pwmpin-close-sync)
+
+
+### `pin` <a name="pin"></a>
+* On Linux, `pin` is a pwm 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-stm32f4/Stm32f4dis.md#pwm-pin)
+
+
+## Class: PWM <a name="pwm"></a>
+
+
+## Constructor <a name="pwm-constructor"></a>
+
+
+### `new PWM()` <a name="pwm-new"></a>
+
+Returns a new PWM object which can open PWM pin.
+
+
+## Prototype methods <a name="pwm-prototype-methods"></a>
+
+
+### `pwm.open(configuration[, callback])` <a name="pwm-open"></a>
+* `configuration <Object>`
+  * `pin <Number>`, mandatory configuration
+  * `chip <Number>`, chip number, Default: 0, only Linux configuration
+  * `period <Number>`, seconds(positive integer) 
+  * `frequency <Number>`, Hz(positive integer)
+  * `dutyCycle <Number>`, between 0 and 1
+* `callback <Function(err: Error | null)>`
+* Returns: `<PWMPin>`
+
+Opens PWM pin with the specified configuration.
+
+
+**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() {
+  if (err) {
+    throw err;
+  }
+});
+```
+
+
+## Class: PWMPin <a name="pwmpin"></a>
+
+
+## Prototype methods <a name="pwmpin-prototype-methods"></a>
+
+
+### `pwmpin.setPeriod(period[, callback])` <a name="pwmpin-period"></a>
+* `period <Number>`, seconds(positive integer) 
+* `callback <Function(err: Error | null)>`
+
+Sets period that is the duration of one cycle in a repeating signal. It is given in seconds asynchronously.
+
+`callback` will be called after period is set.
+
+**Example**
+```js
+pwm0.setPeriod(1, function(err) {
+  if (err) {
+    throw err;
+  }
+  console.log('done');
+});
+```
+
+
+### `pwmpin.setPeriodSync(period)` <a name="pwmpin-period-sync"></a>
+* `period <Number>`, seconds(positive integer) 
+
+Sets period that is the duration of one cycle in a repeating signal synchronously.
+
+**Example**
+```js
+pwm0.setPeriodSync(1);
+console.log('done');
+```
+
+
+### `pwmpin.setFrequency(frequency[, callback])` <a name="pwmpin-frequency"></a>
+* `frequency <Number>`, Hz(positive integer)
+* `callback <Function(err: Error | null)>`
+
+Sets frequency that is a measurement of how often repeating signal per unit time asynchronously.
+
+`callback` will be called after frequency is set.
+
+**Example**
+```js
+pwm0.setFrequency(1, function(err) {
+  if (err) {
+    throw err;
+  }
+  console.log('done');
+});
+```
+
+
+### `pwmpin.setFrequencySync(frequency)` <a name="pwmpin-frequency-sync"></a>
+* `frequency <Number>`, Hz(positive integer)
+
+Sets frequency that is a measurement of how often repeating signal per unit time synchronously.
+
+**Example**
+```js
+pwm0.setFrequencySync(1);
+console.log('done');
+```
+
+
+### `pwmpin.setDutyCycle(dutyCycle[, callback])` <a name="pwmpin-dutycycle"></a>
+* `dutyCycle <Number>`, between 0 and 1
+* `callback <Function(err: Error | null)>`
+
+Sets duty cycle that is the ratio of pulse width in one period asynchronously.
+
+`callback` will be called after duty-cycle is set.
+
+**Example**
+```js
+pwm0.setDutyCycle(1, function(err) {
+  if (err) {
+    throw err;
+  }
+  console.log('done');
+});
+```
+
+
+### `pwmpin.setDutyCycleSync(dutyCycle)` <a name="pwmpin-dutycycle-sync"></a>
+* `dutyCycle <Number>`, between 0 and 1
+
+Sets duty cycle that is the ratio of pulse width in one period synchronously.
+
+**Example**
+```js
+pwm0.setDutyCycleSync(1);
+console.log('done');
+```
+
+
+### `pwmpin.setEnable(enable[, callback])` <a name="pwmpin-enable"></a>
+* `enable <Boolean>`
+* `callback <Function(err: Error | null)>`
+
+Enables or Disables PWM asynchronously.
+
+`callback` will be called after enable is set.
+
+**Example**
+```js
+pwm0.setEnable(true, function(err) {
+  if (err) {
+    throw err;
+  }
+  console.log('done');
+});
+```
+
+
+### `pwmpin.setEnableSync(enable)` <a name="pwmpin-enable-sync"></a>
+* `enable <Boolean>`
+
+Enables or Disables PWM synchronously.
+
+**Example**
+```js
+pwm0.setEnableSync(false);
+console.log('done');
+```
+
+
+### `pwmpin.close([callback])` <a name="pwmpin-close"></a>
+* `callback <Function(err: Error | null)>`
+
+Closes PWM pin asynchronously.
+
+`callback` will be called after PWM device is released.
+
+**Example**
+```js
+pwm0.close(function(err) {
+  if (err) {
+    throw err;
+  }
+  console.log('done');
+});
+```
+
+
+### `pwmpin.closeSync()` <a name="pwmpin-close-sync"></a>
+
+Closes PWM pin synchronously.
+
+**Example**
+```js
+pwm0.closeSync();
+console.log('done');
+```
\ No newline at end of file
diff --git a/docs/api/IoT.js-API-Process.md b/docs/api/IoT.js-API-Process.md
new file mode 100644 (file)
index 0000000..ae6b98b
--- /dev/null
@@ -0,0 +1,86 @@
+## process
+
+### Platform Support
+
+The following shows process module APIs available for each platform.
+
+|  | Linux<br/>(Ubuntu) | Raspbian<br/>(Raspberry Pi) | Nuttx<br/>(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` is unique global object can be accessed from anywhere.
+
+### Events
+
+
+#### `'exit'`
+* `callback: Function(code)`
+ * `code: Number - exitCode`
+
+Emitted when IoT.js process is about to exit.
+
+
+#### `'uncaughtException'`
+* `callback: Function(err)`
+ * `err: Error - error object uncaught by catch handler`
+
+Emitted there's no catch handler for exception.
+
+
+### Methods
+
+
+#### process.chdir(path)
+* `path: String`
+
+Changes current working directory to `path`.
+
+
+#### process.cwd()
+
+Returns current working directory.
+
+
+#### process.exit(code)
+* `code: Number - exitCode`
+
+Exits executing process with code.
+
+
+#### process.nextTick(callback)
+* `callback: Function()`
+
+After current event loop finished, calls the `callback` function. The next tick callback will be called before any I/O events.
+
+
+### Member Variable
+
+
+#### `'arch'`
+
+Target Arch, one of (`arm`|`ia32`|`x64`|`unknown`)
+
+
+#### `'argv'`
+
+Argument vector to be passed to IoT.js
+
+
+#### `'board'`
+
+Target Board, one of (`STM32F4DIS`|`RP2`|`unknown`)
+
+
+#### `'env'`
+
+Environment object holding `HOME` and `NODE_PATH`. On NuttX `NODE_PATH` is `/mnt/sdcard` in default.
+
+
+#### `'platform'`
+
+Target Platform, one of (`linux`|`nuttx`|`darwin`|`unknown`)
diff --git a/docs/api/IoT.js-API-SPI.md b/docs/api/IoT.js-API-SPI.md
new file mode 100644 (file)
index 0000000..6032bed
--- /dev/null
@@ -0,0 +1,170 @@
+### Platform Support
+
+The following shows spi module APIs available for each platform.
+
+|  | Linux<br/>(Ubuntu) | Raspbian<br/>(Raspberry Pi) | Nuttx<br/>(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 |
+
+
+## Contents
+* [SPI](#spi)
+  * [Constructor](#spi-constructor)
+    * [`new SPI()`](#spi-new)
+  * [Properties](#spi-properties)
+    * [`MODE`](#spi-mode)
+    * [`CHIPSELECT`](#spi-chipselect)
+    * [`BITORDER`](#spi-bitorder)
+  * [Prototype methods](#spi-prototype-methods)
+    * [`spi.open(configuration[, callback])`](#spi-open)
+* [SPIBus](#spibus)
+  * [Prototype methods](#spibus-prototype-methods)
+    * [`spibus.transfer(tx, rx[, callback])`](#spibus-transfer)
+    * [`spibus.transferSync(tx, rx)`](#spibus-transfer-sync)
+    * [`spibus.close([callback])`](#spibus-close)
+    * [`spibus.closeSync()`](#spibus-close-sync)
+
+
+## Class: SPI <a name="spi"></a>
+
+
+## Constructor <a name="spi-constructor"></a>
+
+
+### `new SPI()` <a name="spi-new"></a>
+
+Returns a new SPI object which can open SPI bus.
+
+
+## Properties <a name="spi-properties"></a>
+
+
+### `MODE`<a name="spi-mode"></a>
+* `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)
+
+
+### `CHIPSELECT`<a name="spi-chipselect"></a>
+* `NONE`
+* `HIGH` - chip select active high
+
+
+### `BITORDER`<a name="spi-bitorder"></a>
+* `MSB` - most significant bit
+* `LSB` - least significant bit
+
+
+## Prototype methods <a name="spi-prototype-methods"></a>
+
+
+### `spi.open(configuration[, callback])` <a name="spi-open"></a>
+* `configuration <Object>`
+  * `device <String>`, the specified path for `spidev`
+  * `mode <SPI.MODE>`, the combinations of polarity and phases, Default: `SPI.MODE[0]`
+  * `chipSelect <SPI.CHIPSELECT>`, Default: `SPI.CHIPSELECT.NONE`
+  * `maxSpeed <Number>`, max transfer speed, Default: `500000`
+  * `bitsPerWord <Number>`, bits per word to send, should be 8 or 9, Default: `8`
+  * `bitOrder <SPI.bitORDER>`, Default: `SPI.BITORDER.MSB`
+  * `loopback <Boolean>`, Default: `false`
+* `callback <Function(err: Error | null)>`
+* Returns: `<SPIBus>`
+
+Opens 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 <a name="spibus"></a>
+
+
+## Prototype methods <a name="spibus-prototype-methods"></a>
+
+
+### `spibus.transfer(txBuffer, rxBuffer[, callback])` <a name="spibus-transfer"></a>
+* `txBuffer <Array | Buffer>`
+* `rxBuffer <Array | Buffer>`
+* `callback <Function(err: Error | null)>`
+
+Writes and reads data from SPI device asynchronously.
+`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)` <a name="spibus-transfer-sync"></a>
+* `txBuffer <Array | Buffer>`
+* `rxBuffer <Array | Buffer>`
+
+Writes and reads data from SPI device synchronously.
+`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])` <a name="spibus-close"></a>
+* `callback <Function(err: Error | null)>`
+
+Closes SPI device asynchronously.
+
+`callback` will be called after SPI device is closed.
+
+**Example**
+```js
+spi0.close(function(err) {
+  if (err) {
+    throw err;
+  }
+  console.log('spi bus is closed');
+});
+```
+
+
+### `spibus.closeSync()` <a name="spibus-close-sync"></a>
+
+Closes SPI device synchronously.
+
+**Example**
+```js
+spi.closeSync();
+console.log('spi bus is closed');
+```
diff --git a/docs/api/IoT.js-API-Stream.md b/docs/api/IoT.js-API-Stream.md
new file mode 100644 (file)
index 0000000..54bde7c
--- /dev/null
@@ -0,0 +1,107 @@
+## Class: Stream.Readable
+
+Readable stream is abstraction for data source from which data will be read.
+
+At any time a readable stream is in one of two state: **flowing** and **paused**. In paused state, readable stream emits `'readable'` event for you that indicates there are data ready for read. and then you can explicitly call `stream.read()` to get the data form the stream. In flowing state, readable stream emits `'data'` event with actual data that you can receive data as fast as possible. All streams start out in paused mode.
+
+### Events
+
+
+#### 'close'
+* `callback: Function()`
+
+Emitted when the underlying resource has been closed.
+
+
+#### 'data'
+* `callback: Function(chunk)`
+ * `chunk: Buffer | String`
+
+Readable stream emits this event when a chunk of data prepared to be read.
+This event only emitted when the stream is in flowing state.
+
+Attaching a `data` event listener to a stream makes the stream to be switched to flowing mode.
+
+
+#### 'end'
+* `callback: Function()`
+
+This event is only fired when there will be no more data to read.
+
+
+#### 'readable'
+* `callback: Function()`
+
+Readable stream emits this event when a chunk of data prepared to be read.
+This event only emitted when the stream is in paused state.
+
+
+### Methods
+
+
+#### readable.isPaused()
+Returns `true` if the readable stream is in paused mode.
+
+
+#### readable.pause()
+Pause emitting `data` events if the stream was in flowing mode
+
+
+#### readable.read([size])
+* `size | Number` - specifies how much data will be read
+
+Reads data from readable stream, and returns the data as `String | Buffer`
+
+
+#### readable.resume()
+Resume emitting `data` events if the readable was paused.
+
+
+***
+
+## Class: stream.Writable
+
+Writable stream is abstraction for target that you can write data to.
+
+
+### Events
+
+#### 'drain'
+* `callback: Function()`
+
+If `writable.write()` returns false, `drain` events will indicate you that the stream is ready to be written.
+
+
+#### 'error'
+* `callback: Function(err)`
+ * `err: Error`
+
+Emitted if there were something wrong writing data.
+
+
+#### 'finish'
+* `callback: Function()`
+
+After `writable.end()` has been called, and all data has been flushed, this event will be fired.
+
+
+### Methods
+
+
+#### writable.end([chunk][, callback])
+* `chunk: String | Buffer` - The data to write
+* `callback: Function()` - Function callback for when the chunk of data is flushed.
+
+
+#### writable.write(chunk[, callback])
+* `chunk: String | Buffer` - The data to write
+* `callback: Function()` - Function callback for when the chunk of data is flushed.
+* Returns: `Boolean`
+
+This method writes `chunk` of data to the underlying system, when the data is flush it calls back the `callback` function.
+If you can write right after calling this method, it will return `true`, otherwise, return `false`.
+
+***
+
+## Class: Stream.Duplex
+Duplex streams are streams that implement both the Readable and Writable interfaces.
diff --git a/docs/api/IoT.js-API-Timers.md b/docs/api/IoT.js-API-Timers.md
new file mode 100644 (file)
index 0000000..1e658a1
--- /dev/null
@@ -0,0 +1,38 @@
+## Module: timers
+
+### Platform Support
+
+The following shows timers module APIs available for each platform.
+
+|  | Linux<br/>(Ubuntu) | Raspbian<br/>(Raspberry Pi) | Nuttx<br/>(STM32F4-Discovery) |
+| :---: | :---: | :---: | :---: |
+| setTimeout | O | O | O |
+| clearTimeout | O | O | O |
+| setInterval | O | O | O |
+| clearInterval | O | O | O |
+
+### Methods
+
+#### setTimeout(callback, delay[, args..])
+* `callback: Function([args..])`
+* `delay: Int`
+* Return: `timeoutObject`
+
+Schedules to call one-time to `callback` function after `delay` milliseconds.
+
+#### clearTimeout(timeoutObject)
+* `timeoutObject: timeoutObject` - A `timeoutObject` returned from `setTimeout()`
+
+Disables timeout call from `setTimeout` method.
+
+#### setInterval(callback, delay[, args..])
+* `callback: Function([args..])`
+* `delay: Int`
+* Return: `intervalObject`
+
+Schedules to call periodic to `callback` function after every `delay` milliseconds.
+
+#### clearInterval(intervalObject)
+* `intervalObject: intervalObject` - A `intervalObject` returned from `setInterval`
+
+Disables timeout call from `setInterval` method.
diff --git a/docs/api/IoT.js-API-UART.md b/docs/api/IoT.js-API-UART.md
new file mode 100644 (file)
index 0000000..df58d4e
--- /dev/null
@@ -0,0 +1,134 @@
+### Platform Support
+
+The following shows uart module APIs available for each platform.
+
+|  | Linux<br/>(Ubuntu) | Raspbian<br/>(Raspberry Pi) | Nuttx<br/>(STM32F4-Discovery) |
+| :---: | :---: | :---: | :---: |
+| uart.open | O | O | O |
+| uartport.write | O | O | O |
+| uartport.writeSync | O | O | O |
+| uartport.close | O | O | O |
+| uartport.closeSync | O | O | O |
+
+
+## Contents
+  * [UART](#uart)
+    * [Constructor](#uart-constructor)
+      * [`new UART()`](#new-uart)
+    * [Prototype Methods](#uart-prototype-methods)
+      * [`uart.open(configurable[, callback])`](#uart-open)
+  * [UARTPort](#uartport)
+    * [Prototype Methods](#uartport-prototype-methods)
+      * [`uartport.write(data[, callback])`](#uartport-write)
+      * [`uartport.writeSync(data)`](#uartport-write-sync)
+      * [`uartport.close([callback])`](#uartport-close)
+      * [`uartport.closeSync()`](#uartport-close-sync)
+    * [Event](#uartport-event)
+
+
+## Class: UART <a name="uart"></a>
+
+
+## Constructor <a name="uart-constructor"></a>
+
+
+### `new UART()` <a name="uart-new"></a>
+
+Returns a new UART object which can open UART port.
+
+
+## Prototype methods <a name="uart-prototype-methods"></a>
+
+
+### `uart.open(configuration[, callback])` <a name="uart-open"></a>
+* `configuration <Object>`
+  * `device <String>`, mandatory configuration
+  * `baudRate <Number> (Default value is 9600)`
+  * `dataBits <Number> (Default value is 8)`
+* `callback <Function(err: Error | null)>`
+* Returns: `<UARTPort>`
+
+On Nuttx, you can set the properties of `configuration` only on Nuttx config. `Device Drivers -> Serial Driver Support -> U[S]ART(N) Configuration` will help. And if you want to get information about `device`, please see below list.
+  * [STM32F4-discovery](../../targets/nuttx-stm32f4/Stm32f4dis.md#uart)
+
+Opens UART port with the specified configuration. Following methods can be called with UARTPort object.
+
+
+**Example**
+```javascript
+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 <a name="uartport"></a>
+
+
+## Prototype methods <a name="uartport-prototype-methods"></a>
+
+
+### `uartport.write(data[, callback])` <a name="uartport-write"></a>
+* `data <String>`
+* `callback <Function(err: Error | null)>`
+
+Writes data to UART device asynchronously.
+
+**Example**
+```javascript
+serial.write("Hello?", function(err) {
+  if (err) {
+    // Do something.
+  }
+  serial.close();
+});
+```
+
+### `uartport.writeSync(data)` <a name="uartport-write-sync"></a>
+* `data <String>`
+
+Writes data to UART device synchronously.
+
+**Example**
+```javascript
+serial.writeSync("Hello?");
+serial.close();
+```
+
+
+### `uartport.close([callback])` <a name="uartport-close"></a>
+* `callback <Function(err: Error | null)>`
+
+Closes UART device asynchronously.
+
+
+### `uartport.closeSync()` <a name="uartport-close-sync"></a>
+
+Closes UART device synchronously.
+
+
+## Events <a name="uartport-event"></a>
+
+
+### `'data'`
+* `callback <Function(data)>`
+
+ `data` is a string from sender
+
+For example,
+```javascript
+...
+serial.on('data', function(data) {
+  console.log('read result: ' + data.toString());
+});
+
+```
\ No newline at end of file
diff --git a/docs/api/IoT.js-API-reference.md b/docs/api/IoT.js-API-reference.md
new file mode 100644 (file)
index 0000000..d2ad978
--- /dev/null
@@ -0,0 +1,27 @@
+# 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
diff --git a/docs/build/Build-Script.md b/docs/build/Build-Script.md
new file mode 100644 (file)
index 0000000..aee48b3
--- /dev/null
@@ -0,0 +1,244 @@
+## 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/<arch-os>/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.
\ No newline at end of file
diff --git a/docs/build/Build-for-ARTIK.md b/docs/build/Build-for-ARTIK.md
new file mode 100644 (file)
index 0000000..7b0729d
--- /dev/null
@@ -0,0 +1,38 @@
+## 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
+```
+
diff --git a/docs/build/Build-for-Linux.md b/docs/build/Build-for-Linux.md
new file mode 100644 (file)
index 0000000..039f5e4
--- /dev/null
@@ -0,0 +1,204 @@
+### 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 ./test/run_pass/test_console.js --memstat
+```
+
+With given `show-opcodes` option, opcodes will be shown.
+```
+./build/x86_64-linux/debug/iotjs/iotjs ./test/run_pass/test_console.js --show-opcodes
+```
+
+### 4. Clean build directory
+
+Just remove the folder as follows;
+```
+rm -rf build
+rm -rf deps/libuv/out
+```
diff --git a/docs/build/Build-for-NuttX.md b/docs/build/Build-for-NuttX.md
new file mode 100644 (file)
index 0000000..453aa52
--- /dev/null
@@ -0,0 +1,134 @@
+## 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-stm32f4/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-stm32f4/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 <kbd>Ctrl-A</kbd> + <kbd>Z</kbd> + <kbd>U</kbd> for short in minicom screen. (For linux user)
+* Press <kbd>[Meta](http://osxdaily.com/2013/02/01/use-option-as-meta-key-in-mac-os-x-terminal/)</kbd> + <kbd>Z</kbd> 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.
diff --git a/docs/build/Build-for-RPi2.md b/docs/build/Build-for-RPi2.md
new file mode 100644 (file)
index 0000000..41676ef
--- /dev/null
@@ -0,0 +1,142 @@
+## 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/iotjs/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
+```
diff --git a/docs/devs/Enabling-Experimental-Feature.md b/docs/devs/Enabling-Experimental-Feature.md
new file mode 100644 (file)
index 0000000..b905bde
--- /dev/null
@@ -0,0 +1,59 @@
+# 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.
diff --git a/docs/devs/Inside-IoT.js-Validated-Struct.md b/docs/devs/Inside-IoT.js-Validated-Struct.md
new file mode 100644 (file)
index 0000000..97341be
--- /dev/null
@@ -0,0 +1,195 @@
+Validated 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.
+
+
diff --git a/docs/devs/Inside-IoT.js.md b/docs/devs/Inside-IoT.js.md
new file mode 100644 (file)
index 0000000..e904713
--- /dev/null
@@ -0,0 +1,292 @@
+Inside 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.
diff --git a/docs/devs/IoT.js-Package-(outdated).md b/docs/devs/IoT.js-Package-(outdated).md
new file mode 100644 (file)
index 0000000..0a5d944
--- /dev/null
@@ -0,0 +1,121 @@
+**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 email address> (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 <package name>
+(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 <keyword>
+```
+
+If you omit the keyword, it'll list all packages registered.
diff --git a/docs/devs/Logging-IoT.js-execution.md b/docs/devs/Logging-IoT.js-execution.md
new file mode 100644 (file)
index 0000000..c835527
--- /dev/null
@@ -0,0 +1,33 @@
+### 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.
diff --git a/docs/devs/Memory-savings-with-libtuv.md b/docs/devs/Memory-savings-with-libtuv.md
new file mode 100644 (file)
index 0000000..ca1f64b
--- /dev/null
@@ -0,0 +1,241 @@
+Memory 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 bytes
\ No newline at end of file
diff --git a/docs/devs/Optimization-Tips.md b/docs/devs/Optimization-Tips.md
new file mode 100644 (file)
index 0000000..8424be6
--- /dev/null
@@ -0,0 +1,48 @@
+Optimization 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 test.js --memstat
+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;
+```
diff --git a/docs/devs/Writing-New-Builtin-Module.md b/docs/devs/Writing-New-Builtin-Module.md
new file mode 100644 (file)
index 0000000..ceb1170
--- /dev/null
@@ -0,0 +1,174 @@
+Writing 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/jerry-api.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;
+
+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,
+                               (JFreeHandlerType)iotjs_bufferwrap_destroy); /* 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)
diff --git a/docs/help/Assigned-people.md b/docs/help/Assigned-people.md
new file mode 100644 (file)
index 0000000..60a9a98
--- /dev/null
@@ -0,0 +1,11 @@
+#### Maintainers
+* akiss77 (integration)
+* LaszloLango (integration)
+* zherczeg (Steering Committee)
+* yichoi (Steering Committee, Project main contact)
+
+#### Committers
+* chokobole
+* nova0821
+* glistening
+* hs0225
\ No newline at end of file
diff --git a/docs/help/Coding-Style-Guideline.md b/docs/help/Coding-Style-Guideline.md
new file mode 100644 (file)
index 0000000..e9f7256
--- /dev/null
@@ -0,0 +1,213 @@
+Coding 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. `<FILE>_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/)
diff --git a/docs/help/Community-Guidelines.md b/docs/help/Community-Guidelines.md
new file mode 100644 (file)
index 0000000..9789400
--- /dev/null
@@ -0,0 +1,20 @@
+All 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.
+
+<br>
+
+### 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.<p>
+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_**)<p>
+Silent Consent means that those who do not offer a reasoned alternative in course of the discussion implicitly agree with the proposal.
+
+<br>
+
+### 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.
diff --git a/docs/help/Developer's-Guide.md b/docs/help/Developer's-Guide.md
new file mode 100644 (file)
index 0000000..fe8d950
--- /dev/null
@@ -0,0 +1,3 @@
+ - [Getting Started](Getting-Started.md)
+ - [Developer Tutorial](Developer-Tutorial.md)
+ - [IoT.js API Reference](../api/IoT.js-API-reference.md)
\ No newline at end of file
diff --git a/docs/help/Developer-Tutorial.md b/docs/help/Developer-Tutorial.md
new file mode 100644 (file)
index 0000000..cb7189f
--- /dev/null
@@ -0,0 +1,161 @@
+### 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`.
\ No newline at end of file
diff --git a/docs/help/Development-Process.md b/docs/help/Development-Process.md
new file mode 100644 (file)
index 0000000..707b2d7
--- /dev/null
@@ -0,0 +1,69 @@
+* [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/).
\ No newline at end of file
diff --git a/docs/help/Extended-API-Guideline.md b/docs/help/Extended-API-Guideline.md
new file mode 100644 (file)
index 0000000..3400cbb
--- /dev/null
@@ -0,0 +1,63 @@
+Extended API Guideline
+======================
+
+Basically, our basic APIs are based on node.js. They will follow same form with node.js because of compatibility.<br>
+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.<br>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.<br>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.
diff --git a/docs/help/Getting-Started.md b/docs/help/Getting-Started.md
new file mode 100644 (file)
index 0000000..81c5582
--- /dev/null
@@ -0,0 +1,86 @@
+### Overview
+IoT.js is built based on JerryScript(lightweight JavaScript engine) and libuv for asynchronous I/O event handling.
+
+#### Source repositories
+* IoT.js: https://github.com/Samsung/iotjs.git
+* JerryScript: https://github.com/jerryscript-project/jerryscript.git
+* libuv: https://github.com/Samsung/libuv.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)
+```
+
+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
+
+##### 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
+
+1. Write a test case inside test directory.
+2. List up a test case in **test/testsets.js**. (this procedure will be removed after ``fs.readDir[Sync]`` is implemented.)
+3. Set attributes on the test case if it needs in **attrs.js** where the directory of your test case belongs.
+
+#### 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)
diff --git a/docs/help/Getting-involved.md b/docs/help/Getting-involved.md
new file mode 100644 (file)
index 0000000..18f2d39
--- /dev/null
@@ -0,0 +1,12 @@
+To 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)
\ No newline at end of file
diff --git a/docs/help/Governance.md b/docs/help/Governance.md
new file mode 100644 (file)
index 0000000..67d3522
--- /dev/null
@@ -0,0 +1,81 @@
+* [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.
\ No newline at end of file
diff --git a/docs/help/IoT.js-Developer's-Certificate-of-Origin-1.0.md b/docs/help/IoT.js-Developer's-Certificate-of-Origin-1.0.md
new file mode 100644 (file)
index 0000000..9dafce0
--- /dev/null
@@ -0,0 +1,42 @@
+The 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: <Your Name> <Your Email>" % content)
+```
+
+Please refer [Git Hooks](http://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks) for more information.
\ No newline at end of file
diff --git a/docs/help/Patch-Submission-Process.md b/docs/help/Patch-Submission-Process.md
new file mode 100644 (file)
index 0000000..a6ad0c4
--- /dev/null
@@ -0,0 +1,40 @@
+The 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.
\ No newline at end of file
diff --git a/include/iotjs.h b/include/iotjs.h
new file mode 100644 (file)
index 0000000..a15070a
--- /dev/null
@@ -0,0 +1,30 @@
+/* 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 */
diff --git a/iotjs_linux.c b/iotjs_linux.c
new file mode 100644 (file)
index 0000000..78fb5d1
--- /dev/null
@@ -0,0 +1,20 @@
+/* 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);
+}
diff --git a/src/iotjs.c b/src/iotjs.c
new file mode 100644 (file)
index 0000000..7e99b91
--- /dev/null
@@ -0,0 +1,214 @@
+/* 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 "jerry-port-default.h"
+#include "jerry-port.h"
+#include "jerryscript.h"
+
+#include <stdio.h>
+#include <string.h>
+
+
+/**
+ * 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;
+    jerry_port_default_set_log_level(JERRY_LOG_LEVEL_DEBUG);
+  }
+
+  if (iotjs_environment_config(env)->show_opcode) {
+    jerry_flag |= JERRY_INIT_SHOW_OPCODES;
+    jerry_port_default_set_log_level(JERRY_LOG_LEVEL_DEBUG);
+  }
+
+  // Initialize jerry.
+  jerry_init((jerry_init_flag_t)jerry_flag);
+
+  // 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(const iotjs_jval_t* process) {
+  // Evaluating 'iotjs.js' returns a function.
+  bool throws;
+#ifndef ENABLE_SNAPSHOT
+  iotjs_jval_t jmain = iotjs_jhelper_eval(iotjs_s, iotjs_l, false, &throws);
+#else
+  iotjs_jval_t jmain = iotjs_jhelper_exec_snapshot(iotjs_s, iotjs_l, &throws);
+#endif
+  IOTJS_ASSERT(!throws);
+
+  // Run the entry function passing process builtin.
+  // The entry function will continue initializing process module, global, and
+  // other native modules, and finally load and run application.
+  iotjs_jargs_t args = iotjs_jargs_create(1);
+  iotjs_jargs_append_jval(&args, process);
+
+  const iotjs_jval_t* global = iotjs_jval_get_global_object();
+  iotjs_jval_t jmain_res = iotjs_jhelper_call(&jmain, global, &args, &throws);
+
+  iotjs_jargs_destroy(&args);
+  iotjs_jval_destroy(&jmain);
+
+  if (throws) {
+    iotjs_uncaught_exception(&jmain_res);
+  }
+  iotjs_jval_destroy(&jmain_res);
+
+  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_run(process);
+
+  // 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));
+    }
+  } 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, 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;
+}
diff --git a/src/iotjs_binding.c b/src/iotjs_binding.c
new file mode 100644 (file)
index 0000000..9c8863e
--- /dev/null
@@ -0,0 +1,818 @@
+/* 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 <string.h>
+
+
+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);
+
+  _this->value = jerry_create_string_sz(data, size);
+
+  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,
+                                         JFreeHandlerType free_handler) {
+  const IOTJS_VALIDATED_STRUCT_METHOD(iotjs_jval_t, jobj);
+  IOTJS_ASSERT(iotjs_jval_is_object(jobj));
+
+  jerry_set_object_native_handle(_this->value, ptr, free_handler);
+}
+
+
+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;
+  jerry_get_object_native_handle(_this->value, &ptr);
+  return ptr;
+}
+
+
+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* data, size_t size, bool strict_mode,
+                                bool* throws) {
+  jerry_value_t res = jerry_eval((const jerry_char_t*)data, size, strict_mode);
+
+  *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;
+  if (!jerry_get_object_native_handle(jfunc, &target_function_ptr)) {
+    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);
+}
diff --git a/src/iotjs_binding.h b/src/iotjs_binding.h
new file mode 100644 (file)
index 0000000..6c1e27f
--- /dev/null
@@ -0,0 +1,300 @@
+/* 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 <stdio.h>
+
+
+typedef jerry_external_handler_t JHandlerType;
+typedef jerry_object_free_callback_t JFreeHandlerType;
+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,
+                                         JFreeHandlerType free_handler);
+uintptr_t iotjs_jval_get_object_native_handle(THIS_JVAL);
+
+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* 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)
+
+
+void iotjs_binding_initialize();
+void iotjs_binding_finalize();
+
+
+#endif /* IOTJS_BINDING_H */
diff --git a/src/iotjs_binding_helper.c b/src/iotjs_binding_helper.c
new file mode 100644 (file)
index 0000000..177099f
--- /dev/null
@@ -0,0 +1,124 @@
+/* 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+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);
+}
diff --git a/src/iotjs_binding_helper.h b/src/iotjs_binding_helper.h
new file mode 100644 (file)
index 0000000..5ebbaa4
--- /dev/null
@@ -0,0 +1,40 @@
+/* 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 */
diff --git a/src/iotjs_debuglog.c b/src/iotjs_debuglog.c
new file mode 100644 (file)
index 0000000..f2187fd
--- /dev/null
@@ -0,0 +1,66 @@
+/* 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 <stdio.h>
+#include <stdlib.h>
+
+#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
+}
diff --git a/src/iotjs_debuglog.h b/src/iotjs_debuglog.h
new file mode 100644 (file)
index 0000000..7468027
--- /dev/null
@@ -0,0 +1,65 @@
+/* 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 <stdio.h>
+
+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 */
diff --git a/src/iotjs_def.h b/src/iotjs_def.h
new file mode 100644 (file)
index 0000000..5d2788f
--- /dev/null
@@ -0,0 +1,170 @@
+/* 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 <uv.h>
+#include <assert.h>
+#include <limits.h> /* PATH_MAX */
+#include <stdbool.h>
+#include <string.h>
+
+// 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 */
diff --git a/src/iotjs_env.c b/src/iotjs_env.c
new file mode 100644 (file)
index 0000000..f81c9b7
--- /dev/null
@@ -0,0 +1,192 @@
+/* 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 <string.h>
+
+
+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(&current_env);
+    initialized = true;
+  }
+  return &current_env;
+}
+
+
+/**
+ * Release the singleton instance of iotjs_environment_t.
+ */
+void iotjs_environment_release() {
+  if (initialized) {
+    iotjs_environment_destroy(&current_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.
+    int i;
+    for (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,
+                                                    int argc, char** argv) {
+  IOTJS_VALIDATED_STRUCT_METHOD(iotjs_environment_t, env);
+
+  // There must be at least two arguments.
+  if (argc < 2) {
+    fprintf(stderr,
+            "usage: iotjs <js> [<iotjs arguments>] [-- <app arguments>]\n");
+    return false;
+  }
+
+  // Parse IoT.js command line arguments.
+  int i = 2;
+  while (i < argc) {
+    if (!strcmp(argv[i], "--")) {
+      ++i;
+      break;
+    }
+    if (!strcmp(argv[i], "--memstat")) {
+      _this->config.memstat = true;
+    } else if (!strcmp(argv[i], "--show-opcodes")) {
+      _this->config.show_opcode = true;
+    } else {
+      fprintf(stderr, "unknown command line argument %s\n", argv[i]);
+      return false;
+    }
+    ++i;
+  }
+
+  // Remaining arguments are for application.
+  _this->argc = 2;
+  size_t buffer_size = (_this->argc + argc - i) * sizeof(char*);
+  _this->argv = (char**)iotjs_buffer_allocate(buffer_size);
+  _this->argv[0] = argv[0];
+  _this->argv[1] = argv[1];
+  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;
+}
+
+int 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, int 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;
+}
diff --git a/src/iotjs_env.h b/src/iotjs_env.h
new file mode 100644 (file)
index 0000000..6174d4b
--- /dev/null
@@ -0,0 +1,72 @@
+/* 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;
+} Config;
+
+typedef enum {
+  kInitializing,
+  kRunningMain,
+  kRunningLoop,
+  kExiting,
+} State;
+
+
+typedef struct {
+  // Number of application arguments including 'iotjs' and app name.
+  int 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,
+                                                    int argc, char** argv);
+
+int iotjs_environment_argc(const iotjs_environment_t* env);
+const char* iotjs_environment_argv(const iotjs_environment_t* env, int 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 */
diff --git a/src/iotjs_exception.c b/src/iotjs_exception.c
new file mode 100644 (file)
index 0000000..bad8c26
--- /dev/null
@@ -0,0 +1,29 @@
+/* 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 <stdio.h>
+
+#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);
+}
diff --git a/src/iotjs_exception.h b/src/iotjs_exception.h
new file mode 100644 (file)
index 0000000..6be7916
--- /dev/null
@@ -0,0 +1,23 @@
+/* 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 */
diff --git a/src/iotjs_handlewrap.c b/src/iotjs_handlewrap.c
new file mode 100644 (file)
index 0000000..1885f08
--- /dev/null
@@ -0,0 +1,125 @@
+/* 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,
+                                 JFreeHandlerType jfreehandler) {
+  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, jfreehandler);
+
+  _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)));
+}
diff --git a/src/iotjs_handlewrap.h b/src/iotjs_handlewrap.h
new file mode 100644 (file)
index 0000000..b69f545
--- /dev/null
@@ -0,0 +1,72 @@
+/* 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 <uv.h>
+
+#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,
+                                 JFreeHandlerType jfreehandler);
+
+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 */
diff --git a/src/iotjs_magic_strings.h b/src/iotjs_magic_strings.h
new file mode 100644 (file)
index 0000000..a5ae5b8
--- /dev/null
@@ -0,0 +1,183 @@
+/* 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_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_EMIT "emit"
+#define IOTJS_MAGIC_STRING_EMITEXIT "emitExit"
+#define IOTJS_MAGIC_STRING_ENV "env"
+#define IOTJS_MAGIC_STRING_EXECUTE "execute"
+#define IOTJS_MAGIC_STRING_EXPORT "export"
+#define IOTJS_MAGIC_STRING_FAMILY "family"
+#define IOTJS_MAGIC_STRING_FINISH "finish"
+#define IOTJS_MAGIC_STRING_FLOAT "FLOAT"
+#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__INITARGV "_initArgv"
+#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_NODE_PATH "NODE_PATH"
+#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_READBLOCK "readBlock"
+#define IOTJS_MAGIC_STRING_READBYTE "readByte"
+#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_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_WRITEBLOCK "writeBlock"
+#define IOTJS_MAGIC_STRING_WRITEBYTE "writeByte"
+#define IOTJS_MAGIC_STRING_WRITESYNC "writeSync"
+#define IOTJS_MAGIC_STRING_WRITEUINT8 "writeUInt8"
+#define IOTJS_MAGIC_STRING_WRITE "write"
+
+#endif /* IOTJS_STRING_CONSTANTS_H */
diff --git a/src/iotjs_module.c b/src/iotjs_module.c
new file mode 100644 (file)
index 0000000..20a8080
--- /dev/null
@@ -0,0 +1,78 @@
+/* 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;
+}
diff --git a/src/iotjs_module.h b/src/iotjs_module.h
new file mode 100644 (file)
index 0000000..fb880b1
--- /dev/null
@@ -0,0 +1,75 @@
+/* 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 */
diff --git a/src/iotjs_objectwrap.c b/src/iotjs_objectwrap.c
new file mode 100644 (file)
index 0000000..b1f7c76
--- /dev/null
@@ -0,0 +1,61 @@
+/* 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,
+                                  JFreeHandlerType jfreehandler) {
+  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,
+                                      jfreehandler);
+}
+
+
+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;
+}
diff --git a/src/iotjs_objectwrap.h b/src/iotjs_objectwrap.h
new file mode 100644 (file)
index 0000000..e668295
--- /dev/null
@@ -0,0 +1,40 @@
+/* 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,
+                                  JFreeHandlerType jfreehandler);
+
+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);
+
+
+#endif /* IOTJS_OBJECTWRAP_H */
diff --git a/src/iotjs_reqwrap.c b/src/iotjs_reqwrap.c
new file mode 100644 (file)
index 0000000..ae9037f
--- /dev/null
@@ -0,0 +1,61 @@
+/* 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;
+}
diff --git a/src/iotjs_reqwrap.h b/src/iotjs_reqwrap.h
new file mode 100644 (file)
index 0000000..3fb99ac
--- /dev/null
@@ -0,0 +1,50 @@
+/* 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 <uv.h>
+
+#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 */
diff --git a/src/iotjs_string.c b/src/iotjs_string.c
new file mode 100644 (file)
index 0000000..b55aa1c
--- /dev/null
@@ -0,0 +1,132 @@
+/* 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 <string.h>
+
+
+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, uint32_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, uint32_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, uint32_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;
+}
diff --git a/src/iotjs_string.h b/src/iotjs_string.h
new file mode 100644 (file)
index 0000000..abec85f
--- /dev/null
@@ -0,0 +1,48 @@
+/* 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 {
+  uint32_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, uint32_t size);
+iotjs_string_t iotjs_string_create_with_buffer(char* buffer, uint32_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, uint32_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 */
diff --git a/src/iotjs_string_ext.c b/src/iotjs_string_ext.c
new file mode 100644 (file)
index 0000000..9cadefb
--- /dev/null
@@ -0,0 +1,66 @@
+/* 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);
+}
diff --git a/src/iotjs_string_ext.h b/src/iotjs_string_ext.h
new file mode 100644 (file)
index 0000000..f5d129b
--- /dev/null
@@ -0,0 +1,23 @@
+/* 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 */
diff --git a/src/iotjs_util.c b/src/iotjs_util.c
new file mode 100644 (file)
index 0000000..04fa7b2
--- /dev/null
@@ -0,0 +1,76 @@
+/* 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+iotjs_string_t iotjs_file_read(const char* path) {
+  FILE* file = fopen(path, "rb");
+  IOTJS_ASSERT(file != NULL);
+
+  fseek(file, 0, SEEK_END);
+  long len = ftell(file);
+  IOTJS_ASSERT(len >= 0);
+  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 == (size_t)len);
+
+  *(buffer + len) = 0;
+
+  fclose(file);
+
+  iotjs_string_t contents = iotjs_string_create_with_buffer(buffer, len);
+
+  return contents;
+}
+
+
+char* iotjs_buffer_allocate(unsigned size) {
+  char* buffer = (char*)(calloc(size, sizeof(char)));
+  IOTJS_ASSERT(buffer != NULL);
+  return buffer;
+}
+
+
+char* iotjs_buffer_reallocate(char* buffer, unsigned size) {
+  IOTJS_ASSERT(buffer != NULL);
+  return (char*)(realloc(buffer, size));
+}
+
+
+void iotjs_buffer_release(char* buffer) {
+  IOTJS_ASSERT(buffer != NULL);
+  free(buffer);
+}
diff --git a/src/iotjs_util.h b/src/iotjs_util.h
new file mode 100644 (file)
index 0000000..a1d1c3e
--- /dev/null
@@ -0,0 +1,37 @@
+/* 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(unsigned size);
+char* iotjs_buffer_reallocate(char* buffer, unsigned 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 */
diff --git a/src/js/adc.js b/src/js/adc.js
new file mode 100644 (file)
index 0000000..5d4eed9
--- /dev/null
@@ -0,0 +1,107 @@
+/* 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 new AdcPin(configuration, callback);
+};
+
+
+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')
+  }
+
+  this._binding = new adc.Adc(configuration, function(err) {
+    util.isFunction(callback) && callback.call(self, err);
+  });
+
+  process.on('exit', (function(self) {
+    return function() {
+      if (!util.isNull(self._binding)) {
+        self.closeSync();
+      }
+    };
+  })(this));
+}
+
+AdcPin.prototype.read = function(callback) {
+  var self = this;
+
+  if (util.isNull(this._binding)) {
+    throw new Error('ADC pin is not opened');
+  }
+
+  this._binding.read(function(err, value) {
+    util.isFunction(callback) && callback.call(self, err, value);
+  });
+};
+
+AdcPin.prototype.readSync = function() {
+  if (util.isNull(this._binding)) {
+    throw new Error('ADC pin is not opened');
+  }
+
+  return this._binding.read();
+};
+
+AdcPin.prototype.close = function(callback) {
+  var self = this;
+
+  if (util.isNull(this._binding)) {
+    throw new Error('ADC pin is not opened');
+  }
+
+  this._binding.close(function(err) {
+    util.isFunction(callback) && callback.call(self, err);
+  });
+
+  this._binding = null;
+};
+
+AdcPin.prototype.closeSync = function() {
+  if (util.isNull(this._binding)) {
+    throw new Error('ADC pin is not opened');
+  }
+
+  this._binding.close();
+
+  this._binding = null;
+};
+
+module.exports = Adc;
diff --git a/src/js/assert.js b/src/js/assert.js
new file mode 100644 (file)
index 0000000..ec43ba9
--- /dev/null
@@ -0,0 +1,153 @@
+// 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 (!(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;
diff --git a/src/js/ble.js b/src/js/ble.js
new file mode 100644 (file)
index 0000000..6d1d2cb
--- /dev/null
@@ -0,0 +1,270 @@
+/* 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; //requir('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') {
+  // `requir` is intentional errta  to avoid pre-build module dependency analyzer error
+  // The analyzer does not understand comment
+  // bindings = requir('./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();
diff --git a/src/js/ble_characteristic.js b/src/js/ble_characteristic.js
new file mode 100644 (file)
index 0000000..f8f34c3
--- /dev/null
@@ -0,0 +1,129 @@
+/* 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; //requir('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;
diff --git a/src/js/ble_descriptor.js b/src/js/ble_descriptor.js
new file mode 100644 (file)
index 0000000..6c8b1f6
--- /dev/null
@@ -0,0 +1,53 @@
+/* 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; //requir('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;
diff --git a/src/js/ble_hci_socket.js b/src/js/ble_hci_socket.js
new file mode 100644 (file)
index 0000000..944ff7c
--- /dev/null
@@ -0,0 +1,50 @@
+/* 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;
diff --git a/src/js/ble_hci_socket_acl_stream.js b/src/js/ble_hci_socket_acl_stream.js
new file mode 100644 (file)
index 0000000..3a3bebb
--- /dev/null
@@ -0,0 +1,78 @@
+/* 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; //requir('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;
diff --git a/src/js/ble_hci_socket_bindings.js b/src/js/ble_hci_socket_bindings.js
new file mode 100644 (file)
index 0000000..2551e1d
--- /dev/null
@@ -0,0 +1,253 @@
+/* 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; //requir('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();
diff --git a/src/js/ble_hci_socket_crypto.js b/src/js/ble_hci_socket_crypto.js
new file mode 100644 (file)
index 0000000..28e715c
--- /dev/null
@@ -0,0 +1,112 @@
+/* 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
+};
diff --git a/src/js/ble_hci_socket_gap.js b/src/js/ble_hci_socket_gap.js
new file mode 100644 (file)
index 0000000..9d5f630
--- /dev/null
@@ -0,0 +1,247 @@
+/* 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; //requir('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;
diff --git a/src/js/ble_hci_socket_gatt.js b/src/js/ble_hci_socket_gatt.js
new file mode 100644 (file)
index 0000000..b18261c
--- /dev/null
@@ -0,0 +1,1090 @@
+/* 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; //requir('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;
diff --git a/src/js/ble_hci_socket_hci.js b/src/js/ble_hci_socket_hci.js
new file mode 100644 (file)
index 0000000..d1732f5
--- /dev/null
@@ -0,0 +1,644 @@
+/* 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; //requir('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;
diff --git a/src/js/ble_hci_socket_hci_status.js b/src/js/ble_hci_socket_hci_status.js
new file mode 100644 (file)
index 0000000..ef621d7
--- /dev/null
@@ -0,0 +1,103 @@
+/* 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"
+]
diff --git a/src/js/ble_hci_socket_mgmt.js b/src/js/ble_hci_socket_mgmt.js
new file mode 100644 (file)
index 0000000..dca71da
--- /dev/null
@@ -0,0 +1,126 @@
+/* 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; // requir('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();
diff --git a/src/js/ble_hci_socket_smp.js b/src/js/ble_hci_socket_smp.js
new file mode 100644 (file)
index 0000000..563e217
--- /dev/null
@@ -0,0 +1,198 @@
+/* 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; //requir('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: <none>
+    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;
diff --git a/src/js/ble_primary_service.js b/src/js/ble_primary_service.js
new file mode 100644 (file)
index 0000000..0e4b4c4
--- /dev/null
@@ -0,0 +1,58 @@
+/* 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; //requir('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;
diff --git a/src/js/ble_uuid_util.js b/src/js/ble_uuid_util.js
new file mode 100644 (file)
index 0000000..c8ee3d3
--- /dev/null
@@ -0,0 +1,43 @@
+/* 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;
+};
diff --git a/src/js/buffer.js b/src/js/buffer.js
new file mode 100644 (file)
index 0000000..558e509
--- /dev/null
@@ -0,0 +1,320 @@
+/* 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 (!(buffer instanceof Buffer))
+    throw new TypeError('buffer must be a Buffer instance');
+  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;
diff --git a/src/js/console.js b/src/js/console.js
new file mode 100644 (file)
index 0000000..3d1dfa1
--- /dev/null
@@ -0,0 +1,38 @@
+/* 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;
diff --git a/src/js/constants.js b/src/js/constants.js
new file mode 100644 (file)
index 0000000..a2f9e4d
--- /dev/null
@@ -0,0 +1,17 @@
+/* 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);
diff --git a/src/js/dgram.js b/src/js/dgram.js
new file mode 100644 (file)
index 0000000..0998896
--- /dev/null
@@ -0,0 +1,464 @@
+/* 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;
+
+  if (util.isFunction(arguments[arguments.length - 1]))
+    self.once('listening', arguments[arguments.length - 1]);
+
+  var address;
+  if (util.isObject(port)) {
+    address = port.address || '';
+    port = port.port;
+  } else {
+    address = util.isFunction(arguments[1]) ? '' : arguments[1];
+  }
+
+  // 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 (!(buffer instanceof 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);
+}
+
+
+Socket.prototype.ref = function() {
+  if (this._handle)
+    this._handle.ref();
+
+  return this;
+};
+
+
+Socket.prototype.unref = function() {
+  if (this._handle)
+    this._handle.unref();
+
+  return this;
+};
diff --git a/src/js/dns.js b/src/js/dns.js
new file mode 100644 (file)
index 0000000..70973e6
--- /dev/null
@@ -0,0 +1,79 @@
+/* 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');
+
+  var err = dnsBuiltin.getaddrinfo(
+      hostname,
+      family,
+      hints,
+      function(err, address, family) {
+        var errObj = null;
+        if (err) {
+          errObj = dnsException(err, 'getaddrinfo', hostname);
+        }
+        return callback(errObj, address, family);
+      });
+  return err;
+};
+
+
+// uv_getaddrinfo flags
+exports.ADDRCONFIG = dnsBuiltin.AI_ADDRCONFIG;
+exports.V4MAPPED = dnsBuiltin.AI_V4MAPPED;
diff --git a/src/js/events.js b/src/js/events.js
new file mode 100644 (file)
index 0000000..770e757
--- /dev/null
@@ -0,0 +1,132 @@
+/* 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");
+    }
+    return false;
+  }
+
+  var listeners = this._events[type];
+  if (util.isArray(listeners)) {
+    listeners = listeners.slice();
+    var len = arguments.length;
+    var args = new Array(len - 1);
+    for (var i = 1; i < len; ++i) {
+      args[i - 1] = arguments[i];
+    }
+    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);
+        break;
+      }
+    }
+  }
+
+  return this;
+
+};
+
+
+EventEmitter.prototype.removeAllListeners = function(type) {
+  if (arguments.length === 0) {
+    this._events = {};
+  } else {
+    delete this._events[type];
+  }
+
+  return this;
+};
diff --git a/src/js/fs.js b/src/js/fs.js
new file mode 100644 (file)
index 0000000..da7c8d3
--- /dev/null
@@ -0,0 +1,485 @@
+/* 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);
+
+
+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;
+
+
+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) {
+  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;
+  }
+  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.
+  }
+
+  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);
+  checkArgBuffer(data);
+  checkArgFunction(callback);
+
+  var fd;
+  var len;
+  var bytesWritten;
+
+  fs.open(path, 'w', function(err, _fd) {
+    if (err) {
+      return callback(err);
+    }
+
+    fd = _fd;
+    len = data.length;
+    bytesWritten = 0;
+
+    write();
+  });
+
+  var write = function() {
+    var tryN = (len - bytesWritten) >= 1024 ? 1023 : (len - bytesWritten);
+    fs.write(fd, data, 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 data
+      fs.close(fd, function(err) {
+        callback(err);
+      });
+    } else {
+      // continue writing
+      bytesWritten += n;
+      write();
+    }
+  };
+};
+
+
+fs.writeFileSync = function(path, data) {
+  checkArgString(path);
+  checkArgBuffer(data);
+
+  var fd = fs.openSync(path, 'w');
+  var len = data.length;
+  var bytesWritten = 0;
+
+  while (true) {
+    try {
+      var tryN = (len - bytesWritten) >= 1024 ? 1023 : (len - bytesWritten);
+      var n = fs.writeSync(fd, data, 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) {
+  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);
+  } else if (def) {
+    return convertMode(def);
+  }
+  return undefined;
+}
+
+
+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);
+}
diff --git a/src/js/gpio.js b/src/js/gpio.js
new file mode 100644 (file)
index 0000000..1c2e991
--- /dev/null
@@ -0,0 +1,175 @@
+/* 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 gpio = process.binding(process.binding.gpio);
+var util = require('util');
+
+
+var defaultConfiguration = {
+  direction: gpio.DIRECTION.OUT,
+  mode: gpio.MODE.NONE
+};
+
+
+function Gpio() {
+  if (!(this instanceof Gpio)) {
+    return new Gpio();
+  }
+}
+
+Gpio.prototype.open = function(configuration, callback) {
+  return new GpioPin(configuration, callback);
+};
+
+Gpio.prototype.DIRECTION = gpio.DIRECTION;
+
+Gpio.prototype.MODE = gpio.MODE;
+
+
+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
+  if (process.platform === 'linux') {
+    configuration.mode = defaultConfiguration.mode;
+  } else if (process.platform === 'nuttx') {
+    var mode = configuration.mode;
+    if (!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;
+    }
+  }
+
+  this._binding = new gpio.Gpio(configuration, function(err) {
+    util.isFunction(callback) && callback.call(self, err);
+  });
+
+  process.on('exit', (function(self) {
+    return function() {
+      if (!util.isNull(self._binding)) {
+        self.closeSync();
+      }
+    };
+  })(this));
+}
+
+GpioPin.prototype.write = function(value, callback) {
+  var self = this;
+
+  if (util.isNull(this._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');
+  }
+
+  this._binding.write(!!value, function(err) {
+    util.isFunction(callback) && callback.call(self, err);
+  });
+};
+
+GpioPin.prototype.writeSync = function(value) {
+  if (util.isNull(this._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');
+  }
+
+  this._binding.writeSync(!!value);
+};
+
+GpioPin.prototype.read = function(callback) {
+  var self = this;
+
+  if (util.isNull(this._binding)) {
+    throw new Error('GPIO pin is not opened');
+  }
+
+  this._binding.read(function(err, value) {
+    util.isFunction(callback) && callback.call(self, err, value);
+  });
+};
+
+GpioPin.prototype.readSync = function() {
+  if (util.isNull(this._binding)) {
+    throw new Error('GPIO pin is not opened');
+  }
+
+  return this._binding.readSync();
+};
+
+GpioPin.prototype.close = function(callback) {
+  var self = this;
+
+  if (util.isNull(this._binding)) {
+    throw new Error('GPIO pin is not opened');
+  }
+
+  this._binding.close(function(err) {
+    util.isFunction(callback) && callback.call(self, err);
+  });
+
+  this._binding = null;
+};
+
+GpioPin.prototype.closeSync = function() {
+  if (util.isNull(this._binding)) {
+    throw new Error('GPIO pin is not opened');
+  }
+
+  this._binding.closeSync();
+
+  this._binding = null;
+};
+
+
+module.exports = Gpio;
diff --git a/src/js/http.js b/src/js/http.js
new file mode 100644 (file)
index 0000000..80905e4
--- /dev/null
@@ -0,0 +1,41 @@
+/* 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;
+};
diff --git a/src/js/http_client.js b/src/js/http_client.js
new file mode 100644 (file)
index 0000000..ca865a9
--- /dev/null
@@ -0,0 +1,231 @@
+/* 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;
+  }
+  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);
+  });
+
+};
diff --git a/src/js/http_common.js b/src/js/http_common.js
new file mode 100644 (file)
index 0000000..feb07dc
--- /dev/null
@@ -0,0 +1,134 @@
+/* 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');
+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 Buffer = require('buffer');
+
+
+
+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 parser = this;
+  var stream = parser.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 parser = this;
+  var headers = info.headers;
+  var url = info.url;
+
+  if (!url) {
+    url = parser._url;
+    parser.url = "";
+  }
+
+  if (!headers) {
+    headers = parser._headers;
+    // FIXME: This should be impl. with Array
+    parser._headers = {};
+  }
+
+
+  parser.incoming = new IncomingMessage(parser.socket);
+  parser.incoming.url = url;
+
+  // add header fields of headers to incoming.headers
+  parser.incoming.addHeaders(headers);
+
+  if (util.isNumber(info.method)) {
+    // for server
+    parser.incoming.method = HTTPParser.methods[info.method];
+  } else {
+    // for client
+    parser.incoming.statusCode = info.status;
+    parser.incoming.statusMessage = info.status_msg;
+  }
+
+  // For client side, if response to 'HEAD' request, we will skip parsing body
+  var skipBody = parser.onIncoming(parser.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 parser = this;
+  var stream = parser.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);
+}
+
+
+function AddHeader(dest, src) {
+  if (!dest.length) {
+    dest.length = 0;
+  }
+
+  for (var i=0;i<src.length;i++) {
+    dest[dest.length+i] = src[i];
+  }
+  dest.length = dest.length + src.length;
+}
+
+
+// This is called when http header is fragmented and
+// HTTPParser sends it to JS in separate pieces.
+function parserOnHeaders(headers, url) {
+  // FIXME: This should be impl. with Array.concat
+  AddHeader(this._headers, headers);
+  if (url) {
+    this._url += url;
+  }
+}
diff --git a/src/js/http_incoming.js b/src/js/http_incoming.js
new file mode 100644 (file)
index 0000000..72249c1
--- /dev/null
@@ -0,0 +1,69 @@
+/* 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<headers.length; i=i+2) {
+    this.headers[headers[i]] = headers[i+1];
+  }
+};
+
+
+IncomingMessage.prototype.setTimeout = function(ms, cb) {
+  if (cb)
+    this.once('timeout', cb);
+  this.socket.setTimeout(ms, cb);
+};
diff --git a/src/js/http_outgoing.js b/src/js/http_outgoing.js
new file mode 100644 (file)
index 0000000..fb2bc3a
--- /dev/null
@@ -0,0 +1,188 @@
+/* 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 OutgoingMessage() {
+  stream.Stream.call(this);
+
+  this.writable = true;
+
+  this._hasBody = true;
+
+  this.finished = false;
+  this._sentHeader = false;
+
+  this.socket = null;
+  this.connection = null;
+  // response header string : same 'content' as this._headers
+  this._header = null;
+  // response header obj : (key, value) pairs
+  this._headers = {};
+
+}
+
+util.inherits(OutgoingMessage, stream.Stream);
+
+exports.OutgoingMessage = OutgoingMessage;
+
+
+OutgoingMessage.prototype.end = function(data, encoding, callback) {
+  var self = this;
+
+  if (util.isFunction(data)) {
+    callback = data;
+    data = null;
+  } else if (util.isFunction(encoding)) {
+    callback = encoding;
+    encoding = null;
+  }
+
+  if (this.finished) {
+    return false;
+  }
+
+  // flush header
+  if (!this._header) {
+    this._implicitHeader();
+  }
+
+  if (data) {
+    this.write(data, encoding);
+  }
+
+  // Register finish event handler.
+  if (util.isFunction(callback)) {
+    this.once('finish', callback);
+  }
+
+  // Force flush buffered data.
+  // After all data was sent, emit 'finish' event meaning segment of header and
+  // body were all sent finished. This means different from 'finish' event
+  // emitted by net which indicate there will be no more data to be sent through
+  // the connection. On the other hand emitting 'finish' event from http does
+  // not neccessarily imply end of data transmission since there might be
+  // another segment of data when connection is 'Keep-Alive'.
+  this._send('', function() {
+    self.emit('finish');
+  });
+
+
+  this.finished = true;
+
+  this._finish();
+
+  return true;
+};
+
+
+OutgoingMessage.prototype._finish = function() {
+  this.emit('prefinish');
+};
+
+
+// This sends chunk directly into socket
+// TODO: buffering of chunk in the case of socket is not available
+OutgoingMessage.prototype._send = function(chunk, encoding, callback) {
+  if (util.isFunction(encoding)) {
+    callback = encoding;
+  }
+
+  if (util.isBuffer(chunk)) {
+    chunk = chunk.toString();
+  }
+
+  if (!this._sentHeader) {
+    chunk = this._header + "\r\n" + chunk;
+    this._sentHeader = true;
+  }
+
+  return this.connection.write(chunk, encoding, callback);
+};
+
+
+OutgoingMessage.prototype.write = function(chunk, encoding, callback) {
+  if (!this._header) {
+    this._implicitHeader();
+  }
+
+  if (!this._hasBody) {
+    return true;
+  }
+
+  var ret = this._send(chunk, encoding, callback);
+
+  return ret;
+
+};
+
+
+// Stringfy header fields of _headers into _header
+OutgoingMessage.prototype._storeHeader = function(statusLine) {
+  var headerStr = '';
+
+  var keys;
+  if (this._headers) {
+    keys = Object.keys(this._headers);
+    for (var i=0; i<keys.length; i++) {
+      var key = keys[i];
+      headerStr += key + ": " + this._headers[key] + '\r\n';
+    }
+  }
+
+  this._header = statusLine + headerStr;
+
+};
+
+
+OutgoingMessage.prototype.setHeader = function(name, value) {
+
+  if (this._headers === null) {
+    this._headers = {};
+  }
+
+  this._headers[name] = value;
+
+};
+
+
+OutgoingMessage.prototype.removeHeader = function(name) {
+  if (this._headers === null) {
+    return;
+  }
+
+  delete this._headers[name];
+};
+
+
+OutgoingMessage.prototype.getHeader = function(name) {
+  return this._headers[name];
+};
+
+
+OutgoingMessage.prototype.setTimeout = function(ms, cb) {
+  if (cb)
+    this.once('timeout', cb);
+
+  if (!this.socket) {
+    this.once('socket', function(socket) {
+      socket.setTimeout(msecs);
+    });
+  } else
+    this.socket.setTimeout(msecs);
+};
diff --git a/src/js/http_server.js b/src/js/http_server.js
new file mode 100644 (file)
index 0000000..bad92d1
--- /dev/null
@@ -0,0 +1,305 @@
+/* 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');
+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');
+
+// RFC 7231 (http://tools.ietf.org/html/rfc7231#page-49)
+var STATUS_CODES = exports.STATUS_CODES = {
+  100 : 'Continue',
+  101 : 'Switching Protocols',
+  200 : 'OK',
+  201 : 'Created',
+  202 : 'Accepted',
+  203 : 'Non-Authoritative Information',
+  204 : 'No Content',
+  205 : 'Reset Content',
+  206 : 'Partial Content',
+  300 : 'Multiple Choices',
+  301 : 'Moved Permanently',
+  302 : 'Found',
+  303 : 'See Other',
+  304 : 'Not Modified',
+  305 : 'Use Proxy',
+  307 : 'Temporary Redirect',
+  400 : 'Bad Request',
+  401 : 'Unauthorized',
+  402 : 'Payment Required',
+  403 : 'Forbidden',
+  404 : 'Not Found',
+  405 : 'Method Not Allowed',
+  406 : 'Not Acceptable',
+  407 : 'Proxy Authentication Required',
+  408 : 'Request Timeout',
+  409 : 'Conflict',
+  410 : 'Gone',
+  411 : 'Length Required',
+  412 : 'Precondition Failed',
+  413 : 'Payload Too Large',
+  414 : 'URI Too Large',
+  415 : 'Unsupported Media Type',
+  416 : 'Range Not Satisfiable',
+  417 : 'Expectation Failed',
+  426 : 'Upgrade Required',
+  500 : 'Internal Server Error',
+  501 : 'Not Implemented',
+  502 : 'Bad Gateway',
+  503 : 'Service Unavailable',
+  504 : 'Gateway Time-out',
+  505 : 'HTTP Version Not Supported'
+};
+
+
+// response to req
+function ServerResponse(req) {
+  OutgoingMessage.call(this);
+  // response to HEAD method has no body
+  if (req.method === 'HEAD') this._hasBody = false;
+}
+
+util.inherits(ServerResponse, OutgoingMessage);
+
+
+// default status code : 200
+ServerResponse.prototype.statusCode = 200;
+ServerResponse.prototype.statusMessage = undefined;
+
+
+// if user does not set Header before write(..),
+// this function set default header(200).
+ServerResponse.prototype._implicitHeader = function() {
+  this.writeHead(this.statusCode);
+};
+
+
+ServerResponse.prototype.writeHead = function(statusCode, reason, obj) {
+  if (util.isString(reason)) {
+    this.statusMessage = reason;
+  }
+  else {
+    this.statusMessage = STATUS_CODES[statusCode] || 'unknown';
+    obj = reason;
+  }
+
+  var statusLine = util.format('HTTP/1.1 %s %s\r\n',
+                               statusCode.toString(),
+                               this.statusMessage);
+
+  this.statusCode = statusCode;
+
+  // HTTP response without body
+  if (statusCode === 204 || statusCode === 304 ||
+      (100 <= statusCode && statusCode <= 199)) {
+    this._hasBody = false;
+  }
+
+  if (util.isObject(obj)) {
+    if (util.isNullOrUndefined(this._headers)) {
+      this._headers = {};
+    }
+    for (key in Object.keys(obj)) {
+      this._headers[key] = obj[key];
+    }
+  }
+
+  this._storeHeader(statusLine);
+};
+
+
+ServerResponse.prototype.assignSocket = function(socket) {
+  socket._httpMessage = this;
+  this.socket = socket;
+  this.connection = socket;
+  socket.on('close', onServerResponseClose);
+  this.emit('socket', socket);
+};
+
+
+function onServerResponseClose() {
+  if (this._httpMessage) {
+    this._httpMessage.emit('close');
+  }
+}
+
+
+ServerResponse.prototype.detachSocket = function() {
+  this.socket._httpMessage = null;
+  this.socket = this.connection = null;
+};
+
+
+function Server(requestListener) {
+  if (!(this instanceof Server)) {
+    return new Server(requestListener);
+  }
+
+  net.Server.call(this, {allowHalfOpen: true});
+
+  if (util.isFunction(requestListener)) {
+    this.addListener('request', requestListener);
+  }
+
+  this.httpAllowHalfOpen = false;
+
+  this.on('connection', connectionListener);
+  this.on('clientError', function(err, conn) {
+    conn.destroy(err);
+  });
+
+  this.timeout = 2 * 1000 * 60; // default timeout is 2 min
+}
+
+util.inherits(Server, net.Server);
+exports.Server = Server;
+
+
+// TODO: Implement Server.prototype.setTimeout function
+// For this, socket.prototype.setTimeout is needed.
+Server.prototype.setTimeout = function (ms, cb) {
+  this.timeout = ms;
+  if (cb) {
+    this.on('timeout', cb);
+  }
+};
+
+
+function connectionListener(socket) {
+  var server = this;
+
+  // cf) In Node.js, freelist returns a new parser.
+  // parser initialize
+  var parser = common.createHTTPParser();
+  // FIXME: This should be impl. with Array
+  parser._headers = {};
+  parser._url = '';
+
+  parser.onIncoming = parserOnIncoming;
+
+  parser.socket = socket;
+  parser.incoming = null;
+  socket.parser = parser;
+
+  socket.on("data", socketOnData);
+  socket.on("end", socketOnEnd);
+  socket.on("close", socketOnClose);
+  socket.on('timeout', socketOnTimeout);
+  socket.on("error", socketOnError);
+
+  if (server.timeout) {
+    socket.setTimeout(server.timeout);
+  }
+}
+
+
+function socketOnData(data) {
+  var socket = this;
+
+  // Begin parsing
+  var ret = socket.parser.execute(data);
+
+  if (ret instanceof Error) {
+    socket.destroy();
+  }
+}
+
+
+function socketOnEnd() {
+  var socket = this;
+  var server = socket._server;
+  var ret = socket.parser.finish();
+
+  if (ret instanceof Error) {
+    socket.destroy();
+    return;
+  }
+
+  socket.parser = null;
+
+  if (!server.httpAllowHalfOpen && socket._socketState.writable) {
+    socket.end();
+  }
+}
+
+
+function socketOnClose() {
+  var socket = this;
+
+  if (socket.parser) {
+    socket.parser = null;
+  }
+}
+
+
+function socketOnTimeout() {
+  var socket = this;
+  var server = socket._server;
+
+  var serverTimeout = server.emit('timeout', socket);
+  var req = socket.parser && socket.parser.incoming;
+  var reqTimeout = req && !req.complete && req.emit('timeout', socket);
+  var res = socket._httpMessage;
+  var resTimeout = res && res.emit('timeout', socket);
+
+  // if user doesn't provide timeout handler, kill socket.
+  // otherwise, user cb must take care of timeouted socket.
+  if (!serverTimeout && !reqTimeout && !resTimeout) {
+    socket.destroy();
+  }
+}
+
+
+function socketOnError(err) {
+  var socket = this;
+  var server = socket._server;
+
+  server.emit("clientError", err, socket);
+}
+
+
+// This is called by parserOnHeadersComplete after req header is parsed.
+// TODO: keepalive support
+function parserOnIncoming(req, shouldKeepAlive) {
+  var socket = req.socket;
+  var server = socket._server;
+
+  var res = new ServerResponse(req);
+  res.assignSocket(socket);
+  res.on('prefinish', resOnFinish);
+
+  server.emit('request', req, res);
+
+  // In server, HTTPParser determines whether body should be parsed or not.
+  // It is fine to return false
+  return false;
+}
+
+
+// This cb is called when response ended
+// (res.end emits 'prefinish' event)
+function resOnFinish() {
+  var res = this;
+  var socket = res.socket;
+
+  res.detachSocket();
+
+  // cf) In Node, ConnectionListener has a list of incoming msgs.
+  socket.destroySoon();
+}
diff --git a/src/js/i2c.js b/src/js/i2c.js
new file mode 100644 (file)
index 0000000..17cfde2
--- /dev/null
@@ -0,0 +1,173 @@
+/* Copyright (c) 2013, Kelly Korevec <korevec@gmail.com>
+ * 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) {
+  var i2c_bus = new I2CBus(configurable, callback);
+  return i2c_bus;
+};
+
+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;
+
+    this.i2c = 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() {
+  this.i2c.close();
+};
+
+
+I2CBus.prototype.setAddress = function(address, callback) {
+  if (!util.isNumber(address)) {
+    throw new TypeError('Bad argument - address: Number');
+  }
+
+  this.address = address;
+  this.i2c.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);
+  this.i2c.write(array, function(err) {
+    util.isFunction(callback) && callback(err);
+  });
+};
+
+I2CBus.prototype.writeByte = function(byte, callback) {
+  if (!util.isNumber(byte)) {
+    throw new TypeError('Bad argument - byte: Number');
+  }
+
+  this.setAddress(this.address);
+  this.i2c.writeByte(byte, function(err) {
+    util.isFunction(callback) && callback(err);
+  });
+};
+
+I2CBus.prototype.writeBytes = function(cmd, array, callback) {
+  if (!util.isNumber(cmd)) {
+    throw new TypeError('Bad argument - cmd: Number');
+  }
+  if (!util.isArray(array)) {
+    throw new TypeError('Bad argument - array: Array');
+  }
+
+  this.setAddress(this.address);
+  this.i2c.writeBlock(cmd, 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);
+  this.i2c.read(length, function(err, data) {
+    util.isFunction(callback) && callback(err, data);
+  });
+};
+
+I2CBus.prototype.readByte = function(callback) {
+  this.setAddress(this.address);
+  this.i2c.readByte(function(err, data) {
+    util.isFunction(callback) && callback(err, data);
+  });
+};
+
+I2CBus.prototype.readBytes = function(cmd, length, callback) {
+  if (!util.isNumber(cmd)) {
+    throw new TypeError('Bad argument - cmd: Number');
+  }
+  if (!util.isNumber(length)) {
+    throw new TypeError('Bad argument - length: Number');
+  }
+
+  this.setAddress(this.address);
+  this.i2c.readBlock(cmd, length, 0, function(err, resArray) {
+    util.isFunction(callback) && callback(err, resArray);
+  });
+};
+
+module.exports = I2C;
diff --git a/src/js/iotjs.js b/src/js/iotjs.js
new file mode 100644 (file)
index 0000000..b533800
--- /dev/null
@@ -0,0 +1,223 @@
+/* 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(process) {
+
+  this.global = this;
+  global.process = process;
+
+
+  function startIoTjs() {
+    initGlobal();
+    initTimers();
+
+    initProcess();
+
+    var module = Native.require('module');
+
+    module.runMain();
+  };
+
+
+  function initGlobal() {
+    global.process = process;
+    global.global = global;
+    global.GLOBAL = global;
+    global.root = global;
+    global.console = Native.require('console');
+    global.Buffer = Native.require('buffer');
+  };
+
+
+  function initTimers() {
+    global.setTimeout = function() {
+      var t = Native.require('timers');
+      return t.setTimeout.apply(this, arguments);
+    };
+
+    global.setInterval = function() {
+      var t = Native.require('timers');
+      return t.setInterval.apply(this, arguments);
+    };
+
+    global.clearTimeout = function() {
+      var t = Native.require('timers');
+      return t.clearTimeout.apply(this, arguments);
+    };
+
+    global.clearInterval = function() {
+      var t = Native.require('timers');
+      return t.clearInterval.apply(this, arguments);
+    };
+  }
+
+
+  function initProcess() {
+    initProcessArgv();
+    initProcessEvents();
+    initProcessNextTick();
+    initProcessUncaughtException();
+    initProcessExit();
+  }
+
+
+  // Initialize `process.argv`
+  function initProcessArgv() {
+    process.argv = [];
+    process._initArgv();
+  }
+
+
+  function initProcessEvents() {
+    var EventEmitter = Native.require('events').EventEmitter;
+
+    EventEmitter.call(process);
+
+    var keys = Object.keys(EventEmitter.prototype);
+    for (var i = 0; i < keys.length; ++i) {
+      var key = keys[i];
+      if (!process[key]) {
+        process[key] = EventEmitter.prototype[key];
+      }
+    }
+  }
+
+
+  function initProcessNextTick() {
+    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 = [];
+
+      for (var i = 0; i < callbacks.length; ++i) {
+        try {
+          callbacks[i]();
+        } catch (e) {
+          process._onUncaughtException(e);
+        }
+      }
+
+      return nextTickQueue.length > 0;
+    }
+
+    function nextTick(callback) {
+      nextTickQueue.push(callback);
+    }
+  }
+
+
+  function initProcessUncaughtException() {
+    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);
+      }
+    }
+  }
+
+
+  function initProcessExit() {
+    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);
+      }
+    };
+  }
+
+
+  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);
+  };
+
+  startIoTjs();
+
+});
diff --git a/src/js/module.js b/src/js/module.js
new file mode 100644 (file)
index 0000000..861a714
--- /dev/null
@@ -0,0 +1,221 @@
+/* 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 + "/node_modules/");
+}
+if(process.env.HOME){
+  moduledirs.push(process.env.HOME + "/node_modules/");
+}
+if(process.env.NODE_PATH){
+  moduledirs.push(process.env.NODE_PATH + "/node_modules/")
+}
+
+iotjs_module_t.concatdir = function(a, b){
+  var rlist = [];
+  for(var i = 0; i< a.length ; i++) {
+    rlist.push(a[i]);
+  }
+
+  for(var i = 0; i< b.length ; i++) {
+    rlist.push(b[i]);
+  }
+
+  return rlist;
+};
+
+
+iotjs_module_t.resolveDirectories = function(id, parent) {
+  var dirs = moduledirs;
+  if(parent) {
+    if(!parent.dirs){
+      parent.dirs = [];
+    }
+    dirs = iotjs_module_t.concatdir(parent.dirs, dirs);
+  }
+  return dirs;
+};
+
+
+iotjs_module_t.resolveFilepath = function(id, directories) {
+
+  for(var i = 0; i<directories.length ; i++) {
+    var dir = directories[i];
+    // 1. 'id'
+    var filepath = iotjs_module_t.tryPath(dir+id);
+
+    if(filepath){
+      return filepath;
+    }
+
+    // 2. 'id.js'
+    filepath = iotjs_module_t.tryPath(dir+id+'.js');
+
+    if(filepath){
+      return filepath;
+    }
+
+    // 3. package path /node_modules/id
+    var packagepath = dir + id;
+    var jsonpath = packagepath + "/package.json";
+    filepath = iotjs_module_t.tryPath(jsonpath);
+    if(filepath){
+      var pkgSrc = process.readSource(jsonpath);
+      var pkgMainFile = JSON.parse(pkgSrc).main;
+      filepath = iotjs_module_t.tryPath(packagepath + "/" + pkgMainFile);
+      if(filepath){
+        return filepath;
+      }
+      // index.js
+      filepath = iotjs_module_t.tryPath(packagepath + "/" + "index.js");
+      if(filepath){
+        return filepath;
+      }
+    }
+
+  }
+
+  return false;
+};
+
+
+iotjs_module_t.resolveModPath = function(id, parent) {
+
+  // 0. resolve Directory for lookup
+  var directories = iotjs_module_t.resolveDirectories(id, parent);
+
+  var filepath = iotjs_module_t.resolveFilepath(id, directories);
+
+  if(filepath){
+    return filepath;
+  }
+
+  return false;
+};
+
+
+iotjs_module_t.tryPath = function(path) {
+  var stats = iotjs_module_t.statPath(path);
+  if(stats && !stats.isDirectory()) {
+    return path;
+  }
+  else {
+    return false;
+  }
+};
+
+
+iotjs_module_t.statPath = function(path) {
+  try {
+    return fs.statSync(path);
+  } catch (ex) {}
+  return false;
+};
+
+
+iotjs_module_t.load = function(id, parent, isMain) {
+  if(process.native_sources[id]){
+    return Native.require(id);
+  }
+  var module = new iotjs_module_t(id, parent);
+
+  var modPath = iotjs_module_t.resolveModPath(module.id, module.parent);
+
+  var cachedModule = iotjs_module_t.cache[modPath];
+  if (cachedModule) {
+    return cachedModule.exports;
+  }
+
+  if (modPath) {
+    module.filename = modPath;
+    module.SetModuleDirs(modPath);
+    module.compile();
+  }
+  else {
+    throw new Error('No module found');
+  }
+
+  iotjs_module_t.cache[modPath] = module;
+
+  return module.exports;
+};
+
+
+iotjs_module_t.prototype.compile = function() {
+  var self = this;
+  var requireForThis = function(path) {
+      return self.require(path);
+  };
+
+  var source = process.readSource(self.filename);
+  var fn = process.compile(source);
+  fn.call(self.exports, self.exports, requireForThis, self);
+};
+
+
+iotjs_module_t.runMain = function(){
+  iotjs_module_t.load(process.argv[1], null, true);
+  process._onNextTick();
+};
+
+
+
+iotjs_module_t.prototype.SetModuleDirs = function(filepath)
+{
+  // At next require, search module from parent's directory
+  var dir = "";
+  var i;
+  for(i = filepath.length-1;i>=0 ; i--) {
+    if(filepath[i] == '/'){
+      break;
+    }
+  }
+
+  // save filepath[0] to filepath[i]
+  // e.g. /home/foo/main.js ->  /home/foo/
+  for(;i>=0 ; i--) {
+    dir = filepath[i] + dir;
+  }
+  this.dirs = [dir];
+};
+
+
+iotjs_module_t.prototype.require = function(id) {
+  return iotjs_module_t.load(id, this);
+};
diff --git a/src/js/net.js b/src/js/net.js
new file mode 100644 (file)
index 0000000..3af8b90
--- /dev/null
@@ -0,0 +1,647 @@
+/* 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 stream = require('stream');
+var util = require('util');
+var assert = require('assert');
+
+var TCP = process.binding(process.binding.tcp);
+
+
+function createTCP() {
+  var tcp = new TCP();
+  return tcp;
+}
+
+
+function SocketState(options) {
+  // 'true' during connection handshaking.
+  this.connecting = false;
+
+  // become 'true' when connection established.
+  this.connected = false;
+
+  this.writable = true;
+  this.readable = true;
+
+  this.destroyed = false;
+
+  this.allowHalfOpen = options && options.allowHalfOpen || false;
+}
+
+
+function Socket(options) {
+  if (!(this instanceof Socket)) {
+    return new Socket(options);
+  }
+
+  if (util.isUndefined(options)) {
+    options = {};
+  }
+
+  stream.Duplex.call(this, options);
+
+  this._timer = null;
+  this._timeout = 0;
+
+  this._socketState = new SocketState(options);
+
+  if (options.handle) {
+    this._handle = options.handle;
+    this._handle.owner = this;
+  }
+
+  this.on('finish', onSocketFinish);
+  this.on('end', onSocketEnd);
+}
+
+
+// Socket inherits Duplex.
+util.inherits(Socket, stream.Duplex);
+
+
+Socket.prototype.connect = function() {
+  var self = this;
+  var state = self._socketState;
+
+  var args = normalizeConnectArgs(arguments);
+  var options = args[0];
+  var callback = args[1];
+
+  if (state.connecting || state.connected) {
+    return self;
+  }
+
+  if (!self._handle) {
+    self._handle = createTCP();
+    self._handle.owner = self;
+  }
+
+  if (util.isFunction(callback)) {
+    self.once('connect', callback);
+  }
+
+  resetSocketTimeout(self);
+
+  state.connecting = true;
+
+  var dns = require('dns');
+  var host = options.host ? options.host : 'localhost';
+  var port = options.port;
+  var dnsopts = {
+    family: options.family >>> 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('port should be 4 or 6: ' + dnsopts.family);
+
+  self._host = host;
+  dns.lookup(host, dnsopts, function(err, ip, family) {
+    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.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) {
+    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: ' + status));
+    }
+  };
+
+  socket._handle.connect(ip, port, afterConnect);
+}
+
+
+function close(socket) {
+  socket._handle.owner = socket;
+  socket._handle.onclose = function() {
+    socket.emit('close');
+  };
+
+  socket._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) {
+    // 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 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 err;
+  }
+
+  process.nextTick(function() {
+    if (self._handle) {
+      self.emit('listening');
+    }
+  });
+};
+
+
+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: ' + 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[, connectListenr])
+// 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;
diff --git a/src/js/pwm.js b/src/js/pwm.js
new file mode 100644 (file)
index 0000000..0b866f1
--- /dev/null
@@ -0,0 +1,230 @@
+/* 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 new PwmPin(configuration, callback);
+};
+
+
+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;
+  }
+
+  this._binding = new pwm(self._configuration, function(err) {
+    util.isFunction(callback) && callback.call(self, err);
+  });
+
+  process.on('exit', (function(self) {
+    return function() {
+      if (!util.isNull(self._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(this._binding)) {
+    throw new Error('Pwm pin is not opened');
+  }
+
+  if (this._validatePeriod(period)) {
+    this._binding.setPeriod(period, function(err) {
+      util.isFunction(callback) && callback.call(self, err);
+    });
+  }
+};
+
+PwmPin.prototype.setPeriodSync = function(period) {
+  if (util.isNull(this._binding)) {
+    throw new Error('Pwm pin is not opened');
+  }
+
+  if (this._validatePeriod(period)) {
+    this._binding.setPeriod(period);
+  }
+};
+
+PwmPin.prototype.setFrequency = function(frequency, callback) {
+  var self = this;
+
+  if (util.isNull(this._binding)) {
+    throw new Error('Pwm pin is not opened');
+  }
+
+  if (this._validateFrequency(frequency)) {
+    this._binding.setPeriod(1.0 / frequency, function(err) {
+      util.isFunction(callback) && callback.call(self, err);
+    });
+  }
+};
+
+PwmPin.prototype.setFrequencySync = function(frequency) {
+  if (util.isNull(this._binding)) {
+    throw new Error('Pwm pin is not opened');
+  }
+
+  if (this._validateFrequency(frequency)) {
+    this._binding.setPeriod(1.0 / frequency);
+  }
+};
+
+PwmPin.prototype.setDutyCycle = function(dutyCycle, callback) {
+  var self = this;
+
+  if (util.isNull(this._binding)) {
+    throw new Error('Pwm pin is not opened');
+  }
+
+  // Check arguments.
+  if (this._validateDutyCycle(dutyCycle)) {
+    this._binding.setDutyCycle(dutyCycle, function(err) {
+      util.isFunction(callback) && callback.call(self, err);
+    });
+  }
+};
+
+PwmPin.prototype.setDutyCycleSync = function(dutyCycle) {
+  if (util.isNull(this._binding)) {
+    throw new Error('Pwm pin is not opened');
+  }
+
+  // Check arguments.
+  if (this._validateDutyCycle(dutyCycle)) {
+    this._binding.setDutyCycle(dutyCycle);
+  }
+};
+
+PwmPin.prototype.setEnable = function(enable, callback) {
+  var self = this;
+
+  if (util.isNull(this._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));
+  }
+
+  this._binding.setEnable(!!enable, function(err) {
+    util.isFunction(callback) && callback.call(self, err);
+  });
+};
+
+PwmPin.prototype.setEnableSync = function(enable) {
+  if (util.isNull(this._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));
+  }
+
+  this._binding.setEnable(!!enable);
+};
+
+PwmPin.prototype.close = function(callback) {
+  if (util.isNull(this._binding)) {
+    throw new Error('Pwm pin is not opened');
+  }
+
+  this._binding.close(function(err) {
+    util.isFunction(callback) && callback.call(self, err);
+  });
+};
+
+PwmPin.prototype.closeSync = function() {
+  if (util.isNull(this._binding)) {
+    throw new Error('Pwm pin is not opened');
+  }
+
+  this._binding.close();
+};
+
+module.exports = Pwm;
diff --git a/src/js/spi.js b/src/js/spi.js
new file mode 100644 (file)
index 0000000..17e30e5
--- /dev/null
@@ -0,0 +1,214 @@
+/* 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 new SpiBus(configuration, callback);
+};
+
+Spi.prototype.MODE = spi.MODE;
+Spi.prototype.CHIPSELECT = spi.CHIPSELECT;
+Spi.prototype.BITORDER = spi.BITORDER;
+
+
+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;
+  }
+
+  this._binding = new spi.Spi(configuration, function(err) {
+   util.isFunction(callback) && callback.call(self, err);
+  });
+
+  process.on('exit', (function(self) {
+   return function() {
+     if (!util.isNull(self._binding)) {
+       self.closeSync();
+     }
+   };
+  })(this));
+}
+
+SpiBus.prototype.transfer = function(txBuffer, rxBuffer, callback) {
+  var self = this;
+
+  if (util.isNull(this._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)) {
+    this._binding.transferArray(txBuffer, rxBuffer, afterCallback);
+  } else if (util.isBuffer(txBuffer) && util.isBuffer(rxBuffer)) {
+    this._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(this._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 = this._binding.transferArray(txBuffer, rxBuffer);
+  } else if (util.isBuffer(txBuffer) && util.isBuffer(rxBuffer)) {
+    data = this._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(this._binding)) {
+    throw new Error('SPI bus is not opened');
+  }
+
+  return this._binding.close(function(err) {
+    util.isFunction(callback) && callback.call(self, err);
+  });
+};
+
+SpiBus.prototype.closeSync = function() {
+  if (util.isNull(this._binding)) {
+    throw new Error('SPI bus is not opened');
+  }
+
+  return this._binding.close();
+};
+
+module.exports = Spi;
diff --git a/src/js/stm32f4dis.js b/src/js/stm32f4dis.js
new file mode 100644 (file)
index 0000000..2cbcb06
--- /dev/null
@@ -0,0 +1,16 @@
+/* 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);
diff --git a/src/js/stream.js b/src/js/stream.js
new file mode 100644 (file)
index 0000000..4924164
--- /dev/null
@@ -0,0 +1,33 @@
+/* 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 EE = require('events').EventEmitter;
+var util = require('util');
+
+
+function Stream() {
+  EE.call(this);
+};
+
+
+util.inherits(Stream, EE);
+
+
+exports.Stream = Stream;
+
+exports.Readable = require('stream_readable');
+exports.Writable = require('stream_writable');
+exports.Duplex = require('stream_duplex');
diff --git a/src/js/stream_duplex.js b/src/js/stream_duplex.js
new file mode 100644 (file)
index 0000000..7beb75c
--- /dev/null
@@ -0,0 +1,46 @@
+/* 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;
diff --git a/src/js/stream_readable.js b/src/js/stream_readable.js
new file mode 100644 (file)
index 0000000..a29bd56
--- /dev/null
@@ -0,0 +1,217 @@
+/* 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) {
+  emitError(this, error);
+};
+
+
+Readable.prototype.push = function(chunk, encoding) {
+  var state = this._readableState;
+
+  if (!util.isString(chunk) &&
+      !util.isBuffer(chunk) &&
+      !util.isNull(chunk)) {
+    emitError(this, TypeError('Invalid chunk'));
+  } else if (util.isNull(chunk)) {
+    onEof(this);
+  } else if (state.ended) {
+    emitError(this, 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);
+      emitReadable(this);
+    }
+  }
+};
+
+
+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 emitReadable(stream) {
+  stream.emit('readable');
+};
+
+
+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 emitError(stream, er) {
+  stream.emit('error', er);
+};
+
+
+function onEof(stream) {
+  var state = stream._readableState;
+
+  state.ended = true;
+
+  if (state.length == 0) {
+    emitEnd(stream);
+  }
+};
+
+
+module.exports = Readable;
diff --git a/src/js/stream_writable.js b/src/js/stream_writable.js
new file mode 100644 (file)
index 0000000..30e084f
--- /dev/null
@@ -0,0 +1,280 @@
+/* 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.
+  var hwm = options.highWaterMark;
+  this.highWaterMark = (hwm || hwm === 0) ? hwm : 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;
+  var res = false;
+
+  if (state.ended) {
+    writeAfterEnd(this, callback);
+  } else {
+    res = writeOrBuffer(this, chunk, callback);
+  }
+
+  return res;
+};
+
+
+// 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(status) {
+  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(function(){
+      callback(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;
+
+  var afterWrite = function(status) {
+    stream._onwrite(status);
+  };
+
+  // Write down the chunk data.
+  stream._write(chunk, callback, afterWrite);
+}
+
+
+// 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(function(){
+      emitFinish(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;
diff --git a/src/js/testdriver.js b/src/js/testdriver.js
new file mode 100644 (file)
index 0000000..1dc0d74
--- /dev/null
@@ -0,0 +1,16 @@
+/* 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);
diff --git a/src/js/timers.js b/src/js/timers.js
new file mode 100644 (file)
index 0000000..bb7bc22
--- /dev/null
@@ -0,0 +1,136 @@
+/* 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.close();
+    }
+  }
+};
+
+
+Timeout.prototype.activate = 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.close = function() {
+  this.callback = undefined;
+  if (this.handler) {
+    this.handler.timeoutObj = undefined;
+    this.handler.stop();
+    this.handler = undefined;
+  }
+};
+
+
+exports.setTimeout = function(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 <= 2) {
+    timeout.callback = callback;
+  } else {
+    var args = Array.prototype.slice.call(arguments, 2);
+    timeout.callback = function() {
+      callback.apply(timeout, args);
+    };
+  }
+
+  timeout.activate();
+
+  return timeout;
+};
+
+
+exports.clearTimeout = function(timeout) {
+  if (timeout && timeout.callback && (timeout instanceof Timeout))
+    timeout.close();
+  else
+    throw new Error('clearTimeout() - invalid timeout');
+};
+
+
+exports.setInterval = function(callback, repeat) {
+  if (!util.isFunction(callback)) {
+    throw new TypeError('Bad arguments: callback must be a Function');
+  }
+
+  repeat *= 1;
+  if (repeat < 1 || repeat > TIMEOUT_MAX) {
+    repeat = 1;
+  }
+  var timeout = new Timeout(repeat);
+
+  // set interval timeout handler.
+  if (arguments.length <= 2) {
+    timeout.callback = callback;
+  } else {
+    var args = Array.prototype.slice.call(arguments, 2);
+    timeout.callback = function() {
+      callback.apply(timeout, args);
+    };
+  }
+  timeout.isrepeat = true;
+  timeout.activate();
+
+  return timeout;
+};
+
+
+exports.clearInterval = function(timeout) {
+  if (timeout && timeout.isrepeat)
+    timeout.close();
+  else
+    throw new Error('clearInterval() - invalid interval');
+};
diff --git a/src/js/uart.js b/src/js/uart.js
new file mode 100644 (file)
index 0000000..8453c51
--- /dev/null
@@ -0,0 +1,133 @@
+/* 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 new UartPort(configuration, callback);
+};
+
+
+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);
+
+  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(self._binding)) {
+        self.closeSync();
+      }
+    };
+  })(this));
+}
+
+util.inherits(UartPort, EventEmitter);
+
+UartPort.prototype.write = function(buffer, callback) {
+  var self = this;
+
+  if (util.isNull(this._binding)) {
+    throw new Error('UART port is not opened');
+  }
+
+  this._binding.write(buffer, function(err) {
+    util.isFunction(callback) && callback.call(self, err);
+  });
+};
+
+UartPort.prototype.writeSync = function(buffer) {
+  var self = this;
+
+  if (util.isNull(this._binding)) {
+    throw new Error('UART port is not opened');
+  }
+
+  this._binding.write(buffer);
+};
+
+UartPort.prototype.close = function(callback) {
+  var self = this;
+
+  if (util.isNull(this._binding)) {
+    throw new Error('UART port is not opened');
+  }
+
+  this._binding.close(function(err) {
+    util.isFunction(callback) && callback.call(self, err);
+  });
+  this._binding = null;
+};
+
+UartPort.prototype.closeSync = function() {
+  if (util.isNull(this._binding)) {
+    throw new Error('UART port is not opened');
+  }
+
+  this._binding.close();
+  this._binding = null;
+};
+
+module.exports = Uart;
diff --git a/src/js/util.js b/src/js/util.js
new file mode 100644 (file)
index 0000000..9741c4c
--- /dev/null
@@ -0,0 +1,175 @@
+/* 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': return '[JSON object]';
+      default: return m;
+    }
+  });
+
+  while (i < args.length) {
+      str += ' ' + args[i++].toString();
+  }
+
+  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;
diff --git a/src/module/iotjs_module_adc.c b/src/module/iotjs_module_adc.c
new file mode 100644 (file)
index 0000000..aa3961d
--- /dev/null
@@ -0,0 +1,290 @@
+/* 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"
+
+
+static void iotjs_adc_destroy(iotjs_adc_t* 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,
+                               (JFreeHandlerType)iotjs_adc_destroy);
+
+  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, const iotjs_jval_t* jadc, 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 = iotjs_adc_instance_from_jval(jadc);
+  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, jthis, jcallback, op)                                  \
+  do {                                                                         \
+    uv_loop_t* loop = iotjs_environment_loop(iotjs_environment_get());         \
+    iotjs_adc_reqwrap_t* req_wrap =                                            \
+        iotjs_adc_reqwrap_create(jcallback, jthis, 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) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_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, jadc, jcallback, kAdcOpOpen);
+}
+
+
+JHANDLER_FUNCTION(Read) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_CHECK_ARG_IF_EXIST(0, function);
+
+  const iotjs_jval_t* jcallback = JHANDLER_GET_ARG_IF_EXIST(0, function);
+  const iotjs_jval_t* jadc = JHANDLER_GET_THIS(object);
+  iotjs_adc_t* adc = iotjs_adc_instance_from_jval(jadc);
+
+  if (jcallback) {
+    ADC_ASYNC(read, jadc, 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_CHECK_THIS(object);
+  JHANDLER_CHECK_ARG_IF_EXIST(0, function);
+
+  const iotjs_jval_t* jcallback = JHANDLER_GET_ARG_IF_EXIST(0, function);
+  const iotjs_jval_t* jadc = JHANDLER_GET_THIS(object);
+  iotjs_adc_t* adc = iotjs_adc_instance_from_jval(jadc);
+
+  if (jcallback) {
+    ADC_ASYNC(close, jadc, 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;
+}
diff --git a/src/module/iotjs_module_adc.h b/src/module/iotjs_module_adc.h
new file mode 100644 (file)
index 0000000..4fd04fd
--- /dev/null
@@ -0,0 +1,81 @@
+/* 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 */
diff --git a/src/module/iotjs_module_blehcisocket.c b/src/module/iotjs_module_blehcisocket.c
new file mode 100644 (file)
index 0000000..1318e37
--- /dev/null
@@ -0,0 +1,251 @@
+/* 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+#define THIS iotjs_blehcisocket_t* blehcisocket
+
+
+static void iotjs_blehcisocket_destroy(THIS);
+
+
+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,
+                               (JFreeHandlerType)iotjs_blehcisocket_destroy);
+
+  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_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(0);
+
+  const iotjs_jval_t* jblehcisocket = JHANDLER_GET_THIS(object);
+
+  iotjs_blehcisocket_t* blehcisocket =
+      iotjs_blehcisocket_instance_from_jval(jblehcisocket);
+
+  iotjs_blehcisocket_start(blehcisocket);
+
+  iotjs_jhandler_return_undefined(jhandler);
+}
+
+
+JHANDLER_FUNCTION(BindRaw) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_CHECK(ge(iotjs_jhandler_get_arg_length(jhandler), 1));
+
+  const iotjs_jval_t* jblehcisocket = JHANDLER_GET_THIS(object);
+
+  iotjs_blehcisocket_t* blehcisocket =
+      iotjs_blehcisocket_instance_from_jval(jblehcisocket);
+
+  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_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(1, number);
+
+  const iotjs_jval_t* jblehcisocket = JHANDLER_GET_THIS(object);
+
+  iotjs_blehcisocket_t* blehcisocket =
+      iotjs_blehcisocket_instance_from_jval(jblehcisocket);
+
+  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_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(0);
+
+  const iotjs_jval_t* jblehcisocket = JHANDLER_GET_THIS(object);
+
+  iotjs_blehcisocket_t* blehcisocket =
+      iotjs_blehcisocket_instance_from_jval(jblehcisocket);
+
+  iotjs_blehcisocket_bindControl(blehcisocket);
+
+  iotjs_jhandler_return_undefined(jhandler);
+}
+
+
+JHANDLER_FUNCTION(IsDevUp) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(0);
+
+  const iotjs_jval_t* jblehcisocket = JHANDLER_GET_THIS(object);
+
+  iotjs_blehcisocket_t* blehcisocket =
+      iotjs_blehcisocket_instance_from_jval(jblehcisocket);
+
+  bool ret = iotjs_blehcisocket_isDevUp(blehcisocket);
+
+  iotjs_jhandler_return_boolean(jhandler, ret);
+}
+
+
+JHANDLER_FUNCTION(SetFilter) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(1, object);
+
+  const iotjs_jval_t* jblehcisocket = JHANDLER_GET_THIS(object);
+  iotjs_blehcisocket_t* blehcisocket =
+      iotjs_blehcisocket_instance_from_jval(jblehcisocket);
+  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_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(0);
+
+  const iotjs_jval_t* jblehcisocket = JHANDLER_GET_THIS(object);
+
+  iotjs_blehcisocket_t* blehcisocket =
+      iotjs_blehcisocket_instance_from_jval(jblehcisocket);
+
+  iotjs_blehcisocket_stop(blehcisocket);
+
+  iotjs_jhandler_return_undefined(jhandler);
+}
+
+
+JHANDLER_FUNCTION(Write) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(1, object);
+
+  const iotjs_jval_t* jblehcisocket = JHANDLER_GET_THIS(object);
+  iotjs_blehcisocket_t* blehcisocket =
+      iotjs_blehcisocket_instance_from_jval(jblehcisocket);
+  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) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_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;
+}
diff --git a/src/module/iotjs_module_blehcisocket.h b/src/module/iotjs_module_blehcisocket.h
new file mode 100644 (file)
index 0000000..93cc6ad
--- /dev/null
@@ -0,0 +1,87 @@
+/* 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, int length);
+void iotjs_blehcisocket_poll(THIS);
+void iotjs_blehcisocket_stop(THIS);
+void iotjs_blehcisocket_write(THIS, char* data, int length);
+void iotjs_blehcisocket_emitErrnoError(THIS);
+int iotjs_blehcisocket_devIdFor(THIS, int* pDevId, bool isUp);
+void 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 */
diff --git a/src/module/iotjs_module_buffer.c b/src/module/iotjs_module_buffer.c
new file mode 100644 (file)
index 0000000..3b838c9
--- /dev/null
@@ -0,0 +1,519 @@
+/* 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 <stdlib.h>
+#include <string.h>
+
+
+static void iotjs_bufferwrap_destroy(iotjs_bufferwrap_t* 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,
+                               (JFreeHandlerType)iotjs_bufferwrap_destroy);
+  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(int index, size_t low, size_t upper) {
+  if (index < (int)low) {
+    return low;
+  }
+  if (index > (int)upper) {
+    return upper;
+  }
+  return index;
+}
+
+
+static unsigned hex2bin(char c) {
+  if (c >= '0' && c <= '9')
+    return c - '0';
+  if (c >= 'A' && c <= 'F')
+    return 10 + (c - 'A');
+  if (c >= 'a' && c <= 'f')
+    return 10 + (c - 'a');
+
+  IOTJS_ASSERT(!"Bad argument");
+  return (unsigned)(-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) {
+    unsigned a = hex2bin(src[i * 2 + 0]);
+    unsigned b = hex2bin(src[i * 2 + 1]);
+    if (!~a || !~b)
+      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) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(2, object, number);
+
+  const iotjs_jval_t* jbuiltin = JHANDLER_GET_THIS(object);
+  const iotjs_jval_t* jbuffer = JHANDLER_GET_ARG(0, object);
+  int 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_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(1, object);
+
+  const iotjs_jval_t* jsrc_builtin = JHANDLER_GET_THIS(object);
+  iotjs_bufferwrap_t* src_buffer_wrap =
+      iotjs_bufferwrap_from_jbuiltin(jsrc_builtin);
+
+  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);
+}
+
+
+JHANDLER_FUNCTION(Copy) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(4, object, number, number, number);
+
+  const iotjs_jval_t* jsrc_builtin = JHANDLER_GET_THIS(object);
+  iotjs_bufferwrap_t* src_buffer_wrap =
+      iotjs_bufferwrap_from_jbuiltin(jsrc_builtin);
+
+  const iotjs_jval_t* jdst_buffer = JHANDLER_GET_ARG(0, object);
+  iotjs_bufferwrap_t* dst_buffer_wrap =
+      iotjs_bufferwrap_from_jbuffer(jdst_buffer);
+
+  int dst_start = JHANDLER_GET_ARG(1, number);
+  int src_start = JHANDLER_GET_ARG(2, number);
+  int src_end = JHANDLER_GET_ARG(3, number);
+
+  size_t dst_length = iotjs_bufferwrap_length(dst_buffer_wrap);
+  size_t src_length = iotjs_bufferwrap_length(src_buffer_wrap);
+
+  dst_start = bound_range(dst_start, 0, dst_length);
+  src_start = bound_range(src_start, 0, src_length);
+  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_CHECK_ARGS(3, string, number, number);
+
+  iotjs_string_t src = JHANDLER_GET_ARG(0, string);
+  int offset = JHANDLER_GET_ARG(1, number);
+  int length = JHANDLER_GET_ARG(2, number);
+
+  const iotjs_jval_t* jbuiltin = JHANDLER_GET_THIS(object);
+
+  iotjs_bufferwrap_t* buffer_wrap = iotjs_bufferwrap_from_jbuiltin(jbuiltin);
+
+  size_t buffer_length = iotjs_bufferwrap_length(buffer_wrap);
+  offset = bound_range(offset, 0, buffer_length);
+  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_CHECK_ARGS(2, number, number);
+
+  uint8_t src = (uint8_t)JHANDLER_GET_ARG(0, number);
+  int offset = JHANDLER_GET_ARG(1, number);
+  int length = 1;
+
+  const iotjs_jval_t* jbuiltin = JHANDLER_GET_THIS(object);
+
+  iotjs_bufferwrap_t* buffer_wrap = iotjs_bufferwrap_from_jbuiltin(jbuiltin);
+
+  size_t buffer_length = iotjs_bufferwrap_length(buffer_wrap);
+  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, (const char*)&src,
+                                                 0, length, offset);
+
+  iotjs_jhandler_return_number(jhandler, copied);
+}
+
+
+JHANDLER_FUNCTION(HexWrite) {
+  JHANDLER_CHECK_ARGS(3, string, number, number);
+
+  iotjs_string_t src = JHANDLER_GET_ARG(0, string);
+  int offset = JHANDLER_GET_ARG(1, number);
+  int length = JHANDLER_GET_ARG(2, number);
+
+  const iotjs_jval_t* jbuiltin = JHANDLER_GET_THIS(object);
+
+  iotjs_bufferwrap_t* buffer_wrap = iotjs_bufferwrap_from_jbuiltin(jbuiltin);
+
+  size_t buffer_length = iotjs_bufferwrap_length(buffer_wrap);
+  offset = bound_range(offset, 0, buffer_length);
+  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_CHECK_ARGS(1, number);
+
+  int offset = JHANDLER_GET_ARG(0, number);
+
+  const iotjs_jval_t* jbuiltin = JHANDLER_GET_THIS(object);
+
+  iotjs_bufferwrap_t* buffer_wrap = iotjs_bufferwrap_from_jbuiltin(jbuiltin);
+
+  size_t buffer_length = iotjs_bufferwrap_length(buffer_wrap);
+  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_CHECK_ARGS(2, number, number);
+
+  const iotjs_jval_t* jbuiltin = JHANDLER_GET_THIS(object);
+  iotjs_bufferwrap_t* buffer_wrap = iotjs_bufferwrap_from_jbuiltin(jbuiltin);
+
+  int start = JHANDLER_GET_ARG(0, number);
+  int end = JHANDLER_GET_ARG(1, number);
+
+  if (start < 0) {
+    start += iotjs_bufferwrap_length(buffer_wrap);
+  }
+  start = bound_range(start, 0, iotjs_bufferwrap_length(buffer_wrap));
+
+  if (end < 0) {
+    end += iotjs_bufferwrap_length(buffer_wrap);
+  }
+  end = bound_range(end, 0, iotjs_bufferwrap_length(buffer_wrap));
+
+  if (end < start) {
+    end = start;
+  }
+
+  int length = end - start;
+  IOTJS_ASSERT(length >= 0);
+
+  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,
+                                 end, 0);
+
+  iotjs_jhandler_return_jval(jhandler, &jnew_buffer);
+  iotjs_jval_destroy(&jnew_buffer);
+}
+
+
+JHANDLER_FUNCTION(ToString) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(2, number, number);
+
+  const iotjs_jval_t* jbuiltin = JHANDLER_GET_THIS(object);
+  iotjs_bufferwrap_t* buffer_wrap = iotjs_bufferwrap_from_jbuiltin(jbuiltin);
+
+  int start = JHANDLER_GET_ARG(0, number);
+  int end = JHANDLER_GET_ARG(1, number);
+
+  start = bound_range(start, 0, iotjs_bufferwrap_length(buffer_wrap));
+  end = bound_range(end, 0, iotjs_bufferwrap_length(buffer_wrap));
+
+  if (end < start) {
+    end = start;
+  }
+
+  int length = end - start;
+  IOTJS_ASSERT(length >= 0);
+
+  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_CHECK_THIS(object);
+
+  const iotjs_jval_t* jbuiltin = JHANDLER_GET_THIS(object);
+  iotjs_bufferwrap_t* buffer_wrap = iotjs_bufferwrap_from_jbuiltin(jbuiltin);
+
+  int 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 (int 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) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_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;
+}
diff --git a/src/module/iotjs_module_buffer.h b/src/module/iotjs_module_buffer.h
new file mode 100644 (file)
index 0000000..2f1e53f
--- /dev/null
@@ -0,0 +1,53 @@
+/* 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 */
diff --git a/src/module/iotjs_module_console.c b/src/module/iotjs_module_console.c
new file mode 100644 (file)
index 0000000..c827636
--- /dev/null
@@ -0,0 +1,45 @@
+/* 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;
+}
diff --git a/src/module/iotjs_module_constants.c b/src/module/iotjs_module_constants.c
new file mode 100644 (file)
index 0000000..a02e675
--- /dev/null
@@ -0,0 +1,41 @@
+/* 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;
+}
diff --git a/src/module/iotjs_module_dns.c b/src/module/iotjs_module_dns.c
new file mode 100644 (file)
index 0000000..82c2f51
--- /dev/null
@@ -0,0 +1,202 @@
+/* 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) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_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) {
+    family = AF_UNSPEC;
+  } 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(AF_INET, hostname_data, &(addr.sin_addr));
+
+    if (result != 1) {
+      err = errno;
+    } else {
+      inet_ntop(AF_INET, &(addr.sin_addr), ip, INET6_ADDRSTRLEN);
+    }
+  }
+
+  iotjs_jargs_append_number(&args, err);
+  iotjs_jargs_append_string_raw(&args, ip);
+  iotjs_jargs_append_number(&args, family);
+
+  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;
+}
diff --git a/src/module/iotjs_module_dns.h b/src/module/iotjs_module_dns.h
new file mode 100644 (file)
index 0000000..51cc508
--- /dev/null
@@ -0,0 +1,43 @@
+/* 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 */
diff --git a/src/module/iotjs_module_fs.c b/src/module/iotjs_module_fs.c
new file mode 100644 (file)
index 0000000..82b1933
--- /dev/null
@@ -0,0 +1,502 @@
+/* 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, 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_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_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) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(1, number);
+  JHANDLER_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) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(3, string, number, number);
+  JHANDLER_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) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(5, number, object, number, number, number);
+  JHANDLER_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) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(5, number, object, number, number, number);
+  JHANDLER_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) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(1, string);
+  JHANDLER_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(MkDir) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(2, string, number);
+  JHANDLER_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) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(1, string);
+  JHANDLER_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) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(1, string);
+  JHANDLER_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) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(2, string, string);
+  JHANDLER_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) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(1, string);
+  JHANDLER_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_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;
+}
diff --git a/src/module/iotjs_module_fs.h b/src/module/iotjs_module_fs.h
new file mode 100644 (file)
index 0000000..aaab379
--- /dev/null
@@ -0,0 +1,39 @@
+/* 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 */
diff --git a/src/module/iotjs_module_gpio.c b/src/module/iotjs_module_gpio.c
new file mode 100644 (file)
index 0000000..d9b86f5
--- /dev/null
@@ -0,0 +1,373 @@
+/* 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 <string.h>
+
+#include "iotjs_def.h"
+#include "iotjs_module_gpio.h"
+#include "iotjs_objectwrap.h"
+#include <stdio.h>
+
+
+static void iotjs_gpio_destroy(iotjs_gpio_t* gpio);
+static iotjs_gpio_t* iotjs_gpio_instance_from_jval(const iotjs_jval_t* jgpio);
+
+
+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,
+                               (JFreeHandlerType)iotjs_gpio_destroy);
+  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, const iotjs_jval_t* jgpio, 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 = iotjs_gpio_instance_from_jval(jgpio);
+  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
+
+
+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);
+
+  if (status) {
+    iotjs_jargs_append_error(&jargs, "GPIO System Error");
+  } else {
+    switch (req_data->op) {
+      case kGpioOpOpen:
+        if (req_data->result < 0) {
+          iotjs_jargs_append_error(&jargs, "GPIO Open Error");
+        } else {
+          iotjs_jargs_append_null(&jargs);
+        }
+        break;
+      case kGpioOpWrite:
+        if (req_data->result < 0) {
+          iotjs_jargs_append_error(&jargs, "GPIO Write Error");
+        } else {
+          iotjs_jargs_append_null(&jargs);
+        }
+        break;
+      case kGpioOpRead:
+        if (req_data->result < 0) {
+          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 (req_data->result < 0) {
+          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);
+}
+
+
+#define GPIO_ASYNC(op)                                                 \
+  do {                                                                 \
+    uv_loop_t* loop = iotjs_environment_loop(iotjs_environment_get()); \
+    uv_work_t* req = iotjs_gpio_reqwrap_req(req_wrap);                 \
+    uv_queue_work(loop, req, iotjs_gpio_##op##_worker,                 \
+                  iotjs_gpio_after_worker);                            \
+  } while (0)
+
+
+// write(value, callback)
+JHANDLER_FUNCTION(Write) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(2, boolean, function);
+
+  bool value = JHANDLER_GET_ARG(0, boolean);
+  const iotjs_jval_t* jcallback = JHANDLER_GET_ARG(1, function);
+
+  iotjs_gpio_reqwrap_t* req_wrap =
+      iotjs_gpio_reqwrap_create(jcallback, JHANDLER_GET_THIS(object),
+                                kGpioOpWrite);
+
+  iotjs_gpio_reqdata_t* req_data = iotjs_gpio_reqwrap_data(req_wrap);
+  req_data->value = value;
+
+  GPIO_ASYNC(write);
+
+  iotjs_jhandler_return_null(jhandler);
+}
+
+
+// writeSync(value)
+JHANDLER_FUNCTION(WriteSync) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(1, boolean);
+
+  const iotjs_jval_t* jgpio = JHANDLER_GET_THIS(object);
+  iotjs_gpio_t* gpio = iotjs_gpio_instance_from_jval(jgpio);
+  IOTJS_VALIDATED_STRUCT_METHOD(iotjs_gpio_t, gpio);
+
+  bool value = JHANDLER_GET_ARG(0, boolean);
+
+  if (iotjs_gpio_write(_this->pin, value)) {
+    iotjs_jhandler_return_null(jhandler);
+  } else {
+    iotjs_jval_t jerror = iotjs_jval_create_error("GPIO WriteSync Error");
+    iotjs_jhandler_throw(jhandler, &jerror);
+    iotjs_jval_destroy(&jerror);
+  }
+}
+
+
+// read(callback)
+JHANDLER_FUNCTION(Read) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(1, function);
+
+  const iotjs_jval_t* jcallback = JHANDLER_GET_ARG(0, function);
+  iotjs_gpio_reqwrap_t* req_wrap =
+      iotjs_gpio_reqwrap_create(jcallback, JHANDLER_GET_THIS(object),
+                                kGpioOpRead);
+
+  GPIO_ASYNC(read);
+
+  iotjs_jhandler_return_null(jhandler);
+}
+
+
+// readSync()
+JHANDLER_FUNCTION(ReadSync) {
+  JHANDLER_CHECK_THIS(object);
+
+  const iotjs_jval_t* jgpio = JHANDLER_GET_THIS(object);
+  iotjs_gpio_t* gpio = iotjs_gpio_instance_from_jval(jgpio);
+  IOTJS_VALIDATED_STRUCT_METHOD(iotjs_gpio_t, gpio);
+
+  int value = iotjs_gpio_read(_this->pin);
+
+  if (value >= 0) {
+    iotjs_jhandler_return_boolean(jhandler, value);
+  } else {
+    iotjs_jval_t jerror = iotjs_jval_create_error("GPIO ReadSync Error");
+    iotjs_jhandler_throw(jhandler, &jerror);
+    iotjs_jval_destroy(&jerror);
+  }
+}
+
+
+// close(callback)
+JHANDLER_FUNCTION(Close) {
+  JHANDLER_CHECK_ARGS(1, function);
+
+  const iotjs_jval_t* jcallback = JHANDLER_GET_ARG(0, function);
+  iotjs_gpio_reqwrap_t* req_wrap =
+      iotjs_gpio_reqwrap_create(jcallback, JHANDLER_GET_THIS(object),
+                                kGpioOpClose);
+
+  GPIO_ASYNC(close);
+
+  iotjs_jhandler_return_null(jhandler);
+}
+
+
+// closeSync()
+JHANDLER_FUNCTION(CloseSync) {
+  JHANDLER_CHECK_THIS(object);
+
+  const iotjs_jval_t* jgpio = JHANDLER_GET_THIS(object);
+  iotjs_gpio_t* gpio = iotjs_gpio_instance_from_jval(jgpio);
+  IOTJS_VALIDATED_STRUCT_METHOD(iotjs_gpio_t, gpio);
+
+  if (iotjs_gpio_close(_this->pin)) {
+    iotjs_jhandler_return_null(jhandler);
+  } else {
+    iotjs_jval_t jerror = iotjs_jval_create_error("GPIO CloseSync Error");
+    iotjs_jhandler_throw(jhandler, &jerror);
+    iotjs_jval_destroy(&jerror);
+  }
+}
+
+
+// Constructor(configurable, callback)
+JHANDLER_FUNCTION(GpioConstructor) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_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));
+
+  // Create reqwrap
+  iotjs_gpio_reqwrap_t* req_wrap =
+      iotjs_gpio_reqwrap_create(JHANDLER_GET_ARG(1, function), jgpio,
+                                kGpioOpOpen);
+
+  GPIO_ASYNC(open);
+}
+
+
+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_WRITESYNC, WriteSync);
+  iotjs_jval_set_method(&jprototype, IOTJS_MAGIC_STRING_READ, Read);
+  iotjs_jval_set_method(&jprototype, IOTJS_MAGIC_STRING_READSYNC, ReadSync);
+  iotjs_jval_set_method(&jprototype, IOTJS_MAGIC_STRING_CLOSE, Close);
+  iotjs_jval_set_method(&jprototype, IOTJS_MAGIC_STRING_CLOSESYNC, CloseSync);
+  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);
+  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);
+  iotjs_jval_set_property_jval(&jgpio, IOTJS_MAGIC_STRING_MODE_U, &jmode);
+  iotjs_jval_destroy(&jmode);
+
+  return jgpio;
+}
diff --git a/src/module/iotjs_module_gpio.h b/src/module/iotjs_module_gpio.h
new file mode 100644 (file)
index 0000000..1bb0353
--- /dev/null
@@ -0,0 +1,99 @@
+/* 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"
+
+
+typedef enum {
+  kGpioDirectionIn = 0,
+  kGpioDirectionOut,
+} GpioDirection;
+
+
+typedef enum {
+  kGpioModeNone = 0,
+  kGpioModePullup,
+  kGpioModePulldown,
+  kGpioModeFloat,
+  kGpioModePushpull,
+  kGpioModeOpendrain,
+} GpioMode;
+
+
+typedef enum {
+  kGpioOpOpen,
+  kGpioOpWrite,
+  kGpioOpRead,
+  kGpioOpClose,
+} GpioOp;
+
+
+typedef struct {
+  bool value;
+  ssize_t 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;
+} 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);            \
+  IOTJS_VALIDATED_STRUCT_METHOD(iotjs_gpio_t, gpio);
+
+
+void iotjs_gpio_open_worker(uv_work_t* work_req);
+void iotjs_gpio_write_worker(uv_work_t* work_req);
+void iotjs_gpio_read_worker(uv_work_t* work_req);
+void iotjs_gpio_close_worker(uv_work_t* work_req);
+bool iotjs_gpio_write(int32_t pin, bool value);
+int iotjs_gpio_read(int32_t pin);
+bool iotjs_gpio_close(int32_t pin);
+
+#endif /* IOTJS_MODULE_GPIO_H */
diff --git a/src/module/iotjs_module_httpparser.c b/src/module/iotjs_module_httpparser.c
new file mode 100644 (file)
index 0000000..8e12b04
--- /dev/null
@@ -0,0 +1,511 @@
+/* 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+#define THIS iotjs_httpparserwrap_t* httpparserwrap
+
+
+static void iotjs_httpparserwrap_destroy(THIS);
+
+
+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,
+                               (JFreeHandlerType)iotjs_httpparserwrap_destroy);
+
+  _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, int 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 */
+};
+
+
+static iotjs_httpparserwrap_t* get_parser_wrap(const iotjs_jval_t* jparser) {
+  uintptr_t handle = iotjs_jval_get_object_native_handle(jparser);
+  return (iotjs_httpparserwrap_t*)(handle);
+}
+
+
+JHANDLER_FUNCTION(Reinitialize) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_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 = get_parser_wrap(jparser);
+  iotjs_httpparserwrap_initialize(parser, httpparser_type);
+}
+
+
+JHANDLER_FUNCTION(Finish) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(0);
+
+  const iotjs_jval_t* jparser = JHANDLER_GET_THIS(object);
+  iotjs_httpparserwrap_t* parser = get_parser_wrap(jparser);
+
+  http_parser* nativeparser = iotjs_httpparserwrap_parser(parser);
+  int 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_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(1, object);
+
+  const iotjs_jval_t* jparser = JHANDLER_GET_THIS(object);
+  iotjs_httpparserwrap_t* parser = get_parser_wrap(jparser);
+
+
+  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);
+  int 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);
+  int 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_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(0);
+  const iotjs_jval_t* jparser = JHANDLER_GET_THIS(object);
+  iotjs_httpparserwrap_t* parser = get_parser_wrap(jparser);
+  http_parser* nativeparser = iotjs_httpparserwrap_parser(parser);
+  http_parser_pause(nativeparser, 1);
+}
+
+
+JHANDLER_FUNCTION(Resume) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(0);
+  const iotjs_jval_t* jparser = JHANDLER_GET_THIS(object);
+  iotjs_httpparserwrap_t* parser = get_parser_wrap(jparser);
+  http_parser* nativeparser = iotjs_httpparserwrap_parser(parser);
+  http_parser_pause(nativeparser, 0);
+}
+
+
+JHANDLER_FUNCTION(HTTPParserCons) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_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_ASSERT(get_parser_wrap(jparser) == 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;
+}
diff --git a/src/module/iotjs_module_httpparser.h b/src/module/iotjs_module_httpparser.h
new file mode 100644 (file)
index 0000000..dd25b3f
--- /dev/null
@@ -0,0 +1,80 @@
+/* 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, int sz);
+
+iotjs_jval_t* iotjs_httpparserwrap_jobject(THIS);
+http_parser* iotjs_httpparserwrap_parser(THIS);
+
+
+#undef THIS
+
+
+#endif /* IOTJS_MODULE_HTTPPARSER_H */
diff --git a/src/module/iotjs_module_i2c.c b/src/module/iotjs_module_i2c.c
new file mode 100644 (file)
index 0000000..3a49a9a
--- /dev/null
@@ -0,0 +1,435 @@
+/* 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_i2c_reqwrap_t* iotjs_i2c_reqwrap_create(const iotjs_jval_t* jcallback,
+                                              const iotjs_jval_t* ji2c,
+                                              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 = iotjs_i2c_instance_from_jval(ji2c);
+  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
+
+
+static void iotjs_i2c_destroy(iotjs_i2c_t* i2c);
+
+
+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(__NUTTX__)
+  _this->i2c_master = NULL;
+#endif
+
+  iotjs_jobjectwrap_initialize(&_this->jobjectwrap, ji2c,
+                               (JFreeHandlerType)iotjs_i2c_destroy);
+  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:
+      case kI2cOpWriteByte:
+      case kI2cOpWriteBlock: {
+        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:
+      case kI2cOpReadBlock: {
+        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 if (req_data->error == kI2cErrReadBlock) {
+          iotjs_jval_t error =
+              iotjs_jval_create_error("Error reading length of bytes");
+          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;
+      }
+      case kI2cOpReadByte: {
+        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_jargs_append_number(&jargs, req_data->byte);
+        }
+        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 (int 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) {
+  JHANDLER_CHECK_THIS(object);
+#if defined(__linux__) || defined(__APPLE__)
+  JHANDLER_CHECK_ARGS(2, string, function);
+  iotjs_string_t device = JHANDLER_GET_ARG(0, string);
+#elif defined(__NUTTX__)
+  JHANDLER_CHECK_ARGS(2, number, function);
+  uint32_t 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, ji2c, 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_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(1, number);
+  iotjs_i2c_t* i2c = iotjs_i2c_instance_from_jval(JHANDLER_GET_THIS(object));
+
+  I2cSetAddress(i2c, JHANDLER_GET_ARG(0, number));
+
+  iotjs_jhandler_return_null(jhandler);
+}
+
+
+JHANDLER_FUNCTION(Close) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(0);
+
+  iotjs_i2c_t* i2c = iotjs_i2c_instance_from_jval(JHANDLER_GET_THIS(object));
+  I2cClose(i2c);
+
+  iotjs_jhandler_return_null(jhandler);
+}
+
+
+JHANDLER_FUNCTION(Write) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(2, array, function);
+
+  const iotjs_jval_t* jcallback = JHANDLER_GET_ARG(1, function);
+  const iotjs_jval_t* ji2c = JHANDLER_GET_THIS(object);
+
+  iotjs_i2c_reqwrap_t* req_wrap =
+      iotjs_i2c_reqwrap_create(jcallback, ji2c, 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(WriteByte) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(2, number, function);
+
+  uint8_t byte = JHANDLER_GET_ARG(0, number);
+  const iotjs_jval_t* jcallback = JHANDLER_GET_ARG(1, function);
+  const iotjs_jval_t* ji2c = JHANDLER_GET_THIS(object);
+
+  iotjs_i2c_reqwrap_t* req_wrap =
+      iotjs_i2c_reqwrap_create(jcallback, ji2c, kI2cOpWriteByte);
+
+  iotjs_i2c_reqdata_t* req_data = iotjs_i2c_reqwrap_data(req_wrap);
+  req_data->byte = byte;
+
+  I2C_ASYNC(WriteByte);
+
+  iotjs_jhandler_return_null(jhandler);
+}
+
+
+JHANDLER_FUNCTION(WriteBlock) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(3, number, array, function);
+
+  const iotjs_jval_t* jcallback = JHANDLER_GET_ARG(2, function);
+  const iotjs_jval_t* ji2c = JHANDLER_GET_THIS(object);
+
+  iotjs_i2c_reqwrap_t* req_wrap =
+      iotjs_i2c_reqwrap_create(jcallback, ji2c, kI2cOpWriteBlock);
+
+  iotjs_i2c_reqdata_t* req_data = iotjs_i2c_reqwrap_data(req_wrap);
+  req_data->cmd = JHANDLER_GET_ARG(0, number);
+  GetI2cArray(JHANDLER_GET_ARG(1, array), req_data);
+
+  I2C_ASYNC(WriteBlock);
+
+  iotjs_jhandler_return_null(jhandler);
+}
+
+
+JHANDLER_FUNCTION(Read) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(2, number, function);
+
+  const iotjs_jval_t* jcallback = JHANDLER_GET_ARG(1, function);
+  const iotjs_jval_t* ji2c = JHANDLER_GET_THIS(object);
+
+  iotjs_i2c_reqwrap_t* req_wrap =
+      iotjs_i2c_reqwrap_create(jcallback, ji2c, 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);
+}
+
+
+JHANDLER_FUNCTION(ReadByte) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(1, function);
+
+  const iotjs_jval_t* jcallback = JHANDLER_GET_ARG(0, function);
+  const iotjs_jval_t* ji2c = JHANDLER_GET_THIS(object);
+
+  iotjs_i2c_reqwrap_t* req_wrap =
+      iotjs_i2c_reqwrap_create(jcallback, ji2c, kI2cOpReadByte);
+
+  I2C_ASYNC(ReadByte);
+
+  iotjs_jhandler_return_null(jhandler);
+}
+
+
+JHANDLER_FUNCTION(ReadBlock) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(4, number, number, number, function);
+
+  const iotjs_jval_t* jcallback = JHANDLER_GET_ARG(3, function);
+  const iotjs_jval_t* ji2c = JHANDLER_GET_THIS(object);
+
+  iotjs_i2c_reqwrap_t* req_wrap =
+      iotjs_i2c_reqwrap_create(jcallback, ji2c, kI2cOpReadBlock);
+
+  iotjs_i2c_reqdata_t* req_data = iotjs_i2c_reqwrap_data(req_wrap);
+  req_data->cmd = JHANDLER_GET_ARG(0, number);
+  req_data->buf_len = JHANDLER_GET_ARG(1, number);
+  req_data->delay = JHANDLER_GET_ARG(2, number);
+
+  I2C_ASYNC(ReadBlock);
+
+  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_WRITEBYTE, WriteByte);
+  iotjs_jval_set_method(&prototype, IOTJS_MAGIC_STRING_WRITEBLOCK, WriteBlock);
+  iotjs_jval_set_method(&prototype, IOTJS_MAGIC_STRING_READ, Read);
+  iotjs_jval_set_method(&prototype, IOTJS_MAGIC_STRING_READBYTE, ReadByte);
+  iotjs_jval_set_method(&prototype, IOTJS_MAGIC_STRING_READBLOCK, ReadBlock);
+
+  iotjs_jval_set_property_jval(&jI2cCons, IOTJS_MAGIC_STRING_PROTOTYPE,
+                               &prototype);
+
+  iotjs_jval_destroy(&prototype);
+
+  return jI2cCons;
+}
diff --git a/src/module/iotjs_module_i2c.h b/src/module/iotjs_module_i2c.h
new file mode 100644 (file)
index 0000000..75e48f9
--- /dev/null
@@ -0,0 +1,111 @@
+/* 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 <nuttx/i2c/i2c_master.h>
+#endif
+
+typedef enum {
+  kI2cOpSetAddress,
+  kI2cOpOpen,
+  kI2cOpClose,
+  kI2cOpWrite,
+  kI2cOpWriteByte,
+  kI2cOpWriteBlock,
+  kI2cOpRead,
+  kI2cOpReadByte,
+  kI2cOpReadBlock,
+} I2cOp;
+
+typedef enum {
+  kI2cErrOk = 0,
+  kI2cErrOpen = -1,
+  kI2cErrRead = -2,
+  kI2cErrReadBlock = -3,
+  kI2cErrWrite = -4,
+} I2cError;
+
+
+typedef struct {
+#if defined(__linux__) || defined(__APPLE__)
+  iotjs_string_t device;
+#elif defined(__NUTTX__)
+  uint32_t 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 {
+#if defined(__NUTTX__)
+  struct i2c_master_s* i2c_master;
+  struct i2c_config_s config;
+#endif
+  iotjs_jobjectwrap_t jobjectwrap;
+} 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,
+                                              const iotjs_jval_t* ji2c,
+                                              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 WriteByteWorker(uv_work_t* work_req);
+void WriteBlockWorker(uv_work_t* work_req);
+void ReadWorker(uv_work_t* work_req);
+void ReadByteWorker(uv_work_t* work_req);
+void ReadBlockWorker(uv_work_t* work_req);
+
+
+#endif /* IOTJS_MODULE_I2C_H */
diff --git a/src/module/iotjs_module_process.c b/src/module/iotjs_module_process.c
new file mode 100644 (file)
index 0000000..6f30679
--- /dev/null
@@ -0,0 +1,293 @@
+/* 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 <stdlib.h>
+
+
+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* source, size_t length, bool* throws) {
+  static const char* wrapper[2] = { "(function(exports, require, module) {\n",
+                                    "\n});\n" };
+
+  int len0 = strlen(wrapper[0]);
+  int len1 = strlen(wrapper[1]);
+
+  uint32_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(buffer, buffer_length, false, throws);
+
+  iotjs_buffer_release(buffer);
+
+  return res;
+}
+
+
+JHANDLER_FUNCTION(Compile) {
+  JHANDLER_CHECK_ARGS(1, string);
+
+  iotjs_string_t source = JHANDLER_GET_ARG(0, string);
+
+  bool throws;
+  iotjs_jval_t jres =
+      WrapEval(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(&source);
+  iotjs_jval_destroy(&jres);
+}
+
+
+JHANDLER_FUNCTION(CompileNativePtr) {
+  JHANDLER_CHECK_ARGS(1, string);
+
+  iotjs_string_t id = JHANDLER_GET_ARG(0, string);
+
+  int i = 0;
+  while (natives[i].name != NULL) {
+    if (!strcmp(natives[i].name, iotjs_string_data(&id))) {
+      break;
+    }
+
+    i++;
+  }
+
+  iotjs_string_destroy(&id);
+
+  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((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);
+  }
+}
+
+
+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);
+
+  int exit_code = JHANDLER_GET_ARG(0, number);
+
+  exit(exit_code);
+}
+
+
+// Initialize `process.argv`
+JHANDLER_FUNCTION(InitArgv) {
+  JHANDLER_CHECK_THIS(object);
+
+  // environment
+  const iotjs_environment_t* env = iotjs_environment_get();
+
+  // process.argv
+  const iotjs_jval_t* thisObj = JHANDLER_GET_THIS(object);
+  iotjs_jval_t jargv =
+      iotjs_jval_get_property(thisObj, IOTJS_MAGIC_STRING_ARGV);
+
+  int argc = iotjs_environment_argc(env);
+
+  for (int 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(&jargv, i, &arg);
+    iotjs_jval_destroy(&arg);
+  }
+  iotjs_jval_destroy(&jargv);
+}
+
+
+void SetNativeSources(iotjs_jval_t* native_sources) {
+  for (int i = 0; natives[i].name; i++) {
+    iotjs_jval_t native_src = iotjs_jval_create_object();
+    uintptr_t handle = (uintptr_t)(&natives[i]);
+    iotjs_jval_set_object_native_handle(&native_src, handle, NULL);
+    iotjs_jval_set_property_jval(native_sources, natives[i].name, &native_src);
+    iotjs_jval_destroy(&native_src);
+  }
+}
+
+
+static void SetProcessEnv(iotjs_jval_t* process) {
+  const char *homedir, *nodepath, *iotjsenv;
+
+  homedir = getenv("HOME");
+  if (homedir == NULL) {
+    homedir = "";
+  }
+
+  nodepath = getenv("NODE_PATH");
+  if (nodepath == NULL) {
+#if defined(__NUTTX__) || defined(__TIZENRT__)
+    nodepath = "/mnt/sdcard";
+#else
+    nodepath = "";
+#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_NODE_PATH,
+                                     nodepath);
+  iotjs_jval_set_property_string_raw(&env, IOTJS_MAGIC_STRING_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);
+}
+
+
+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);
+  iotjs_jval_set_method(&process, IOTJS_MAGIC_STRING__INITARGV, InitArgv);
+  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);
+
+  // 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;
+}
diff --git a/src/module/iotjs_module_pwm.c b/src/module/iotjs_module_pwm.c
new file mode 100644 (file)
index 0000000..67ece49
--- /dev/null
@@ -0,0 +1,378 @@
+/* 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 void iotjs_pwm_destroy(iotjs_pwm_t* pwm);
+static iotjs_pwm_t* iotjs_pwm_instance_from_jval(const iotjs_jval_t* jpwm);
+
+
+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,
+                               (JFreeHandlerType)iotjs_pwm_destroy);
+
+  _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, const iotjs_jval_t* jpwm, 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 = iotjs_pwm_instance_from_jval(jpwm);
+  _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, jthis, jcallback, op)                          \
+  do {                                                                 \
+    uv_loop_t* loop = iotjs_environment_loop(iotjs_environment_get()); \
+    iotjs_pwm_reqwrap_t* req_wrap =                                    \
+        iotjs_pwm_reqwrap_create(jcallback, jthis, 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, jthis, jcallback, op)                    \
+  do {                                                                         \
+    uv_loop_t* loop = iotjs_environment_loop(iotjs_environment_get());         \
+    iotjs_pwm_reqwrap_t* req_wrap =                                            \
+        iotjs_pwm_reqwrap_create(jcallback, jthis, 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) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_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, jpwm, jcallback, kPwmOpOpen);
+}
+
+
+JHANDLER_FUNCTION(SetPeriod) {
+  JHANDLER_CHECK_ARGS(1, number);
+  JHANDLER_CHECK_ARG_IF_EXIST(1, function);
+
+  const iotjs_jval_t* jcallback = JHANDLER_GET_ARG_IF_EXIST(1, function);
+  const iotjs_jval_t* jpwm = JHANDLER_GET_THIS(object);
+  iotjs_pwm_t* pwm = iotjs_pwm_instance_from_jval(jpwm);
+
+  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, jpwm, jcallback,
+                            kPwmOpSetPeriod);
+  } else {
+    if (!iotjs_pwm_set_period(pwm)) {
+      JHANDLER_THROW(COMMON, "PWM SetPeriod Error");
+    }
+  }
+
+  iotjs_jhandler_return_null(jhandler);
+}
+
+
+JHANDLER_FUNCTION(SetDutyCycle) {
+  JHANDLER_CHECK_ARGS(1, number);
+  JHANDLER_CHECK_ARG_IF_EXIST(1, function);
+
+  const iotjs_jval_t* jcallback = JHANDLER_GET_ARG_IF_EXIST(1, function);
+  const iotjs_jval_t* jpwm = JHANDLER_GET_THIS(object);
+  iotjs_pwm_t* pwm = iotjs_pwm_instance_from_jval(jpwm);
+
+  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, jpwm, jcallback,
+                            kPwmOpSetDutyCycle);
+  } else {
+    if (!iotjs_pwm_set_dutycycle(pwm)) {
+      JHANDLER_THROW(COMMON, "PWM SetDutyCycle Error");
+    }
+  }
+
+  iotjs_jhandler_return_null(jhandler);
+}
+
+
+JHANDLER_FUNCTION(SetEnable) {
+  JHANDLER_CHECK_ARGS(1, boolean);
+  JHANDLER_CHECK_ARG_IF_EXIST(1, function);
+
+  const iotjs_jval_t* jcallback = JHANDLER_GET_ARG_IF_EXIST(1, function);
+  const iotjs_jval_t* jpwm = JHANDLER_GET_THIS(object);
+  iotjs_pwm_t* pwm = iotjs_pwm_instance_from_jval(jpwm);
+
+  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, jpwm, jcallback,
+                            kPwmOpSetEnable);
+  } else {
+    if (!iotjs_pwm_set_enable(pwm)) {
+      JHANDLER_THROW(COMMON, "PWM SetEnabe Error");
+    }
+  }
+
+  iotjs_jhandler_return_null(jhandler);
+}
+
+
+JHANDLER_FUNCTION(Close) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_CHECK_ARG_IF_EXIST(0, function);
+
+  const iotjs_jval_t* jcallback = JHANDLER_GET_ARG_IF_EXIST(0, function);
+  const iotjs_jval_t* jpwm = JHANDLER_GET_THIS(object);
+  iotjs_pwm_t* pwm = iotjs_pwm_instance_from_jval(jpwm);
+
+  if (jcallback) {
+    PWM_ASYNC_COMMON_WORKER(iotjs_pwm_close, jpwm, 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;
+}
diff --git a/src/module/iotjs_module_pwm.h b/src/module/iotjs_module_pwm.h
new file mode 100644 (file)
index 0000000..0f9a9bf
--- /dev/null
@@ -0,0 +1,93 @@
+/* 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"
+
+
+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;
+#endif
+  int 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 */
diff --git a/src/module/iotjs_module_spi.c b/src/module/iotjs_module_spi.c
new file mode 100644 (file)
index 0000000..ef829d4
--- /dev/null
@@ -0,0 +1,465 @@
+/* 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 <unistd.h>
+
+
+/*
+ * SPI instance function
+ */
+static void iotjs_spi_destroy(iotjs_spi_t* spi);
+static iotjs_spi_t* iotjs_spi_instance_from_jval(const iotjs_jval_t* jspi);
+
+
+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,
+                               (JFreeHandlerType)iotjs_spi_destroy);
+
+  _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, const iotjs_jval_t* jspi, 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 = iotjs_spi_instance_from_jval(jspi);
+
+  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);
+}
+
+
+static iotjs_spi_t* iotjs_spi_instance_from_jval(const iotjs_jval_t* jspi) {
+  uintptr_t handle = iotjs_jval_get_object_native_handle(jspi);
+  return (iotjs_spi_t*)handle;
+}
+
+
+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));
+
+  int length = iotjs_jval_as_number(&jlength);
+  *buf = iotjs_buffer_allocate(length);
+
+  for (int 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 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, jthis, jcallback, op)                                  \
+  do {                                                                         \
+    uv_loop_t* loop = iotjs_environment_loop(iotjs_environment_get());         \
+    iotjs_spi_reqwrap_t* req_wrap =                                            \
+        iotjs_spi_reqwrap_create(jcallback, jthis, 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) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_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, jspi, jcallback, kSpiOpOpen);
+}
+
+
+// FIXME: do not need transferArray if array buffer is implemented.
+JHANDLER_FUNCTION(TransferArray) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(2, array, array);
+  JHANDLER_CHECK_ARG_IF_EXIST(2, function);
+
+  const iotjs_jval_t* jcallback = JHANDLER_GET_ARG_IF_EXIST(2, function);
+  const iotjs_jval_t* jspi = JHANDLER_GET_THIS(object);
+  iotjs_spi_t* spi = iotjs_spi_get_instance(jspi);
+
+  iotjs_spi_set_array_buffer(spi, JHANDLER_GET_ARG(0, array),
+                             JHANDLER_GET_ARG(1, array));
+
+  if (jcallback) {
+    SPI_ASYNC(transfer, jspi, 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_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(2, object, object);
+  JHANDLER_CHECK_ARG_IF_EXIST(2, function);
+
+  const iotjs_jval_t* jcallback = JHANDLER_GET_ARG_IF_EXIST(2, function);
+  const iotjs_jval_t* jspi = JHANDLER_GET_THIS(object);
+  iotjs_spi_t* spi = iotjs_spi_get_instance(jspi);
+
+  iotjs_spi_set_buffer(spi, JHANDLER_GET_ARG(0, object),
+                       JHANDLER_GET_ARG(1, object));
+
+  if (jcallback) {
+    SPI_ASYNC(transfer, jspi, 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_CHECK_THIS(object);
+  JHANDLER_CHECK_ARG_IF_EXIST(0, function);
+
+  const iotjs_jval_t* jcallback = JHANDLER_GET_ARG_IF_EXIST(0, function);
+  const iotjs_jval_t* jspi = JHANDLER_GET_THIS(object);
+  iotjs_spi_t* spi = iotjs_spi_get_instance(jspi);
+
+  if (jcallback) {
+    SPI_ASYNC(close, jspi, 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;
+}
diff --git a/src/module/iotjs_module_spi.h b/src/module/iotjs_module_spi.h
new file mode 100644 (file)
index 0000000..b4349f3
--- /dev/null
@@ -0,0 +1,104 @@
+/* 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 */
diff --git a/src/module/iotjs_module_stm32f4dis.c b/src/module/iotjs_module_stm32f4dis.c
new file mode 100644 (file)
index 0000000..672a504
--- /dev/null
@@ -0,0 +1,30 @@
+/* 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;
+}
diff --git a/src/module/iotjs_module_stm32f4dis.h b/src/module/iotjs_module_stm32f4dis.h
new file mode 100644 (file)
index 0000000..f14d608
--- /dev/null
@@ -0,0 +1,23 @@
+/* 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 */
diff --git a/src/module/iotjs_module_tcp.c b/src/module/iotjs_module_tcp.c
new file mode 100644 (file)
index 0000000..02b37dc
--- /dev/null
@@ -0,0 +1,674 @@
+/* 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"
+
+
+static void iotjs_tcpwrap_destroy(iotjs_tcpwrap_t* 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),
+                              (JFreeHandlerType)iotjs_tcpwrap_destroy);
+
+  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) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_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_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(0);
+
+  const iotjs_jval_t* jtcp = JHANDLER_GET_THIS(object);
+  iotjs_handlewrap_t* wrap = iotjs_handlewrap_from_jobject(jtcp);
+
+  // 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_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(2, string, number);
+
+  const iotjs_jval_t* jtcp = JHANDLER_GET_THIS(object);
+  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) {
+    iotjs_tcpwrap_t* tcp_wrap = iotjs_tcpwrap_from_jobject(jtcp);
+    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_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(3, string, number, function);
+
+  const iotjs_jval_t* jtcp = JHANDLER_GET_THIS(object);
+  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) {
+    // Get tcp wrapper from javascript socket object.
+    iotjs_tcpwrap_t* tcp_wrap = iotjs_tcpwrap_from_jobject(jtcp);
+
+    // 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_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(1, number);
+
+  const iotjs_jval_t* jtcp = JHANDLER_GET_THIS(object);
+  iotjs_tcpwrap_t* tcp_wrap = iotjs_tcpwrap_from_jobject(jtcp);
+
+  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_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(2, object, function);
+
+  const iotjs_jval_t* jtcp = JHANDLER_GET_THIS(object);
+  iotjs_tcpwrap_t* tcp_wrap = iotjs_tcpwrap_from_jobject(jtcp);
+
+  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);
+  int 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(nread);
+    iotjs_bufferwrap_t* buffer_wrap = iotjs_bufferwrap_from_jbuffer(&jbuffer);
+
+    iotjs_bufferwrap_copy(buffer_wrap, buf->base, 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_CHECK_THIS(object);
+
+  const iotjs_jval_t* jtcp = JHANDLER_GET_THIS(object);
+  iotjs_tcpwrap_t* tcp_wrap = iotjs_tcpwrap_from_jobject(jtcp);
+
+  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_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(1, function);
+
+  const iotjs_jval_t* jtcp = JHANDLER_GET_THIS(object);
+  iotjs_tcpwrap_t* tcp_wrap = iotjs_tcpwrap_from_jobject(jtcp);
+
+  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_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(2, number, number);
+
+  const iotjs_jval_t* jtcp = JHANDLER_GET_THIS(object);
+  int enable = JHANDLER_GET_ARG(0, number);
+  unsigned delay = JHANDLER_GET_ARG(1, number);
+
+  iotjs_tcpwrap_t* tcp_wrap = iotjs_tcpwrap_from_jobject(jtcp);
+  int err = uv_tcp_keepalive(iotjs_tcpwrap_tcp_handle(tcp_wrap), enable, delay);
+
+  iotjs_jhandler_return_number(jhandler, err);
+}
+
+
+// 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_set_property_jval(&tcp, IOTJS_MAGIC_STRING_PROTOTYPE, &prototype);
+
+  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);
+
+  return tcp;
+}
diff --git a/src/module/iotjs_module_tcp.h b/src/module/iotjs_module_tcp.h
new file mode 100644 (file)
index 0000000..5fbe909
--- /dev/null
@@ -0,0 +1,110 @@
+/* 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) {                      \
+    JHANDLER_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 */
diff --git a/src/module/iotjs_module_testdriver.c b/src/module/iotjs_module_testdriver.c
new file mode 100644 (file)
index 0000000..1c6d087
--- /dev/null
@@ -0,0 +1,71 @@
+/* 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) {
+      int active_handlers = loop->active_handles;
+      if (active_handlers == 1) {
+        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;
+}
diff --git a/src/module/iotjs_module_timer.c b/src/module/iotjs_module_timer.c
new file mode 100644 (file)
index 0000000..5dda485
--- /dev/null
@@ -0,0 +1,178 @@
+/* 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_timerwrap_t* iotjs_timerwrap_create(const iotjs_jval_t* jtimer) {
+  iotjs_timerwrap_t* timerwrap = IOTJS_ALLOC(iotjs_timerwrap_t);
+  IOTJS_VALIDATED_STRUCT_CONSTRUCTOR(iotjs_timerwrap_t, timerwrap);
+
+  iotjs_handlewrap_initialize(&_this->handlewrap, jtimer,
+                              (uv_handle_t*)(&_this->handle),
+                              (JFreeHandlerType)iotjs_timerwrap_destroy);
+
+  // Initialize timer handler.
+  const iotjs_environment_t* env = iotjs_environment_get();
+  uv_timer_init(iotjs_environment_loop(env), &_this->handle);
+
+  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);
+}
+
+
+// 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, int64_t timeout,
+                          int64_t repeat) {
+  IOTJS_VALIDATED_STRUCT_METHOD(iotjs_timerwrap_t, timerwrap);
+
+  // Start uv timer.
+  return uv_timer_start(&_this->handle, 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, NULL);
+  }
+
+  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 &_this->handle;
+}
+
+
+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_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(2, number, number);
+
+  const iotjs_jval_t* jtimer = JHANDLER_GET_THIS(object);
+
+  // Take timer wrap.
+  iotjs_timerwrap_t* timer_wrap = iotjs_timerwrap_from_jobject(jtimer);
+
+  // parameters.
+  int64_t timeout = JHANDLER_GET_ARG(0, number);
+  int64_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_CHECK_THIS(object);
+
+  const iotjs_jval_t* jtimer = JHANDLER_GET_THIS(object);
+
+  iotjs_timerwrap_t* timer_wrap = iotjs_timerwrap_from_jobject(jtimer);
+
+  // 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;
+}
diff --git a/src/module/iotjs_module_timer.h b/src/module/iotjs_module_timer.h
new file mode 100644 (file)
index 0000000..f419592
--- /dev/null
@@ -0,0 +1,45 @@
+/* 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;
+  uv_timer_t handle;
+} 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, int64_t timeout,
+                          int64_t repeat);
+// Stop & close timer.
+int iotjs_timerwrap_stop(iotjs_timerwrap_t* timerwrap);
+
+
+#endif /* IOTJS_MODULE_TIMER_H */
diff --git a/src/module/iotjs_module_uart.c b/src/module/iotjs_module_uart.c
new file mode 100644 (file)
index 0000000..c082374
--- /dev/null
@@ -0,0 +1,360 @@
+/* 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 <unistd.h>
+
+#include "iotjs_def.h"
+#include "iotjs_module_uart.h"
+#include "iotjs_objectwrap.h"
+
+
+static void iotjs_uart_destroy(iotjs_uart_t* uart);
+static iotjs_uart_t* iotjs_uart_instance_from_jval(const iotjs_jval_t* juart);
+
+
+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,
+                               (JFreeHandlerType)iotjs_uart_destroy);
+
+  _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, const iotjs_jval_t* juart, 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 = iotjs_uart_instance_from_jval(juart);
+
+  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, jthis, jcallback, op)                         \
+  do {                                                                 \
+    uv_loop_t* loop = iotjs_environment_loop(iotjs_environment_get()); \
+    iotjs_uart_reqwrap_t* req_wrap =                                   \
+        iotjs_uart_reqwrap_create(jcallback, jthis, 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) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_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, juart, jcallback, kUartOpOpen);
+}
+
+
+JHANDLER_FUNCTION(Write) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(1, string);
+  JHANDLER_CHECK_ARG_IF_EXIST(1, function);
+
+  const iotjs_jval_t* jcallback = JHANDLER_GET_ARG_IF_EXIST(1, function);
+  const iotjs_jval_t* juart = JHANDLER_GET_THIS(object);
+  iotjs_uart_t* uart = iotjs_uart_instance_from_jval(juart);
+
+  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, juart, 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_CHECK_THIS(object);
+  JHANDLER_CHECK_ARG_IF_EXIST(0, function);
+
+  const iotjs_jval_t* jcallback = JHANDLER_GET_ARG_IF_EXIST(0, function);
+  const iotjs_jval_t* juart = JHANDLER_GET_THIS(object);
+  iotjs_uart_t* uart = iotjs_uart_instance_from_jval(juart);
+
+  IOTJS_VALIDATED_STRUCT_METHOD(iotjs_uart_t, uart);
+  iotjs_jval_destroy(&_this->jemitter_this);
+
+  if (jcallback) {
+    UART_ASYNC(close, juart, 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;
+}
diff --git a/src/module/iotjs_module_uart.h b/src/module/iotjs_module_uart.h
new file mode 100644 (file)
index 0000000..3b1c72f
--- /dev/null
@@ -0,0 +1,82 @@
+/* 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 */
diff --git a/src/module/iotjs_module_udp.c b/src/module/iotjs_module_udp.c
new file mode 100644 (file)
index 0000000..119c79e
--- /dev/null
@@ -0,0 +1,509 @@
+/* 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"
+
+
+static void iotjs_udpwrap_destroy(iotjs_udpwrap_t* 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),
+                              (JFreeHandlerType)iotjs_udpwrap_destroy);
+
+  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) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_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_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS_2(string, number);
+
+  const iotjs_jval_t* judp = JHANDLER_GET_THIS(object);
+  iotjs_udpwrap_t* udp_wrap = iotjs_udpwrap_from_jobject(judp);
+
+  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));
+
+  int flags = false;
+  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(nread);
+  iotjs_bufferwrap_t* buffer_wrap = iotjs_bufferwrap_from_jbuffer(&jbuffer);
+
+  iotjs_bufferwrap_copy(buffer_wrap, buf->base, 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_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(0);
+
+  const iotjs_jval_t* judp = JHANDLER_GET_THIS(object);
+  iotjs_udpwrap_t* udp_wrap = iotjs_udpwrap_from_jobject(judp);
+
+  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_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(0);
+
+  const iotjs_jval_t* judp = JHANDLER_GET_THIS(object);
+  iotjs_udpwrap_t* udp_wrap = iotjs_udpwrap_from_jobject(judp);
+
+  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_CHECK_THIS(object);
+  JHANDLER_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* judp = JHANDLER_GET_THIS(object);
+  iotjs_udpwrap_t* udp_wrap = iotjs_udpwrap_from_jobject(judp);
+
+  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);
+  int 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_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(0);
+
+  const iotjs_jval_t* judp = JHANDLER_GET_THIS(object);
+  iotjs_handlewrap_t* wrap = iotjs_handlewrap_from_jobject(judp);
+
+  iotjs_handlewrap_close(wrap, NULL);
+}
+
+
+GetSockNameFunction(udpwrap, udp_handle, uv_udp_getsockname);
+
+
+JHANDLER_FUNCTION(GetSockeName) {
+  DoGetSockName(jhandler);
+}
+
+
+#define IOTJS_UV_SET_SOCKOPT(fn)                                \
+  JHANDLER_CHECK_THIS(object);                                  \
+  JHANDLER_CHECK_ARGS_1(number);                                \
+                                                                \
+  const iotjs_jval_t* judp = JHANDLER_GET_THIS(object);         \
+  iotjs_udpwrap_t* udp_wrap = iotjs_udpwrap_from_jobject(judp); \
+                                                                \
+  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_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS_1(string);
+
+  const iotjs_jval_t* judp = JHANDLER_GET_THIS(object);
+  iotjs_udpwrap_t* udp_wrap = iotjs_udpwrap_from_jobject(judp);
+
+  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;
+}
diff --git a/src/module/iotjs_module_udp.h b/src/module/iotjs_module_udp.h
new file mode 100644 (file)
index 0000000..2d9e669
--- /dev/null
@@ -0,0 +1,60 @@
+/* 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 */
diff --git a/src/platform/arm-linux/iotjs_module_adc-arm-linux.c b/src/platform/arm-linux/iotjs_module_adc-arm-linux.c
new file mode 100644 (file)
index 0000000..ad31407
--- /dev/null
@@ -0,0 +1,21 @@
+/* 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(__linux__)
+
+#include "../iotjs_module_adc-linux-general.inl.h"
+
+#endif
diff --git a/src/platform/arm-linux/iotjs_module_blehcisocket-arm-linux.c b/src/platform/arm-linux/iotjs_module_blehcisocket-arm-linux.c
new file mode 100644 (file)
index 0000000..eddc16e
--- /dev/null
@@ -0,0 +1,22 @@
+/* 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(__linux__)
+
+#include "iotjs_def.h"
+#include "../iotjs_module_blehcisocket-linux-general.inl.h"
+
+#endif
diff --git a/src/platform/arm-linux/iotjs_module_gpio-arm-linux.c b/src/platform/arm-linux/iotjs_module_gpio-arm-linux.c
new file mode 100644 (file)
index 0000000..8c68b40
--- /dev/null
@@ -0,0 +1,22 @@
+/* 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.
+ */
+
+
+#if defined(__linux__)
+
+#include "iotjs_def.h"
+#include "../iotjs_module_gpio-linux-general.inl.h"
+
+#endif
diff --git a/src/platform/arm-linux/iotjs_module_i2c-arm-linux.c b/src/platform/arm-linux/iotjs_module_i2c-arm-linux.c
new file mode 100644 (file)
index 0000000..0ad37b1
--- /dev/null
@@ -0,0 +1,21 @@
+/* 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(__linux__)
+
+#include "../iotjs_module_i2c-linux-general.inl.h"
+
+#endif
diff --git a/src/platform/arm-linux/iotjs_module_pwm-arm-linux.c b/src/platform/arm-linux/iotjs_module_pwm-arm-linux.c
new file mode 100644 (file)
index 0000000..94e9800
--- /dev/null
@@ -0,0 +1,22 @@
+/* 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(__linux__)
+
+#include "iotjs_def.h"
+#include "../iotjs_module_pwm-linux-general.inl.h"
+
+#endif
diff --git a/src/platform/arm-linux/iotjs_module_spi-arm-linux.c b/src/platform/arm-linux/iotjs_module_spi-arm-linux.c
new file mode 100644 (file)
index 0000000..257ac80
--- /dev/null
@@ -0,0 +1,22 @@
+/* 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(__linux__)
+
+#include "iotjs_def.h"
+#include "../iotjs_module_spi-linux-general.inl.h"
+
+#endif
diff --git a/src/platform/arm-linux/iotjs_module_uart-arm-linux.c b/src/platform/arm-linux/iotjs_module_uart-arm-linux.c
new file mode 100644 (file)
index 0000000..ec6ece5
--- /dev/null
@@ -0,0 +1,21 @@
+/* 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(__linux__)
+
+#include "../iotjs_module_uart-linux-general.inl.h"
+
+#endif // __linux__
diff --git a/src/platform/arm-nuttx/iotjs_module_adc-arm-nuttx.c b/src/platform/arm-nuttx/iotjs_module_adc-arm-nuttx.c
new file mode 100644 (file)
index 0000000..f69e1ca
--- /dev/null
@@ -0,0 +1,134 @@
+/* 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 <uv.h>
+#include <nuttx/analog/adc.h>
+#include <stdlib.h>
+
+#include "iotjs_def.h"
+#include "iotjs_systemio-arm-nuttx.h"
+#include "module/iotjs_module_adc.h"
+#include "module/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(int32_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);
+
+  int32_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);
+
+  int32_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__
diff --git a/src/platform/arm-nuttx/iotjs_module_blehcisocket-arm-nuttx.c b/src/platform/arm-nuttx/iotjs_module_blehcisocket-arm-nuttx.c
new file mode 100644 (file)
index 0000000..a34ef57
--- /dev/null
@@ -0,0 +1,103 @@
+/* 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 "module/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, int 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, int 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;
+}
+
+
+void iotjs_blehcisocket_kernelDisconnectWorkArounds(THIS, int length,
+                                                    char* data) {
+  IOTJS_ASSERT(!"Not implemented");
+}
+
+
+#undef THIS
+
+#endif /* IOTJS_MODULE_BLE_HCI_SOCKET_LINUX_GENERAL_INL_H */
diff --git a/src/platform/arm-nuttx/iotjs_module_gpio-arm-nuttx-general.inl.h b/src/platform/arm-nuttx/iotjs_module_gpio-arm-nuttx-general.inl.h
new file mode 100644 (file)
index 0000000..34d7c18
--- /dev/null
@@ -0,0 +1,48 @@
+/* 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_GPIO_ARM_NUTTX_GENERAL_INL_H
+#define IOTJS_MODULE_GPIO_ARM_NUTTX_GENERAL_INL_H
+
+#include "module/iotjs_module_gpio.h"
+
+
+void iotjs_gpio_open_worker(uv_work_t* work_req) {
+  IOTJS_ASSERT(!"Not implemented");
+}
+
+void iotjs_gpio_write_worker(uv_work_t* work_req) {
+  IOTJS_ASSERT(!"Not implemented");
+}
+
+void iotjs_gpio_read_worker(uv_work_t* work_req) {
+  IOTJS_ASSERT(!"Not implemented");
+}
+
+void iotjs_gpio_close_worker(uv_work_t* work_req) {
+  IOTJS_ASSERT(!"Not implemented");
+}
+
+bool iotjs_gpio_write(uv_work_t* work_req) {
+  IOTJS_ASSERT(!"Not implemented");
+  return false;
+}
+
+int iotjs_gpio_read(uv_work_t* work_req) {
+  IOTJS_ASSERT(!"Not implemented");
+  return -1;
+}
+
+#endif /* IOTJS_MODULE_GPIO_ARM_NUTTX_GENERAL_INL_H */
diff --git a/src/platform/arm-nuttx/iotjs_module_gpio-arm-nuttx-stm32.inl.h b/src/platform/arm-nuttx/iotjs_module_gpio-arm-nuttx-stm32.inl.h
new file mode 100644 (file)
index 0000000..aa88515
--- /dev/null
@@ -0,0 +1,108 @@
+/* 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_GPIO_ARM_NUTTX_STM32_INL_H
+#define IOTJS_MODULE_GPIO_ARM_NUTTX_STM32_INL_H
+
+#include "module/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(int32_t pin, bool value) {
+  DDDLOG("%s - pin: %d, value: %d", __func__, pin, value);
+  stm32_gpiowrite(pin, value);
+
+  return true;
+}
+
+
+int iotjs_gpio_read(int32_t pin) {
+  DDDLOG("%s - pin: %d", __func__, pin);
+  return stm32_gpioread(pin);
+}
+
+
+bool iotjs_gpio_close(int32_t pin) {
+  DDDLOG("%s - pin: %d", __func__, pin);
+  iotjs_gpio_write(pin, 0);
+
+  return true;
+}
+
+
+void iotjs_gpio_open_worker(uv_work_t* work_req) {
+  GPIO_WORKER_INIT();
+  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 = -1;
+    return;
+  }
+
+  req_data->result = 0;
+}
+
+
+void iotjs_gpio_write_worker(uv_work_t* work_req) {
+  GPIO_WORKER_INIT();
+  DDDLOG("%s - pin: %d, value: %d", __func__, _this->pin, req_data->value);
+
+  iotjs_gpio_write(_this->pin, req_data->value);
+
+  req_data->result = 0;
+}
+
+
+void iotjs_gpio_read_worker(uv_work_t* work_req) {
+  GPIO_WORKER_INIT();
+  DDDLOG("%s - pin: %d", __func__, _this->pin);
+
+  req_data->result = 0;
+  req_data->value = iotjs_gpio_read(_this->pin);
+}
+
+
+void iotjs_gpio_close_worker(uv_work_t* work_req) {
+  GPIO_WORKER_INIT();
+  DDDLOG("%s - pin: %d", __func__, _this->pin);
+
+  iotjs_gpio_close(_this->pin);
+
+  req_data->result = 0;
+}
+
+#endif /* IOTJS_MODULE_GPIO_ARM_NUTTX_STM32_INL_H */
diff --git a/src/platform/arm-nuttx/iotjs_module_gpio-arm-nuttx.c b/src/platform/arm-nuttx/iotjs_module_gpio-arm-nuttx.c
new file mode 100644 (file)
index 0000000..0e48a20
--- /dev/null
@@ -0,0 +1,30 @@
+/* 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.
+ */
+
+#if defined(__NUTTX__)
+
+#if defined(TARGET_BOARD) && TARGET_BOARD == STM32F4DIS
+
+#include "iotjs_def.h"
+#include "./iotjs_module_gpio-arm-nuttx-stm32.inl.h"
+
+#else
+
+#include "iotjs_def.h"
+#include "./iotjs_module_gpio-arm-nuttx-general.inl.h"
+
+#endif
+
+#endif // __NUTTX__
diff --git a/src/platform/arm-nuttx/iotjs_module_i2c-arm-nuttx.c b/src/platform/arm-nuttx/iotjs_module_i2c-arm-nuttx.c
new file mode 100644 (file)
index 0000000..6f06169
--- /dev/null
@@ -0,0 +1,197 @@
+/* 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 "module/iotjs_module_i2c.h"
+#include "iotjs_systemio-arm-nuttx.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 WriteByteWorker(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);
+
+  IOTJS_ASSERT(!_this->i2c_master);
+
+  int ret = i2c_write(_this->i2c_master, &_this->config, &req_data->byte, 1);
+  if (ret < 0) {
+    DDLOG("I2C WriteByteWorker : cannot write - %d", ret);
+    req_data->error = kI2cErrWrite;
+    return;
+  }
+  req_data->error = kI2cErrOk;
+}
+
+
+void WriteBlockWorker(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 cmd = req_data->cmd;
+  uint8_t len = req_data->buf_len;
+  char* data = req_data->buf_data;
+
+  // The first element of data array is command.
+  iotjs_buffer_reallocate(data, len + 1);
+  memmove(data + 1, data, len * sizeof(char));
+  data[0] = cmd;
+
+  IOTJS_ASSERT(!_this->i2c_master);
+
+  int ret =
+      i2c_write(_this->i2c_master, &_this->config, &req_data->byte, len + 1);
+  if (ret < 0) {
+    DDLOG("I2C WriteBlockWorker : cannot write - %d", ret);
+    req_data->error = kI2cErrWrite;
+    return;
+  }
+  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;
+}
+
+
+void ReadByteWorker(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);
+
+  IOTJS_ASSERT(!_this->i2c_master);
+
+  int ret = i2c_read(_this->i2c_master, &_this->config, &req_data->byte, 1);
+  if (ret < 0) {
+    DDLOG("I2C ReadByteWorker : cannot read - %d", ret);
+    req_data->error = kI2cErrRead;
+    return;
+  }
+  req_data->error = kI2cErrOk;
+}
+
+
+void ReadBlockWorker(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 cmd = req_data->cmd;
+  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_writeread(_this->i2c_master, &_this->config, &cmd, 1,
+                          (uint8_t*)req_data->buf_data, len);
+
+  if (ret < 0) {
+    DDLOG("I2C ReadBlockWorker : cannot read - %d", ret);
+    req_data->error = kI2cErrRead;
+    return;
+  }
+  req_data->error = kI2cErrOk;
+}
+
+
+#endif // __NUTTX__
diff --git a/src/platform/arm-nuttx/iotjs_module_pwm-arm-nuttx.c b/src/platform/arm-nuttx/iotjs_module_pwm-arm-nuttx.c
new file mode 100644 (file)
index 0000000..6da6ce9
--- /dev/null
@@ -0,0 +1,174 @@
+/* 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 <nuttx/drivers/pwm.h>
+#include <stdlib.h>
+#include <sys/ioctl.h>
+
+#include "iotjs_def.h"
+#include "iotjs_systemio-arm-nuttx.h"
+#include "module/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);
+
+  uint32_t 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__
diff --git a/src/platform/arm-nuttx/iotjs_module_spi-arm-nuttx.c b/src/platform/arm-nuttx/iotjs_module_spi-arm-nuttx.c
new file mode 100644 (file)
index 0000000..2361b0c
--- /dev/null
@@ -0,0 +1,48 @@
+/* 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 "module/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__
diff --git a/src/platform/arm-nuttx/iotjs_module_stm32f4dis-arm-nuttx.c b/src/platform/arm-nuttx/iotjs_module_stm32f4dis-arm-nuttx.c
new file mode 100644 (file)
index 0000000..aaf4392
--- /dev/null
@@ -0,0 +1,194 @@
+/* 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 "module/iotjs_module_stm32f4dis.h"
+#include "iotjs_systemio-arm-nuttx.h"
+#include "stm32_gpio.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); \
+  iotjs_jval_destroy(&jtim##timer);
+
+#define SET_GPIO_CONSTANT_TIM_2(timer) \
+  SET_GPIO_CONSTANT_TIM(timer);        \
+  SET_GPIO_CONSTANT_CHANNEL(timer, 1); \
+  SET_GPIO_CONSTANT_CHANNEL(timer, 2); \
+  iotjs_jval_destroy(&jtim##timer);
+
+#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); \
+  iotjs_jval_destroy(&jtim##timer);
+
+  SET_GPIO_CONSTANT_TIM_4(1); // PA8, PE9, PA9, PE11, PA10, PE13, PA11, PE14
+  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
+  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
+  SET_GPIO_CONSTANT_TIM_4(4);  // PB6, PD12, PB7, PD13, PB8, PD14, PB9, PD15
+  SET_GPIO_CONSTANT_TIM_4(5);  // PA0, PH10, PA1, PH11, PA2, PH12, PA3, PI0
+  SET_GPIO_CONSTANT_TIM_4(8);  // PC6, PI5, PC7, PI6, PC8, PI7, PC9, PI2
+  SET_GPIO_CONSTANT_TIM_2(9);  // PA2, PE5, PA3, PE6
+  SET_GPIO_CONSTANT_TIM_1(10); // PB8, PF6
+  SET_GPIO_CONSTANT_TIM_1(11); // PB9, PF7
+  SET_GPIO_CONSTANT_TIM_2(12); // PH6, PB14, PB15, PH9
+  SET_GPIO_CONSTANT_TIM_1(13); // PA6, PF8
+  SET_GPIO_CONSTANT_TIM_1(14); // PA7, PF9
+
+#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__
diff --git a/src/platform/arm-nuttx/iotjs_module_uart-arm-nuttx.c b/src/platform/arm-nuttx/iotjs_module_uart-arm-nuttx.c
new file mode 100644 (file)
index 0000000..d9547a5
--- /dev/null
@@ -0,0 +1,78 @@
+/* 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 "module/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 += bytesWritten;
+      continue;
+    }
+
+    if (errno == EINTR) {
+      continue;
+    }
+
+    return false;
+
+  } while (_this->buf_len > offset);
+
+  return true;
+}
+
+
+#endif // __NUTTX__
diff --git a/src/platform/arm-nuttx/iotjs_systemio-arm-nuttx-stm32.c b/src/platform/arm-nuttx/iotjs_systemio-arm-nuttx-stm32.c
new file mode 100644 (file)
index 0000000..27d9b7c
--- /dev/null
@@ -0,0 +1,73 @@
+/* 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_systemio-arm-nuttx.h"
+#include "stm32_gpio.h"
+
+
+void iotjs_gpio_unconfig_nuttx(int pin) {
+  stm32_unconfiggpio(pin);
+}
+
+
+#if ENABLE_MODULE_ADC
+
+#include "stm32_adc.h"
+
+struct adc_dev_s* iotjs_adc_config_nuttx(int number, int timer, int 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, int pin) {
+  // Set alternative function
+  stm32_configgpio(pin);
+
+  // PWM initialize
+  return stm32_pwminitialize(timer);
+}
+
+#endif /* ENABLE_MODULE_PWM */
+
+
+#endif // __NUTTX__
diff --git a/src/platform/arm-nuttx/iotjs_systemio-arm-nuttx.h b/src/platform/arm-nuttx/iotjs_systemio-arm-nuttx.h
new file mode 100644 (file)
index 0000000..306d677
--- /dev/null
@@ -0,0 +1,67 @@
+/* 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
+
+
+void iotjs_gpio_unconfig_nuttx(int 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 <nuttx/analog/adc.h>
+
+#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, int pin);
+
+#endif /* ENABLE_MODULE_ADC */
+
+
+#if ENABLE_MODULE_I2C
+
+#include <nuttx/i2c/i2c_master.h>
+
+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 <nuttx/drivers/pwm.h>
+
+struct pwm_lowerhalf_s* iotjs_pwm_config_nuttx(int timer, int pin);
+
+#endif /* ENABLE_MODULE_PWM */
+
+
+#endif /* IOTJS_SYSTEMIO_ARM_NUTTX_H */
diff --git a/src/platform/i686-linux/iotjs_module_adc-i686-linux.c b/src/platform/i686-linux/iotjs_module_adc-i686-linux.c
new file mode 100644 (file)
index 0000000..ad31407
--- /dev/null
@@ -0,0 +1,21 @@
+/* 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(__linux__)
+
+#include "../iotjs_module_adc-linux-general.inl.h"
+
+#endif
diff --git a/src/platform/i686-linux/iotjs_module_blehcisocket-i686-linux.c b/src/platform/i686-linux/iotjs_module_blehcisocket-i686-linux.c
new file mode 100644 (file)
index 0000000..eddc16e
--- /dev/null
@@ -0,0 +1,22 @@
+/* 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(__linux__)
+
+#include "iotjs_def.h"
+#include "../iotjs_module_blehcisocket-linux-general.inl.h"
+
+#endif
diff --git a/src/platform/i686-linux/iotjs_module_gpio-i686-linux.c b/src/platform/i686-linux/iotjs_module_gpio-i686-linux.c
new file mode 100644 (file)
index 0000000..8c68b40
--- /dev/null
@@ -0,0 +1,22 @@
+/* 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.
+ */
+
+
+#if defined(__linux__)
+
+#include "iotjs_def.h"
+#include "../iotjs_module_gpio-linux-general.inl.h"
+
+#endif
diff --git a/src/platform/i686-linux/iotjs_module_i2c-i686-linux.c b/src/platform/i686-linux/iotjs_module_i2c-i686-linux.c
new file mode 100644 (file)
index 0000000..0ad37b1
--- /dev/null
@@ -0,0 +1,21 @@
+/* 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(__linux__)
+
+#include "../iotjs_module_i2c-linux-general.inl.h"
+
+#endif
diff --git a/src/platform/i686-linux/iotjs_module_pwm-i686-linux.c b/src/platform/i686-linux/iotjs_module_pwm-i686-linux.c
new file mode 100644 (file)
index 0000000..94e9800
--- /dev/null
@@ -0,0 +1,22 @@
+/* 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(__linux__)
+
+#include "iotjs_def.h"
+#include "../iotjs_module_pwm-linux-general.inl.h"
+
+#endif
diff --git a/src/platform/i686-linux/iotjs_module_spi-i686-linux.c b/src/platform/i686-linux/iotjs_module_spi-i686-linux.c
new file mode 100644 (file)
index 0000000..257ac80
--- /dev/null
@@ -0,0 +1,22 @@
+/* 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(__linux__)
+
+#include "iotjs_def.h"
+#include "../iotjs_module_spi-linux-general.inl.h"
+
+#endif
diff --git a/src/platform/i686-linux/iotjs_module_uart-i686-linux.c b/src/platform/i686-linux/iotjs_module_uart-i686-linux.c
new file mode 100644 (file)
index 0000000..df55956
--- /dev/null
@@ -0,0 +1,21 @@
+/* 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(__linux__)
+
+#include "../iotjs_module_uart-linux-general.inl.h"
+
+#endif // __linux__
diff --git a/src/platform/iotjs_module_adc-linux-general.inl.h b/src/platform/iotjs_module_adc-linux-general.inl.h
new file mode 100644 (file)
index 0000000..a4b95b8
--- /dev/null
@@ -0,0 +1,68 @@
+/* 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "iotjs_systemio-linux.h"
+#include "module/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 */
diff --git a/src/platform/iotjs_module_blehcisocket-linux-general.inl.h b/src/platform/iotjs_module_blehcisocket-linux-general.inl.h
new file mode 100644 (file)
index 0000000..4803a34
--- /dev/null
@@ -0,0 +1,442 @@
+/* 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 <errno.h>
+#include <stdlib.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "iotjs_def.h"
+#include "module/iotjs_module_blehcisocket.h"
+#include "module/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;
+
+  bind(_this->_socket, (struct sockaddr*)&a, sizeof(a));
+
+  // 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;
+
+  bind(_this->_socket, (struct sockaddr*)&a, sizeof(a));
+
+  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;
+
+  bind(_this->_socket, (struct sockaddr*)&a, sizeof(a));
+}
+
+
+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, int length) {
+  IOTJS_VALIDATED_STRUCT_METHOD(iotjs_blehcisocket_t, blehcisocket);
+
+  if (setsockopt(_this->_socket, SOL_HCI, HCI_FILTER, data, 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) {
+      iotjs_blehcisocket_kernelDisconnectWorkArounds(blehcisocket, length,
+                                                     data);
+    }
+
+    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_jval_t jbuf = iotjs_bufferwrap_create_buffer(length);
+    iotjs_bufferwrap_t* buf_wrap = iotjs_bufferwrap_from_jbuffer(&jbuf);
+    iotjs_bufferwrap_copy(buf_wrap, data, 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, int 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;
+}
+
+
+void 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);
+
+    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;
+    bind(l2socket, (struct sockaddr*)&l2a, sizeof(l2a));
+
+    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;
+
+    connect(l2socket, (struct sockaddr*)&l2a, sizeof(l2a));
+
+    _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--;
+    }
+  }
+}
+
+#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 */
diff --git a/src/platform/iotjs_module_gpio-linux-general.inl.h b/src/platform/iotjs_module_gpio-linux-general.inl.h
new file mode 100644 (file)
index 0000000..27150ad
--- /dev/null
@@ -0,0 +1,180 @@
+/* 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_LINUX_GENERAL_INL_H
+#define IOTJS_MODULE_GPIO_LINUX_GENERAL_INL_H
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "iotjs_systemio-linux.h"
+#include "module/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 bool gpio_set_direction(int32_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(int32_t pin, GpioMode mode) {
+  return true;
+}
+
+
+bool iotjs_gpio_write(int32_t pin, bool value) {
+  char value_path[GPIO_PATH_BUFFER_SIZE];
+  snprintf(value_path, GPIO_PATH_BUFFER_SIZE, GPIO_PIN_FORMAT_VALUE, pin);
+
+  const char* buffer = value ? "1" : "0";
+
+  DDDLOG("%s - pin: %d, value: %d", __func__, pin, value);
+
+  return iotjs_systemio_open_write_close(value_path, buffer);
+}
+
+
+int iotjs_gpio_read(int32_t pin) {
+  char buffer[GPIO_VALUE_BUFFER_SIZE];
+  char value_path[GPIO_PATH_BUFFER_SIZE];
+  snprintf(value_path, GPIO_PATH_BUFFER_SIZE, GPIO_PIN_FORMAT_VALUE, pin);
+
+  if (!iotjs_systemio_open_read_close(value_path, buffer,
+                                      GPIO_VALUE_BUFFER_SIZE - 1)) {
+    return -1;
+  }
+
+  return atoi(buffer);
+}
+
+
+bool iotjs_gpio_close(int32_t pin) {
+  char buff[GPIO_PIN_BUFFER_SIZE];
+  snprintf(buff, GPIO_PIN_BUFFER_SIZE, "%d", pin);
+
+  return iotjs_systemio_open_write_close(GPIO_PIN_FORMAT_UNEXPORT, buff);
+}
+
+
+void iotjs_gpio_open_worker(uv_work_t* work_req) {
+  GPIO_WORKER_INIT();
+
+  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 = -1;
+    return;
+  }
+  // Set direction.
+  if (!gpio_set_direction(_this->pin, _this->direction)) {
+    req_data->result = -1;
+    return;
+  }
+  // Set mode.
+  if (!gpio_set_mode(_this->pin, _this->mode)) {
+    req_data->result = -1;
+    return;
+  }
+
+  req_data->result = 0;
+}
+
+
+void iotjs_gpio_write_worker(uv_work_t* work_req) {
+  GPIO_WORKER_INIT();
+  DDDLOG("%s - pin: %d, value: %d", __func__, _this->pin, req_data->value);
+
+  bool result = iotjs_gpio_write(_this->pin, req_data->value);
+
+  if (result) {
+    req_data->result = 0;
+  } else {
+    req_data->result = -1;
+  }
+}
+
+
+void iotjs_gpio_read_worker(uv_work_t* work_req) {
+  GPIO_WORKER_INIT();
+  DDDLOG("%s - pin: %d", __func__, _this->pin);
+
+  int result = iotjs_gpio_read(_this->pin);
+  if (result >= 0) {
+    req_data->result = 0;
+    req_data->value = (bool)result;
+  } else {
+    req_data->result = -1;
+  }
+}
+
+
+void iotjs_gpio_close_worker(uv_work_t* work_req) {
+  GPIO_WORKER_INIT();
+  DDDLOG("%s - pin : %d", __func__, _this->pin);
+
+  if (iotjs_gpio_close(_this->pin)) {
+    req_data->result = 0;
+  } else {
+    req_data->result = -1;
+  }
+}
+
+
+#endif /* IOTJS_MODULE_GPIO_LINUX_GENERAL_INL_H */
diff --git a/src/platform/iotjs_module_i2c-linux-general.inl.h b/src/platform/iotjs_module_i2c-linux-general.inl.h
new file mode 100644 (file)
index 0000000..c3f7792
--- /dev/null
@@ -0,0 +1,278 @@
+/* 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.)
+ */
+
+
+#ifndef IOTJS_MODULE_I2C_LINUX_GENERAL_INL_H
+#define IOTJS_MODULE_I2C_LINUX_GENERAL_INL_H
+
+
+#include <fcntl.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+
+#include "module/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;
+
+
+static int current_fd;
+static uint8_t addr;
+
+
+int I2cSmbusAccess(int fd, uint8_t read_write, uint8_t command, int size,
+                   I2cSmbusData* data) {
+  I2cSmbusIoctlData args;
+
+  args.read_write = read_write;
+  args.command = command;
+  args.size = size;
+  args.data = data;
+
+  return ioctl(fd, I2C_SMBUS, &args);
+}
+
+
+int I2cSmbusWriteByte(int fd, uint8_t byte) {
+  return I2cSmbusAccess(fd, I2C_SMBUS_WRITE, byte, I2C_SMBUS_BYTE, NULL);
+}
+
+
+int I2cSmbusWriteI2cBlockData(int fd, uint8_t command, uint8_t* values,
+                              uint8_t length) {
+  I2cSmbusData data;
+
+  if (length > I2C_SMBUS_BLOCK_MAX) {
+    length = I2C_SMBUS_BLOCK_MAX;
+  }
+
+  for (int i = 1; i <= length; i++) {
+    data.block[i] = values[i - 1];
+  }
+  data.block[0] = length;
+
+  return I2cSmbusAccess(fd, I2C_SMBUS_WRITE, command, I2C_SMBUS_I2C_BLOCK_DATA,
+                        &data);
+}
+
+
+int I2cSmbusReadByte(int fd) {
+  I2cSmbusData data;
+
+  int result =
+      I2cSmbusAccess(fd, I2C_SMBUS_READ, I2C_NOCMD, I2C_SMBUS_BYTE, &data);
+
+  // Mask one byte from result (data.byte).
+  return result >= 0 ? 0xFF & data.byte : -1;
+}
+
+
+int I2cSmbusReadI2cBlockData(int fd, uint8_t command, uint8_t* values,
+                             uint8_t length) {
+  I2cSmbusData data;
+
+  if (length > I2C_SMBUS_BLOCK_MAX) {
+    length = I2C_SMBUS_BLOCK_MAX;
+  }
+  data.block[0] = length;
+
+  int result = I2cSmbusAccess(fd, I2C_SMBUS_READ, command,
+                              I2C_SMBUS_I2C_BLOCK_DATA, &data);
+  if (result >= 0) {
+    for (int i = 1; i <= data.block[0]; i++) {
+      values[i - 1] = data.block[i];
+    }
+    result = data.block[0];
+  }
+
+  return result;
+}
+
+
+#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) {
+  addr = address;
+  ioctl(current_fd, I2C_SLAVE_FORCE, addr);
+}
+
+
+void OpenWorker(uv_work_t* work_req) {
+  I2C_WORKER_INIT_TEMPLATE;
+
+  current_fd = open(iotjs_string_data(&req_data->device), O_RDWR);
+
+  if (current_fd == -1) {
+    req_data->error = kI2cErrOpen;
+  } else {
+    req_data->error = kI2cErrOk;
+  }
+}
+
+
+void I2cClose(iotjs_i2c_t* i2c) {
+  if (current_fd > 0) {
+    close(current_fd);
+  }
+}
+
+
+void WriteWorker(uv_work_t* work_req) {
+  I2C_WORKER_INIT_TEMPLATE;
+
+  uint8_t len = req_data->buf_len;
+  char* data = req_data->buf_data;
+
+  if (write(current_fd, data, len) != len) {
+    req_data->error = kI2cErrWrite;
+  }
+
+  if (req_data->buf_data != NULL) {
+    iotjs_buffer_release(req_data->buf_data);
+  }
+}
+
+
+void WriteByteWorker(uv_work_t* work_req) {
+  I2C_WORKER_INIT_TEMPLATE;
+
+  if (I2cSmbusWriteByte(current_fd, req_data->byte) == -1) {
+    req_data->error = kI2cErrWrite;
+  }
+}
+
+
+void WriteBlockWorker(uv_work_t* work_req) {
+  I2C_WORKER_INIT_TEMPLATE;
+
+  uint8_t cmd = req_data->cmd;
+  uint8_t len = req_data->buf_len;
+  uint8_t* data = (uint8_t*)(req_data->buf_data);
+
+  if (I2cSmbusWriteI2cBlockData(current_fd, cmd, data, len) == -1) {
+    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;
+
+  uint8_t len = req_data->buf_len;
+  req_data->buf_data = iotjs_buffer_allocate(len);
+
+  if (read(current_fd, req_data->buf_data, len) != len) {
+    req_data->error = kI2cErrRead;
+  }
+}
+
+
+void ReadByteWorker(uv_work_t* work_req) {
+  I2C_WORKER_INIT_TEMPLATE;
+
+  int result = I2cSmbusReadByte(current_fd);
+  if (result == -1) {
+    req_data->error = kI2cErrRead;
+  } else {
+    req_data->byte = result;
+  }
+}
+
+
+void ReadBlockWorker(uv_work_t* work_req) {
+  I2C_WORKER_INIT_TEMPLATE;
+
+  uint8_t cmd = req_data->cmd;
+  uint8_t len = req_data->buf_len;
+  uint8_t data[I2C_SMBUS_BLOCK_MAX + 2];
+
+  if (I2cSmbusReadI2cBlockData(current_fd, cmd, data, len) != len) {
+    req_data->error = kI2cErrReadBlock;
+  }
+
+  req_data->buf_data = iotjs_buffer_allocate(len);
+  memcpy(req_data->buf_data, data, len);
+}
+
+
+#endif /* IOTJS_MODULE_I2C_LINUX_GENERAL_INL_H */
diff --git a/src/platform/iotjs_module_pwm-linux-general.inl.h b/src/platform/iotjs_module_pwm-linux-general.inl.h
new file mode 100644 (file)
index 0000000..5bb4a0f
--- /dev/null
@@ -0,0 +1,229 @@
+/* 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 <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "iotjs_systemio-linux.h"
+#include "module/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.
+  int prefixSize = iotjs_string_size(device);
+  if (prefixSize > 0) {
+    int suffixSize = fileName ? strlen(fileName) : 0;
+    devicePath = malloc(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 */
diff --git a/src/platform/iotjs_module_spi-linux-general.inl.h b/src/platform/iotjs_module_spi-linux-general.inl.h
new file mode 100644 (file)
index 0000000..b7d3ef0
--- /dev/null
@@ -0,0 +1,169 @@
+/* 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 <uv.h>
+#include <linux/spi/spidev.h>
+#include <sys/ioctl.h>
+
+#include "iotjs_def.h"
+#include "iotjs_systemio-linux.h"
+#include "module/iotjs_module_buffer.h"
+#include "module/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 */
diff --git a/src/platform/iotjs_module_uart-linux-general.inl.h b/src/platform/iotjs_module_uart-linux-general.inl.h
new file mode 100644 (file)
index 0000000..660c31c
--- /dev/null
@@ -0,0 +1,154 @@
+/* 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 <errno.h>
+#include <fcntl.h>
+#include <termios.h>
+#include <unistd.h>
+#include "module/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 |= baud_to_constant(_this->baud_rate);
+  options.c_cflag |= 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 += bytesWritten;
+      continue;
+    }
+
+    if (errno == EINTR) {
+      continue;
+    }
+
+    return false;
+
+  } while (_this->buf_len > offset);
+
+  return true;
+}
+
+
+#endif /* IOTJS_MODULE_UART_LINUX_GENERAL_INL_H */
diff --git a/src/platform/iotjs_systemio-linux.c b/src/platform/iotjs_systemio-linux.c
new file mode 100644 (file)
index 0000000..48738f8
--- /dev/null
@@ -0,0 +1,192 @@
+/* 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 <uv.h>
+#include <unistd.h>
+
+#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,
+                                    int 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, int 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, int 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;
+}
diff --git a/src/platform/iotjs_systemio-linux.h b/src/platform/iotjs_systemio-linux.h
new file mode 100644 (file)
index 0000000..87dc691
--- /dev/null
@@ -0,0 +1,40 @@
+/* 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,
+                                    int buffer_len);
+
+bool iotjs_systemio_device_open(const char* export_path, int value,
+                                const char* exported_path,
+                                const char** created_files,
+                                int created_files_length);
+
+bool iotjs_systemio_device_close(const char* export_path, int value);
+
+
+#endif /* IOTJS_DEVICE_IO_LINUX_GENERAL_H */
diff --git a/src/platform/x86_64-darwin/iotjs_module_adc-x86_64-darwin.c b/src/platform/x86_64-darwin/iotjs_module_adc-x86_64-darwin.c
new file mode 100644 (file)
index 0000000..69344e5
--- /dev/null
@@ -0,0 +1,26 @@
+/* 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(__APPLE__)
+
+#include "module/iotjs_module_adc.h"
+#include "iotjs_module_unimplemented.inl.h"
+
+int32_t iotjs_adc_read(iotjs_adc_t* adc) IOTJS_MODULE_UNIMPLEMENTED(-1);
+bool iotjs_adc_close(iotjs_adc_t* adc) IOTJS_MODULE_UNIMPLEMENTED(0);
+void iotjs_adc_open_worker(uv_work_t* work_req) IOTJS_MODULE_UNIMPLEMENTED();
+
+#endif // __APPLE__
diff --git a/src/platform/x86_64-darwin/iotjs_module_blehcisocket-x86_64-darwin.c b/src/platform/x86_64-darwin/iotjs_module_blehcisocket-x86_64-darwin.c
new file mode 100644 (file)
index 0000000..de961c2
--- /dev/null
@@ -0,0 +1,39 @@
+/* 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(__APPLE__)
+
+#include "module/iotjs_module_blehcisocket.h"
+#include "iotjs_module_unimplemented.inl.h"
+
+#define THIS iotjs_blehcisocket_t* iotjs_blehcisocket
+
+void iotjs_blehcisocket_initialize(THIS) IOTJS_MODULE_UNIMPLEMENTED();
+void iotjs_blehcisocket_close(THIS) IOTJS_MODULE_UNIMPLEMENTED();
+void iotjs_blehcisocket_start(THIS) IOTJS_MODULE_UNIMPLEMENTED();
+int iotjs_blehcisocket_bindRaw(THIS, int* devId) IOTJS_MODULE_UNIMPLEMENTED(0);
+int iotjs_blehcisocket_bindUser(THIS, int* devId) IOTJS_MODULE_UNIMPLEMENTED(0);
+void iotjs_blehcisocket_bindControl(THIS) IOTJS_MODULE_UNIMPLEMENTED();
+bool iotjs_blehcisocket_isDevUp(THIS) IOTJS_MODULE_UNIMPLEMENTED(false);
+void iotjs_blehcisocket_setFilter(THIS, char* data, int length)
+    IOTJS_MODULE_UNIMPLEMENTED();
+void iotjs_blehcisocket_stop(THIS) IOTJS_MODULE_UNIMPLEMENTED();
+void iotjs_blehcisocket_write(THIS, char* data, int length)
+    IOTJS_MODULE_UNIMPLEMENTED();
+
+#undef THIS
+
+#endif // __APPLE__
diff --git a/src/platform/x86_64-darwin/iotjs_module_gpio-x86_64-darwin.c b/src/platform/x86_64-darwin/iotjs_module_gpio-x86_64-darwin.c
new file mode 100644 (file)
index 0000000..84ce9c5
--- /dev/null
@@ -0,0 +1,31 @@
+/* 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(__APPLE__)
+
+#include "module/iotjs_module_gpio.h"
+#include "iotjs_module_unimplemented.inl.h"
+
+void iotjs_gpio_open_worker(uv_work_t* work_req) IOTJS_MODULE_UNIMPLEMENTED();
+void iotjs_gpio_write_worker(uv_work_t* work_req) IOTJS_MODULE_UNIMPLEMENTED();
+void iotjs_gpio_read_worker(uv_work_t* work_req) IOTJS_MODULE_UNIMPLEMENTED();
+void iotjs_gpio_close_worker(uv_work_t* work_req) IOTJS_MODULE_UNIMPLEMENTED();
+bool iotjs_gpio_write(int32_t pin, bool value)
+    IOTJS_MODULE_UNIMPLEMENTED(false);
+int iotjs_gpio_read(int32_t pin) IOTJS_MODULE_UNIMPLEMENTED(0);
+bool iotjs_gpio_close(int32_t pin) IOTJS_MODULE_UNIMPLEMENTED(false);
+
+#endif // __APPLE__
diff --git a/src/platform/x86_64-darwin/iotjs_module_i2c-x86_64-darwin.c b/src/platform/x86_64-darwin/iotjs_module_i2c-x86_64-darwin.c
new file mode 100644 (file)
index 0000000..b806f92
--- /dev/null
@@ -0,0 +1,33 @@
+/* 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(__APPLE__)
+
+#include "module/iotjs_module_i2c.h"
+#include "iotjs_module_unimplemented.inl.h"
+
+void I2cSetAddress(iotjs_i2c_t* i2c, uint8_t address)
+    IOTJS_MODULE_UNIMPLEMENTED();
+void OpenWorker(uv_work_t* work_req) IOTJS_MODULE_UNIMPLEMENTED();
+void I2cClose(iotjs_i2c_t* i2c) IOTJS_MODULE_UNIMPLEMENTED();
+void WriteWorker(uv_work_t* work_req) IOTJS_MODULE_UNIMPLEMENTED();
+void WriteByteWorker(uv_work_t* work_req) IOTJS_MODULE_UNIMPLEMENTED();
+void WriteBlockWorker(uv_work_t* work_req) IOTJS_MODULE_UNIMPLEMENTED();
+void ReadWorker(uv_work_t* work_req) IOTJS_MODULE_UNIMPLEMENTED();
+void ReadByteWorker(uv_work_t* work_req) IOTJS_MODULE_UNIMPLEMENTED();
+void ReadBlockWorker(uv_work_t* work_req) IOTJS_MODULE_UNIMPLEMENTED();
+
+#endif // __APPLE__
diff --git a/src/platform/x86_64-darwin/iotjs_module_pwm-x86_64-darwin.c b/src/platform/x86_64-darwin/iotjs_module_pwm-x86_64-darwin.c
new file mode 100644 (file)
index 0000000..c0d012b
--- /dev/null
@@ -0,0 +1,29 @@
+/* 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(__APPLE__)
+
+#include "module/iotjs_module_pwm.h"
+#include "iotjs_module_unimplemented.inl.h"
+
+void iotjs_pwm_open_worker(uv_work_t* work_req) IOTJS_MODULE_UNIMPLEMENTED();
+bool iotjs_pwm_set_period(iotjs_pwm_t* pwm) IOTJS_MODULE_UNIMPLEMENTED(false);
+bool iotjs_pwm_set_dutycycle(iotjs_pwm_t* pwm)
+    IOTJS_MODULE_UNIMPLEMENTED(false);
+bool iotjs_pwm_set_enable(iotjs_pwm_t* pwm) IOTJS_MODULE_UNIMPLEMENTED(false);
+bool iotjs_pwm_close(iotjs_pwm_t* pwm) IOTJS_MODULE_UNIMPLEMENTED(false);
+
+#endif // __APPLE__
diff --git a/src/platform/x86_64-darwin/iotjs_module_spi-x86_64-darwin.c b/src/platform/x86_64-darwin/iotjs_module_spi-x86_64-darwin.c
new file mode 100644 (file)
index 0000000..69d1555
--- /dev/null
@@ -0,0 +1,26 @@
+/* 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(__APPLE__)
+
+#include "module/iotjs_module_spi.h"
+#include "iotjs_module_unimplemented.inl.h"
+
+bool iotjs_spi_transfer(iotjs_spi_t* spi) IOTJS_MODULE_UNIMPLEMENTED(false);
+bool iotjs_spi_close(iotjs_spi_t* spi) IOTJS_MODULE_UNIMPLEMENTED(false);
+void iotjs_spi_open_worker(uv_work_t* work_req) IOTJS_MODULE_UNIMPLEMENTED();
+
+#endif // __APPLE__
diff --git a/src/platform/x86_64-darwin/iotjs_module_uart-x86_64-darwin.c b/src/platform/x86_64-darwin/iotjs_module_uart-x86_64-darwin.c
new file mode 100644 (file)
index 0000000..3e1531c
--- /dev/null
@@ -0,0 +1,25 @@
+/* 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(__APPLE__)
+
+#include "module/iotjs_module_uart.h"
+#include "iotjs_module_unimplemented.inl.h"
+
+void iotjs_uart_open_worker(uv_work_t* work_req) IOTJS_MODULE_UNIMPLEMENTED();
+bool iotjs_uart_write(iotjs_uart_t* uart) IOTJS_MODULE_UNIMPLEMENTED(false);
+
+#endif // __APPLE__
diff --git a/src/platform/x86_64-darwin/iotjs_module_unimplemented.inl.h b/src/platform/x86_64-darwin/iotjs_module_unimplemented.inl.h
new file mode 100644 (file)
index 0000000..4b6b3f5
--- /dev/null
@@ -0,0 +1,29 @@
+/* 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_UNIMPLEMENTED_INL_H
+#define IOTJS_MODULE_UNIMPLEMENTED_INL_H
+
+#include "iotjs_def.h"
+
+
+#define IOTJS_MODULE_UNIMPLEMENTED(DUMMY) \
+  {                                       \
+    IOTJS_ASSERT(!"Not implemented");     \
+    return DUMMY;                         \
+  }
+
+
+#endif /* IOTJS_MODULE_UNIMPLEMENTED_INL_H */
diff --git a/src/platform/x86_64-linux/iotjs_module_adc-x86_64-linux.c b/src/platform/x86_64-linux/iotjs_module_adc-x86_64-linux.c
new file mode 100644 (file)
index 0000000..ad31407
--- /dev/null
@@ -0,0 +1,21 @@
+/* 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(__linux__)
+
+#include "../iotjs_module_adc-linux-general.inl.h"
+
+#endif
diff --git a/src/platform/x86_64-linux/iotjs_module_blehcisocket-x86_64-linux.c b/src/platform/x86_64-linux/iotjs_module_blehcisocket-x86_64-linux.c
new file mode 100644 (file)
index 0000000..eddc16e
--- /dev/null
@@ -0,0 +1,22 @@
+/* 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(__linux__)
+
+#include "iotjs_def.h"
+#include "../iotjs_module_blehcisocket-linux-general.inl.h"
+
+#endif
diff --git a/src/platform/x86_64-linux/iotjs_module_gpio-x86_64-linux.c b/src/platform/x86_64-linux/iotjs_module_gpio-x86_64-linux.c
new file mode 100644 (file)
index 0000000..8c68b40
--- /dev/null
@@ -0,0 +1,22 @@
+/* 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.
+ */
+
+
+#if defined(__linux__)
+
+#include "iotjs_def.h"
+#include "../iotjs_module_gpio-linux-general.inl.h"
+
+#endif
diff --git a/src/platform/x86_64-linux/iotjs_module_i2c-x86_64-linux.c b/src/platform/x86_64-linux/iotjs_module_i2c-x86_64-linux.c
new file mode 100644 (file)
index 0000000..0ad37b1
--- /dev/null
@@ -0,0 +1,21 @@
+/* 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(__linux__)
+
+#include "../iotjs_module_i2c-linux-general.inl.h"
+
+#endif
diff --git a/src/platform/x86_64-linux/iotjs_module_pwm-x86_64-linux.c b/src/platform/x86_64-linux/iotjs_module_pwm-x86_64-linux.c
new file mode 100644 (file)
index 0000000..94e9800
--- /dev/null
@@ -0,0 +1,22 @@
+/* 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(__linux__)
+
+#include "iotjs_def.h"
+#include "../iotjs_module_pwm-linux-general.inl.h"
+
+#endif
diff --git a/src/platform/x86_64-linux/iotjs_module_spi-x86_64-linux.c b/src/platform/x86_64-linux/iotjs_module_spi-x86_64-linux.c
new file mode 100644 (file)
index 0000000..3b0b0d6
--- /dev/null
@@ -0,0 +1,21 @@
+/* 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(__linux__)
+
+#include "../iotjs_module_spi-linux-general.inl.h"
+
+#endif
diff --git a/src/platform/x86_64-linux/iotjs_module_uart-x86_64-linux.c b/src/platform/x86_64-linux/iotjs_module_uart-x86_64-linux.c
new file mode 100644 (file)
index 0000000..ec6ece5
--- /dev/null
@@ -0,0 +1,21 @@
+/* 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(__linux__)
+
+#include "../iotjs_module_uart-linux-general.inl.h"
+
+#endif // __linux__
diff --git a/targets/nuttx-stm32f4/README.md b/targets/nuttx-stm32f4/README.md
new file mode 100644 (file)
index 0000000..6c4f7d1
--- /dev/null
@@ -0,0 +1,154 @@
+### 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
+  |  + targets
+  |      + nuttx-stm32f4
+  + nuttx
+  + stlink
+```
+
+#### 2. Add IoT.js as a builtin application for NuttX
+
+```bash
+$ cd apps/system
+$ mkdir iotjs
+$ cp ../../iotjs/targets/nuttx-stm32f4/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/targets/nuttx-stm32f4/nuttx/.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)`
+
+#### 4. Build IoT.js for NuttX
+
+##### Follow the instruction
+* [Build-for-NuttX](../../docs/build/Build-for-NuttX.md)
+
+#### 5. Build NuttX
+
+```bash
+# assuming you are in iotjs-nuttx folder
+$ cd nuttx/
+$ make
+```
+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 flash,
+```bash
+# assuming you are in nuttx folder
+$ sudo ../stlink/build/st-flash write nuttx.bin 0x8000000
+```
diff --git a/targets/nuttx-stm32f4/Stm32f4dis.md b/targets/nuttx-stm32f4/Stm32f4dis.md
new file mode 100644 (file)
index 0000000..d2401fa
--- /dev/null
@@ -0,0 +1,127 @@
+## Stm32f4dis module
+
+## `Pin`
+To use system IO, such as GPIO, PWM and ADC you must know pin name.
+`stm32f4dis` module has pin object which is designed to find a pin name easier.
+
+``` javascript
+var pin = require('stm32f4dis').pin;
+```
+
+
+### `GPIO Pin` <a name="gpio-pin"></a>
+`P<port><pin>`
+
+For example,
+``` javascript
+var gpio = require('gpio');
+var pin = require('stm32f4dis').pin;
+
+gpio.open(pin.PD6);
+```
+
+
+### `PWM Pin` <a name="pwm-pin"></a>
+`PWM<timer>.CH<channel>_<number>`
+
+For example,
+``` javascript
+var pwm = require('pwm');
+var pin = require('stm32f4dis').pin;
+
+var pwm2 = new pwm(pin.PWM2.CH1_2);
+```
+The following is a list of PWM pin name.
+
+| 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` <a name="adc-pin"></a>
+`ADC<number>_<timer>`
+
+For example,
+``` javascript
+var adc = require('adc');
+var pin = require('stm32f4dis').pin;
+
+var adc1 = new adc(pin.ADC1_3);
+```
+The following is a list of ADC pin name.
+
+| 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` <a name="uart"></a>
+To use UART on stm32f4-discovery board, you must use proper pins. Stm32f4-discovery board supports 4 UART ports, such as USART2, USART3, UART5, USART6.
+But as our default config option sets SDIO to be on, it makes conflict with UART5 port because these two use the same pin for connection. So you must be careful when you enable UART5 port.
+
+The following is a list of ADC 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 |
+
+* Different from other system IO such as GPIO, ADC, PWM, you can't find the name of the UART device easily by `stm32f4dis.pin` module. It's because the name of the uart device can be changed according to your Nuttx config option. You can find '/dev/ttyS[0-3]' according to your environment.
+
+
+### Enable more ports using patch file
+
+Current version of Nuttx doesn't support USART1 and UART4 as the ports for stm32f4-discovery board. But if you want to enable more ports other than above, you can modify Nuttx code by referring to a part of `targets/nuttx-stm32f4/nuttx/patch` file.
+
+To apply whole patch,
+```bash
+~/workspace/nuttx$ patch -p1 < ../iotjs/targets/nuttx-stm32f4/nuttx/patch
+```
+Make sure it is your responsibility to enable the ports only when they do not make any conflicts.
\ No newline at end of file
diff --git a/targets/nuttx-stm32f4/app/Kconfig b/targets/nuttx-stm32f4/app/Kconfig
new file mode 100644 (file)
index 0000000..85409a7
--- /dev/null
@@ -0,0 +1,22 @@
+#
+# 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
diff --git a/targets/nuttx-stm32f4/app/Make.defs b/targets/nuttx-stm32f4/app/Make.defs
new file mode 100644 (file)
index 0000000..4cd4a82
--- /dev/null
@@ -0,0 +1,18 @@
+# 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
diff --git a/targets/nuttx-stm32f4/app/Makefile b/targets/nuttx-stm32f4/app/Makefile
new file mode 100644 (file)
index 0000000..ed43219
--- /dev/null
@@ -0,0 +1,195 @@
+# 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 <gnutt@nuttx.org>
+#
+# 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
+
+
+CONFIG_IOTJS_PRIORITY ?= SCHED_PRIORITY_DEFAULT
+CONFIG_IOTJS_STACKSIZE ?= 16384
+# NSH sysinfo command
+
+APPNAME = iotjs
+IOTJS_ROOT_DIR = ../../../iotjs
+PRIORITY = $(CONFIG_IOTJS_PRIORITY)
+STACKSIZE = $(CONFIG_IOTJS_STACKSIZE)
+HEAPSIZE = $(CONFIG_IOTJS_HEAPSIZE)
+
+ASRCS =
+CSRCS =
+CXXSRCS =
+MAINSRC = iotjs_main.cxx
+LIBS = libhttpparser.a libiotjs.a libjerry-core.a libtuv.a libjerry-libm.a libjerry-libc.a
+
+AOBJS = $(ASRCS:.S=$(OBJEXT))
+COBJS = $(CSRCS:.c=$(OBJEXT))
+CXXOBJS = $(CXXSRCS:.cxx=$(OBJEXT))
+MAINOBJ = $(MAINSRC:.cxx=$(OBJEXT))
+
+SRCS = $(ASRCS) $(CSRCS) $(CXXSRCS) $(MAINSRC)
+OBJS = $(AOBJS) $(COBJS) $(CXXOBJS)
+
+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
+
+chkcxx:
+ifneq ($(CONFIG_HAVE_CXX),y)
+  @echo ""
+  @echo "In order to use this example, you toolchain must support must"
+  @echo ""
+  @echo "  (1) Explicitly select CONFIG_HAVE_CXX to build in C++ support"
+  @echo "  (2) Define CXX, CXXFLAGS, and COMPILEXX in the Make.defs file"
+  @echo "      of the configuration that you are using."
+  @echo ""
+  @exit 1
+endif
+
+
+$(AOBJS): %$(OBJEXT): %.S
+       $(call ASSEMBLE, $<, $@)
+
+$(COBJS): %$(OBJEXT): %.c
+       $(call COMPILE, $<, $@)
+
+$(CXXOBJS) $(MAINOBJ): %$(OBJEXT): %.cxx
+       $(call COMPILEXX, $<, $@)
+
+copylibs :
+       cp $(IOTJS_ROOT_DIR)/build/arm-nuttx/$(BUILD_TYPE)/lib/lib*.a .
+
+$(LIBS) : copylibs
+       $(firstword $(AR)) x $@
+
+.built: chkcxx $(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) "$(CXX)" -- $(CXXFLAGS) -- $(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:
diff --git a/targets/nuttx-stm32f4/app/iotjs_main.cxx b/targets/nuttx-stm32f4/app/iotjs_main.cxx
new file mode 100644 (file)
index 0000000..21ba43a
--- /dev/null
@@ -0,0 +1,110 @@
+/* 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 <gnutt@nuttx.org>
+ *
+ * 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 <nuttx/config.h>
+#include <nuttx/arch.h>
+
+#include <stdio.h>
+#include <setjmp.h>
+
+#ifdef CONFIG_IOTJS
+# if !defined(CONFIG_HAVE_CXX) || !defined(CONFIG_HAVE_CXXINITIALIZE)
+#   error Need CONFIG_HAVE_CXX and CONFIG_HAVE_CXXINITIALIZE
+# endif
+#endif
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/**
+ * 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 */
+
+extern "C" int iotjs_entry(int argc, char *argv[]);
+extern "C" int tuv_cleanup(void);
+
+#ifdef CONFIG_BUILD_KERNEL
+extern "C" int main(int argc, FAR char *argv[])
+#else
+extern "C" int iotjs_main(int argc, char *argv[])
+#endif
+{
+  int ret = 0;
+  up_cxxinitialize();
+  ret = iotjs_entry(argc, argv);
+  tuv_cleanup();
+  return ret;
+}
diff --git a/targets/nuttx-stm32f4/nuttx/.config.default b/targets/nuttx-stm32f4/nuttx/.config.default
new file mode 100644 (file)
index 0000000..7aaddc0
--- /dev/null
@@ -0,0 +1,1471 @@
+#
+# 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
diff --git a/targets/nuttx-stm32f4/nuttx/.config.travis b/targets/nuttx-stm32f4/nuttx/.config.travis
new file mode 100644 (file)
index 0000000..2079a4a
--- /dev/null
@@ -0,0 +1,1522 @@
+#
+# 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
diff --git a/targets/nuttx-stm32f4/nuttx/patch b/targets/nuttx-stm32f4/nuttx/patch
new file mode 100644 (file)
index 0000000..efa8999
--- /dev/null
@@ -0,0 +1,24 @@
+--- 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
diff --git a/targets/tizenrt-artik05x/app/README.md b/targets/tizenrt-artik05x/app/README.md
new file mode 100644 (file)
index 0000000..55ba021
--- /dev/null
@@ -0,0 +1,82 @@
+### 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
+  |  + targets
+  |      + tizenrt-artik05x
+  + tizenrt
+```
+
+#### 2. Add IoT.js as a builtin application for TizenRT
+
+```bash
+$ cd tizenrt/apps/system
+$ mkdir iotjs
+$ cp ../../../iotjs/targets/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)
diff --git a/targets/tizenrt-artik05x/app/iotjs/.gitignore b/targets/tizenrt-artik05x/app/iotjs/.gitignore
new file mode 100644 (file)
index 0000000..fa1ec75
--- /dev/null
@@ -0,0 +1,11 @@
+/Make.dep
+/.depend
+/.built
+/*.asm
+/*.obj
+/*.rel
+/*.lst
+/*.sym
+/*.adb
+/*.lib
+/*.src
diff --git a/targets/tizenrt-artik05x/app/iotjs/Kconfig b/targets/tizenrt-artik05x/app/iotjs/Kconfig
new file mode 100644 (file)
index 0000000..67200a9
--- /dev/null
@@ -0,0 +1,27 @@
+#
+# 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 IOTJS
+
+config IOTJS_PRIORITY
+  int "IoT.js task priority"
+  default 100
+
+config IOTJS_STACKSIZE
+  int "IoT.js stack size"
+  default 16384
+
+endif
+
+config USER_ENTRYPOINT
+        string
+        default "iotjs_main" if ENTRY_IOTJS
+
diff --git a/targets/tizenrt-artik05x/app/iotjs/Kconfig_ENTRY b/targets/tizenrt-artik05x/app/iotjs/Kconfig_ENTRY
new file mode 100644 (file)
index 0000000..94c48db
--- /dev/null
@@ -0,0 +1,3 @@
+config ENTRY_IOTJS
+       bool "iotjs application"
+       depends on SYSTEM_IOTJS
diff --git a/targets/tizenrt-artik05x/app/iotjs/Make.defs b/targets/tizenrt-artik05x/app/iotjs/Make.defs
new file mode 100644 (file)
index 0000000..da059d9
--- /dev/null
@@ -0,0 +1,18 @@
+# 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
diff --git a/targets/tizenrt-artik05x/app/iotjs/Makefile b/targets/tizenrt-artik05x/app/iotjs/Makefile
new file mode 100644 (file)
index 0000000..4bb5617
--- /dev/null
@@ -0,0 +1,170 @@
+###########################################################################
+#
+# 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 <gnutt@nuttx.org>
+#
+# 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
diff --git a/targets/tizenrt-artik05x/app/iotjs/iotjs_main.c b/targets/tizenrt-artik05x/app/iotjs/iotjs_main.c
new file mode 100644 (file)
index 0000000..4a5fc6a
--- /dev/null
@@ -0,0 +1,109 @@
+/* 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 <gnutt@nuttx.org>
+ *
+ * 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 <apps/shell/tash.h>
+#include <tinyara/arch.h>
+#include <tinyara/config.h>
+
+#include <setjmp.h>
+#include <stdio.h>
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/**
+ * 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);
+
+static int iotjs(int argc, char *argv[]) {
+  int ret = 0;
+  ret = iotjs_entry(argc, argv);
+  tuv_cleanup();
+  return ret;
+}
+
+const static tash_cmdlist_t iotjs_cmds[] = { { "iotjs", iotjs,
+                                               TASH_EXECMD_SYNC },
+                                             { 0, 0, 0 } };
+
+#ifdef CONFIG_BUILD_KERNEL
+int main(int argc, FAR char *argv[])
+#else
+int iotjs_main(int argc, char *argv[])
+#endif
+{
+  tash_cmdlist_install(iotjs_cmds);
+  return 0;
+}
diff --git a/test/resources/greeting.txt b/test/resources/greeting.txt
new file mode 100644 (file)
index 0000000..3c3130b
--- /dev/null
@@ -0,0 +1 @@
+Hello IoT.js!!
\ No newline at end of file
diff --git a/test/resources/readdir/DO_NOT_MODIFY_THIS_FOLDER b/test/resources/readdir/DO_NOT_MODIFY_THIS_FOLDER
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/test/resources/readdir/This_is_a_directory/.gitkeep b/test/resources/readdir/This_is_a_directory/.gitkeep
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/test/resources/readdir/This_is_another_directory/.gitkeep b/test/resources/readdir/This_is_another_directory/.gitkeep
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/test/resources/readdir/regular.txt b/test/resources/readdir/regular.txt
new file mode 100644 (file)
index 0000000..3c3130b
--- /dev/null
@@ -0,0 +1 @@
+Hello IoT.js!!
\ No newline at end of file
diff --git a/test/resources/rename.txt b/test/resources/rename.txt
new file mode 100644 (file)
index 0000000..3c3130b
--- /dev/null
@@ -0,0 +1 @@
+Hello IoT.js!!
\ No newline at end of file
diff --git a/test/resources/test1.txt b/test/resources/test1.txt
new file mode 100644 (file)
index 0000000..3c3ecf7
--- /dev/null
@@ -0,0 +1 @@
+TEST File Read & Write
diff --git a/test/resources/test_console_stdout.txt b/test/resources/test_console_stdout.txt
new file mode 100644 (file)
index 0000000..ea97cf7
--- /dev/null
@@ -0,0 +1,8 @@
+Hello IoT.js!!
+1
+2
+3
+13
+1,2,3
+1 2 3
+a 1 b 2 c 3
diff --git a/test/resources/tobeornottobe.txt b/test/resources/tobeornottobe.txt
new file mode 100644 (file)
index 0000000..08687b1
--- /dev/null
@@ -0,0 +1,35 @@
+To 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.
\ No newline at end of file
diff --git a/test/run_fail/assert_fail1.js b/test/run_fail/assert_fail1.js
new file mode 100644 (file)
index 0000000..3c6cd84
--- /dev/null
@@ -0,0 +1,19 @@
+/* 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();
diff --git a/test/run_fail/assert_fail2.js b/test/run_fail/assert_fail2.js
new file mode 100644 (file)
index 0000000..b82766c
--- /dev/null
@@ -0,0 +1,19 @@
+/* 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);
diff --git a/test/run_fail/assert_fail3.js b/test/run_fail/assert_fail3.js
new file mode 100644 (file)
index 0000000..cf155b9
--- /dev/null
@@ -0,0 +1,19 @@
+/* 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);
diff --git a/test/run_fail/fs_callbacks_called.js b/test/run_fail/fs_callbacks_called.js
new file mode 100644 (file)
index 0000000..0df7a85
--- /dev/null
@@ -0,0 +1,40 @@
+/* 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);
diff --git a/test/run_fail/process_exit1.js b/test/run_fail/process_exit1.js
new file mode 100644 (file)
index 0000000..a6d5a78
--- /dev/null
@@ -0,0 +1,21 @@
+/* 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();
+});
diff --git a/test/run_fail/process_exit2.js b/test/run_fail/process_exit2.js
new file mode 100644 (file)
index 0000000..e1a20bd
--- /dev/null
@@ -0,0 +1,23 @@
+/* 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();
diff --git a/test/run_fail/process_exitcode1.js b/test/run_fail/process_exitcode1.js
new file mode 100644 (file)
index 0000000..1808c7c
--- /dev/null
@@ -0,0 +1,24 @@
+/* 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);
diff --git a/test/run_fail/process_exitcode2.js b/test/run_fail/process_exitcode2.js
new file mode 100644 (file)
index 0000000..3bafef7
--- /dev/null
@@ -0,0 +1,25 @@
+/* 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();
diff --git a/test/run_fail/require_fail1.js b/test/run_fail/require_fail1.js
new file mode 100644 (file)
index 0000000..f1acad0
--- /dev/null
@@ -0,0 +1,17 @@
+/* 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');
diff --git a/test/run_fail/runtime_error1.js b/test/run_fail/runtime_error1.js
new file mode 100644 (file)
index 0000000..d0ea00d
--- /dev/null
@@ -0,0 +1,19 @@
+/* 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();
diff --git a/test/run_fail/syntax_fail1.js b/test/run_fail/syntax_fail1.js
new file mode 100644 (file)
index 0000000..76725e0
--- /dev/null
@@ -0,0 +1,16 @@
+/* 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
diff --git a/test/run_fail/uncaught_error_event.js b/test/run_fail/uncaught_error_event.js
new file mode 100644 (file)
index 0000000..9140e7f
--- /dev/null
@@ -0,0 +1,21 @@
+/* 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');
diff --git a/test/run_pass/issue/issue-133.js b/test/run_pass/issue/issue-133.js
new file mode 100644 (file)
index 0000000..a58d3e4
--- /dev/null
@@ -0,0 +1,18 @@
+/* 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("");
diff --git a/test/run_pass/issue/issue-137.js b/test/run_pass/issue/issue-137.js
new file mode 100644 (file)
index 0000000..51b9c08
--- /dev/null
@@ -0,0 +1,37 @@
+/* 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);
diff --git a/test/run_pass/issue/issue-198.js b/test/run_pass/issue/issue-198.js
new file mode 100644 (file)
index 0000000..23bec1b
--- /dev/null
@@ -0,0 +1,24 @@
+/* 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
+);
diff --git a/test/run_pass/issue/issue-223.js b/test/run_pass/issue/issue-223.js
new file mode 100644 (file)
index 0000000..ba8ba0a
--- /dev/null
@@ -0,0 +1,26 @@
+/* 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
+);
diff --git a/test/run_pass/issue/issue-266.js b/test/run_pass/issue/issue-266.js
new file mode 100644 (file)
index 0000000..51ccd98
--- /dev/null
@@ -0,0 +1,49 @@
+/* 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;
+
+var server = net.createServer();
+server.listen(port);
+
+server.on('connection', function(socket) {
+  socket.on('data', function(data) {
+  });
+  socket.on('finish', function() {
+    socket.destroy();
+    socket.destroy();
+    socket.destroy();
+  });
+});
+
+
+setTimeout(function() {
+    server.close();
+}, 1000);
+
+
+var socket = new net.Socket();
+socket.connect(port, "127.0.0.1");
+socket.end('test');
+
+process.on('exit', function() {
+  assert.equal(server._socketCount, 0);
+});
diff --git a/test/run_pass/issue/issue-323.js b/test/run_pass/issue/issue-323.js
new file mode 100644 (file)
index 0000000..db6b1f6
--- /dev/null
@@ -0,0 +1,33 @@
+/* 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
+);
diff --git a/test/run_pass/require1/module_cache.js b/test/run_pass/require1/module_cache.js
new file mode 100644 (file)
index 0000000..feb94b3
--- /dev/null
@@ -0,0 +1,20 @@
+/* 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;
diff --git a/test/run_pass/require1/node_modules/test_index/add2.js b/test/run_pass/require1/node_modules/test_index/add2.js
new file mode 100644 (file)
index 0000000..9841ea6
--- /dev/null
@@ -0,0 +1,22 @@
+/* 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;
+}
diff --git a/test/run_pass/require1/node_modules/test_index/index.js b/test/run_pass/require1/node_modules/test_index/index.js
new file mode 100644 (file)
index 0000000..590c324
--- /dev/null
@@ -0,0 +1,26 @@
+/* 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;
diff --git a/test/run_pass/require1/node_modules/test_index/lib/multi.js b/test/run_pass/require1/node_modules/test_index/lib/multi.js
new file mode 100644 (file)
index 0000000..b757e5b
--- /dev/null
@@ -0,0 +1,24 @@
+/* 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;
diff --git a/test/run_pass/require1/node_modules/test_index/package.json b/test/run_pass/require1/node_modules/test_index/package.json
new file mode 100644 (file)
index 0000000..31d54be
--- /dev/null
@@ -0,0 +1,3 @@
+{
+  "name": "index_test"
+}
diff --git a/test/run_pass/require1/node_modules/test_pkg/add2.js b/test/run_pass/require1/node_modules/test_pkg/add2.js
new file mode 100644 (file)
index 0000000..9841ea6
--- /dev/null
@@ -0,0 +1,22 @@
+/* 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;
+}
diff --git a/test/run_pass/require1/node_modules/test_pkg/lib/multi.js b/test/run_pass/require1/node_modules/test_pkg/lib/multi.js
new file mode 100644 (file)
index 0000000..b757e5b
--- /dev/null
@@ -0,0 +1,24 @@
+/* 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;
diff --git a/test/run_pass/require1/node_modules/test_pkg/main.js b/test/run_pass/require1/node_modules/test_pkg/main.js
new file mode 100644 (file)
index 0000000..590c324
--- /dev/null
@@ -0,0 +1,26 @@
+/* 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;
diff --git a/test/run_pass/require1/node_modules/test_pkg/package.json b/test/run_pass/require1/node_modules/test_pkg/package.json
new file mode 100644 (file)
index 0000000..c13b8cf
--- /dev/null
@@ -0,0 +1,3 @@
+{
+  "main": "main.js"
+}
diff --git a/test/run_pass/require1/package.json b/test/run_pass/require1/package.json
new file mode 100644 (file)
index 0000000..c827db8
--- /dev/null
@@ -0,0 +1,30 @@
+{
+  "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"
+}
diff --git a/test/run_pass/require1/require_add.js b/test/run_pass/require1/require_add.js
new file mode 100644 (file)
index 0000000..bca973a
--- /dev/null
@@ -0,0 +1,24 @@
+/* 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
+*/
+
+var x = require("buffer");
+
+exports.add = function(a, b) {
+  return a + b;
+};
diff --git a/test/run_pass/require1/test_require.js b/test/run_pass/require1/test_require.js
new file mode 100644 (file)
index 0000000..930ec9c
--- /dev/null
@@ -0,0 +1,40 @@
+/* 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(process.platform, false);
+
+var x = require("require_add");
+assert.equal(x.add(1,4), 5);
+
+var str = process.readSource("package.json");
+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");
+
+var pkg1 = require('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('test_index');
+assert.equal(pkg2.add(22, 44), 66);
+assert.equal(pkg2.multi(22, 44), 968);
+assert.equal(pkg2.add2(22, 44), 66);
diff --git a/test/run_pass/test_adc.js b/test/run_pass/test_adc.js
new file mode 100644 (file)
index 0000000..9558717
--- /dev/null
@@ -0,0 +1,85 @@
+/* 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();
+}
+
+var adc0 = adc.open(configuration, function(err) {
+  console.log('ADC initialized');
+
+  if (err) {
+    assert.fail();
+  }
+
+  test1();
+});
+
+// read async test
+function test1() {
+  var loopCnt = 5;
+
+  console.log('test1 start(read async test)');
+  var test1Loop = setInterval(function() {
+    if (--loopCnt < 0) {
+      console.log('test1 complete');
+      clearInterval(test1Loop);
+      test2();
+    } else {
+      adc0.read(function(err, value) {
+        if (err) {
+          console.log('read failed');
+          assert.fail();
+        }
+
+        console.log(value);
+      });
+    }
+  }, 1000);
+}
+
+// read sync test
+function test2() {
+  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);
+}
diff --git a/test/run_pass/test_assert.js b/test/run_pass/test_assert.js
new file mode 100644 (file)
index 0000000..828f171
--- /dev/null
@@ -0,0 +1,89 @@
+/* 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.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');
+}
diff --git a/test/run_pass/test_ble_advertisement.js b/test/run_pass/test_ble_advertisement.js
new file mode 100644 (file)
index 0000000..2cdb910
--- /dev/null
@@ -0,0 +1,40 @@
+/* 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.');
+    });
+  }
+});
diff --git a/test/run_pass/test_ble_setservices.js b/test/run_pass/test_ble_setservices.js
new file mode 100644 (file)
index 0000000..999ee26
--- /dev/null
@@ -0,0 +1,114 @@
+/* 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()
+        ]
+      })
+    ]);
+  }
+});
diff --git a/test/run_pass/test_buffer.js b/test/run_pass/test_buffer.js
new file mode 100644 (file)
index 0000000..edc1e1e
--- /dev/null
@@ -0,0 +1,145 @@
+/* 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);
+
+
+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);
diff --git a/test/run_pass/test_buffer_builtin.js b/test/run_pass/test_buffer_builtin.js
new file mode 100644 (file)
index 0000000..66d3d57
--- /dev/null
@@ -0,0 +1,111 @@
+/* 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);
diff --git a/test/run_pass/test_console.js b/test/run_pass/test_console.js
new file mode 100644 (file)
index 0000000..e60cc3a
--- /dev/null
@@ -0,0 +1,24 @@
+/* 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("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);
diff --git a/test/run_pass/test_cwd.js b/test/run_pass/test_cwd.js
new file mode 100644 (file)
index 0000000..5d8cdad
--- /dev/null
@@ -0,0 +1,17 @@
+/* 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());
diff --git a/test/run_pass/test_dgram_1_server_1_client.js b/test/run_pass/test_dgram_1_server_1_client.js
new file mode 100644 (file)
index 0000000..6f03661
--- /dev/null
@@ -0,0 +1,71 @@
+/* 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);
+});
diff --git a/test/run_pass/test_dgram_1_server_n_clients.js b/test/run_pass/test_dgram_1_server_n_clients.js
new file mode 100644 (file)
index 0000000..8373188
--- /dev/null
@@ -0,0 +1,72 @@
+/* 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);
+});
diff --git a/test/run_pass/test_dgram_address.js b/test/run_pass/test_dgram_address.js
new file mode 100644 (file)
index 0000000..efad184
--- /dev/null
@@ -0,0 +1,63 @@
+/* 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('udp4');
+var server = dgram.createSocket('udp4');
+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);
+});
diff --git a/test/run_pass/test_dgram_broadcast.js b/test/run_pass/test_dgram_broadcast.js
new file mode 100644 (file)
index 0000000..18d06cf
--- /dev/null
@@ -0,0 +1,90 @@
+/* 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);
+});
diff --git a/test/run_pass/test_dgram_multicast_membership.js b/test/run_pass/test_dgram_multicast_membership.js
new file mode 100644 (file)
index 0000000..fff837a
--- /dev/null
@@ -0,0 +1,63 @@
+/* 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);
+});
diff --git a/test/run_pass/test_dgram_multicast_set_multicast_loop.js b/test/run_pass/test_dgram_multicast_set_multicast_loop.js
new file mode 100644 (file)
index 0000000..9838c84
--- /dev/null
@@ -0,0 +1,45 @@
+/* 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);
+});
diff --git a/test/run_pass/test_dns.js b/test/run_pass/test_dns.js
new file mode 100644 (file)
index 0000000..de75547
--- /dev/null
@@ -0,0 +1,58 @@
+/* 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);
+});
diff --git a/test/run_pass/test_dns_lookup.js b/test/run_pass/test_dns_lookup.js
new file mode 100644 (file)
index 0000000..19d996e
--- /dev/null
@@ -0,0 +1,105 @@
+/* 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 with invalid hostname.
+dns.lookup('invalid', 4, function(err, ip, family) {
+  assert.notEqual(err, null);
+  assert.equal(err.code, -3008);
+});
+
+// Test with empty hostname.
+dns.lookup('', 4, function(err, ip, family) {
+  assert.notEqual(err, null);
+  assert.equal(err.code, -3008);
+});
+
+// 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);
diff --git a/test/run_pass/test_events.js b/test/run_pass/test_events.js
new file mode 100644 (file)
index 0000000..ecfe7c0
--- /dev/null
@@ -0,0 +1,179 @@
+/* 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);
+
+
+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||");
diff --git a/test/run_pass/test_exit.js b/test/run_pass/test_exit.js
new file mode 100644 (file)
index 0000000..3f0adc6
--- /dev/null
@@ -0,0 +1,17 @@
+/* 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);
diff --git a/test/run_pass/test_experimental_off.js b/test/run_pass/test_experimental_off.js
new file mode 100644 (file)
index 0000000..43fa20e
--- /dev/null
@@ -0,0 +1,18 @@
+/* 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');
diff --git a/test/run_pass/test_experimental_on.js b/test/run_pass/test_experimental_on.js
new file mode 100644 (file)
index 0000000..5218fed
--- /dev/null
@@ -0,0 +1,18 @@
+/* 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');
diff --git a/test/run_pass/test_fs.js b/test/run_pass/test_fs.js
new file mode 100644 (file)
index 0000000..7c66997
--- /dev/null
@@ -0,0 +1,62 @@
+/* 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 = "../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;
+}
+
+
+// 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
+);
diff --git a/test/run_pass/test_fs1.js b/test/run_pass/test_fs1.js
new file mode 100644 (file)
index 0000000..b670c8d
--- /dev/null
@@ -0,0 +1,48 @@
+/* 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 = "../resources/test1.txt";
+var dstFilePath = "../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);
+  fs.closeSync(fd2);
+
+  assert.equal(bytes1, bytes2);
+
+  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;
+}
diff --git a/test/run_pass/test_fs2.js b/test/run_pass/test_fs2.js
new file mode 100644 (file)
index 0000000..c1af534
--- /dev/null
@@ -0,0 +1,67 @@
+/* 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 = "../resources/test1.txt";
+var dstFilePath = "../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);
diff --git a/test/run_pass/test_fs_exists.js b/test/run_pass/test_fs_exists.js
new file mode 100644 (file)
index 0000000..d376c68
--- /dev/null
@@ -0,0 +1,49 @@
+/* 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 = "../resources/tobeornottobe.txt";
+
+  fs.exists(filePath, function(exists) {
+    assert.equal(exists, true);
+  });
+}
+
+{
+  var filePath = "../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);
+  });
+}
diff --git a/test/run_pass/test_fs_existssync.js b/test/run_pass/test_fs_existssync.js
new file mode 100644 (file)
index 0000000..254eb57
--- /dev/null
@@ -0,0 +1,45 @@
+/* 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 = "../resources/tobeornottobe.txt";
+
+  var result = fs.existsSync(filePath);
+  assert.equal(result, true);
+}
+
+{
+  var filePath = "../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);
+}
diff --git a/test/run_pass/test_fs_mkdir_rmdir.js b/test/run_pass/test_fs_mkdir_rmdir.js
new file mode 100644 (file)
index 0000000..46c1678
--- /dev/null
@@ -0,0 +1,51 @@
+/* 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 = "../resources/test_dir";
+  var sub1 = "../resources/test_dir/file1";
+  var sub2 = "../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);
+    });
+  });
+}
diff --git a/test/run_pass/test_fs_open_close.js b/test/run_pass/test_fs_open_close.js
new file mode 100644 (file)
index 0000000..9269b72
--- /dev/null
@@ -0,0 +1,102 @@
+/* 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 = "../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);
+
+process.on('exit', function() {
+  assert.equal(fs_async_normal_ok, true);
+  assert.equal(fs_async_open_not_exist_ok, true);
+  assert.equal(fs_async_close_bad_fd_ok, true);
+});
diff --git a/test/run_pass/test_fs_readdir.js b/test/run_pass/test_fs_readdir.js
new file mode 100644 (file)
index 0000000..51d3eea
--- /dev/null
@@ -0,0 +1,42 @@
+/* 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 = '../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);
+});
diff --git a/test/run_pass/test_fs_readfile.js b/test/run_pass/test_fs_readfile.js
new file mode 100644 (file)
index 0000000..b024b03
--- /dev/null
@@ -0,0 +1,61 @@
+/* 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 = "../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);
+});
diff --git a/test/run_pass/test_fs_readfilesync.js b/test/run_pass/test_fs_readfilesync.js
new file mode 100644 (file)
index 0000000..94ee18a
--- /dev/null
@@ -0,0 +1,60 @@
+/* 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 = "../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);
diff --git a/test/run_pass/test_fs_rename.js b/test/run_pass/test_fs_rename.js
new file mode 100644 (file)
index 0000000..c4c3d6f
--- /dev/null
@@ -0,0 +1,34 @@
+/* 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 = "../resources/rename.txt";
+var file2 = "../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");
+  });
+});
diff --git a/test/run_pass/test_fs_rename_sync.js b/test/run_pass/test_fs_rename_sync.js
new file mode 100644 (file)
index 0000000..fada5df
--- /dev/null
@@ -0,0 +1,25 @@
+/* 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 = "../resources/rename.txt";
+var file2 = "../resources/rename.txt.sync";
+
+fs.renameSync(file1, file2);
+assert.equal(fs.existsSync(file1), false);
+assert.equal(fs.existsSync(file2), true);
+fs.renameSync(file2, file1);
diff --git a/test/run_pass/test_fs_stat.js b/test/run_pass/test_fs_stat.js
new file mode 100644 (file)
index 0000000..622572d
--- /dev/null
@@ -0,0 +1,48 @@
+/* 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('test_fs_stat.js');
+assert.equal(stats1.isFile(), true);
+assert.equal(stats1.isDirectory(), false);
+
+fs.stat('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('../resources');
+assert.equal(stats2.isDirectory(), true);
+assert.equal(stats2.isFile(), false);
+
+fs.stat('../resources', function(err, stats) {
+  if (!err) {
+    assert.equal(stats.isDirectory(), true);
+    assert.equal(stats.isFile(), false);
+  }
+  else {
+    throw err
+  }
+});
diff --git a/test/run_pass/test_fs_writefile_unlink.js b/test/run_pass/test_fs_writefile_unlink.js
new file mode 100644 (file)
index 0000000..1d370d1
--- /dev/null
@@ -0,0 +1,45 @@
+/* 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 = "../resources/tobeornottobe.txt";
+var file2 = "../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");
+          });
+        });
+      });
+    });
+  });
+});
diff --git a/test/run_pass/test_fs_writefile_unlink_sync.js b/test/run_pass/test_fs_writefile_unlink_sync.js
new file mode 100644 (file)
index 0000000..2a95ddd
--- /dev/null
@@ -0,0 +1,39 @@
+/* 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 = "../resources/tobeornottobe.txt";
+var file2 = "../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);
diff --git a/test/run_pass/test_gpio1.js b/test/run_pass/test_gpio1.js
new file mode 100644 (file)
index 0000000..a7ae87b
--- /dev/null
@@ -0,0 +1,75 @@
+/* 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 gpio10;
+
+if (process.platform === 'linux') {
+  pin = 10;
+  mode = gpio.MODE.NONE;
+} else if (process.platform === 'nuttx') {
+  pin = require('stm32f4dis').pin.PA10;
+  mode = gpio.MODE.PUSHPULL;
+} else {
+  assert.fail();
+}
+
+test1();
+
+gpio10 = 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);
+  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);
+
+  gpio10.write(LED_ON, function(writeErr) {
+    assert.equal(writeErr, null);
+    console.log('gpio write');
+
+    gpio10.read(function(readErr, value) {
+      assert.equal(readErr, null);
+      console.log('gpio read:', value);
+      assert.equal(LED_ON, value);
+
+      setTimeout(function() {
+        gpio10.writeSync(LED_OFF);
+        assert.equal(LED_OFF, gpio10.readSync());
+        gpio10.close();
+      }, 3000);
+    });
+  });
+}
diff --git a/test/run_pass/test_gpio2.js b/test/run_pass/test_gpio2.js
new file mode 100644 (file)
index 0000000..33abe55
--- /dev/null
@@ -0,0 +1,78 @@
+/* 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 = 10;
+  switchPin = 9;
+  ledMode = gpio.MODE.NONE;
+} else if (process.platform === 'nuttx') {
+  var pin = require('stm32f4dis').pin;
+  ledPin = pin.PA10;
+  switchPin = pin.PA8;
+  ledMode = gpio.MODE.PUSHPULL;
+} 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);
+  }
+
+  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);
diff --git a/test/run_pass/test_http_get.js b/test/run_pass/test_http_get.js
new file mode 100644 (file)
index 0000000..7f9ff4d
--- /dev/null
@@ -0,0 +1,98 @@
+/* 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();
diff --git a/test/run_pass/test_http_header.js b/test/run_pass/test_http_header.js
new file mode 100644 (file)
index 0000000..708d8be
--- /dev/null
@@ -0,0 +1,84 @@
+/* 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 () {
+
+    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' }
+
+    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);
+});
diff --git a/test/run_pass/test_httpclient_timeout.js b/test/run_pass/test_httpclient_timeout.js
new file mode 100644 (file)
index 0000000..52b96d4
--- /dev/null
@@ -0,0 +1,51 @@
+/* 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: 3002
+};
+
+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);
+});
diff --git a/test/run_pass/test_httpclient_timeout2.js b/test/run_pass/test_httpclient_timeout2.js
new file mode 100644 (file)
index 0000000..141197c
--- /dev/null
@@ -0,0 +1,63 @@
+/* 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);
+});
diff --git a/test/run_pass/test_httpserver.js b/test/run_pass/test_httpserver.js
new file mode 100644 (file)
index 0000000..fc1fce2
--- /dev/null
@@ -0,0 +1,186 @@
+/* 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 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();
+
+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);
+});
diff --git a/test/run_pass/test_httpserver_timeout.js b/test/run_pass/test_httpserver_timeout.js
new file mode 100644 (file)
index 0000000..32eccee
--- /dev/null
@@ -0,0 +1,48 @@
+/* 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);
+});
diff --git a/test/run_pass/test_i2c.js b/test/run_pass/test_i2c.js
new file mode 100644 (file)
index 0000000..ff0a00b
--- /dev/null
@@ -0,0 +1,54 @@
+/* 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 wire = i2c.open({device: '/dev/i2c-1', address: 0x23}, function(err) {
+  if (err) {
+    throw err;
+  }
+});
+
+wire.write([0x10], function(err) {
+  assert.equal(err, null);
+  console.log('write done');
+});
+
+wire.writeByte(0x10, function(err) {
+  assert.equal(err, null);
+  console.log('writeByte 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.readByte(function(err, res) {
+  assert.equal(err, null);
+  console.log('readByte result: '+res);
+});
+
+wire.readBytes(0x20, 2, function(err, res) {
+  assert.equal(err, null);
+  assert.equal(res.length, 2, 'I2C readBytes failed.(length is not equal)');
+  console.log('readBytes(cmd:0x20, length:2) result: '+res[0]+', '+res[1]);
+});
diff --git a/test/run_pass/test_module_cache.js b/test/run_pass/test_module_cache.js
new file mode 100644 (file)
index 0000000..d2e8029
--- /dev/null
@@ -0,0 +1,22 @@
+/* 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('require1/module_cache.js');
+module_cache.i = 100;
+module_cache = require('require1/module_cache.js');
+
+assert.equal(module_cache.i, 100);
diff --git a/test/run_pass/test_net1.js b/test/run_pass/test_net1.js
new file mode 100644 (file)
index 0000000..3a5df6e
--- /dev/null
@@ -0,0 +1,51 @@
+/* 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");
+});
diff --git a/test/run_pass/test_net10.js b/test/run_pass/test_net10.js
new file mode 100644 (file)
index 0000000..6459cbc
--- /dev/null
@@ -0,0 +1,44 @@
+/* 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 timedout = false;
+var connected = false;
+
+// Try connect to host that is not exist (Reserved address of TEST-NET-1)
+var socket1 = net.createConnection(11111, '192.0.2.1');
+
+socket1.setTimeout(1000);
+
+socket1.on('timeout', function() {
+  timedout = true;
+  socket1.destroy();
+});
+
+socket1.on('error', function() {
+  assert.fail();
+});
+
+socket1.on('connect', function() {
+  connected = true;
+  socket1.destroy();
+});
+
+process.on('exit', function() {
+  assert(timedout);
+  assert(!connected);
+});
diff --git a/test/run_pass/test_net2.js b/test/run_pass/test_net2.js
new file mode 100644 (file)
index 0000000..4f14943
--- /dev/null
@@ -0,0 +1,53 @@
+/* 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");
+});
diff --git a/test/run_pass/test_net3.js b/test/run_pass/test_net3.js
new file mode 100644 (file)
index 0000000..1b34918
--- /dev/null
@@ -0,0 +1,89 @@
+/* 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);
+});
diff --git a/test/run_pass/test_net4.js b/test/run_pass/test_net4.js
new file mode 100644 (file)
index 0000000..d8817a0
--- /dev/null
@@ -0,0 +1,57 @@
+/* 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);
+});
diff --git a/test/run_pass/test_net5.js b/test/run_pass/test_net5.js
new file mode 100644 (file)
index 0000000..1374e1e
--- /dev/null
@@ -0,0 +1,60 @@
+/* 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);
+});
diff --git a/test/run_pass/test_net6.js b/test/run_pass/test_net6.js
new file mode 100644 (file)
index 0000000..0541322
--- /dev/null
@@ -0,0 +1,67 @@
+/* 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");
+});
diff --git a/test/run_pass/test_net7.js b/test/run_pass/test_net7.js
new file mode 100644 (file)
index 0000000..faa4a14
--- /dev/null
@@ -0,0 +1,75 @@
+/* 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();
+    }
+  }
+});
diff --git a/test/run_pass/test_net8.js b/test/run_pass/test_net8.js
new file mode 100644 (file)
index 0000000..f83db72
--- /dev/null
@@ -0,0 +1,73 @@
+/* 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);
+});
diff --git a/test/run_pass/test_net9.js b/test/run_pass/test_net9.js
new file mode 100644 (file)
index 0000000..6bd2dee
--- /dev/null
@@ -0,0 +1,56 @@
+/* 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");
+});
diff --git a/test/run_pass/test_next_tick.js b/test/run_pass/test_next_tick.js
new file mode 100644 (file)
index 0000000..279de36
--- /dev/null
@@ -0,0 +1,41 @@
+/* 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");
+});
diff --git a/test/run_pass/test_process.js b/test/run_pass/test_process.js
new file mode 100644 (file)
index 0000000..292f03a
--- /dev/null
@@ -0,0 +1,28 @@
+/* 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');
+});
diff --git a/test/run_pass/test_pwm.js b/test/run_pass/test_pwm.js
new file mode 100644 (file)
index 0000000..92e9342
--- /dev/null
@@ -0,0 +1,103 @@
+/* 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 = {};
+
+if (process.platform === 'linux') {
+  configuration.pin = 0;
+} else if (process.platform === 'nuttx') {
+  configuration.pin = require('stm32f4dis').pin.PWM1.CH1_1;
+} 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 = pwm.open(configuration, function (err) {
+  console.log('PWM initialized');
+
+  if (err) {
+    console.log('Have an error: ' + err.message);
+    assert.fail();
+  }
+
+  pwm0.setEnable(1, testCb);
+  testPeriods(pwm0, testCb);
+});
+
+function testPeriods(pwm, callback) {
+  var options = periodOptions;
+  console.log('PWM: period test start ');
+  var idx = 0;
+  var period = options.values[idx++];
+  console.log("Period(%d)", period);
+  pwm.setFrequency(1.0 / period, callback);
+  pwm.setDutyCycleSync(options.dutyCycle);
+
+  var loop = setInterval(function () {
+    if (idx == options.values.length) {
+      pwm.setPeriodSync(options.values[0]);
+      clearInterval(loop);
+      console.log('PWM period test complete');
+      testDutyCycles(pwm, callback);
+    } else {
+      period = options.values[idx++];
+      console.log("Period(%d)", period);
+      pwm.setPeriod(period, callback);
+    }
+  }, 1000);
+}
+
+function testDutyCycles(pwm, callback) {
+  var options = dutyOptions;
+
+  console.log('PWM: duty cycle test start');
+  pwm.setFrequencySync(1.0 / options.period);
+
+  var idx = 0;
+  var loop = setInterval(function () {
+    console.log('Duty cycle %d', options.values[idx]);
+    pwm.setDutyCycle(options.values[idx], callback);
+
+    if (++idx == options.values.length) {
+      clearInterval(loop);
+      pwm.setEnableSync(0);
+      console.log('PWM duty cycle test complete');
+    }
+  }, 1000);
+}
diff --git a/test/run_pass/test_spi.js b/test/run_pass/test_spi.js
new file mode 100644 (file)
index 0000000..1805934
--- /dev/null
@@ -0,0 +1,75 @@
+/* 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();
+
+//  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]);
+
+  setTimeout(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);
+
+      spi0.close();
+    });
+  }, 500);
+});
+
+// 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);
+});
diff --git a/test/run_pass/test_stream.js b/test/run_pass/test_stream.js
new file mode 100644 (file)
index 0000000..082cf5f
--- /dev/null
@@ -0,0 +1,77 @@
+/* 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 readable = new Readable();
+var d = "";
+var e = "";
+
+
+readable.on('error', function(err) {
+  e += ".";
+});
+
+readable.on('data', function(data) {
+  d += data.toString();
+});
+
+readable.on('end', function() {
+  e += 'e';
+});
+
+
+readable.pause();
+readable.push('abcde');
+readable.push('12345');
+assert.equal(d, '');
+assert.equal(e, '');
+
+readable.resume();
+assert.equal(d, 'abcde12345');
+assert.equal(e, '');
+
+readable.push('a');
+readable.push('1');
+readable.push('b');
+readable.push('2');
+assert.equal(d, 'abcde12345a1b2');
+assert.equal(e, '');
+
+readable.pause();
+assert.equal(d, 'abcde12345a1b2');
+assert.equal(e, '');
+
+readable.push('c');
+readable.push('3');
+readable.push('d');
+readable.push('4');
+assert.equal(d, 'abcde12345a1b2');
+assert.equal(e, '');
+
+readable.resume();
+assert.equal(d, 'abcde12345a1b2c3d4');
+assert.equal(e, '');
+
+readable.push(null);
+assert.equal(d, 'abcde12345a1b2c3d4');
+assert.equal(e, 'e');
+
+readable.push('push after eof');
+assert.equal(d, 'abcde12345a1b2c3d4');
+assert.equal(e, 'e.');
diff --git a/test/run_pass/test_timers.js b/test/run_pass/test_timers.js
new file mode 100644 (file)
index 0000000..6917acd
--- /dev/null
@@ -0,0 +1,42 @@
+/* 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 timerSequence = '';
+
+var timerA = setTimeout(function() {
+  timerSequence += 'A';
+  timerACnt++;
+}, 1000);
+
+var timerB = setInterval(function() {
+  timerSequence += 'B';
+  timerBCnt++;
+  if (timerBCnt > 5) {
+    clearInterval(timerB);
+  }
+}, 300);
+
+process.on('exit', function(code) {
+  assert.equal(code, 0);
+  assert.equal(timerACnt, 1);
+  assert.equal(timerBCnt, 6);
+  assert.equal(timerSequence.length, 7);
+});
diff --git a/test/run_pass/test_timers2.js b/test/run_pass/test_timers2.js
new file mode 100644 (file)
index 0000000..587f57c
--- /dev/null
@@ -0,0 +1,61 @@
+/* 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);
+});
diff --git a/test/run_pass/test_uart.js b/test/run_pass/test_uart.js
new file mode 100644 (file)
index 0000000..24b0643
--- /dev/null
@@ -0,0 +1,56 @@
+/* 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 = {
+  device: '/dev/ttyUSB0',
+  baudRate: 115200,
+  dataBits: 8
+};
+
+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.closeSync();
+      console.log('close done');
+    }
+  });
+
+  serial.writeSync("Hello IoT.js.\n\r");
+
+  serial.write("Hello there?\n\r", function(err) {
+    assert.equal(err, null);
+    console.log('write done');
+    write = 1;
+
+    if (read && write) {
+      serial.closeSync();
+      console.log('close done');
+    }
+  });
+});
diff --git a/test/run_pass/test_uncaught1.js b/test/run_pass/test_uncaught1.js
new file mode 100644 (file)
index 0000000..48d5877
--- /dev/null
@@ -0,0 +1,41 @@
+/* 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();
diff --git a/test/run_pass/test_uncaught2.js b/test/run_pass/test_uncaught2.js
new file mode 100644 (file)
index 0000000..84180bd
--- /dev/null
@@ -0,0 +1,37 @@
+/* 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';
diff --git a/test/run_pass/test_uncaught_error1.js b/test/run_pass/test_uncaught_error1.js
new file mode 100644 (file)
index 0000000..1420615
--- /dev/null
@@ -0,0 +1,26 @@
+/* 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);
diff --git a/test/run_pass/test_uncaught_error2.js b/test/run_pass/test_uncaught_error2.js
new file mode 100644 (file)
index 0000000..0eb61a6
--- /dev/null
@@ -0,0 +1,35 @@
+/* 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');
diff --git a/test/test_stat.js b/test/test_stat.js
new file mode 100644 (file)
index 0000000..1b43dc2
--- /dev/null
@@ -0,0 +1,80 @@
+/* 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');
+
+try{ // fs.statSync throw ex for non-existing file
+  var statbuf1 = fs.statSync('../test');
+  console.log("../test dev : " + statbuf1.dev);
+  console.log("../test mode : " + statbuf1.mode);
+  console.log("../test size : " + statbuf1.size);
+
+  if(statbuf1.isDirectory()){
+    console.log("../test is a directory");
+  }
+  else {
+    console.log("../test is not a directory");
+  }
+}
+catch(ex){}
+
+
+try{ // fs.statSync throw ex for non-existing file
+  var statbuf2 = fs.statSync('test_stat.js');
+
+  console.log("test_stat.js dev : " + statbuf2.dev);
+  console.log("test_stat.js mode : " + statbuf2.mode);
+  console.log("test_stat.js size : " + statbuf2.size);
+
+  if(statbuf2.isDirectory()){
+    console.log("test_stat.js is a directory");
+  }
+  else {
+    console.log("test_stat.js is not a directory");
+  }
+}
+catch(ex){}
+
+try{ // fs.statSync throw ex for non-existing file
+  console.log("non-existing file(non_existing.js) statSync tried.");
+  var statbuf3 = fs.statSync('non_existing.js');
+}
+catch(ex){
+  console.log("but, failed.");
+}
+
+function statcallback(err, statbuf) {
+  console.log("statcallback called");
+  if(err){
+    console.log("stat async call error");
+    return;
+  }
+
+  if(statbuf.isDirectory()){
+    console.log("async stat for test_stat.js is a directory");
+  }
+  else {
+    console.log("async stat for test_stat.js is not a directory");
+  }
+
+}
+
+try {
+  fs.stat('test_stat.js', statcallback);
+}
+catch(ex) {
+  console.log("stat async call error");
+}
diff --git a/test/testsets.json b/test/testsets.json
new file mode 100644 (file)
index 0000000..ee5b32f
--- /dev/null
@@ -0,0 +1,91 @@
+{
+  "run_pass":  [
+    { "name": "test_adc.js", "skip": ["all"], "reason": "need to setup test environment" },
+    { "name": "test_assert.js" },
+    { "name": "test_ble.js", "skip": ["all"], "reason": "need to setup test environment" },
+    { "name": "test_buffer_builtin.js" },
+    { "name": "test_buffer.js" },
+    { "name": "test_console.js" },
+    { "name": "test_cwd.js", "skip": ["all"], "reason": "this test had @STDOUT=COMMAND[pwd], but there's no way to check out current directory path with js driver. So it skips temporarily." },
+    { "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_dns.js", "skip": ["nuttx"], "reason": "not implemented for nuttx" },
+    { "name": "test_dns_lookup.js", "skip": ["nuttx"], "reason": "not implemented for nuttx" },
+    { "name": "test_events.js", "skip": ["nuttx"], "reason": "not implemented for nuttx" },
+    { "name": "test_experimental_off.js", "skip": ["experimental"], "reason": "needed if testing stablity is set with stable" },
+    { "name": "test_experimental_on.js", "skip": ["stable"], "reason": "needed if testing stablity is set with experimental" },
+    { "name": "test_exit.js", "skip": ["all"], "reason": "driver can not run with test which checks out process.exit events" },
+    { "name": "test_fs_exists.js", "skip": ["nuttx"], "reason": "not implemented for nuttx" },
+    { "name": "test_fs_existssync.js", "skip": ["nuttx"], "reason": "not implemented for nuttx" },
+    { "name": "test_fs_mkdir_rmdir.js", "skip": ["nuttx"], "reason": "not implemented for nuttx" },
+    { "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", "skip": ["nuttx"], "reason": "not implemented for nuttx" },
+    { "name": "test_fs_readfilesync.js", "skip": ["nuttx"], "reason": "not implemented for nuttx" },
+    { "name": "test_fs_rename.js" },
+    { "name": "test_fs_rename_sync.js" },
+    { "name": "test_fs_stat.js", "skip": ["nuttx"], "reason": "not implemented for nuttx" },
+    { "name": "test_fs_writefile_unlink.js" },
+    { "name": "test_fs_writefile_unlink_sync.js" },
+    { "name": "test_fs.js", "skip": ["nuttx"], "reason": "not implemented for nuttx" },
+    { "name": "test_fs1.js", "skip": ["nuttx"], "reason": "not implemented for nuttx" },
+    { "name": "test_fs2.js", "skip": ["nuttx"], "reason": "not implemented for nuttx" },
+    { "name": "test_gpio1.js", "skip": ["all"], "reason": "needs hardware" },
+    { "name": "test_gpio2.js", "skip": ["all"], "reason": "need user input"},
+    { "name": "test_http_get.js", "timeout": 20, "skip": ["nuttx"], "reason": "not implemented for nuttx" },
+    { "name": "test_http_header.js", "skip": ["nuttx"], "reason": "not implemented for nuttx" },
+    { "name": "test_httpclient_timeout.js", "timeout": 10, "skip": ["nuttx"], "reason": "not implemented for nuttx" },
+    { "name": "test_httpclient_timeout2.js", "timeout": 15, "skip": ["nuttx"], "reason": "not implemented for nuttx" },
+    { "name": "test_httpserver_timeout.js", "timeout": 10, "skip": ["nuttx"], "reason": "not implemented for nuttx" },
+    { "name": "test_httpserver.js", "timeout": 20, "skip": ["nuttx"], "reason": "not implemented for nuttx" },
+    { "name": "test_i2c.js", "skip": ["all"], "reason": "need to setup test environment" },
+    { "name": "test_module_cache.js", "skip": ["nuttx"], "reason": "not implemented for nuttx" },
+    { "name": "test_net1.js" },
+    { "name": "test_net2.js" },
+    { "name": "test_net3.js", "timeout": 20, "skip": ["nuttx"], "reason": "requires too many socket descriptors and too large buffers" },
+    { "name": "test_net4.js" },
+    { "name": "test_net5.js" },
+    { "name": "test_net6.js" },
+    { "name": "test_net7.js", "skip": ["nuttx"], "reason": "requires too many socket descriptors" },
+    { "name": "test_net8.js" },
+    { "name": "test_net9.js" },
+    { "name": "test_net10.js" },
+    { "name": "test_next_tick.js" },
+    { "name": "test_process.js" },
+    { "name": "test_pwm.js", "skip": ["all"], "reason": "need to setup test environment" },
+    { "name": "test_stream.js" },
+    { "name": "test_timers.js", "timeout": 10 },
+    { "name": "test_timers2.js" },
+    { "name": "test_uart.js", "skip": ["all"], "reason": "need to setup test environment" },
+    { "name": "test_uncaught1.js", "uncaught": true },
+    { "name": "test_uncaught2.js", "uncaught": true },
+    { "name": "test_uncaught_error1.js", "uncaught": true },
+    { "name": "test_uncaught_error2.js", "uncaught": true }
+  ],
+  "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" }
+  ],
+  "run_fail":  [
+    { "name": "assert_fail1.js", "expected-failure": true },
+    { "name": "assert_fail2.js", "expected-failure": true },
+    { "name": "assert_fail3.js", "expected-failure": true },
+    { "name": "fs_callbacks_called.js", "expected-failure": true },
+    { "name": "process_exit1.js", "expected-failure": true },
+    { "name": "process_exit2.js", "expected-failure": true },
+    { "name": "process_exitcode1.js", "expected-failure": true },
+    { "name": "process_exitcode2.js", "expected-failure": true },
+    { "name": "require_fail1.js", "expected-failure": true },
+    { "name": "runtime_error1.js", "expected-failure": true },
+    { "name": "syntax_fail1.js", "expected-failure": true },
+    { "name": "uncaught_error_event.js", "expected-failure": true }
+  ]
+}
diff --git a/test/tmp/README b/test/tmp/README
new file mode 100644 (file)
index 0000000..bc2f0ba
--- /dev/null
@@ -0,0 +1 @@
+This directory is for temporary files will be generated during build test.
diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt
new file mode 100644 (file)
index 0000000..5bb57af
--- /dev/null
@@ -0,0 +1,73 @@
+# 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: <arch>-<os>)")
+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)
+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
+  -std=gnu99
+)
+
+include(ExternalProject)
+
+# Include external projects
+include(cmake/jerry.cmake)
+include(cmake/http-parser.cmake)
+include(cmake/libtuv.cmake)
+
+include(cmake/iotjs.cmake)
+
diff --git a/tools/LICENSE b/tools/LICENSE
new file mode 100644 (file)
index 0000000..5146304
--- /dev/null
@@ -0,0 +1,218 @@
+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.
+
+
+                                 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:
+
diff --git a/tools/README.md b/tools/README.md
new file mode 100644 (file)
index 0000000..c6ca04a
--- /dev/null
@@ -0,0 +1,66 @@
+# 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)
+
+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)
+
+## 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.
+
+> 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:
diff --git a/tools/__init__.py b/tools/__init__.py
new file mode 100644 (file)
index 0000000..ef65bee
--- /dev/null
@@ -0,0 +1 @@
+# Required for Python to search this directory for module files
diff --git a/tools/apt-get-install-arm.sh b/tools/apt-get-install-arm.sh
new file mode 100755 (executable)
index 0000000..e6c6d59
--- /dev/null
@@ -0,0 +1,19 @@
+#!/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
diff --git a/tools/apt-get-install-deps.sh b/tools/apt-get-install-deps.sh
new file mode 100755 (executable)
index 0000000..e7045d7
--- /dev/null
@@ -0,0 +1,19 @@
+#!/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
diff --git a/tools/apt-get-install-nuttx.sh b/tools/apt-get-install-nuttx.sh
new file mode 100755 (executable)
index 0000000..012d01f
--- /dev/null
@@ -0,0 +1,21 @@
+#!/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
diff --git a/tools/apt-get-install-tizen.sh b/tools/apt-get-install-tizen.sh
new file mode 100755 (executable)
index 0000000..cb6d460
--- /dev/null
@@ -0,0 +1,23 @@
+#!/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
diff --git a/tools/apt-get-install-travis-i686.sh b/tools/apt-get-install-travis-i686.sh
new file mode 100755 (executable)
index 0000000..2dd6931
--- /dev/null
@@ -0,0 +1,20 @@
+#!/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
diff --git a/tools/brew-install-deps.sh b/tools/brew-install-deps.sh
new file mode 100755 (executable)
index 0000000..7f4e9af
--- /dev/null
@@ -0,0 +1,29 @@
+#!/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
diff --git a/tools/build.config b/tools/build.config
new file mode 100644 (file)
index 0000000..4f1c14c
--- /dev/null
@@ -0,0 +1,111 @@
+{
+  "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": ["-O2"],
+      "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": ["adc", "ble", "dgram", "gpio", "i2c", "pwm", "spi", 
+                "stm32f4dis", "uart"]
+  }
+}
diff --git a/tools/build.py b/tools/build.py
new file mode 100755 (executable)
index 0000000..090302a
--- /dev/null
@@ -0,0 +1,484 @@
+#!/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('--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)
+    include_dirs.extend(options.external_include_dir)
+    cmake_args.append("-DEXTERNAL_INCLUDE_DIR='%s'" % (' '.join(include_dirs)))
+
+    # set target board
+    if options.target_board == 'stm32f4dis':
+        cmake_args.append('-DTARGET_BOARD=stm32f4dis')
+
+    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 JerryScript 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)
+
+    # --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))
diff --git a/tools/check_license.py b/tools/check_license.py
new file mode 100755 (executable)
index 0000000..d9ddece
--- /dev/null
@@ -0,0 +1,40 @@
+#!/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))
diff --git a/tools/check_signed_off.sh b/tools/check_signed_off.sh
new file mode 100755 (executable)
index 0000000..584da04
--- /dev/null
@@ -0,0 +1,111 @@
+#!/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
diff --git a/tools/check_test.js b/tools/check_test.js
new file mode 100644 (file)
index 0000000..000ee02
--- /dev/null
@@ -0,0 +1,262 @@
+/* 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) {
+      process.chdir(this.root);
+      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;
+  process.chdir(util.absolutePath(dirname));
+  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 content = fs.readFileSync(util.absolutePath(test['name'])).toString();
+  return content;
+};
+
+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();
+}
diff --git a/tools/check_tidy.py b/tools/check_tidy.py
new file mode 100755 (executable)
index 0000000..0cb5a49
--- /dev/null
@@ -0,0 +1,222 @@
+#!/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']
+    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)
diff --git a/tools/cmake/config/arm-linux.cmake b/tools/cmake/config/arm-linux.cmake
new file mode 100644 (file)
index 0000000..974b541
--- /dev/null
@@ -0,0 +1,22 @@
+# 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)
diff --git a/tools/cmake/config/arm-nuttx.cmake b/tools/cmake/config/arm-nuttx.cmake
new file mode 100644 (file)
index 0000000..6ad88b8
--- /dev/null
@@ -0,0 +1,22 @@
+# 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 EXTERNAL)
+set(CMAKE_SYSTEM_PROCESSOR armv7l)
+
+set(EXTERNAL_CMAKE_C_COMPILER arm-none-eabi-gcc)
+
+CMAKE_FORCE_C_COMPILER(${EXTERNAL_CMAKE_C_COMPILER} GNU)
diff --git a/tools/cmake/config/arm-tizen.cmake b/tools/cmake/config/arm-tizen.cmake
new file mode 100644 (file)
index 0000000..cf41e48
--- /dev/null
@@ -0,0 +1,32 @@
+# 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()
diff --git a/tools/cmake/config/arm-tizenrt.cmake b/tools/cmake/config/arm-tizenrt.cmake
new file mode 100644 (file)
index 0000000..39611ef
--- /dev/null
@@ -0,0 +1,22 @@
+# 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 EXTERNAL)
+set(CMAKE_SYSTEM_PROCESSOR armv7l)
+
+set(EXTERNAL_CMAKE_C_COMPILER arm-none-eabi-gcc)
+
+CMAKE_FORCE_C_COMPILER(${EXTERNAL_CMAKE_C_COMPILER} GNU)
diff --git a/tools/cmake/config/i686-linux.cmake b/tools/cmake/config/i686-linux.cmake
new file mode 100644 (file)
index 0000000..c4c7f56
--- /dev/null
@@ -0,0 +1,18 @@
+# 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)
diff --git a/tools/cmake/config/x86_64-darwin.cmake b/tools/cmake/config/x86_64-darwin.cmake
new file mode 100644 (file)
index 0000000..e3c4bc4
--- /dev/null
@@ -0,0 +1,18 @@
+# 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)
diff --git a/tools/cmake/config/x86_64-linux.cmake b/tools/cmake/config/x86_64-linux.cmake
new file mode 100644 (file)
index 0000000..79cf370
--- /dev/null
@@ -0,0 +1,18 @@
+# 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)
diff --git a/tools/cmake/http-parser.cmake b/tools/cmake/http-parser.cmake
new file mode 100644 (file)
index 0000000..67128c3
--- /dev/null
@@ -0,0 +1,47 @@
+# 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}
+    -DBUILDTYPE=${CMAKE_BUILD_TYPE} # TODO: use CMAKE_BUILD_TYPE in sub-project
+    -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})
diff --git a/tools/cmake/iotjs.cmake b/tools/cmake/iotjs.cmake
new file mode 100644 (file)
index 0000000..5cf0ad7
--- /dev/null
@@ -0,0 +1,283 @@
+# 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
+set(IOTJS_PLATFORM_SRC)
+if("${CMAKE_SYSTEM_NAME}" MATCHES "Linux|Tizen")
+  file(GLOB IOTJS_PLATFORM_LINUX_SRC
+       ${IOTJS_SOURCE_DIR}/platform/iotjs_*-linux.c)
+  list(APPEND IOTJS_PLATFORM_SRC ${IOTJS_PLATFORM_LINUX_SRC})
+  # in case of Tizen force the platform to Linux
+  string(REGEX REPLACE "tizen$" "linux"
+         PLATFORM_DESCRIPTOR "${PLATFORM_DESCRIPTOR}")
+endif()
+
+# Board Configuration (not module)
+if(DEFINED TARGET_BOARD)
+  string(TOLOWER "${TARGET_BOARD}" BOARD_DESCRIPTOR)
+
+  if("${BOARD_DESCRIPTOR}" STREQUAL "stm32f4dis")
+    set(BOARD_DESCRIPTOR stm32)
+  endif()
+
+  set(BOARD_SRC ${IOTJS_SOURCE_DIR}/platform/${PLATFORM_DESCRIPTOR})
+  set(BOARD_SRC ${BOARD_SRC}/iotjs_[^module]*${BOARD_DESCRIPTOR}.c)
+  file(GLOB IOTJS_BOARD_SRC ${BOARD_SRC})
+  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
+          --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}/module/*.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}/module/iotjs_module_${module}.c)
+  if(EXISTS "${BASE_MODULE_SRC}")
+    list(APPEND IOTJS_MODULE_SRC ${BASE_MODULE_SRC})
+  endif()
+
+  # check if there is an extra platform support code for the module
+  # PLATFORM_DESCRIPTOR is <arch>-<os>  (eg.: x86_64-linux)
+  # ../platform/<arch>-<os>/iotjs_module_<module> ...
+  set(PLATFORM_MODULE_BASE ${PLATFORM_SRC}_${module}-${PLATFORM_DESCRIPTOR})
+  set(PLATFORM_MODULE_SRC ${PLATFORM_MODULE_BASE}.c)
+  if(VERBOSE)
+    message("Checking platform file: ${PLATFORM_MODULE_SRC}")
+  endif()
+  if(EXISTS "${PLATFORM_MODULE_SRC}")
+    list(APPEND IOTJS_MODULE_SRC ${PLATFORM_MODULE_SRC})
+    list(APPEND IOTJS_PLATFORM_SUPPORT ${MODULE})
+  endif()
+
+  # check if there is an extra board support code for the module
+  # BOARD_DESCRIPTOR is eg.: stm32
+  if(DEFINED BOARD_DESCRIPTOR)
+    set(BOARD_MODULE_SRC "${PLATFORM_MODULE_BASE}-${BOARD_DESCRIPTOR}.c")
+    if(VERBOSE)
+      message("Checking module file: ${BOARD_MODULE_SRC}")
+    endif()
+    if(EXISTS "${BOARD_MODULE_SRC}")
+      list(APPEND IOTJS_MODULE_SRC ${BOARD_MODULE_SRC})
+      list(APPEND IOTJS_MODULE_SUPPORT ${MODULE})
+    endif()
+  endif()
+  string(TOUPPER ${module} module)
+
+  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 BOARD_DESCRIPTOR)
+      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}
+  ${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()
diff --git a/tools/cmake/jerry.cmake b/tools/cmake/jerry.cmake
new file mode 100644 (file)
index 0000000..891b5bf
--- /dev/null
@@ -0,0 +1,143 @@
+# 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_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<KEY>=<KEY_Value>
+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)
+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 "LINUX|TIZEN|DARWIN")
+  list(APPEND JERRY_LIBS m)
+  list(APPEND DEPS_LIB_JERRY_ARGS
+    -DJERRY_LIBC=OFF
+    -DJERRY_LIBM=OFF)
+elseif("${TARGET_OS}" MATCHES "TIZENRT")
+  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}
+  )
+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()
+
+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 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)
+
+set(JERRY_PORT_DIR ${DEPS_LIB_JERRY_SRC}/targets/default)
+set(JERRY_INCLUDE_DIR ${DEPS_LIB_JERRY}/jerry-core)
diff --git a/tools/cmake/libtuv.cmake b/tools/cmake/libtuv.cmake
new file mode 100644 (file)
index 0000000..40eb22a
--- /dev/null
@@ -0,0 +1,55 @@
+# 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()
diff --git a/tools/common_js/logger.js b/tools/common_js/logger.js
new file mode 100644 (file)
index 0000000..043eb31
--- /dev/null
@@ -0,0 +1,58 @@
+/* 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;
diff --git a/tools/common_js/module/console.js b/tools/common_js/module/console.js
new file mode 100644 (file)
index 0000000..4aac72a
--- /dev/null
@@ -0,0 +1,29 @@
+/* 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();
diff --git a/tools/common_js/option_parser.js b/tools/common_js/option_parser.js
new file mode 100644 (file)
index 0000000..dbdcc8b
--- /dev/null
@@ -0,0 +1,89 @@
+/* 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;
diff --git a/tools/common_js/util.js b/tools/common_js/util.js
new file mode 100644 (file)
index 0000000..ca79704
--- /dev/null
@@ -0,0 +1,29 @@
+/* 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;
diff --git a/tools/common_py/__init__.py b/tools/common_py/__init__.py
new file mode 100644 (file)
index 0000000..ef65bee
--- /dev/null
@@ -0,0 +1 @@
+# Required for Python to search this directory for module files
diff --git a/tools/common_py/path.py b/tools/common_py/path.py
new file mode 100644 (file)
index 0000000..b00ca52
--- /dev/null
@@ -0,0 +1,59 @@
+# 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')
diff --git a/tools/common_py/system/__init__.py b/tools/common_py/system/__init__.py
new file mode 100644 (file)
index 0000000..ef65bee
--- /dev/null
@@ -0,0 +1 @@
+# Required for Python to search this directory for module files
diff --git a/tools/common_py/system/executor.py b/tools/common_py/system/executor.py
new file mode 100644 (file)
index 0000000..a8d721e
--- /dev/null
@@ -0,0 +1,67 @@
+# 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)))
diff --git a/tools/common_py/system/filesystem.py b/tools/common_py/system/filesystem.py
new file mode 100644 (file)
index 0000000..7f47075
--- /dev/null
@@ -0,0 +1,385 @@
+# 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)
diff --git a/tools/common_py/system/platform.py b/tools/common_py/system/platform.py
new file mode 100644 (file)
index 0000000..5f7c7f3
--- /dev/null
@@ -0,0 +1,33 @@
+# 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
diff --git a/tools/docs/License.md b/tools/docs/License.md
new file mode 100644 (file)
index 0000000..3ef9f7d
--- /dev/null
@@ -0,0 +1,14 @@
+### 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)
diff --git a/tools/docs/README.md b/tools/docs/README.md
new file mode 100644 (file)
index 0000000..c131ac0
--- /dev/null
@@ -0,0 +1,18 @@
+Welcome 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)
+<br>
+
+
+### [Getting Started](help/Getting-Started.md) - Developer guide
+### [Getting Involved](help/Getting-involved.md)
+### Roadmap(TBD)
diff --git a/tools/docs/api/IoT.js-API-ADC.md b/tools/docs/api/IoT.js-API-ADC.md
new file mode 100644 (file)
index 0000000..e755836
--- /dev/null
@@ -0,0 +1,130 @@
+### Platform Support
+
+The following shows ADC module APIs available for each platform.
+
+|  | Linux<br/>(Ubuntu) | Raspbian<br/>(Raspberry Pi) | Nuttx<br/>(STM32F4-Discovery) |
+| :---: | :---: | :---: | :---: |
+| adc.open | O | O | O |
+| adcpin.read | O | O | O |
+| adcpin.readSync | O | O | O |
+| adcpin.close | O | O | O |
+| adcpin.closeSync | O | O | O |
+
+
+## Contents
+* [Pin](#pin)
+* [ADC](#adc)
+  * [Constructor](#adc-constructor)
+    * [`new ADC()`](#adc-new)
+  * [Prototype methods](#adc-prototype-methods)
+    * [`adc.open(configuration[, callback])`](#adc-open)
+* [ADCPin](#adcpin)
+  * [Prototype methods](#adcpin-prototype-methods)
+    * [`adcpin.read([callback])`](#adcpin-read)
+    * [`adcpin.readSync()`](#adcpin-read-sync)
+    * [`adcpin.close([callback])`](#adcpin-close)
+    * [`adcpin.closeSync()`](#adcpin-close-sync)
+
+## `pin` <a name="pin"></a>
+On Nuttx, you have to know pin number that is defined in target board module. For more module information, please see below list.
+  * [STM32F4-discovery](../../targets/nuttx-stm32f4/Stm32f4dis.md#adc-pin)
+
+## Class: ADC <a name="adc"></a>
+
+
+## Constructor <a name="adc-constructor"></a>
+
+
+### `new ADC()` <a name="adc-new"></a>
+
+Returns a new ADC object which can open ADC pin.
+
+
+## Prototype methods <a name="adc-prototype-methods"></a>
+
+
+### `adc.open(configuration[, callback])` <a name="adc-open"></a>
+* `configuration <Object>`
+  * `device <String>`, mandatory configuration on Linux
+  * `pin <Number>`, mandatory configuration on Nuttx
+* `callback <Function(err: Error | null)>`
+* Returns: `<ADCPin>`
+
+Opens 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 <a name="adcpin"></a>
+
+
+## Prototype methods <a name="adcpin-prototype-methods"></a>
+
+
+### `adcpin.read([callback])` <a name="adcpin-read"></a>
+* `callback <Function(err: Error | null, value: Number)>`
+
+Reads the analog value from pin asynchronously.
+
+`callback` will be called after read the analog value.
+
+**Example**
+```js
+adc0.read(function(err, value) {
+  if (err) {
+    throw err;
+  }
+  console.log('value:', value);
+});
+```
+
+
+### `adcpin.readSync()` <a name="adcpin-read-sync"></a>
+* Return: `<Number>`, analog value
+
+Reads the analog value from pin synchronously.
+
+**Example**
+```js
+var value = adc0.readSync();
+console.log('value:', value);
+```
+
+
+### `adcpin.close([callback])` <a name="adcpin-close"></a>
+* `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.clsoe(function(err) {
+  if (err) {
+    throw err;
+  }
+});
+```
+
+
+### `adcpin.closeSync()` <a name="adcpin-close-sync"></a>
+
+Closes ADC pin synchronously. This function must be called after the work of ADC finished.
+
+**Example**
+```js
+adc0.clsoeSync();
+console.log('adc pin is closed');
+```
diff --git a/tools/docs/api/IoT.js-API-Assert.md b/tools/docs/api/IoT.js-API-Assert.md
new file mode 100644 (file)
index 0000000..eaa1a33
--- /dev/null
@@ -0,0 +1,64 @@
+## Module: Assert
+
+Assert module is for writing test for applications.
+
+## AssertionError
+Assert module will produce `AssertionError` in case of assertion failure. `AssertionError` inherits standard `Error` thus it has properties provided by `Error` object including additional properties.
+
+### Properties
+
+
+#### actual
+This property contains the actual value.
+
+
+#### message
+The error message.
+
+
+#### expected
+This property contains the expected value.
+
+
+#### name
+The name of `AssertionError` is 'AssertionError` this is fixed.
+
+
+#### operator
+This property contains the operator used for evaluating `actual` with `expected`.
+
+
+## Assert
+You can get assert module by `require('assert')` the module provide.
+
+
+#### assert(value, message)
+Test if `value` is true, it throws an `AssertionError` exception if `value` evaluates `false`.
+
+
+#### assert.doesNotThrows(block, message)
+Test if the given `block` does not throw any exception, if not, it throws an exception.
+
+
+#### assert.equal(actual, expected, message)
+Test if `actual == expected` is evaluated to `true`, if not, it throws an exception.
+
+
+#### assert.fail(actual, expected, message, operator)
+Throw an `AssertionError` exception.
+
+
+#### assert.notEqual(actual, expected, message)
+Test if `actual != expected` is evaluated to `true`, if not, it throws an exception.
+
+
+#### assert.notStrictEqual(actual, expected, message)
+Test if `actual !== expected` is evaluated to `true`, if not, it throws an exception.
+
+
+#### assert.strictEqual(actual, expected, message)
+Test if `actual === expected` is evaluated to `true`, if not, it throws an exception.
+
+
+#### assert.throws(block, expected, message)
+Test if the given `block` throws an `expected` error, if not, it throws an exception.
diff --git a/tools/docs/api/IoT.js-API-BLE.md b/tools/docs/api/IoT.js-API-BLE.md
new file mode 100644 (file)
index 0000000..b0695fb
--- /dev/null
@@ -0,0 +1,42 @@
+## Module: ble
+
+### Platform Support
+
+The following shows ble module APIs available for each platform.
+
+|  | Linux<br/>(Ubuntu) | Raspbian<br/>(Raspberry Pi) | Nuttx<br/>(STM32F4-Discovery) |
+| :---: | :---: | :---: | :---: |
+| ble.startAdvertising | O | O | X |
+| ble.stopAdvertising | O | O | X |
+| ble.setServices | O | O | X |
+
+### Events
+
+#### `'stateChange'`
+* `callback: Function(state)`
+
+  * `state: String` - "unknown" | "resetting" | "unsupported" | "unauthorized" | "poweredOff" | "poweredOn"
+
+Emitted when adapter state is changed.
+
+
+### Methods
+
+#### ble.startAdvertising(name, serviceUuids[, callback(error)])
+* `name: String` - maximum 26 bytes
+* `serviceUuids: Array`
+  * 1 128-bit service UUID
+  * 1 128-bit service UUID + 2 16-bit service UUIDs
+  * 7 16-bit service UUID
+* `callback: Function(error)`
+
+Start advertising.
+
+ble.state must be poweredOn before advertising is started. 
+ble.on('stateChange', callback(state)); can be used register for state change events.
+
+
+#### ble.stopAdvertising(callback)
+* `callback: Function()`
+
+Stop advertising.
diff --git a/tools/docs/api/IoT.js-API-Buffer.md b/tools/docs/api/IoT.js-API-Buffer.md
new file mode 100644 (file)
index 0000000..9b16c06
--- /dev/null
@@ -0,0 +1,507 @@
+## Contents
+
+* [Buffer](#buffer)
+  * [Constructor](#constructor)
+    * [`new Buffer(size)`](#new-buffer-size)
+    * [`new Buffer(buffer)`](#new-buffer-buffer)
+    * [`new Buffer(str[, encoding]))`](#new-buffer-str)
+    * [`new Buffer(array)`](#new-buffer-array)
+  * [Class Methods](#class-methods)
+    * [`Buffer.byteLength(str[, encoding])`](#buffer-byte-length)
+    * [`Buffer.concat(list)`](#buffer-concat)
+    * [`Buffer.isBuffer(obj)`](#buffer-isbuffer)
+  * [Properties](#properties)
+    * [`buf.length`](#buf-length)
+  * [Prototype methods](#prototype-methods)
+    * [`buf.compare(otherBuffer)`](#buf-compare)
+    * [`buf.copy(targetBuffer[,targetStart[,sourceStart[,sourceEnd]]])`](#buf-copy)
+    * [`buf.equals(otherBuffer)`](#buf-equals)
+    * [`buf.fill(value)`](#buf-fill)
+    * [`buf.slice([start[,end]])`](#buf-slice)
+    * [`buf.toString([start[,end]])`](#buf-to-string)
+    * [`buf.write(string[,offset[,length]])`](#buf-write)
+    * [`buf.writeUInt8(value, offset[, noAssert])`](#buf-write-uint8)
+    * [`buf.writeUInt16LE(value, offset[, noAssert])`](#buf-write-uint16le)
+    * [`buf.writeUInt32LE(value, offset[, noAssert])`](#buf-write-uint32le)
+    * [`buf.readInt8(offset[, noAssert])`](#buf-read-int8)
+    * [`buf.readUInt8(offset[, noAssert])`](#buf-read-uint8)
+    * [`buf.readUInt16LE(offset[, noAssert])`](#buf-read-uint16)
+
+
+## Class: Buffer <a name="buffer"></a>
+
+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 <a name="constructor"></a>
+
+
+### `new Buffer(size)` <a name="new-buffer-size"></a>
+* `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)` <a name="new-buffer-buffer"></a>
+* `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]))` <a name="new-buffer-str"></a>
+* `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))
+console.log(buffer); // prints 1
+var buffer = new Buffer(String.fromCharCode(128))
+console.log(buffer); // prints 2
+var buffer = new Buffer(String.fromCharCode(2048))
+console.log(buffer); // prints 3
+
+var buffer = new Buffer('4142', 'hex')
+console.log(buffer); // prints AB
+```
+
+
+### `new Buffer(array)` <a name="new-buffer-array"></a>
+* `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])
+console.log(buffer); // prints AAAA
+```
+
+
+## Class Methods <a name="class-methods"></a>
+
+
+### `Buffer.byteLength(str[, encoding])` <a name="buffer-byte-length"></a>
+* `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)` <a name="buffer-concat"></a>
+* `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)` <a name="buffer-isbuffer"></a>
+* `obj <Object>`, a generic object
+* Returns: `<Boolean>`
+
+Returns `true` if `obj` is an instance of `Buffer`. Returns
+`false` otherwise.
+
+**Example**
+
+```js
+var Buffer = require('buffer');
+
+console.log(Buffer.isBuffer(new Buffer(1))); // prints true
+console.log(Buffer.isBuffer('str')); // prints false
+```
+
+
+## Properties <a name="properties"></a>
+
+
+### `buf.length` <a name="buf-length"></a>
+* `<Integer>`, 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
+```
+
+
+## Prototype methods <a name="prototype-methods"></a>
+
+
+### `buf.compare(otherBuffer)` <a name="buf-compare"></a>
+* `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');
+
+console.log(buffer1.compare(buffer1)); // prints 0
+console.log(buffer1.compare(buffer2)); // prints 1
+console.log(buffer1.compare(buffer3)); // prints -1
+```
+
+
+### `buf.copy(targetBuffer[,targetStart[,sourceStart[,sourceEnd]]])` <a name="buf-copy"></a>
+* `targetBuffer <Buffer>`, modified buffer
+* `targetStart <Number>`, Default: `0`
+* `sourceStart <Number>`, Default: `0`
+* `sourceEnd <Number>`, Default: `buf.length`
+
+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('<JS>');
+
+buffer2.copy(buffer1, 6, 1, 3);
+
+console.log(buffer1); // prints Hello JS world!
+```
+
+
+### `buf.equals(otherBuffer)` <a name="buf-equals"></a>
+* `otherBuffer <Buffer>`, the right-hand side of the comparison
+* Return: `<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');
+
+console.log(buffer1.equals(buffer2)); // prints true
+console.log(buffer1.equals(buffer3)); // prints false
+```
+
+
+### `buf.fill(value)` <a name="buf-fill"></a>
+* `value <Integer>`, all bytes are set to this value
+* Return: `<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);
+console.log(buffer); // prints AAAAA
+buffer.fill(66 - 256);
+console.log(buffer); // prints BBBBB
+```
+
+
+### `buf.slice([start[,end]])` <a name="buf-slice"></a>
+* `start <Integer>`, Default: `0`
+* `end <Integer>`, Default: `buf.length`
+* Return: `<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!!!');
+
+console.log(buffer.slice(8, 18)); // prints JavaScript
+```
+
+
+### `buf.toString([start[,end]])` <a name="buf-to-string"></a>
+* `start <Integer>`, Default: `0`
+* `end <Integer>`, Default: `buffer.length`
+* Return: `<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");
+
+console.log(buffer.toString(1, 3)); // prints EF
+console.log(buffer.toString('hex')); // prints 44454647
+```
+
+
+### `buf.write(string[,offset[,length]])` <a name="buf-write"></a>
+* `string <String>`, data to be written to buffer
+* `offset <Integer>`, start position of buffer for writing. Default: `0`
+* `length <Integer>`, maximum length to be written. Default: `buffer.length - offset`.
+* Return: `<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);
+
+console.log(buffer); // prints AB.XY.
+
+var buffer = new Buffer("......");
+buffer.write("ABCDEF", 1, 3);
+
+console.log(buffer); // prints .ABC..
+```
+
+
+### `buf.writeUInt8(value, offset[, noAssert])` <a name="buf-write-uint8"></a>
+* `value <Integer>`, number to be written into the buffer
+* `offset <Integer>`, start position of the writing
+* `noAssert <Boolean>, skip argument validation. Default: `false`
+* Return: `<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.
+
+**Example**
+
+```js
+var Buffer = require('buffer');
+
+var buffer = new Buffer("....");
+
+console.log(buffer.writeUInt8(65, 2)); // prints 3
+console.log(buffer); // prints ..A.
+```
+
+
+### `buf.writeUInt16LE(value, offset[, noAssert])` <a name="buf-write-uint16le"></a>
+* `value <Integer>`, number to be written into the buffer
+* `offset <Integer>`, start position of the writing
+* `noAssert <Boolean>`, skip argument validation. Default: `false`
+* Return: `<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.
+
+**Example**
+
+```js
+var Buffer = require('buffer');
+
+var buffer = new Buffer("......");
+
+print(buffer.wrrteUInt16LE(0x4142, 1)); // prints 3
+print(buffer); // prints .BA...
+```
+
+
+### `buf.writeUInt32LE(value, offset[, noAssert])` <a name="buf-write-uint32le"></a>
+* `value <Integer>`, number to be written into the buffer
+* `offset <Integer>`, start position of the writing
+* `noAssert <Boolean>`, skip argument validation. Default: `false`
+* Return: `<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.
+
+**Example**
+
+```js
+var Buffer = require('buffer');
+
+var buffer = new Buffer("......");
+
+print(buffer.wrrteUInt32LE(0x41424344, 1)); // prints 5
+print(buffer); // prints .DCBA.
+```
+
+
+### `buf.readInt8(offset[, noAssert])` <a name="buf-read-int8"></a>
+* `offset: Number` - start position of buffer for reading.
+* `noAssert: Boolean`, Default: false - skip offset validation.
+* Return: `Number`
+
+Reads a signed 8-bit integer from `buf` buffer starting from
+`offset` position.
+
+**Example**
+
+```js
+var Buffer = require('buffer');
+
+var buffer = new Buffer("ABCDEF");
+
+print(buffer.readUInt8(1).toString(16)); // prints 42
+```
+
+
+### `buf.readUInt8(offset[, noAssert])` <a name="buf-read-uint8"></a>
+* `offset <Integer>`, start position of the reading
+* `noAssert <Boolean>`, skip argument validation. Default: `false`
+* Return: `Number`
+
+Reads an unsigned 8-bit integer from `buf` buffer starting from
+`offset` position.
+
+**Example**
+
+```js
+var Buffer = require('buffer');
+
+var buffer = new Buffer("ABCDEF");
+
+print(buffer.readUInt8(1).toString(16)); // prints 42
+```
+
+
+### `buf.readUInt16LE(offset[, noAssert])` <a name="buf-read-uint16"></a>
+* `offset: Number` - start position of buffer for reading.
+* `noAssert: Boolean`, Default: false - skip offset validation.
+* Return: `Number`
+
+Reads an unsigned 16-bit integer from `buf` buffer starting from
+`offset` position with little endian format.
+
+**Example**
+
+```js
+var Buffer = require('buffer');
+
+var buffer = new Buffer("ABCDEF");
+
+print(buffer.readUInt16LE(1).toString(16)); // prints 4342
+```
+
diff --git a/tools/docs/api/IoT.js-API-DGRAM.md b/tools/docs/api/IoT.js-API-DGRAM.md
new file mode 100644 (file)
index 0000000..e70c244
--- /dev/null
@@ -0,0 +1,174 @@
+## Module: dgram
+
+### Platform Support
+
+The following shows dgram module APIs available for each platform.
+
+|  | Linux<br/>(Ubuntu) | Raspbian<br/>(Raspberry Pi) | Nuttx<br/>(STM32F4-Discovery) |
+| :---: | :---: | :---: | :---: |
+| dgram.createSocket | O | O | O |
+| dgram.Socket.bind | O | O | O |
+| dgram.Socket.close | O | O | O |
+| dgram.Socket.send | O | O | O |
+| dgram.Socket.address | O | O | X |
+| dgram.Socket.setBroadcast | O | O | X |
+| dgram.Socket.setTTL | O | O | X |
+| dgram.Socket.addMembership | O | O | X |
+| dgram.Socket.dropMembership | O | O | X |
+| dgram.Socket.setMulticastLoopback | O | O | X |
+| dgram.Socket.setMulticastTTL | X | X | X |
+
+IoT.js provides udp connections through Dgram module.
+
+You can use this module with `require('dgram')` and create sockets.
+
+
+### Module Functions
+
+
+#### dgram.createSocket(options[, createListener])
+#### dgram.createSocket(type[, createListener])
+* `options: Object`
+ * `type: String`: it indicates an address family either `udp4` or `udp6`.
+ * `reuseAddr: Boolean`: it indicates to allow socket to bind the address and port used previously.
+
+* `type: String`: it indicates an address family either 'udp4' or 'udp6'.
+
+* `createListener: Function(msg, rinfo)`
+ * `msg: Buffer`
+ * `rinfo: Object`
+   * `address: String`
+   * `family: String`: it indicates an address family either `IPv4` or `IPv6`
+   * `port: Number`
+
+Creates a `dgram.Socket` according to `options` or `type`. (Currently we only accept `type`, `udp4`.)
+
+`createListener` is automatically registered as `message` event listener.
+
+
+***
+
+
+## class: dgram.Socket
+
+You can create `dgram.Socket` instance with `dgram.createSocket()`.
+
+
+### Events
+
+
+#### `'close'`
+* `callback: Function()`
+
+Emitted when socket closed.
+
+
+#### `'error'`
+* `callback: Function()`
+
+Emitted when an error occurs.
+
+
+#### `'listening'`
+* `callback: Function()`
+
+Emitted when socket is ready to receive data.
+
+
+#### `'message'`
+* `callback: Function(msg, rinfo)`
+ * `msg: Buffer`
+ * `rinfo: Object`
+   * `address: String`
+   * `family: String`: it indicates an address family either `IPv4` or `IPv6`
+   * `port: Number`
+
+Emitted when message comes to the socket.
+
+
+
+### Methods
+
+
+#### socket.address()
+
+Returns an object with the properties `address`, `port` and `family`. Basically the returned object is same with the object `rinfo` mentioned above.
+
+
+#### socket.addMembership(multicastAddress[, multicastInterface])
+* `multicastAddress: String`
+* `multicastInterface: String`
+
+Joins for socket the given multicast group with given `multicastAddress` and `multicastInterface`.
+
+
+#### socket.dropMembership(multicastAddress[, multicastInterface])
+* `multicastAddress: String`
+* `multicastInterface: String`
+
+Leaves for socket the given multicast group with given `multicastAddress` and `multicastInterface`.
+
+
+#### socket.bind([port][, address][, bindListener])
+#### socket.bind(options[, bindListener])
+* `port: Number`, if it is not specified, OS will bind socket with a random port.
+* `options: Object`
+ * `port: Number`
+ * `address: String`, Default: `0.0.0.0`
+* `bindListener: Function()`
+
+Binds `net.Socket` with given `address` and `port`.
+
+`bindListener` is automatically registered as `listening` event listener.
+
+
+#### socket.close([closeListener])
+* `closeListener: Function()`
+
+Stops listening data.
+
+`closeListener` is registered as `close` event listener.
+
+
+#### socket.setBroadcast(flag)
+* `flag: Boolean`
+
+Sets or clears the `SO_BROADCAST` socket option.
+
+
+#### socket.setTTL(ttl)
+* `ttl: Number`, it should be between 1 and 255.
+
+Sets the `IP_TTL` socket option.
+
+
+#### socket.send(msg, [offset, length], port, address[, sendListener])
+* `msg: Buffer | String | Array`
+* `offset: Number`, is is only valid when `msg` is Buffer.
+* `length: Number`, is is only valid when `msg` is Buffer.
+* `port: Number`
+* `address: String`, Default: `127.0.0.1` or `::1`
+* `sendListener: Function(err, length)`
+ * `err: Null | Error`
+   * `code: String`, temporally, it is just a String of *"error"*.
+   * `errno: String`, it is same with `code`
+   * `syscall: Number`
+   * `address: String`
+   * `port: Number`
+ * `length: Number`, it indicates the length of data.
+
+Sends the message to the destination with given `address` and `port`.
+
+If send operation is successfully completed, `sendListener` will be called with Null and the length of data, otherwise with Error object and the length of data.
+
+
+#### socket.setMulticastLoopback(flag)
+* `flag: Boolean`
+
+Sets or clears the `IP_MULTICAST_LOOP` socket option.
+
+
+#### socket.setMulticastTTL(ttl)
+* `ttl: Number`, it should be between 0 and 255.
+
+Sets the `IP_MULTICAST_TTL` socket option.
diff --git a/tools/docs/api/IoT.js-API-DNS.md b/tools/docs/api/IoT.js-API-DNS.md
new file mode 100644 (file)
index 0000000..6c361ef
--- /dev/null
@@ -0,0 +1,23 @@
+## Module: dns
+
+### Platform Support
+
+The following shows dns module APIs available for each platform.
+
+|  | Linux<br/>(Ubuntu) | Raspbian<br/>(Raspberry Pi) | Nuttx<br/>(STM32F4-Discovery) |
+| :---: | :---: | :---: | :---: |
+| dns.lookup | O | O | X |
+
+※ dns.lookup on `nuttx` works but due to lack of `nuttx` implementation, internally it only allows valid `ip4` address,
+but we are going to support `ip6` address, soon.
+
+IoT.js provides dns module.
+
+### Methods
+
+#### dns.lookup(hostname[, options], callback)
+* `hostname: String`
+* `options: Object | Number`
+* `callback: Function(err: Error, address: String, family: Number)`
+
+Resolves a hostname into the first found A (IPv4) or AAAA (IPv6) record.
diff --git a/tools/docs/api/IoT.js-API-Events.md b/tools/docs/api/IoT.js-API-Events.md
new file mode 100644 (file)
index 0000000..17a5ad3
--- /dev/null
@@ -0,0 +1,55 @@
+The application programming model of IoT.js is based on event-driven programming. Thus many objects in IoT.js emit events. `events.EventEmitter` plays a role as base class for such objects.
+
+
+## Class: EventEmitter
+User application would not directly create an instance of `EventEmitter` since `EventEmitter` is an abstract trait which defines its behavior and grants to sub-classes.
+
+
+### Methods
+
+
+#### emitter.addListener(event, listener)
+#### emitter.on(event, listener)
+* `event: String`
+* `listener: Function([args..])`
+* Returns emitter
+
+Adds `listener` to the end of list of event listeners for `event`.
+
+
+#### emitter.emit(event[, arg1[, arg2[...]]])
+* `event: String`
+* Returns `Boolean`
+
+Invokes each of listener with supplied arguments.
+
+Returns `true` if there were listeners, `false` otherwise.
+
+
+#### emitter.once(event, listener)
+* `event: String`
+* `listener: Function([args..])`
+* Returns emitter
+
+Adds `listener` for one time listener for `event`.
+
+The listener will be invoked at the next event and removed.
+
+
+#### emitter.removeListener(event, listener)
+* `event: String`
+* `listener: Function([args..])`
+* Returns emitter
+
+Removes listener from the list of event listeners.
+
+If you add the same listener multiple times, this removes only one instance of them.
+
+
+#### emitter.removeAllListener([event])
+* `event: String`
+* Returns emitter
+
+Removes all listeners.
+
+If `event` was specified, it only removes listeners for that event.
diff --git a/tools/docs/api/IoT.js-API-File-System.md b/tools/docs/api/IoT.js-API-File-System.md
new file mode 100644 (file)
index 0000000..e6b1139
--- /dev/null
@@ -0,0 +1,227 @@
+## Module: fs
+
+### Platform Support
+
+The following shows fs module APIs available for each platform.
+
+|  | Linux<br/>(Ubuntu) | Raspbian<br/>(Raspberry Pi) | Nuttx<br/>(STM32F4-Discovery) |
+| :---: | :---: | :---: | :---: |
+| fs.close | O | O | O |
+| fs.closeSync | 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.stat | O | O | O |
+| fs.statSync | O | O | O |
+| fs.fstat | O | O | O |
+| fs.fstatSync | O | O | O |
+| fs.write | O | O | O |
+| fs.writeSync | O | O | O |
+| fs.writeFile | O | O | O |
+| fs.writeFileSync | O | O | O |
+| fs.unlink | O | O | O |
+| fs.unlinkSync | O | O | O |
+
+※ On `nuttx` path should be passed with a form of **absolute path**.
+
+
+### Methods
+
+#### fs.close(fd, callback)
+
+* `fd: Int` - file descriptor.
+* `callback: Function(err) `
+ * `err: Error`
+
+Closes the file of fd asynchronously.
+
+
+#### fs.closeSync(fd)
+
+* `fd: Int` - file descriptor.
+
+Closes the file of fd synchronously.
+
+
+#### fs.open(path, flags[, mode], callback)
+
+* `path: String` - file path to be opened.
+* `flags: String` - open flags.
+* `mode: Number`, Default: `0666` - permission mode.
+* `callback: Function(err, fd)`
+ * `err: Error` - `Error` object if there was something wrong, otherwise `null`.
+ * `fd: Number` - file descriptor.
+
+
+#### fs.openSync(path, flags[, mode])
+
+* `path: String` - file path to be opened.
+* `flags: String` - open flags.
+* `mode: Number`, Default: `0666` - permission mode.
+
+
+#### fs.read(fd, buffer, offset, length, position, callback)
+
+* `fd: Int` - 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`, read from current position.
+* `callback: Function(err, bytesRead, buffer) `
+ * `err: Error`
+ * `bytesRead: Number`
+ * `buffer: Buffer`
+
+
+#### fs.readSync(fd, buffer, offset, length, position)
+
+* `fd: Int` - 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`, read from current position.
+
+
+#### fs.readFile(path[, options], callback)
+
+* `path: String` - file path to be opened.
+* `options: Object` - options for the operation.
+ * `encoding: String`, Default: `null` - encoding of the file.
+ * `flag: String`, Default: `r` - file open flag.
+* `callback: Function(err, data)` - callback function.
+ * `err: Error`
+ * `data: Buffer`
+
+Reads entire file asynchronously.
+
+
+#### fs.readFileSync(path[, options])
+
+* `path: String` - file path to be opened.
+* `options: Object` - options for the operation.
+ * `encoding: String`, Default: `null` - encoding of the file.
+ * `flag: String`, Default: `r` - file open flag.
+
+Reads entire file synchronously.
+
+
+#### fs.rename(oldPath, newPath, callback)
+
+* `oldPath: String` - old file path
+* `newPath: String` - new file path
+* `callback: Function(err)` - callback function.
+ * `err: Error`
+
+Renames `oldPath` to `newPath` asynchronously.
+
+
+#### fs.renameSync(oldPath, newPath)
+
+* `oldPath: String` - old file path
+* `newPath: String` - new file path
+
+Renames `oldPath` to `newPath` synchronously.
+
+
+#### fs.stat(path, callback)
+
+* `path: String` - file path to be stated
+* callback: Function(err, stat)` - callback function.
+ * `err: Error`
+ * `stat: Object`
+
+
+#### fs.statSync(path)
+
+* `path: String` - file path to be stated
+
+
+#### fs.fstat(fd, callback)
+
+* `fd: Number` - file descriptor to be stated
+* callback: Function(err, stat)` - callback function.
+ * `err: Error`
+ * `stat: Object`
+
+
+#### fs.fstatSync(fd)
+
+* `fd: Number` - file descriptor to be stated
+
+ ### Class: fs.Stats
+
+ fs.Stats class is a object returned from ```fs.stat()```,```fs.fstat()``` and their synchronous counterparts.
+
+ ### Methods
+
+ #### stats.isDirectory()
+
+ Returns true if stated file is a directory
+
+ #### stats.isFile()
+
+ Returns true if stated file is a file
+
+
+#### fs.write(fd, buffer, offset, length, position, callback)
+
+* `fd: Int` - 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`, read from current position.
+* callback: Function(err, bytesWrite)` - callback function.
+ * `err: Error`
+ * `byteWrite: Int`
+
+
+#### fs.writeSync(fd, buffer, offset, length, position)
+
+* `fd: Int` - 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`, read from current position.
+
+
+#### fs.writeFile(path, data, [, options], callback)
+
+* `path: String` - file path that the `data` will be written
+* `data: Buffer` - buffer that contains data
+* `options: Object` - options for the operation
+* `callback: Function(err)` - callback function
+ * `err: Error`
+
+Writes entire `data` to the file specified by `path` asynchronously.
+
+
+#### fs.writeFileSync(path, data, [, options])
+
+* `path: String` - file path that the `data` will be written
+* `data: Buffer` - buffer that contains data
+* `options: Object` - options for the operation
+
+Writes entire `data` to the file specified by `path` synchronously.
+
+
+#### fs.unlink(path, callback)
+
+* `path: String` - file path to be removed
+* `callback: Function(err) `
+ * `err: Error`
+
+Removes the file specified by `path` asynchronously.
+
+
+#### fs.unlinkSync(path)
+
+* `path: String` - file path to be removed
+
+Removes the file specified by `path` synchronously.
diff --git a/tools/docs/api/IoT.js-API-GPIO.md b/tools/docs/api/IoT.js-API-GPIO.md
new file mode 100644 (file)
index 0000000..487abfa
--- /dev/null
@@ -0,0 +1,194 @@
+### Platform Support
+
+The following shows GPIO module APIs available for each platform.
+
+|  | Linux<br/>(Ubuntu) | Raspbian<br/>(Raspberry Pi) | Nuttx<br/>(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 |
+
+
+## Contents
+* [Pin](#pin)
+* [GPIO](#gpio)
+  * [Constructor](#gpio-constructor)
+    * [`new GPIO()`](#gpio-new)
+  * [Properties](#gpio-properties)
+    * [`DIRECTION`](#gpio-direction)
+    * [`MODE`](#gpio-mode)
+  * [Prototype methods](#gpio-prototype-methods)
+    * [`gpio.open(configuration[, callback])`](#gpio-open)
+* [GPIOPin](#gpiopin)
+  * [Prototype methods](#gpiopin-prototype-methods)
+    * [`gpiopin.write(value[, callback])`](#gpiopin-write)
+    * [`gpiopin.writeSync(value)`](#gpiopin-write-sync)
+    * [`gpiopin.read([callback])`](#gpiopin-read)
+    * [`gpiopin.readSync()`](#gpiopin-read-sync)
+    * [`gpiopin.close([callback])`](#gpiopin-close)
+    * [`gpiopin.closeSync()`](#gpiopin-close-sync)
+
+
+## `Pin` <a name="pin"></a>
+
+* On Linux, pin number is logical number starts from 1. Thus logical pin number *k* is not necessarily bound to physical pin number *k* in your board.
+* On Nuttx, you have to know pin number. The pin number is defined in target board module. For more module information, please see below list.
+  * [STM32F4-discovery](../../targets/nuttx-stm32f4/Stm32f4dis.md#gpio-pin)
+
+
+## Class: GPIO <a name="gpio"></a>
+
+
+## Constructor <a name="gpio-constructor"></a>
+
+
+### `new GPIO()` <a name="gpio-new"></a>
+
+Returns a new GPIO object which can open all GPIO pins.
+
+
+## Properties <a name="gpio-properties"></a>
+
+
+### `DIRECTION`<a name="gpio-direction"></a>
+* `IN` - I/O input
+* `OUT` - I/O output
+
+
+### `MODE` <a name="gpio-mode"></a>
+* `NONE` - none
+* `PULLUP` - pull-up (only mode is input)
+* `PULLDOWN` - pull-down (only mode is input)
+* `FLOAT` - float (only mode is output)
+* `PUSHPULL` - push-pull (only mode is output)
+* `OPENDRAIN` - open drain (only mode is output)
+
+
+## Prototype methods <a name="gpio-prototype-methods"></a>
+
+
+### `gpio.open(configuration[, callback])` <a name="gpio-open"></a>
+* `configuration <Object>`
+  * `pin <Number>`, pin number to configure, mandatory configuration
+  * `direction <GPIO.DIRECTION>`, direction of the pin, Default: `GPIO.DIRECTION.OUT`
+  * `mode <GPIO.MODE>`, pin mode, Default: `GPIO.MODE.NONE`
+* `callback <Function(err: Error | null)>`
+* Returns: `<GPIOPin>`
+
+Opens the specified GPIO pin and sets GPIO pin configuration.
+
+The mode option is not supported on Linux.
+
+`callback` will be called with the value. `err` is null on success, or Error on failure.
+
+ **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 <a name="gpiopin"></a>
+
+
+### Prototype methods <a name="gpiopin-prototype-methods"></a>
+
+
+### `gpiopin.write(value[, callback])` <a name="gpiopin-write"></a>
+* `value <Boolean>`
+* `callback <Function(err: Error | null)>`
+
+Writes out a boolean value to a GPIO pin asynchronously.
+
+`callback` will be called with the value. `err` is null on success, or Error on failure.
+
+**Example**
+```js
+gpio10.write(1, function(err) {
+  if (err) {
+    throw err;
+  }
+});
+```
+
+
+### `gpiopin.writeSync(value)` <a name="gpiopin-write-sync"></a>
+* `value <Boolean>`
+
+Writes out a boolean value to a GPIO pin synchronously.
+
+**Example**
+```js
+gpio10.writeSync(1);
+```
+
+
+### `gpiopin.read([callback])` <a name="gpiopin-read"></a>
+* `callback <Function(err: Error | null, value: Boolean)>`
+
+Reads a boolean value from a GPIO pin asynchronously.
+
+`callback` will be called with the value. `err` is null on success, or Error on failure.
+
+**Example**
+```js
+gpio10.read(function(err, value) {
+  if (err) {
+    throw err;
+  }
+  console.log('value:', value);
+});
+```
+
+
+### `gpiopin.readSync()` <a name="gpiopin-read-sync"></a>
+* Returns: `<Boolean>`
+
+Returns a boolean value from a GPIO pin synchronously.
+
+**Example**
+```js
+console.log('value:', gpio10.readSync());
+```
+
+
+### `gpiopin.close([callback])` <a name="gpiopin-close"></a>
+* `callback <Function(err: Error | null)>`
+
+Closes a GPIO pin asynchronously.
+
+`callback` will be called with the value. `err` is null on success, or Error on failure.
+
+**Example**
+```js
+gpio10.close(function(err) {
+  if (err) {
+    throw err;
+  }
+  console.log('gpio pin is closed');
+});
+```
+
+
+### `gpiopin.closeSync()` <a name="gpiopin-close-sync"></a>
+
+Closes a GPIO pin synchronously.
+
+**Example**
+```js
+gpio10.closeSync();
+console.log('gpio pin is closed');
+```
diff --git a/tools/docs/api/IoT.js-API-HTTP.md b/tools/docs/api/IoT.js-API-HTTP.md
new file mode 100644 (file)
index 0000000..0f45203
--- /dev/null
@@ -0,0 +1,219 @@
+# Module: http
+
+IoT.js provides HTTP to support HTTP server and client enabling users to receive/send HTTP request easily.
+
+## Methods
+### http.createServer(requestListener)
+* `requestListener: Function`
+* Return: `http.Server` instance
+
+
+### http.request(options[, callback])
+* `options: Object`
+* `callback: Function`
+* Return: `http.ClientRequest` instance
+
+### http.get(options[, callback])
+* `options: Object`
+* `callback: Function`
+* Return: `http.ClientRequest` instance
+
+Same as http.request except that `http.get` automatically call `req.end()` at the end.
+
+
+## Class: http.Server
+
+### Event
+
+#### 'request'
+* `request: http.IncomingMessage` instance.
+* `response: http.ServerResponse` instance.
+After request header is parsed, this event will be fired.
+
+#### 'connection'
+This event is emitted when new TCP connection is established.
+
+#### 'close'
+This event is emitted when server is closed.
+
+### Method
+
+#### 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.
+`callback` will be called when server has been bound.
+
+#### 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.
+
+#### 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.
+
+### Member Variable
+#### timeout
+Server's timeout value. Default value is 2 minutes.
+
+
+## Class: http.ClientRequest
+### Event
+
+#### 'response'
+* `response: http.IncomingMessage` instance
+
+This event is emitted when server's response header is parsed. ` http.IncomingMessage` object is passed as argument to handler.
+
+
+#### 'socket'
+* `Net.socket` instance
+
+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.
+
+### Method
+
+#### write(data[, callback])
+* `data: Buffer|String`
+* `callback: Function`
+
+Sends `data` as a request body. `callback` will be called when data is flushed.
+
+
+#### 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.
+
+
+
+#### 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.
+
+
+## Class: http.ServerResponse
+### Event
+#### 'end'
+This event is fired when no more data to be sent.
+
+#### 'close'
+When underlying connection is closed, 'close' event is emitted.
+
+#### 'finish'
+This event is emitted when the response has been sent. It does not guarantee that client has received data yet.
+
+### Method
+#### writeHead(statusCode[, statusMessage][, headers])
+* `statusCode: Number`
+* `statusMessage: String`
+* `headers: Object`
+
+Sets response's header. `headers` is a map between field and value in header.
+
+#### setHeader(name, value)
+* `name: String`
+* `value: `
+
+Sets response's header field(`name`) to `value`. If the field exists, it overwrites the existing value.
+
+#### getHeader(name)
+* `name: String`
+
+Returns `name` field of response's header
+
+#### removeHeader(name)
+* `name: String`
+
+Removes `name` field from response's header
+
+#### write(data[, callback])
+* `data: Buffer|String`
+* `callback: Function`
+
+Sends `data` as a response body. `callback` will be called when data is flushed.
+
+#### 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.
+
+#### 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.
+
+
+
+## Class: http.IncomingMessage
+
+http.IncomingMessage inherits [`Stream.readable`](IoT.js-API-Stream.md)
+
+### Event
+#### 'end'
+This event is fired when no more data to be received.
+
+#### 'close'
+When underlying connection is closed, 'close' event is emitted.
+
+### Method
+#### 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.
+
+
+
+### Member Variable
+#### headers
+HTTP header object.
+
+#### method
+Requests method as `String`
+
+#### url
+Requests URL as `String`
+
+#### statusCode
+HTTP response status code as `Number` of 3-digit.
+
+#### statusMessage
+HTTP response status message as `String`
+
+#### socket
+Underlying socket
diff --git a/tools/docs/api/IoT.js-API-I2C.md b/tools/docs/api/IoT.js-API-I2C.md
new file mode 100644 (file)
index 0000000..23e83fc
--- /dev/null
@@ -0,0 +1,234 @@
+## Platform Support
+
+The following shows i2c module APIs available for each platform.
+
+|  | Linux<br/>(Ubuntu) | Raspbian<br/>(Raspberry Pi) | Nuttx<br/>(STM32F4-Discovery) |
+| :---: | :---: | :---: | :---: |
+| i2c.open | O | O | O |
+| i2cbus.read | O | O | O |
+| i2cbus.readByte | O | O | O |
+| i2cbus.readBytes | O | O | O |
+| i2cbus.write | O | O | O |
+| i2cbus.writeByte | O | O | O |
+| i2cbus.writeBytes | O | O | O |
+| i2cbus.close | O | O | O |
+
+
+## Contents
+
+  * [I2C](#i2c)
+    * [Constructor](#constructor)
+      * [`new I2C()`](#new-i2c)
+    * [Prototype Methods](#i2c-prototype-methods)
+      * [`i2c.open(configurable[, callback])`](#i2c-open)
+  * [I2CBus](#i2cbus)
+    * [Prototype Methods](#i2cbus-prototype-methods)
+      * [i2cbus.read(length[, callback])](#i2cbus-read)
+      * [i2cbus.readByte([callback])](#i2cbus-readbyte)
+      * [i2cbus.readBytes(cmd, length[, callback])](#i2cbus-readbytes)
+      * [i2cbus.write(array[, callback])](#i2cbus-write)
+      * [i2cbus.writeByte(byte[, callback])](#i2cbus-writebyte)
+      * [i2cbus.writeBytes(cmd, array[, callback])](#i2cbus-writebytes)
+      * [i2cbus.close()](#i2cbus-close)
+
+
+## Class: I2C <a name="i2c"></a>
+
+The I2C class supports the I2C protocol. I2C bus has two signals - SDA and SCL.
+
+
+## Constructor <a name="constructor"></a>
+
+
+### `new I2C()` <a name="new-i2c"></a>
+
+Create I2C object.
+
+**Example**
+
+```js
+var I2C = require('i2c');
+
+var i2c = new I2C();
+```
+
+
+## Prototype Methods <a name="i2c-prototype-methods"></a>
+
+
+### `i2c.open(configuration[, callback])` <a name="i2c-open"></a>
+* `configuration <Object>`, configuration for open I2CBus
+  * `device <String(linux)|Number(nuttx)>`, device path
+  * `address <Number>`
+* `callback <Function(err: Error)>`
+* Returns: `<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 <a name="i2cbus"></a>
+
+
+## Prototype Methods <a name="i2cbus-prototype-methods"></a>
+
+
+### `i2cbus.read(length[, callback])` <a name="i2cbus-read"></a>
+* `length <Number>`, the number of bytes.
+* `callback <Function(err: Error, res: Array)>`, `res` contains an 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.readByte([callback])` <a name="i2cbus-readbyte"></a>
+* `callback <Function(err: Error, res: Array)>`, `res` contains an array of bytes.
+
+Read one byte 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.readByte(function(err, res) {
+  if(!err) {
+    console.log('readByte result: ' + res);
+  }
+});
+```
+
+
+### `i2cbus.readBytes(cmd, length[, callback])` <a name="i2cbus-readbytes"></a>
+* `command <Number>`
+* `length <Number>`, the number of bytes
+* `callback <Function(err: Error, res: Array)>`, `res` contains an array of bytes.
+
+Read bytes from I2C device with command.
+
+**Example**
+
+```js
+var I2C = require('i2c');
+
+var i2c = new I2C();
+var i2c_bus = i2c.open({device: '/dev/i2c-1', address: 0x23});
+
+i2c_bus.readBytes(0x20, 2, function(err, res) {
+  if(!err) {
+    console.log('readBytes result: ' + res);
+  }
+});
+```
+
+
+### `i2cbus.write(array[, callback])` <a name="i2cbus-write"></a>
+* `bytes <Array>`, an array of numbers
+* `callback <Function(err: Error)>`
+
+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.writeByte(byte[, callback])` <a name="i2cbus-writebyte"></a>
+ * `byte <Number>`
+ * `callback <Function(err: Error)>`
+
+Write one byte 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.writeByte(0x10, function(err) {
+  if(!err) {
+    console.log('writeByte done');
+  } 
+});
+```
+
+
+### `i2cbus.writeBytes(cmd, array[, callback])` <a name="i2cbus-writebytes"></a>
+ * `command <Number>`
+ * `bytes <Array>`, an array of numbers
+ * `callback <Function(err: Error)>`
+
+Write bytes to I2C device with command.
+
+**Example**
+
+```js
+var I2C = require('i2c');
+
+var i2c = new I2C();
+var i2c_bus = i2c.open({device: '/dev/i2c-1', address: 0x23});
+
+i2c_bus.writeBytes(0x10, [0x10], function(err) {
+  if(!err) {
+    console.log('writeBytes done');
+  }
+});
+```
+
+
+### `i2cbus.close()` <a name="i2cbus-close"></a>
+
+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();
+```
diff --git a/tools/docs/api/IoT.js-API-Module.md b/tools/docs/api/IoT.js-API-Module.md
new file mode 100644 (file)
index 0000000..38ac4c1
--- /dev/null
@@ -0,0 +1,35 @@
+## Module
+``` module ``` implements ``` require ``` function.
+Since ``` require ``` function is implicitly passed to user code, user do not need to import it explicitly.
+
+### Methods
+
+#### require(id)
+* ``` id : String ``` - module name to be loaded
+
+Loads the module named 'id'
+
+
+### Module Loading by ``` require ``` function
+
+#### ``` require ``` search paths
+``` require ``` function finds modules in the order of
+
+1. current working directory
+2. node_modules directory under current working directory
+3. $HOME/node_modules
+4. $NODE_PATH/node_modules
+
+
+#### ``` require('id') ``` works as follows:
+For each directory in search paths above,
+
+0. If native module named 'id' exists, load it and return.
+1. If id.js file exists, load it and return.
+2. If a directory id exists, load it as an package and return.
+
+#### ``` require('id') ``` as a package
+For a given id, if a directory id exists, module system consider the directory as a package.
+
+0. if 'id/node_modules/package.json' contains 'main' property, load the file named main property.
+1. if either id/node_modules/package.json or main property exists, load index.js
diff --git a/tools/docs/api/IoT.js-API-Net.md b/tools/docs/api/IoT.js-API-Net.md
new file mode 100644 (file)
index 0000000..401b4e5
--- /dev/null
@@ -0,0 +1,256 @@
+## Module: net
+
+### Platform Support
+
+The following shows net module APIs available for each platform.
+
+|  | Linux<br/>(Ubuntu) | Raspbian<br/>(Raspberry Pi) | Nuttx<br/>(STM32F4-Discovery) |
+| :---: | :---: | :---: | :---: |
+| net.createServer | O | O | O |
+| net.connect | O | O | O |
+| net.createConnection | O | O | O |
+| net.Server.listen | O | O | O |
+| net.Server.close | O | O | O |
+| net.Socket.connect | O | O | O |
+| net.Socket.write | O | O | O |
+| net.Socket.end | O | O | O |
+| net.Socket.destroy | O | O | O |
+| net.Socket.pause | O | O | O |
+| net.Socket.resume | O | O | O |
+| net.Socket.setTimeout | O | O | O |
+| net.Socket.setKeepAlive | X | X | X |
+
+※ 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.
+
+IoT.js provides asynchronous networking through Net module.
+
+You can use this module with `require('net')` and create both servers and clients.
+
+### Module Functions
+
+#### net.connect(options[, connectListener])
+#### net.connect(port[, host][, connectListener])
+#### net.createConnection(options[, connectListener])
+#### net.createConnection(port[, host][, connectListener])
+* `options: Object`
+* `port: Number`
+* `host: String`, Default: `localhost`
+* `connectListener: Function()`
+
+Creates a `net.Socket` and connects to the supplied host.
+
+It is equivalent to `new net.Socket()` followed by `socket.connect()`.
+
+
+#### net.createServer([options][, connectionListener])
+* `options: Object`
+* `connectionListener: Function(connection: net.Socket)`
+
+Creates a TCP server according to `options`.
+
+`connectionListener` is automatically registered as `connection` event listener.
+
+
+***
+
+## class: net.Server
+
+You can create `net.Server` instance with `net.createServer()`.
+
+
+### Events
+
+#### `'close'`
+* `callback: Function()`
+
+Emitted when server closed.
+
+Note that this event will be emitted after all existing connections are closed.
+
+
+#### `'connection(socket)'`
+* `callback: Function(socket)`
+ * `socket: net.Socket`
+
+Emitted when new connection is established.
+
+
+#### `'error'`
+* `callback: Function()`
+
+Emitted when an error occurs.
+
+
+#### `'listening'`
+* `callback: Function()`
+
+Emitted when server has been started listening.
+
+
+### Methods
+
+#### server.close([closeListener])
+* `closeListener: Function()`
+
+Stops listening new arriving connection.
+
+Server socket will finally close when all existing connections are closed, then emit 'close' event.
+
+`closeListener` is registered as `close` event listener.
+
+
+#### server.listen(port[, host][, backlog][, listenListener])
+#### server.listen(options[, listenListener])
+* `port: Number`
+* `host: String`
+* `backlog: Number`
+* `listenListener: Function()`
+
+Starts listening and accepting connections on specified port and host.
+
+
+***
+
+## class: net.Socket
+
+net.Socket inherits [`Stream.Duplex`](IoT.js-API-Stream.md)
+
+### Constructor
+
+#### new net.Socket([options])
+* `options: Object`
+
+Creates a new socket object.
+
+`options` is an object specifying following information:
+
+* `allowHalfOpen: Boolean`
+
+
+
+### Events
+
+
+#### `'connect'`
+* `callback: Function()`
+
+Emitted after connection is established.
+
+
+#### `'close'`
+* `callback: Function()`
+
+Emitted when the socket closed.
+
+
+#### `'data'`
+* `callback: Function(data)`
+ * `data: Buffer | String`
+
+Emitted when data is received from the connection.
+
+
+#### `'drain'`
+* `callback: Function()`
+
+Emitted when the write buffer becomes empty.
+
+
+#### `'end'`
+* `callback: Function()`
+
+Emitted when FIN packet received.
+
+
+#### `'error'`
+* `callback: Function()`
+
+Emitted when an error occurs.
+
+
+#### `'lookup'`
+* `callback: Function(err, address, family)`
+ * `err: Error | Null`
+ * `address: String`
+ * `family: String | Null`
+
+Emitted after resolving hostname.
+
+
+#### `'timeout'`
+* `callback: Function()`
+
+Emitted when the connection remains idle for specified timeout.
+
+
+### Methods
+
+#### socket.connect(options[, connectListener])
+#### socket.connect(port[, host][, connectListener])
+* `options: Object`
+* `port: Number`
+* 'host: String`, Default: `'localhost'`
+
+Opens the connection with supplied port and host.
+
+`options` is an object specifying following information:
+* `port: Number` - port connect to (required)
+* `host: String` - host connect to (optional, default: `'127.0.0.1'`)
+
+`connectionListener` is automatically registered as `connect` event listener which will be emitted when the connection is established.
+
+
+#### socket.destroy()
+
+Destroys the socket.
+
+
+#### socket.end([data][, callback])
+
+* `data: String | Buffer`
+* `callback: Function()`
+
+Half-closes the socket.
+
+If `data` is given it is equivalent to `socket.write(data)` followed by `socket.end()`.
+
+* `data: String | Buffer`
+
+
+#### socket.pause()
+
+Pauses reading data.
+
+
+#### socket.resume()
+
+Resumes reading data after a call to `pause()`.
+
+
+#### socket.setKeepAlive([enable][, initialDelay])
+
+* `enable: Boolean`
+* `initialDelay: Number`, Default: `0`
+
+Enables or disables keep-alive functionality.
+
+
+#### socket.setTimeout(timeout[, callback])
+* `timeout: Number`
+* `callback: Function()`
+
+Sets timeout for the socket.
+
+If the socket is inactive for `timeout` milliseconds, `'timeout'` event will emit.
+
+`callback` is registered as `timeout` event listener.
+
+
+#### socket.write(data[, callback])
+* `data: String | Buffer`
+* `callback: Function()`
+
+Sends `data` on the socket.
+
+`callback` function will be called after given data is flushed through the connection.
diff --git a/tools/docs/api/IoT.js-API-PWM.md b/tools/docs/api/IoT.js-API-PWM.md
new file mode 100644 (file)
index 0000000..4edfbb3
--- /dev/null
@@ -0,0 +1,247 @@
+### Platform Support
+
+The following shows PWM module APIs available for each platform.
+
+|  | Linux<br/>(Ubuntu) | Raspbian<br/>(Raspberry Pi) | Nuttx<br/>(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 |
+
+
+## Contents
+* [Pin](#pin)
+* [PWM](#pwm)
+  * [Constructor](#pwm-constructor)
+    * [`new PWM()`](#pwm-new)
+  * [Prototype methods](#pwm-prototype-methods)
+    * [`pwm.open(configuration[, callback])`](#pwm-open)
+* [PWMPin](#pwmpin)
+  * [Prototype methods](#pwmpin-prototype-methods)
+    * [`pwmpin.setPeriod(period[, callback])`](#pwmpin-period)
+    * [`pwmpin.setPeriodSync(period)`](#pwmpin-period-sync)
+    * [`pwmpin.setFrequency(frequency[, callback])`](#pwmpin-frequency)
+    * [`pwmpin.setFrequencySync(frequency)`](#pwmpin-frequency-sync)
+    * [`pwmpin.setDutyCycle(dutyCycle[, callback])`](#pwmpin-dutycycle)
+    * [`pwmpin.setDutyCycleSync(dutyCycle)`](#pwmpin-dutycycle-sync)
+    * [`pwmpin.setEnable(enable[, callback])`](#pwmpin-enable)
+    * [`pwmpin.setEnableSync(enable)`](#pwmpin-enable-sync)
+    * [`pwmpin.close([callback])`](#pwmpin-close)
+    * [`pwmpin.closeSync()`](#pwmpin-close-sync)
+
+
+### `pin` <a name="pin"></a>
+* On Linux, `pin` is a pwm 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-stm32f4/Stm32f4dis.md#pwm-pin)
+
+
+## Class: PWM <a name="pwm"></a>
+
+
+## Constructor <a name="pwm-constructor"></a>
+
+
+### `new PWM()` <a name="pwm-new"></a>
+
+Returns a new PWM object which can open PWM pin.
+
+
+## Prototype methods <a name="pwm-prototype-methods"></a>
+
+
+### `pwm.open(configuration[, callback])` <a name="pwm-open"></a>
+* `configuration <Object>`
+  * `pin <Number>`, mandatory configuration
+  * `chip <Number>`, chip number, Default: 0, only Linux configuration
+  * `period <Number>`, seconds(positive integer) 
+  * `frequency <Number>`, Hz(positive integer)
+  * `dutyCycle <Number>`, between 0 and 1
+* `callback <Function(err: Error | null)>`
+* Returns: `<PWMPin>`
+
+Opens PWM pin with the specified configuration.
+
+
+**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() {
+  if (err) {
+    throw err;
+  }
+});
+```
+
+
+## Class: PWMPin <a name="pwmpin"></a>
+
+
+## Prototype methods <a name="pwmpin-prototype-methods"></a>
+
+
+### `pwmpin.setPeriod(period[, callback])` <a name="pwmpin-period"></a>
+* `period <Number>`, seconds(positive integer) 
+* `callback <Function(err: Error | null)>`
+
+Sets period that is the duration of one cycle in a repeating signal. It is given in seconds asynchronously.
+
+`callback` will be called after period is set.
+
+**Example**
+```js
+pwm0.setPeriod(1, function(err) {
+  if (err) {
+    throw err;
+  }
+  console.log('done');
+});
+```
+
+
+### `pwmpin.setPeriodSync(period)` <a name="pwmpin-period-sync"></a>
+* `period <Number>`, seconds(positive integer) 
+
+Sets period that is the duration of one cycle in a repeating signal synchronously.
+
+**Example**
+```js
+pwm0.setPeriodSync(1);
+console.log('done');
+```
+
+
+### `pwmpin.setFrequency(frequency[, callback])` <a name="pwmpin-frequency"></a>
+* `frequency <Number>`, Hz(positive integer)
+* `callback <Function(err: Error | null)>`
+
+Sets frequency that is a measurement of how often repeating signal per unit time asynchronously.
+
+`callback` will be called after frequency is set.
+
+**Example**
+```js
+pwm0.setFrequency(1, function(err) {
+  if (err) {
+    throw err;
+  }
+  console.log('done');
+});
+```
+
+
+### `pwmpin.setFrequencySync(frequency)` <a name="pwmpin-frequency-sync"></a>
+* `frequency <Number>`, Hz(positive integer)
+
+Sets frequency that is a measurement of how often repeating signal per unit time synchronously.
+
+**Example**
+```js
+pwm0.setFrequencySync(1);
+console.log('done');
+```
+
+
+### `pwmpin.setDutyCycle(dutyCycle[, callback])` <a name="pwmpin-dutycycle"></a>
+* `dutyCycle <Number>`, between 0 and 1
+* `callback <Function(err: Error | null)>`
+
+Sets duty cycle that is the ratio of pulse width in one period asynchronously.
+
+`callback` will be called after duty-cycle is set.
+
+**Example**
+```js
+pwm0.setDutyCycle(1, function(err) {
+  if (err) {
+    throw err;
+  }
+  console.log('done');
+});
+```
+
+
+### `pwmpin.setDutyCycleSync(dutyCycle)` <a name="pwmpin-dutycycle-sync"></a>
+* `dutyCycle <Number>`, between 0 and 1
+
+Sets duty cycle that is the ratio of pulse width in one period synchronously.
+
+**Example**
+```js
+pwm0.setDutyCycleSync(1);
+console.log('done');
+```
+
+
+### `pwmpin.setEnable(enable[, callback])` <a name="pwmpin-enable"></a>
+* `enable <Boolean>`
+* `callback <Function(err: Error | null)>`
+
+Enables or Disables PWM asynchronously.
+
+`callback` will be called after enable is set.
+
+**Example**
+```js
+pwm0.setEnable(true, function(err) {
+  if (err) {
+    throw err;
+  }
+  console.log('done');
+});
+```
+
+
+### `pwmpin.setEnableSync(enable)` <a name="pwmpin-enable-sync"></a>
+* `enable <Boolean>`
+
+Enables or Disables PWM synchronously.
+
+**Example**
+```js
+pwm0.setEnableSync(false);
+console.log('done');
+```
+
+
+### `pwmpin.close([callback])` <a name="pwmpin-close"></a>
+* `callback <Function(err: Error | null)>`
+
+Closes PWM pin asynchronously.
+
+`callback` will be called after PWM device is released.
+
+**Example**
+```js
+pwm0.close(function(err) {
+  if (err) {
+    throw err;
+  }
+  console.log('done');
+});
+```
+
+
+### `pwmpin.closeSync()` <a name="pwmpin-close-sync"></a>
+
+Closes PWM pin synchronously.
+
+**Example**
+```js
+pwm0.closeSync();
+console.log('done');
+```
\ No newline at end of file
diff --git a/tools/docs/api/IoT.js-API-Process.md b/tools/docs/api/IoT.js-API-Process.md
new file mode 100644 (file)
index 0000000..ae6b98b
--- /dev/null
@@ -0,0 +1,86 @@
+## process
+
+### Platform Support
+
+The following shows process module APIs available for each platform.
+
+|  | Linux<br/>(Ubuntu) | Raspbian<br/>(Raspberry Pi) | Nuttx<br/>(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` is unique global object can be accessed from anywhere.
+
+### Events
+
+
+#### `'exit'`
+* `callback: Function(code)`
+ * `code: Number - exitCode`
+
+Emitted when IoT.js process is about to exit.
+
+
+#### `'uncaughtException'`
+* `callback: Function(err)`
+ * `err: Error - error object uncaught by catch handler`
+
+Emitted there's no catch handler for exception.
+
+
+### Methods
+
+
+#### process.chdir(path)
+* `path: String`
+
+Changes current working directory to `path`.
+
+
+#### process.cwd()
+
+Returns current working directory.
+
+
+#### process.exit(code)
+* `code: Number - exitCode`
+
+Exits executing process with code.
+
+
+#### process.nextTick(callback)
+* `callback: Function()`
+
+After current event loop finished, calls the `callback` function. The next tick callback will be called before any I/O events.
+
+
+### Member Variable
+
+
+#### `'arch'`
+
+Target Arch, one of (`arm`|`ia32`|`x64`|`unknown`)
+
+
+#### `'argv'`
+
+Argument vector to be passed to IoT.js
+
+
+#### `'board'`
+
+Target Board, one of (`STM32F4DIS`|`RP2`|`unknown`)
+
+
+#### `'env'`
+
+Environment object holding `HOME` and `NODE_PATH`. On NuttX `NODE_PATH` is `/mnt/sdcard` in default.
+
+
+#### `'platform'`
+
+Target Platform, one of (`linux`|`nuttx`|`darwin`|`unknown`)
diff --git a/tools/docs/api/IoT.js-API-SPI.md b/tools/docs/api/IoT.js-API-SPI.md
new file mode 100644 (file)
index 0000000..6032bed
--- /dev/null
@@ -0,0 +1,170 @@
+### Platform Support
+
+The following shows spi module APIs available for each platform.
+
+|  | Linux<br/>(Ubuntu) | Raspbian<br/>(Raspberry Pi) | Nuttx<br/>(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 |
+
+
+## Contents
+* [SPI](#spi)
+  * [Constructor](#spi-constructor)
+    * [`new SPI()`](#spi-new)
+  * [Properties](#spi-properties)
+    * [`MODE`](#spi-mode)
+    * [`CHIPSELECT`](#spi-chipselect)
+    * [`BITORDER`](#spi-bitorder)
+  * [Prototype methods](#spi-prototype-methods)
+    * [`spi.open(configuration[, callback])`](#spi-open)
+* [SPIBus](#spibus)
+  * [Prototype methods](#spibus-prototype-methods)
+    * [`spibus.transfer(tx, rx[, callback])`](#spibus-transfer)
+    * [`spibus.transferSync(tx, rx)`](#spibus-transfer-sync)
+    * [`spibus.close([callback])`](#spibus-close)
+    * [`spibus.closeSync()`](#spibus-close-sync)
+
+
+## Class: SPI <a name="spi"></a>
+
+
+## Constructor <a name="spi-constructor"></a>
+
+
+### `new SPI()` <a name="spi-new"></a>
+
+Returns a new SPI object which can open SPI bus.
+
+
+## Properties <a name="spi-properties"></a>
+
+
+### `MODE`<a name="spi-mode"></a>
+* `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)
+
+
+### `CHIPSELECT`<a name="spi-chipselect"></a>
+* `NONE`
+* `HIGH` - chip select active high
+
+
+### `BITORDER`<a name="spi-bitorder"></a>
+* `MSB` - most significant bit
+* `LSB` - least significant bit
+
+
+## Prototype methods <a name="spi-prototype-methods"></a>
+
+
+### `spi.open(configuration[, callback])` <a name="spi-open"></a>
+* `configuration <Object>`
+  * `device <String>`, the specified path for `spidev`
+  * `mode <SPI.MODE>`, the combinations of polarity and phases, Default: `SPI.MODE[0]`
+  * `chipSelect <SPI.CHIPSELECT>`, Default: `SPI.CHIPSELECT.NONE`
+  * `maxSpeed <Number>`, max transfer speed, Default: `500000`
+  * `bitsPerWord <Number>`, bits per word to send, should be 8 or 9, Default: `8`
+  * `bitOrder <SPI.bitORDER>`, Default: `SPI.BITORDER.MSB`
+  * `loopback <Boolean>`, Default: `false`
+* `callback <Function(err: Error | null)>`
+* Returns: `<SPIBus>`
+
+Opens 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 <a name="spibus"></a>
+
+
+## Prototype methods <a name="spibus-prototype-methods"></a>
+
+
+### `spibus.transfer(txBuffer, rxBuffer[, callback])` <a name="spibus-transfer"></a>
+* `txBuffer <Array | Buffer>`
+* `rxBuffer <Array | Buffer>`
+* `callback <Function(err: Error | null)>`
+
+Writes and reads data from SPI device asynchronously.
+`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)` <a name="spibus-transfer-sync"></a>
+* `txBuffer <Array | Buffer>`
+* `rxBuffer <Array | Buffer>`
+
+Writes and reads data from SPI device synchronously.
+`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])` <a name="spibus-close"></a>
+* `callback <Function(err: Error | null)>`
+
+Closes SPI device asynchronously.
+
+`callback` will be called after SPI device is closed.
+
+**Example**
+```js
+spi0.close(function(err) {
+  if (err) {
+    throw err;
+  }
+  console.log('spi bus is closed');
+});
+```
+
+
+### `spibus.closeSync()` <a name="spibus-close-sync"></a>
+
+Closes SPI device synchronously.
+
+**Example**
+```js
+spi.closeSync();
+console.log('spi bus is closed');
+```
diff --git a/tools/docs/api/IoT.js-API-Stream.md b/tools/docs/api/IoT.js-API-Stream.md
new file mode 100644 (file)
index 0000000..54bde7c
--- /dev/null
@@ -0,0 +1,107 @@
+## Class: Stream.Readable
+
+Readable stream is abstraction for data source from which data will be read.
+
+At any time a readable stream is in one of two state: **flowing** and **paused**. In paused state, readable stream emits `'readable'` event for you that indicates there are data ready for read. and then you can explicitly call `stream.read()` to get the data form the stream. In flowing state, readable stream emits `'data'` event with actual data that you can receive data as fast as possible. All streams start out in paused mode.
+
+### Events
+
+
+#### 'close'
+* `callback: Function()`
+
+Emitted when the underlying resource has been closed.
+
+
+#### 'data'
+* `callback: Function(chunk)`
+ * `chunk: Buffer | String`
+
+Readable stream emits this event when a chunk of data prepared to be read.
+This event only emitted when the stream is in flowing state.
+
+Attaching a `data` event listener to a stream makes the stream to be switched to flowing mode.
+
+
+#### 'end'
+* `callback: Function()`
+
+This event is only fired when there will be no more data to read.
+
+
+#### 'readable'
+* `callback: Function()`
+
+Readable stream emits this event when a chunk of data prepared to be read.
+This event only emitted when the stream is in paused state.
+
+
+### Methods
+
+
+#### readable.isPaused()
+Returns `true` if the readable stream is in paused mode.
+
+
+#### readable.pause()
+Pause emitting `data` events if the stream was in flowing mode
+
+
+#### readable.read([size])
+* `size | Number` - specifies how much data will be read
+
+Reads data from readable stream, and returns the data as `String | Buffer`
+
+
+#### readable.resume()
+Resume emitting `data` events if the readable was paused.
+
+
+***
+
+## Class: stream.Writable
+
+Writable stream is abstraction for target that you can write data to.
+
+
+### Events
+
+#### 'drain'
+* `callback: Function()`
+
+If `writable.write()` returns false, `drain` events will indicate you that the stream is ready to be written.
+
+
+#### 'error'
+* `callback: Function(err)`
+ * `err: Error`
+
+Emitted if there were something wrong writing data.
+
+
+#### 'finish'
+* `callback: Function()`
+
+After `writable.end()` has been called, and all data has been flushed, this event will be fired.
+
+
+### Methods
+
+
+#### writable.end([chunk][, callback])
+* `chunk: String | Buffer` - The data to write
+* `callback: Function()` - Function callback for when the chunk of data is flushed.
+
+
+#### writable.write(chunk[, callback])
+* `chunk: String | Buffer` - The data to write
+* `callback: Function()` - Function callback for when the chunk of data is flushed.
+* Returns: `Boolean`
+
+This method writes `chunk` of data to the underlying system, when the data is flush it calls back the `callback` function.
+If you can write right after calling this method, it will return `true`, otherwise, return `false`.
+
+***
+
+## Class: Stream.Duplex
+Duplex streams are streams that implement both the Readable and Writable interfaces.
diff --git a/tools/docs/api/IoT.js-API-Timers.md b/tools/docs/api/IoT.js-API-Timers.md
new file mode 100644 (file)
index 0000000..1e658a1
--- /dev/null
@@ -0,0 +1,38 @@
+## Module: timers
+
+### Platform Support
+
+The following shows timers module APIs available for each platform.
+
+|  | Linux<br/>(Ubuntu) | Raspbian<br/>(Raspberry Pi) | Nuttx<br/>(STM32F4-Discovery) |
+| :---: | :---: | :---: | :---: |
+| setTimeout | O | O | O |
+| clearTimeout | O | O | O |
+| setInterval | O | O | O |
+| clearInterval | O | O | O |
+
+### Methods
+
+#### setTimeout(callback, delay[, args..])
+* `callback: Function([args..])`
+* `delay: Int`
+* Return: `timeoutObject`
+
+Schedules to call one-time to `callback` function after `delay` milliseconds.
+
+#### clearTimeout(timeoutObject)
+* `timeoutObject: timeoutObject` - A `timeoutObject` returned from `setTimeout()`
+
+Disables timeout call from `setTimeout` method.
+
+#### setInterval(callback, delay[, args..])
+* `callback: Function([args..])`
+* `delay: Int`
+* Return: `intervalObject`
+
+Schedules to call periodic to `callback` function after every `delay` milliseconds.
+
+#### clearInterval(intervalObject)
+* `intervalObject: intervalObject` - A `intervalObject` returned from `setInterval`
+
+Disables timeout call from `setInterval` method.
diff --git a/tools/docs/api/IoT.js-API-UART.md b/tools/docs/api/IoT.js-API-UART.md
new file mode 100644 (file)
index 0000000..df58d4e
--- /dev/null
@@ -0,0 +1,134 @@
+### Platform Support
+
+The following shows uart module APIs available for each platform.
+
+|  | Linux<br/>(Ubuntu) | Raspbian<br/>(Raspberry Pi) | Nuttx<br/>(STM32F4-Discovery) |
+| :---: | :---: | :---: | :---: |
+| uart.open | O | O | O |
+| uartport.write | O | O | O |
+| uartport.writeSync | O | O | O |
+| uartport.close | O | O | O |
+| uartport.closeSync | O | O | O |
+
+
+## Contents
+  * [UART](#uart)
+    * [Constructor](#uart-constructor)
+      * [`new UART()`](#new-uart)
+    * [Prototype Methods](#uart-prototype-methods)
+      * [`uart.open(configurable[, callback])`](#uart-open)
+  * [UARTPort](#uartport)
+    * [Prototype Methods](#uartport-prototype-methods)
+      * [`uartport.write(data[, callback])`](#uartport-write)
+      * [`uartport.writeSync(data)`](#uartport-write-sync)
+      * [`uartport.close([callback])`](#uartport-close)
+      * [`uartport.closeSync()`](#uartport-close-sync)
+    * [Event](#uartport-event)
+
+
+## Class: UART <a name="uart"></a>
+
+
+## Constructor <a name="uart-constructor"></a>
+
+
+### `new UART()` <a name="uart-new"></a>
+
+Returns a new UART object which can open UART port.
+
+
+## Prototype methods <a name="uart-prototype-methods"></a>
+
+
+### `uart.open(configuration[, callback])` <a name="uart-open"></a>
+* `configuration <Object>`
+  * `device <String>`, mandatory configuration
+  * `baudRate <Number> (Default value is 9600)`
+  * `dataBits <Number> (Default value is 8)`
+* `callback <Function(err: Error | null)>`
+* Returns: `<UARTPort>`
+
+On Nuttx, you can set the properties of `configuration` only on Nuttx config. `Device Drivers -> Serial Driver Support -> U[S]ART(N) Configuration` will help. And if you want to get information about `device`, please see below list.
+  * [STM32F4-discovery](../../targets/nuttx-stm32f4/Stm32f4dis.md#uart)
+
+Opens UART port with the specified configuration. Following methods can be called with UARTPort object.
+
+
+**Example**
+```javascript
+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 <a name="uartport"></a>
+
+
+## Prototype methods <a name="uartport-prototype-methods"></a>
+
+
+### `uartport.write(data[, callback])` <a name="uartport-write"></a>
+* `data <String>`
+* `callback <Function(err: Error | null)>`
+
+Writes data to UART device asynchronously.
+
+**Example**
+```javascript
+serial.write("Hello?", function(err) {
+  if (err) {
+    // Do something.
+  }
+  serial.close();
+});
+```
+
+### `uartport.writeSync(data)` <a name="uartport-write-sync"></a>
+* `data <String>`
+
+Writes data to UART device synchronously.
+
+**Example**
+```javascript
+serial.writeSync("Hello?");
+serial.close();
+```
+
+
+### `uartport.close([callback])` <a name="uartport-close"></a>
+* `callback <Function(err: Error | null)>`
+
+Closes UART device asynchronously.
+
+
+### `uartport.closeSync()` <a name="uartport-close-sync"></a>
+
+Closes UART device synchronously.
+
+
+## Events <a name="uartport-event"></a>
+
+
+### `'data'`
+* `callback <Function(data)>`
+
+ `data` is a string from sender
+
+For example,
+```javascript
+...
+serial.on('data', function(data) {
+  console.log('read result: ' + data.toString());
+});
+
+```
\ No newline at end of file
diff --git a/tools/docs/api/IoT.js-API-reference.md b/tools/docs/api/IoT.js-API-reference.md
new file mode 100644 (file)
index 0000000..d2ad978
--- /dev/null
@@ -0,0 +1,27 @@
+# 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
diff --git a/tools/docs/build/Build-Script.md b/tools/docs/build/Build-Script.md
new file mode 100644 (file)
index 0000000..aee48b3
--- /dev/null
@@ -0,0 +1,244 @@
+## 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/<arch-os>/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.
\ No newline at end of file
diff --git a/tools/docs/build/Build-for-ARTIK.md b/tools/docs/build/Build-for-ARTIK.md
new file mode 100644 (file)
index 0000000..7b0729d
--- /dev/null
@@ -0,0 +1,38 @@
+## 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
+```
+
diff --git a/tools/docs/build/Build-for-Linux.md b/tools/docs/build/Build-for-Linux.md
new file mode 100644 (file)
index 0000000..039f5e4
--- /dev/null
@@ -0,0 +1,204 @@
+### 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 ./test/run_pass/test_console.js --memstat
+```
+
+With given `show-opcodes` option, opcodes will be shown.
+```
+./build/x86_64-linux/debug/iotjs/iotjs ./test/run_pass/test_console.js --show-opcodes
+```
+
+### 4. Clean build directory
+
+Just remove the folder as follows;
+```
+rm -rf build
+rm -rf deps/libuv/out
+```
diff --git a/tools/docs/build/Build-for-NuttX.md b/tools/docs/build/Build-for-NuttX.md
new file mode 100644 (file)
index 0000000..453aa52
--- /dev/null
@@ -0,0 +1,134 @@
+## 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-stm32f4/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-stm32f4/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 <kbd>Ctrl-A</kbd> + <kbd>Z</kbd> + <kbd>U</kbd> for short in minicom screen. (For linux user)
+* Press <kbd>[Meta](http://osxdaily.com/2013/02/01/use-option-as-meta-key-in-mac-os-x-terminal/)</kbd> + <kbd>Z</kbd> 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.
diff --git a/tools/docs/build/Build-for-RPi2.md b/tools/docs/build/Build-for-RPi2.md
new file mode 100644 (file)
index 0000000..41676ef
--- /dev/null
@@ -0,0 +1,142 @@
+## 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/iotjs/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
+```
diff --git a/tools/docs/devs/Enabling-Experimental-Feature.md b/tools/docs/devs/Enabling-Experimental-Feature.md
new file mode 100644 (file)
index 0000000..b905bde
--- /dev/null
@@ -0,0 +1,59 @@
+# 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.
diff --git a/tools/docs/devs/Inside-IoT.js-Validated-Struct.md b/tools/docs/devs/Inside-IoT.js-Validated-Struct.md
new file mode 100644 (file)
index 0000000..97341be
--- /dev/null
@@ -0,0 +1,195 @@
+Validated 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.
+
+
diff --git a/tools/docs/devs/Inside-IoT.js.md b/tools/docs/devs/Inside-IoT.js.md
new file mode 100644 (file)
index 0000000..e904713
--- /dev/null
@@ -0,0 +1,292 @@
+Inside 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.
diff --git a/tools/docs/devs/IoT.js-Package-(outdated).md b/tools/docs/devs/IoT.js-Package-(outdated).md
new file mode 100644 (file)
index 0000000..0a5d944
--- /dev/null
@@ -0,0 +1,121 @@
+**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 email address> (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 <package name>
+(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 <keyword>
+```
+
+If you omit the keyword, it'll list all packages registered.
diff --git a/tools/docs/devs/Logging-IoT.js-execution.md b/tools/docs/devs/Logging-IoT.js-execution.md
new file mode 100644 (file)
index 0000000..c835527
--- /dev/null
@@ -0,0 +1,33 @@
+### 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.
diff --git a/tools/docs/devs/Memory-savings-with-libtuv.md b/tools/docs/devs/Memory-savings-with-libtuv.md
new file mode 100644 (file)
index 0000000..ca1f64b
--- /dev/null
@@ -0,0 +1,241 @@
+Memory 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 bytes
\ No newline at end of file
diff --git a/tools/docs/devs/Optimization-Tips.md b/tools/docs/devs/Optimization-Tips.md
new file mode 100644 (file)
index 0000000..8424be6
--- /dev/null
@@ -0,0 +1,48 @@
+Optimization 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 test.js --memstat
+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;
+```
diff --git a/tools/docs/devs/Writing-New-Builtin-Module.md b/tools/docs/devs/Writing-New-Builtin-Module.md
new file mode 100644 (file)
index 0000000..ceb1170
--- /dev/null
@@ -0,0 +1,174 @@
+Writing 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/jerry-api.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;
+
+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,
+                               (JFreeHandlerType)iotjs_bufferwrap_destroy); /* 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)
diff --git a/tools/docs/help/Assigned-people.md b/tools/docs/help/Assigned-people.md
new file mode 100644 (file)
index 0000000..60a9a98
--- /dev/null
@@ -0,0 +1,11 @@
+#### Maintainers
+* akiss77 (integration)
+* LaszloLango (integration)
+* zherczeg (Steering Committee)
+* yichoi (Steering Committee, Project main contact)
+
+#### Committers
+* chokobole
+* nova0821
+* glistening
+* hs0225
\ No newline at end of file
diff --git a/tools/docs/help/Coding-Style-Guideline.md b/tools/docs/help/Coding-Style-Guideline.md
new file mode 100644 (file)
index 0000000..e9f7256
--- /dev/null
@@ -0,0 +1,213 @@
+Coding 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. `<FILE>_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/)
diff --git a/tools/docs/help/Community-Guidelines.md b/tools/docs/help/Community-Guidelines.md
new file mode 100644 (file)
index 0000000..9789400
--- /dev/null
@@ -0,0 +1,20 @@
+All 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.
+
+<br>
+
+### 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.<p>
+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_**)<p>
+Silent Consent means that those who do not offer a reasoned alternative in course of the discussion implicitly agree with the proposal.
+
+<br>
+
+### 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.
diff --git a/tools/docs/help/Developer's-Guide.md b/tools/docs/help/Developer's-Guide.md
new file mode 100644 (file)
index 0000000..fe8d950
--- /dev/null
@@ -0,0 +1,3 @@
+ - [Getting Started](Getting-Started.md)
+ - [Developer Tutorial](Developer-Tutorial.md)
+ - [IoT.js API Reference](../api/IoT.js-API-reference.md)
\ No newline at end of file
diff --git a/tools/docs/help/Developer-Tutorial.md b/tools/docs/help/Developer-Tutorial.md
new file mode 100644 (file)
index 0000000..cb7189f
--- /dev/null
@@ -0,0 +1,161 @@
+### 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`.
\ No newline at end of file
diff --git a/tools/docs/help/Development-Process.md b/tools/docs/help/Development-Process.md
new file mode 100644 (file)
index 0000000..707b2d7
--- /dev/null
@@ -0,0 +1,69 @@
+* [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/).
\ No newline at end of file
diff --git a/tools/docs/help/Extended-API-Guideline.md b/tools/docs/help/Extended-API-Guideline.md
new file mode 100644 (file)
index 0000000..3400cbb
--- /dev/null
@@ -0,0 +1,63 @@
+Extended API Guideline
+======================
+
+Basically, our basic APIs are based on node.js. They will follow same form with node.js because of compatibility.<br>
+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.<br>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.<br>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.
diff --git a/tools/docs/help/Getting-Started.md b/tools/docs/help/Getting-Started.md
new file mode 100644 (file)
index 0000000..81c5582
--- /dev/null
@@ -0,0 +1,86 @@
+### Overview
+IoT.js is built based on JerryScript(lightweight JavaScript engine) and libuv for asynchronous I/O event handling.
+
+#### Source repositories
+* IoT.js: https://github.com/Samsung/iotjs.git
+* JerryScript: https://github.com/jerryscript-project/jerryscript.git
+* libuv: https://github.com/Samsung/libuv.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)
+```
+
+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
+
+##### 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
+
+1. Write a test case inside test directory.
+2. List up a test case in **test/testsets.js**. (this procedure will be removed after ``fs.readDir[Sync]`` is implemented.)
+3. Set attributes on the test case if it needs in **attrs.js** where the directory of your test case belongs.
+
+#### 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)
diff --git a/tools/docs/help/Getting-involved.md b/tools/docs/help/Getting-involved.md
new file mode 100644 (file)
index 0000000..18f2d39
--- /dev/null
@@ -0,0 +1,12 @@
+To 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)
\ No newline at end of file
diff --git a/tools/docs/help/Governance.md b/tools/docs/help/Governance.md
new file mode 100644 (file)
index 0000000..67d3522
--- /dev/null
@@ -0,0 +1,81 @@
+* [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.
\ No newline at end of file
diff --git a/tools/docs/help/IoT.js-Developer's-Certificate-of-Origin-1.0.md b/tools/docs/help/IoT.js-Developer's-Certificate-of-Origin-1.0.md
new file mode 100644 (file)
index 0000000..9dafce0
--- /dev/null
@@ -0,0 +1,42 @@
+The 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: <Your Name> <Your Email>" % content)
+```
+
+Please refer [Git Hooks](http://git-scm.com/book/en/v2/Customizing-Git-Git-Hooks) for more information.
\ No newline at end of file
diff --git a/tools/docs/help/Patch-Submission-Process.md b/tools/docs/help/Patch-Submission-Process.md
new file mode 100644 (file)
index 0000000..a6ad0c4
--- /dev/null
@@ -0,0 +1,40 @@
+The 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.
\ No newline at end of file
diff --git a/tools/include/iotjs.h b/tools/include/iotjs.h
new file mode 100644 (file)
index 0000000..a15070a
--- /dev/null
@@ -0,0 +1,30 @@
+/* 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 */
diff --git a/tools/iotjs_linux.c b/tools/iotjs_linux.c
new file mode 100644 (file)
index 0000000..78fb5d1
--- /dev/null
@@ -0,0 +1,20 @@
+/* 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);
+}
diff --git a/tools/js2c.py b/tools/js2c.py
new file mode 100755 (executable)
index 0000000..0e2fc5d
--- /dev/null
@@ -0,0 +1,310 @@
+#!/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 = 6
+
+    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 <stdio.h>
+#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 char {NAME}_s[];
+extern const int {NAME}_l;
+'''
+
+MODULE_VARIABLES_C = '''
+#define SIZE_{NAME_UPPER} {SIZE}
+const int {NAME}_l = SIZE_{NAME_UPPER};
+const char {NAME}_n[] = "{NAME}";
+const char {NAME}_s[] = {{
+{CODE}
+}};
+'''
+
+NATIVE_STRUCT_H = '''
+typedef struct {
+  const char* name;
+  const void* code;
+  const int 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: <module>,<module2>,...')
+    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)
diff --git a/tools/measure_coverage.sh b/tools/measure_coverage.sh
new file mode 100755 (executable)
index 0000000..fe4cfc6
--- /dev/null
@@ -0,0 +1,153 @@
+#!/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.
+
+function print_dep
+{
+  echo "The following dependencies are required:"
+  echo "    sudo apt install lcov gcc-multilib"
+  echo ""
+}
+
+function 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 ""
+}
+
+function print_npm_dep
+{
+  echo "The following node dependencies are required: "
+  echo "    npm install babel-cli nyc babel-plugin-istanbul"
+  echo ""
+}
+
+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
+
+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 4.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/iotjs/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
+$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/iotjs/
+genhtml -o coverage/c .c-coverage.info
+rm .c-coverage.info
+
+cd -
diff --git a/tools/mem_stats.sh b/tools/mem_stats.sh
new file mode 100755 (executable)
index 0000000..3bcdb3e
--- /dev/null
@@ -0,0 +1,124 @@
+#!/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" $tmpfile --memstat 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" $bench_canon --memstat | \
+    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
diff --git a/tools/module_analyzer.py b/tools/module_analyzer.py
new file mode 100644 (file)
index 0000000..ea79c4a
--- /dev/null
@@ -0,0 +1,225 @@
+#!/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 import path
+
+
+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'])
+
+    # By default the target included modules are:
+    #  - always module set from the build config
+    #  - modules specified by the command line argument
+    include_modules = set()
+    include_modules |= build_modules_always
+    include_modules |= options.iotjs_include_module
+
+    if not options.iotjs_minimal_profile:
+        # In case of normal build (not minimal profile):
+        # Check if there is any overlap between the included and excluded
+        # module sets which are from the build config
+        problem_modules = build_modules_includes & build_modules_excludes
+        if problem_modules:
+            print('Detected module(s) both in include and exclude list.',
+                  end=' ')
+            print('Module name(s): %s' % ', '.join(problem_modules))
+            ex.fail('Inconsistency in build config file!')
+
+        # Add the include set from the build config to
+        # the target include modules set
+        include_modules |= build_modules_includes
+
+    # Check if there is 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))
+
+    # Remove any excluded modules (defined by the command line argument) from
+    # the target include set
+    include_modules -= options.iotjs_exclude_module
+
+    # 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 included modules set from the excluded modules
+    exclude_modules -= include_modules
+
+    assert len(include_modules & exclude_modules) == 0, \
+        'Module can NOT be both in include and exclude list'
+
+    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': '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()
diff --git a/tools/precommit.py b/tools/precommit.py
new file mode 100755 (executable)
index 0000000..80b2dec
--- /dev/null
@@ -0,0 +1,185 @@
+#!/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', '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,
+                                   'targets', 'nuttx-stm32f4', 'app')):
+        fs.copy(fs.join(path.PROJECT_ROOT,'targets','nuttx-stm32f4','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,
+                    'targets',
+                    'nuttx-stm32f4',
+                    'nuttx',
+                    '.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)
+
+
+option = parse_option()
+config = get_config()
+if len(config['module']['exclude']) > 0 :
+    include_module = ','.join(config['module']['exclude'])
+    include_module = ['--iotjs-include-module=' + include_module]
+else:
+    include_module = []
+
+build_args = []
+
+if option.buildoptions:
+    build_args.extend(option.buildoptions.split(','))
+
+for test in option.test:
+    if test == "host":
+        for buildtype in option.buildtype:
+            build(buildtype, include_module + build_args)
+
+    elif test == "rpi2":
+        for buildtype in option.buildtype:
+            build(buildtype, ['--target-arch=arm', '--target-board=rpi2']
+                              + include_module + 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
+                              ] + include_module + 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']
+                              + include_module + 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']
+                       + include_module + build_args)
+
+        build("debug", ['--iotjs-minimal-profile'] + build_args)
+
+    elif test == "coverity":
+        build("debug", include_module + build_args)
diff --git a/tools/src/iotjs.c b/tools/src/iotjs.c
new file mode 100644 (file)
index 0000000..7e99b91
--- /dev/null
@@ -0,0 +1,214 @@
+/* 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 "jerry-port-default.h"
+#include "jerry-port.h"
+#include "jerryscript.h"
+
+#include <stdio.h>
+#include <string.h>
+
+
+/**
+ * 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;
+    jerry_port_default_set_log_level(JERRY_LOG_LEVEL_DEBUG);
+  }
+
+  if (iotjs_environment_config(env)->show_opcode) {
+    jerry_flag |= JERRY_INIT_SHOW_OPCODES;
+    jerry_port_default_set_log_level(JERRY_LOG_LEVEL_DEBUG);
+  }
+
+  // Initialize jerry.
+  jerry_init((jerry_init_flag_t)jerry_flag);
+
+  // 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(const iotjs_jval_t* process) {
+  // Evaluating 'iotjs.js' returns a function.
+  bool throws;
+#ifndef ENABLE_SNAPSHOT
+  iotjs_jval_t jmain = iotjs_jhelper_eval(iotjs_s, iotjs_l, false, &throws);
+#else
+  iotjs_jval_t jmain = iotjs_jhelper_exec_snapshot(iotjs_s, iotjs_l, &throws);
+#endif
+  IOTJS_ASSERT(!throws);
+
+  // Run the entry function passing process builtin.
+  // The entry function will continue initializing process module, global, and
+  // other native modules, and finally load and run application.
+  iotjs_jargs_t args = iotjs_jargs_create(1);
+  iotjs_jargs_append_jval(&args, process);
+
+  const iotjs_jval_t* global = iotjs_jval_get_global_object();
+  iotjs_jval_t jmain_res = iotjs_jhelper_call(&jmain, global, &args, &throws);
+
+  iotjs_jargs_destroy(&args);
+  iotjs_jval_destroy(&jmain);
+
+  if (throws) {
+    iotjs_uncaught_exception(&jmain_res);
+  }
+  iotjs_jval_destroy(&jmain_res);
+
+  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_run(process);
+
+  // 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));
+    }
+  } 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, 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;
+}
diff --git a/tools/src/iotjs_binding.c b/tools/src/iotjs_binding.c
new file mode 100644 (file)
index 0000000..9c8863e
--- /dev/null
@@ -0,0 +1,818 @@
+/* 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 <string.h>
+
+
+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);
+
+  _this->value = jerry_create_string_sz(data, size);
+
+  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,
+                                         JFreeHandlerType free_handler) {
+  const IOTJS_VALIDATED_STRUCT_METHOD(iotjs_jval_t, jobj);
+  IOTJS_ASSERT(iotjs_jval_is_object(jobj));
+
+  jerry_set_object_native_handle(_this->value, ptr, free_handler);
+}
+
+
+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;
+  jerry_get_object_native_handle(_this->value, &ptr);
+  return ptr;
+}
+
+
+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* data, size_t size, bool strict_mode,
+                                bool* throws) {
+  jerry_value_t res = jerry_eval((const jerry_char_t*)data, size, strict_mode);
+
+  *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;
+  if (!jerry_get_object_native_handle(jfunc, &target_function_ptr)) {
+    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);
+}
diff --git a/tools/src/iotjs_binding.h b/tools/src/iotjs_binding.h
new file mode 100644 (file)
index 0000000..6c1e27f
--- /dev/null
@@ -0,0 +1,300 @@
+/* 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 <stdio.h>
+
+
+typedef jerry_external_handler_t JHandlerType;
+typedef jerry_object_free_callback_t JFreeHandlerType;
+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,
+                                         JFreeHandlerType free_handler);
+uintptr_t iotjs_jval_get_object_native_handle(THIS_JVAL);
+
+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* 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)
+
+
+void iotjs_binding_initialize();
+void iotjs_binding_finalize();
+
+
+#endif /* IOTJS_BINDING_H */
diff --git a/tools/src/iotjs_binding_helper.c b/tools/src/iotjs_binding_helper.c
new file mode 100644 (file)
index 0000000..177099f
--- /dev/null
@@ -0,0 +1,124 @@
+/* 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+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);
+}
diff --git a/tools/src/iotjs_binding_helper.h b/tools/src/iotjs_binding_helper.h
new file mode 100644 (file)
index 0000000..5ebbaa4
--- /dev/null
@@ -0,0 +1,40 @@
+/* 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 */
diff --git a/tools/src/iotjs_debuglog.c b/tools/src/iotjs_debuglog.c
new file mode 100644 (file)
index 0000000..f2187fd
--- /dev/null
@@ -0,0 +1,66 @@
+/* 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 <stdio.h>
+#include <stdlib.h>
+
+#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
+}
diff --git a/tools/src/iotjs_debuglog.h b/tools/src/iotjs_debuglog.h
new file mode 100644 (file)
index 0000000..7468027
--- /dev/null
@@ -0,0 +1,65 @@
+/* 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 <stdio.h>
+
+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 */
diff --git a/tools/src/iotjs_def.h b/tools/src/iotjs_def.h
new file mode 100644 (file)
index 0000000..5d2788f
--- /dev/null
@@ -0,0 +1,170 @@
+/* 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 <uv.h>
+#include <assert.h>
+#include <limits.h> /* PATH_MAX */
+#include <stdbool.h>
+#include <string.h>
+
+// 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 */
diff --git a/tools/src/iotjs_env.c b/tools/src/iotjs_env.c
new file mode 100644 (file)
index 0000000..f81c9b7
--- /dev/null
@@ -0,0 +1,192 @@
+/* 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 <string.h>
+
+
+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(&current_env);
+    initialized = true;
+  }
+  return &current_env;
+}
+
+
+/**
+ * Release the singleton instance of iotjs_environment_t.
+ */
+void iotjs_environment_release() {
+  if (initialized) {
+    iotjs_environment_destroy(&current_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.
+    int i;
+    for (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,
+                                                    int argc, char** argv) {
+  IOTJS_VALIDATED_STRUCT_METHOD(iotjs_environment_t, env);
+
+  // There must be at least two arguments.
+  if (argc < 2) {
+    fprintf(stderr,
+            "usage: iotjs <js> [<iotjs arguments>] [-- <app arguments>]\n");
+    return false;
+  }
+
+  // Parse IoT.js command line arguments.
+  int i = 2;
+  while (i < argc) {
+    if (!strcmp(argv[i], "--")) {
+      ++i;
+      break;
+    }
+    if (!strcmp(argv[i], "--memstat")) {
+      _this->config.memstat = true;
+    } else if (!strcmp(argv[i], "--show-opcodes")) {
+      _this->config.show_opcode = true;
+    } else {
+      fprintf(stderr, "unknown command line argument %s\n", argv[i]);
+      return false;
+    }
+    ++i;
+  }
+
+  // Remaining arguments are for application.
+  _this->argc = 2;
+  size_t buffer_size = (_this->argc + argc - i) * sizeof(char*);
+  _this->argv = (char**)iotjs_buffer_allocate(buffer_size);
+  _this->argv[0] = argv[0];
+  _this->argv[1] = argv[1];
+  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;
+}
+
+int 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, int 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;
+}
diff --git a/tools/src/iotjs_env.h b/tools/src/iotjs_env.h
new file mode 100644 (file)
index 0000000..6174d4b
--- /dev/null
@@ -0,0 +1,72 @@
+/* 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;
+} Config;
+
+typedef enum {
+  kInitializing,
+  kRunningMain,
+  kRunningLoop,
+  kExiting,
+} State;
+
+
+typedef struct {
+  // Number of application arguments including 'iotjs' and app name.
+  int 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,
+                                                    int argc, char** argv);
+
+int iotjs_environment_argc(const iotjs_environment_t* env);
+const char* iotjs_environment_argv(const iotjs_environment_t* env, int 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 */
diff --git a/tools/src/iotjs_exception.c b/tools/src/iotjs_exception.c
new file mode 100644 (file)
index 0000000..bad8c26
--- /dev/null
@@ -0,0 +1,29 @@
+/* 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 <stdio.h>
+
+#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);
+}
diff --git a/tools/src/iotjs_exception.h b/tools/src/iotjs_exception.h
new file mode 100644 (file)
index 0000000..6be7916
--- /dev/null
@@ -0,0 +1,23 @@
+/* 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 */
diff --git a/tools/src/iotjs_handlewrap.c b/tools/src/iotjs_handlewrap.c
new file mode 100644 (file)
index 0000000..1885f08
--- /dev/null
@@ -0,0 +1,125 @@
+/* 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,
+                                 JFreeHandlerType jfreehandler) {
+  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, jfreehandler);
+
+  _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)));
+}
diff --git a/tools/src/iotjs_handlewrap.h b/tools/src/iotjs_handlewrap.h
new file mode 100644 (file)
index 0000000..b69f545
--- /dev/null
@@ -0,0 +1,72 @@
+/* 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 <uv.h>
+
+#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,
+                                 JFreeHandlerType jfreehandler);
+
+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 */
diff --git a/tools/src/iotjs_magic_strings.h b/tools/src/iotjs_magic_strings.h
new file mode 100644 (file)
index 0000000..a5ae5b8
--- /dev/null
@@ -0,0 +1,183 @@
+/* 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_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_EMIT "emit"
+#define IOTJS_MAGIC_STRING_EMITEXIT "emitExit"
+#define IOTJS_MAGIC_STRING_ENV "env"
+#define IOTJS_MAGIC_STRING_EXECUTE "execute"
+#define IOTJS_MAGIC_STRING_EXPORT "export"
+#define IOTJS_MAGIC_STRING_FAMILY "family"
+#define IOTJS_MAGIC_STRING_FINISH "finish"
+#define IOTJS_MAGIC_STRING_FLOAT "FLOAT"
+#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__INITARGV "_initArgv"
+#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_NODE_PATH "NODE_PATH"
+#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_READBLOCK "readBlock"
+#define IOTJS_MAGIC_STRING_READBYTE "readByte"
+#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_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_WRITEBLOCK "writeBlock"
+#define IOTJS_MAGIC_STRING_WRITEBYTE "writeByte"
+#define IOTJS_MAGIC_STRING_WRITESYNC "writeSync"
+#define IOTJS_MAGIC_STRING_WRITEUINT8 "writeUInt8"
+#define IOTJS_MAGIC_STRING_WRITE "write"
+
+#endif /* IOTJS_STRING_CONSTANTS_H */
diff --git a/tools/src/iotjs_module.c b/tools/src/iotjs_module.c
new file mode 100644 (file)
index 0000000..20a8080
--- /dev/null
@@ -0,0 +1,78 @@
+/* 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;
+}
diff --git a/tools/src/iotjs_module.h b/tools/src/iotjs_module.h
new file mode 100644 (file)
index 0000000..fb880b1
--- /dev/null
@@ -0,0 +1,75 @@
+/* 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 */
diff --git a/tools/src/iotjs_objectwrap.c b/tools/src/iotjs_objectwrap.c
new file mode 100644 (file)
index 0000000..b1f7c76
--- /dev/null
@@ -0,0 +1,61 @@
+/* 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,
+                                  JFreeHandlerType jfreehandler) {
+  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,
+                                      jfreehandler);
+}
+
+
+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;
+}
diff --git a/tools/src/iotjs_objectwrap.h b/tools/src/iotjs_objectwrap.h
new file mode 100644 (file)
index 0000000..e668295
--- /dev/null
@@ -0,0 +1,40 @@
+/* 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,
+                                  JFreeHandlerType jfreehandler);
+
+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);
+
+
+#endif /* IOTJS_OBJECTWRAP_H */
diff --git a/tools/src/iotjs_reqwrap.c b/tools/src/iotjs_reqwrap.c
new file mode 100644 (file)
index 0000000..ae9037f
--- /dev/null
@@ -0,0 +1,61 @@
+/* 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;
+}
diff --git a/tools/src/iotjs_reqwrap.h b/tools/src/iotjs_reqwrap.h
new file mode 100644 (file)
index 0000000..3fb99ac
--- /dev/null
@@ -0,0 +1,50 @@
+/* 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 <uv.h>
+
+#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 */
diff --git a/tools/src/iotjs_string.c b/tools/src/iotjs_string.c
new file mode 100644 (file)
index 0000000..b55aa1c
--- /dev/null
@@ -0,0 +1,132 @@
+/* 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 <string.h>
+
+
+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, uint32_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, uint32_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, uint32_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;
+}
diff --git a/tools/src/iotjs_string.h b/tools/src/iotjs_string.h
new file mode 100644 (file)
index 0000000..abec85f
--- /dev/null
@@ -0,0 +1,48 @@
+/* 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 {
+  uint32_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, uint32_t size);
+iotjs_string_t iotjs_string_create_with_buffer(char* buffer, uint32_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, uint32_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 */
diff --git a/tools/src/iotjs_string_ext.c b/tools/src/iotjs_string_ext.c
new file mode 100644 (file)
index 0000000..9cadefb
--- /dev/null
@@ -0,0 +1,66 @@
+/* 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);
+}
diff --git a/tools/src/iotjs_string_ext.h b/tools/src/iotjs_string_ext.h
new file mode 100644 (file)
index 0000000..f5d129b
--- /dev/null
@@ -0,0 +1,23 @@
+/* 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 */
diff --git a/tools/src/iotjs_util.c b/tools/src/iotjs_util.c
new file mode 100644 (file)
index 0000000..04fa7b2
--- /dev/null
@@ -0,0 +1,76 @@
+/* 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+iotjs_string_t iotjs_file_read(const char* path) {
+  FILE* file = fopen(path, "rb");
+  IOTJS_ASSERT(file != NULL);
+
+  fseek(file, 0, SEEK_END);
+  long len = ftell(file);
+  IOTJS_ASSERT(len >= 0);
+  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 == (size_t)len);
+
+  *(buffer + len) = 0;
+
+  fclose(file);
+
+  iotjs_string_t contents = iotjs_string_create_with_buffer(buffer, len);
+
+  return contents;
+}
+
+
+char* iotjs_buffer_allocate(unsigned size) {
+  char* buffer = (char*)(calloc(size, sizeof(char)));
+  IOTJS_ASSERT(buffer != NULL);
+  return buffer;
+}
+
+
+char* iotjs_buffer_reallocate(char* buffer, unsigned size) {
+  IOTJS_ASSERT(buffer != NULL);
+  return (char*)(realloc(buffer, size));
+}
+
+
+void iotjs_buffer_release(char* buffer) {
+  IOTJS_ASSERT(buffer != NULL);
+  free(buffer);
+}
diff --git a/tools/src/iotjs_util.h b/tools/src/iotjs_util.h
new file mode 100644 (file)
index 0000000..a1d1c3e
--- /dev/null
@@ -0,0 +1,37 @@
+/* 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(unsigned size);
+char* iotjs_buffer_reallocate(char* buffer, unsigned 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 */
diff --git a/tools/src/js/adc.js b/tools/src/js/adc.js
new file mode 100644 (file)
index 0000000..5d4eed9
--- /dev/null
@@ -0,0 +1,107 @@
+/* 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 new AdcPin(configuration, callback);
+};
+
+
+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')
+  }
+
+  this._binding = new adc.Adc(configuration, function(err) {
+    util.isFunction(callback) && callback.call(self, err);
+  });
+
+  process.on('exit', (function(self) {
+    return function() {
+      if (!util.isNull(self._binding)) {
+        self.closeSync();
+      }
+    };
+  })(this));
+}
+
+AdcPin.prototype.read = function(callback) {
+  var self = this;
+
+  if (util.isNull(this._binding)) {
+    throw new Error('ADC pin is not opened');
+  }
+
+  this._binding.read(function(err, value) {
+    util.isFunction(callback) && callback.call(self, err, value);
+  });
+};
+
+AdcPin.prototype.readSync = function() {
+  if (util.isNull(this._binding)) {
+    throw new Error('ADC pin is not opened');
+  }
+
+  return this._binding.read();
+};
+
+AdcPin.prototype.close = function(callback) {
+  var self = this;
+
+  if (util.isNull(this._binding)) {
+    throw new Error('ADC pin is not opened');
+  }
+
+  this._binding.close(function(err) {
+    util.isFunction(callback) && callback.call(self, err);
+  });
+
+  this._binding = null;
+};
+
+AdcPin.prototype.closeSync = function() {
+  if (util.isNull(this._binding)) {
+    throw new Error('ADC pin is not opened');
+  }
+
+  this._binding.close();
+
+  this._binding = null;
+};
+
+module.exports = Adc;
diff --git a/tools/src/js/assert.js b/tools/src/js/assert.js
new file mode 100644 (file)
index 0000000..ec43ba9
--- /dev/null
@@ -0,0 +1,153 @@
+// 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 (!(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;
diff --git a/tools/src/js/ble.js b/tools/src/js/ble.js
new file mode 100644 (file)
index 0000000..6d1d2cb
--- /dev/null
@@ -0,0 +1,270 @@
+/* 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; //requir('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') {
+  // `requir` is intentional errta  to avoid pre-build module dependency analyzer error
+  // The analyzer does not understand comment
+  // bindings = requir('./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();
diff --git a/tools/src/js/ble_characteristic.js b/tools/src/js/ble_characteristic.js
new file mode 100644 (file)
index 0000000..f8f34c3
--- /dev/null
@@ -0,0 +1,129 @@
+/* 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; //requir('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;
diff --git a/tools/src/js/ble_descriptor.js b/tools/src/js/ble_descriptor.js
new file mode 100644 (file)
index 0000000..6c8b1f6
--- /dev/null
@@ -0,0 +1,53 @@
+/* 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; //requir('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;
diff --git a/tools/src/js/ble_hci_socket.js b/tools/src/js/ble_hci_socket.js
new file mode 100644 (file)
index 0000000..944ff7c
--- /dev/null
@@ -0,0 +1,50 @@
+/* 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;
diff --git a/tools/src/js/ble_hci_socket_acl_stream.js b/tools/src/js/ble_hci_socket_acl_stream.js
new file mode 100644 (file)
index 0000000..3a3bebb
--- /dev/null
@@ -0,0 +1,78 @@
+/* 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; //requir('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;
diff --git a/tools/src/js/ble_hci_socket_bindings.js b/tools/src/js/ble_hci_socket_bindings.js
new file mode 100644 (file)
index 0000000..2551e1d
--- /dev/null
@@ -0,0 +1,253 @@
+/* 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; //requir('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();
diff --git a/tools/src/js/ble_hci_socket_crypto.js b/tools/src/js/ble_hci_socket_crypto.js
new file mode 100644 (file)
index 0000000..28e715c
--- /dev/null
@@ -0,0 +1,112 @@
+/* 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
+};
diff --git a/tools/src/js/ble_hci_socket_gap.js b/tools/src/js/ble_hci_socket_gap.js
new file mode 100644 (file)
index 0000000..9d5f630
--- /dev/null
@@ -0,0 +1,247 @@
+/* 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; //requir('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;
diff --git a/tools/src/js/ble_hci_socket_gatt.js b/tools/src/js/ble_hci_socket_gatt.js
new file mode 100644 (file)
index 0000000..b18261c
--- /dev/null
@@ -0,0 +1,1090 @@
+/* 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; //requir('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;
diff --git a/tools/src/js/ble_hci_socket_hci.js b/tools/src/js/ble_hci_socket_hci.js
new file mode 100644 (file)
index 0000000..d1732f5
--- /dev/null
@@ -0,0 +1,644 @@
+/* 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; //requir('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;
diff --git a/tools/src/js/ble_hci_socket_hci_status.js b/tools/src/js/ble_hci_socket_hci_status.js
new file mode 100644 (file)
index 0000000..ef621d7
--- /dev/null
@@ -0,0 +1,103 @@
+/* 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"
+]
diff --git a/tools/src/js/ble_hci_socket_mgmt.js b/tools/src/js/ble_hci_socket_mgmt.js
new file mode 100644 (file)
index 0000000..dca71da
--- /dev/null
@@ -0,0 +1,126 @@
+/* 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; // requir('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();
diff --git a/tools/src/js/ble_hci_socket_smp.js b/tools/src/js/ble_hci_socket_smp.js
new file mode 100644 (file)
index 0000000..563e217
--- /dev/null
@@ -0,0 +1,198 @@
+/* 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; //requir('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: <none>
+    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;
diff --git a/tools/src/js/ble_primary_service.js b/tools/src/js/ble_primary_service.js
new file mode 100644 (file)
index 0000000..0e4b4c4
--- /dev/null
@@ -0,0 +1,58 @@
+/* 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; //requir('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;
diff --git a/tools/src/js/ble_uuid_util.js b/tools/src/js/ble_uuid_util.js
new file mode 100644 (file)
index 0000000..c8ee3d3
--- /dev/null
@@ -0,0 +1,43 @@
+/* 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;
+};
diff --git a/tools/src/js/buffer.js b/tools/src/js/buffer.js
new file mode 100644 (file)
index 0000000..558e509
--- /dev/null
@@ -0,0 +1,320 @@
+/* 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 (!(buffer instanceof Buffer))
+    throw new TypeError('buffer must be a Buffer instance');
+  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;
diff --git a/tools/src/js/console.js b/tools/src/js/console.js
new file mode 100644 (file)
index 0000000..3d1dfa1
--- /dev/null
@@ -0,0 +1,38 @@
+/* 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;
diff --git a/tools/src/js/constants.js b/tools/src/js/constants.js
new file mode 100644 (file)
index 0000000..a2f9e4d
--- /dev/null
@@ -0,0 +1,17 @@
+/* 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);
diff --git a/tools/src/js/dgram.js b/tools/src/js/dgram.js
new file mode 100644 (file)
index 0000000..0998896
--- /dev/null
@@ -0,0 +1,464 @@
+/* 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;
+
+  if (util.isFunction(arguments[arguments.length - 1]))
+    self.once('listening', arguments[arguments.length - 1]);
+
+  var address;
+  if (util.isObject(port)) {
+    address = port.address || '';
+    port = port.port;
+  } else {
+    address = util.isFunction(arguments[1]) ? '' : arguments[1];
+  }
+
+  // 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 (!(buffer instanceof 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);
+}
+
+
+Socket.prototype.ref = function() {
+  if (this._handle)
+    this._handle.ref();
+
+  return this;
+};
+
+
+Socket.prototype.unref = function() {
+  if (this._handle)
+    this._handle.unref();
+
+  return this;
+};
diff --git a/tools/src/js/dns.js b/tools/src/js/dns.js
new file mode 100644 (file)
index 0000000..70973e6
--- /dev/null
@@ -0,0 +1,79 @@
+/* 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');
+
+  var err = dnsBuiltin.getaddrinfo(
+      hostname,
+      family,
+      hints,
+      function(err, address, family) {
+        var errObj = null;
+        if (err) {
+          errObj = dnsException(err, 'getaddrinfo', hostname);
+        }
+        return callback(errObj, address, family);
+      });
+  return err;
+};
+
+
+// uv_getaddrinfo flags
+exports.ADDRCONFIG = dnsBuiltin.AI_ADDRCONFIG;
+exports.V4MAPPED = dnsBuiltin.AI_V4MAPPED;
diff --git a/tools/src/js/events.js b/tools/src/js/events.js
new file mode 100644 (file)
index 0000000..770e757
--- /dev/null
@@ -0,0 +1,132 @@
+/* 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");
+    }
+    return false;
+  }
+
+  var listeners = this._events[type];
+  if (util.isArray(listeners)) {
+    listeners = listeners.slice();
+    var len = arguments.length;
+    var args = new Array(len - 1);
+    for (var i = 1; i < len; ++i) {
+      args[i - 1] = arguments[i];
+    }
+    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);
+        break;
+      }
+    }
+  }
+
+  return this;
+
+};
+
+
+EventEmitter.prototype.removeAllListeners = function(type) {
+  if (arguments.length === 0) {
+    this._events = {};
+  } else {
+    delete this._events[type];
+  }
+
+  return this;
+};
diff --git a/tools/src/js/fs.js b/tools/src/js/fs.js
new file mode 100644 (file)
index 0000000..da7c8d3
--- /dev/null
@@ -0,0 +1,485 @@
+/* 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);
+
+
+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;
+
+
+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) {
+  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;
+  }
+  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.
+  }
+
+  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);
+  checkArgBuffer(data);
+  checkArgFunction(callback);
+
+  var fd;
+  var len;
+  var bytesWritten;
+
+  fs.open(path, 'w', function(err, _fd) {
+    if (err) {
+      return callback(err);
+    }
+
+    fd = _fd;
+    len = data.length;
+    bytesWritten = 0;
+
+    write();
+  });
+
+  var write = function() {
+    var tryN = (len - bytesWritten) >= 1024 ? 1023 : (len - bytesWritten);
+    fs.write(fd, data, 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 data
+      fs.close(fd, function(err) {
+        callback(err);
+      });
+    } else {
+      // continue writing
+      bytesWritten += n;
+      write();
+    }
+  };
+};
+
+
+fs.writeFileSync = function(path, data) {
+  checkArgString(path);
+  checkArgBuffer(data);
+
+  var fd = fs.openSync(path, 'w');
+  var len = data.length;
+  var bytesWritten = 0;
+
+  while (true) {
+    try {
+      var tryN = (len - bytesWritten) >= 1024 ? 1023 : (len - bytesWritten);
+      var n = fs.writeSync(fd, data, 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) {
+  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);
+  } else if (def) {
+    return convertMode(def);
+  }
+  return undefined;
+}
+
+
+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);
+}
diff --git a/tools/src/js/gpio.js b/tools/src/js/gpio.js
new file mode 100644 (file)
index 0000000..1c2e991
--- /dev/null
@@ -0,0 +1,175 @@
+/* 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 gpio = process.binding(process.binding.gpio);
+var util = require('util');
+
+
+var defaultConfiguration = {
+  direction: gpio.DIRECTION.OUT,
+  mode: gpio.MODE.NONE
+};
+
+
+function Gpio() {
+  if (!(this instanceof Gpio)) {
+    return new Gpio();
+  }
+}
+
+Gpio.prototype.open = function(configuration, callback) {
+  return new GpioPin(configuration, callback);
+};
+
+Gpio.prototype.DIRECTION = gpio.DIRECTION;
+
+Gpio.prototype.MODE = gpio.MODE;
+
+
+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
+  if (process.platform === 'linux') {
+    configuration.mode = defaultConfiguration.mode;
+  } else if (process.platform === 'nuttx') {
+    var mode = configuration.mode;
+    if (!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;
+    }
+  }
+
+  this._binding = new gpio.Gpio(configuration, function(err) {
+    util.isFunction(callback) && callback.call(self, err);
+  });
+
+  process.on('exit', (function(self) {
+    return function() {
+      if (!util.isNull(self._binding)) {
+        self.closeSync();
+      }
+    };
+  })(this));
+}
+
+GpioPin.prototype.write = function(value, callback) {
+  var self = this;
+
+  if (util.isNull(this._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');
+  }
+
+  this._binding.write(!!value, function(err) {
+    util.isFunction(callback) && callback.call(self, err);
+  });
+};
+
+GpioPin.prototype.writeSync = function(value) {
+  if (util.isNull(this._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');
+  }
+
+  this._binding.writeSync(!!value);
+};
+
+GpioPin.prototype.read = function(callback) {
+  var self = this;
+
+  if (util.isNull(this._binding)) {
+    throw new Error('GPIO pin is not opened');
+  }
+
+  this._binding.read(function(err, value) {
+    util.isFunction(callback) && callback.call(self, err, value);
+  });
+};
+
+GpioPin.prototype.readSync = function() {
+  if (util.isNull(this._binding)) {
+    throw new Error('GPIO pin is not opened');
+  }
+
+  return this._binding.readSync();
+};
+
+GpioPin.prototype.close = function(callback) {
+  var self = this;
+
+  if (util.isNull(this._binding)) {
+    throw new Error('GPIO pin is not opened');
+  }
+
+  this._binding.close(function(err) {
+    util.isFunction(callback) && callback.call(self, err);
+  });
+
+  this._binding = null;
+};
+
+GpioPin.prototype.closeSync = function() {
+  if (util.isNull(this._binding)) {
+    throw new Error('GPIO pin is not opened');
+  }
+
+  this._binding.closeSync();
+
+  this._binding = null;
+};
+
+
+module.exports = Gpio;
diff --git a/tools/src/js/http.js b/tools/src/js/http.js
new file mode 100644 (file)
index 0000000..80905e4
--- /dev/null
@@ -0,0 +1,41 @@
+/* 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;
+};
diff --git a/tools/src/js/http_client.js b/tools/src/js/http_client.js
new file mode 100644 (file)
index 0000000..ca865a9
--- /dev/null
@@ -0,0 +1,231 @@
+/* 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;
+  }
+  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);
+  });
+
+};
diff --git a/tools/src/js/http_common.js b/tools/src/js/http_common.js
new file mode 100644 (file)
index 0000000..feb07dc
--- /dev/null
@@ -0,0 +1,134 @@
+/* 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');
+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 Buffer = require('buffer');
+
+
+
+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 parser = this;
+  var stream = parser.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 parser = this;
+  var headers = info.headers;
+  var url = info.url;
+
+  if (!url) {
+    url = parser._url;
+    parser.url = "";
+  }
+
+  if (!headers) {
+    headers = parser._headers;
+    // FIXME: This should be impl. with Array
+    parser._headers = {};
+  }
+
+
+  parser.incoming = new IncomingMessage(parser.socket);
+  parser.incoming.url = url;
+
+  // add header fields of headers to incoming.headers
+  parser.incoming.addHeaders(headers);
+
+  if (util.isNumber(info.method)) {
+    // for server
+    parser.incoming.method = HTTPParser.methods[info.method];
+  } else {
+    // for client
+    parser.incoming.statusCode = info.status;
+    parser.incoming.statusMessage = info.status_msg;
+  }
+
+  // For client side, if response to 'HEAD' request, we will skip parsing body
+  var skipBody = parser.onIncoming(parser.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 parser = this;
+  var stream = parser.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);
+}
+
+
+function AddHeader(dest, src) {
+  if (!dest.length) {
+    dest.length = 0;
+  }
+
+  for (var i=0;i<src.length;i++) {
+    dest[dest.length+i] = src[i];
+  }
+  dest.length = dest.length + src.length;
+}
+
+
+// This is called when http header is fragmented and
+// HTTPParser sends it to JS in separate pieces.
+function parserOnHeaders(headers, url) {
+  // FIXME: This should be impl. with Array.concat
+  AddHeader(this._headers, headers);
+  if (url) {
+    this._url += url;
+  }
+}
diff --git a/tools/src/js/http_incoming.js b/tools/src/js/http_incoming.js
new file mode 100644 (file)
index 0000000..72249c1
--- /dev/null
@@ -0,0 +1,69 @@
+/* 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<headers.length; i=i+2) {
+    this.headers[headers[i]] = headers[i+1];
+  }
+};
+
+
+IncomingMessage.prototype.setTimeout = function(ms, cb) {
+  if (cb)
+    this.once('timeout', cb);
+  this.socket.setTimeout(ms, cb);
+};
diff --git a/tools/src/js/http_outgoing.js b/tools/src/js/http_outgoing.js
new file mode 100644 (file)
index 0000000..fb2bc3a
--- /dev/null
@@ -0,0 +1,188 @@
+/* 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 OutgoingMessage() {
+  stream.Stream.call(this);
+
+  this.writable = true;
+
+  this._hasBody = true;
+
+  this.finished = false;
+  this._sentHeader = false;
+
+  this.socket = null;
+  this.connection = null;
+  // response header string : same 'content' as this._headers
+  this._header = null;
+  // response header obj : (key, value) pairs
+  this._headers = {};
+
+}
+
+util.inherits(OutgoingMessage, stream.Stream);
+
+exports.OutgoingMessage = OutgoingMessage;
+
+
+OutgoingMessage.prototype.end = function(data, encoding, callback) {
+  var self = this;
+
+  if (util.isFunction(data)) {
+    callback = data;
+    data = null;
+  } else if (util.isFunction(encoding)) {
+    callback = encoding;
+    encoding = null;
+  }
+
+  if (this.finished) {
+    return false;
+  }
+
+  // flush header
+  if (!this._header) {
+    this._implicitHeader();
+  }
+
+  if (data) {
+    this.write(data, encoding);
+  }
+
+  // Register finish event handler.
+  if (util.isFunction(callback)) {
+    this.once('finish', callback);
+  }
+
+  // Force flush buffered data.
+  // After all data was sent, emit 'finish' event meaning segment of header and
+  // body were all sent finished. This means different from 'finish' event
+  // emitted by net which indicate there will be no more data to be sent through
+  // the connection. On the other hand emitting 'finish' event from http does
+  // not neccessarily imply end of data transmission since there might be
+  // another segment of data when connection is 'Keep-Alive'.
+  this._send('', function() {
+    self.emit('finish');
+  });
+
+
+  this.finished = true;
+
+  this._finish();
+
+  return true;
+};
+
+
+OutgoingMessage.prototype._finish = function() {
+  this.emit('prefinish');
+};
+
+
+// This sends chunk directly into socket
+// TODO: buffering of chunk in the case of socket is not available
+OutgoingMessage.prototype._send = function(chunk, encoding, callback) {
+  if (util.isFunction(encoding)) {
+    callback = encoding;
+  }
+
+  if (util.isBuffer(chunk)) {
+    chunk = chunk.toString();
+  }
+
+  if (!this._sentHeader) {
+    chunk = this._header + "\r\n" + chunk;
+    this._sentHeader = true;
+  }
+
+  return this.connection.write(chunk, encoding, callback);
+};
+
+
+OutgoingMessage.prototype.write = function(chunk, encoding, callback) {
+  if (!this._header) {
+    this._implicitHeader();
+  }
+
+  if (!this._hasBody) {
+    return true;
+  }
+
+  var ret = this._send(chunk, encoding, callback);
+
+  return ret;
+
+};
+
+
+// Stringfy header fields of _headers into _header
+OutgoingMessage.prototype._storeHeader = function(statusLine) {
+  var headerStr = '';
+
+  var keys;
+  if (this._headers) {
+    keys = Object.keys(this._headers);
+    for (var i=0; i<keys.length; i++) {
+      var key = keys[i];
+      headerStr += key + ": " + this._headers[key] + '\r\n';
+    }
+  }
+
+  this._header = statusLine + headerStr;
+
+};
+
+
+OutgoingMessage.prototype.setHeader = function(name, value) {
+
+  if (this._headers === null) {
+    this._headers = {};
+  }
+
+  this._headers[name] = value;
+
+};
+
+
+OutgoingMessage.prototype.removeHeader = function(name) {
+  if (this._headers === null) {
+    return;
+  }
+
+  delete this._headers[name];
+};
+
+
+OutgoingMessage.prototype.getHeader = function(name) {
+  return this._headers[name];
+};
+
+
+OutgoingMessage.prototype.setTimeout = function(ms, cb) {
+  if (cb)
+    this.once('timeout', cb);
+
+  if (!this.socket) {
+    this.once('socket', function(socket) {
+      socket.setTimeout(msecs);
+    });
+  } else
+    this.socket.setTimeout(msecs);
+};
diff --git a/tools/src/js/http_server.js b/tools/src/js/http_server.js
new file mode 100644 (file)
index 0000000..bad92d1
--- /dev/null
@@ -0,0 +1,305 @@
+/* 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');
+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');
+
+// RFC 7231 (http://tools.ietf.org/html/rfc7231#page-49)
+var STATUS_CODES = exports.STATUS_CODES = {
+  100 : 'Continue',
+  101 : 'Switching Protocols',
+  200 : 'OK',
+  201 : 'Created',
+  202 : 'Accepted',
+  203 : 'Non-Authoritative Information',
+  204 : 'No Content',
+  205 : 'Reset Content',
+  206 : 'Partial Content',
+  300 : 'Multiple Choices',
+  301 : 'Moved Permanently',
+  302 : 'Found',
+  303 : 'See Other',
+  304 : 'Not Modified',
+  305 : 'Use Proxy',
+  307 : 'Temporary Redirect',
+  400 : 'Bad Request',
+  401 : 'Unauthorized',
+  402 : 'Payment Required',
+  403 : 'Forbidden',
+  404 : 'Not Found',
+  405 : 'Method Not Allowed',
+  406 : 'Not Acceptable',
+  407 : 'Proxy Authentication Required',
+  408 : 'Request Timeout',
+  409 : 'Conflict',
+  410 : 'Gone',
+  411 : 'Length Required',
+  412 : 'Precondition Failed',
+  413 : 'Payload Too Large',
+  414 : 'URI Too Large',
+  415 : 'Unsupported Media Type',
+  416 : 'Range Not Satisfiable',
+  417 : 'Expectation Failed',
+  426 : 'Upgrade Required',
+  500 : 'Internal Server Error',
+  501 : 'Not Implemented',
+  502 : 'Bad Gateway',
+  503 : 'Service Unavailable',
+  504 : 'Gateway Time-out',
+  505 : 'HTTP Version Not Supported'
+};
+
+
+// response to req
+function ServerResponse(req) {
+  OutgoingMessage.call(this);
+  // response to HEAD method has no body
+  if (req.method === 'HEAD') this._hasBody = false;
+}
+
+util.inherits(ServerResponse, OutgoingMessage);
+
+
+// default status code : 200
+ServerResponse.prototype.statusCode = 200;
+ServerResponse.prototype.statusMessage = undefined;
+
+
+// if user does not set Header before write(..),
+// this function set default header(200).
+ServerResponse.prototype._implicitHeader = function() {
+  this.writeHead(this.statusCode);
+};
+
+
+ServerResponse.prototype.writeHead = function(statusCode, reason, obj) {
+  if (util.isString(reason)) {
+    this.statusMessage = reason;
+  }
+  else {
+    this.statusMessage = STATUS_CODES[statusCode] || 'unknown';
+    obj = reason;
+  }
+
+  var statusLine = util.format('HTTP/1.1 %s %s\r\n',
+                               statusCode.toString(),
+                               this.statusMessage);
+
+  this.statusCode = statusCode;
+
+  // HTTP response without body
+  if (statusCode === 204 || statusCode === 304 ||
+      (100 <= statusCode && statusCode <= 199)) {
+    this._hasBody = false;
+  }
+
+  if (util.isObject(obj)) {
+    if (util.isNullOrUndefined(this._headers)) {
+      this._headers = {};
+    }
+    for (key in Object.keys(obj)) {
+      this._headers[key] = obj[key];
+    }
+  }
+
+  this._storeHeader(statusLine);
+};
+
+
+ServerResponse.prototype.assignSocket = function(socket) {
+  socket._httpMessage = this;
+  this.socket = socket;
+  this.connection = socket;
+  socket.on('close', onServerResponseClose);
+  this.emit('socket', socket);
+};
+
+
+function onServerResponseClose() {
+  if (this._httpMessage) {
+    this._httpMessage.emit('close');
+  }
+}
+
+
+ServerResponse.prototype.detachSocket = function() {
+  this.socket._httpMessage = null;
+  this.socket = this.connection = null;
+};
+
+
+function Server(requestListener) {
+  if (!(this instanceof Server)) {
+    return new Server(requestListener);
+  }
+
+  net.Server.call(this, {allowHalfOpen: true});
+
+  if (util.isFunction(requestListener)) {
+    this.addListener('request', requestListener);
+  }
+
+  this.httpAllowHalfOpen = false;
+
+  this.on('connection', connectionListener);
+  this.on('clientError', function(err, conn) {
+    conn.destroy(err);
+  });
+
+  this.timeout = 2 * 1000 * 60; // default timeout is 2 min
+}
+
+util.inherits(Server, net.Server);
+exports.Server = Server;
+
+
+// TODO: Implement Server.prototype.setTimeout function
+// For this, socket.prototype.setTimeout is needed.
+Server.prototype.setTimeout = function (ms, cb) {
+  this.timeout = ms;
+  if (cb) {
+    this.on('timeout', cb);
+  }
+};
+
+
+function connectionListener(socket) {
+  var server = this;
+
+  // cf) In Node.js, freelist returns a new parser.
+  // parser initialize
+  var parser = common.createHTTPParser();
+  // FIXME: This should be impl. with Array
+  parser._headers = {};
+  parser._url = '';
+
+  parser.onIncoming = parserOnIncoming;
+
+  parser.socket = socket;
+  parser.incoming = null;
+  socket.parser = parser;
+
+  socket.on("data", socketOnData);
+  socket.on("end", socketOnEnd);
+  socket.on("close", socketOnClose);
+  socket.on('timeout', socketOnTimeout);
+  socket.on("error", socketOnError);
+
+  if (server.timeout) {
+    socket.setTimeout(server.timeout);
+  }
+}
+
+
+function socketOnData(data) {
+  var socket = this;
+
+  // Begin parsing
+  var ret = socket.parser.execute(data);
+
+  if (ret instanceof Error) {
+    socket.destroy();
+  }
+}
+
+
+function socketOnEnd() {
+  var socket = this;
+  var server = socket._server;
+  var ret = socket.parser.finish();
+
+  if (ret instanceof Error) {
+    socket.destroy();
+    return;
+  }
+
+  socket.parser = null;
+
+  if (!server.httpAllowHalfOpen && socket._socketState.writable) {
+    socket.end();
+  }
+}
+
+
+function socketOnClose() {
+  var socket = this;
+
+  if (socket.parser) {
+    socket.parser = null;
+  }
+}
+
+
+function socketOnTimeout() {
+  var socket = this;
+  var server = socket._server;
+
+  var serverTimeout = server.emit('timeout', socket);
+  var req = socket.parser && socket.parser.incoming;
+  var reqTimeout = req && !req.complete && req.emit('timeout', socket);
+  var res = socket._httpMessage;
+  var resTimeout = res && res.emit('timeout', socket);
+
+  // if user doesn't provide timeout handler, kill socket.
+  // otherwise, user cb must take care of timeouted socket.
+  if (!serverTimeout && !reqTimeout && !resTimeout) {
+    socket.destroy();
+  }
+}
+
+
+function socketOnError(err) {
+  var socket = this;
+  var server = socket._server;
+
+  server.emit("clientError", err, socket);
+}
+
+
+// This is called by parserOnHeadersComplete after req header is parsed.
+// TODO: keepalive support
+function parserOnIncoming(req, shouldKeepAlive) {
+  var socket = req.socket;
+  var server = socket._server;
+
+  var res = new ServerResponse(req);
+  res.assignSocket(socket);
+  res.on('prefinish', resOnFinish);
+
+  server.emit('request', req, res);
+
+  // In server, HTTPParser determines whether body should be parsed or not.
+  // It is fine to return false
+  return false;
+}
+
+
+// This cb is called when response ended
+// (res.end emits 'prefinish' event)
+function resOnFinish() {
+  var res = this;
+  var socket = res.socket;
+
+  res.detachSocket();
+
+  // cf) In Node, ConnectionListener has a list of incoming msgs.
+  socket.destroySoon();
+}
diff --git a/tools/src/js/i2c.js b/tools/src/js/i2c.js
new file mode 100644 (file)
index 0000000..17cfde2
--- /dev/null
@@ -0,0 +1,173 @@
+/* Copyright (c) 2013, Kelly Korevec <korevec@gmail.com>
+ * 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) {
+  var i2c_bus = new I2CBus(configurable, callback);
+  return i2c_bus;
+};
+
+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;
+
+    this.i2c = 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() {
+  this.i2c.close();
+};
+
+
+I2CBus.prototype.setAddress = function(address, callback) {
+  if (!util.isNumber(address)) {
+    throw new TypeError('Bad argument - address: Number');
+  }
+
+  this.address = address;
+  this.i2c.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);
+  this.i2c.write(array, function(err) {
+    util.isFunction(callback) && callback(err);
+  });
+};
+
+I2CBus.prototype.writeByte = function(byte, callback) {
+  if (!util.isNumber(byte)) {
+    throw new TypeError('Bad argument - byte: Number');
+  }
+
+  this.setAddress(this.address);
+  this.i2c.writeByte(byte, function(err) {
+    util.isFunction(callback) && callback(err);
+  });
+};
+
+I2CBus.prototype.writeBytes = function(cmd, array, callback) {
+  if (!util.isNumber(cmd)) {
+    throw new TypeError('Bad argument - cmd: Number');
+  }
+  if (!util.isArray(array)) {
+    throw new TypeError('Bad argument - array: Array');
+  }
+
+  this.setAddress(this.address);
+  this.i2c.writeBlock(cmd, 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);
+  this.i2c.read(length, function(err, data) {
+    util.isFunction(callback) && callback(err, data);
+  });
+};
+
+I2CBus.prototype.readByte = function(callback) {
+  this.setAddress(this.address);
+  this.i2c.readByte(function(err, data) {
+    util.isFunction(callback) && callback(err, data);
+  });
+};
+
+I2CBus.prototype.readBytes = function(cmd, length, callback) {
+  if (!util.isNumber(cmd)) {
+    throw new TypeError('Bad argument - cmd: Number');
+  }
+  if (!util.isNumber(length)) {
+    throw new TypeError('Bad argument - length: Number');
+  }
+
+  this.setAddress(this.address);
+  this.i2c.readBlock(cmd, length, 0, function(err, resArray) {
+    util.isFunction(callback) && callback(err, resArray);
+  });
+};
+
+module.exports = I2C;
diff --git a/tools/src/js/iotjs.js b/tools/src/js/iotjs.js
new file mode 100644 (file)
index 0000000..b533800
--- /dev/null
@@ -0,0 +1,223 @@
+/* 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(process) {
+
+  this.global = this;
+  global.process = process;
+
+
+  function startIoTjs() {
+    initGlobal();
+    initTimers();
+
+    initProcess();
+
+    var module = Native.require('module');
+
+    module.runMain();
+  };
+
+
+  function initGlobal() {
+    global.process = process;
+    global.global = global;
+    global.GLOBAL = global;
+    global.root = global;
+    global.console = Native.require('console');
+    global.Buffer = Native.require('buffer');
+  };
+
+
+  function initTimers() {
+    global.setTimeout = function() {
+      var t = Native.require('timers');
+      return t.setTimeout.apply(this, arguments);
+    };
+
+    global.setInterval = function() {
+      var t = Native.require('timers');
+      return t.setInterval.apply(this, arguments);
+    };
+
+    global.clearTimeout = function() {
+      var t = Native.require('timers');
+      return t.clearTimeout.apply(this, arguments);
+    };
+
+    global.clearInterval = function() {
+      var t = Native.require('timers');
+      return t.clearInterval.apply(this, arguments);
+    };
+  }
+
+
+  function initProcess() {
+    initProcessArgv();
+    initProcessEvents();
+    initProcessNextTick();
+    initProcessUncaughtException();
+    initProcessExit();
+  }
+
+
+  // Initialize `process.argv`
+  function initProcessArgv() {
+    process.argv = [];
+    process._initArgv();
+  }
+
+
+  function initProcessEvents() {
+    var EventEmitter = Native.require('events').EventEmitter;
+
+    EventEmitter.call(process);
+
+    var keys = Object.keys(EventEmitter.prototype);
+    for (var i = 0; i < keys.length; ++i) {
+      var key = keys[i];
+      if (!process[key]) {
+        process[key] = EventEmitter.prototype[key];
+      }
+    }
+  }
+
+
+  function initProcessNextTick() {
+    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 = [];
+
+      for (var i = 0; i < callbacks.length; ++i) {
+        try {
+          callbacks[i]();
+        } catch (e) {
+          process._onUncaughtException(e);
+        }
+      }
+
+      return nextTickQueue.length > 0;
+    }
+
+    function nextTick(callback) {
+      nextTickQueue.push(callback);
+    }
+  }
+
+
+  function initProcessUncaughtException() {
+    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);
+      }
+    }
+  }
+
+
+  function initProcessExit() {
+    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);
+      }
+    };
+  }
+
+
+  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);
+  };
+
+  startIoTjs();
+
+});
diff --git a/tools/src/js/module.js b/tools/src/js/module.js
new file mode 100644 (file)
index 0000000..861a714
--- /dev/null
@@ -0,0 +1,221 @@
+/* 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 + "/node_modules/");
+}
+if(process.env.HOME){
+  moduledirs.push(process.env.HOME + "/node_modules/");
+}
+if(process.env.NODE_PATH){
+  moduledirs.push(process.env.NODE_PATH + "/node_modules/")
+}
+
+iotjs_module_t.concatdir = function(a, b){
+  var rlist = [];
+  for(var i = 0; i< a.length ; i++) {
+    rlist.push(a[i]);
+  }
+
+  for(var i = 0; i< b.length ; i++) {
+    rlist.push(b[i]);
+  }
+
+  return rlist;
+};
+
+
+iotjs_module_t.resolveDirectories = function(id, parent) {
+  var dirs = moduledirs;
+  if(parent) {
+    if(!parent.dirs){
+      parent.dirs = [];
+    }
+    dirs = iotjs_module_t.concatdir(parent.dirs, dirs);
+  }
+  return dirs;
+};
+
+
+iotjs_module_t.resolveFilepath = function(id, directories) {
+
+  for(var i = 0; i<directories.length ; i++) {
+    var dir = directories[i];
+    // 1. 'id'
+    var filepath = iotjs_module_t.tryPath(dir+id);
+
+    if(filepath){
+      return filepath;
+    }
+
+    // 2. 'id.js'
+    filepath = iotjs_module_t.tryPath(dir+id+'.js');
+
+    if(filepath){
+      return filepath;
+    }
+
+    // 3. package path /node_modules/id
+    var packagepath = dir + id;
+    var jsonpath = packagepath + "/package.json";
+    filepath = iotjs_module_t.tryPath(jsonpath);
+    if(filepath){
+      var pkgSrc = process.readSource(jsonpath);
+      var pkgMainFile = JSON.parse(pkgSrc).main;
+      filepath = iotjs_module_t.tryPath(packagepath + "/" + pkgMainFile);
+      if(filepath){
+        return filepath;
+      }
+      // index.js
+      filepath = iotjs_module_t.tryPath(packagepath + "/" + "index.js");
+      if(filepath){
+        return filepath;
+      }
+    }
+
+  }
+
+  return false;
+};
+
+
+iotjs_module_t.resolveModPath = function(id, parent) {
+
+  // 0. resolve Directory for lookup
+  var directories = iotjs_module_t.resolveDirectories(id, parent);
+
+  var filepath = iotjs_module_t.resolveFilepath(id, directories);
+
+  if(filepath){
+    return filepath;
+  }
+
+  return false;
+};
+
+
+iotjs_module_t.tryPath = function(path) {
+  var stats = iotjs_module_t.statPath(path);
+  if(stats && !stats.isDirectory()) {
+    return path;
+  }
+  else {
+    return false;
+  }
+};
+
+
+iotjs_module_t.statPath = function(path) {
+  try {
+    return fs.statSync(path);
+  } catch (ex) {}
+  return false;
+};
+
+
+iotjs_module_t.load = function(id, parent, isMain) {
+  if(process.native_sources[id]){
+    return Native.require(id);
+  }
+  var module = new iotjs_module_t(id, parent);
+
+  var modPath = iotjs_module_t.resolveModPath(module.id, module.parent);
+
+  var cachedModule = iotjs_module_t.cache[modPath];
+  if (cachedModule) {
+    return cachedModule.exports;
+  }
+
+  if (modPath) {
+    module.filename = modPath;
+    module.SetModuleDirs(modPath);
+    module.compile();
+  }
+  else {
+    throw new Error('No module found');
+  }
+
+  iotjs_module_t.cache[modPath] = module;
+
+  return module.exports;
+};
+
+
+iotjs_module_t.prototype.compile = function() {
+  var self = this;
+  var requireForThis = function(path) {
+      return self.require(path);
+  };
+
+  var source = process.readSource(self.filename);
+  var fn = process.compile(source);
+  fn.call(self.exports, self.exports, requireForThis, self);
+};
+
+
+iotjs_module_t.runMain = function(){
+  iotjs_module_t.load(process.argv[1], null, true);
+  process._onNextTick();
+};
+
+
+
+iotjs_module_t.prototype.SetModuleDirs = function(filepath)
+{
+  // At next require, search module from parent's directory
+  var dir = "";
+  var i;
+  for(i = filepath.length-1;i>=0 ; i--) {
+    if(filepath[i] == '/'){
+      break;
+    }
+  }
+
+  // save filepath[0] to filepath[i]
+  // e.g. /home/foo/main.js ->  /home/foo/
+  for(;i>=0 ; i--) {
+    dir = filepath[i] + dir;
+  }
+  this.dirs = [dir];
+};
+
+
+iotjs_module_t.prototype.require = function(id) {
+  return iotjs_module_t.load(id, this);
+};
diff --git a/tools/src/js/net.js b/tools/src/js/net.js
new file mode 100644 (file)
index 0000000..3af8b90
--- /dev/null
@@ -0,0 +1,647 @@
+/* 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 stream = require('stream');
+var util = require('util');
+var assert = require('assert');
+
+var TCP = process.binding(process.binding.tcp);
+
+
+function createTCP() {
+  var tcp = new TCP();
+  return tcp;
+}
+
+
+function SocketState(options) {
+  // 'true' during connection handshaking.
+  this.connecting = false;
+
+  // become 'true' when connection established.
+  this.connected = false;
+
+  this.writable = true;
+  this.readable = true;
+
+  this.destroyed = false;
+
+  this.allowHalfOpen = options && options.allowHalfOpen || false;
+}
+
+
+function Socket(options) {
+  if (!(this instanceof Socket)) {
+    return new Socket(options);
+  }
+
+  if (util.isUndefined(options)) {
+    options = {};
+  }
+
+  stream.Duplex.call(this, options);
+
+  this._timer = null;
+  this._timeout = 0;
+
+  this._socketState = new SocketState(options);
+
+  if (options.handle) {
+    this._handle = options.handle;
+    this._handle.owner = this;
+  }
+
+  this.on('finish', onSocketFinish);
+  this.on('end', onSocketEnd);
+}
+
+
+// Socket inherits Duplex.
+util.inherits(Socket, stream.Duplex);
+
+
+Socket.prototype.connect = function() {
+  var self = this;
+  var state = self._socketState;
+
+  var args = normalizeConnectArgs(arguments);
+  var options = args[0];
+  var callback = args[1];
+
+  if (state.connecting || state.connected) {
+    return self;
+  }
+
+  if (!self._handle) {
+    self._handle = createTCP();
+    self._handle.owner = self;
+  }
+
+  if (util.isFunction(callback)) {
+    self.once('connect', callback);
+  }
+
+  resetSocketTimeout(self);
+
+  state.connecting = true;
+
+  var dns = require('dns');
+  var host = options.host ? options.host : 'localhost';
+  var port = options.port;
+  var dnsopts = {
+    family: options.family >>> 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('port should be 4 or 6: ' + dnsopts.family);
+
+  self._host = host;
+  dns.lookup(host, dnsopts, function(err, ip, family) {
+    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.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) {
+    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: ' + status));
+    }
+  };
+
+  socket._handle.connect(ip, port, afterConnect);
+}
+
+
+function close(socket) {
+  socket._handle.owner = socket;
+  socket._handle.onclose = function() {
+    socket.emit('close');
+  };
+
+  socket._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) {
+    // 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 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 err;
+  }
+
+  process.nextTick(function() {
+    if (self._handle) {
+      self.emit('listening');
+    }
+  });
+};
+
+
+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: ' + 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[, connectListenr])
+// 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;
diff --git a/tools/src/js/pwm.js b/tools/src/js/pwm.js
new file mode 100644 (file)
index 0000000..0b866f1
--- /dev/null
@@ -0,0 +1,230 @@
+/* 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 new PwmPin(configuration, callback);
+};
+
+
+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;
+  }
+
+  this._binding = new pwm(self._configuration, function(err) {
+    util.isFunction(callback) && callback.call(self, err);
+  });
+
+  process.on('exit', (function(self) {
+    return function() {
+      if (!util.isNull(self._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(this._binding)) {
+    throw new Error('Pwm pin is not opened');
+  }
+
+  if (this._validatePeriod(period)) {
+    this._binding.setPeriod(period, function(err) {
+      util.isFunction(callback) && callback.call(self, err);
+    });
+  }
+};
+
+PwmPin.prototype.setPeriodSync = function(period) {
+  if (util.isNull(this._binding)) {
+    throw new Error('Pwm pin is not opened');
+  }
+
+  if (this._validatePeriod(period)) {
+    this._binding.setPeriod(period);
+  }
+};
+
+PwmPin.prototype.setFrequency = function(frequency, callback) {
+  var self = this;
+
+  if (util.isNull(this._binding)) {
+    throw new Error('Pwm pin is not opened');
+  }
+
+  if (this._validateFrequency(frequency)) {
+    this._binding.setPeriod(1.0 / frequency, function(err) {
+      util.isFunction(callback) && callback.call(self, err);
+    });
+  }
+};
+
+PwmPin.prototype.setFrequencySync = function(frequency) {
+  if (util.isNull(this._binding)) {
+    throw new Error('Pwm pin is not opened');
+  }
+
+  if (this._validateFrequency(frequency)) {
+    this._binding.setPeriod(1.0 / frequency);
+  }
+};
+
+PwmPin.prototype.setDutyCycle = function(dutyCycle, callback) {
+  var self = this;
+
+  if (util.isNull(this._binding)) {
+    throw new Error('Pwm pin is not opened');
+  }
+
+  // Check arguments.
+  if (this._validateDutyCycle(dutyCycle)) {
+    this._binding.setDutyCycle(dutyCycle, function(err) {
+      util.isFunction(callback) && callback.call(self, err);
+    });
+  }
+};
+
+PwmPin.prototype.setDutyCycleSync = function(dutyCycle) {
+  if (util.isNull(this._binding)) {
+    throw new Error('Pwm pin is not opened');
+  }
+
+  // Check arguments.
+  if (this._validateDutyCycle(dutyCycle)) {
+    this._binding.setDutyCycle(dutyCycle);
+  }
+};
+
+PwmPin.prototype.setEnable = function(enable, callback) {
+  var self = this;
+
+  if (util.isNull(this._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));
+  }
+
+  this._binding.setEnable(!!enable, function(err) {
+    util.isFunction(callback) && callback.call(self, err);
+  });
+};
+
+PwmPin.prototype.setEnableSync = function(enable) {
+  if (util.isNull(this._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));
+  }
+
+  this._binding.setEnable(!!enable);
+};
+
+PwmPin.prototype.close = function(callback) {
+  if (util.isNull(this._binding)) {
+    throw new Error('Pwm pin is not opened');
+  }
+
+  this._binding.close(function(err) {
+    util.isFunction(callback) && callback.call(self, err);
+  });
+};
+
+PwmPin.prototype.closeSync = function() {
+  if (util.isNull(this._binding)) {
+    throw new Error('Pwm pin is not opened');
+  }
+
+  this._binding.close();
+};
+
+module.exports = Pwm;
diff --git a/tools/src/js/spi.js b/tools/src/js/spi.js
new file mode 100644 (file)
index 0000000..17e30e5
--- /dev/null
@@ -0,0 +1,214 @@
+/* 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 new SpiBus(configuration, callback);
+};
+
+Spi.prototype.MODE = spi.MODE;
+Spi.prototype.CHIPSELECT = spi.CHIPSELECT;
+Spi.prototype.BITORDER = spi.BITORDER;
+
+
+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;
+  }
+
+  this._binding = new spi.Spi(configuration, function(err) {
+   util.isFunction(callback) && callback.call(self, err);
+  });
+
+  process.on('exit', (function(self) {
+   return function() {
+     if (!util.isNull(self._binding)) {
+       self.closeSync();
+     }
+   };
+  })(this));
+}
+
+SpiBus.prototype.transfer = function(txBuffer, rxBuffer, callback) {
+  var self = this;
+
+  if (util.isNull(this._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)) {
+    this._binding.transferArray(txBuffer, rxBuffer, afterCallback);
+  } else if (util.isBuffer(txBuffer) && util.isBuffer(rxBuffer)) {
+    this._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(this._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 = this._binding.transferArray(txBuffer, rxBuffer);
+  } else if (util.isBuffer(txBuffer) && util.isBuffer(rxBuffer)) {
+    data = this._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(this._binding)) {
+    throw new Error('SPI bus is not opened');
+  }
+
+  return this._binding.close(function(err) {
+    util.isFunction(callback) && callback.call(self, err);
+  });
+};
+
+SpiBus.prototype.closeSync = function() {
+  if (util.isNull(this._binding)) {
+    throw new Error('SPI bus is not opened');
+  }
+
+  return this._binding.close();
+};
+
+module.exports = Spi;
diff --git a/tools/src/js/stm32f4dis.js b/tools/src/js/stm32f4dis.js
new file mode 100644 (file)
index 0000000..2cbcb06
--- /dev/null
@@ -0,0 +1,16 @@
+/* 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);
diff --git a/tools/src/js/stream.js b/tools/src/js/stream.js
new file mode 100644 (file)
index 0000000..4924164
--- /dev/null
@@ -0,0 +1,33 @@
+/* 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 EE = require('events').EventEmitter;
+var util = require('util');
+
+
+function Stream() {
+  EE.call(this);
+};
+
+
+util.inherits(Stream, EE);
+
+
+exports.Stream = Stream;
+
+exports.Readable = require('stream_readable');
+exports.Writable = require('stream_writable');
+exports.Duplex = require('stream_duplex');
diff --git a/tools/src/js/stream_duplex.js b/tools/src/js/stream_duplex.js
new file mode 100644 (file)
index 0000000..7beb75c
--- /dev/null
@@ -0,0 +1,46 @@
+/* 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;
diff --git a/tools/src/js/stream_readable.js b/tools/src/js/stream_readable.js
new file mode 100644 (file)
index 0000000..a29bd56
--- /dev/null
@@ -0,0 +1,217 @@
+/* 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) {
+  emitError(this, error);
+};
+
+
+Readable.prototype.push = function(chunk, encoding) {
+  var state = this._readableState;
+
+  if (!util.isString(chunk) &&
+      !util.isBuffer(chunk) &&
+      !util.isNull(chunk)) {
+    emitError(this, TypeError('Invalid chunk'));
+  } else if (util.isNull(chunk)) {
+    onEof(this);
+  } else if (state.ended) {
+    emitError(this, 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);
+      emitReadable(this);
+    }
+  }
+};
+
+
+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 emitReadable(stream) {
+  stream.emit('readable');
+};
+
+
+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 emitError(stream, er) {
+  stream.emit('error', er);
+};
+
+
+function onEof(stream) {
+  var state = stream._readableState;
+
+  state.ended = true;
+
+  if (state.length == 0) {
+    emitEnd(stream);
+  }
+};
+
+
+module.exports = Readable;
diff --git a/tools/src/js/stream_writable.js b/tools/src/js/stream_writable.js
new file mode 100644 (file)
index 0000000..30e084f
--- /dev/null
@@ -0,0 +1,280 @@
+/* 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.
+  var hwm = options.highWaterMark;
+  this.highWaterMark = (hwm || hwm === 0) ? hwm : 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;
+  var res = false;
+
+  if (state.ended) {
+    writeAfterEnd(this, callback);
+  } else {
+    res = writeOrBuffer(this, chunk, callback);
+  }
+
+  return res;
+};
+
+
+// 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(status) {
+  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(function(){
+      callback(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;
+
+  var afterWrite = function(status) {
+    stream._onwrite(status);
+  };
+
+  // Write down the chunk data.
+  stream._write(chunk, callback, afterWrite);
+}
+
+
+// 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(function(){
+      emitFinish(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;
diff --git a/tools/src/js/testdriver.js b/tools/src/js/testdriver.js
new file mode 100644 (file)
index 0000000..1dc0d74
--- /dev/null
@@ -0,0 +1,16 @@
+/* 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);
diff --git a/tools/src/js/timers.js b/tools/src/js/timers.js
new file mode 100644 (file)
index 0000000..bb7bc22
--- /dev/null
@@ -0,0 +1,136 @@
+/* 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.close();
+    }
+  }
+};
+
+
+Timeout.prototype.activate = 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.close = function() {
+  this.callback = undefined;
+  if (this.handler) {
+    this.handler.timeoutObj = undefined;
+    this.handler.stop();
+    this.handler = undefined;
+  }
+};
+
+
+exports.setTimeout = function(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 <= 2) {
+    timeout.callback = callback;
+  } else {
+    var args = Array.prototype.slice.call(arguments, 2);
+    timeout.callback = function() {
+      callback.apply(timeout, args);
+    };
+  }
+
+  timeout.activate();
+
+  return timeout;
+};
+
+
+exports.clearTimeout = function(timeout) {
+  if (timeout && timeout.callback && (timeout instanceof Timeout))
+    timeout.close();
+  else
+    throw new Error('clearTimeout() - invalid timeout');
+};
+
+
+exports.setInterval = function(callback, repeat) {
+  if (!util.isFunction(callback)) {
+    throw new TypeError('Bad arguments: callback must be a Function');
+  }
+
+  repeat *= 1;
+  if (repeat < 1 || repeat > TIMEOUT_MAX) {
+    repeat = 1;
+  }
+  var timeout = new Timeout(repeat);
+
+  // set interval timeout handler.
+  if (arguments.length <= 2) {
+    timeout.callback = callback;
+  } else {
+    var args = Array.prototype.slice.call(arguments, 2);
+    timeout.callback = function() {
+      callback.apply(timeout, args);
+    };
+  }
+  timeout.isrepeat = true;
+  timeout.activate();
+
+  return timeout;
+};
+
+
+exports.clearInterval = function(timeout) {
+  if (timeout && timeout.isrepeat)
+    timeout.close();
+  else
+    throw new Error('clearInterval() - invalid interval');
+};
diff --git a/tools/src/js/uart.js b/tools/src/js/uart.js
new file mode 100644 (file)
index 0000000..8453c51
--- /dev/null
@@ -0,0 +1,133 @@
+/* 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 new UartPort(configuration, callback);
+};
+
+
+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);
+
+  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(self._binding)) {
+        self.closeSync();
+      }
+    };
+  })(this));
+}
+
+util.inherits(UartPort, EventEmitter);
+
+UartPort.prototype.write = function(buffer, callback) {
+  var self = this;
+
+  if (util.isNull(this._binding)) {
+    throw new Error('UART port is not opened');
+  }
+
+  this._binding.write(buffer, function(err) {
+    util.isFunction(callback) && callback.call(self, err);
+  });
+};
+
+UartPort.prototype.writeSync = function(buffer) {
+  var self = this;
+
+  if (util.isNull(this._binding)) {
+    throw new Error('UART port is not opened');
+  }
+
+  this._binding.write(buffer);
+};
+
+UartPort.prototype.close = function(callback) {
+  var self = this;
+
+  if (util.isNull(this._binding)) {
+    throw new Error('UART port is not opened');
+  }
+
+  this._binding.close(function(err) {
+    util.isFunction(callback) && callback.call(self, err);
+  });
+  this._binding = null;
+};
+
+UartPort.prototype.closeSync = function() {
+  if (util.isNull(this._binding)) {
+    throw new Error('UART port is not opened');
+  }
+
+  this._binding.close();
+  this._binding = null;
+};
+
+module.exports = Uart;
diff --git a/tools/src/js/util.js b/tools/src/js/util.js
new file mode 100644 (file)
index 0000000..9741c4c
--- /dev/null
@@ -0,0 +1,175 @@
+/* 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': return '[JSON object]';
+      default: return m;
+    }
+  });
+
+  while (i < args.length) {
+      str += ' ' + args[i++].toString();
+  }
+
+  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;
diff --git a/tools/src/module/iotjs_module_adc.c b/tools/src/module/iotjs_module_adc.c
new file mode 100644 (file)
index 0000000..aa3961d
--- /dev/null
@@ -0,0 +1,290 @@
+/* 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"
+
+
+static void iotjs_adc_destroy(iotjs_adc_t* 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,
+                               (JFreeHandlerType)iotjs_adc_destroy);
+
+  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, const iotjs_jval_t* jadc, 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 = iotjs_adc_instance_from_jval(jadc);
+  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, jthis, jcallback, op)                                  \
+  do {                                                                         \
+    uv_loop_t* loop = iotjs_environment_loop(iotjs_environment_get());         \
+    iotjs_adc_reqwrap_t* req_wrap =                                            \
+        iotjs_adc_reqwrap_create(jcallback, jthis, 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) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_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, jadc, jcallback, kAdcOpOpen);
+}
+
+
+JHANDLER_FUNCTION(Read) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_CHECK_ARG_IF_EXIST(0, function);
+
+  const iotjs_jval_t* jcallback = JHANDLER_GET_ARG_IF_EXIST(0, function);
+  const iotjs_jval_t* jadc = JHANDLER_GET_THIS(object);
+  iotjs_adc_t* adc = iotjs_adc_instance_from_jval(jadc);
+
+  if (jcallback) {
+    ADC_ASYNC(read, jadc, 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_CHECK_THIS(object);
+  JHANDLER_CHECK_ARG_IF_EXIST(0, function);
+
+  const iotjs_jval_t* jcallback = JHANDLER_GET_ARG_IF_EXIST(0, function);
+  const iotjs_jval_t* jadc = JHANDLER_GET_THIS(object);
+  iotjs_adc_t* adc = iotjs_adc_instance_from_jval(jadc);
+
+  if (jcallback) {
+    ADC_ASYNC(close, jadc, 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;
+}
diff --git a/tools/src/module/iotjs_module_adc.h b/tools/src/module/iotjs_module_adc.h
new file mode 100644 (file)
index 0000000..4fd04fd
--- /dev/null
@@ -0,0 +1,81 @@
+/* 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 */
diff --git a/tools/src/module/iotjs_module_blehcisocket.c b/tools/src/module/iotjs_module_blehcisocket.c
new file mode 100644 (file)
index 0000000..1318e37
--- /dev/null
@@ -0,0 +1,251 @@
+/* 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+#define THIS iotjs_blehcisocket_t* blehcisocket
+
+
+static void iotjs_blehcisocket_destroy(THIS);
+
+
+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,
+                               (JFreeHandlerType)iotjs_blehcisocket_destroy);
+
+  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_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(0);
+
+  const iotjs_jval_t* jblehcisocket = JHANDLER_GET_THIS(object);
+
+  iotjs_blehcisocket_t* blehcisocket =
+      iotjs_blehcisocket_instance_from_jval(jblehcisocket);
+
+  iotjs_blehcisocket_start(blehcisocket);
+
+  iotjs_jhandler_return_undefined(jhandler);
+}
+
+
+JHANDLER_FUNCTION(BindRaw) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_CHECK(ge(iotjs_jhandler_get_arg_length(jhandler), 1));
+
+  const iotjs_jval_t* jblehcisocket = JHANDLER_GET_THIS(object);
+
+  iotjs_blehcisocket_t* blehcisocket =
+      iotjs_blehcisocket_instance_from_jval(jblehcisocket);
+
+  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_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(1, number);
+
+  const iotjs_jval_t* jblehcisocket = JHANDLER_GET_THIS(object);
+
+  iotjs_blehcisocket_t* blehcisocket =
+      iotjs_blehcisocket_instance_from_jval(jblehcisocket);
+
+  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_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(0);
+
+  const iotjs_jval_t* jblehcisocket = JHANDLER_GET_THIS(object);
+
+  iotjs_blehcisocket_t* blehcisocket =
+      iotjs_blehcisocket_instance_from_jval(jblehcisocket);
+
+  iotjs_blehcisocket_bindControl(blehcisocket);
+
+  iotjs_jhandler_return_undefined(jhandler);
+}
+
+
+JHANDLER_FUNCTION(IsDevUp) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(0);
+
+  const iotjs_jval_t* jblehcisocket = JHANDLER_GET_THIS(object);
+
+  iotjs_blehcisocket_t* blehcisocket =
+      iotjs_blehcisocket_instance_from_jval(jblehcisocket);
+
+  bool ret = iotjs_blehcisocket_isDevUp(blehcisocket);
+
+  iotjs_jhandler_return_boolean(jhandler, ret);
+}
+
+
+JHANDLER_FUNCTION(SetFilter) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(1, object);
+
+  const iotjs_jval_t* jblehcisocket = JHANDLER_GET_THIS(object);
+  iotjs_blehcisocket_t* blehcisocket =
+      iotjs_blehcisocket_instance_from_jval(jblehcisocket);
+  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_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(0);
+
+  const iotjs_jval_t* jblehcisocket = JHANDLER_GET_THIS(object);
+
+  iotjs_blehcisocket_t* blehcisocket =
+      iotjs_blehcisocket_instance_from_jval(jblehcisocket);
+
+  iotjs_blehcisocket_stop(blehcisocket);
+
+  iotjs_jhandler_return_undefined(jhandler);
+}
+
+
+JHANDLER_FUNCTION(Write) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(1, object);
+
+  const iotjs_jval_t* jblehcisocket = JHANDLER_GET_THIS(object);
+  iotjs_blehcisocket_t* blehcisocket =
+      iotjs_blehcisocket_instance_from_jval(jblehcisocket);
+  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) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_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;
+}
diff --git a/tools/src/module/iotjs_module_blehcisocket.h b/tools/src/module/iotjs_module_blehcisocket.h
new file mode 100644 (file)
index 0000000..93cc6ad
--- /dev/null
@@ -0,0 +1,87 @@
+/* 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, int length);
+void iotjs_blehcisocket_poll(THIS);
+void iotjs_blehcisocket_stop(THIS);
+void iotjs_blehcisocket_write(THIS, char* data, int length);
+void iotjs_blehcisocket_emitErrnoError(THIS);
+int iotjs_blehcisocket_devIdFor(THIS, int* pDevId, bool isUp);
+void 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 */
diff --git a/tools/src/module/iotjs_module_buffer.c b/tools/src/module/iotjs_module_buffer.c
new file mode 100644 (file)
index 0000000..3b838c9
--- /dev/null
@@ -0,0 +1,519 @@
+/* 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 <stdlib.h>
+#include <string.h>
+
+
+static void iotjs_bufferwrap_destroy(iotjs_bufferwrap_t* 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,
+                               (JFreeHandlerType)iotjs_bufferwrap_destroy);
+  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(int index, size_t low, size_t upper) {
+  if (index < (int)low) {
+    return low;
+  }
+  if (index > (int)upper) {
+    return upper;
+  }
+  return index;
+}
+
+
+static unsigned hex2bin(char c) {
+  if (c >= '0' && c <= '9')
+    return c - '0';
+  if (c >= 'A' && c <= 'F')
+    return 10 + (c - 'A');
+  if (c >= 'a' && c <= 'f')
+    return 10 + (c - 'a');
+
+  IOTJS_ASSERT(!"Bad argument");
+  return (unsigned)(-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) {
+    unsigned a = hex2bin(src[i * 2 + 0]);
+    unsigned b = hex2bin(src[i * 2 + 1]);
+    if (!~a || !~b)
+      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) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(2, object, number);
+
+  const iotjs_jval_t* jbuiltin = JHANDLER_GET_THIS(object);
+  const iotjs_jval_t* jbuffer = JHANDLER_GET_ARG(0, object);
+  int 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_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(1, object);
+
+  const iotjs_jval_t* jsrc_builtin = JHANDLER_GET_THIS(object);
+  iotjs_bufferwrap_t* src_buffer_wrap =
+      iotjs_bufferwrap_from_jbuiltin(jsrc_builtin);
+
+  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);
+}
+
+
+JHANDLER_FUNCTION(Copy) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(4, object, number, number, number);
+
+  const iotjs_jval_t* jsrc_builtin = JHANDLER_GET_THIS(object);
+  iotjs_bufferwrap_t* src_buffer_wrap =
+      iotjs_bufferwrap_from_jbuiltin(jsrc_builtin);
+
+  const iotjs_jval_t* jdst_buffer = JHANDLER_GET_ARG(0, object);
+  iotjs_bufferwrap_t* dst_buffer_wrap =
+      iotjs_bufferwrap_from_jbuffer(jdst_buffer);
+
+  int dst_start = JHANDLER_GET_ARG(1, number);
+  int src_start = JHANDLER_GET_ARG(2, number);
+  int src_end = JHANDLER_GET_ARG(3, number);
+
+  size_t dst_length = iotjs_bufferwrap_length(dst_buffer_wrap);
+  size_t src_length = iotjs_bufferwrap_length(src_buffer_wrap);
+
+  dst_start = bound_range(dst_start, 0, dst_length);
+  src_start = bound_range(src_start, 0, src_length);
+  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_CHECK_ARGS(3, string, number, number);
+
+  iotjs_string_t src = JHANDLER_GET_ARG(0, string);
+  int offset = JHANDLER_GET_ARG(1, number);
+  int length = JHANDLER_GET_ARG(2, number);
+
+  const iotjs_jval_t* jbuiltin = JHANDLER_GET_THIS(object);
+
+  iotjs_bufferwrap_t* buffer_wrap = iotjs_bufferwrap_from_jbuiltin(jbuiltin);
+
+  size_t buffer_length = iotjs_bufferwrap_length(buffer_wrap);
+  offset = bound_range(offset, 0, buffer_length);
+  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_CHECK_ARGS(2, number, number);
+
+  uint8_t src = (uint8_t)JHANDLER_GET_ARG(0, number);
+  int offset = JHANDLER_GET_ARG(1, number);
+  int length = 1;
+
+  const iotjs_jval_t* jbuiltin = JHANDLER_GET_THIS(object);
+
+  iotjs_bufferwrap_t* buffer_wrap = iotjs_bufferwrap_from_jbuiltin(jbuiltin);
+
+  size_t buffer_length = iotjs_bufferwrap_length(buffer_wrap);
+  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, (const char*)&src,
+                                                 0, length, offset);
+
+  iotjs_jhandler_return_number(jhandler, copied);
+}
+
+
+JHANDLER_FUNCTION(HexWrite) {
+  JHANDLER_CHECK_ARGS(3, string, number, number);
+
+  iotjs_string_t src = JHANDLER_GET_ARG(0, string);
+  int offset = JHANDLER_GET_ARG(1, number);
+  int length = JHANDLER_GET_ARG(2, number);
+
+  const iotjs_jval_t* jbuiltin = JHANDLER_GET_THIS(object);
+
+  iotjs_bufferwrap_t* buffer_wrap = iotjs_bufferwrap_from_jbuiltin(jbuiltin);
+
+  size_t buffer_length = iotjs_bufferwrap_length(buffer_wrap);
+  offset = bound_range(offset, 0, buffer_length);
+  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_CHECK_ARGS(1, number);
+
+  int offset = JHANDLER_GET_ARG(0, number);
+
+  const iotjs_jval_t* jbuiltin = JHANDLER_GET_THIS(object);
+
+  iotjs_bufferwrap_t* buffer_wrap = iotjs_bufferwrap_from_jbuiltin(jbuiltin);
+
+  size_t buffer_length = iotjs_bufferwrap_length(buffer_wrap);
+  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_CHECK_ARGS(2, number, number);
+
+  const iotjs_jval_t* jbuiltin = JHANDLER_GET_THIS(object);
+  iotjs_bufferwrap_t* buffer_wrap = iotjs_bufferwrap_from_jbuiltin(jbuiltin);
+
+  int start = JHANDLER_GET_ARG(0, number);
+  int end = JHANDLER_GET_ARG(1, number);
+
+  if (start < 0) {
+    start += iotjs_bufferwrap_length(buffer_wrap);
+  }
+  start = bound_range(start, 0, iotjs_bufferwrap_length(buffer_wrap));
+
+  if (end < 0) {
+    end += iotjs_bufferwrap_length(buffer_wrap);
+  }
+  end = bound_range(end, 0, iotjs_bufferwrap_length(buffer_wrap));
+
+  if (end < start) {
+    end = start;
+  }
+
+  int length = end - start;
+  IOTJS_ASSERT(length >= 0);
+
+  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,
+                                 end, 0);
+
+  iotjs_jhandler_return_jval(jhandler, &jnew_buffer);
+  iotjs_jval_destroy(&jnew_buffer);
+}
+
+
+JHANDLER_FUNCTION(ToString) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(2, number, number);
+
+  const iotjs_jval_t* jbuiltin = JHANDLER_GET_THIS(object);
+  iotjs_bufferwrap_t* buffer_wrap = iotjs_bufferwrap_from_jbuiltin(jbuiltin);
+
+  int start = JHANDLER_GET_ARG(0, number);
+  int end = JHANDLER_GET_ARG(1, number);
+
+  start = bound_range(start, 0, iotjs_bufferwrap_length(buffer_wrap));
+  end = bound_range(end, 0, iotjs_bufferwrap_length(buffer_wrap));
+
+  if (end < start) {
+    end = start;
+  }
+
+  int length = end - start;
+  IOTJS_ASSERT(length >= 0);
+
+  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_CHECK_THIS(object);
+
+  const iotjs_jval_t* jbuiltin = JHANDLER_GET_THIS(object);
+  iotjs_bufferwrap_t* buffer_wrap = iotjs_bufferwrap_from_jbuiltin(jbuiltin);
+
+  int 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 (int 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) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_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;
+}
diff --git a/tools/src/module/iotjs_module_buffer.h b/tools/src/module/iotjs_module_buffer.h
new file mode 100644 (file)
index 0000000..2f1e53f
--- /dev/null
@@ -0,0 +1,53 @@
+/* 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 */
diff --git a/tools/src/module/iotjs_module_console.c b/tools/src/module/iotjs_module_console.c
new file mode 100644 (file)
index 0000000..c827636
--- /dev/null
@@ -0,0 +1,45 @@
+/* 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;
+}
diff --git a/tools/src/module/iotjs_module_constants.c b/tools/src/module/iotjs_module_constants.c
new file mode 100644 (file)
index 0000000..a02e675
--- /dev/null
@@ -0,0 +1,41 @@
+/* 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;
+}
diff --git a/tools/src/module/iotjs_module_dns.c b/tools/src/module/iotjs_module_dns.c
new file mode 100644 (file)
index 0000000..82c2f51
--- /dev/null
@@ -0,0 +1,202 @@
+/* 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) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_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) {
+    family = AF_UNSPEC;
+  } 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(AF_INET, hostname_data, &(addr.sin_addr));
+
+    if (result != 1) {
+      err = errno;
+    } else {
+      inet_ntop(AF_INET, &(addr.sin_addr), ip, INET6_ADDRSTRLEN);
+    }
+  }
+
+  iotjs_jargs_append_number(&args, err);
+  iotjs_jargs_append_string_raw(&args, ip);
+  iotjs_jargs_append_number(&args, family);
+
+  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;
+}
diff --git a/tools/src/module/iotjs_module_dns.h b/tools/src/module/iotjs_module_dns.h
new file mode 100644 (file)
index 0000000..51cc508
--- /dev/null
@@ -0,0 +1,43 @@
+/* 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 */
diff --git a/tools/src/module/iotjs_module_fs.c b/tools/src/module/iotjs_module_fs.c
new file mode 100644 (file)
index 0000000..82b1933
--- /dev/null
@@ -0,0 +1,502 @@
+/* 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, 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_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_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) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(1, number);
+  JHANDLER_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) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(3, string, number, number);
+  JHANDLER_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) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(5, number, object, number, number, number);
+  JHANDLER_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) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(5, number, object, number, number, number);
+  JHANDLER_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) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(1, string);
+  JHANDLER_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(MkDir) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(2, string, number);
+  JHANDLER_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) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(1, string);
+  JHANDLER_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) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(1, string);
+  JHANDLER_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) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(2, string, string);
+  JHANDLER_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) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(1, string);
+  JHANDLER_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_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;
+}
diff --git a/tools/src/module/iotjs_module_fs.h b/tools/src/module/iotjs_module_fs.h
new file mode 100644 (file)
index 0000000..aaab379
--- /dev/null
@@ -0,0 +1,39 @@
+/* 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 */
diff --git a/tools/src/module/iotjs_module_gpio.c b/tools/src/module/iotjs_module_gpio.c
new file mode 100644 (file)
index 0000000..d9b86f5
--- /dev/null
@@ -0,0 +1,373 @@
+/* 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 <string.h>
+
+#include "iotjs_def.h"
+#include "iotjs_module_gpio.h"
+#include "iotjs_objectwrap.h"
+#include <stdio.h>
+
+
+static void iotjs_gpio_destroy(iotjs_gpio_t* gpio);
+static iotjs_gpio_t* iotjs_gpio_instance_from_jval(const iotjs_jval_t* jgpio);
+
+
+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,
+                               (JFreeHandlerType)iotjs_gpio_destroy);
+  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, const iotjs_jval_t* jgpio, 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 = iotjs_gpio_instance_from_jval(jgpio);
+  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
+
+
+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);
+
+  if (status) {
+    iotjs_jargs_append_error(&jargs, "GPIO System Error");
+  } else {
+    switch (req_data->op) {
+      case kGpioOpOpen:
+        if (req_data->result < 0) {
+          iotjs_jargs_append_error(&jargs, "GPIO Open Error");
+        } else {
+          iotjs_jargs_append_null(&jargs);
+        }
+        break;
+      case kGpioOpWrite:
+        if (req_data->result < 0) {
+          iotjs_jargs_append_error(&jargs, "GPIO Write Error");
+        } else {
+          iotjs_jargs_append_null(&jargs);
+        }
+        break;
+      case kGpioOpRead:
+        if (req_data->result < 0) {
+          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 (req_data->result < 0) {
+          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);
+}
+
+
+#define GPIO_ASYNC(op)                                                 \
+  do {                                                                 \
+    uv_loop_t* loop = iotjs_environment_loop(iotjs_environment_get()); \
+    uv_work_t* req = iotjs_gpio_reqwrap_req(req_wrap);                 \
+    uv_queue_work(loop, req, iotjs_gpio_##op##_worker,                 \
+                  iotjs_gpio_after_worker);                            \
+  } while (0)
+
+
+// write(value, callback)
+JHANDLER_FUNCTION(Write) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(2, boolean, function);
+
+  bool value = JHANDLER_GET_ARG(0, boolean);
+  const iotjs_jval_t* jcallback = JHANDLER_GET_ARG(1, function);
+
+  iotjs_gpio_reqwrap_t* req_wrap =
+      iotjs_gpio_reqwrap_create(jcallback, JHANDLER_GET_THIS(object),
+                                kGpioOpWrite);
+
+  iotjs_gpio_reqdata_t* req_data = iotjs_gpio_reqwrap_data(req_wrap);
+  req_data->value = value;
+
+  GPIO_ASYNC(write);
+
+  iotjs_jhandler_return_null(jhandler);
+}
+
+
+// writeSync(value)
+JHANDLER_FUNCTION(WriteSync) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(1, boolean);
+
+  const iotjs_jval_t* jgpio = JHANDLER_GET_THIS(object);
+  iotjs_gpio_t* gpio = iotjs_gpio_instance_from_jval(jgpio);
+  IOTJS_VALIDATED_STRUCT_METHOD(iotjs_gpio_t, gpio);
+
+  bool value = JHANDLER_GET_ARG(0, boolean);
+
+  if (iotjs_gpio_write(_this->pin, value)) {
+    iotjs_jhandler_return_null(jhandler);
+  } else {
+    iotjs_jval_t jerror = iotjs_jval_create_error("GPIO WriteSync Error");
+    iotjs_jhandler_throw(jhandler, &jerror);
+    iotjs_jval_destroy(&jerror);
+  }
+}
+
+
+// read(callback)
+JHANDLER_FUNCTION(Read) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(1, function);
+
+  const iotjs_jval_t* jcallback = JHANDLER_GET_ARG(0, function);
+  iotjs_gpio_reqwrap_t* req_wrap =
+      iotjs_gpio_reqwrap_create(jcallback, JHANDLER_GET_THIS(object),
+                                kGpioOpRead);
+
+  GPIO_ASYNC(read);
+
+  iotjs_jhandler_return_null(jhandler);
+}
+
+
+// readSync()
+JHANDLER_FUNCTION(ReadSync) {
+  JHANDLER_CHECK_THIS(object);
+
+  const iotjs_jval_t* jgpio = JHANDLER_GET_THIS(object);
+  iotjs_gpio_t* gpio = iotjs_gpio_instance_from_jval(jgpio);
+  IOTJS_VALIDATED_STRUCT_METHOD(iotjs_gpio_t, gpio);
+
+  int value = iotjs_gpio_read(_this->pin);
+
+  if (value >= 0) {
+    iotjs_jhandler_return_boolean(jhandler, value);
+  } else {
+    iotjs_jval_t jerror = iotjs_jval_create_error("GPIO ReadSync Error");
+    iotjs_jhandler_throw(jhandler, &jerror);
+    iotjs_jval_destroy(&jerror);
+  }
+}
+
+
+// close(callback)
+JHANDLER_FUNCTION(Close) {
+  JHANDLER_CHECK_ARGS(1, function);
+
+  const iotjs_jval_t* jcallback = JHANDLER_GET_ARG(0, function);
+  iotjs_gpio_reqwrap_t* req_wrap =
+      iotjs_gpio_reqwrap_create(jcallback, JHANDLER_GET_THIS(object),
+                                kGpioOpClose);
+
+  GPIO_ASYNC(close);
+
+  iotjs_jhandler_return_null(jhandler);
+}
+
+
+// closeSync()
+JHANDLER_FUNCTION(CloseSync) {
+  JHANDLER_CHECK_THIS(object);
+
+  const iotjs_jval_t* jgpio = JHANDLER_GET_THIS(object);
+  iotjs_gpio_t* gpio = iotjs_gpio_instance_from_jval(jgpio);
+  IOTJS_VALIDATED_STRUCT_METHOD(iotjs_gpio_t, gpio);
+
+  if (iotjs_gpio_close(_this->pin)) {
+    iotjs_jhandler_return_null(jhandler);
+  } else {
+    iotjs_jval_t jerror = iotjs_jval_create_error("GPIO CloseSync Error");
+    iotjs_jhandler_throw(jhandler, &jerror);
+    iotjs_jval_destroy(&jerror);
+  }
+}
+
+
+// Constructor(configurable, callback)
+JHANDLER_FUNCTION(GpioConstructor) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_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));
+
+  // Create reqwrap
+  iotjs_gpio_reqwrap_t* req_wrap =
+      iotjs_gpio_reqwrap_create(JHANDLER_GET_ARG(1, function), jgpio,
+                                kGpioOpOpen);
+
+  GPIO_ASYNC(open);
+}
+
+
+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_WRITESYNC, WriteSync);
+  iotjs_jval_set_method(&jprototype, IOTJS_MAGIC_STRING_READ, Read);
+  iotjs_jval_set_method(&jprototype, IOTJS_MAGIC_STRING_READSYNC, ReadSync);
+  iotjs_jval_set_method(&jprototype, IOTJS_MAGIC_STRING_CLOSE, Close);
+  iotjs_jval_set_method(&jprototype, IOTJS_MAGIC_STRING_CLOSESYNC, CloseSync);
+  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);
+  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);
+  iotjs_jval_set_property_jval(&jgpio, IOTJS_MAGIC_STRING_MODE_U, &jmode);
+  iotjs_jval_destroy(&jmode);
+
+  return jgpio;
+}
diff --git a/tools/src/module/iotjs_module_gpio.h b/tools/src/module/iotjs_module_gpio.h
new file mode 100644 (file)
index 0000000..1bb0353
--- /dev/null
@@ -0,0 +1,99 @@
+/* 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"
+
+
+typedef enum {
+  kGpioDirectionIn = 0,
+  kGpioDirectionOut,
+} GpioDirection;
+
+
+typedef enum {
+  kGpioModeNone = 0,
+  kGpioModePullup,
+  kGpioModePulldown,
+  kGpioModeFloat,
+  kGpioModePushpull,
+  kGpioModeOpendrain,
+} GpioMode;
+
+
+typedef enum {
+  kGpioOpOpen,
+  kGpioOpWrite,
+  kGpioOpRead,
+  kGpioOpClose,
+} GpioOp;
+
+
+typedef struct {
+  bool value;
+  ssize_t 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;
+} 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);            \
+  IOTJS_VALIDATED_STRUCT_METHOD(iotjs_gpio_t, gpio);
+
+
+void iotjs_gpio_open_worker(uv_work_t* work_req);
+void iotjs_gpio_write_worker(uv_work_t* work_req);
+void iotjs_gpio_read_worker(uv_work_t* work_req);
+void iotjs_gpio_close_worker(uv_work_t* work_req);
+bool iotjs_gpio_write(int32_t pin, bool value);
+int iotjs_gpio_read(int32_t pin);
+bool iotjs_gpio_close(int32_t pin);
+
+#endif /* IOTJS_MODULE_GPIO_H */
diff --git a/tools/src/module/iotjs_module_httpparser.c b/tools/src/module/iotjs_module_httpparser.c
new file mode 100644 (file)
index 0000000..8e12b04
--- /dev/null
@@ -0,0 +1,511 @@
+/* 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+#define THIS iotjs_httpparserwrap_t* httpparserwrap
+
+
+static void iotjs_httpparserwrap_destroy(THIS);
+
+
+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,
+                               (JFreeHandlerType)iotjs_httpparserwrap_destroy);
+
+  _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, int 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 */
+};
+
+
+static iotjs_httpparserwrap_t* get_parser_wrap(const iotjs_jval_t* jparser) {
+  uintptr_t handle = iotjs_jval_get_object_native_handle(jparser);
+  return (iotjs_httpparserwrap_t*)(handle);
+}
+
+
+JHANDLER_FUNCTION(Reinitialize) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_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 = get_parser_wrap(jparser);
+  iotjs_httpparserwrap_initialize(parser, httpparser_type);
+}
+
+
+JHANDLER_FUNCTION(Finish) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(0);
+
+  const iotjs_jval_t* jparser = JHANDLER_GET_THIS(object);
+  iotjs_httpparserwrap_t* parser = get_parser_wrap(jparser);
+
+  http_parser* nativeparser = iotjs_httpparserwrap_parser(parser);
+  int 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_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(1, object);
+
+  const iotjs_jval_t* jparser = JHANDLER_GET_THIS(object);
+  iotjs_httpparserwrap_t* parser = get_parser_wrap(jparser);
+
+
+  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);
+  int 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);
+  int 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_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(0);
+  const iotjs_jval_t* jparser = JHANDLER_GET_THIS(object);
+  iotjs_httpparserwrap_t* parser = get_parser_wrap(jparser);
+  http_parser* nativeparser = iotjs_httpparserwrap_parser(parser);
+  http_parser_pause(nativeparser, 1);
+}
+
+
+JHANDLER_FUNCTION(Resume) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(0);
+  const iotjs_jval_t* jparser = JHANDLER_GET_THIS(object);
+  iotjs_httpparserwrap_t* parser = get_parser_wrap(jparser);
+  http_parser* nativeparser = iotjs_httpparserwrap_parser(parser);
+  http_parser_pause(nativeparser, 0);
+}
+
+
+JHANDLER_FUNCTION(HTTPParserCons) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_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_ASSERT(get_parser_wrap(jparser) == 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;
+}
diff --git a/tools/src/module/iotjs_module_httpparser.h b/tools/src/module/iotjs_module_httpparser.h
new file mode 100644 (file)
index 0000000..dd25b3f
--- /dev/null
@@ -0,0 +1,80 @@
+/* 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, int sz);
+
+iotjs_jval_t* iotjs_httpparserwrap_jobject(THIS);
+http_parser* iotjs_httpparserwrap_parser(THIS);
+
+
+#undef THIS
+
+
+#endif /* IOTJS_MODULE_HTTPPARSER_H */
diff --git a/tools/src/module/iotjs_module_i2c.c b/tools/src/module/iotjs_module_i2c.c
new file mode 100644 (file)
index 0000000..3a49a9a
--- /dev/null
@@ -0,0 +1,435 @@
+/* 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_i2c_reqwrap_t* iotjs_i2c_reqwrap_create(const iotjs_jval_t* jcallback,
+                                              const iotjs_jval_t* ji2c,
+                                              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 = iotjs_i2c_instance_from_jval(ji2c);
+  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
+
+
+static void iotjs_i2c_destroy(iotjs_i2c_t* i2c);
+
+
+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(__NUTTX__)
+  _this->i2c_master = NULL;
+#endif
+
+  iotjs_jobjectwrap_initialize(&_this->jobjectwrap, ji2c,
+                               (JFreeHandlerType)iotjs_i2c_destroy);
+  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:
+      case kI2cOpWriteByte:
+      case kI2cOpWriteBlock: {
+        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:
+      case kI2cOpReadBlock: {
+        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 if (req_data->error == kI2cErrReadBlock) {
+          iotjs_jval_t error =
+              iotjs_jval_create_error("Error reading length of bytes");
+          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;
+      }
+      case kI2cOpReadByte: {
+        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_jargs_append_number(&jargs, req_data->byte);
+        }
+        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 (int 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) {
+  JHANDLER_CHECK_THIS(object);
+#if defined(__linux__) || defined(__APPLE__)
+  JHANDLER_CHECK_ARGS(2, string, function);
+  iotjs_string_t device = JHANDLER_GET_ARG(0, string);
+#elif defined(__NUTTX__)
+  JHANDLER_CHECK_ARGS(2, number, function);
+  uint32_t 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, ji2c, 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_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(1, number);
+  iotjs_i2c_t* i2c = iotjs_i2c_instance_from_jval(JHANDLER_GET_THIS(object));
+
+  I2cSetAddress(i2c, JHANDLER_GET_ARG(0, number));
+
+  iotjs_jhandler_return_null(jhandler);
+}
+
+
+JHANDLER_FUNCTION(Close) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(0);
+
+  iotjs_i2c_t* i2c = iotjs_i2c_instance_from_jval(JHANDLER_GET_THIS(object));
+  I2cClose(i2c);
+
+  iotjs_jhandler_return_null(jhandler);
+}
+
+
+JHANDLER_FUNCTION(Write) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(2, array, function);
+
+  const iotjs_jval_t* jcallback = JHANDLER_GET_ARG(1, function);
+  const iotjs_jval_t* ji2c = JHANDLER_GET_THIS(object);
+
+  iotjs_i2c_reqwrap_t* req_wrap =
+      iotjs_i2c_reqwrap_create(jcallback, ji2c, 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(WriteByte) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(2, number, function);
+
+  uint8_t byte = JHANDLER_GET_ARG(0, number);
+  const iotjs_jval_t* jcallback = JHANDLER_GET_ARG(1, function);
+  const iotjs_jval_t* ji2c = JHANDLER_GET_THIS(object);
+
+  iotjs_i2c_reqwrap_t* req_wrap =
+      iotjs_i2c_reqwrap_create(jcallback, ji2c, kI2cOpWriteByte);
+
+  iotjs_i2c_reqdata_t* req_data = iotjs_i2c_reqwrap_data(req_wrap);
+  req_data->byte = byte;
+
+  I2C_ASYNC(WriteByte);
+
+  iotjs_jhandler_return_null(jhandler);
+}
+
+
+JHANDLER_FUNCTION(WriteBlock) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(3, number, array, function);
+
+  const iotjs_jval_t* jcallback = JHANDLER_GET_ARG(2, function);
+  const iotjs_jval_t* ji2c = JHANDLER_GET_THIS(object);
+
+  iotjs_i2c_reqwrap_t* req_wrap =
+      iotjs_i2c_reqwrap_create(jcallback, ji2c, kI2cOpWriteBlock);
+
+  iotjs_i2c_reqdata_t* req_data = iotjs_i2c_reqwrap_data(req_wrap);
+  req_data->cmd = JHANDLER_GET_ARG(0, number);
+  GetI2cArray(JHANDLER_GET_ARG(1, array), req_data);
+
+  I2C_ASYNC(WriteBlock);
+
+  iotjs_jhandler_return_null(jhandler);
+}
+
+
+JHANDLER_FUNCTION(Read) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(2, number, function);
+
+  const iotjs_jval_t* jcallback = JHANDLER_GET_ARG(1, function);
+  const iotjs_jval_t* ji2c = JHANDLER_GET_THIS(object);
+
+  iotjs_i2c_reqwrap_t* req_wrap =
+      iotjs_i2c_reqwrap_create(jcallback, ji2c, 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);
+}
+
+
+JHANDLER_FUNCTION(ReadByte) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(1, function);
+
+  const iotjs_jval_t* jcallback = JHANDLER_GET_ARG(0, function);
+  const iotjs_jval_t* ji2c = JHANDLER_GET_THIS(object);
+
+  iotjs_i2c_reqwrap_t* req_wrap =
+      iotjs_i2c_reqwrap_create(jcallback, ji2c, kI2cOpReadByte);
+
+  I2C_ASYNC(ReadByte);
+
+  iotjs_jhandler_return_null(jhandler);
+}
+
+
+JHANDLER_FUNCTION(ReadBlock) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(4, number, number, number, function);
+
+  const iotjs_jval_t* jcallback = JHANDLER_GET_ARG(3, function);
+  const iotjs_jval_t* ji2c = JHANDLER_GET_THIS(object);
+
+  iotjs_i2c_reqwrap_t* req_wrap =
+      iotjs_i2c_reqwrap_create(jcallback, ji2c, kI2cOpReadBlock);
+
+  iotjs_i2c_reqdata_t* req_data = iotjs_i2c_reqwrap_data(req_wrap);
+  req_data->cmd = JHANDLER_GET_ARG(0, number);
+  req_data->buf_len = JHANDLER_GET_ARG(1, number);
+  req_data->delay = JHANDLER_GET_ARG(2, number);
+
+  I2C_ASYNC(ReadBlock);
+
+  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_WRITEBYTE, WriteByte);
+  iotjs_jval_set_method(&prototype, IOTJS_MAGIC_STRING_WRITEBLOCK, WriteBlock);
+  iotjs_jval_set_method(&prototype, IOTJS_MAGIC_STRING_READ, Read);
+  iotjs_jval_set_method(&prototype, IOTJS_MAGIC_STRING_READBYTE, ReadByte);
+  iotjs_jval_set_method(&prototype, IOTJS_MAGIC_STRING_READBLOCK, ReadBlock);
+
+  iotjs_jval_set_property_jval(&jI2cCons, IOTJS_MAGIC_STRING_PROTOTYPE,
+                               &prototype);
+
+  iotjs_jval_destroy(&prototype);
+
+  return jI2cCons;
+}
diff --git a/tools/src/module/iotjs_module_i2c.h b/tools/src/module/iotjs_module_i2c.h
new file mode 100644 (file)
index 0000000..75e48f9
--- /dev/null
@@ -0,0 +1,111 @@
+/* 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 <nuttx/i2c/i2c_master.h>
+#endif
+
+typedef enum {
+  kI2cOpSetAddress,
+  kI2cOpOpen,
+  kI2cOpClose,
+  kI2cOpWrite,
+  kI2cOpWriteByte,
+  kI2cOpWriteBlock,
+  kI2cOpRead,
+  kI2cOpReadByte,
+  kI2cOpReadBlock,
+} I2cOp;
+
+typedef enum {
+  kI2cErrOk = 0,
+  kI2cErrOpen = -1,
+  kI2cErrRead = -2,
+  kI2cErrReadBlock = -3,
+  kI2cErrWrite = -4,
+} I2cError;
+
+
+typedef struct {
+#if defined(__linux__) || defined(__APPLE__)
+  iotjs_string_t device;
+#elif defined(__NUTTX__)
+  uint32_t 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 {
+#if defined(__NUTTX__)
+  struct i2c_master_s* i2c_master;
+  struct i2c_config_s config;
+#endif
+  iotjs_jobjectwrap_t jobjectwrap;
+} 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,
+                                              const iotjs_jval_t* ji2c,
+                                              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 WriteByteWorker(uv_work_t* work_req);
+void WriteBlockWorker(uv_work_t* work_req);
+void ReadWorker(uv_work_t* work_req);
+void ReadByteWorker(uv_work_t* work_req);
+void ReadBlockWorker(uv_work_t* work_req);
+
+
+#endif /* IOTJS_MODULE_I2C_H */
diff --git a/tools/src/module/iotjs_module_process.c b/tools/src/module/iotjs_module_process.c
new file mode 100644 (file)
index 0000000..6f30679
--- /dev/null
@@ -0,0 +1,293 @@
+/* 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 <stdlib.h>
+
+
+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* source, size_t length, bool* throws) {
+  static const char* wrapper[2] = { "(function(exports, require, module) {\n",
+                                    "\n});\n" };
+
+  int len0 = strlen(wrapper[0]);
+  int len1 = strlen(wrapper[1]);
+
+  uint32_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(buffer, buffer_length, false, throws);
+
+  iotjs_buffer_release(buffer);
+
+  return res;
+}
+
+
+JHANDLER_FUNCTION(Compile) {
+  JHANDLER_CHECK_ARGS(1, string);
+
+  iotjs_string_t source = JHANDLER_GET_ARG(0, string);
+
+  bool throws;
+  iotjs_jval_t jres =
+      WrapEval(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(&source);
+  iotjs_jval_destroy(&jres);
+}
+
+
+JHANDLER_FUNCTION(CompileNativePtr) {
+  JHANDLER_CHECK_ARGS(1, string);
+
+  iotjs_string_t id = JHANDLER_GET_ARG(0, string);
+
+  int i = 0;
+  while (natives[i].name != NULL) {
+    if (!strcmp(natives[i].name, iotjs_string_data(&id))) {
+      break;
+    }
+
+    i++;
+  }
+
+  iotjs_string_destroy(&id);
+
+  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((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);
+  }
+}
+
+
+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);
+
+  int exit_code = JHANDLER_GET_ARG(0, number);
+
+  exit(exit_code);
+}
+
+
+// Initialize `process.argv`
+JHANDLER_FUNCTION(InitArgv) {
+  JHANDLER_CHECK_THIS(object);
+
+  // environment
+  const iotjs_environment_t* env = iotjs_environment_get();
+
+  // process.argv
+  const iotjs_jval_t* thisObj = JHANDLER_GET_THIS(object);
+  iotjs_jval_t jargv =
+      iotjs_jval_get_property(thisObj, IOTJS_MAGIC_STRING_ARGV);
+
+  int argc = iotjs_environment_argc(env);
+
+  for (int 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(&jargv, i, &arg);
+    iotjs_jval_destroy(&arg);
+  }
+  iotjs_jval_destroy(&jargv);
+}
+
+
+void SetNativeSources(iotjs_jval_t* native_sources) {
+  for (int i = 0; natives[i].name; i++) {
+    iotjs_jval_t native_src = iotjs_jval_create_object();
+    uintptr_t handle = (uintptr_t)(&natives[i]);
+    iotjs_jval_set_object_native_handle(&native_src, handle, NULL);
+    iotjs_jval_set_property_jval(native_sources, natives[i].name, &native_src);
+    iotjs_jval_destroy(&native_src);
+  }
+}
+
+
+static void SetProcessEnv(iotjs_jval_t* process) {
+  const char *homedir, *nodepath, *iotjsenv;
+
+  homedir = getenv("HOME");
+  if (homedir == NULL) {
+    homedir = "";
+  }
+
+  nodepath = getenv("NODE_PATH");
+  if (nodepath == NULL) {
+#if defined(__NUTTX__) || defined(__TIZENRT__)
+    nodepath = "/mnt/sdcard";
+#else
+    nodepath = "";
+#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_NODE_PATH,
+                                     nodepath);
+  iotjs_jval_set_property_string_raw(&env, IOTJS_MAGIC_STRING_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);
+}
+
+
+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);
+  iotjs_jval_set_method(&process, IOTJS_MAGIC_STRING__INITARGV, InitArgv);
+  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);
+
+  // 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;
+}
diff --git a/tools/src/module/iotjs_module_pwm.c b/tools/src/module/iotjs_module_pwm.c
new file mode 100644 (file)
index 0000000..67ece49
--- /dev/null
@@ -0,0 +1,378 @@
+/* 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 void iotjs_pwm_destroy(iotjs_pwm_t* pwm);
+static iotjs_pwm_t* iotjs_pwm_instance_from_jval(const iotjs_jval_t* jpwm);
+
+
+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,
+                               (JFreeHandlerType)iotjs_pwm_destroy);
+
+  _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, const iotjs_jval_t* jpwm, 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 = iotjs_pwm_instance_from_jval(jpwm);
+  _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, jthis, jcallback, op)                          \
+  do {                                                                 \
+    uv_loop_t* loop = iotjs_environment_loop(iotjs_environment_get()); \
+    iotjs_pwm_reqwrap_t* req_wrap =                                    \
+        iotjs_pwm_reqwrap_create(jcallback, jthis, 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, jthis, jcallback, op)                    \
+  do {                                                                         \
+    uv_loop_t* loop = iotjs_environment_loop(iotjs_environment_get());         \
+    iotjs_pwm_reqwrap_t* req_wrap =                                            \
+        iotjs_pwm_reqwrap_create(jcallback, jthis, 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) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_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, jpwm, jcallback, kPwmOpOpen);
+}
+
+
+JHANDLER_FUNCTION(SetPeriod) {
+  JHANDLER_CHECK_ARGS(1, number);
+  JHANDLER_CHECK_ARG_IF_EXIST(1, function);
+
+  const iotjs_jval_t* jcallback = JHANDLER_GET_ARG_IF_EXIST(1, function);
+  const iotjs_jval_t* jpwm = JHANDLER_GET_THIS(object);
+  iotjs_pwm_t* pwm = iotjs_pwm_instance_from_jval(jpwm);
+
+  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, jpwm, jcallback,
+                            kPwmOpSetPeriod);
+  } else {
+    if (!iotjs_pwm_set_period(pwm)) {
+      JHANDLER_THROW(COMMON, "PWM SetPeriod Error");
+    }
+  }
+
+  iotjs_jhandler_return_null(jhandler);
+}
+
+
+JHANDLER_FUNCTION(SetDutyCycle) {
+  JHANDLER_CHECK_ARGS(1, number);
+  JHANDLER_CHECK_ARG_IF_EXIST(1, function);
+
+  const iotjs_jval_t* jcallback = JHANDLER_GET_ARG_IF_EXIST(1, function);
+  const iotjs_jval_t* jpwm = JHANDLER_GET_THIS(object);
+  iotjs_pwm_t* pwm = iotjs_pwm_instance_from_jval(jpwm);
+
+  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, jpwm, jcallback,
+                            kPwmOpSetDutyCycle);
+  } else {
+    if (!iotjs_pwm_set_dutycycle(pwm)) {
+      JHANDLER_THROW(COMMON, "PWM SetDutyCycle Error");
+    }
+  }
+
+  iotjs_jhandler_return_null(jhandler);
+}
+
+
+JHANDLER_FUNCTION(SetEnable) {
+  JHANDLER_CHECK_ARGS(1, boolean);
+  JHANDLER_CHECK_ARG_IF_EXIST(1, function);
+
+  const iotjs_jval_t* jcallback = JHANDLER_GET_ARG_IF_EXIST(1, function);
+  const iotjs_jval_t* jpwm = JHANDLER_GET_THIS(object);
+  iotjs_pwm_t* pwm = iotjs_pwm_instance_from_jval(jpwm);
+
+  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, jpwm, jcallback,
+                            kPwmOpSetEnable);
+  } else {
+    if (!iotjs_pwm_set_enable(pwm)) {
+      JHANDLER_THROW(COMMON, "PWM SetEnabe Error");
+    }
+  }
+
+  iotjs_jhandler_return_null(jhandler);
+}
+
+
+JHANDLER_FUNCTION(Close) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_CHECK_ARG_IF_EXIST(0, function);
+
+  const iotjs_jval_t* jcallback = JHANDLER_GET_ARG_IF_EXIST(0, function);
+  const iotjs_jval_t* jpwm = JHANDLER_GET_THIS(object);
+  iotjs_pwm_t* pwm = iotjs_pwm_instance_from_jval(jpwm);
+
+  if (jcallback) {
+    PWM_ASYNC_COMMON_WORKER(iotjs_pwm_close, jpwm, 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;
+}
diff --git a/tools/src/module/iotjs_module_pwm.h b/tools/src/module/iotjs_module_pwm.h
new file mode 100644 (file)
index 0000000..0f9a9bf
--- /dev/null
@@ -0,0 +1,93 @@
+/* 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"
+
+
+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;
+#endif
+  int 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 */
diff --git a/tools/src/module/iotjs_module_spi.c b/tools/src/module/iotjs_module_spi.c
new file mode 100644 (file)
index 0000000..ef829d4
--- /dev/null
@@ -0,0 +1,465 @@
+/* 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 <unistd.h>
+
+
+/*
+ * SPI instance function
+ */
+static void iotjs_spi_destroy(iotjs_spi_t* spi);
+static iotjs_spi_t* iotjs_spi_instance_from_jval(const iotjs_jval_t* jspi);
+
+
+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,
+                               (JFreeHandlerType)iotjs_spi_destroy);
+
+  _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, const iotjs_jval_t* jspi, 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 = iotjs_spi_instance_from_jval(jspi);
+
+  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);
+}
+
+
+static iotjs_spi_t* iotjs_spi_instance_from_jval(const iotjs_jval_t* jspi) {
+  uintptr_t handle = iotjs_jval_get_object_native_handle(jspi);
+  return (iotjs_spi_t*)handle;
+}
+
+
+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));
+
+  int length = iotjs_jval_as_number(&jlength);
+  *buf = iotjs_buffer_allocate(length);
+
+  for (int 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 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, jthis, jcallback, op)                                  \
+  do {                                                                         \
+    uv_loop_t* loop = iotjs_environment_loop(iotjs_environment_get());         \
+    iotjs_spi_reqwrap_t* req_wrap =                                            \
+        iotjs_spi_reqwrap_create(jcallback, jthis, 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) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_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, jspi, jcallback, kSpiOpOpen);
+}
+
+
+// FIXME: do not need transferArray if array buffer is implemented.
+JHANDLER_FUNCTION(TransferArray) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(2, array, array);
+  JHANDLER_CHECK_ARG_IF_EXIST(2, function);
+
+  const iotjs_jval_t* jcallback = JHANDLER_GET_ARG_IF_EXIST(2, function);
+  const iotjs_jval_t* jspi = JHANDLER_GET_THIS(object);
+  iotjs_spi_t* spi = iotjs_spi_get_instance(jspi);
+
+  iotjs_spi_set_array_buffer(spi, JHANDLER_GET_ARG(0, array),
+                             JHANDLER_GET_ARG(1, array));
+
+  if (jcallback) {
+    SPI_ASYNC(transfer, jspi, 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_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(2, object, object);
+  JHANDLER_CHECK_ARG_IF_EXIST(2, function);
+
+  const iotjs_jval_t* jcallback = JHANDLER_GET_ARG_IF_EXIST(2, function);
+  const iotjs_jval_t* jspi = JHANDLER_GET_THIS(object);
+  iotjs_spi_t* spi = iotjs_spi_get_instance(jspi);
+
+  iotjs_spi_set_buffer(spi, JHANDLER_GET_ARG(0, object),
+                       JHANDLER_GET_ARG(1, object));
+
+  if (jcallback) {
+    SPI_ASYNC(transfer, jspi, 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_CHECK_THIS(object);
+  JHANDLER_CHECK_ARG_IF_EXIST(0, function);
+
+  const iotjs_jval_t* jcallback = JHANDLER_GET_ARG_IF_EXIST(0, function);
+  const iotjs_jval_t* jspi = JHANDLER_GET_THIS(object);
+  iotjs_spi_t* spi = iotjs_spi_get_instance(jspi);
+
+  if (jcallback) {
+    SPI_ASYNC(close, jspi, 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;
+}
diff --git a/tools/src/module/iotjs_module_spi.h b/tools/src/module/iotjs_module_spi.h
new file mode 100644 (file)
index 0000000..b4349f3
--- /dev/null
@@ -0,0 +1,104 @@
+/* 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 */
diff --git a/tools/src/module/iotjs_module_stm32f4dis.c b/tools/src/module/iotjs_module_stm32f4dis.c
new file mode 100644 (file)
index 0000000..672a504
--- /dev/null
@@ -0,0 +1,30 @@
+/* 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;
+}
diff --git a/tools/src/module/iotjs_module_stm32f4dis.h b/tools/src/module/iotjs_module_stm32f4dis.h
new file mode 100644 (file)
index 0000000..f14d608
--- /dev/null
@@ -0,0 +1,23 @@
+/* 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 */
diff --git a/tools/src/module/iotjs_module_tcp.c b/tools/src/module/iotjs_module_tcp.c
new file mode 100644 (file)
index 0000000..02b37dc
--- /dev/null
@@ -0,0 +1,674 @@
+/* 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"
+
+
+static void iotjs_tcpwrap_destroy(iotjs_tcpwrap_t* 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),
+                              (JFreeHandlerType)iotjs_tcpwrap_destroy);
+
+  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) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_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_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(0);
+
+  const iotjs_jval_t* jtcp = JHANDLER_GET_THIS(object);
+  iotjs_handlewrap_t* wrap = iotjs_handlewrap_from_jobject(jtcp);
+
+  // 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_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(2, string, number);
+
+  const iotjs_jval_t* jtcp = JHANDLER_GET_THIS(object);
+  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) {
+    iotjs_tcpwrap_t* tcp_wrap = iotjs_tcpwrap_from_jobject(jtcp);
+    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_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(3, string, number, function);
+
+  const iotjs_jval_t* jtcp = JHANDLER_GET_THIS(object);
+  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) {
+    // Get tcp wrapper from javascript socket object.
+    iotjs_tcpwrap_t* tcp_wrap = iotjs_tcpwrap_from_jobject(jtcp);
+
+    // 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_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(1, number);
+
+  const iotjs_jval_t* jtcp = JHANDLER_GET_THIS(object);
+  iotjs_tcpwrap_t* tcp_wrap = iotjs_tcpwrap_from_jobject(jtcp);
+
+  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_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(2, object, function);
+
+  const iotjs_jval_t* jtcp = JHANDLER_GET_THIS(object);
+  iotjs_tcpwrap_t* tcp_wrap = iotjs_tcpwrap_from_jobject(jtcp);
+
+  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);
+  int 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(nread);
+    iotjs_bufferwrap_t* buffer_wrap = iotjs_bufferwrap_from_jbuffer(&jbuffer);
+
+    iotjs_bufferwrap_copy(buffer_wrap, buf->base, 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_CHECK_THIS(object);
+
+  const iotjs_jval_t* jtcp = JHANDLER_GET_THIS(object);
+  iotjs_tcpwrap_t* tcp_wrap = iotjs_tcpwrap_from_jobject(jtcp);
+
+  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_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(1, function);
+
+  const iotjs_jval_t* jtcp = JHANDLER_GET_THIS(object);
+  iotjs_tcpwrap_t* tcp_wrap = iotjs_tcpwrap_from_jobject(jtcp);
+
+  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_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(2, number, number);
+
+  const iotjs_jval_t* jtcp = JHANDLER_GET_THIS(object);
+  int enable = JHANDLER_GET_ARG(0, number);
+  unsigned delay = JHANDLER_GET_ARG(1, number);
+
+  iotjs_tcpwrap_t* tcp_wrap = iotjs_tcpwrap_from_jobject(jtcp);
+  int err = uv_tcp_keepalive(iotjs_tcpwrap_tcp_handle(tcp_wrap), enable, delay);
+
+  iotjs_jhandler_return_number(jhandler, err);
+}
+
+
+// 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_set_property_jval(&tcp, IOTJS_MAGIC_STRING_PROTOTYPE, &prototype);
+
+  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);
+
+  return tcp;
+}
diff --git a/tools/src/module/iotjs_module_tcp.h b/tools/src/module/iotjs_module_tcp.h
new file mode 100644 (file)
index 0000000..5fbe909
--- /dev/null
@@ -0,0 +1,110 @@
+/* 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) {                      \
+    JHANDLER_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 */
diff --git a/tools/src/module/iotjs_module_testdriver.c b/tools/src/module/iotjs_module_testdriver.c
new file mode 100644 (file)
index 0000000..1c6d087
--- /dev/null
@@ -0,0 +1,71 @@
+/* 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) {
+      int active_handlers = loop->active_handles;
+      if (active_handlers == 1) {
+        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;
+}
diff --git a/tools/src/module/iotjs_module_timer.c b/tools/src/module/iotjs_module_timer.c
new file mode 100644 (file)
index 0000000..5dda485
--- /dev/null
@@ -0,0 +1,178 @@
+/* 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_timerwrap_t* iotjs_timerwrap_create(const iotjs_jval_t* jtimer) {
+  iotjs_timerwrap_t* timerwrap = IOTJS_ALLOC(iotjs_timerwrap_t);
+  IOTJS_VALIDATED_STRUCT_CONSTRUCTOR(iotjs_timerwrap_t, timerwrap);
+
+  iotjs_handlewrap_initialize(&_this->handlewrap, jtimer,
+                              (uv_handle_t*)(&_this->handle),
+                              (JFreeHandlerType)iotjs_timerwrap_destroy);
+
+  // Initialize timer handler.
+  const iotjs_environment_t* env = iotjs_environment_get();
+  uv_timer_init(iotjs_environment_loop(env), &_this->handle);
+
+  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);
+}
+
+
+// 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, int64_t timeout,
+                          int64_t repeat) {
+  IOTJS_VALIDATED_STRUCT_METHOD(iotjs_timerwrap_t, timerwrap);
+
+  // Start uv timer.
+  return uv_timer_start(&_this->handle, 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, NULL);
+  }
+
+  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 &_this->handle;
+}
+
+
+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_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(2, number, number);
+
+  const iotjs_jval_t* jtimer = JHANDLER_GET_THIS(object);
+
+  // Take timer wrap.
+  iotjs_timerwrap_t* timer_wrap = iotjs_timerwrap_from_jobject(jtimer);
+
+  // parameters.
+  int64_t timeout = JHANDLER_GET_ARG(0, number);
+  int64_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_CHECK_THIS(object);
+
+  const iotjs_jval_t* jtimer = JHANDLER_GET_THIS(object);
+
+  iotjs_timerwrap_t* timer_wrap = iotjs_timerwrap_from_jobject(jtimer);
+
+  // 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;
+}
diff --git a/tools/src/module/iotjs_module_timer.h b/tools/src/module/iotjs_module_timer.h
new file mode 100644 (file)
index 0000000..f419592
--- /dev/null
@@ -0,0 +1,45 @@
+/* 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;
+  uv_timer_t handle;
+} 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, int64_t timeout,
+                          int64_t repeat);
+// Stop & close timer.
+int iotjs_timerwrap_stop(iotjs_timerwrap_t* timerwrap);
+
+
+#endif /* IOTJS_MODULE_TIMER_H */
diff --git a/tools/src/module/iotjs_module_uart.c b/tools/src/module/iotjs_module_uart.c
new file mode 100644 (file)
index 0000000..c082374
--- /dev/null
@@ -0,0 +1,360 @@
+/* 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 <unistd.h>
+
+#include "iotjs_def.h"
+#include "iotjs_module_uart.h"
+#include "iotjs_objectwrap.h"
+
+
+static void iotjs_uart_destroy(iotjs_uart_t* uart);
+static iotjs_uart_t* iotjs_uart_instance_from_jval(const iotjs_jval_t* juart);
+
+
+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,
+                               (JFreeHandlerType)iotjs_uart_destroy);
+
+  _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, const iotjs_jval_t* juart, 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 = iotjs_uart_instance_from_jval(juart);
+
+  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, jthis, jcallback, op)                         \
+  do {                                                                 \
+    uv_loop_t* loop = iotjs_environment_loop(iotjs_environment_get()); \
+    iotjs_uart_reqwrap_t* req_wrap =                                   \
+        iotjs_uart_reqwrap_create(jcallback, jthis, 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) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_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, juart, jcallback, kUartOpOpen);
+}
+
+
+JHANDLER_FUNCTION(Write) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(1, string);
+  JHANDLER_CHECK_ARG_IF_EXIST(1, function);
+
+  const iotjs_jval_t* jcallback = JHANDLER_GET_ARG_IF_EXIST(1, function);
+  const iotjs_jval_t* juart = JHANDLER_GET_THIS(object);
+  iotjs_uart_t* uart = iotjs_uart_instance_from_jval(juart);
+
+  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, juart, 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_CHECK_THIS(object);
+  JHANDLER_CHECK_ARG_IF_EXIST(0, function);
+
+  const iotjs_jval_t* jcallback = JHANDLER_GET_ARG_IF_EXIST(0, function);
+  const iotjs_jval_t* juart = JHANDLER_GET_THIS(object);
+  iotjs_uart_t* uart = iotjs_uart_instance_from_jval(juart);
+
+  IOTJS_VALIDATED_STRUCT_METHOD(iotjs_uart_t, uart);
+  iotjs_jval_destroy(&_this->jemitter_this);
+
+  if (jcallback) {
+    UART_ASYNC(close, juart, 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;
+}
diff --git a/tools/src/module/iotjs_module_uart.h b/tools/src/module/iotjs_module_uart.h
new file mode 100644 (file)
index 0000000..3b1c72f
--- /dev/null
@@ -0,0 +1,82 @@
+/* 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 */
diff --git a/tools/src/module/iotjs_module_udp.c b/tools/src/module/iotjs_module_udp.c
new file mode 100644 (file)
index 0000000..119c79e
--- /dev/null
@@ -0,0 +1,509 @@
+/* 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"
+
+
+static void iotjs_udpwrap_destroy(iotjs_udpwrap_t* 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),
+                              (JFreeHandlerType)iotjs_udpwrap_destroy);
+
+  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) {
+  JHANDLER_CHECK_THIS(object);
+  JHANDLER_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_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS_2(string, number);
+
+  const iotjs_jval_t* judp = JHANDLER_GET_THIS(object);
+  iotjs_udpwrap_t* udp_wrap = iotjs_udpwrap_from_jobject(judp);
+
+  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));
+
+  int flags = false;
+  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(nread);
+  iotjs_bufferwrap_t* buffer_wrap = iotjs_bufferwrap_from_jbuffer(&jbuffer);
+
+  iotjs_bufferwrap_copy(buffer_wrap, buf->base, 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_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(0);
+
+  const iotjs_jval_t* judp = JHANDLER_GET_THIS(object);
+  iotjs_udpwrap_t* udp_wrap = iotjs_udpwrap_from_jobject(judp);
+
+  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_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(0);
+
+  const iotjs_jval_t* judp = JHANDLER_GET_THIS(object);
+  iotjs_udpwrap_t* udp_wrap = iotjs_udpwrap_from_jobject(judp);
+
+  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_CHECK_THIS(object);
+  JHANDLER_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* judp = JHANDLER_GET_THIS(object);
+  iotjs_udpwrap_t* udp_wrap = iotjs_udpwrap_from_jobject(judp);
+
+  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);
+  int 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_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS(0);
+
+  const iotjs_jval_t* judp = JHANDLER_GET_THIS(object);
+  iotjs_handlewrap_t* wrap = iotjs_handlewrap_from_jobject(judp);
+
+  iotjs_handlewrap_close(wrap, NULL);
+}
+
+
+GetSockNameFunction(udpwrap, udp_handle, uv_udp_getsockname);
+
+
+JHANDLER_FUNCTION(GetSockeName) {
+  DoGetSockName(jhandler);
+}
+
+
+#define IOTJS_UV_SET_SOCKOPT(fn)                                \
+  JHANDLER_CHECK_THIS(object);                                  \
+  JHANDLER_CHECK_ARGS_1(number);                                \
+                                                                \
+  const iotjs_jval_t* judp = JHANDLER_GET_THIS(object);         \
+  iotjs_udpwrap_t* udp_wrap = iotjs_udpwrap_from_jobject(judp); \
+                                                                \
+  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_CHECK_THIS(object);
+  JHANDLER_CHECK_ARGS_1(string);
+
+  const iotjs_jval_t* judp = JHANDLER_GET_THIS(object);
+  iotjs_udpwrap_t* udp_wrap = iotjs_udpwrap_from_jobject(judp);
+
+  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;
+}
diff --git a/tools/src/module/iotjs_module_udp.h b/tools/src/module/iotjs_module_udp.h
new file mode 100644 (file)
index 0000000..2d9e669
--- /dev/null
@@ -0,0 +1,60 @@
+/* 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 */
diff --git a/tools/src/platform/arm-linux/iotjs_module_adc-arm-linux.c b/tools/src/platform/arm-linux/iotjs_module_adc-arm-linux.c
new file mode 100644 (file)
index 0000000..ad31407
--- /dev/null
@@ -0,0 +1,21 @@
+/* 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(__linux__)
+
+#include "../iotjs_module_adc-linux-general.inl.h"
+
+#endif
diff --git a/tools/src/platform/arm-linux/iotjs_module_blehcisocket-arm-linux.c b/tools/src/platform/arm-linux/iotjs_module_blehcisocket-arm-linux.c
new file mode 100644 (file)
index 0000000..eddc16e
--- /dev/null
@@ -0,0 +1,22 @@
+/* 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(__linux__)
+
+#include "iotjs_def.h"
+#include "../iotjs_module_blehcisocket-linux-general.inl.h"
+
+#endif
diff --git a/tools/src/platform/arm-linux/iotjs_module_gpio-arm-linux.c b/tools/src/platform/arm-linux/iotjs_module_gpio-arm-linux.c
new file mode 100644 (file)
index 0000000..8c68b40
--- /dev/null
@@ -0,0 +1,22 @@
+/* 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.
+ */
+
+
+#if defined(__linux__)
+
+#include "iotjs_def.h"
+#include "../iotjs_module_gpio-linux-general.inl.h"
+
+#endif
diff --git a/tools/src/platform/arm-linux/iotjs_module_i2c-arm-linux.c b/tools/src/platform/arm-linux/iotjs_module_i2c-arm-linux.c
new file mode 100644 (file)
index 0000000..0ad37b1
--- /dev/null
@@ -0,0 +1,21 @@
+/* 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(__linux__)
+
+#include "../iotjs_module_i2c-linux-general.inl.h"
+
+#endif
diff --git a/tools/src/platform/arm-linux/iotjs_module_pwm-arm-linux.c b/tools/src/platform/arm-linux/iotjs_module_pwm-arm-linux.c
new file mode 100644 (file)
index 0000000..94e9800
--- /dev/null
@@ -0,0 +1,22 @@
+/* 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(__linux__)
+
+#include "iotjs_def.h"
+#include "../iotjs_module_pwm-linux-general.inl.h"
+
+#endif
diff --git a/tools/src/platform/arm-linux/iotjs_module_spi-arm-linux.c b/tools/src/platform/arm-linux/iotjs_module_spi-arm-linux.c
new file mode 100644 (file)
index 0000000..257ac80
--- /dev/null
@@ -0,0 +1,22 @@
+/* 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(__linux__)
+
+#include "iotjs_def.h"
+#include "../iotjs_module_spi-linux-general.inl.h"
+
+#endif
diff --git a/tools/src/platform/arm-linux/iotjs_module_uart-arm-linux.c b/tools/src/platform/arm-linux/iotjs_module_uart-arm-linux.c
new file mode 100644 (file)
index 0000000..ec6ece5
--- /dev/null
@@ -0,0 +1,21 @@
+/* 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(__linux__)
+
+#include "../iotjs_module_uart-linux-general.inl.h"
+
+#endif // __linux__
diff --git a/tools/src/platform/arm-nuttx/iotjs_module_adc-arm-nuttx.c b/tools/src/platform/arm-nuttx/iotjs_module_adc-arm-nuttx.c
new file mode 100644 (file)
index 0000000..f69e1ca
--- /dev/null
@@ -0,0 +1,134 @@
+/* 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 <uv.h>
+#include <nuttx/analog/adc.h>
+#include <stdlib.h>
+
+#include "iotjs_def.h"
+#include "iotjs_systemio-arm-nuttx.h"
+#include "module/iotjs_module_adc.h"
+#include "module/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(int32_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);
+
+  int32_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);
+
+  int32_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__
diff --git a/tools/src/platform/arm-nuttx/iotjs_module_blehcisocket-arm-nuttx.c b/tools/src/platform/arm-nuttx/iotjs_module_blehcisocket-arm-nuttx.c
new file mode 100644 (file)
index 0000000..a34ef57
--- /dev/null
@@ -0,0 +1,103 @@
+/* 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 "module/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, int 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, int 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;
+}
+
+
+void iotjs_blehcisocket_kernelDisconnectWorkArounds(THIS, int length,
+                                                    char* data) {
+  IOTJS_ASSERT(!"Not implemented");
+}
+
+
+#undef THIS
+
+#endif /* IOTJS_MODULE_BLE_HCI_SOCKET_LINUX_GENERAL_INL_H */
diff --git a/tools/src/platform/arm-nuttx/iotjs_module_gpio-arm-nuttx-general.inl.h b/tools/src/platform/arm-nuttx/iotjs_module_gpio-arm-nuttx-general.inl.h
new file mode 100644 (file)
index 0000000..34d7c18
--- /dev/null
@@ -0,0 +1,48 @@
+/* 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_GPIO_ARM_NUTTX_GENERAL_INL_H
+#define IOTJS_MODULE_GPIO_ARM_NUTTX_GENERAL_INL_H
+
+#include "module/iotjs_module_gpio.h"
+
+
+void iotjs_gpio_open_worker(uv_work_t* work_req) {
+  IOTJS_ASSERT(!"Not implemented");
+}
+
+void iotjs_gpio_write_worker(uv_work_t* work_req) {
+  IOTJS_ASSERT(!"Not implemented");
+}
+
+void iotjs_gpio_read_worker(uv_work_t* work_req) {
+  IOTJS_ASSERT(!"Not implemented");
+}
+
+void iotjs_gpio_close_worker(uv_work_t* work_req) {
+  IOTJS_ASSERT(!"Not implemented");
+}
+
+bool iotjs_gpio_write(uv_work_t* work_req) {
+  IOTJS_ASSERT(!"Not implemented");
+  return false;
+}
+
+int iotjs_gpio_read(uv_work_t* work_req) {
+  IOTJS_ASSERT(!"Not implemented");
+  return -1;
+}
+
+#endif /* IOTJS_MODULE_GPIO_ARM_NUTTX_GENERAL_INL_H */
diff --git a/tools/src/platform/arm-nuttx/iotjs_module_gpio-arm-nuttx-stm32.inl.h b/tools/src/platform/arm-nuttx/iotjs_module_gpio-arm-nuttx-stm32.inl.h
new file mode 100644 (file)
index 0000000..aa88515
--- /dev/null
@@ -0,0 +1,108 @@
+/* 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_GPIO_ARM_NUTTX_STM32_INL_H
+#define IOTJS_MODULE_GPIO_ARM_NUTTX_STM32_INL_H
+
+#include "module/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(int32_t pin, bool value) {
+  DDDLOG("%s - pin: %d, value: %d", __func__, pin, value);
+  stm32_gpiowrite(pin, value);
+
+  return true;
+}
+
+
+int iotjs_gpio_read(int32_t pin) {
+  DDDLOG("%s - pin: %d", __func__, pin);
+  return stm32_gpioread(pin);
+}
+
+
+bool iotjs_gpio_close(int32_t pin) {
+  DDDLOG("%s - pin: %d", __func__, pin);
+  iotjs_gpio_write(pin, 0);
+
+  return true;
+}
+
+
+void iotjs_gpio_open_worker(uv_work_t* work_req) {
+  GPIO_WORKER_INIT();
+  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 = -1;
+    return;
+  }
+
+  req_data->result = 0;
+}
+
+
+void iotjs_gpio_write_worker(uv_work_t* work_req) {
+  GPIO_WORKER_INIT();
+  DDDLOG("%s - pin: %d, value: %d", __func__, _this->pin, req_data->value);
+
+  iotjs_gpio_write(_this->pin, req_data->value);
+
+  req_data->result = 0;
+}
+
+
+void iotjs_gpio_read_worker(uv_work_t* work_req) {
+  GPIO_WORKER_INIT();
+  DDDLOG("%s - pin: %d", __func__, _this->pin);
+
+  req_data->result = 0;
+  req_data->value = iotjs_gpio_read(_this->pin);
+}
+
+
+void iotjs_gpio_close_worker(uv_work_t* work_req) {
+  GPIO_WORKER_INIT();
+  DDDLOG("%s - pin: %d", __func__, _this->pin);
+
+  iotjs_gpio_close(_this->pin);
+
+  req_data->result = 0;
+}
+
+#endif /* IOTJS_MODULE_GPIO_ARM_NUTTX_STM32_INL_H */
diff --git a/tools/src/platform/arm-nuttx/iotjs_module_gpio-arm-nuttx.c b/tools/src/platform/arm-nuttx/iotjs_module_gpio-arm-nuttx.c
new file mode 100644 (file)
index 0000000..0e48a20
--- /dev/null
@@ -0,0 +1,30 @@
+/* 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.
+ */
+
+#if defined(__NUTTX__)
+
+#if defined(TARGET_BOARD) && TARGET_BOARD == STM32F4DIS
+
+#include "iotjs_def.h"
+#include "./iotjs_module_gpio-arm-nuttx-stm32.inl.h"
+
+#else
+
+#include "iotjs_def.h"
+#include "./iotjs_module_gpio-arm-nuttx-general.inl.h"
+
+#endif
+
+#endif // __NUTTX__
diff --git a/tools/src/platform/arm-nuttx/iotjs_module_i2c-arm-nuttx.c b/tools/src/platform/arm-nuttx/iotjs_module_i2c-arm-nuttx.c
new file mode 100644 (file)
index 0000000..6f06169
--- /dev/null
@@ -0,0 +1,197 @@
+/* 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 "module/iotjs_module_i2c.h"
+#include "iotjs_systemio-arm-nuttx.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 WriteByteWorker(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);
+
+  IOTJS_ASSERT(!_this->i2c_master);
+
+  int ret = i2c_write(_this->i2c_master, &_this->config, &req_data->byte, 1);
+  if (ret < 0) {
+    DDLOG("I2C WriteByteWorker : cannot write - %d", ret);
+    req_data->error = kI2cErrWrite;
+    return;
+  }
+  req_data->error = kI2cErrOk;
+}
+
+
+void WriteBlockWorker(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 cmd = req_data->cmd;
+  uint8_t len = req_data->buf_len;
+  char* data = req_data->buf_data;
+
+  // The first element of data array is command.
+  iotjs_buffer_reallocate(data, len + 1);
+  memmove(data + 1, data, len * sizeof(char));
+  data[0] = cmd;
+
+  IOTJS_ASSERT(!_this->i2c_master);
+
+  int ret =
+      i2c_write(_this->i2c_master, &_this->config, &req_data->byte, len + 1);
+  if (ret < 0) {
+    DDLOG("I2C WriteBlockWorker : cannot write - %d", ret);
+    req_data->error = kI2cErrWrite;
+    return;
+  }
+  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;
+}
+
+
+void ReadByteWorker(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);
+
+  IOTJS_ASSERT(!_this->i2c_master);
+
+  int ret = i2c_read(_this->i2c_master, &_this->config, &req_data->byte, 1);
+  if (ret < 0) {
+    DDLOG("I2C ReadByteWorker : cannot read - %d", ret);
+    req_data->error = kI2cErrRead;
+    return;
+  }
+  req_data->error = kI2cErrOk;
+}
+
+
+void ReadBlockWorker(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 cmd = req_data->cmd;
+  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_writeread(_this->i2c_master, &_this->config, &cmd, 1,
+                          (uint8_t*)req_data->buf_data, len);
+
+  if (ret < 0) {
+    DDLOG("I2C ReadBlockWorker : cannot read - %d", ret);
+    req_data->error = kI2cErrRead;
+    return;
+  }
+  req_data->error = kI2cErrOk;
+}
+
+
+#endif // __NUTTX__
diff --git a/tools/src/platform/arm-nuttx/iotjs_module_pwm-arm-nuttx.c b/tools/src/platform/arm-nuttx/iotjs_module_pwm-arm-nuttx.c
new file mode 100644 (file)
index 0000000..6da6ce9
--- /dev/null
@@ -0,0 +1,174 @@
+/* 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 <nuttx/drivers/pwm.h>
+#include <stdlib.h>
+#include <sys/ioctl.h>
+
+#include "iotjs_def.h"
+#include "iotjs_systemio-arm-nuttx.h"
+#include "module/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);
+
+  uint32_t 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__
diff --git a/tools/src/platform/arm-nuttx/iotjs_module_spi-arm-nuttx.c b/tools/src/platform/arm-nuttx/iotjs_module_spi-arm-nuttx.c
new file mode 100644 (file)
index 0000000..2361b0c
--- /dev/null
@@ -0,0 +1,48 @@
+/* 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 "module/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__
diff --git a/tools/src/platform/arm-nuttx/iotjs_module_stm32f4dis-arm-nuttx.c b/tools/src/platform/arm-nuttx/iotjs_module_stm32f4dis-arm-nuttx.c
new file mode 100644 (file)
index 0000000..aaf4392
--- /dev/null
@@ -0,0 +1,194 @@
+/* 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 "module/iotjs_module_stm32f4dis.h"
+#include "iotjs_systemio-arm-nuttx.h"
+#include "stm32_gpio.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); \
+  iotjs_jval_destroy(&jtim##timer);
+
+#define SET_GPIO_CONSTANT_TIM_2(timer) \
+  SET_GPIO_CONSTANT_TIM(timer);        \
+  SET_GPIO_CONSTANT_CHANNEL(timer, 1); \
+  SET_GPIO_CONSTANT_CHANNEL(timer, 2); \
+  iotjs_jval_destroy(&jtim##timer);
+
+#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); \
+  iotjs_jval_destroy(&jtim##timer);
+
+  SET_GPIO_CONSTANT_TIM_4(1); // PA8, PE9, PA9, PE11, PA10, PE13, PA11, PE14
+  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
+  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
+  SET_GPIO_CONSTANT_TIM_4(4);  // PB6, PD12, PB7, PD13, PB8, PD14, PB9, PD15
+  SET_GPIO_CONSTANT_TIM_4(5);  // PA0, PH10, PA1, PH11, PA2, PH12, PA3, PI0
+  SET_GPIO_CONSTANT_TIM_4(8);  // PC6, PI5, PC7, PI6, PC8, PI7, PC9, PI2
+  SET_GPIO_CONSTANT_TIM_2(9);  // PA2, PE5, PA3, PE6
+  SET_GPIO_CONSTANT_TIM_1(10); // PB8, PF6
+  SET_GPIO_CONSTANT_TIM_1(11); // PB9, PF7
+  SET_GPIO_CONSTANT_TIM_2(12); // PH6, PB14, PB15, PH9
+  SET_GPIO_CONSTANT_TIM_1(13); // PA6, PF8
+  SET_GPIO_CONSTANT_TIM_1(14); // PA7, PF9
+
+#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__
diff --git a/tools/src/platform/arm-nuttx/iotjs_module_uart-arm-nuttx.c b/tools/src/platform/arm-nuttx/iotjs_module_uart-arm-nuttx.c
new file mode 100644 (file)
index 0000000..d9547a5
--- /dev/null
@@ -0,0 +1,78 @@
+/* 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 "module/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 += bytesWritten;
+      continue;
+    }
+
+    if (errno == EINTR) {
+      continue;
+    }
+
+    return false;
+
+  } while (_this->buf_len > offset);
+
+  return true;
+}
+
+
+#endif // __NUTTX__
diff --git a/tools/src/platform/arm-nuttx/iotjs_systemio-arm-nuttx-stm32.c b/tools/src/platform/arm-nuttx/iotjs_systemio-arm-nuttx-stm32.c
new file mode 100644 (file)
index 0000000..27d9b7c
--- /dev/null
@@ -0,0 +1,73 @@
+/* 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_systemio-arm-nuttx.h"
+#include "stm32_gpio.h"
+
+
+void iotjs_gpio_unconfig_nuttx(int pin) {
+  stm32_unconfiggpio(pin);
+}
+
+
+#if ENABLE_MODULE_ADC
+
+#include "stm32_adc.h"
+
+struct adc_dev_s* iotjs_adc_config_nuttx(int number, int timer, int 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, int pin) {
+  // Set alternative function
+  stm32_configgpio(pin);
+
+  // PWM initialize
+  return stm32_pwminitialize(timer);
+}
+
+#endif /* ENABLE_MODULE_PWM */
+
+
+#endif // __NUTTX__
diff --git a/tools/src/platform/arm-nuttx/iotjs_systemio-arm-nuttx.h b/tools/src/platform/arm-nuttx/iotjs_systemio-arm-nuttx.h
new file mode 100644 (file)
index 0000000..306d677
--- /dev/null
@@ -0,0 +1,67 @@
+/* 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
+
+
+void iotjs_gpio_unconfig_nuttx(int 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 <nuttx/analog/adc.h>
+
+#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, int pin);
+
+#endif /* ENABLE_MODULE_ADC */
+
+
+#if ENABLE_MODULE_I2C
+
+#include <nuttx/i2c/i2c_master.h>
+
+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 <nuttx/drivers/pwm.h>
+
+struct pwm_lowerhalf_s* iotjs_pwm_config_nuttx(int timer, int pin);
+
+#endif /* ENABLE_MODULE_PWM */
+
+
+#endif /* IOTJS_SYSTEMIO_ARM_NUTTX_H */
diff --git a/tools/src/platform/i686-linux/iotjs_module_adc-i686-linux.c b/tools/src/platform/i686-linux/iotjs_module_adc-i686-linux.c
new file mode 100644 (file)
index 0000000..ad31407
--- /dev/null
@@ -0,0 +1,21 @@
+/* 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(__linux__)
+
+#include "../iotjs_module_adc-linux-general.inl.h"
+
+#endif
diff --git a/tools/src/platform/i686-linux/iotjs_module_blehcisocket-i686-linux.c b/tools/src/platform/i686-linux/iotjs_module_blehcisocket-i686-linux.c
new file mode 100644 (file)
index 0000000..eddc16e
--- /dev/null
@@ -0,0 +1,22 @@
+/* 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(__linux__)
+
+#include "iotjs_def.h"
+#include "../iotjs_module_blehcisocket-linux-general.inl.h"
+
+#endif
diff --git a/tools/src/platform/i686-linux/iotjs_module_gpio-i686-linux.c b/tools/src/platform/i686-linux/iotjs_module_gpio-i686-linux.c
new file mode 100644 (file)
index 0000000..8c68b40
--- /dev/null
@@ -0,0 +1,22 @@
+/* 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.
+ */
+
+
+#if defined(__linux__)
+
+#include "iotjs_def.h"
+#include "../iotjs_module_gpio-linux-general.inl.h"
+
+#endif
diff --git a/tools/src/platform/i686-linux/iotjs_module_i2c-i686-linux.c b/tools/src/platform/i686-linux/iotjs_module_i2c-i686-linux.c
new file mode 100644 (file)
index 0000000..0ad37b1
--- /dev/null
@@ -0,0 +1,21 @@
+/* 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(__linux__)
+
+#include "../iotjs_module_i2c-linux-general.inl.h"
+
+#endif
diff --git a/tools/src/platform/i686-linux/iotjs_module_pwm-i686-linux.c b/tools/src/platform/i686-linux/iotjs_module_pwm-i686-linux.c
new file mode 100644 (file)
index 0000000..94e9800
--- /dev/null
@@ -0,0 +1,22 @@
+/* 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(__linux__)
+
+#include "iotjs_def.h"
+#include "../iotjs_module_pwm-linux-general.inl.h"
+
+#endif
diff --git a/tools/src/platform/i686-linux/iotjs_module_spi-i686-linux.c b/tools/src/platform/i686-linux/iotjs_module_spi-i686-linux.c
new file mode 100644 (file)
index 0000000..257ac80
--- /dev/null
@@ -0,0 +1,22 @@
+/* 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(__linux__)
+
+#include "iotjs_def.h"
+#include "../iotjs_module_spi-linux-general.inl.h"
+
+#endif
diff --git a/tools/src/platform/i686-linux/iotjs_module_uart-i686-linux.c b/tools/src/platform/i686-linux/iotjs_module_uart-i686-linux.c
new file mode 100644 (file)
index 0000000..df55956
--- /dev/null
@@ -0,0 +1,21 @@
+/* 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(__linux__)
+
+#include "../iotjs_module_uart-linux-general.inl.h"
+
+#endif // __linux__
diff --git a/tools/src/platform/iotjs_module_adc-linux-general.inl.h b/tools/src/platform/iotjs_module_adc-linux-general.inl.h
new file mode 100644 (file)
index 0000000..a4b95b8
--- /dev/null
@@ -0,0 +1,68 @@
+/* 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "iotjs_systemio-linux.h"
+#include "module/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 */
diff --git a/tools/src/platform/iotjs_module_blehcisocket-linux-general.inl.h b/tools/src/platform/iotjs_module_blehcisocket-linux-general.inl.h
new file mode 100644 (file)
index 0000000..4803a34
--- /dev/null
@@ -0,0 +1,442 @@
+/* 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 <errno.h>
+#include <stdlib.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "iotjs_def.h"
+#include "module/iotjs_module_blehcisocket.h"
+#include "module/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;
+
+  bind(_this->_socket, (struct sockaddr*)&a, sizeof(a));
+
+  // 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;
+
+  bind(_this->_socket, (struct sockaddr*)&a, sizeof(a));
+
+  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;
+
+  bind(_this->_socket, (struct sockaddr*)&a, sizeof(a));
+}
+
+
+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, int length) {
+  IOTJS_VALIDATED_STRUCT_METHOD(iotjs_blehcisocket_t, blehcisocket);
+
+  if (setsockopt(_this->_socket, SOL_HCI, HCI_FILTER, data, 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) {
+      iotjs_blehcisocket_kernelDisconnectWorkArounds(blehcisocket, length,
+                                                     data);
+    }
+
+    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_jval_t jbuf = iotjs_bufferwrap_create_buffer(length);
+    iotjs_bufferwrap_t* buf_wrap = iotjs_bufferwrap_from_jbuffer(&jbuf);
+    iotjs_bufferwrap_copy(buf_wrap, data, 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, int 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;
+}
+
+
+void 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);
+
+    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;
+    bind(l2socket, (struct sockaddr*)&l2a, sizeof(l2a));
+
+    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;
+
+    connect(l2socket, (struct sockaddr*)&l2a, sizeof(l2a));
+
+    _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--;
+    }
+  }
+}
+
+#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 */
diff --git a/tools/src/platform/iotjs_module_gpio-linux-general.inl.h b/tools/src/platform/iotjs_module_gpio-linux-general.inl.h
new file mode 100644 (file)
index 0000000..27150ad
--- /dev/null
@@ -0,0 +1,180 @@
+/* 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_LINUX_GENERAL_INL_H
+#define IOTJS_MODULE_GPIO_LINUX_GENERAL_INL_H
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "iotjs_systemio-linux.h"
+#include "module/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 bool gpio_set_direction(int32_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(int32_t pin, GpioMode mode) {
+  return true;
+}
+
+
+bool iotjs_gpio_write(int32_t pin, bool value) {
+  char value_path[GPIO_PATH_BUFFER_SIZE];
+  snprintf(value_path, GPIO_PATH_BUFFER_SIZE, GPIO_PIN_FORMAT_VALUE, pin);
+
+  const char* buffer = value ? "1" : "0";
+
+  DDDLOG("%s - pin: %d, value: %d", __func__, pin, value);
+
+  return iotjs_systemio_open_write_close(value_path, buffer);
+}
+
+
+int iotjs_gpio_read(int32_t pin) {
+  char buffer[GPIO_VALUE_BUFFER_SIZE];
+  char value_path[GPIO_PATH_BUFFER_SIZE];
+  snprintf(value_path, GPIO_PATH_BUFFER_SIZE, GPIO_PIN_FORMAT_VALUE, pin);
+
+  if (!iotjs_systemio_open_read_close(value_path, buffer,
+                                      GPIO_VALUE_BUFFER_SIZE - 1)) {
+    return -1;
+  }
+
+  return atoi(buffer);
+}
+
+
+bool iotjs_gpio_close(int32_t pin) {
+  char buff[GPIO_PIN_BUFFER_SIZE];
+  snprintf(buff, GPIO_PIN_BUFFER_SIZE, "%d", pin);
+
+  return iotjs_systemio_open_write_close(GPIO_PIN_FORMAT_UNEXPORT, buff);
+}
+
+
+void iotjs_gpio_open_worker(uv_work_t* work_req) {
+  GPIO_WORKER_INIT();
+
+  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 = -1;
+    return;
+  }
+  // Set direction.
+  if (!gpio_set_direction(_this->pin, _this->direction)) {
+    req_data->result = -1;
+    return;
+  }
+  // Set mode.
+  if (!gpio_set_mode(_this->pin, _this->mode)) {
+    req_data->result = -1;
+    return;
+  }
+
+  req_data->result = 0;
+}
+
+
+void iotjs_gpio_write_worker(uv_work_t* work_req) {
+  GPIO_WORKER_INIT();
+  DDDLOG("%s - pin: %d, value: %d", __func__, _this->pin, req_data->value);
+
+  bool result = iotjs_gpio_write(_this->pin, req_data->value);
+
+  if (result) {
+    req_data->result = 0;
+  } else {
+    req_data->result = -1;
+  }
+}
+
+
+void iotjs_gpio_read_worker(uv_work_t* work_req) {
+  GPIO_WORKER_INIT();
+  DDDLOG("%s - pin: %d", __func__, _this->pin);
+
+  int result = iotjs_gpio_read(_this->pin);
+  if (result >= 0) {
+    req_data->result = 0;
+    req_data->value = (bool)result;
+  } else {
+    req_data->result = -1;
+  }
+}
+
+
+void iotjs_gpio_close_worker(uv_work_t* work_req) {
+  GPIO_WORKER_INIT();
+  DDDLOG("%s - pin : %d", __func__, _this->pin);
+
+  if (iotjs_gpio_close(_this->pin)) {
+    req_data->result = 0;
+  } else {
+    req_data->result = -1;
+  }
+}
+
+
+#endif /* IOTJS_MODULE_GPIO_LINUX_GENERAL_INL_H */
diff --git a/tools/src/platform/iotjs_module_i2c-linux-general.inl.h b/tools/src/platform/iotjs_module_i2c-linux-general.inl.h
new file mode 100644 (file)
index 0000000..c3f7792
--- /dev/null
@@ -0,0 +1,278 @@
+/* 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.)
+ */
+
+
+#ifndef IOTJS_MODULE_I2C_LINUX_GENERAL_INL_H
+#define IOTJS_MODULE_I2C_LINUX_GENERAL_INL_H
+
+
+#include <fcntl.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+
+#include "module/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;
+
+
+static int current_fd;
+static uint8_t addr;
+
+
+int I2cSmbusAccess(int fd, uint8_t read_write, uint8_t command, int size,
+                   I2cSmbusData* data) {
+  I2cSmbusIoctlData args;
+
+  args.read_write = read_write;
+  args.command = command;
+  args.size = size;
+  args.data = data;
+
+  return ioctl(fd, I2C_SMBUS, &args);
+}
+
+
+int I2cSmbusWriteByte(int fd, uint8_t byte) {
+  return I2cSmbusAccess(fd, I2C_SMBUS_WRITE, byte, I2C_SMBUS_BYTE, NULL);
+}
+
+
+int I2cSmbusWriteI2cBlockData(int fd, uint8_t command, uint8_t* values,
+                              uint8_t length) {
+  I2cSmbusData data;
+
+  if (length > I2C_SMBUS_BLOCK_MAX) {
+    length = I2C_SMBUS_BLOCK_MAX;
+  }
+
+  for (int i = 1; i <= length; i++) {
+    data.block[i] = values[i - 1];
+  }
+  data.block[0] = length;
+
+  return I2cSmbusAccess(fd, I2C_SMBUS_WRITE, command, I2C_SMBUS_I2C_BLOCK_DATA,
+                        &data);
+}
+
+
+int I2cSmbusReadByte(int fd) {
+  I2cSmbusData data;
+
+  int result =
+      I2cSmbusAccess(fd, I2C_SMBUS_READ, I2C_NOCMD, I2C_SMBUS_BYTE, &data);
+
+  // Mask one byte from result (data.byte).
+  return result >= 0 ? 0xFF & data.byte : -1;
+}
+
+
+int I2cSmbusReadI2cBlockData(int fd, uint8_t command, uint8_t* values,
+                             uint8_t length) {
+  I2cSmbusData data;
+
+  if (length > I2C_SMBUS_BLOCK_MAX) {
+    length = I2C_SMBUS_BLOCK_MAX;
+  }
+  data.block[0] = length;
+
+  int result = I2cSmbusAccess(fd, I2C_SMBUS_READ, command,
+                              I2C_SMBUS_I2C_BLOCK_DATA, &data);
+  if (result >= 0) {
+    for (int i = 1; i <= data.block[0]; i++) {
+      values[i - 1] = data.block[i];
+    }
+    result = data.block[0];
+  }
+
+  return result;
+}
+
+
+#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) {
+  addr = address;
+  ioctl(current_fd, I2C_SLAVE_FORCE, addr);
+}
+
+
+void OpenWorker(uv_work_t* work_req) {
+  I2C_WORKER_INIT_TEMPLATE;
+
+  current_fd = open(iotjs_string_data(&req_data->device), O_RDWR);
+
+  if (current_fd == -1) {
+    req_data->error = kI2cErrOpen;
+  } else {
+    req_data->error = kI2cErrOk;
+  }
+}
+
+
+void I2cClose(iotjs_i2c_t* i2c) {
+  if (current_fd > 0) {
+    close(current_fd);
+  }
+}
+
+
+void WriteWorker(uv_work_t* work_req) {
+  I2C_WORKER_INIT_TEMPLATE;
+
+  uint8_t len = req_data->buf_len;
+  char* data = req_data->buf_data;
+
+  if (write(current_fd, data, len) != len) {
+    req_data->error = kI2cErrWrite;
+  }
+
+  if (req_data->buf_data != NULL) {
+    iotjs_buffer_release(req_data->buf_data);
+  }
+}
+
+
+void WriteByteWorker(uv_work_t* work_req) {
+  I2C_WORKER_INIT_TEMPLATE;
+
+  if (I2cSmbusWriteByte(current_fd, req_data->byte) == -1) {
+    req_data->error = kI2cErrWrite;
+  }
+}
+
+
+void WriteBlockWorker(uv_work_t* work_req) {
+  I2C_WORKER_INIT_TEMPLATE;
+
+  uint8_t cmd = req_data->cmd;
+  uint8_t len = req_data->buf_len;
+  uint8_t* data = (uint8_t*)(req_data->buf_data);
+
+  if (I2cSmbusWriteI2cBlockData(current_fd, cmd, data, len) == -1) {
+    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;
+
+  uint8_t len = req_data->buf_len;
+  req_data->buf_data = iotjs_buffer_allocate(len);
+
+  if (read(current_fd, req_data->buf_data, len) != len) {
+    req_data->error = kI2cErrRead;
+  }
+}
+
+
+void ReadByteWorker(uv_work_t* work_req) {
+  I2C_WORKER_INIT_TEMPLATE;
+
+  int result = I2cSmbusReadByte(current_fd);
+  if (result == -1) {
+    req_data->error = kI2cErrRead;
+  } else {
+    req_data->byte = result;
+  }
+}
+
+
+void ReadBlockWorker(uv_work_t* work_req) {
+  I2C_WORKER_INIT_TEMPLATE;
+
+  uint8_t cmd = req_data->cmd;
+  uint8_t len = req_data->buf_len;
+  uint8_t data[I2C_SMBUS_BLOCK_MAX + 2];
+
+  if (I2cSmbusReadI2cBlockData(current_fd, cmd, data, len) != len) {
+    req_data->error = kI2cErrReadBlock;
+  }
+
+  req_data->buf_data = iotjs_buffer_allocate(len);
+  memcpy(req_data->buf_data, data, len);
+}
+
+
+#endif /* IOTJS_MODULE_I2C_LINUX_GENERAL_INL_H */
diff --git a/tools/src/platform/iotjs_module_pwm-linux-general.inl.h b/tools/src/platform/iotjs_module_pwm-linux-general.inl.h
new file mode 100644 (file)
index 0000000..5bb4a0f
--- /dev/null
@@ -0,0 +1,229 @@
+/* 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 <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "iotjs_systemio-linux.h"
+#include "module/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.
+  int prefixSize = iotjs_string_size(device);
+  if (prefixSize > 0) {
+    int suffixSize = fileName ? strlen(fileName) : 0;
+    devicePath = malloc(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 */
diff --git a/tools/src/platform/iotjs_module_spi-linux-general.inl.h b/tools/src/platform/iotjs_module_spi-linux-general.inl.h
new file mode 100644 (file)
index 0000000..b7d3ef0
--- /dev/null
@@ -0,0 +1,169 @@
+/* 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 <uv.h>
+#include <linux/spi/spidev.h>
+#include <sys/ioctl.h>
+
+#include "iotjs_def.h"
+#include "iotjs_systemio-linux.h"
+#include "module/iotjs_module_buffer.h"
+#include "module/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 */
diff --git a/tools/src/platform/iotjs_module_uart-linux-general.inl.h b/tools/src/platform/iotjs_module_uart-linux-general.inl.h
new file mode 100644 (file)
index 0000000..660c31c
--- /dev/null
@@ -0,0 +1,154 @@
+/* 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 <errno.h>
+#include <fcntl.h>
+#include <termios.h>
+#include <unistd.h>
+#include "module/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 |= baud_to_constant(_this->baud_rate);
+  options.c_cflag |= 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 += bytesWritten;
+      continue;
+    }
+
+    if (errno == EINTR) {
+      continue;
+    }
+
+    return false;
+
+  } while (_this->buf_len > offset);
+
+  return true;
+}
+
+
+#endif /* IOTJS_MODULE_UART_LINUX_GENERAL_INL_H */
diff --git a/tools/src/platform/iotjs_systemio-linux.c b/tools/src/platform/iotjs_systemio-linux.c
new file mode 100644 (file)
index 0000000..48738f8
--- /dev/null
@@ -0,0 +1,192 @@
+/* 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 <uv.h>
+#include <unistd.h>
+
+#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,
+                                    int 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, int 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, int 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;
+}
diff --git a/tools/src/platform/iotjs_systemio-linux.h b/tools/src/platform/iotjs_systemio-linux.h
new file mode 100644 (file)
index 0000000..87dc691
--- /dev/null
@@ -0,0 +1,40 @@
+/* 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,
+                                    int buffer_len);
+
+bool iotjs_systemio_device_open(const char* export_path, int value,
+                                const char* exported_path,
+                                const char** created_files,
+                                int created_files_length);
+
+bool iotjs_systemio_device_close(const char* export_path, int value);
+
+
+#endif /* IOTJS_DEVICE_IO_LINUX_GENERAL_H */
diff --git a/tools/src/platform/x86_64-darwin/iotjs_module_adc-x86_64-darwin.c b/tools/src/platform/x86_64-darwin/iotjs_module_adc-x86_64-darwin.c
new file mode 100644 (file)
index 0000000..69344e5
--- /dev/null
@@ -0,0 +1,26 @@
+/* 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(__APPLE__)
+
+#include "module/iotjs_module_adc.h"
+#include "iotjs_module_unimplemented.inl.h"
+
+int32_t iotjs_adc_read(iotjs_adc_t* adc) IOTJS_MODULE_UNIMPLEMENTED(-1);
+bool iotjs_adc_close(iotjs_adc_t* adc) IOTJS_MODULE_UNIMPLEMENTED(0);
+void iotjs_adc_open_worker(uv_work_t* work_req) IOTJS_MODULE_UNIMPLEMENTED();
+
+#endif // __APPLE__
diff --git a/tools/src/platform/x86_64-darwin/iotjs_module_blehcisocket-x86_64-darwin.c b/tools/src/platform/x86_64-darwin/iotjs_module_blehcisocket-x86_64-darwin.c
new file mode 100644 (file)
index 0000000..de961c2
--- /dev/null
@@ -0,0 +1,39 @@
+/* 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(__APPLE__)
+
+#include "module/iotjs_module_blehcisocket.h"
+#include "iotjs_module_unimplemented.inl.h"
+
+#define THIS iotjs_blehcisocket_t* iotjs_blehcisocket
+
+void iotjs_blehcisocket_initialize(THIS) IOTJS_MODULE_UNIMPLEMENTED();
+void iotjs_blehcisocket_close(THIS) IOTJS_MODULE_UNIMPLEMENTED();
+void iotjs_blehcisocket_start(THIS) IOTJS_MODULE_UNIMPLEMENTED();
+int iotjs_blehcisocket_bindRaw(THIS, int* devId) IOTJS_MODULE_UNIMPLEMENTED(0);
+int iotjs_blehcisocket_bindUser(THIS, int* devId) IOTJS_MODULE_UNIMPLEMENTED(0);
+void iotjs_blehcisocket_bindControl(THIS) IOTJS_MODULE_UNIMPLEMENTED();
+bool iotjs_blehcisocket_isDevUp(THIS) IOTJS_MODULE_UNIMPLEMENTED(false);
+void iotjs_blehcisocket_setFilter(THIS, char* data, int length)
+    IOTJS_MODULE_UNIMPLEMENTED();
+void iotjs_blehcisocket_stop(THIS) IOTJS_MODULE_UNIMPLEMENTED();
+void iotjs_blehcisocket_write(THIS, char* data, int length)
+    IOTJS_MODULE_UNIMPLEMENTED();
+
+#undef THIS
+
+#endif // __APPLE__
diff --git a/tools/src/platform/x86_64-darwin/iotjs_module_gpio-x86_64-darwin.c b/tools/src/platform/x86_64-darwin/iotjs_module_gpio-x86_64-darwin.c
new file mode 100644 (file)
index 0000000..84ce9c5
--- /dev/null
@@ -0,0 +1,31 @@
+/* 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(__APPLE__)
+
+#include "module/iotjs_module_gpio.h"
+#include "iotjs_module_unimplemented.inl.h"
+
+void iotjs_gpio_open_worker(uv_work_t* work_req) IOTJS_MODULE_UNIMPLEMENTED();
+void iotjs_gpio_write_worker(uv_work_t* work_req) IOTJS_MODULE_UNIMPLEMENTED();
+void iotjs_gpio_read_worker(uv_work_t* work_req) IOTJS_MODULE_UNIMPLEMENTED();
+void iotjs_gpio_close_worker(uv_work_t* work_req) IOTJS_MODULE_UNIMPLEMENTED();
+bool iotjs_gpio_write(int32_t pin, bool value)
+    IOTJS_MODULE_UNIMPLEMENTED(false);
+int iotjs_gpio_read(int32_t pin) IOTJS_MODULE_UNIMPLEMENTED(0);
+bool iotjs_gpio_close(int32_t pin) IOTJS_MODULE_UNIMPLEMENTED(false);
+
+#endif // __APPLE__
diff --git a/tools/src/platform/x86_64-darwin/iotjs_module_i2c-x86_64-darwin.c b/tools/src/platform/x86_64-darwin/iotjs_module_i2c-x86_64-darwin.c
new file mode 100644 (file)
index 0000000..b806f92
--- /dev/null
@@ -0,0 +1,33 @@
+/* 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(__APPLE__)
+
+#include "module/iotjs_module_i2c.h"
+#include "iotjs_module_unimplemented.inl.h"
+
+void I2cSetAddress(iotjs_i2c_t* i2c, uint8_t address)
+    IOTJS_MODULE_UNIMPLEMENTED();
+void OpenWorker(uv_work_t* work_req) IOTJS_MODULE_UNIMPLEMENTED();
+void I2cClose(iotjs_i2c_t* i2c) IOTJS_MODULE_UNIMPLEMENTED();
+void WriteWorker(uv_work_t* work_req) IOTJS_MODULE_UNIMPLEMENTED();
+void WriteByteWorker(uv_work_t* work_req) IOTJS_MODULE_UNIMPLEMENTED();
+void WriteBlockWorker(uv_work_t* work_req) IOTJS_MODULE_UNIMPLEMENTED();
+void ReadWorker(uv_work_t* work_req) IOTJS_MODULE_UNIMPLEMENTED();
+void ReadByteWorker(uv_work_t* work_req) IOTJS_MODULE_UNIMPLEMENTED();
+void ReadBlockWorker(uv_work_t* work_req) IOTJS_MODULE_UNIMPLEMENTED();
+
+#endif // __APPLE__
diff --git a/tools/src/platform/x86_64-darwin/iotjs_module_pwm-x86_64-darwin.c b/tools/src/platform/x86_64-darwin/iotjs_module_pwm-x86_64-darwin.c
new file mode 100644 (file)
index 0000000..c0d012b
--- /dev/null
@@ -0,0 +1,29 @@
+/* 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(__APPLE__)
+
+#include "module/iotjs_module_pwm.h"
+#include "iotjs_module_unimplemented.inl.h"
+
+void iotjs_pwm_open_worker(uv_work_t* work_req) IOTJS_MODULE_UNIMPLEMENTED();
+bool iotjs_pwm_set_period(iotjs_pwm_t* pwm) IOTJS_MODULE_UNIMPLEMENTED(false);
+bool iotjs_pwm_set_dutycycle(iotjs_pwm_t* pwm)
+    IOTJS_MODULE_UNIMPLEMENTED(false);
+bool iotjs_pwm_set_enable(iotjs_pwm_t* pwm) IOTJS_MODULE_UNIMPLEMENTED(false);
+bool iotjs_pwm_close(iotjs_pwm_t* pwm) IOTJS_MODULE_UNIMPLEMENTED(false);
+
+#endif // __APPLE__
diff --git a/tools/src/platform/x86_64-darwin/iotjs_module_spi-x86_64-darwin.c b/tools/src/platform/x86_64-darwin/iotjs_module_spi-x86_64-darwin.c
new file mode 100644 (file)
index 0000000..69d1555
--- /dev/null
@@ -0,0 +1,26 @@
+/* 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(__APPLE__)
+
+#include "module/iotjs_module_spi.h"
+#include "iotjs_module_unimplemented.inl.h"
+
+bool iotjs_spi_transfer(iotjs_spi_t* spi) IOTJS_MODULE_UNIMPLEMENTED(false);
+bool iotjs_spi_close(iotjs_spi_t* spi) IOTJS_MODULE_UNIMPLEMENTED(false);
+void iotjs_spi_open_worker(uv_work_t* work_req) IOTJS_MODULE_UNIMPLEMENTED();
+
+#endif // __APPLE__
diff --git a/tools/src/platform/x86_64-darwin/iotjs_module_uart-x86_64-darwin.c b/tools/src/platform/x86_64-darwin/iotjs_module_uart-x86_64-darwin.c
new file mode 100644 (file)
index 0000000..3e1531c
--- /dev/null
@@ -0,0 +1,25 @@
+/* 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(__APPLE__)
+
+#include "module/iotjs_module_uart.h"
+#include "iotjs_module_unimplemented.inl.h"
+
+void iotjs_uart_open_worker(uv_work_t* work_req) IOTJS_MODULE_UNIMPLEMENTED();
+bool iotjs_uart_write(iotjs_uart_t* uart) IOTJS_MODULE_UNIMPLEMENTED(false);
+
+#endif // __APPLE__
diff --git a/tools/src/platform/x86_64-darwin/iotjs_module_unimplemented.inl.h b/tools/src/platform/x86_64-darwin/iotjs_module_unimplemented.inl.h
new file mode 100644 (file)
index 0000000..4b6b3f5
--- /dev/null
@@ -0,0 +1,29 @@
+/* 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_UNIMPLEMENTED_INL_H
+#define IOTJS_MODULE_UNIMPLEMENTED_INL_H
+
+#include "iotjs_def.h"
+
+
+#define IOTJS_MODULE_UNIMPLEMENTED(DUMMY) \
+  {                                       \
+    IOTJS_ASSERT(!"Not implemented");     \
+    return DUMMY;                         \
+  }
+
+
+#endif /* IOTJS_MODULE_UNIMPLEMENTED_INL_H */
diff --git a/tools/src/platform/x86_64-linux/iotjs_module_adc-x86_64-linux.c b/tools/src/platform/x86_64-linux/iotjs_module_adc-x86_64-linux.c
new file mode 100644 (file)
index 0000000..ad31407
--- /dev/null
@@ -0,0 +1,21 @@
+/* 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(__linux__)
+
+#include "../iotjs_module_adc-linux-general.inl.h"
+
+#endif
diff --git a/tools/src/platform/x86_64-linux/iotjs_module_blehcisocket-x86_64-linux.c b/tools/src/platform/x86_64-linux/iotjs_module_blehcisocket-x86_64-linux.c
new file mode 100644 (file)
index 0000000..eddc16e
--- /dev/null
@@ -0,0 +1,22 @@
+/* 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(__linux__)
+
+#include "iotjs_def.h"
+#include "../iotjs_module_blehcisocket-linux-general.inl.h"
+
+#endif
diff --git a/tools/src/platform/x86_64-linux/iotjs_module_gpio-x86_64-linux.c b/tools/src/platform/x86_64-linux/iotjs_module_gpio-x86_64-linux.c
new file mode 100644 (file)
index 0000000..8c68b40
--- /dev/null
@@ -0,0 +1,22 @@
+/* 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.
+ */
+
+
+#if defined(__linux__)
+
+#include "iotjs_def.h"
+#include "../iotjs_module_gpio-linux-general.inl.h"
+
+#endif
diff --git a/tools/src/platform/x86_64-linux/iotjs_module_i2c-x86_64-linux.c b/tools/src/platform/x86_64-linux/iotjs_module_i2c-x86_64-linux.c
new file mode 100644 (file)
index 0000000..0ad37b1
--- /dev/null
@@ -0,0 +1,21 @@
+/* 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(__linux__)
+
+#include "../iotjs_module_i2c-linux-general.inl.h"
+
+#endif
diff --git a/tools/src/platform/x86_64-linux/iotjs_module_pwm-x86_64-linux.c b/tools/src/platform/x86_64-linux/iotjs_module_pwm-x86_64-linux.c
new file mode 100644 (file)
index 0000000..94e9800
--- /dev/null
@@ -0,0 +1,22 @@
+/* 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(__linux__)
+
+#include "iotjs_def.h"
+#include "../iotjs_module_pwm-linux-general.inl.h"
+
+#endif
diff --git a/tools/src/platform/x86_64-linux/iotjs_module_spi-x86_64-linux.c b/tools/src/platform/x86_64-linux/iotjs_module_spi-x86_64-linux.c
new file mode 100644 (file)
index 0000000..3b0b0d6
--- /dev/null
@@ -0,0 +1,21 @@
+/* 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(__linux__)
+
+#include "../iotjs_module_spi-linux-general.inl.h"
+
+#endif
diff --git a/tools/src/platform/x86_64-linux/iotjs_module_uart-x86_64-linux.c b/tools/src/platform/x86_64-linux/iotjs_module_uart-x86_64-linux.c
new file mode 100644 (file)
index 0000000..ec6ece5
--- /dev/null
@@ -0,0 +1,21 @@
+/* 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(__linux__)
+
+#include "../iotjs_module_uart-linux-general.inl.h"
+
+#endif // __linux__
diff --git a/tools/targets/nuttx-stm32f4/README.md b/tools/targets/nuttx-stm32f4/README.md
new file mode 100644 (file)
index 0000000..6c4f7d1
--- /dev/null
@@ -0,0 +1,154 @@
+### 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
+  |  + targets
+  |      + nuttx-stm32f4
+  + nuttx
+  + stlink
+```
+
+#### 2. Add IoT.js as a builtin application for NuttX
+
+```bash
+$ cd apps/system
+$ mkdir iotjs
+$ cp ../../iotjs/targets/nuttx-stm32f4/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/targets/nuttx-stm32f4/nuttx/.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)`
+
+#### 4. Build IoT.js for NuttX
+
+##### Follow the instruction
+* [Build-for-NuttX](../../docs/build/Build-for-NuttX.md)
+
+#### 5. Build NuttX
+
+```bash
+# assuming you are in iotjs-nuttx folder
+$ cd nuttx/
+$ make
+```
+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 flash,
+```bash
+# assuming you are in nuttx folder
+$ sudo ../stlink/build/st-flash write nuttx.bin 0x8000000
+```
diff --git a/tools/targets/nuttx-stm32f4/Stm32f4dis.md b/tools/targets/nuttx-stm32f4/Stm32f4dis.md
new file mode 100644 (file)
index 0000000..d2401fa
--- /dev/null
@@ -0,0 +1,127 @@
+## Stm32f4dis module
+
+## `Pin`
+To use system IO, such as GPIO, PWM and ADC you must know pin name.
+`stm32f4dis` module has pin object which is designed to find a pin name easier.
+
+``` javascript
+var pin = require('stm32f4dis').pin;
+```
+
+
+### `GPIO Pin` <a name="gpio-pin"></a>
+`P<port><pin>`
+
+For example,
+``` javascript
+var gpio = require('gpio');
+var pin = require('stm32f4dis').pin;
+
+gpio.open(pin.PD6);
+```
+
+
+### `PWM Pin` <a name="pwm-pin"></a>
+`PWM<timer>.CH<channel>_<number>`
+
+For example,
+``` javascript
+var pwm = require('pwm');
+var pin = require('stm32f4dis').pin;
+
+var pwm2 = new pwm(pin.PWM2.CH1_2);
+```
+The following is a list of PWM pin name.
+
+| 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` <a name="adc-pin"></a>
+`ADC<number>_<timer>`
+
+For example,
+``` javascript
+var adc = require('adc');
+var pin = require('stm32f4dis').pin;
+
+var adc1 = new adc(pin.ADC1_3);
+```
+The following is a list of ADC pin name.
+
+| 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` <a name="uart"></a>
+To use UART on stm32f4-discovery board, you must use proper pins. Stm32f4-discovery board supports 4 UART ports, such as USART2, USART3, UART5, USART6.
+But as our default config option sets SDIO to be on, it makes conflict with UART5 port because these two use the same pin for connection. So you must be careful when you enable UART5 port.
+
+The following is a list of ADC 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 |
+
+* Different from other system IO such as GPIO, ADC, PWM, you can't find the name of the UART device easily by `stm32f4dis.pin` module. It's because the name of the uart device can be changed according to your Nuttx config option. You can find '/dev/ttyS[0-3]' according to your environment.
+
+
+### Enable more ports using patch file
+
+Current version of Nuttx doesn't support USART1 and UART4 as the ports for stm32f4-discovery board. But if you want to enable more ports other than above, you can modify Nuttx code by referring to a part of `targets/nuttx-stm32f4/nuttx/patch` file.
+
+To apply whole patch,
+```bash
+~/workspace/nuttx$ patch -p1 < ../iotjs/targets/nuttx-stm32f4/nuttx/patch
+```
+Make sure it is your responsibility to enable the ports only when they do not make any conflicts.
\ No newline at end of file
diff --git a/tools/targets/nuttx-stm32f4/app/Kconfig b/tools/targets/nuttx-stm32f4/app/Kconfig
new file mode 100644 (file)
index 0000000..85409a7
--- /dev/null
@@ -0,0 +1,22 @@
+#
+# 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
diff --git a/tools/targets/nuttx-stm32f4/app/Make.defs b/tools/targets/nuttx-stm32f4/app/Make.defs
new file mode 100644 (file)
index 0000000..4cd4a82
--- /dev/null
@@ -0,0 +1,18 @@
+# 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
diff --git a/tools/targets/nuttx-stm32f4/app/Makefile b/tools/targets/nuttx-stm32f4/app/Makefile
new file mode 100644 (file)
index 0000000..ed43219
--- /dev/null
@@ -0,0 +1,195 @@
+# 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 <gnutt@nuttx.org>
+#
+# 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
+
+
+CONFIG_IOTJS_PRIORITY ?= SCHED_PRIORITY_DEFAULT
+CONFIG_IOTJS_STACKSIZE ?= 16384
+# NSH sysinfo command
+
+APPNAME = iotjs
+IOTJS_ROOT_DIR = ../../../iotjs
+PRIORITY = $(CONFIG_IOTJS_PRIORITY)
+STACKSIZE = $(CONFIG_IOTJS_STACKSIZE)
+HEAPSIZE = $(CONFIG_IOTJS_HEAPSIZE)
+
+ASRCS =
+CSRCS =
+CXXSRCS =
+MAINSRC = iotjs_main.cxx
+LIBS = libhttpparser.a libiotjs.a libjerry-core.a libtuv.a libjerry-libm.a libjerry-libc.a
+
+AOBJS = $(ASRCS:.S=$(OBJEXT))
+COBJS = $(CSRCS:.c=$(OBJEXT))
+CXXOBJS = $(CXXSRCS:.cxx=$(OBJEXT))
+MAINOBJ = $(MAINSRC:.cxx=$(OBJEXT))
+
+SRCS = $(ASRCS) $(CSRCS) $(CXXSRCS) $(MAINSRC)
+OBJS = $(AOBJS) $(COBJS) $(CXXOBJS)
+
+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
+
+chkcxx:
+ifneq ($(CONFIG_HAVE_CXX),y)
+  @echo ""
+  @echo "In order to use this example, you toolchain must support must"
+  @echo ""
+  @echo "  (1) Explicitly select CONFIG_HAVE_CXX to build in C++ support"
+  @echo "  (2) Define CXX, CXXFLAGS, and COMPILEXX in the Make.defs file"
+  @echo "      of the configuration that you are using."
+  @echo ""
+  @exit 1
+endif
+
+
+$(AOBJS): %$(OBJEXT): %.S
+       $(call ASSEMBLE, $<, $@)
+
+$(COBJS): %$(OBJEXT): %.c
+       $(call COMPILE, $<, $@)
+
+$(CXXOBJS) $(MAINOBJ): %$(OBJEXT): %.cxx
+       $(call COMPILEXX, $<, $@)
+
+copylibs :
+       cp $(IOTJS_ROOT_DIR)/build/arm-nuttx/$(BUILD_TYPE)/lib/lib*.a .
+
+$(LIBS) : copylibs
+       $(firstword $(AR)) x $@
+
+.built: chkcxx $(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) "$(CXX)" -- $(CXXFLAGS) -- $(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:
diff --git a/tools/targets/nuttx-stm32f4/app/iotjs_main.cxx b/tools/targets/nuttx-stm32f4/app/iotjs_main.cxx
new file mode 100644 (file)
index 0000000..21ba43a
--- /dev/null
@@ -0,0 +1,110 @@
+/* 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 <gnutt@nuttx.org>
+ *
+ * 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 <nuttx/config.h>
+#include <nuttx/arch.h>
+
+#include <stdio.h>
+#include <setjmp.h>
+
+#ifdef CONFIG_IOTJS
+# if !defined(CONFIG_HAVE_CXX) || !defined(CONFIG_HAVE_CXXINITIALIZE)
+#   error Need CONFIG_HAVE_CXX and CONFIG_HAVE_CXXINITIALIZE
+# endif
+#endif
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/**
+ * 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 */
+
+extern "C" int iotjs_entry(int argc, char *argv[]);
+extern "C" int tuv_cleanup(void);
+
+#ifdef CONFIG_BUILD_KERNEL
+extern "C" int main(int argc, FAR char *argv[])
+#else
+extern "C" int iotjs_main(int argc, char *argv[])
+#endif
+{
+  int ret = 0;
+  up_cxxinitialize();
+  ret = iotjs_entry(argc, argv);
+  tuv_cleanup();
+  return ret;
+}
diff --git a/tools/targets/nuttx-stm32f4/nuttx/.config.default b/tools/targets/nuttx-stm32f4/nuttx/.config.default
new file mode 100644 (file)
index 0000000..7aaddc0
--- /dev/null
@@ -0,0 +1,1471 @@
+#
+# 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
diff --git a/tools/targets/nuttx-stm32f4/nuttx/.config.travis b/tools/targets/nuttx-stm32f4/nuttx/.config.travis
new file mode 100644 (file)
index 0000000..2079a4a
--- /dev/null
@@ -0,0 +1,1522 @@
+#
+# 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
diff --git a/tools/targets/nuttx-stm32f4/nuttx/patch b/tools/targets/nuttx-stm32f4/nuttx/patch
new file mode 100644 (file)
index 0000000..efa8999
--- /dev/null
@@ -0,0 +1,24 @@
+--- 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
diff --git a/tools/targets/tizenrt-artik05x/app/README.md b/tools/targets/tizenrt-artik05x/app/README.md
new file mode 100644 (file)
index 0000000..55ba021
--- /dev/null
@@ -0,0 +1,82 @@
+### 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
+  |  + targets
+  |      + tizenrt-artik05x
+  + tizenrt
+```
+
+#### 2. Add IoT.js as a builtin application for TizenRT
+
+```bash
+$ cd tizenrt/apps/system
+$ mkdir iotjs
+$ cp ../../../iotjs/targets/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)
diff --git a/tools/targets/tizenrt-artik05x/app/iotjs/.gitignore b/tools/targets/tizenrt-artik05x/app/iotjs/.gitignore
new file mode 100644 (file)
index 0000000..fa1ec75
--- /dev/null
@@ -0,0 +1,11 @@
+/Make.dep
+/.depend
+/.built
+/*.asm
+/*.obj
+/*.rel
+/*.lst
+/*.sym
+/*.adb
+/*.lib
+/*.src
diff --git a/tools/targets/tizenrt-artik05x/app/iotjs/Kconfig b/tools/targets/tizenrt-artik05x/app/iotjs/Kconfig
new file mode 100644 (file)
index 0000000..67200a9
--- /dev/null
@@ -0,0 +1,27 @@
+#
+# 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 IOTJS
+
+config IOTJS_PRIORITY
+  int "IoT.js task priority"
+  default 100
+
+config IOTJS_STACKSIZE
+  int "IoT.js stack size"
+  default 16384
+
+endif
+
+config USER_ENTRYPOINT
+        string
+        default "iotjs_main" if ENTRY_IOTJS
+
diff --git a/tools/targets/tizenrt-artik05x/app/iotjs/Kconfig_ENTRY b/tools/targets/tizenrt-artik05x/app/iotjs/Kconfig_ENTRY
new file mode 100644 (file)
index 0000000..94c48db
--- /dev/null
@@ -0,0 +1,3 @@
+config ENTRY_IOTJS
+       bool "iotjs application"
+       depends on SYSTEM_IOTJS
diff --git a/tools/targets/tizenrt-artik05x/app/iotjs/Make.defs b/tools/targets/tizenrt-artik05x/app/iotjs/Make.defs
new file mode 100644 (file)
index 0000000..da059d9
--- /dev/null
@@ -0,0 +1,18 @@
+# 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
diff --git a/tools/targets/tizenrt-artik05x/app/iotjs/Makefile b/tools/targets/tizenrt-artik05x/app/iotjs/Makefile
new file mode 100644 (file)
index 0000000..4bb5617
--- /dev/null
@@ -0,0 +1,170 @@
+###########################################################################
+#
+# 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 <gnutt@nuttx.org>
+#
+# 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
diff --git a/tools/targets/tizenrt-artik05x/app/iotjs/iotjs_main.c b/tools/targets/tizenrt-artik05x/app/iotjs/iotjs_main.c
new file mode 100644 (file)
index 0000000..4a5fc6a
--- /dev/null
@@ -0,0 +1,109 @@
+/* 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 <gnutt@nuttx.org>
+ *
+ * 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 <apps/shell/tash.h>
+#include <tinyara/arch.h>
+#include <tinyara/config.h>
+
+#include <setjmp.h>
+#include <stdio.h>
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/**
+ * 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);
+
+static int iotjs(int argc, char *argv[]) {
+  int ret = 0;
+  ret = iotjs_entry(argc, argv);
+  tuv_cleanup();
+  return ret;
+}
+
+const static tash_cmdlist_t iotjs_cmds[] = { { "iotjs", iotjs,
+                                               TASH_EXECMD_SYNC },
+                                             { 0, 0, 0 } };
+
+#ifdef CONFIG_BUILD_KERNEL
+int main(int argc, FAR char *argv[])
+#else
+int iotjs_main(int argc, char *argv[])
+#endif
+{
+  tash_cmdlist_install(iotjs_cmds);
+  return 0;
+}
diff --git a/tools/test/resources/greeting.txt b/tools/test/resources/greeting.txt
new file mode 100644 (file)
index 0000000..3c3130b
--- /dev/null
@@ -0,0 +1 @@
+Hello IoT.js!!
\ No newline at end of file
diff --git a/tools/test/resources/readdir/DO_NOT_MODIFY_THIS_FOLDER b/tools/test/resources/readdir/DO_NOT_MODIFY_THIS_FOLDER
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tools/test/resources/readdir/This_is_a_directory/.gitkeep b/tools/test/resources/readdir/This_is_a_directory/.gitkeep
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tools/test/resources/readdir/This_is_another_directory/.gitkeep b/tools/test/resources/readdir/This_is_another_directory/.gitkeep
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tools/test/resources/readdir/regular.txt b/tools/test/resources/readdir/regular.txt
new file mode 100644 (file)
index 0000000..3c3130b
--- /dev/null
@@ -0,0 +1 @@
+Hello IoT.js!!
\ No newline at end of file
diff --git a/tools/test/resources/rename.txt b/tools/test/resources/rename.txt
new file mode 100644 (file)
index 0000000..3c3130b
--- /dev/null
@@ -0,0 +1 @@
+Hello IoT.js!!
\ No newline at end of file
diff --git a/tools/test/resources/test1.txt b/tools/test/resources/test1.txt
new file mode 100644 (file)
index 0000000..3c3ecf7
--- /dev/null
@@ -0,0 +1 @@
+TEST File Read & Write
diff --git a/tools/test/resources/test_console_stdout.txt b/tools/test/resources/test_console_stdout.txt
new file mode 100644 (file)
index 0000000..ea97cf7
--- /dev/null
@@ -0,0 +1,8 @@
+Hello IoT.js!!
+1
+2
+3
+13
+1,2,3
+1 2 3
+a 1 b 2 c 3
diff --git a/tools/test/resources/tobeornottobe.txt b/tools/test/resources/tobeornottobe.txt
new file mode 100644 (file)
index 0000000..08687b1
--- /dev/null
@@ -0,0 +1,35 @@
+To 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.
\ No newline at end of file
diff --git a/tools/test/run_fail/assert_fail1.js b/tools/test/run_fail/assert_fail1.js
new file mode 100644 (file)
index 0000000..3c6cd84
--- /dev/null
@@ -0,0 +1,19 @@
+/* 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();
diff --git a/tools/test/run_fail/assert_fail2.js b/tools/test/run_fail/assert_fail2.js
new file mode 100644 (file)
index 0000000..b82766c
--- /dev/null
@@ -0,0 +1,19 @@
+/* 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);
diff --git a/tools/test/run_fail/assert_fail3.js b/tools/test/run_fail/assert_fail3.js
new file mode 100644 (file)
index 0000000..cf155b9
--- /dev/null
@@ -0,0 +1,19 @@
+/* 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);
diff --git a/tools/test/run_fail/fs_callbacks_called.js b/tools/test/run_fail/fs_callbacks_called.js
new file mode 100644 (file)
index 0000000..0df7a85
--- /dev/null
@@ -0,0 +1,40 @@
+/* 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);
diff --git a/tools/test/run_fail/process_exit1.js b/tools/test/run_fail/process_exit1.js
new file mode 100644 (file)
index 0000000..a6d5a78
--- /dev/null
@@ -0,0 +1,21 @@
+/* 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();
+});
diff --git a/tools/test/run_fail/process_exit2.js b/tools/test/run_fail/process_exit2.js
new file mode 100644 (file)
index 0000000..e1a20bd
--- /dev/null
@@ -0,0 +1,23 @@
+/* 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();
diff --git a/tools/test/run_fail/process_exitcode1.js b/tools/test/run_fail/process_exitcode1.js
new file mode 100644 (file)
index 0000000..1808c7c
--- /dev/null
@@ -0,0 +1,24 @@
+/* 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);
diff --git a/tools/test/run_fail/process_exitcode2.js b/tools/test/run_fail/process_exitcode2.js
new file mode 100644 (file)
index 0000000..3bafef7
--- /dev/null
@@ -0,0 +1,25 @@
+/* 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();
diff --git a/tools/test/run_fail/require_fail1.js b/tools/test/run_fail/require_fail1.js
new file mode 100644 (file)
index 0000000..f1acad0
--- /dev/null
@@ -0,0 +1,17 @@
+/* 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');
diff --git a/tools/test/run_fail/runtime_error1.js b/tools/test/run_fail/runtime_error1.js
new file mode 100644 (file)
index 0000000..d0ea00d
--- /dev/null
@@ -0,0 +1,19 @@
+/* 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();
diff --git a/tools/test/run_fail/syntax_fail1.js b/tools/test/run_fail/syntax_fail1.js
new file mode 100644 (file)
index 0000000..76725e0
--- /dev/null
@@ -0,0 +1,16 @@
+/* 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
diff --git a/tools/test/run_fail/uncaught_error_event.js b/tools/test/run_fail/uncaught_error_event.js
new file mode 100644 (file)
index 0000000..9140e7f
--- /dev/null
@@ -0,0 +1,21 @@
+/* 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');
diff --git a/tools/test/run_pass/issue/issue-133.js b/tools/test/run_pass/issue/issue-133.js
new file mode 100644 (file)
index 0000000..a58d3e4
--- /dev/null
@@ -0,0 +1,18 @@
+/* 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("");
diff --git a/tools/test/run_pass/issue/issue-137.js b/tools/test/run_pass/issue/issue-137.js
new file mode 100644 (file)
index 0000000..51b9c08
--- /dev/null
@@ -0,0 +1,37 @@
+/* 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);
diff --git a/tools/test/run_pass/issue/issue-198.js b/tools/test/run_pass/issue/issue-198.js
new file mode 100644 (file)
index 0000000..23bec1b
--- /dev/null
@@ -0,0 +1,24 @@
+/* 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
+);
diff --git a/tools/test/run_pass/issue/issue-223.js b/tools/test/run_pass/issue/issue-223.js
new file mode 100644 (file)
index 0000000..ba8ba0a
--- /dev/null
@@ -0,0 +1,26 @@
+/* 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
+);
diff --git a/tools/test/run_pass/issue/issue-266.js b/tools/test/run_pass/issue/issue-266.js
new file mode 100644 (file)
index 0000000..51ccd98
--- /dev/null
@@ -0,0 +1,49 @@
+/* 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;
+
+var server = net.createServer();
+server.listen(port);
+
+server.on('connection', function(socket) {
+  socket.on('data', function(data) {
+  });
+  socket.on('finish', function() {
+    socket.destroy();
+    socket.destroy();
+    socket.destroy();
+  });
+});
+
+
+setTimeout(function() {
+    server.close();
+}, 1000);
+
+
+var socket = new net.Socket();
+socket.connect(port, "127.0.0.1");
+socket.end('test');
+
+process.on('exit', function() {
+  assert.equal(server._socketCount, 0);
+});
diff --git a/tools/test/run_pass/issue/issue-323.js b/tools/test/run_pass/issue/issue-323.js
new file mode 100644 (file)
index 0000000..db6b1f6
--- /dev/null
@@ -0,0 +1,33 @@
+/* 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
+);
diff --git a/tools/test/run_pass/require1/module_cache.js b/tools/test/run_pass/require1/module_cache.js
new file mode 100644 (file)
index 0000000..feb94b3
--- /dev/null
@@ -0,0 +1,20 @@
+/* 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;
diff --git a/tools/test/run_pass/require1/node_modules/test_index/add2.js b/tools/test/run_pass/require1/node_modules/test_index/add2.js
new file mode 100644 (file)
index 0000000..9841ea6
--- /dev/null
@@ -0,0 +1,22 @@
+/* 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;
+}
diff --git a/tools/test/run_pass/require1/node_modules/test_index/index.js b/tools/test/run_pass/require1/node_modules/test_index/index.js
new file mode 100644 (file)
index 0000000..590c324
--- /dev/null
@@ -0,0 +1,26 @@
+/* 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;
diff --git a/tools/test/run_pass/require1/node_modules/test_index/lib/multi.js b/tools/test/run_pass/require1/node_modules/test_index/lib/multi.js
new file mode 100644 (file)
index 0000000..b757e5b
--- /dev/null
@@ -0,0 +1,24 @@
+/* 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;
diff --git a/tools/test/run_pass/require1/node_modules/test_index/package.json b/tools/test/run_pass/require1/node_modules/test_index/package.json
new file mode 100644 (file)
index 0000000..31d54be
--- /dev/null
@@ -0,0 +1,3 @@
+{
+  "name": "index_test"
+}
diff --git a/tools/test/run_pass/require1/node_modules/test_pkg/add2.js b/tools/test/run_pass/require1/node_modules/test_pkg/add2.js
new file mode 100644 (file)
index 0000000..9841ea6
--- /dev/null
@@ -0,0 +1,22 @@
+/* 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;
+}
diff --git a/tools/test/run_pass/require1/node_modules/test_pkg/lib/multi.js b/tools/test/run_pass/require1/node_modules/test_pkg/lib/multi.js
new file mode 100644 (file)
index 0000000..b757e5b
--- /dev/null
@@ -0,0 +1,24 @@
+/* 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;
diff --git a/tools/test/run_pass/require1/node_modules/test_pkg/main.js b/tools/test/run_pass/require1/node_modules/test_pkg/main.js
new file mode 100644 (file)
index 0000000..590c324
--- /dev/null
@@ -0,0 +1,26 @@
+/* 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;
diff --git a/tools/test/run_pass/require1/node_modules/test_pkg/package.json b/tools/test/run_pass/require1/node_modules/test_pkg/package.json
new file mode 100644 (file)
index 0000000..c13b8cf
--- /dev/null
@@ -0,0 +1,3 @@
+{
+  "main": "main.js"
+}
diff --git a/tools/test/run_pass/require1/package.json b/tools/test/run_pass/require1/package.json
new file mode 100644 (file)
index 0000000..c827db8
--- /dev/null
@@ -0,0 +1,30 @@
+{
+  "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"
+}
diff --git a/tools/test/run_pass/require1/require_add.js b/tools/test/run_pass/require1/require_add.js
new file mode 100644 (file)
index 0000000..bca973a
--- /dev/null
@@ -0,0 +1,24 @@
+/* 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
+*/
+
+var x = require("buffer");
+
+exports.add = function(a, b) {
+  return a + b;
+};
diff --git a/tools/test/run_pass/require1/test_require.js b/tools/test/run_pass/require1/test_require.js
new file mode 100644 (file)
index 0000000..930ec9c
--- /dev/null
@@ -0,0 +1,40 @@
+/* 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(process.platform, false);
+
+var x = require("require_add");
+assert.equal(x.add(1,4), 5);
+
+var str = process.readSource("package.json");
+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");
+
+var pkg1 = require('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('test_index');
+assert.equal(pkg2.add(22, 44), 66);
+assert.equal(pkg2.multi(22, 44), 968);
+assert.equal(pkg2.add2(22, 44), 66);
diff --git a/tools/test/run_pass/test_adc.js b/tools/test/run_pass/test_adc.js
new file mode 100644 (file)
index 0000000..9558717
--- /dev/null
@@ -0,0 +1,85 @@
+/* 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();
+}
+
+var adc0 = adc.open(configuration, function(err) {
+  console.log('ADC initialized');
+
+  if (err) {
+    assert.fail();
+  }
+
+  test1();
+});
+
+// read async test
+function test1() {
+  var loopCnt = 5;
+
+  console.log('test1 start(read async test)');
+  var test1Loop = setInterval(function() {
+    if (--loopCnt < 0) {
+      console.log('test1 complete');
+      clearInterval(test1Loop);
+      test2();
+    } else {
+      adc0.read(function(err, value) {
+        if (err) {
+          console.log('read failed');
+          assert.fail();
+        }
+
+        console.log(value);
+      });
+    }
+  }, 1000);
+}
+
+// read sync test
+function test2() {
+  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);
+}
diff --git a/tools/test/run_pass/test_assert.js b/tools/test/run_pass/test_assert.js
new file mode 100644 (file)
index 0000000..828f171
--- /dev/null
@@ -0,0 +1,89 @@
+/* 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.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');
+}
diff --git a/tools/test/run_pass/test_ble_advertisement.js b/tools/test/run_pass/test_ble_advertisement.js
new file mode 100644 (file)
index 0000000..2cdb910
--- /dev/null
@@ -0,0 +1,40 @@
+/* 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.');
+    });
+  }
+});
diff --git a/tools/test/run_pass/test_ble_setservices.js b/tools/test/run_pass/test_ble_setservices.js
new file mode 100644 (file)
index 0000000..999ee26
--- /dev/null
@@ -0,0 +1,114 @@
+/* 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()
+        ]
+      })
+    ]);
+  }
+});
diff --git a/tools/test/run_pass/test_buffer.js b/tools/test/run_pass/test_buffer.js
new file mode 100644 (file)
index 0000000..edc1e1e
--- /dev/null
@@ -0,0 +1,145 @@
+/* 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);
+
+
+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);
diff --git a/tools/test/run_pass/test_buffer_builtin.js b/tools/test/run_pass/test_buffer_builtin.js
new file mode 100644 (file)
index 0000000..66d3d57
--- /dev/null
@@ -0,0 +1,111 @@
+/* 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);
diff --git a/tools/test/run_pass/test_console.js b/tools/test/run_pass/test_console.js
new file mode 100644 (file)
index 0000000..e60cc3a
--- /dev/null
@@ -0,0 +1,24 @@
+/* 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("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);
diff --git a/tools/test/run_pass/test_cwd.js b/tools/test/run_pass/test_cwd.js
new file mode 100644 (file)
index 0000000..5d8cdad
--- /dev/null
@@ -0,0 +1,17 @@
+/* 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());
diff --git a/tools/test/run_pass/test_dgram_1_server_1_client.js b/tools/test/run_pass/test_dgram_1_server_1_client.js
new file mode 100644 (file)
index 0000000..6f03661
--- /dev/null
@@ -0,0 +1,71 @@
+/* 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);
+});
diff --git a/tools/test/run_pass/test_dgram_1_server_n_clients.js b/tools/test/run_pass/test_dgram_1_server_n_clients.js
new file mode 100644 (file)
index 0000000..8373188
--- /dev/null
@@ -0,0 +1,72 @@
+/* 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);
+});
diff --git a/tools/test/run_pass/test_dgram_address.js b/tools/test/run_pass/test_dgram_address.js
new file mode 100644 (file)
index 0000000..efad184
--- /dev/null
@@ -0,0 +1,63 @@
+/* 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('udp4');
+var server = dgram.createSocket('udp4');
+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);
+});
diff --git a/tools/test/run_pass/test_dgram_broadcast.js b/tools/test/run_pass/test_dgram_broadcast.js
new file mode 100644 (file)
index 0000000..18d06cf
--- /dev/null
@@ -0,0 +1,90 @@
+/* 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);
+});
diff --git a/tools/test/run_pass/test_dgram_multicast_membership.js b/tools/test/run_pass/test_dgram_multicast_membership.js
new file mode 100644 (file)
index 0000000..fff837a
--- /dev/null
@@ -0,0 +1,63 @@
+/* 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);
+});
diff --git a/tools/test/run_pass/test_dgram_multicast_set_multicast_loop.js b/tools/test/run_pass/test_dgram_multicast_set_multicast_loop.js
new file mode 100644 (file)
index 0000000..9838c84
--- /dev/null
@@ -0,0 +1,45 @@
+/* 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);
+});
diff --git a/tools/test/run_pass/test_dns.js b/tools/test/run_pass/test_dns.js
new file mode 100644 (file)
index 0000000..de75547
--- /dev/null
@@ -0,0 +1,58 @@
+/* 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);
+});
diff --git a/tools/test/run_pass/test_dns_lookup.js b/tools/test/run_pass/test_dns_lookup.js
new file mode 100644 (file)
index 0000000..19d996e
--- /dev/null
@@ -0,0 +1,105 @@
+/* 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 with invalid hostname.
+dns.lookup('invalid', 4, function(err, ip, family) {
+  assert.notEqual(err, null);
+  assert.equal(err.code, -3008);
+});
+
+// Test with empty hostname.
+dns.lookup('', 4, function(err, ip, family) {
+  assert.notEqual(err, null);
+  assert.equal(err.code, -3008);
+});
+
+// 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);
diff --git a/tools/test/run_pass/test_events.js b/tools/test/run_pass/test_events.js
new file mode 100644 (file)
index 0000000..ecfe7c0
--- /dev/null
@@ -0,0 +1,179 @@
+/* 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);
+
+
+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||");
diff --git a/tools/test/run_pass/test_exit.js b/tools/test/run_pass/test_exit.js
new file mode 100644 (file)
index 0000000..3f0adc6
--- /dev/null
@@ -0,0 +1,17 @@
+/* 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);
diff --git a/tools/test/run_pass/test_experimental_off.js b/tools/test/run_pass/test_experimental_off.js
new file mode 100644 (file)
index 0000000..43fa20e
--- /dev/null
@@ -0,0 +1,18 @@
+/* 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');
diff --git a/tools/test/run_pass/test_experimental_on.js b/tools/test/run_pass/test_experimental_on.js
new file mode 100644 (file)
index 0000000..5218fed
--- /dev/null
@@ -0,0 +1,18 @@
+/* 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');
diff --git a/tools/test/run_pass/test_fs.js b/tools/test/run_pass/test_fs.js
new file mode 100644 (file)
index 0000000..7c66997
--- /dev/null
@@ -0,0 +1,62 @@
+/* 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 = "../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;
+}
+
+
+// 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
+);
diff --git a/tools/test/run_pass/test_fs1.js b/tools/test/run_pass/test_fs1.js
new file mode 100644 (file)
index 0000000..b670c8d
--- /dev/null
@@ -0,0 +1,48 @@
+/* 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 = "../resources/test1.txt";
+var dstFilePath = "../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);
+  fs.closeSync(fd2);
+
+  assert.equal(bytes1, bytes2);
+
+  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;
+}
diff --git a/tools/test/run_pass/test_fs2.js b/tools/test/run_pass/test_fs2.js
new file mode 100644 (file)
index 0000000..c1af534
--- /dev/null
@@ -0,0 +1,67 @@
+/* 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 = "../resources/test1.txt";
+var dstFilePath = "../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);
diff --git a/tools/test/run_pass/test_fs_exists.js b/tools/test/run_pass/test_fs_exists.js
new file mode 100644 (file)
index 0000000..d376c68
--- /dev/null
@@ -0,0 +1,49 @@
+/* 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 = "../resources/tobeornottobe.txt";
+
+  fs.exists(filePath, function(exists) {
+    assert.equal(exists, true);
+  });
+}
+
+{
+  var filePath = "../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);
+  });
+}
diff --git a/tools/test/run_pass/test_fs_existssync.js b/tools/test/run_pass/test_fs_existssync.js
new file mode 100644 (file)
index 0000000..254eb57
--- /dev/null
@@ -0,0 +1,45 @@
+/* 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 = "../resources/tobeornottobe.txt";
+
+  var result = fs.existsSync(filePath);
+  assert.equal(result, true);
+}
+
+{
+  var filePath = "../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);
+}
diff --git a/tools/test/run_pass/test_fs_mkdir_rmdir.js b/tools/test/run_pass/test_fs_mkdir_rmdir.js
new file mode 100644 (file)
index 0000000..46c1678
--- /dev/null
@@ -0,0 +1,51 @@
+/* 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 = "../resources/test_dir";
+  var sub1 = "../resources/test_dir/file1";
+  var sub2 = "../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);
+    });
+  });
+}
diff --git a/tools/test/run_pass/test_fs_open_close.js b/tools/test/run_pass/test_fs_open_close.js
new file mode 100644 (file)
index 0000000..9269b72
--- /dev/null
@@ -0,0 +1,102 @@
+/* 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 = "../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);
+
+process.on('exit', function() {
+  assert.equal(fs_async_normal_ok, true);
+  assert.equal(fs_async_open_not_exist_ok, true);
+  assert.equal(fs_async_close_bad_fd_ok, true);
+});
diff --git a/tools/test/run_pass/test_fs_readdir.js b/tools/test/run_pass/test_fs_readdir.js
new file mode 100644 (file)
index 0000000..51d3eea
--- /dev/null
@@ -0,0 +1,42 @@
+/* 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 = '../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);
+});
diff --git a/tools/test/run_pass/test_fs_readfile.js b/tools/test/run_pass/test_fs_readfile.js
new file mode 100644 (file)
index 0000000..b024b03
--- /dev/null
@@ -0,0 +1,61 @@
+/* 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 = "../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);
+});
diff --git a/tools/test/run_pass/test_fs_readfilesync.js b/tools/test/run_pass/test_fs_readfilesync.js
new file mode 100644 (file)
index 0000000..94ee18a
--- /dev/null
@@ -0,0 +1,60 @@
+/* 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 = "../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);
diff --git a/tools/test/run_pass/test_fs_rename.js b/tools/test/run_pass/test_fs_rename.js
new file mode 100644 (file)
index 0000000..c4c3d6f
--- /dev/null
@@ -0,0 +1,34 @@
+/* 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 = "../resources/rename.txt";
+var file2 = "../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");
+  });
+});
diff --git a/tools/test/run_pass/test_fs_rename_sync.js b/tools/test/run_pass/test_fs_rename_sync.js
new file mode 100644 (file)
index 0000000..fada5df
--- /dev/null
@@ -0,0 +1,25 @@
+/* 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 = "../resources/rename.txt";
+var file2 = "../resources/rename.txt.sync";
+
+fs.renameSync(file1, file2);
+assert.equal(fs.existsSync(file1), false);
+assert.equal(fs.existsSync(file2), true);
+fs.renameSync(file2, file1);
diff --git a/tools/test/run_pass/test_fs_stat.js b/tools/test/run_pass/test_fs_stat.js
new file mode 100644 (file)
index 0000000..622572d
--- /dev/null
@@ -0,0 +1,48 @@
+/* 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('test_fs_stat.js');
+assert.equal(stats1.isFile(), true);
+assert.equal(stats1.isDirectory(), false);
+
+fs.stat('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('../resources');
+assert.equal(stats2.isDirectory(), true);
+assert.equal(stats2.isFile(), false);
+
+fs.stat('../resources', function(err, stats) {
+  if (!err) {
+    assert.equal(stats.isDirectory(), true);
+    assert.equal(stats.isFile(), false);
+  }
+  else {
+    throw err
+  }
+});
diff --git a/tools/test/run_pass/test_fs_writefile_unlink.js b/tools/test/run_pass/test_fs_writefile_unlink.js
new file mode 100644 (file)
index 0000000..1d370d1
--- /dev/null
@@ -0,0 +1,45 @@
+/* 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 = "../resources/tobeornottobe.txt";
+var file2 = "../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");
+          });
+        });
+      });
+    });
+  });
+});
diff --git a/tools/test/run_pass/test_fs_writefile_unlink_sync.js b/tools/test/run_pass/test_fs_writefile_unlink_sync.js
new file mode 100644 (file)
index 0000000..2a95ddd
--- /dev/null
@@ -0,0 +1,39 @@
+/* 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 = "../resources/tobeornottobe.txt";
+var file2 = "../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);
diff --git a/tools/test/run_pass/test_gpio1.js b/tools/test/run_pass/test_gpio1.js
new file mode 100644 (file)
index 0000000..a7ae87b
--- /dev/null
@@ -0,0 +1,75 @@
+/* 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 gpio10;
+
+if (process.platform === 'linux') {
+  pin = 10;
+  mode = gpio.MODE.NONE;
+} else if (process.platform === 'nuttx') {
+  pin = require('stm32f4dis').pin.PA10;
+  mode = gpio.MODE.PUSHPULL;
+} else {
+  assert.fail();
+}
+
+test1();
+
+gpio10 = 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);
+  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);
+
+  gpio10.write(LED_ON, function(writeErr) {
+    assert.equal(writeErr, null);
+    console.log('gpio write');
+
+    gpio10.read(function(readErr, value) {
+      assert.equal(readErr, null);
+      console.log('gpio read:', value);
+      assert.equal(LED_ON, value);
+
+      setTimeout(function() {
+        gpio10.writeSync(LED_OFF);
+        assert.equal(LED_OFF, gpio10.readSync());
+        gpio10.close();
+      }, 3000);
+    });
+  });
+}
diff --git a/tools/test/run_pass/test_gpio2.js b/tools/test/run_pass/test_gpio2.js
new file mode 100644 (file)
index 0000000..33abe55
--- /dev/null
@@ -0,0 +1,78 @@
+/* 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 = 10;
+  switchPin = 9;
+  ledMode = gpio.MODE.NONE;
+} else if (process.platform === 'nuttx') {
+  var pin = require('stm32f4dis').pin;
+  ledPin = pin.PA10;
+  switchPin = pin.PA8;
+  ledMode = gpio.MODE.PUSHPULL;
+} 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);
+  }
+
+  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);
diff --git a/tools/test/run_pass/test_http_get.js b/tools/test/run_pass/test_http_get.js
new file mode 100644 (file)
index 0000000..7f9ff4d
--- /dev/null
@@ -0,0 +1,98 @@
+/* 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();
diff --git a/tools/test/run_pass/test_http_header.js b/tools/test/run_pass/test_http_header.js
new file mode 100644 (file)
index 0000000..708d8be
--- /dev/null
@@ -0,0 +1,84 @@
+/* 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 () {
+
+    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' }
+
+    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);
+});
diff --git a/tools/test/run_pass/test_httpclient_timeout.js b/tools/test/run_pass/test_httpclient_timeout.js
new file mode 100644 (file)
index 0000000..52b96d4
--- /dev/null
@@ -0,0 +1,51 @@
+/* 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: 3002
+};
+
+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);
+});
diff --git a/tools/test/run_pass/test_httpclient_timeout2.js b/tools/test/run_pass/test_httpclient_timeout2.js
new file mode 100644 (file)
index 0000000..141197c
--- /dev/null
@@ -0,0 +1,63 @@
+/* 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);
+});
diff --git a/tools/test/run_pass/test_httpserver.js b/tools/test/run_pass/test_httpserver.js
new file mode 100644 (file)
index 0000000..fc1fce2
--- /dev/null
@@ -0,0 +1,186 @@
+/* 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 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();
+
+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);
+});
diff --git a/tools/test/run_pass/test_httpserver_timeout.js b/tools/test/run_pass/test_httpserver_timeout.js
new file mode 100644 (file)
index 0000000..32eccee
--- /dev/null
@@ -0,0 +1,48 @@
+/* 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);
+});
diff --git a/tools/test/run_pass/test_i2c.js b/tools/test/run_pass/test_i2c.js
new file mode 100644 (file)
index 0000000..ff0a00b
--- /dev/null
@@ -0,0 +1,54 @@
+/* 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 wire = i2c.open({device: '/dev/i2c-1', address: 0x23}, function(err) {
+  if (err) {
+    throw err;
+  }
+});
+
+wire.write([0x10], function(err) {
+  assert.equal(err, null);
+  console.log('write done');
+});
+
+wire.writeByte(0x10, function(err) {
+  assert.equal(err, null);
+  console.log('writeByte 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.readByte(function(err, res) {
+  assert.equal(err, null);
+  console.log('readByte result: '+res);
+});
+
+wire.readBytes(0x20, 2, function(err, res) {
+  assert.equal(err, null);
+  assert.equal(res.length, 2, 'I2C readBytes failed.(length is not equal)');
+  console.log('readBytes(cmd:0x20, length:2) result: '+res[0]+', '+res[1]);
+});
diff --git a/tools/test/run_pass/test_module_cache.js b/tools/test/run_pass/test_module_cache.js
new file mode 100644 (file)
index 0000000..d2e8029
--- /dev/null
@@ -0,0 +1,22 @@
+/* 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('require1/module_cache.js');
+module_cache.i = 100;
+module_cache = require('require1/module_cache.js');
+
+assert.equal(module_cache.i, 100);
diff --git a/tools/test/run_pass/test_net1.js b/tools/test/run_pass/test_net1.js
new file mode 100644 (file)
index 0000000..3a5df6e
--- /dev/null
@@ -0,0 +1,51 @@
+/* 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");
+});
diff --git a/tools/test/run_pass/test_net10.js b/tools/test/run_pass/test_net10.js
new file mode 100644 (file)
index 0000000..6459cbc
--- /dev/null
@@ -0,0 +1,44 @@
+/* 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 timedout = false;
+var connected = false;
+
+// Try connect to host that is not exist (Reserved address of TEST-NET-1)
+var socket1 = net.createConnection(11111, '192.0.2.1');
+
+socket1.setTimeout(1000);
+
+socket1.on('timeout', function() {
+  timedout = true;
+  socket1.destroy();
+});
+
+socket1.on('error', function() {
+  assert.fail();
+});
+
+socket1.on('connect', function() {
+  connected = true;
+  socket1.destroy();
+});
+
+process.on('exit', function() {
+  assert(timedout);
+  assert(!connected);
+});
diff --git a/tools/test/run_pass/test_net2.js b/tools/test/run_pass/test_net2.js
new file mode 100644 (file)
index 0000000..4f14943
--- /dev/null
@@ -0,0 +1,53 @@
+/* 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");
+});
diff --git a/tools/test/run_pass/test_net3.js b/tools/test/run_pass/test_net3.js
new file mode 100644 (file)
index 0000000..1b34918
--- /dev/null
@@ -0,0 +1,89 @@
+/* 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);
+});
diff --git a/tools/test/run_pass/test_net4.js b/tools/test/run_pass/test_net4.js
new file mode 100644 (file)
index 0000000..d8817a0
--- /dev/null
@@ -0,0 +1,57 @@
+/* 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);
+});
diff --git a/tools/test/run_pass/test_net5.js b/tools/test/run_pass/test_net5.js
new file mode 100644 (file)
index 0000000..1374e1e
--- /dev/null
@@ -0,0 +1,60 @@
+/* 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);
+});
diff --git a/tools/test/run_pass/test_net6.js b/tools/test/run_pass/test_net6.js
new file mode 100644 (file)
index 0000000..0541322
--- /dev/null
@@ -0,0 +1,67 @@
+/* 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");
+});
diff --git a/tools/test/run_pass/test_net7.js b/tools/test/run_pass/test_net7.js
new file mode 100644 (file)
index 0000000..faa4a14
--- /dev/null
@@ -0,0 +1,75 @@
+/* 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();
+    }
+  }
+});
diff --git a/tools/test/run_pass/test_net8.js b/tools/test/run_pass/test_net8.js
new file mode 100644 (file)
index 0000000..f83db72
--- /dev/null
@@ -0,0 +1,73 @@
+/* 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);
+});
diff --git a/tools/test/run_pass/test_net9.js b/tools/test/run_pass/test_net9.js
new file mode 100644 (file)
index 0000000..6bd2dee
--- /dev/null
@@ -0,0 +1,56 @@
+/* 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");
+});
diff --git a/tools/test/run_pass/test_next_tick.js b/tools/test/run_pass/test_next_tick.js
new file mode 100644 (file)
index 0000000..279de36
--- /dev/null
@@ -0,0 +1,41 @@
+/* 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");
+});
diff --git a/tools/test/run_pass/test_process.js b/tools/test/run_pass/test_process.js
new file mode 100644 (file)
index 0000000..292f03a
--- /dev/null
@@ -0,0 +1,28 @@
+/* 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');
+});
diff --git a/tools/test/run_pass/test_pwm.js b/tools/test/run_pass/test_pwm.js
new file mode 100644 (file)
index 0000000..92e9342
--- /dev/null
@@ -0,0 +1,103 @@
+/* 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 = {};
+
+if (process.platform === 'linux') {
+  configuration.pin = 0;
+} else if (process.platform === 'nuttx') {
+  configuration.pin = require('stm32f4dis').pin.PWM1.CH1_1;
+} 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 = pwm.open(configuration, function (err) {
+  console.log('PWM initialized');
+
+  if (err) {
+    console.log('Have an error: ' + err.message);
+    assert.fail();
+  }
+
+  pwm0.setEnable(1, testCb);
+  testPeriods(pwm0, testCb);
+});
+
+function testPeriods(pwm, callback) {
+  var options = periodOptions;
+  console.log('PWM: period test start ');
+  var idx = 0;
+  var period = options.values[idx++];
+  console.log("Period(%d)", period);
+  pwm.setFrequency(1.0 / period, callback);
+  pwm.setDutyCycleSync(options.dutyCycle);
+
+  var loop = setInterval(function () {
+    if (idx == options.values.length) {
+      pwm.setPeriodSync(options.values[0]);
+      clearInterval(loop);
+      console.log('PWM period test complete');
+      testDutyCycles(pwm, callback);
+    } else {
+      period = options.values[idx++];
+      console.log("Period(%d)", period);
+      pwm.setPeriod(period, callback);
+    }
+  }, 1000);
+}
+
+function testDutyCycles(pwm, callback) {
+  var options = dutyOptions;
+
+  console.log('PWM: duty cycle test start');
+  pwm.setFrequencySync(1.0 / options.period);
+
+  var idx = 0;
+  var loop = setInterval(function () {
+    console.log('Duty cycle %d', options.values[idx]);
+    pwm.setDutyCycle(options.values[idx], callback);
+
+    if (++idx == options.values.length) {
+      clearInterval(loop);
+      pwm.setEnableSync(0);
+      console.log('PWM duty cycle test complete');
+    }
+  }, 1000);
+}
diff --git a/tools/test/run_pass/test_spi.js b/tools/test/run_pass/test_spi.js
new file mode 100644 (file)
index 0000000..1805934
--- /dev/null
@@ -0,0 +1,75 @@
+/* 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();
+
+//  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]);
+
+  setTimeout(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);
+
+      spi0.close();
+    });
+  }, 500);
+});
+
+// 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);
+});
diff --git a/tools/test/run_pass/test_stream.js b/tools/test/run_pass/test_stream.js
new file mode 100644 (file)
index 0000000..082cf5f
--- /dev/null
@@ -0,0 +1,77 @@
+/* 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 readable = new Readable();
+var d = "";
+var e = "";
+
+
+readable.on('error', function(err) {
+  e += ".";
+});
+
+readable.on('data', function(data) {
+  d += data.toString();
+});
+
+readable.on('end', function() {
+  e += 'e';
+});
+
+
+readable.pause();
+readable.push('abcde');
+readable.push('12345');
+assert.equal(d, '');
+assert.equal(e, '');
+
+readable.resume();
+assert.equal(d, 'abcde12345');
+assert.equal(e, '');
+
+readable.push('a');
+readable.push('1');
+readable.push('b');
+readable.push('2');
+assert.equal(d, 'abcde12345a1b2');
+assert.equal(e, '');
+
+readable.pause();
+assert.equal(d, 'abcde12345a1b2');
+assert.equal(e, '');
+
+readable.push('c');
+readable.push('3');
+readable.push('d');
+readable.push('4');
+assert.equal(d, 'abcde12345a1b2');
+assert.equal(e, '');
+
+readable.resume();
+assert.equal(d, 'abcde12345a1b2c3d4');
+assert.equal(e, '');
+
+readable.push(null);
+assert.equal(d, 'abcde12345a1b2c3d4');
+assert.equal(e, 'e');
+
+readable.push('push after eof');
+assert.equal(d, 'abcde12345a1b2c3d4');
+assert.equal(e, 'e.');
diff --git a/tools/test/run_pass/test_timers.js b/tools/test/run_pass/test_timers.js
new file mode 100644 (file)
index 0000000..6917acd
--- /dev/null
@@ -0,0 +1,42 @@
+/* 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 timerSequence = '';
+
+var timerA = setTimeout(function() {
+  timerSequence += 'A';
+  timerACnt++;
+}, 1000);
+
+var timerB = setInterval(function() {
+  timerSequence += 'B';
+  timerBCnt++;
+  if (timerBCnt > 5) {
+    clearInterval(timerB);
+  }
+}, 300);
+
+process.on('exit', function(code) {
+  assert.equal(code, 0);
+  assert.equal(timerACnt, 1);
+  assert.equal(timerBCnt, 6);
+  assert.equal(timerSequence.length, 7);
+});
diff --git a/tools/test/run_pass/test_timers2.js b/tools/test/run_pass/test_timers2.js
new file mode 100644 (file)
index 0000000..587f57c
--- /dev/null
@@ -0,0 +1,61 @@
+/* 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);
+});
diff --git a/tools/test/run_pass/test_uart.js b/tools/test/run_pass/test_uart.js
new file mode 100644 (file)
index 0000000..24b0643
--- /dev/null
@@ -0,0 +1,56 @@
+/* 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 = {
+  device: '/dev/ttyUSB0',
+  baudRate: 115200,
+  dataBits: 8
+};
+
+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.closeSync();
+      console.log('close done');
+    }
+  });
+
+  serial.writeSync("Hello IoT.js.\n\r");
+
+  serial.write("Hello there?\n\r", function(err) {
+    assert.equal(err, null);
+    console.log('write done');
+    write = 1;
+
+    if (read && write) {
+      serial.closeSync();
+      console.log('close done');
+    }
+  });
+});
diff --git a/tools/test/run_pass/test_uncaught1.js b/tools/test/run_pass/test_uncaught1.js
new file mode 100644 (file)
index 0000000..48d5877
--- /dev/null
@@ -0,0 +1,41 @@
+/* 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();
diff --git a/tools/test/run_pass/test_uncaught2.js b/tools/test/run_pass/test_uncaught2.js
new file mode 100644 (file)
index 0000000..84180bd
--- /dev/null
@@ -0,0 +1,37 @@
+/* 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';
diff --git a/tools/test/run_pass/test_uncaught_error1.js b/tools/test/run_pass/test_uncaught_error1.js
new file mode 100644 (file)
index 0000000..1420615
--- /dev/null
@@ -0,0 +1,26 @@
+/* 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);
diff --git a/tools/test/run_pass/test_uncaught_error2.js b/tools/test/run_pass/test_uncaught_error2.js
new file mode 100644 (file)
index 0000000..0eb61a6
--- /dev/null
@@ -0,0 +1,35 @@
+/* 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');
diff --git a/tools/test/test_stat.js b/tools/test/test_stat.js
new file mode 100644 (file)
index 0000000..1b43dc2
--- /dev/null
@@ -0,0 +1,80 @@
+/* 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');
+
+try{ // fs.statSync throw ex for non-existing file
+  var statbuf1 = fs.statSync('../test');
+  console.log("../test dev : " + statbuf1.dev);
+  console.log("../test mode : " + statbuf1.mode);
+  console.log("../test size : " + statbuf1.size);
+
+  if(statbuf1.isDirectory()){
+    console.log("../test is a directory");
+  }
+  else {
+    console.log("../test is not a directory");
+  }
+}
+catch(ex){}
+
+
+try{ // fs.statSync throw ex for non-existing file
+  var statbuf2 = fs.statSync('test_stat.js');
+
+  console.log("test_stat.js dev : " + statbuf2.dev);
+  console.log("test_stat.js mode : " + statbuf2.mode);
+  console.log("test_stat.js size : " + statbuf2.size);
+
+  if(statbuf2.isDirectory()){
+    console.log("test_stat.js is a directory");
+  }
+  else {
+    console.log("test_stat.js is not a directory");
+  }
+}
+catch(ex){}
+
+try{ // fs.statSync throw ex for non-existing file
+  console.log("non-existing file(non_existing.js) statSync tried.");
+  var statbuf3 = fs.statSync('non_existing.js');
+}
+catch(ex){
+  console.log("but, failed.");
+}
+
+function statcallback(err, statbuf) {
+  console.log("statcallback called");
+  if(err){
+    console.log("stat async call error");
+    return;
+  }
+
+  if(statbuf.isDirectory()){
+    console.log("async stat for test_stat.js is a directory");
+  }
+  else {
+    console.log("async stat for test_stat.js is not a directory");
+  }
+
+}
+
+try {
+  fs.stat('test_stat.js', statcallback);
+}
+catch(ex) {
+  console.log("stat async call error");
+}
diff --git a/tools/test/testsets.json b/tools/test/testsets.json
new file mode 100644 (file)
index 0000000..ee5b32f
--- /dev/null
@@ -0,0 +1,91 @@
+{
+  "run_pass":  [
+    { "name": "test_adc.js", "skip": ["all"], "reason": "need to setup test environment" },
+    { "name": "test_assert.js" },
+    { "name": "test_ble.js", "skip": ["all"], "reason": "need to setup test environment" },
+    { "name": "test_buffer_builtin.js" },
+    { "name": "test_buffer.js" },
+    { "name": "test_console.js" },
+    { "name": "test_cwd.js", "skip": ["all"], "reason": "this test had @STDOUT=COMMAND[pwd], but there's no way to check out current directory path with js driver. So it skips temporarily." },
+    { "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_dns.js", "skip": ["nuttx"], "reason": "not implemented for nuttx" },
+    { "name": "test_dns_lookup.js", "skip": ["nuttx"], "reason": "not implemented for nuttx" },
+    { "name": "test_events.js", "skip": ["nuttx"], "reason": "not implemented for nuttx" },
+    { "name": "test_experimental_off.js", "skip": ["experimental"], "reason": "needed if testing stablity is set with stable" },
+    { "name": "test_experimental_on.js", "skip": ["stable"], "reason": "needed if testing stablity is set with experimental" },
+    { "name": "test_exit.js", "skip": ["all"], "reason": "driver can not run with test which checks out process.exit events" },
+    { "name": "test_fs_exists.js", "skip": ["nuttx"], "reason": "not implemented for nuttx" },
+    { "name": "test_fs_existssync.js", "skip": ["nuttx"], "reason": "not implemented for nuttx" },
+    { "name": "test_fs_mkdir_rmdir.js", "skip": ["nuttx"], "reason": "not implemented for nuttx" },
+    { "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", "skip": ["nuttx"], "reason": "not implemented for nuttx" },
+    { "name": "test_fs_readfilesync.js", "skip": ["nuttx"], "reason": "not implemented for nuttx" },
+    { "name": "test_fs_rename.js" },
+    { "name": "test_fs_rename_sync.js" },
+    { "name": "test_fs_stat.js", "skip": ["nuttx"], "reason": "not implemented for nuttx" },
+    { "name": "test_fs_writefile_unlink.js" },
+    { "name": "test_fs_writefile_unlink_sync.js" },
+    { "name": "test_fs.js", "skip": ["nuttx"], "reason": "not implemented for nuttx" },
+    { "name": "test_fs1.js", "skip": ["nuttx"], "reason": "not implemented for nuttx" },
+    { "name": "test_fs2.js", "skip": ["nuttx"], "reason": "not implemented for nuttx" },
+    { "name": "test_gpio1.js", "skip": ["all"], "reason": "needs hardware" },
+    { "name": "test_gpio2.js", "skip": ["all"], "reason": "need user input"},
+    { "name": "test_http_get.js", "timeout": 20, "skip": ["nuttx"], "reason": "not implemented for nuttx" },
+    { "name": "test_http_header.js", "skip": ["nuttx"], "reason": "not implemented for nuttx" },
+    { "name": "test_httpclient_timeout.js", "timeout": 10, "skip": ["nuttx"], "reason": "not implemented for nuttx" },
+    { "name": "test_httpclient_timeout2.js", "timeout": 15, "skip": ["nuttx"], "reason": "not implemented for nuttx" },
+    { "name": "test_httpserver_timeout.js", "timeout": 10, "skip": ["nuttx"], "reason": "not implemented for nuttx" },
+    { "name": "test_httpserver.js", "timeout": 20, "skip": ["nuttx"], "reason": "not implemented for nuttx" },
+    { "name": "test_i2c.js", "skip": ["all"], "reason": "need to setup test environment" },
+    { "name": "test_module_cache.js", "skip": ["nuttx"], "reason": "not implemented for nuttx" },
+    { "name": "test_net1.js" },
+    { "name": "test_net2.js" },
+    { "name": "test_net3.js", "timeout": 20, "skip": ["nuttx"], "reason": "requires too many socket descriptors and too large buffers" },
+    { "name": "test_net4.js" },
+    { "name": "test_net5.js" },
+    { "name": "test_net6.js" },
+    { "name": "test_net7.js", "skip": ["nuttx"], "reason": "requires too many socket descriptors" },
+    { "name": "test_net8.js" },
+    { "name": "test_net9.js" },
+    { "name": "test_net10.js" },
+    { "name": "test_next_tick.js" },
+    { "name": "test_process.js" },
+    { "name": "test_pwm.js", "skip": ["all"], "reason": "need to setup test environment" },
+    { "name": "test_stream.js" },
+    { "name": "test_timers.js", "timeout": 10 },
+    { "name": "test_timers2.js" },
+    { "name": "test_uart.js", "skip": ["all"], "reason": "need to setup test environment" },
+    { "name": "test_uncaught1.js", "uncaught": true },
+    { "name": "test_uncaught2.js", "uncaught": true },
+    { "name": "test_uncaught_error1.js", "uncaught": true },
+    { "name": "test_uncaught_error2.js", "uncaught": true }
+  ],
+  "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" }
+  ],
+  "run_fail":  [
+    { "name": "assert_fail1.js", "expected-failure": true },
+    { "name": "assert_fail2.js", "expected-failure": true },
+    { "name": "assert_fail3.js", "expected-failure": true },
+    { "name": "fs_callbacks_called.js", "expected-failure": true },
+    { "name": "process_exit1.js", "expected-failure": true },
+    { "name": "process_exit2.js", "expected-failure": true },
+    { "name": "process_exitcode1.js", "expected-failure": true },
+    { "name": "process_exitcode2.js", "expected-failure": true },
+    { "name": "require_fail1.js", "expected-failure": true },
+    { "name": "runtime_error1.js", "expected-failure": true },
+    { "name": "syntax_fail1.js", "expected-failure": true },
+    { "name": "uncaught_error_event.js", "expected-failure": true }
+  ]
+}
diff --git a/tools/test/tmp/README b/tools/test/tmp/README
new file mode 100644 (file)
index 0000000..bc2f0ba
--- /dev/null
@@ -0,0 +1 @@
+This directory is for temporary files will be generated during build test.
diff --git a/tools/test_runner.js b/tools/test_runner.js
new file mode 100644 (file)
index 0000000..2e6504c
--- /dev/null
@@ -0,0 +1,136 @@
+/* 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');
+
+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;
+  process.nextTick(function() {
+      var timerOnlyAlive = !testdriver.isAliveExceptFor(that.timer);
+      if (timerOnlyAlive) {
+        timerOnlyAlive = !process._onNextTick();
+      }
+
+      if (timerOnlyAlive) {
+        process.exit(0);
+      } else {
+        if (!that.finished) {
+          that.spin();
+        }
+      }
+  });
+};
+
+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.run = function() {
+  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;
diff --git a/tools/zlib-Makefile.patch b/tools/zlib-Makefile.patch
new file mode 100644 (file)
index 0000000..e2f7abf
--- /dev/null
@@ -0,0 +1,34 @@
+--- 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