Mbed OS version of IoT.js implementation running on GR-PEACH
ビルド方法
ビルド環境セットアップ
Host PC要件 : Ubuntu 16.04 (64-bit)
1. 以下のコマンドを実行し、下表に示すツールをインストールします。
$ sudo apt update $ sudo apt upgrade $ sudo apt install [Package]
Package | Version |
build-essential | 12.1ubuntu2 |
gyp | 0.1+20150913git1f374df9-1ubuntu1 |
mercurial | 3.7.3-1ubuntu1 |
cmake | 3.5.1-1ubuntu3 |
git | 1:2.7.4-0ubuntu1.4 |
python2.7 | 2.7.12-1ubuntu016.04.3 |
valgrind | 1:3.11.0-1ubuntu4.2 |
python-pip | 8.1.1-2ubuntu0.4 |
2. 以下のコマンドを実行してMbed OS用ビルドツール mbed CLIをインストールします。
$ sudo -H pip install mbed-cli
3. GNU Arm Embedded Toolchainをインストールします。
- 下記URLからLinux用パッケージ (gcc-arm-none-eabi-6-2017-q2-update-linux.tar.bz2) をダウンロードしてください。
https://developer.arm.com/-/media/Files/downloads/gnu-rm/6-2017q2/gcc-arm-none-eabi-6-2017-q2-update-linux.tar.bz2?revision=2cc92fb5-3e0e-402d-9197-bdfc8224d8a5?product=GNU%20Arm%20Embedded%20Toolchain,64-bit,,Linux,6-2017-q2-update
- ダウンロードしたファイルを任意のディレクトリに展開します。
(以下、展開先を${TOOLCHAIN}と記載します)
tar xjf gcc-arm-none-eabi-6-2017-q2-update-linux.tar.bz2
- ツールチェインのパスを設定します。
環境変数を使用する場合
$ export GCC_ARM_ROOT=${TOOLCHAIN}/gcc-arm-none-eabi-6-2017-q2-update/bin $ export PATH=$GCC_ARM_ROOT:$PATH
mbed CLIで指定する場合
$ mbed config -G GCC_ARM_PATH $GCC_ARM_ROOT
iotjs環境のビルド
1. 本プログラムのクローン
下記コマンドを実行し、本プログラムをクローンしてください。
$ hg clone https://HinoNaka@os.mbed.com/users/HinoNaka/code/GR-PEACH_mbed-os-iotjs/
クローンが正常に終了すると、GR-PEACH_mbed-os-iotjs という名称のディレクトリが生成されますので、下記コマンドで当該ディレクトリへ移動してください。
$ cd GR-PEACH_mbed-os-iotjs
(Optional)
GR-PEACH-mbed-os-iotjsディレクトリを指す環境変数 ROOTを設定してください。以降の記載は本環境変数が設定されているものとします。
$ export ROOT=$(PWD)
2. 作業用ディレクトリ(e.g. work)を作成し、当該ディレクトリに移動してください。
$ mkdir -p work $ cd work
(Optional)
作業用ディレクトリを指す環境変数 WORK を設定してください。以降の記載は本環境変数 が設定されているものとします。
$ export WORK=$(PWD)
3. iotjsのソースツリーを取得します。
$ git clone https://github.com/pando-project/iotjs
クローンが正常に終了するとiotjsというディレクトリが生成されますので、当該ディレクトリに移動してください。
$cd iotjs
コミットID: acae9c8b2d40e7598b8d39b630b79113ce880a7e を取得します。
(下記例では、あわせてposixというブランチを作成し、当該ブランチへ切り替えています)
$ git checkout -b posix acae9c8b2d40e7598b8d39b630b79113ce880a7e
4. mbed-osセットアップ
Mbed OSソースツリーを格納するフォルダを生成し、当該フォルダへ移動します。
$ mkdir -p $(WORK)/iotjs/src/platform/mbedos5 $ cd $(WORK)/iotjs/src/platform/mbedos5
Mbed OSのソースツリーをクローンします。
$ git clone -b mbed-os-5.9 https://github.com/ARMmbed/mbed-os.git
クローンが正常に終了するとmbed-osというディレクトリが生成されますので、当該ディレクトリに移動してください。
$ cd mbed-os
コミットID: 50bd61a4a72332baa6b1bac6caccb44dc5423309 を取得します。
(下記例では、あわせてposixというブランチを作成し、当該ブランチへ切り替えています)
$ git checkout -b posix 50bd61a4a72332baa6b1bac6caccb44dc5423309
5. sd-driverの取得
下記コマンドでmbedos5ディレクトリへ移動します。
$ cd $(WORK)/iotjs/src/platform/mbedos5
sd-driverをクローンします。
$ git clone https://github.com/ARMmbed/sd-driver.git
クローンが正常終了するとsd-driverディレクトリが生成されますので、当該ディレクトリへ移動します。
$ cd sd-driver
コミットID: c8ae38fb291e086232566b0f1372cfb69c277e84 を取得します。
(下記例では、あわせてposixというブランチを作成し、当該ブランチへ切り替えています)
$ git checkout -b posix c8ae38fb291e086232566b0f1372cfb69c277e84
6. mbed-gr-libsの取得
下記コマンドでmbedos5ディレクトリへ移動します。
$ cd $(WORK)/iotjs/src/platform/mbedos5
mbed-gr-libsをクローンします。
$ git clone https://github.com/d-kato/mbed-gr-libs
クローンが正常終了するとmbed-gr-libsディレクトリが生成されますので、当該ディレクトリへ移動します。
$ cd mbed-gr-libs
コミットID: d921d611d596ecaebaab49070ef82450c583309c を取得します。
(下記例では、あわせてposixというブランチを作成し、当該ブランチへ切り替えています)
$ git checkout -b posix d921d611d596ecaebaab49070ef82450c583309c
7. AsciiFONTの取得
下記コマンドでmbedos5ディレクトリへ移動します。
$ cd $(WORK)/iotjs/src/platform/mbedos5
AsciiFONTライブラリを追加します。
$ mbed add https://os.mbed.com/teams/Renesas/code/AsciiFont/
8. iotjs環境のビルド
下記コマンドでiotjs環境のビルドディレクトリに移動し、ビルドを実行します。
$ cd $(WORK)/iotjs $ ./tools/build.py --no-snapshot
9. GR-PEACH用コードのコピー
(Optional) 既存のiotjs環境に上書きする場合、下記コマンドを実行してください。
$ rm -rf $(WORK)/iotjs/deps/posix $ rm -rf $(WORK)/iotjs/src/ext-modules $ rm -rf $(WORK)/iotjs/src/platform/mbedos5/iotjs_def.h
下記コマンドでGR-PEACH用コードをコピーします。
$ cp -pr $(ROOT)/src/iotjs/* $(WORK)/iotjs/
10. lwipパッチ適用
以下コマンドでlwipパッチを適用します。
$ cd $(WORK)/iotjs/src/platform/mbedos5/mbed-os $ git apply lwip_improve.patch
11. ESP32 TRNG対応パッチ適用
以下コマンドでESP32のTRNGを活用するためのパッチを適用します。
$ cd $(WORK)/iotjs/src/platform/mbedos5/mbed-os $ git apply trng_support.patch
12. Mbed OS版iotjs環境のビルド
下記コマンドを実行してMbed OS版iotjs環境をビルドします。
(リリースビルドの場合)
$ cd $(WORK)/iotjs/src/platform/mbedos5 $ make clean; make DEBUG=0
(デバッグビルドの場合)
$ cd $(WORK)/iotjs/src/platform/mbedos5 $ make clean; make DEBUG=1
13. ビルドが正常に終了すると、以下の通りバイナリが生成されます。
(リリースビルドの場合)
$ ls -l ${WORK}/iotjs/src/platform/mbedos5/BUILD/RZ_A1H/GCC_ARM-RELEASE/iotjs.bin
(デバッグビルドの場合)
$ ls -l ${WORK}/iotjs/src/platform/mbedos5/BUILD/RZ_A1H/GCC_ARM-DEBUG/iotjs.bin
実行方法
1. GR-PEACHにmicro SDカードを挿入します。
2. GR-PEACHのEthernetポートから遠い側のUSBポートとHost PCをマイクロUSBケーブルで接続します。
3. Host PCでGR-PEACHが『mbed:』ドライブとして認識されたら、iotjs.binをmbedドライブにコピーします。
4. ターミナルS/Wを立上げ、『mbed Serial Port』と接続します。
シリアルポートは下記設定としてください。
Baud rate | 115200 | |||
Data | 8 bit | |||
Parity | none | |||
Stop | 1 bit | |||
Flow control | none |
5. 正常に書込みが終了したらGR-PEACHのRESETボタンを押下します。
6. ターミナルS/W上に下記メッセージが表示されます。
7. Enterキーを押下してコード入力モードに移行します。
8. 実行するJavascriptコードをターミナルソフトウェアに貼り付けてEnterキーを押下すると、実行開始します。Javascriptコード例については、test/case.txtを参照ください。
Revision 0:7cc000799c93, committed 2019-07-11
- Comitter:
- Osamu Nakamura
- Date:
- Thu Jul 11 18:48:09 2019 +0900
- Child:
- 1:c3d69f309845
- Commit message:
- Initial commit of iotjs core
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/iotjs/deps/posix/inc/arpa/inet.h Thu Jul 11 18:48:09 2019 +0900 @@ -0,0 +1,1 @@ +#include "../../posix4.h"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/iotjs/deps/posix/inc/dirent.h Thu Jul 11 18:48:09 2019 +0900 @@ -0,0 +1,1 @@ +#include "../posix4.h"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/iotjs/deps/posix/inc/dlfcn.h Thu Jul 11 18:48:09 2019 +0900 @@ -0,0 +1,1 @@ +#include "../posix4.h"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/iotjs/deps/posix/inc/execinfo.h Thu Jul 11 18:48:09 2019 +0900 @@ -0,0 +1,1 @@ +#include "../posix4.h"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/iotjs/deps/posix/inc/ifaddrs.h Thu Jul 11 18:48:09 2019 +0900 @@ -0,0 +1,1 @@ +#include "../posix4.h"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/iotjs/deps/posix/inc/net/ethernet.h Thu Jul 11 18:48:09 2019 +0900 @@ -0,0 +1,1 @@ +#include "../../posix4.h"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/iotjs/deps/posix/inc/net/if.h Thu Jul 11 18:48:09 2019 +0900 @@ -0,0 +1,1 @@ +#include "../../posix4.h"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/iotjs/deps/posix/inc/netdb.h Thu Jul 11 18:48:09 2019 +0900 @@ -0,0 +1,1 @@ +#include "../posix4.h"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/iotjs/deps/posix/inc/netinet/in.h Thu Jul 11 18:48:09 2019 +0900 @@ -0,0 +1,1 @@ +#include "../../posix4.h"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/iotjs/deps/posix/inc/netinet/tcp.h Thu Jul 11 18:48:09 2019 +0900 @@ -0,0 +1,1 @@ +#include "../../posix4.h"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/iotjs/deps/posix/inc/netpacket/packet.h Thu Jul 11 18:48:09 2019 +0900 @@ -0,0 +1,1 @@ +#include "../../posix4.h"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/iotjs/deps/posix/inc/nic.h Thu Jul 11 18:48:09 2019 +0900 @@ -0,0 +1,1 @@ +#include "../posix4.h"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/iotjs/deps/posix/inc/poll.h Thu Jul 11 18:48:09 2019 +0900 @@ -0,0 +1,1 @@ +#include "../posix4.h"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/iotjs/deps/posix/inc/pthread.h Thu Jul 11 18:48:09 2019 +0900 @@ -0,0 +1,1 @@ +#include "../posix4.h"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/iotjs/deps/posix/inc/semaphore.h Thu Jul 11 18:48:09 2019 +0900 @@ -0,0 +1,1 @@ +#include "../posix4.h"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/iotjs/deps/posix/inc/sys/ioctl.h Thu Jul 11 18:48:09 2019 +0900 @@ -0,0 +1,1 @@ +#include "../../posix4.h"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/iotjs/deps/posix/inc/sys/prctl.h Thu Jul 11 18:48:09 2019 +0900 @@ -0,0 +1,1 @@ +#include "../../posix4.h"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/iotjs/deps/posix/inc/sys/sendfile.h Thu Jul 11 18:48:09 2019 +0900 @@ -0,0 +1,7 @@ +#include "../../posix4.h" + +#if defined(USE_POSIX_BRIDGE) + #undef _GNU_SOURCE // to avoid compile error of uv__to_stat() in iotjs/deps/libtuv/src/unix/fs.c + #undef _DEFAULT_SOURCE // for gcc-arm-none-eabi-6-2017-q2-update-linux.tar.bz2 +#endif // #if defined(USE_POSIX_BRIDGE) +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/iotjs/deps/posix/inc/sys/socket.h Thu Jul 11 18:48:09 2019 +0900 @@ -0,0 +1,1 @@ +#include "../../posix4.h"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/iotjs/deps/posix/inc/sys/syscall.h Thu Jul 11 18:48:09 2019 +0900 @@ -0,0 +1,1 @@ +#include "../../posix4.h"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/iotjs/deps/posix/inc/sys/sysinfo.h Thu Jul 11 18:48:09 2019 +0900 @@ -0,0 +1,1 @@ +#include "../../posix4.h"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/iotjs/deps/posix/inc/sys/termios.h Thu Jul 11 18:48:09 2019 +0900 @@ -0,0 +1,1 @@ +#include "../../posix4.h"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/iotjs/deps/posix/inc/sys/uio.h Thu Jul 11 18:48:09 2019 +0900 @@ -0,0 +1,1 @@ +#include "../../posix4.h"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/iotjs/deps/posix/inc/sys/un.h Thu Jul 11 18:48:09 2019 +0900 @@ -0,0 +1,1 @@ +#include "../../posix4.h"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/iotjs/deps/posix/peripheral_io.h Thu Jul 11 18:48:09 2019 +0900 @@ -0,0 +1,27 @@ +/* Copyright 2017-present Renesas Electronics Corporation and other contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT 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 PERIPHERAL_IO_INCL +#define PERIPHERAL_IO_INCL + +#if defined(__MBED_OS__) + #include "platform/mbedos5/peripheral_io_4mbed.h" +#endif // #if defined(__MBED_OS__) + +#if defined(__UC3__) + #include "platform/uC3/peripheral_io_4uC3.h" +#endif // #if defined(__UC3__) + +#endif // #ifndef PERIPHERAL_IO_INCL
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/iotjs/deps/posix/platform/.mbedignore Thu Jul 11 18:48:09 2019 +0900 @@ -0,0 +1,2 @@ +RESPECT_mbedos5/* +uC3/*
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/iotjs/deps/posix/platform/mbedos5/peripheral_io_4mbed.cpp Thu Jul 11 18:48:09 2019 +0900 @@ -0,0 +1,410 @@ +/* Copyright 2017-present Renesas Electronics Corporation and other contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT 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 <mbed.h> +#include "posix4mbed.h" +#include "peripheral_io_4mbed.h" +#include "primitives.h" + +using namespace os::primitives; + +inline const char* safe_str(const char* in) { return in ? in : "<null>"; } + + +#if ENABLE_MODULE_VIDEO==1 +P4(video_h) P4(video_open)(video_source_t video_source) +{ + TRACE(ENTER "video_open()"); + P4(video_h) rc = video::open(video_source); + TRACE(LEAVE "video_open() = %p", rc); + return rc; +} + +bool P4(video_start)(P4(video_h) handle, void* buf) +{ + TRACE(ENTER "video_start()"); + bool rc = handle ? video::start(handle, buf) : false; + TRACE(LEAVE "video_start() = %d", rc); + return rc; +} + +bool P4(video_stop)(P4(video_h) handle) +{ + TRACE(ENTER "video_stop()"); + bool rc = handle ? video::stop(handle) : false; + TRACE(LEAVE "video_stop() = %d", rc); + return rc; +} + +bool P4(video_close)(P4(video_h) handle) +{ + TRACE(ENTER "video_close()"); + bool rc = handle ? video::close(handle) : false; + TRACE(LEAVE "video_close() = %d", rc); + return rc; +} + +namespace os { namespace video { + + union handle_instance { + P4(video_h) handle; + Video* instance; + handle_instance(P4(video_h) h) : handle( h ) {} + }; + +}} // namespace os::video + +P4(video_h) os::video::open(video_source_t video_source) +{ + Video* instance = new Video; + if( instance && !instance->open(video_source) ) { + delete instance; + return 0; + } + return instance; +} + +bool os::video::close(P4(video_h) handle) +{ + Video* instance = handle_instance( handle ).instance; + bool rc = instance->close(); + delete instance; + return rc; +} + +bool os::video::start(P4(video_h) handle, void* buf) +{ + Video* instance = handle_instance( handle ).instance; + return instance->start( buf ); +} + +bool os::video::stop(P4(video_h) handle) +{ + Video* instance = handle_instance( handle ).instance; + return instance->stop(); +} + +#endif // #if ENABLE_MODULE_VIDEO==1 + + +#if ENABLE_MODULE_DISPLAY==1 +P4(lcd_h) P4(lcd_open)(lcd_t *lcd) +{ + TRACE(ENTER "lcd_open()"); + P4(lcd_h) rc = lcd::open(lcd); + TRACE(LEAVE "lcd_open() = %p", rc); + return rc; +} + +bool P4(lcd_close)(P4(lcd_h) handle) +{ + TRACE(ENTER "lcd_close()"); + bool rc = handle ? lcd::close(handle) : false; + TRACE(LEAVE "lcd_close() = %d", rc); + return rc; +} + +bool P4(lcd_start)(P4(lcd_h) handle, lcd_layer_t lcd_layer) +{ + TRACE(ENTER "lcd_start()"); + bool rc = handle ? lcd::start(handle, lcd_layer) : false; + TRACE(LEAVE "lcd_start() = %d", rc); + return rc; +} + +bool P4(lcd_stop)(P4(lcd_h) handle, lcd_layer_id_t id) +{ + TRACE(ENTER "lcd_stop()"); + bool rc = handle ? lcd::stop(handle, id) : false; + TRACE(LEAVE "lcd_stop() = %d", rc); + return rc; +} + +bool P4(lcd_update)(P4(lcd_h) handle, lcd_layer_t lcd_layer) +{ + TRACE(ENTER "lcd_update()"); + bool rc = handle ? lcd::update(handle, lcd_layer) : false; + TRACE(LEAVE "lcd_update() = %d", rc); + return rc; +} + +namespace os { namespace lcd { + + union handle_instance { + P4(lcd_h) handle; + Lcd* instance; + handle_instance(P4(lcd_h) h) : handle( h ) {} + }; + +}} // namespace os::lcd + +P4(lcd_h) os::lcd::open(lcd_t *lcd) +{ + Lcd* instance = new Lcd; + if( instance && !instance->open(lcd) ) { + delete instance; + return 0; + } + return instance; +} + +bool os::lcd::close(P4(lcd_h) handle) +{ + Lcd* instance = handle_instance( handle ).instance; + bool rc = instance->close(); + delete instance; + return rc; +} + +bool os::lcd::start(P4(lcd_h) handle, lcd_layer_t lcd_layer) +{ + Lcd* instance = handle_instance( handle ).instance; + return instance->start(lcd_layer); +} + +bool os::lcd::stop(P4(lcd_h) handle, lcd_layer_id_t id) +{ + Lcd* instance = handle_instance( handle ).instance; + return instance->stop(id); +} + +bool os::lcd::update(P4(lcd_h) handle, lcd_layer_t lcd_layer) +{ + Lcd* instance = handle_instance( handle ).instance; + return instance->update(lcd_layer); +} + +#endif // #if ENABLE_MODULE_DISPLAY==1 + + +#if ENABLE_MODULE_JPEG==1 +int P4(jpeg_encode)(jpeg_convert_data_t encode_data) +{ + TRACE(ENTER "jpeg_encode()"); + int rc = jpeg::encode(encode_data); + TRACE(LEAVE "jpeg_encode() = %d", rc); + return rc; +} + +bool P4(jpeg_decode)(jpeg_convert_data_t decode_data) +{ + TRACE(ENTER "jpeg_decode()"); + bool rc = jpeg::decode(decode_data); + TRACE(LEAVE "jpeg_decode() = %d", rc); + return rc; +} + +namespace os { namespace jpeg { + + Jpeg jpeg; + +}} // namespace os::jpeg + +int os::jpeg::encode(jpeg_convert_data_t encode_data) +{ + return jpeg.encode(encode_data); +} + +bool os::jpeg::decode(jpeg_convert_data_t decode_data) +{ + return jpeg.decode(decode_data); +} + +#endif // #if ENABLE_MODULE_JPEG==1 + + +#if ENABLE_MODULE_GRAPHICS==1 +P4(graphics_h) P4(initFrameBuffer)(char *buf, int width, int height, int format) +{ + TRACE(ENTER "initFrameBuffer()"); + P4(graphics_h) rc = graphics::initFrameBuffer(buf, width, height, format); + TRACE(LEAVE "initFrameBuffer() = %p", rc); + return rc; +} + +int P4(deinitFrameBuffer)(P4(graphics_h) handle) +{ + TRACE(ENTER "deinitFrameBuffer()"); + int rc = handle ? graphics::deinitFrameBuffer(handle) : -1; + TRACE(LEAVE "deinitFrameBuffer() = %d", rc); + return rc; +} + +int P4(drawLine)(P4(graphics_h) handle, int startX, int startY, int endX, int endY, uint32_t color) +{ + TRACE(ENTER "drawLine()"); + int rc = handle ? graphics::drawLine(handle, startX, startY, endX, endY, color) : -1; + TRACE(LEAVE "drawLine() = %d", rc); + return rc; +} + +int P4(drawRect)(P4(graphics_h) handle, int x, int y, int width, int height, uint32_t color, bool fill) +{ + TRACE(ENTER "drawRect()"); + int rc = handle ? graphics::drawRect(handle, x, y, width, height, color, fill) : -1; + TRACE(LEAVE "drawRect() = %d", rc); + return rc; +} + +int P4(drawArc)(P4(graphics_h) handle, int centerX, int centerY, int radius, int startAngle, int endAngle, uint32_t color) +{ + TRACE(ENTER "drawArc()"); + int rc = handle ? graphics::drawArc(handle, centerX, centerY, radius, startAngle, endAngle, color) : -1; + TRACE(LEAVE "drawArc() = %d", rc); + return rc; +} + +int P4(drawCircle)(P4(graphics_h) handle, int centerX, int centerY, int radius, uint32_t color, bool fill) +{ + TRACE(ENTER "drawCircle()"); + int rc = handle ? graphics::drawCircle(handle, centerX, centerY, radius, color, fill) : -1; + TRACE(LEAVE "drawCircle() = %d", rc); + return rc; +} + +int P4(drawEllipse)(P4(graphics_h) handle, int centerX, int centerY, int radiusX, int radiusY, uint32_t color, bool fill) +{ + TRACE(ENTER "drawEllipse()"); + int rc = handle ? graphics::drawEllipse(handle, centerX, centerY, radiusX, radiusY, color, fill) : -1; + TRACE(LEAVE "drawEllipse() = %d", rc); + return rc; +} + +int P4(drawPolygon)(P4(graphics_h) handle, int centerX, int centerY, int radius, int sides, uint32_t color, bool fill) +{ + TRACE(ENTER "drawPolygon()"); + int rc = handle ? graphics::drawPolygon(handle, centerX, centerY, radius, sides, color, fill) : -1; + TRACE(LEAVE "drawPolygon() = %d", rc); + return rc; +} + +int P4(drawText)(P4(graphics_h) handle, char* text, int x, int y, int size, uint32_t color, uint32_t background) +{ + TRACE(ENTER "drawText()"); + int rc = handle ? graphics::drawText(handle, text, x, y, size, color, background) : -1; + TRACE(LEAVE "drawText() = %d", rc); + return rc; +} + +int P4(drawImage)(P4(graphics_h) handle, char* image, int x, int y, int width, int height) +{ + TRACE(ENTER "drawImage()"); + int rc = handle ? graphics::drawImage(handle, image, x, y, width, height) : -1; + TRACE(LEAVE "drawImage() = %d", rc); + return rc; +} + +namespace os { namespace graphics { + + union handle_instance { + P4(graphics_h) handle; + Graphics* instance; + handle_instance(P4(graphics_h) h) : handle( h ) {} + }; + + static int convert_buffer_format(display_pixel_format_t format) { + switch(format) { + case DISPLAY_PIXELFORMAT_RGB565: return Graphics::FORMAT_RGB565; + case DISPLAY_PIXELFORMAT_RGB888: return Graphics::FORMAT_RGB888; + case DISPLAY_PIXELFORMAT_ARGB8888: return Graphics::FORMAT_ARGB8888; + case DISPLAY_PIXELFORMAT_ARGB4444: return Graphics::FORMAT_ARGB4444; + default: return -1; + } + } +}} // namespace os::graphics + +P4(graphics_h) os::graphics::initFrameBuffer(char *buf, int width, int height, int format) +{ + Graphics* instance = new Graphics; + if( instance && (instance->initFrameBuffer(buf, width, height, convert_buffer_format((display_pixel_format_t)format)) < 0 ) ) { + delete instance; + return 0; + } + return instance; +} + +int os::graphics::deinitFrameBuffer(P4(graphics_h) handle) +{ + Graphics* instance = handle_instance( handle ).instance; + delete instance; + return 0; +} + +int os::graphics::drawLine(P4(graphics_h) handle, int startX, int startY, int endX, int endY, uint32_t color) +{ + Graphics* instance = handle_instance( handle ).instance; + int ret = instance->drawLine(startX, startY, endX, endY, color); + instance->flush(); + return ret; +} + +int os::graphics::drawRect(P4(graphics_h) handle, int x, int y, int width, int height, uint32_t color, bool fill) +{ + Graphics* instance = handle_instance( handle ).instance; + int ret = instance->drawRect(x, y, width, height, color, (fill ? 1 : 0)); + instance->flush(); + return ret; +} + +int os::graphics::drawArc(P4(graphics_h) handle, int centerX, int centerY, int radius, int startAngle, int endAngle, uint32_t color) +{ + Graphics* instance = handle_instance( handle ).instance; + int ret = instance->drawArc(centerX, centerY, radius, startAngle, endAngle, color); + instance->flush(); + return ret; +} + +int os::graphics::drawCircle(P4(graphics_h) handle, int centerX, int centerY, int radius, uint32_t color, bool fill) +{ + Graphics* instance = handle_instance( handle ).instance; + int ret = instance->drawCircle(centerX, centerY, radius, color, (fill ? 1 : 0)); + instance->flush(); + return ret; +} + +int os::graphics::drawEllipse(P4(graphics_h) handle, int centerX, int centerY, int radiusX, int radiusY, uint32_t color, bool fill) +{ + Graphics* instance = handle_instance( handle ).instance; + int ret = instance->drawEllipse(centerX, centerY, radiusX, radiusY, color, (fill ? 1 : 0)); + instance->flush(); + return ret; +} + +int os::graphics::drawPolygon(P4(graphics_h) handle, int centerX, int centerY, int radius, int sides, uint32_t color, bool fill) +{ + Graphics* instance = handle_instance( handle ).instance; + int ret = instance->drawPolygon(centerX, centerY, radius, sides, color, (fill ? 1 : 0)); + instance->flush(); + return ret; +} + +int os::graphics::drawText(P4(graphics_h) handle, char* text, int x, int y, int size, uint32_t color, uint32_t background) +{ + Graphics* instance = handle_instance( handle ).instance; + int ret = instance->drawText(text, x, y, size, color, background); + instance->flush(); + return ret; +} + +int os::graphics::drawImage(P4(graphics_h) handle, char* image, int x, int y, int width, int height) +{ + Graphics* instance = handle_instance( handle ).instance; + int ret = instance->drawImage(image, x, y, width, height); + instance->flush(); + return ret; +} + +#endif // #if ENABLE_MODULE_GRAPHICS==1 +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/iotjs/deps/posix/platform/mbedos5/peripheral_io_4mbed.h Thu Jul 11 18:48:09 2019 +0900 @@ -0,0 +1,250 @@ +/* Copyright 2017-present Renesas Electronics Corporation and other contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT 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 PERIPHERAL_IO_4MBED_INCL +#define PERIPHERAL_IO_4MBED_INCL + +#ifdef __cplusplus +extern "C" { +#endif + +#define P4_API(type,func) type P4(func) +#define VIDEO_API P4_API +#define DISPLAY_API P4_API +#define JPEG_API P4_API +#define GRAPHICS_API P4_API + +// VIDEO +typedef void* P4(video_h); + +typedef enum { + VIDEO_PIXELFORMAT_YCBCR422, + VIDEO_PIXELFORMAT_RGB565, + VIDEO_PIXELFORMAT_RGB888, + VIDEO_PIXELFORMAT_MAX, +} video_pixel_format_t; + +typedef enum { + DEVICETYPE_CMOSCAMERA, + DEVICETYPE_COMPOSITESIGNAL, + DEVICETYPE_MAX, +} device_type_t; + +typedef enum { + CAMERATYPE_OV7725, + CAMERATYPE_MAX, +} camera_type_t; + +typedef enum { + CHANNEL_0, + CHANNEL_1, + CHANNEL_MAX, +} channel_num_t; + +typedef enum { + SIGNALFORMAT_NTSC, + SIGNALFORMAT_PAL, + SIGNALFORMAT_MAX, +} signal_format_t; + +typedef struct { + uint32_t width; + uint32_t height; + uint32_t pixel_bytes; + uint8_t* frame_buffer; + + device_type_t device; + camera_type_t camera; + video_pixel_format_t pixel_format; + signal_format_t signal_format; + channel_num_t channel; +} video_source_t; + +VIDEO_API(P4(video_h), video_open(video_source_t video_source)); +VIDEO_API(bool, video_start(P4(video_h) handle, void* buf)); +VIDEO_API(bool, video_stop(P4(video_h) handle)); +VIDEO_API(bool, video_close(P4(video_h) handle)); + +// DISPLAY(LCD) +typedef void* P4(lcd_h); + +typedef enum { + DISPLAY_PIXELFORMAT_YCBCR422, + DISPLAY_PIXELFORMAT_RGB565, + DISPLAY_PIXELFORMAT_RGB888, + DISPLAY_PIXELFORMAT_ARGB8888, + DISPLAY_PIXELFORMAT_ARGB4444, + DISPLAY_PIXELFORMAT_MAX, +} display_pixel_format_t; + +typedef enum { + LCDTYPE_4_3INCH, + LCDTYPE_MAX, +} lcd_type_t; + +typedef enum { + LCDLAYER_0, + LCDLAYER_1, + LCDLAYER_2, + LCDLAYER_3, + LCDLAYER_MAX, +} lcd_layer_id_t; + +typedef struct { + lcd_layer_id_t id; + display_pixel_format_t buffer_format; + uint32_t pixel_bytes; + uint8_t* frame_buffer; +} lcd_layer_t; + +typedef struct { + lcd_type_t type; + + uint32_t width; + uint32_t height; +} lcd_t; + +DISPLAY_API(P4(lcd_h), lcd_open(lcd_t *lcd)); +DISPLAY_API(bool, lcd_close(P4(lcd_h) handle)); +DISPLAY_API(bool, lcd_start(P4(lcd_h) handle, lcd_layer_t lcd_layer)); +DISPLAY_API(bool, lcd_stop(P4(lcd_h) handle, lcd_layer_id_t id)); +DISPLAY_API(bool, lcd_update(P4(lcd_h) handle, lcd_layer_t lcd_layer)); + +// JPEG +typedef void* P4(jpeg_h); + +typedef enum { + JPEG_PIXELFORMAT_YCBCR422, /* encode, decode */ + JPEG_PIXELFORMAT_ARGB8888, /* decode */ + JPEG_PIXELFORMAT_RGB565, /* decode */ + JPEG_PIXELFORMAT_MAX, +} jpeg_pixel_format_t; + +typedef struct { + uint32_t width; + uint32_t height; + jpeg_pixel_format_t pixel_format; + uint32_t alpha; + + struct { + uint32_t len; + uint8_t* buf; + } src, dst; +} jpeg_convert_data_t; + +JPEG_API(int, jpeg_encode(jpeg_convert_data_t encode_data)); +JPEG_API(bool, jpeg_decode(jpeg_convert_data_t decode_data)); + +// GRAPHICS +typedef void* P4(graphics_h); + +GRAPHICS_API(P4(graphics_h), initFrameBuffer(char *buf, int width, int height, int format)); +GRAPHICS_API(int, deinitFrameBuffer(P4(graphics_h) handle)); +GRAPHICS_API(int, drawLine(P4(graphics_h) handle, int startX, int startY, int endX, int endY, uint32_t color)); +GRAPHICS_API(int, drawRect(P4(graphics_h) handle, int x, int y, int width, int height, uint32_t color, bool fill)); +GRAPHICS_API(int, drawArc(P4(graphics_h) handle, int centerX, int centerY, int radius, int startAngle, int endAngle, uint32_t color)); +GRAPHICS_API(int, drawCircle(P4(graphics_h) handle, int centerX, int centerY, int radius, uint32_t color, bool fill)); +GRAPHICS_API(int, drawEllipse(P4(graphics_h) handle, int centerX, int centerY, int radiusX, int radiusY, uint32_t color, bool fill)); +GRAPHICS_API(int, drawPolygon(P4(graphics_h) handle, int centerX, int centerY, int radius, int sides, uint32_t color, bool fill)); +GRAPHICS_API(int, drawText(P4(graphics_h) handle, char* text, int x, int y, int size, uint32_t color, uint32_t background)); +GRAPHICS_API(int, drawImage(P4(graphics_h) handle, char* image, int x, int y, int width, int height)); + +#undef GRAPHICS_API +#undef JPEG_API +#undef DISPLAY_API +#undef VIDEO_API + +#if !defined( POSIX4_ITSELF ) + + // functions + #define video_open P4(video_open) + #define video_start P4(video_start) + #define video_stop P4(video_stop) + #define video_close P4(video_close) + #define lcd_open P4(lcd_open) + #define lcd_close P4(lcd_close) + #define lcd_start P4(lcd_start) + #define lcd_stop P4(lcd_stop) + #define lcd_update P4(lcd_update) + #define jpeg_encode P4(jpeg_encode) + #define jpeg_decode P4(jpeg_decode) + + #define initFrameBuffer P4(initFrameBuffer) + #define deinitFrameBuffer P4(deinitFrameBuffer) + #define drawLine P4(drawLine) + #define drawRect P4(drawRect) + #define drawArc P4(drawArc) + #define drawCircle P4(drawCircle) + #define drawEllipse P4(drawEllipse) + #define drawPolygon P4(drawPolygon) + #define drawText P4(drawText) + #define drawImage P4(drawImage) + + // typedefs + #define video_h P4(video_h) + #define lcd_h P4(lcd_h) + #define jpeg_h P4(jpeg_h) + #define graphics_h P4(graphics_h) + +#endif // #if !defined( POSIX4_ITSELF ) + +#ifdef __cplusplus +} +#endif + +#ifdef __cplusplus + +namespace mbed { + + namespace video { + P4(video_h) open(video_source_t video_source); + bool close(P4(video_h) handle); + bool start(P4(video_h) handle, void* buf); + bool stop(P4(video_h) handle); + } // namespace video + + namespace lcd { + P4(lcd_h) open(lcd_t *lcd); + bool close(P4(lcd_h) handle); + bool start(P4(lcd_h) handle, lcd_layer_t lcd_layer); + bool stop(P4(lcd_h) handle, lcd_layer_id_t id); + bool update(P4(lcd_h) handle, lcd_layer_t id); + } // namespace lcd + + namespace jpeg { + int encode(jpeg_convert_data_t encode_data); + bool decode(jpeg_convert_data_t decode_data); + } // namespace jpeg + + namespace graphics { + P4(graphics_h) initFrameBuffer(char *buf, int width, int height, int format); + int deinitFrameBuffer(P4(graphics_h) handle); + int drawLine(P4(graphics_h) handle, int startX, int startY, int endX, int endY, uint32_t color); + int drawRect(P4(graphics_h) handle, int x, int y, int width, int height, uint32_t color, bool fill); + int drawArc(P4(graphics_h) handle, int centerX, int centerY, int radius, int startAngle, int endAngle, uint32_t color); + int drawCircle(P4(graphics_h) handle, int centerX, int centerY, int radius, uint32_t color, bool fill); + int drawEllipse(P4(graphics_h) handle, int centerX, int centerY, int radiusX, int radiusY, uint32_t color, bool fill); + int drawPolygon(P4(graphics_h) handle, int centerX, int centerY, int radius, int sides, uint32_t color, bool fill); + int drawText(P4(graphics_h) handle, char* text, int x, int y, int size, uint32_t color, uint32_t background); + int drawImage(P4(graphics_h) handle, char* image, int x, int y, int width, int height); + } // namespace graphics + +} // namespace mbed + +using namespace mbed; + +#endif + +#endif // #ifndef PERIPHERAL_IO_4MBED_INCL
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/iotjs/deps/posix/platform/mbedos5/posix4mbed.cpp Thu Jul 11 18:48:09 2019 +0900 @@ -0,0 +1,1646 @@ +/* Copyright 2017-present Renesas Electronics Corporation and other contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT 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 <string.h> +#include <stdarg.h> +#include <errno.h> +#include <assert.h> +#include <algorithm> +#include <string> +#include <iterator> +#include <vector> +#include <list> +#include <map> + +extern "C" { + //#include <unistd.h> + int close(int fd); + ssize_t read(int fd, void* buf, size_t count); + ssize_t write(int fd, const void* buf, size_t count); + off_t lseek(int fd, off_t offset, int whence); + int unlink(const char* pathname); +} // extern "C" + +#include <mbed.h> +#include "mbed_retarget.h" +#include "hal/us_ticker_api.h" +#include "posix4mbed.h" +#include "peripheral_io_4mbed.h" +#include "primitives.h" + +using namespace os::primitives; +#define SocketAddress os::primitives::SocketAddress + +#define NAME_STRINGIZER_(name) #name +#define NAME_STRINGIZER(name) NAME_STRINGIZER_(name) + +const struct P4(in6_addr) in6addr_any = {0}; + +namespace helper { + + #if defined(DEFAULT_WORKING_DIR) + std::string cwd_ = NAME_STRINGIZER(DEFAULT_WORKING_DIR); + #else // if defined(DEFAULT_WORKING_DIR) + std::string cwd_ = "/"; + #endif // if defined(DEFAULT_WORKING_DIR) + + std::string& cwd() { + return cwd_; + } + + int clear_errno() { + errno = 0; + return 0; + } + + int set_errno(int num) { + if( ENOSYS == num ) { + TRACE(INFO "ENOSYS ......"); + } + errno = num; + return -1; + } + + uint64_t time_in_usec() { + struct pack { + uint64_t usec; // in micro-seconds + uint64_t unix; // in micro-seconds + uint64_t tick; // in micro-seconds + }; + static pack last = {0}; + pack curr = {0}; + curr.unix = time( 0 ) * uint64_t( 1 * 1000 * 1000 ); + curr.tick = us_ticker_read() * 32 * 3 / 100; + + static bool first_time = true; + if( first_time || ( curr.tick < last.tick ) || ( curr.unix < last.unix ) ) { + first_time = false; + curr.usec = curr.unix; + } + else { + pack diff; + diff.unix = curr.unix - last.unix; + diff.tick = curr.tick - last.tick; + diff.usec = diff.tick; + + uint64_t range = ( 1 * 1000 * 1000 ) + diff.usec - diff.unix; + if( range <= 2 * 1000 * 1000 ) { + curr.usec = last.usec + diff.usec; + } + else { + curr.usec = curr.unix; + } + } + + last = curr; + return curr.usec; + } + + class lseeker { + int fd_; + P4(off_t) saved_; + public: + lseeker(int fd) : fd_(fd), saved_(-1) {} + bool go(P4(off_t) offset) { + saved_ = ::lseek( fd_, 0, SEEK_CUR ); + return ( 0 <= saved_ ) && ( 0 <= ::lseek( fd_, offset, SEEK_SET ) ); + } + bool back() { + return ( 0 <= saved_ ) && ( 0 <= ::lseek( fd_, saved_, SEEK_SET ) ); + } + }; + + ip_addr_t ip4addr(u8_t a, u8_t b, u8_t c, u8_t d) { + ip_addr_t rc = { ip_addr_t::IPv4, 0 }; + rc.value.bytes[0] = a; + rc.value.bytes[1] = b; + rc.value.bytes[2] = c; + rc.value.bytes[3] = d; + return rc; + } + + ip_addr_t ip6addr(u16_t a, u16_t b, u16_t c, u16_t d, u16_t e, u16_t f, u16_t g, u16_t h) { + ip_addr_t rc = { ip_addr_t::IPv6, 0 }; + rc.value.u16[0] = htons( a ); + rc.value.u16[1] = htons( b ); + rc.value.u16[2] = htons( c ); + rc.value.u16[3] = htons( d ); + rc.value.u16[4] = htons( e ); + rc.value.u16[5] = htons( f ); + rc.value.u16[6] = htons( g ); + rc.value.u16[7] = htons( h ); + return rc; + } + + ip_addr_t ip6addr(const u8_t bytes[]) { + ip_addr_t rc = { ip_addr_t::IPv6, 0 }; + memcpy( rc.value.bytes, bytes, sizeof( rc.value.bytes ) ); + return rc; + } + + ip_addr_t ipaddr(const nsapi_addr_t& na) { + TRACE(INFO "nsapi_addr.version=%d bytes[%d.%d.%d...]", na.version, na.bytes[0], na.bytes[1], na.bytes[2]); + switch( na.version ) + { + default: return { ip_addr_t::UNSPEC, 0 }; + case NSAPI_IPv4: return ip4addr( na.bytes[0], na.bytes[1], na.bytes[2], na.bytes[3] ); + case NSAPI_IPv6: return ip6addr( na.bytes ); + } + } + + inline ip_addr_t ipaddr_any(bool ipv6) { + return ipv6 ? ip6addr( 0,0,0,0,0,0,0,0 ) : ip4addr( 0,0,0,0 ); + } + + inline ip_addr_t ipaddr_loopback(bool ipv6) { + return ipv6 ? ip6addr( 0,0,0,0,0,0,0,1 ) : ip4addr( 127,0,0,1 ); + } + + Nic nic; + +} // namespace helper:: + +namespace os { namespace posix { namespace pthread { + + union thread_posix_raw { + P4(pthread_t) posix; + Thread* raw; + thread_posix_raw(P4(pthread_t) p) : posix( p ) {} + }; + + union func_posix_raw { + void* (*posix)(void*); + void (*raw)(void const*); + func_posix_raw(void* (*p)(void*)) : posix( p ) {} + }; + + union mutex_posix_raw { + P4(pthread_mutex_t) posix; + Mutex* raw; + mutex_posix_raw(P4(pthread_mutex_t)* p) : posix( *p ) {} + }; + + union condvar_posix_raw { + P4(pthread_cond_t) posix; + CondVar* raw; + condvar_posix_raw(P4(pthread_cond_t)* p) : posix( *p ) {} + }; + +}}} // namespace os::posix::pthread:: + + +namespace iotjs { namespace bugfix { + + nsapi_size_or_error_t send(TCPSocket& socket, const void* buf, P4(size_t) count) { + const char* top = static_cast<const char*>( buf ); + int remain = count; + while( 0 < remain ) { + nsapi_size_or_error_t rc = socket.send( top, remain ); + if( NSAPI_ERROR_WOULD_BLOCK == rc ) { + TRACE(INFO "socket.send(%p, %d) again", top, remain); + continue; + } + if( rc < 0 ) { + return rc; + } + remain -= rc; + top += rc; + } + return count; + } + +}} // namespace iotjs::bugfix:: + + +namespace os { namespace linux { namespace epoll { + + Semaphore poll_; + + class fd_builder { + Mutex mutex_; + int from_, to_; + std::vector< bool > using_; + public: + fd_builder( int from, int to ) + : mutex_(), from_( from ), to_( to ), using_( to - from + 1, false ) { + } + int allocate() { + lock_guard g( mutex_ ); + auto itr = std::find( using_.rbegin(), using_.rend(), false ); + if( itr == using_.rend() ) { + return -1; + } + *itr = true; + return from_ + std::distance( begin( using_ ), itr.base() ) - 1; + } + bool release( int fd ) { + lock_guard g( mutex_ ); + if( ( fd < from_ ) || ( to_ < fd ) ) { + return false; + } + using_[ fd - from_ ] = false; + return true; + } + } fd_builder_( 100, 250 ); // fd range[100, 250] + + class evt_counter { + Mutex mutex_; + int count_; + evt_counter( const evt_counter& ); + evt_counter& operator=( const evt_counter& ); + public: + evt_counter() : mutex_(), count_(0) {} + void add() { + mutex_.lock(); + count_ += 1; + poll_.release(); + mutex_.unlock(); + } + bool check() { + bool rc = false; + mutex_.lock(); + if( count_ > 0 ) { + rc = true; + TRACE(INFO "evt_counter : SOMETHING HAPPENED : %d", count_); + count_ -= 1; + } + mutex_.unlock(); + return rc; + } + }; + + typedef std::map<int, P4(poll_event)> poll_internal; + typedef std::map<int, poll_internal> EPollFDs; + EPollFDs epfds_; + inline bool isEPollFd(int fd) { return epfds_.find( fd ) != epfds_.end(); } + inline int newEPollFd(int flags) { int fd = fd_builder_.allocate(); if(0<fd) epfds_[ fd ].clear(); return fd; } + inline void removeEPollFd(int fd) { epfds_.erase( fd ); fd_builder_.release( fd ); } + inline poll_internal& getEPollInfo(int fd) { return epfds_[ fd ]; } + + typedef uint64_t eventfd_t; + typedef std::map<int, eventfd_t> EventFDs; + EventFDs evfds_; + inline bool isEventFd(int fd) { return evfds_.find( fd ) != evfds_.end(); } + inline int newEventFd(unsigned int initval) { int fd = fd_builder_.allocate(); if(0<fd) evfds_[ fd ] = initval; return fd; } + inline void removeEventFd(int fd) { evfds_.erase( fd ); fd_builder_.release( fd ); } + inline void resetEventFd(int fd) { evfds_[ fd ] = 0; } + inline void plusEventFd(int fd, eventfd_t value) { evfds_[ fd ] += value; } + inline eventfd_t& getEventFd(int fd) { return evfds_[ fd ]; } + + class sock_t { + enum { UNKNOWN, UDP, TCP, SRV } type_; + int shutdown_; + evt_counter events_; + UDPSocket udp_; + TCPSocket tcp_; + TCPServer srv_; + SocketAddress addr_; + sock_t( const sock_t& ); + sock_t& operator=( const sock_t& ); + public: + sock_t() : type_( UNKNOWN ), shutdown_( -1 ) {} + bool isUDP() const { return type_ == UDP; } + bool isTCP() const { return type_ == TCP; } + bool isSRV() const { return type_ == SRV; } + sock_t& asUDP() { type_ = UDP; return *this; } + sock_t& asTCP() { type_ = TCP; return *this; } + sock_t& asSRV() { type_ = SRV; return *this; } + UDPSocket& udp() { return udp_; } + TCPSocket& tcp() { return tcp_; } + TCPServer& srv() { return srv_; } + const SocketAddress& addr() const { return addr_; } + SocketAddress& addr() { return addr_; } + SocketAddress& addr(const P4(sockaddr)& addr) { return addr_ = SocketAddress::trans( addr ); } + int open(); + int attach(); + bool evt_check() { return events_.check(); } + void evt_add() { return events_.add(); } + int shutdown() const { return shutdown_; } + int shutdown(int how); + }; + typedef std::map<int, sock_t> SockFDs; + SockFDs sockfds_; + inline bool isSockFd(int fd) { return sockfds_.find( fd ) != sockfds_.end(); } + inline sock_t& getSock(int fd) { return sockfds_[ fd ]; } + inline sock_t& newSock(int fd) { return sockfds_[ fd ]; } + inline void removeSockFd(int fd) { sockfds_.erase( fd ); fd_builder_.release( fd ); } + inline bool isUdpSockFd(int fd) { return isSockFd( fd ) && getSock( fd ).isUDP(); } + inline bool isTcpSockFd(int fd) { return isSockFd( fd ) && getSock( fd ).isTCP(); } + inline bool isSrvSockFd(int fd) { return isSockFd( fd ) && getSock( fd ).isSRV(); } + + inline bool isRelatedFd(int fd) { return isEPollFd( fd ) || isEventFd( fd ) || isSockFd( fd ); } + + int eventfd_read(int fd, eventfd_t* value) { + TRACE(ENTER "eventfd_read(fd=%d, value=%p)", fd, value); + int rc = -1; + eventfd_t prev_counter = getEventFd( fd ); + if( prev_counter == 0 ) { + rc = helper::set_errno( EAGAIN ); // EFD_NONBLOCK + } + else { + *value = prev_counter; + resetEventFd( fd ); // ! EFD_SEMAPHORE + rc = helper::clear_errno(); + poll_.release(); // POLLOUT + } + TRACE(LEAVE "eventfd_read(fd=%d, value={%llu}%llu->%llu) = %d(errno:%d)", fd, *value, prev_counter, getEventFd( fd ), rc, errno); + return rc; + } + + int eventfd_write(int fd, eventfd_t value) { + TRACE(ENTER "eventfd_write(fd=%d, value=%llu)", fd, value); + int rc = -1; + eventfd_t prev_counter = getEventFd( fd ); + if( value + 1 == 0 ) { + rc = helper::set_errno( EINVAL ); + } + else { + if( prev_counter + value < prev_counter ) { + rc = helper::set_errno( EAGAIN ); // EFD_NONBLOCK + } + else { + plusEventFd( fd, value ); + rc = helper::clear_errno(); + poll_.release(); // POLLIN + } + } + TRACE(LEAVE "eventfd_write(fd=%d, value=%llu->%llu) = %d(errno:%d)", fd, prev_counter, getEventFd( fd ), rc, errno); + return rc; + } + + P4(ssize_t) socketfd_read(int fd, void* buf, P4(size_t) count) { + if( isTcpSockFd( fd ) ) { + TRACE(INFO "socketfd_read() with TCP sock fd=%d", fd); + nsapi_size_or_error_t ret = 0; + sock_t& sock = getSock( fd ); + int shutdown = sock.shutdown(); + if( shutdown == SHUT_RD || shutdown == SHUT_RDWR ) { + TRACE(INFO "socketfd_read() with TCP sock fd=%d shutdown=%d", fd, shutdown); + ret = 0; + } + else { + TCPSocket& socket = sock.tcp(); + ret = socket.recv( buf, count ); + } + TRACE(INFO "socketfd_read() with TCP sock fd=%d nsapi_error=%d", fd, ret); + if( NSAPI_ERROR_WOULD_BLOCK == ret ) { + return helper::set_errno( EWOULDBLOCK ); + } + else if( ret < 0 ) { + return helper::set_errno( EINVAL ); + } + return ret; + } + else if( isSrvSockFd( fd ) ) { + TRACE(INFO "socketfd_read() with SRV sock fd=%d", fd); + return helper::set_errno( EINVAL ); + } + else if( isUdpSockFd( fd ) ) { + TRACE(INFO "socketfd_read() with UDP sock fd=%d", fd); + return helper::set_errno( EINVAL ); + } + return helper::set_errno( ENOSYS ); + } + + P4(ssize_t) socketfd_write(int fd, const void* buf, P4(size_t) count) { + if( isTcpSockFd( fd ) ) { + TRACE(INFO "socketfd_write() with TCP sock fd=%d first=%02Xh count=%d", fd, *((char*)buf), count); + nsapi_size_or_error_t ret = 0; + sock_t& sock = getSock( fd ); + int shutdown = sock.shutdown(); + if( shutdown == SHUT_WR || shutdown == SHUT_RDWR ) { + TRACE(INFO "socketfd_write() with TCP sock fd=%d shutdown=%d", fd, shutdown); + ret = 0; + } + else { + TCPSocket& socket = sock.tcp(); + ret = iotjs::bugfix::send( socket, buf, count ); // socket.send( buf, count ); + } + TRACE(INFO "socketfd_write() with TCP sock fd=%d first=%02Xh count=%d nsapi_error=%d", fd, *((char*)buf), count, ret); + if( NSAPI_ERROR_WOULD_BLOCK == ret ) { + return helper::set_errno( EWOULDBLOCK ); + } + if( ret < 0 ) { + return helper::set_errno( EINVAL ); + } + return ret; + } + else if( isSrvSockFd( fd ) ) { + TRACE(INFO "socketfd_write() with SRV sock fd=%d", fd); + return helper::set_errno( EINVAL ); + } + else if( isUdpSockFd( fd ) ) { + TRACE(INFO "socketfd_write() with UDP sock fd=%d", fd); + return helper::set_errno( EINVAL ); + } + return helper::set_errno( ENOSYS ); + } + + union ptr_void_evfd { + const void* cv; + void* v; + eventfd_t* evfd; + }; + + P4(ssize_t) read(int fd, void* buf, P4(size_t) count) { + if( isEventFd( fd ) ) { + if( count < sizeof( eventfd_t ) ) { + return helper::set_errno( EINVAL ); + } + ptr_void_evfd ptr; + ptr.v = buf; + if( eventfd_read( fd, ptr.evfd ) ) { + return -1; + } + return sizeof( eventfd_t ); + } + else if( isSockFd( fd ) ) { + return socketfd_read( fd, buf, count ); + } + TRACE(INFO "epoll::read() with wrong fd=%d", fd); + return helper::set_errno( EINVAL ); + } + + P4(ssize_t) write(int fd, const void* buf, P4(size_t) count) { + if( isEventFd( fd ) ) { + if( count < sizeof( eventfd_t ) ) { + return helper::set_errno( EINVAL ); + } + ptr_void_evfd ptr; + ptr.cv = buf; + if( eventfd_write( fd, *ptr.evfd ) ) { + return -1; + } + return sizeof( eventfd_t ); + } + else if( isSockFd( fd ) ) { + return socketfd_write( fd, buf, count ); + } + TRACE(INFO "epoll::write() with wrong fd=%d", fd); + return helper::set_errno( EINVAL ); + } + + int close(int fd) { + if( isEPollFd( fd ) ) { + removeEPollFd( fd ); + return helper::clear_errno(); + } + else if( isEventFd( fd ) ) { + removeEventFd( fd ); + poll_.release(); // POLLHUP + return helper::clear_errno(); + } + else if( isSockFd( fd ) ) { + removeSockFd( fd ); + return helper::clear_errno(); + } + TRACE(INFO "epoll::close() with wrong fd=%d", fd); + return helper::set_errno( ENOSYS ); + } + + int sock_t::open() { + Socket* socket = 0; + if( isSRV() ) { socket = &srv(); } + else if( isTCP() ) { socket = &tcp(); } + else if( isUDP() ) { socket = &udp(); } + else { + return helper::set_errno( EINVAL ); + } + EthernetInterface& stack = helper::nic.iface(); + socket->sigio( callback( &events_, &evt_counter::add ) ); + nsapi_error_t ret = socket->open( &stack ); + if( ret < 0 ) { + TRACE(INFO "sock Socket::open()={%d}", ret); + return helper::set_errno( ENFILE ); + } + socket->set_blocking( false ); + return helper::clear_errno(); + } + + int sock_t::attach() { + Socket* socket = 0; + if( isTCP() ) { socket = &tcp(); } + else { + return helper::set_errno( ENFILE ); + } + socket->sigio( callback( &events_, &evt_counter::add ) ); + socket->set_blocking( false ); + evt_add(); + evt_add(); + return helper::clear_errno(); + } + + int sock_t::shutdown(int how) { + shutdown_ = how; + bool ret = ( tcp().send( NAME_STRINGIZER(VIRTUAL_FIN_PACKET), 1 + how ) == 1 + how ); + evt_add(); + return ret ? 0 : -1; + } + +}}} // namespace os::linux::epoll:: + + +namespace os { namespace bugfix { + + typedef struct stat stat_t; + + int stat(const char* pathname, stat_t* buf) { + if( !pathname || !pathname[0] ) { + return helper::set_errno( ENOENT ); + } + int rc = ::stat( pathname, buf ); + if( rc < 0 && errno == 0 ) { + return helper::set_errno( ENOENT ); + } + return rc; + } + + int fstat(int fd, stat_t* buf) { + if( fd < 0 ) { + return helper::set_errno( EBADF ); + } + if( fd < 3 ) { + buf->st_mode = S_IFCHR; + return helper::clear_errno(); + } + struct { + int operator()(int fd) { + int cur = ::lseek( fd, 0, SEEK_CUR ); + int end = ::lseek( fd, 0, SEEK_END ); + ::lseek( fd, cur, SEEK_SET ); + return end; + } + } file_size; + int size = file_size( fd ); + if( size < 0 ) { + return helper::set_errno( EBADF ); + } + buf->st_mode = S_IFREG; + buf->st_size = size; + return helper::clear_errno(); + } + + int open(const std::string& pathname, va_list args) { + if( pathname == "/" ) { + return helper::set_errno( ENOENT ); + } + else if( pathname == "/dev/null" ) { + return helper::set_errno( ENOENT ); + } + return ::open( pathname.c_str(), va_arg(args, int), va_arg(args, mode_t) ); + } + + int close(int fd) { + if( fd < 0 ) { + return helper::set_errno( EBADF ); + } + return ::close( fd ); + } + +}} // namespace os::bugfix:: + + +#define NOT_IMPL(detail) detail { return 0; } + +void os::debug::trace(const char* fmt, ...) +{ +#if defined(DEBUG_POSIX_BRIDGE) + static struct { + int sequence; + Mutex mutex; + std::map< void*, int > threads; + } trace_; + + int saved_errno = errno; + trace_.mutex.lock(); + + ++ trace_.sequence; + void* id = Thread::gettid(); + if( trace_.threads.find( id ) == trace_.threads.end() ) { + trace_.threads[ id ] = trace_.threads.size() - 1; + } + + printf( "--- POSIX[%3u][thr%d] %*s", + trace_.sequence % 1000, trace_.threads[ id ], trace_.threads[ id ] * 3, "" ); + va_list args; + va_start( args, fmt ); + vfprintf( stdout, fmt, args ); + va_end( args ); + printf( "\n" ); + + trace_.mutex.unlock(); + errno = saved_errno; +#endif // #if defined(DEBUG_POSIX_BRIDGE) +} + +int os::posix::obsolete::gettimeofday(P4(timeval)* tv, timezone* tz) +{ + if( !tv && !tz ) { + return helper::set_errno( EFAULT ); + } + if( tv ) { + P4(timespec) tp; + if( clock::gettime( 123, &tp ) < 0 ) { + return helper::set_errno( EFAULT ); + } + tv->tv_sec = tp.tv_sec; + tv->tv_usec = tp.tv_nsec / 1000; + } + if( tz ) { + tz->tz_minuteswest = 0; + tz->tz_dsttime = 0; + } + return helper::clear_errno(); +} + +char* os::posix::getcwd(char* buf, P4(size_t) size) +{ + if( !buf || size <= helper::cwd().size() ) { + helper::set_errno( EFAULT ); + return 0; + } + return strcpy( buf, helper::cwd().c_str() ); +} + +int os::posix::chdir(const char* path) +{ + helper::cwd() = path; + return helper::clear_errno(); +} + +NOT_IMPL( int os::posix::fdatasync(int fd) ); +NOT_IMPL( int os::posix::fsync(int fd) ); +NOT_IMPL( int os::posix::ftruncate(int fd, P4(off_t) length) ); + +int os::posix::scandir(const char* dirp, P4(dirent)*** namelist, int (*filter)(const P4(dirent)*), int (*compar)(const P4(dirent)**, const P4(dirent)**)) +{ + DIR* dir = opendir( dirp ); + if( !dir ) { + return helper::set_errno( ENOENT ); + } + + std::list<P4(dirent)*> items; + for( dirent* entry = readdir( dir ); entry; entry = readdir( dir ) ) { + P4(dirent) temp; + strcpy( temp.d_name, entry->d_name ); + temp.d_type = entry->d_type; + if( filter && !(*filter)( &temp ) ) { + continue; + } + P4(dirent)* item = static_cast<P4(dirent)*>( malloc( sizeof( P4(dirent) ) ) ); + if( !item ) { + std::for_each( items.begin(), items.end(), free ); + return helper::set_errno( ENOMEM ); + } + *item = temp; + items.push_back( item ); + } + closedir( dir ); + + P4(dirent)** names = 0; + P4(size_t) count = items.size(); + if( count ) { + P4(size_t) bytes = count * sizeof( P4(dirent)* ); + names = static_cast<P4(dirent)**>( malloc( bytes ) ); + if( !names ) { + std::for_each( items.begin(), items.end(), free ); + return helper::set_errno( ENOMEM ); + } + std::copy( items.begin(), items.end(), names ); + + if( count && compar ) { + union { + int (*param)(const P4(dirent)**, const P4(dirent)**); + int (*qsort)(const void*, const void*); + } func; + func.param = compar; + qsort( names, count, sizeof( P4(dirent)* ), func.qsort ); + } + } +#if defined(DEBUG_POSIX_BRIDGE) + for( P4(size_t) i = 0; i < count; ++ i ) { + TRACE(INFO "scandir[%u]={%s}", i, names[ i ]->d_name ); + } +#endif // #if defined(DEBUG_POSIX_BRIDGE) + + *namelist = names; + return count; +} + +NOT_IMPL( int os::posix::utime(const char* filename, const P4(utimbuf)* times) ); +NOT_IMPL( int os::posix::utimes(const char* filename, const P4(timeval) times[2]) ); + +P4(ssize_t) os::posix::pread(int fd, void* buf, P4(size_t) count, P4(off_t) offset) +{ + helper::lseeker seeker( fd ); + if( !seeker.go( offset ) ) { + return -1; + } + P4(ssize_t) rc = ::read( fd, buf, count ); + return seeker.back() ? rc : -1; +} + +P4(ssize_t) os::posix::pwrite(int fd, const void* buf, P4(size_t) count, P4(off_t) offset) +{ + helper::lseeker seeker( fd ); + if( !seeker.go( offset ) ) { + return -1; + } + P4(ssize_t) rc = ::write( fd, buf, count ); + return seeker.back() ? rc : -1; +} + +NOT_IMPL( P4(ssize_t) os::posix::readv(int fd, const P4(iovec)* iov, int iovcnt) ); +NOT_IMPL( P4(ssize_t) os::posix::writev(int fd, const P4(iovec)* iov, int iovcnt) ); +NOT_IMPL( int os::posix::utimensat(int dirfd, const char* pathname, const P4(timespec) times[2], int flags) ); + +int os::posix::clock::getres(P4(clockid_t) clk_id, P4(timespec)* res) +{ + if( !res ) { + return helper::set_errno( EFAULT ); + } + res->tv_sec = 0; + res->tv_nsec = 1 * 1000 * 1000; // 1 millisecond + return helper::clear_errno(); +} + +int os::posix::clock::gettime(P4(clockid_t) clk_id, P4(timespec)* tp) +{ + if( !tp ) { + return helper::set_errno( EFAULT ); + } + uint64_t msec = helper::time_in_usec() / 1000; + tp->tv_sec = static_cast< time_t >( msec / 1000 ); + msec %= 1000; + tp->tv_nsec = static_cast< long >( msec * 1000 * 1000 ); // in nano-seconds + return helper::clear_errno(); +} + +int os::posix::pthread::create(P4(pthread_t)* thread, P4(pthread_attr_t)* attr, void* (*start_routine)(void*), void* arg) +{ + if( !thread ) { + return EINVAL; + } + func_posix_raw func( start_routine ); + const uint32_t stack_size = 16 * 1024; + Thread* thr = new Thread( osPriorityNormal, stack_size ); + *thread = thr; + thr->start( callback( func.raw, arg ) ); + return 0; +} + +int os::posix::pthread::join(P4(pthread_t) thread, void** retval) +{ + if( !thread ) { + return EINVAL; + } + thread_posix_raw thr( thread ); + thr.raw->join(); + return 0; +} + +int os::posix::pthread::once(P4(pthread_once_t)* once_control, void (*init_routine)(void)) +{ + if( once_control && *once_control == PTHREAD_ONCE_INIT ) { + if( init_routine ) { + (*init_routine)(); + } + *once_control = ~PTHREAD_ONCE_INIT; + } + return 0; +} + +NOT_IMPL( int os::posix::pthread::sigmask(int how, const P4(sigset_t)* set, P4(sigset_t)* oldset) ); +NOT_IMPL( int os::posix::pthread::attr::destroy(P4(pthread_attr_t)* attr) ); + +int os::posix::pthread::cond::destroy(P4(pthread_cond_t)* cond) +{ + if( !cond ) { + return EBUSY; + } + condvar_posix_raw condvar( cond ); + delete condvar.raw; + return 0; +} + +int os::posix::pthread::cond::init(P4(pthread_cond_t)* cond, P4(pthread_condattr_t)* cond_attr) +{ + if( cond ) { + *cond = new CondVar; + } + return 0; +} + +int os::posix::pthread::cond::signal(P4(pthread_cond_t)* cond) +{ + if( cond ) { + condvar_posix_raw condvar( cond ); + condvar.raw->notify_one(); + } + return 0; +} + +int os::posix::pthread::cond::wait(P4(pthread_cond_t)* cond, P4(pthread_mutex_t)* mutex) +{ + if( cond ) { + condvar_posix_raw condvar( cond ); + condvar.raw->wait( mutex ); + } + return 0; +} + +NOT_IMPL( int os::posix::pthread::condattr::destroy(P4(pthread_condattr_t)* attr) ); +NOT_IMPL( int os::posix::pthread::condattr::init(P4(pthread_condattr_t)* attr) ); +NOT_IMPL( int os::posix::pthread::condattr::setclock(P4(pthread_condattr_t)* attr, P4(clockid_t) clock_id) ); + +int os::posix::pthread::mutex::destroy(P4(pthread_mutex_t)* mutex) +{ + if( !mutex ) { + return EBUSY; + } + mutex_posix_raw mtx( mutex ); + delete mtx.raw; + return 0; +} + +int os::posix::pthread::mutex::init(P4(pthread_mutex_t)* mutex, const P4(pthread_mutexattr_t)* mutexattr) +{ + if( mutex ) { + *mutex = new Mutex; + } + return 0; +} + +int os::posix::pthread::mutex::lock(P4(pthread_mutex_t)* mutex) +{ + if( !mutex ) { + return EINVAL; + } + mutex_posix_raw mtx( mutex ); + mtx.raw->lock(); + return 0; +} + +int os::posix::pthread::mutex::unlock(P4(pthread_mutex_t)* mutex) +{ + if( !mutex ) { + return EINVAL; + } + mutex_posix_raw mtx( mutex ); + mtx.raw->unlock(); + return 0; +} + +NOT_IMPL( int os::posix::pthread::rwlock::destroy(P4(pthread_rwlock_t)* rwlock) ); +NOT_IMPL( int os::posix::pthread::rwlock::init(P4(pthread_rwlock_t)* rwlock, const P4(pthread_rwlockattr_t)* attr) ); +NOT_IMPL( int os::posix::pthread::rwlock::rdlock(P4(pthread_rwlock_t)* rwlock) ); +NOT_IMPL( int os::posix::pthread::rwlock::unlock(P4(pthread_rwlock_t)* rwlock) ); + +int os::posix::sock::accept(int sockfd, P4(sockaddr)* addr, P4(socklen_t)* addrlen) +{ + return P4(accept4)( sockfd, addr, addrlen, 0 ); +} + +int os::posix::sock::bind(int sockfd, const P4(sockaddr)* addr, P4(socklen_t) addrlen) +{ + if( addr->sa_family == AF_INET ) { + if( linux::epoll::isUdpSockFd( sockfd ) ) { + linux::epoll::sock_t& sock = linux::epoll::getSock( sockfd ); + sock.addr( *addr ); + TRACE(INFO "bind addr={%s:%d}", sock.addr().get_ip_address(), sock.addr().get_port()); + sock.udp().bind( sock.addr() ); + sock.evt_add(); + sock.evt_add(); + return helper::clear_errno(); + } + else if( linux::epoll::isTcpSockFd( sockfd ) ) { + linux::epoll::sock_t& sock = linux::epoll::getSock( sockfd ).asSRV(); + if( sock.open() < 0 ) { + return helper::set_errno( EINVAL ); + } + sock.addr( *addr ); + TRACE(INFO "bind addr={%s:%d}", sock.addr().get_ip_address(), sock.addr().get_port()); + sock.srv().bind( sock.addr() ); + return helper::clear_errno(); + } + } + return helper::set_errno( EINVAL ); +} + +int os::posix::sock::connect(int sockfd, const P4(sockaddr)* addr, P4(socklen_t) addrlen) +{ + if( !linux::epoll::isTcpSockFd( sockfd ) ) { + return helper::set_errno( EBADF ); + } + linux::epoll::sock_t& sock = linux::epoll::getSock( sockfd ); + sock.addr( *addr ); + TRACE(INFO "connecting to addr={%s:%d}", sock.addr().get_ip_address(), sock.addr().get_port()); + nsapi_error_t ret = sock.tcp().connect( sock.addr() ); + if( ret < 0 ) { + TRACE(INFO "TCPSocket.connect() returned=%d", ret); + return helper::set_errno( EFAULT ); + } +sock.evt_add(); + return helper::clear_errno(); +} + +void os::posix::sock::freeaddrinfo(P4(addrinfo)* res) +{ + while( res ) { + P4(addrinfo)* next = res->ai_next; + free( res ); + res = next; + } +} + +int os::posix::sock::getaddrinfo(const char* node, const char* service, const P4(addrinfo)* hints, P4(addrinfo)** res) +{ + if( !res ) { + return EAI_FAIL; + } + *res = NULL; + + if( !node && !service ) { + return EAI_NONAME; + } + + int ai_family = AF_UNSPEC; + if( hints ) { + ai_family = hints->ai_family; + switch( ai_family ) { + default: return EAI_FAMILY; + case AF_UNSPEC: + case AF_INET: + case AF_INET6: break; + } + } + + int port_host = 0; + if( service ) { + port_host = atoi( service ); + if( (port_host <= 0) || (0xFFFF < port_host) ) { + return EAI_SERVICE; + } + } + + ip_addr_t addr = { ip_addr_t::UNSPEC, 0 }; + if( node ) { + SocketAddress sa; + nsapi_error_t err = helper::nic.iface().gethostbyname( node, &sa ); + if( err ) { + TRACE(INFO "nsapi_error_t err=%d", err); + return EAI_NONAME; + } + addr = helper::ipaddr( sa.get_addr() ); + if( (addr.v6() && ai_family == AF_INET ) || + (addr.v4() && ai_family == AF_INET6) ) { + return EAI_NONAME; + } + } + else { + if( hints && ( hints->ai_flags & AI_PASSIVE ) ) { + addr = helper::ipaddr_any( ai_family == AF_INET6 ); + } + else { + addr = helper::ipaddr_loopback( ai_family == AF_INET6 ); + } + } + if( !addr.valid() ) { + TRACE(INFO "addr is not valid"); + return EAI_FAIL; + } + + struct response_t { + P4(addrinfo) ai; + P4(sockaddr_storage) sas; + char canonname[1]; + }; + + P4(size_t) total_size = sizeof( response_t ) + ( node ? strlen( node ) : 0 ); + void* buf = malloc( total_size ); + if( !buf ) { + return EAI_MEMORY; + } + memset( buf, 0, total_size ); + + response_t& response = *static_cast< response_t* >( buf ); + P4(addrinfo)& ai = response.ai; + P4(sockaddr_storage)& sas = response.sas; + char* canonname = response.canonname; + + helper::sockaddrs addrs; + addrs.sas = &sas; + if( addr.v4() ) { + P4(sockaddr_in)& sa4 = *addrs.sa4; + sa4.sin_addr = addr.value.ip4; + sa4.sin_family = AF_INET; + sa4.sin_len = sizeof( P4(sockaddr_in) ); + sa4.sin_port = htons( port_host ); + + ai.ai_family = AF_INET; + } + else { + P4(sockaddr_in6)& sa6 = *addrs.sa6; + sa6.sin6_addr = addr.value.ip6; + sa6.sin6_family = AF_INET6; + sa6.sin6_len = sizeof( P4(sockaddr_in6) ); + sa6.sin6_port = htons( port_host ); + + ai.ai_family = AF_INET6; + } + + if( hints ) { + ai.ai_socktype = hints->ai_socktype; + ai.ai_protocol = hints->ai_protocol; + } + if( node ) { + strcpy( canonname, node ); + ai.ai_canonname = canonname; + } + ai.ai_addrlen = sizeof( P4(sockaddr_storage) ); + ai.ai_addr = addrs.sa; + + *res = &ai; + return 0; +} + +int os::posix::sock::getsockname(int sockfd, P4(sockaddr)* addr, P4(socklen_t)* addrlen) +{ + if( !addr || !addrlen ) { + return helper::set_errno( EFAULT ); + } + if( !linux::epoll::isSockFd( sockfd ) ) { + return helper::set_errno( EBADF ); + } + linux::epoll::sock_t& sock = linux::epoll::getSock( sockfd ); + TRACE(INFO "getsockname bound={%s:%d}", sock.addr().get_ip_address(), sock.addr().get_port()); + return SocketAddress::trans( sock.addr(), addr, addrlen ); +} + +int os::posix::sock::getsockopt(int sockfd, int level, int optname, void* optval, P4(socklen_t)* optlen) +{ + if( !optval || !optlen ) { + return helper::set_errno( EFAULT ); + } + if( level != SOL_SOCKET ) { + return helper::set_errno( ENOPROTOOPT ); + } + if( !linux::epoll::isSockFd( sockfd ) ) { + return helper::set_errno( EBADF ); + } + + union { void* optval; int* as_int; } ov; + ov.optval = optval; + if( optname == SO_ERROR ) { + int& error = *ov.as_int; + P4(socklen_t)& size = *optlen; + error = 0; + size = sizeof( int ); + return helper::clear_errno(); + } + else if( optname == SO_TYPE ) { + int& type = *ov.as_int; + P4(socklen_t)& size = *optlen; + type = SOCK_STREAM; + size = sizeof( int ); + return helper::clear_errno(); + } + + return helper::set_errno( ENOPROTOOPT ); +} + +uint32_t os::posix::sock::htonl(uint32_t hostlong) +{ + return helper::htonl( hostlong ); +} + +uint16_t os::posix::sock::htons(uint16_t hostshort) +{ + return helper::htons( hostshort ); +} + +NOT_IMPL( unsigned int os::posix::sock::if_nametoindex(const char* ifname) ); + +int os::posix::sock::listen(int sockfd, int backlog) +{ + if( !linux::epoll::isSrvSockFd( sockfd ) ) { + return helper::set_errno( EOPNOTSUPP ); + } + nsapi_error_t ret = linux::epoll::getSock( sockfd ).srv().listen( backlog ); + if( ret < 0 ) { + TRACE(INFO "TCPServer::listen()=%d", ret); + return helper::set_errno( EBADF ); + } + return helper::clear_errno(); +} + +uint16_t os::posix::sock::ntohs(uint16_t netshort) +{ + return helper::ntohs( netshort ); +} + +P4(ssize_t) os::posix::sock::recvmsg(int sockfd, P4(msghdr)* msg, int flags) +{ + if( !linux::epoll::isUdpSockFd( sockfd ) ) { + return helper::set_errno( EINVAL ); + } + TRACE(INFO "msg.msg_namelen={%lu}", msg->msg_namelen); // P4(sockaddr) length + TRACE(INFO "msg.msg_name={%p}", msg->msg_name); // P4(sockaddr) * + TRACE(INFO "msg.msg_iovlen={%d}", msg->msg_iovlen); + TRACE(INFO "msg.msg_iov={%p}", msg->msg_iov); + TRACE(INFO "msg.msg_controllen={%lu}", msg->msg_controllen); + TRACE(INFO "msg.msg_control={%p}", msg->msg_control); + TRACE(INFO "msg.msg_flags={%d}", msg->msg_flags); + + linux::epoll::sock_t& sock = linux::epoll::getSock( sockfd ); + P4(iovec)* iov = msg->msg_iov; + SocketAddress sa; + P4(ssize_t) recv = 0; + for( int x = 0; x < msg->msg_iovlen; ++ x, ++ iov ) { + TRACE(INFO "iov.iov_len={%u}", iov->iov_len); + TRACE(INFO "iov.iov_base={%p}", iov->iov_base); + nsapi_size_or_error_t ret = sock.udp().recvfrom( &sa, iov->iov_base, iov->iov_len ); + if( NSAPI_ERROR_WOULD_BLOCK == ret ) { + return helper::set_errno( EWOULDBLOCK ); + } + if( ret < 0 ) { + TRACE(INFO "UDPSocket::recvfrom()=%d", ret); + return helper::set_errno( EINVAL ); + } + linux::epoll::poll_.release(); // POLLxx + recv += ret; + } + + if( msg->msg_name ) { + TRACE(INFO "recvmsg from={%s:%d}", sa.get_ip_address(), sa.get_port()); + if( SocketAddress::trans( sa, msg->msg_name, &msg->msg_namelen ) < 0 ) { + return helper::set_errno( EINVAL ); + } + } + return recv; +} + +P4(ssize_t) os::posix::sock::sendmsg(int sockfd, const P4(msghdr)* msg, int flags) +{ + if( !linux::epoll::isUdpSockFd( sockfd ) ) { + return helper::set_errno( EINVAL ); + } + + TRACE(INFO "msg.msg_namelen={%lu}", msg->msg_namelen); // P4(sockaddr) length + TRACE(INFO "msg.msg_name={%p}", msg->msg_name); // P4(sockaddr) * + TRACE(INFO "msg.msg_iovlen={%d}", msg->msg_iovlen); + TRACE(INFO "msg.msg_iov={%p}", msg->msg_iov); + TRACE(INFO "msg.msg_controllen={%lu}", msg->msg_controllen); + TRACE(INFO "msg.msg_control={%p}", msg->msg_control); + + P4(sockaddr)& ai = *static_cast< P4(sockaddr)* >( msg->msg_name ); + SocketAddress sa = SocketAddress::trans( ai ); + TRACE(INFO "sendmsg to={%s:%d}", sa.get_ip_address(), sa.get_port()); + + linux::epoll::sock_t& sock = linux::epoll::getSock( sockfd ); + P4(iovec)* iov = msg->msg_iov; + P4(ssize_t) sent = 0; + for( int x = 0; x < msg->msg_iovlen; ++ x, ++ iov ) { + TRACE(INFO "iov.iov_len={%u}", iov->iov_len); + TRACE(INFO "iov.iov_base={%p}", iov->iov_base); + sent += sock.udp().sendto( sa, iov->iov_base, iov->iov_len ); + } + return sent; +} + +NOT_IMPL( int os::posix::sock::setsockopt(int sockfd, int level, int optname, const void* optval, P4(socklen_t) optlen) ); + +int os::posix::sock::shutdown(int sockfd, int how) +{ + if( linux::epoll::isTcpSockFd( sockfd ) ) { + linux::epoll::sock_t& socket = linux::epoll::getSock( sockfd ); + return socket.shutdown( how ); + } + return 0; +} + +int os::posix::sock::socket(int domain, int type, int protocol) +{ + if( domain != AF_INET ) { + TRACE(INFO "domain=unknown"); + return helper::set_errno( EINVAL ); + } + + using namespace os::linux::epoll; + int new_fd = fd_builder_.allocate(); + if( new_fd < 0 ) { + return helper::set_errno( ENFILE ); + } + + TRACE(INFO "domain=AF_INET"); + if( type == SOCK_STREAM ) { + TRACE(INFO "type=SOCK_STREAM"); + if( linux::epoll::newSock( new_fd ).asTCP().open() < 0 ) { + fd_builder_.release( new_fd ); + return helper::set_errno( ENFILE ); + } + } + else if( type == SOCK_DGRAM ) { + TRACE(INFO "type=SOCK_DGRAM"); + if( linux::epoll::newSock( new_fd ).asUDP().open() < 0 ) { + fd_builder_.release( new_fd ); + return helper::set_errno( ENFILE ); + } + } + else { + TRACE(INFO "type=unknown"); + fd_builder_.release( new_fd ); + return helper::set_errno( EINVAL ); + } + + return new_fd; +} + +int os::posix::sys::nanosleep(const P4(timespec)* req, P4(timespec)* rem) +{ + double sec = req->tv_sec + req->tv_nsec / double( 1 * 1000 * 1000 * 1000 ); + wait( sec ); + return helper::clear_errno(); +} + +NOT_IMPL( int os::posix::sys::pipe(int pipefd[2]) ); +NOT_IMPL( long os::posix::sys::sysconf(int name) ); + + +NOT_IMPL( P4(ssize_t) os::linux::preadv(int fd, const P4(iovec)* iov, int iovcnt, P4(off_t) offset) ); +NOT_IMPL( P4(ssize_t) os::linux::pwritev(int fd, const P4(iovec)* iov, int iovcnt, P4(off_t) offset) ); + +int os::linux::epoll::create(int size) +{ + return P4(epoll_create1)( 0 ); +} + +int os::linux::epoll::create1(int flags) +{ // flags: EPOLL_CLOEXEC=0x00080000 + return newEPollFd( flags ); +} + +int os::linux::epoll::ctl(int epfd, int op, int fd, P4(poll_event)* event) +{ + if( !isEPollFd( epfd ) ) { + return helper::set_errno( EBADF ); + } + + poll_internal& pi = getEPollInfo( epfd ); + if( op == POLL_CTL_ADD ) { + if( pi.find( fd ) != pi.end() ) { + return helper::set_errno( EEXIST ); + } + TRACE(INFO "epoll_ctl ADD fd=%d", fd); + P4(poll_event) ev = *event; + //ev.events |= POLLHUP; + //ev.events |= POLLERR; + pi[ fd ] = ev; // add + return helper::clear_errno(); + } + else if( op == POLL_CTL_MOD ) { + poll_internal::iterator itr = pi.find( fd ); + if( itr == pi.end() ) { + return helper::set_errno( ENOENT ); + } + TRACE(INFO "epoll_ctl MOD fd=%d", fd); + P4(poll_event) ev = *event; + //ev.events |= POLLHUP; + //ev.events |= POLLERR; + itr->second = ev; // modify + return helper::clear_errno(); + } + else if( op == POLL_CTL_DEL ) { + poll_internal::iterator itr = pi.find( fd ); + if( itr == pi.end() ) { + return helper::set_errno( ENOENT ); + } + TRACE(INFO "epoll_ctl DEL fd=%d", fd); + pi.erase( itr ); // delete + return helper::clear_errno(); + } + return helper::set_errno( EINVAL ); +} + +int os::linux::epoll::pwait(int epfd, P4(poll_event)* events, int maxevents, int timeout, const P4(sigset_t)* sigmask) +{ + if( !isEPollFd( epfd ) || maxevents <= 0 ) { + return helper::set_errno( EINVAL ); + } + + for(;;) { + if( !poll_.wait( timeout ) ) { + break; // timeout + } + + int candidate = 0; + + const poll_internal& pi = getEPollInfo( epfd ); + poll_internal::const_iterator citr = pi.begin(); + for( ; citr != pi.end() && candidate < maxevents; ++ citr ) { + int evfd = citr->first; + uint32_t polling_events = citr->second.events; + + uint32_t event_mask = 0; + if( isEventFd( evfd ) ) { + eventfd_t counter = getEventFd( evfd ); + if( counter ) event_mask = POLLIN; + else event_mask = POLLOUT; + } + else if( isSrvSockFd( evfd ) ) { + if( getSock( evfd ).evt_check() ) { + TRACE(INFO "epoll_wait socketfd=%d events=0x%08lX", evfd, polling_events); + event_mask = POLLIN; + } + } + else if( isTcpSockFd( evfd ) ) { + if( getSock( evfd ).evt_check() ) { + TRACE(INFO "epoll_wait socketfd=%d events=0x%08lX", evfd, polling_events); + event_mask = polling_events; + } + } + else if( isUdpSockFd( evfd ) ) { + if( getSock( evfd ).evt_check() ) { + TRACE(INFO "epoll_wait socketfd=%d events=0x%08lX", evfd, polling_events); + event_mask = polling_events; + } + } + else { + TRACE(INFO "epoll_wait came here evfd=%d", evfd); + event_mask = POLLHUP; + } + + if( !( polling_events & event_mask ) ) { + continue; + } + + P4(poll_event) ev; + ev.events = event_mask; + ev.data.fd = evfd; + events[ candidate ++ ] = ev; + } + + if( 0 < candidate ) { + TRACE(INFO "epoll_wait candidate=%d", candidate); + for( int i = 0; i < candidate; ++ i ) { + TRACE(INFO "[%d]={fd:%d, events:0x%08X}", i, events[ i ].data.fd, events[ i ].events); + } + return candidate; + } + } + return 0; +} + +int os::linux::epoll::wait(int epfd, P4(poll_event)* events, int maxevents, int timeout) +{ + return P4(epoll_pwait)( epfd, events, maxevents, timeout, 0 ); +} + +int os::linux::epoll::eventfd(unsigned int initval, int flags) +{ + return P4(eventfd2)( initval, flags ); +} + +int os::linux::epoll::eventfd2(unsigned int initval, int flags) +{ // flags: EFD_CLOEXEC=0x00080000, EFD_NONBLOCK=0x00000800 + return newEventFd( initval ); +} + +int os::linux::sock::accept4(int fd, P4(sockaddr)* addr, P4(socklen_t)* addr_len, int flags) +{ + if( !linux::epoll::isSrvSockFd( fd ) ) { + return helper::set_errno( EINVAL ); + } + + using namespace os::linux::epoll; + int new_fd = fd_builder_.allocate(); + if( new_fd < 0 ) { + return helper::set_errno( ENFILE ); + } + + linux::epoll::sock_t& server = linux::epoll::getSock( fd ); + linux::epoll::sock_t& client = linux::epoll::newSock( new_fd ).asTCP(); + nsapi_error_t ret = server.srv().accept( &client.tcp(), &client.addr() ); + if( ret == NSAPI_ERROR_WOULD_BLOCK ) { + fd_builder_.release( new_fd ); + return helper::set_errno( EWOULDBLOCK ); + } + if( ret < 0 ) { + fd_builder_.release( new_fd ); + return helper::set_errno( EINVAL ); + } + + TRACE(INFO "accepted %s:%d", client.addr().get_ip_address(), client.addr().get_port()); + if( addr && addr_len ) { + if( SocketAddress::trans( client.addr(), addr, addr_len ) < 0 ) { + fd_builder_.release( new_fd ); + return helper::set_errno( EFAULT ); + } + } + + client.attach(); + return new_fd; +} + +NOT_IMPL( int os::linux::sock::socketcall(int call, unsigned long* args) ); +NOT_IMPL( int os::linux::sys::ioctl(int fd, unsigned long request, va_list args) ); + +// see deps/libtuv/src/unix/linux-syscalls.c +#define __NR_accept4 (366) // syscall(__NR_accept4, fd, addr, addrlen, flags); +#define __NR_epoll_create (250) // syscall(__NR_epoll_create, size); +#define __NR_epoll_create1 (357) // syscall(__NR_epoll_create1, flags); +#define __NR_epoll_ctl (251) // syscall(__NR_epoll_ctl, epfd, op, fd, events); +#define __NR_epoll_pwait (346) // syscall(__NR_epoll_pwait, +#define __NR_epoll_wait (252) // syscall(__NR_epoll_wait, epfd, events, nevents, timeout); +#define __NR_eventfd (351) // syscall(__NR_eventfd, count); +#define __NR_eventfd2 (356) // syscall(__NR_eventfd2, count, flags); +#define __NR_pipe2 (359) // syscall(__NR_pipe2, pipefd, flags); +#define __NR_preadv (361) // syscall(__NR_preadv, fd, iov, iovcnt, (long)offset, (long)(offset >> 32)); +#define __NR_pwritev (362) // syscall(__NR_pwritev, fd, iov, iovcnt, (long)offset, (long)(offset >> 32)); +#define __NR_socketcall (102) // syscall(__NR_socketcall, 18 /* SYS_ACCEPT4 */, args); +#define __NR_utimensat (348) // syscall(__NR_utimensat, dirfd, path, times, flags); + +long os::linux::sys::syscall(long number, va_list args) +{ +#define P(type) va_arg(args, type) + switch(number) + { + case __NR_accept4: return P4(accept4)( P(int), P(P4(sockaddr)*), P(P4(socklen_t)*), P(int) ); + case __NR_epoll_create: return P4(epoll_create)( P(int) ); + case __NR_epoll_create1:return P4(epoll_create1)( P(int) ); + case __NR_epoll_ctl: return P4(epoll_ctl)( P(int), P(int), P(int), P(P4(poll_event)*) ); + case __NR_epoll_pwait: return P4(epoll_pwait)( P(int), P(P4(poll_event)*), P(int), P(int), P(const P4(sigset_t)*) ); + case __NR_epoll_wait: return P4(epoll_wait)( P(int), P(P4(poll_event)*), P(int), P(int) ); + case __NR_eventfd: return P4(eventfd)( P(int), P(int) ); + case __NR_eventfd2: return P4(eventfd2)( P(int), P(int) ); + case __NR_pipe2: return P4(pipe2)( P(int*), P(int) ); + case __NR_preadv: return P4(preadv)( P(int), P(const P4(iovec)*), P(int), P(P4(off_t)) ); + case __NR_pwritev: return P4(pwritev)( P(int), P(const P4(iovec)*), P(int), P(P4(off_t)) ); + case __NR_socketcall: return P4(socketcall)( P(int), P(unsigned long*) ); + case __NR_utimensat: return P4(utimensat)( P(int), P(const char*), P(const P4(timespec)*), P(int) ); + } +#undef P + TRACE(INFO "syscall(unknown (num=%ld), ...)", number); + return helper::set_errno( ENOSYS ); +} + +NOT_IMPL( int os::linux::sys::pipe2(int pipefd[2], int flags) ); +NOT_IMPL( void* os::linux::sys::dlopen(const char* filename, int flag) ); +NOT_IMPL( void* os::linux::sys::dlsym(void* handle, char* symbol) ); +NOT_IMPL( int os::linux::sys::dlclose(void* handle) ); +NOT_IMPL( char** os::linux::debug::backtrace_symbols(void*const* buffer, int size) ); +NOT_IMPL( int os::linux::debug::backtrace(void** buffer, int size) ); + + +void os::overridden::abort() +{ + ::abort(); +} + +int os::overridden::gettimeofday(P4(timeval)* tv, void* tz) +{ + return posix::obsolete::gettimeofday( tv, static_cast<timezone*>( tz ) ); +} + +P4(ssize_t) os::overridden::read(int fd, void* buf, P4(size_t) count) +{ + if( linux::epoll::isRelatedFd( fd ) ) { + return linux::epoll::read( fd, buf, count ); + } + return ::read( fd, buf, count ); +} + +P4(ssize_t) os::overridden::write(int fd, const void* buf, P4(size_t) count) +{ + if( linux::epoll::isRelatedFd( fd ) ) { + return linux::epoll::write( fd, buf, count ); + } + return ::write( fd, buf, count ); +} + +int os::overridden::open(const char* pathname, va_list args) +{ + return bugfix::open( pathname, args ); +} + +int os::overridden::close(int fd) +{ + if( linux::epoll::isRelatedFd( fd ) ) { + return linux::epoll::close( fd ); + } + return bugfix::close( fd ); +} + +int os::overridden::unlink(const char* pathname) +{ + return ::remove( pathname ); +} + +int os::overridden::mkdir(const char* pathname, P4(mode_t) mode) +{ + return ::mkdir( pathname, mode ); +} + +int os::overridden::rmdir(const char* pathname) +{ + return ::remove( pathname ); +} + +int os::overridden::stat(const char* pathname, P4(stat_t)* buf) +{ + return bugfix::stat( pathname, buf ); +} + +int os::overridden::fstat(int fd, P4(stat_t)* buf) +{ + return bugfix::fstat( fd, buf ); +} + + +char* os::nic::enumerate() +{ + return helper::nic.enumerate(); +} + +int os::nic::ifup(const char* nic, const char* params) +{ + return helper::nic.ifup( nic, params ) ? 0 : -1; +} + +int os::nic::ifdown(const char* nic) +{ + return helper::nic.ifdown( nic ) ? 0 : -1; +} + +char* os::nic::ifconfig(const char* nic) +{ + return helper::nic.ifconfig( nic ); +} + +int os::nic::ntpdate(const char* nic, const char* server, int port, int timeout) +{ + return helper::nic.ntpdate( nic, server, port, timeout ) ? 0 : -1; +} + + +#define NEWLIB_OVERRIDE extern "C" + +NEWLIB_OVERRIDE int gettimeofday(struct P4(timeval)* tv, void* tz) +{ + return overridden::gettimeofday( tv, tz ); +} + + +#define LWIP_OVERRIDE extern "C" + +#include "lwip/err.h" +LWIP_OVERRIDE err_t tcp_send_fin(struct tcp_pcb* pcb); +LWIP_OVERRIDE err_t __real_tcp_write(struct tcp_pcb* pcb, const void* arg, u16_t len, u8_t apiflags); +LWIP_OVERRIDE err_t __wrap_tcp_write(struct tcp_pcb* pcb, const void* arg, u16_t len, u8_t apiflags) +{ + if( strcmp((char*)arg, NAME_STRINGIZER(VIRTUAL_FIN_PACKET)) == 0 ) { + return tcp_send_fin(pcb); + } + return __real_tcp_write(pcb, arg, len, apiflags); +} + +#define MBEDTLS_OVERRIDE extern "C" + +MBEDTLS_OVERRIDE int __real_mbedtls_hardware_poll(void* data, unsigned char* output, size_t length, size_t* output_length); +MBEDTLS_OVERRIDE int __wrap_mbedtls_hardware_poll(void* data, unsigned char* output, size_t length, size_t* output_length) +{ +#if ENABLE_MODULE_VIDEO==1 + return __real_mbedtls_hardware_poll(data, output, length, output_length); +#else + if( !output || !output_length ) { + return -1; + } + + u16_t* out = reinterpret_cast<u16_t*>( output ); + size_t len = length / sizeof( u16_t ); + for( size_t i=0; i<len; ++i ) { + *out++ = rand(); + } + + output = reinterpret_cast<u8_t*>( out ); + len = length % sizeof( u16_t ); + for( size_t i=0; i<len; ++i ) { + *output++ = rand(); + } + *output_length = length; + return 0; +#endif +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/iotjs/deps/posix/platform/mbedos5/posix4mbed.h Thu Jul 11 18:48:09 2019 +0900 @@ -0,0 +1,183 @@ +/* Copyright 2017-present Renesas Electronics Corporation and other contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT 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 POSIX4MBED_INCL +#define POSIX4MBED_INCL + +#include <stdarg.h> +#include <errno.h> + +#if defined(MBED_DEBUG) + #define DEBUG + #define ENABLE_DEBUG_LOG + #define DEBUG_POSIX_BRIDGE +#endif // #if defined(MBED_DEBUG) + +#define POSIX4_ITSELF +#include "../../posix4.h" + +#if !defined(DEBUG_POSIX_BRIDGE) + #define TRACE(fmt, ...) ((void)0) +#else // #if !defined(DEBUG_POSIX_BRIDGE) + #define INFO "@- " + #define ENTER "-->" + #define LEAVE "<--" + #define TRACE mbed::debug::trace +#endif // #if !defined(DEBUG_POSIX_BRIDGE) + +#define CALLED_FROM __builtin_return_address(0) + +namespace mbed { + + namespace debug { + void trace(const char* fmt, ...); + } // namespace debug + + namespace posix { + namespace obsolete { + int gettimeofday(P4(timeval)* tv, timezone* tz); + } // namespace obsolete + char* getcwd(char* buf, P4(size_t) size); + int chdir(const char* path); + int fdatasync(int fd); + int fsync(int fd); + int ftruncate(int fd, P4(off_t) length); + int scandir(const char* dirp, P4(dirent)*** namelist, int (*filter)(const P4(dirent)*), int (*compar)(const P4(dirent)**, const P4(dirent)**)); + int utime(const char* filename, const P4(utimbuf)* times); + int utimes(const char* filename, const P4(timeval) times[2]); + P4(ssize_t) pread(int fd, void* buf, P4(size_t) count, P4(off_t) offset); + P4(ssize_t) pwrite(int fd, const void* buf, P4(size_t) count, P4(off_t) offset); + P4(ssize_t) readv(int fd, const P4(iovec)* iov, int iovcnt); + P4(ssize_t) writev(int fd, const P4(iovec)* iov, int iovcnt); + int utimensat(int dirfd, const char* pathname, const P4(timespec) times[2], int flags); + namespace clock { + int getres(P4(clockid_t) clk_id, P4(timespec)* res); + int gettime(P4(clockid_t) clk_id, P4(timespec)* tp); + } // namespace clock + namespace pthread { + int create(P4(pthread_t)* thread, P4(pthread_attr_t)* attr, void* (*start_routine)(void*), void* arg); + int join(P4(pthread_t) thread, void** retval); + int once(P4(pthread_once_t)* once_control, void (*init_routine)(void)); + int sigmask(int how, const P4(sigset_t)* set, P4(sigset_t)* oldset); + namespace attr { + int destroy(P4(pthread_attr_t)* attr); + } // namespace attr + namespace cond { + int destroy(P4(pthread_cond_t)* cond); + int init(P4(pthread_cond_t)* cond, P4(pthread_condattr_t)* cond_attr); + int signal(P4(pthread_cond_t)* cond); + int wait(P4(pthread_cond_t)* cond, P4(pthread_mutex_t)* mutex); + } // namespace cond + namespace condattr { + int destroy(P4(pthread_condattr_t)* attr); + int init(P4(pthread_condattr_t)* attr); + int setclock(P4(pthread_condattr_t)* attr, P4(clockid_t) clock_id); + } // namespace condattr + namespace mutex { + int destroy(P4(pthread_mutex_t)* mutex); + int init(P4(pthread_mutex_t)* mutex, const P4(pthread_mutexattr_t)* mutexattr); + int lock(P4(pthread_mutex_t)* mutex); + int unlock(P4(pthread_mutex_t)* mutex); + } // namespace mutex + namespace rwlock { + int destroy(P4(pthread_rwlock_t)* rwlock); + int init(P4(pthread_rwlock_t)* rwlock, const P4(pthread_rwlockattr_t)* attr); + int rdlock(P4(pthread_rwlock_t)* rwlock); + int unlock(P4(pthread_rwlock_t)* rwlock); + } // namespace rwlock + } // namespace pthread + namespace sock { + int accept(int sockfd, P4(sockaddr)* addr, P4(socklen_t)* addrlen); + int bind(int sockfd, const P4(sockaddr)* addr, P4(socklen_t) addrlen); + int connect(int sockfd, const P4(sockaddr)* addr, P4(socklen_t) addrlen); + void freeaddrinfo(P4(addrinfo)* res); + int getaddrinfo(const char* node, const char* service, const P4(addrinfo)* hints, P4(addrinfo)** res); + int getsockname(int sockfd, P4(sockaddr)* addr, P4(socklen_t)* addrlen); + int getsockopt(int sockfd, int level, int optname, void* optval, P4(socklen_t)* optlen); + uint32_t htonl(uint32_t hostlong); + uint16_t htons(uint16_t hostshort); + unsigned int if_nametoindex(const char* ifname); + int listen(int sockfd, int backlog); + uint16_t ntohs(uint16_t netshort); + P4(ssize_t) recvmsg(int sockfd, P4(msghdr)* msg, int flags); + P4(ssize_t) sendmsg(int sockfd, const P4(msghdr)* msg, int flags); + int setsockopt(int sockfd, int level, int optname, const void* optval, P4(socklen_t) optlen); + int shutdown(int sockfd, int how); + int socket(int domain, int type, int protocol); + } // namespace sock + namespace sys { + int nanosleep(const P4(timespec)* req, P4(timespec)* rem); + int pipe(int pipefd[2]); + long sysconf(int name); + } // namespace sys + } // namespace posix + + namespace linux { + P4(ssize_t) preadv(int fd, const P4(iovec)* iov, int iovcnt, P4(off_t) offset); + P4(ssize_t) pwritev(int fd, const P4(iovec)* iov, int iovcnt, P4(off_t) offset); + namespace epoll { + int create(int size); + int create1(int flags); + int ctl(int epfd, int op, int fd, P4(poll_event)* event); + int pwait(int epfd, P4(poll_event)* events, int maxevents, int timeout, const P4(sigset_t)* sigmask); + int wait(int epfd, P4(poll_event)* events, int maxevents, int timeout); + int eventfd(unsigned int initval, int flags); + int eventfd2(unsigned int initval, int flags); + } // namespace epoll + namespace sock { + int accept4(int fd, P4(sockaddr)* addr, P4(socklen_t)* addr_len, int flags); + int socketcall(int call, unsigned long* args); + } // namespace sock + namespace sys { + int ioctl(int fd, unsigned long request, va_list args); + long syscall(long number, va_list args); + int pipe2(int pipefd[2], int flags); + void* dlopen(const char* filename, int flag); + void* dlsym(void* handle, char* symbol); + int dlclose(void* handle); + } // namespace sys + namespace debug { + char** backtrace_symbols(void*const* buffer, int size); + int backtrace(void** buffer, int size); + } // namespace debug + } // namespace linux + + namespace overridden { + void abort(); + int gettimeofday(P4(timeval)* tv, void* tz); + P4(ssize_t) read(int fd, void* buf, P4(size_t) count); + P4(ssize_t) write(int fd, const void* buf, P4(size_t) count); + int open(const char* pathname, va_list args); + int close(int fd); + int unlink(const char* pathname); + int mkdir(const char* pathname, P4(mode_t) mode); + int rmdir(const char* pathname); + int stat(const char* pathname, P4(stat_t)* buf); + int fstat(int fd, P4(stat_t)* buf); + } // namespace overridden + + namespace nic { + char* enumerate(); + int ifup(const char* nic, const char* params); + int ifdown(const char* nic); + char* ifconfig(const char* nic); + int ntpdate(const char* nic, const char* server, int port, int timeout); + } // namespace nic + +} // namespace mbed + +using namespace mbed; + +#endif // #ifndef POSIX4MBED_INCL
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/iotjs/deps/posix/platform/mbedos5/posix4mbed_aux.h Thu Jul 11 18:48:09 2019 +0900 @@ -0,0 +1,295 @@ +/* Copyright 2017-present Renesas Electronics Corporation and other contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT 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 POSIX4MBED_AUX_INCL +#define POSIX4MBED_AUX_INCL + +#include <stddef.h> +#include <stdint.h> +#include <signal.h> +#include <sys/time.h> +#include <sys/utime.h> +#include <sys/syscall.h> +#include <sys/syslimits.h> +#include <sys/types.h> +//#include <sys/stat.h> + +#ifdef __cplusplus +extern "C" { +#endif + +typedef uint8_t u8_t; +typedef int8_t s8_t; +typedef uint16_t u16_t; +typedef int16_t s16_t; +typedef uint32_t u32_t; +typedef int32_t s32_t; +typedef uint64_t u64_t; +typedef int64_t s64_t; + +typedef struct stat stat_t; + +#define P4(name) p4_ ## name + +#define p4_timespec timespec +#define p4_timeval timeval +#define p4_utimbuf utimbuf + +#define NAME_MAX 255 // Maximum size of a name in a file path + +enum { CLOCK_MONOTONIC = 1 }; // clockid_t +enum { PTHREAD_ONCE_INIT = 1234 }; // pthread_once_t + +enum { SOCK_STREAM, SOCK_DGRAM, SOCK_RAW }; // Socket protocol types (TCP/UDP/RAW) +enum { // Option flags per-socket + SOL_SOCKET, + SO_REUSEADDR, SO_KEEPALIVE, SO_BROADCAST, + SO_TYPE, SO_ERROR, +}; + +enum { + IPPROTO_IP = 0, + IPPROTO_TCP = 6, + IPPROTO_UDP = 17, + IPPROTO_IPV6 = 41, + IPPROTO_RAW = 255, +}; +enum { + // Options for level IPPROTO_IP + IP_TOS, + IP_TTL, + // Options for level IPPROTO_TCP + TCP_NODELAY, + TCP_KEEPALIVE, + TCP_KEEPIDLE, + TCP_KEEPINTVL, + TCP_KEEPCNT, + // Options and types related to multicast membership + IP_ADD_MEMBERSHIP, + IP_DROP_MEMBERSHIP, + // Options and types for UDP multicast traffic handling + IP_MULTICAST_IF, + IP_MULTICAST_LOOP, + IP_MULTICAST_TTL, + // Options and types related to multicast membership + IPV6_ADD_MEMBERSHIP, + IPV6_DROP_MEMBERSHIP, + // Options and types for UDP multicast traffic handling + IPV6_MULTICAST_HOPS, + IPV6_MULTICAST_IF, + IPV6_MULTICAST_LOOP, + IPV6_UNICAST_HOPS, +}; + +enum { AF_UNSPEC, AF_INET, AF_INET6, AF_UNIX = AF_UNSPEC }; + +#define IPADDR_NONE ((u32_t)0xffffffffUL) // 255.255.255.255 +#define IPADDR_LOOPBACK ((u32_t)0x7f000001UL) // 127.0.0.1 +#define IPADDR_ANY ((u32_t)0x00000000UL) // 0.0.0.0 +#define IPADDR_BROADCAST ((u32_t)0xffffffffUL) // 255.255.255.255 + +#define IP6ADDR_STRLEN_MAX (46) +#define IP4ADDR_STRLEN_MAX (16) +#define IPADDR_STRLEN_MAX IP6ADDR_STRLEN_MAX + +#define INET_ADDRSTRLEN IP4ADDR_STRLEN_MAX +#define INET6_ADDRSTRLEN IP6ADDR_STRLEN_MAX + +#define INADDR_NONE IPADDR_NONE // 255.255.255.255 +#define INADDR_LOOPBACK IPADDR_LOOPBACK // 127.0.0.1 +#define INADDR_ANY IPADDR_ANY // 0.0.0.0 +#define INADDR_BROADCAST IPADDR_BROADCAST // 255.255.255.255 +extern const struct P4(in6_addr) in6addr_any; + +enum { + AI_PASSIVE = 0x01, + AI_V4MAPPED = 0x08, + AI_ADDRCONFIG = 0x20, +}; + +enum { + EAI_NONAME = 200, + EAI_SERVICE, + EAI_FAIL, + EAI_MEMORY, + EAI_FAMILY, +}; + +enum { MSG_TRUNC }; // msghdr.msg_flags +enum { SCM_RIGHTS, SCM_CREDENTIALS }; // cmsghdr.cmsg_type +enum { SHUT_RD, SHUT_WR, SHUT_RDWR }; // shutdown().how + +enum POLL_OPCODES { POLL_CTL_ADD=1, POLL_CTL_DEL, POLL_CTL_MOD }; // epoll_ctl().op + +#if !defined(POLLIN) +enum POLL_EVENTS { + POLLIN = 0x0001, // see <mbed-os/platform/mbed_poll.h> + POLLOUT = 0x0010, // see <mbed-os/platform/mbed_poll.h> + POLLERR = 0x1000, // see <mbed-os/platform/mbed_poll.h> + POLLHUP = 0x2000, // see <mbed-os/platform/mbed_poll.h> + POLLNVAL= 0x4000, // see <mbed-os/platform/mbed_poll.h> + + POLLPRI = 0x0100, +}; +#endif + +enum { FIONREAD, FIONBIO, FIOCLEX, FIONCLEX }; // ioctl().request +enum { RTLD_LAZY, RTLD_NOW }; // dlopen().flag + + +typedef clockid_t P4(clockid_t); +typedef u32_t P4(in_addr_t); +typedef u16_t P4(in_port_t); +typedef mode_t P4(mode_t); +typedef off_t P4(off_t); +typedef int P4(pthread_attr_t); +typedef void* P4(pthread_cond_t); +typedef void* P4(pthread_condattr_t); +typedef int P4(pthread_key_t); +typedef void* P4(pthread_mutex_t); +typedef int P4(pthread_mutexattr_t); +typedef int P4(pthread_once_t); +typedef int P4(pthread_rwlock_t); +typedef int P4(pthread_rwlockattr_t); +typedef void* P4(pthread_t); +typedef u8_t P4(sa_family_t); +typedef int P4(sem_t); +typedef sigset_t P4(sigset_t); +typedef size_t P4(size_t); +typedef u32_t P4(socklen_t); +typedef ssize_t P4(ssize_t); +typedef stat_t P4(stat_t); + +struct P4(addrinfo); +struct P4(cmsghdr); +struct P4(dirent); +struct P4(in6_addr); +struct P4(in_addr); +struct P4(iovec); +struct P4(msghdr); +struct P4(poll_event); +struct P4(sockaddr); +struct P4(sockaddr_in); +struct P4(sockaddr_in6); +struct P4(sockaddr_storage); +struct P4(termios); +struct P4(timespec); +struct P4(timeval); +struct P4(utimbuf); + + +struct P4(addrinfo) { + int ai_flags; // Input flags + int ai_family; // Address family of socket + int ai_socktype; // Socket type + int ai_protocol; // Protocol of socket + P4(socklen_t) ai_addrlen; // Length of socket address + struct P4(sockaddr)* ai_addr; // Socket address of socket + char* ai_canonname; // Canonical name of service location + struct P4(addrinfo)* ai_next; // Pointer to next in list +}; + +struct P4(cmsghdr) { + int cmsg_type; + int cmsg_len; + int cmsg_level; +}; + +struct P4(dirent) { + char d_name[NAME_MAX+1]; + u8_t d_type; +}; + +struct P4(in6_addr) { + u8_t s6_addr[16]; +}; + +struct P4(in_addr) { + P4(in_addr_t) s_addr; +}; + +struct P4(iovec) { + void* iov_base; + P4(size_t) iov_len; +}; + +struct P4(msghdr) { + void* msg_name; + P4(socklen_t) msg_namelen; + struct P4(iovec)* msg_iov; + int msg_iovlen; + void* msg_control; + P4(socklen_t) msg_controllen; + int msg_flags; +}; + +struct P4(poll_event) { + u32_t events; // Poll events + union { + void* ptr; + int fd; + u32_t u32; + u64_t u64; + } data; // User data variable +}; + +struct P4(sockaddr) { + u8_t sa_len; + P4(sa_family_t) sa_family; + char sa_data[14]; +}; + +struct P4(sockaddr_in) { + u8_t sin_len; + P4(sa_family_t) sin_family; + P4(in_port_t) sin_port; + struct P4(in_addr) sin_addr; + char sin_zero[8]; +}; + +struct P4(sockaddr_in6) { + u8_t sin6_len; + P4(sa_family_t) sin6_family; + P4(in_port_t) sin6_port; + u32_t sin6_flowinfo; + struct P4(in6_addr) sin6_addr; + u32_t sin6_scope_id; +}; + +struct P4(sockaddr_storage) { + u8_t s2_len; + P4(sa_family_t) ss_family; + char s2_data1[2]; + u32_t s2_data2[3]; + u32_t s2_data3[3]; +}; + +struct P4(termios) {}; + +typedef struct P4(ip_mreq) { + struct P4(in_addr) imr_multiaddr; + struct P4(in_addr) imr_interface; +} P4(ip_mreq); + +typedef struct P4(ipv6_mreq) { + struct P4(in6_addr) ipv6mr_multiaddr; + unsigned int ipv6mr_interface; +} P4(ipv6_mreq); + +#ifdef __cplusplus +} +#endif + +#endif // #ifndef POSIX4MBED_AUX_INCL
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/iotjs/deps/posix/platform/mbedos5/primitives.cpp Thu Jul 11 18:48:09 2019 +0900 @@ -0,0 +1,2127 @@ +/* Copyright 2017-present Renesas Electronics Corporation and other contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT 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 <string.h> +#include <stdarg.h> +#include <errno.h> +#include <string> +#include <sstream> +#include <algorithm> + +extern "C" { + //#include <unistd.h> + int close(int fd); + ssize_t read(int fd, void* buf, size_t count); + ssize_t write(int fd, const void* buf, size_t count); + off_t lseek(int fd, off_t offset, int whence); + int unlink(const char* pathname); +} // extern "C" + +#include <mbed.h> +#include "posix4mbed.h" +#include "peripheral_io_4mbed.h" +#include "primitives.h" + +#include "DisplayBace.h" +#include "JPEG_Converter.h" +#include "dcache-control.h" +#include "AsciiFont.h" + +using namespace os::primitives; + +namespace os { namespace primitives { + + CondVar::CondVar() : mutex_(), sems_() { + } + + void CondVar::notify_one() { + mutex_.lock(); + if( !sems_.empty() ) { + sems_.front()->release(); + sems_.pop_front(); + } + mutex_.unlock(); + } + + void CondVar::wait( P4(pthread_mutex_t)* lock ) { + Semaphore sem; + { + mutex_.lock(); + sems_.push_back( &sem ); + mutex_.unlock(); + } + { + P4(pthread_mutex_unlock)( lock ); + sem.wait(); + P4(pthread_mutex_lock)( lock ); + } + } + + void SocketAddress::dbg() const { + printf( "SocketAddress [%s:%d] \n", get_ip_address(), get_port() ); + } + + SocketAddress SocketAddress::trans(const P4(sockaddr)& addr) { + helper::sockaddrs addrs; + addrs.csa = &addr; + if( addr.sa_family == AF_INET ) { + const P4(sockaddr_in)& sa4 = *addrs.csa4; + return SocketAddress( &sa4.sin_addr, NSAPI_IPv4, helper::ntohs( sa4.sin_port ) ); + } + else if( addr.sa_family == AF_INET6 ) { + const P4(sockaddr_in6)& sa6 = *addrs.csa6; + return SocketAddress( &sa6.sin6_addr, NSAPI_IPv6, helper::ntohs( sa6.sin6_port ) ); + } + TRACE(INFO "SocketAddress::trans unknown sa_family = %d", addr.sa_family); + return SocketAddress(); + } + + int SocketAddress::trans(const SocketAddress& sa, void* addr, P4(socklen_t)* addrlen) { + if( sa.get_ip_version() == NSAPI_IPv4 ) { + P4(sockaddr_in) sai = {0}; + sai.sin_len = sizeof( sai ); + sai.sin_family = AF_INET; + sai.sin_port = helper::htons( sa.get_port() ); + union { uint8_t* bytes; P4(in_addr)* addr; } cnv; + cnv.bytes = sa.get_addr().bytes; + sai.sin_addr = *cnv.addr; + memcpy( addr, &sai, *addrlen < sizeof( sai ) ? *addrlen : sizeof( sai ) ); + *addrlen = sizeof( sai ); + return helper::clear_errno(); + } + else if( sa.get_ip_version() == NSAPI_IPv6 ) { + P4(sockaddr_in6) sai = {0}; + sai.sin6_len = sizeof( sai ); + sai.sin6_family = AF_INET6; + sai.sin6_port = helper::htons( sa.get_port() ); + // sai.sin6_flowinfo = 0; + union { uint8_t* bytes; P4(in6_addr)* addr; } cnv; + cnv.bytes = sa.get_addr().bytes; + sai.sin6_addr = *cnv.addr; + // sai.sin6_scope_id = 0; + memcpy( addr, &sai, *addrlen < sizeof( sai ) ? *addrlen : sizeof( sai ) ); + *addrlen = sizeof( sai ); + return helper::clear_errno(); + } + return helper::set_errno( EINVAL ); + } + + bool Nic::connect() { + return is_ip_assigned() || (eth_.connect() == 0); + } + + bool Nic::disconnect() { + return !is_ip_assigned() || (eth_.disconnect() == 0); + } + + bool Nic::is_ip_assigned() const { + return eth_.get_ip_address(); + } + + Nic::Params Nic::parse_params( const std::string& str_params ) const { + Params params; + std::istringstream iss( str_params ); + while( iss ) { + std::string key, value; + iss >> key >> value; + params[ key ] = value; + } + return params; + } + + /*static*/ + char* Nic::enumerate() { + #define NIC(name,tp) "\""#name"\":{\"type\":\""#tp"\"}" + #define NIC_AND "," + const char* nics = "{" + NIC(ETHERNET, eth) +// NIC_AND NIC(WIFI_ESP8266, wifi) +// NIC_AND NIC(WIFI_BP3595, wifi) + "}"; + #undef NIC_AND + #undef NIC + return strdup( nics ); + } + + bool Nic::ifup(const std::string& nic, const std::string& str_params) { + if( nic != targetIF() || is_ip_assigned() ) { + return false; + } + Params params = parse_params( str_params ); + bool dhcp = ( params[ "dhcp:"] == "1" ); + if( eth_.set_dhcp( dhcp ) < 0 ) { + return false; + } + std::string& ip = params[ "ip:" ]; + std::string& mask = params[ "netmask:" ]; + std::string& gw = params[ "gateway:" ]; + if( !dhcp && eth_.set_network( ip.c_str(), mask.c_str(), gw.c_str() ) < 0 ) { + return false; + } + std::string& dns = params[ "dns:" ]; + if( !dns.empty() && eth_.add_dns_server( SocketAddress( dns.c_str() ) ) < 0 ) { + return false; + } + return connect(); + } + + bool Nic::ifdown(const std::string& nic) { + if( nic != targetIF() || !is_ip_assigned() ) { + return false; + } + return disconnect(); + } + + char* Nic::ifconfig(const std::string& nic) { + if( nic != targetIF() ) { + return strdup( "" ); + } + std::string conf; + #define JSON_BEGIN_KV(str,key,value) str+=std::string("{\""#key"\":\"") + value + "\"" + #define JSON_NEXT_KV(str,key,value) str+=std::string(",\""#key"\":\"") + value + "\"" + #define JSON_END(str) str+=std::string("}") + JSON_BEGIN_KV( conf, NIC, targetIF() ); + if( !is_ip_assigned() ) { + JSON_NEXT_KV( conf, inet, "none" ); + } + else { + JSON_NEXT_KV( conf, HWaddr, eth_.get_mac_address() ); + JSON_NEXT_KV( conf, inet, eth_.get_ip_address() ); + JSON_NEXT_KV( conf, netmask, eth_.get_netmask() ); + JSON_NEXT_KV( conf, gateway, eth_.get_gateway() ); + } + JSON_END( conf ); + #undef JSON_END + #undef JSON_NEXT_KV + #undef JSON_BEGIN_KV + return strdup( conf.c_str() ); + } + + bool Nic::ntpdate(const std::string& nic, const char* server/*="0.pool.ntp.org"*/, int port/*=123*/, int timeout/*=10*1000*/) { + if( nic != targetIF() || !is_ip_assigned() ) { + return false; + } + + UDPSocket sock; + sock.open( ð_ ); + sock.set_timeout( timeout ); + + uint32_t send[12] = {0x1B, 0}; + if( sizeof( send ) != sock.sendto( server, port, send, sizeof( send ) ) ) { + return false; + } + + SocketAddress src; + uint32_t recv[12] = {0}; + if( sizeof( recv ) != sock.recvfrom( &src, recv, sizeof( recv ) ) ) { + return false; + } + + const uint32_t time1970 = 25567u * 24 * 60 * 60; + const uint32_t time1900 = helper::ntohl( recv[ 10 ] ); + set_time( time1900 - time1970 ); + return true; + } + + DisplayBase display; + bool isLcdInitialized = false; // LCD初期化フラグ + +}} // namespace os::primitives:: + +namespace os { namespace video { + + bool isStarted = false; // カメラ動作中フラグ + + bool Video::camera_initialize() { + /* OV7725 camera input config */ + const char OV7725_InitRegTable[][2] = { + {0x0D, 0x41}, /* COM4 */ + {0x0F, 0xC5}, /* COM6 */ + {0x11, 0x00}, /* CLKRC */ + {0x14, 0x1F}, /* COM9 Drop VSYNC/HREF */ + {0x15, 0x40}, /* COM10 HSYNC*/ + {0x17, 0x22}, /* HSTART */ + {0x18, 0xA4}, /* HSIZE */ + {0x19, 0x07}, /* VSTRT */ + {0x1A, 0xF0}, /* VSIZE */ + {0x22, 0x99}, /* BDBase */ + {0x23, 0x02}, /* BDMStep */ + {0x24, 0x60}, /* AEW */ + {0x25, 0x50}, /* AEB */ + {0x26, 0xA1}, /* VPT */ + {0x29, 0xA0}, /* HOutSize */ + {0x2A, 0x00}, /* EXHCH */ + {0x2B, 0x00}, /* EXHCL */ + {0x2C, 0xF0}, /* VOutSize */ + {0x32, 0x00}, /* HREF */ + {0x33, 0x01}, /* DM_LNL */ + {0x3D, 0x03}, /* COM12 */ + {0x42, 0x7F}, /* TGT_B */ + {0x4D, 0x09}, /* FixGain */ + {0x63, 0xE0}, /* AWB_Ctrl0 */ + {0x64, 0xFF}, /* DSP_Ctrl1 */ + {0x65, 0x20}, /* DSP_Ctrl2 */ + {0x66, 0x00}, /* DSP_Ctrl3 */ + {0x67, 0x48}, /* DSP_Ctrl4 */ + {0x6B, 0xAA}, /* AWBCtrl3 */ + {0x7E, 0x04}, /* GAM1 */ + {0x7F, 0x0E}, /* GAM2 */ + {0x80, 0x20}, /* GAM3 */ + {0x81, 0x43}, /* GAM4 */ + {0x82, 0x53}, /* GAM5 */ + {0x83, 0x61}, /* GAM6 */ + {0x84, 0x6D}, /* GAM7 */ + {0x85, 0x76}, /* GAM8 */ + {0x86, 0x7E}, /* GAM9 */ + {0x87, 0x86}, /* GAM10 */ + {0x88, 0x94}, /* GAM11 */ + {0x89, 0xA1}, /* GAM12 */ + {0x8A, 0xBA}, /* GAM13 */ + {0x8B, 0xCF}, /* GAM14 */ + {0x8C, 0xE3}, /* GAM15 */ + {0x8D, 0x26}, /* SLOP */ + {0x90, 0x05}, /* EDGE1 */ + {0x91, 0x01}, /* DNSOff */ + {0x92, 0x05}, /* EDGE2 */ + {0x93, 0x00}, /* EDGE3 */ + {0x94, 0x80}, /* MTX1 */ + {0x95, 0x7B}, /* MTX2 */ + {0x96, 0x06}, /* MTX3 */ + {0x97, 0x1E}, /* MTX4 */ + {0x98, 0x69}, /* MTX5 */ + {0x99, 0x86}, /* MTX6 */ + {0x9A, 0x1E}, /* MTX_Ctrl */ + {0x9B, 0x00}, /* BRIGHT */ + {0x9C, 0x20}, /* CNST */ + {0x9E, 0x81}, /* UVADJ0 */ + {0xA6, 0x04}, /* SDE */ + }; + const char sw_reset_cmd[2] = {0x12, 0x80}; + int ret; + I2C mI2c_(I2C_SDA, I2C_SCL); + mI2c_.frequency(150000); + + mI2c_.write(0x42, sw_reset_cmd, 2); + Thread::wait(1); + + for (uint32_t i = 0; i < (sizeof(OV7725_InitRegTable) / 2) ; i++) { + ret = mI2c_.write(0x42, OV7725_InitRegTable[i], 2); + if (ret != 0) { + return false; + } + } + + return true; + } + + DisplayBase::video_format_t convert_video_format(video_pixel_format_t format) { + switch(format) { + case VIDEO_PIXELFORMAT_YCBCR422: return DisplayBase::VIDEO_FORMAT_YCBCR422; + case VIDEO_PIXELFORMAT_RGB565: return DisplayBase::VIDEO_FORMAT_RGB565; + case VIDEO_PIXELFORMAT_RGB888: return DisplayBase::VIDEO_FORMAT_RGB888; + default: return DisplayBase::VIDEO_FORMAT_YCBCR422; + } + } + + DisplayBase::wr_rd_swa_t get_swap_setting(video_pixel_format_t format) { + switch(format) { + case VIDEO_PIXELFORMAT_YCBCR422: return DisplayBase::WR_RD_WRSWA_32_16BIT; + case VIDEO_PIXELFORMAT_RGB565: return DisplayBase::WR_RD_WRSWA_32_16BIT; + case VIDEO_PIXELFORMAT_RGB888: return DisplayBase::WR_RD_WRSWA_32BIT; + default: return DisplayBase::WR_RD_WRSWA_NON; + } + } + + bool Video::open(video_source_t video_source) { + DisplayBase::graphics_error_t error; + DisplayBase::video_ext_in_config_t ext_in_config; + + if(!os::primitives::isLcdInitialized) { + error = os::primitives::display.Graphics_init(NULL); + if(error != DisplayBase::GRAPHICS_OK) { + return false; + } +// os::primitives::isLcdInitialized = true; + } + + PinName cmos_camera_pin[11] = { + /* data pin */ + P2_7, P2_6, P2_5, P2_4, P2_3, P2_2, P2_1, P2_0, + /* control pin */ + P10_0, /* DV0_CLK */ + P1_0, /* DV0_Vsync */ + P1_1 /* DV0_Hsync */ + }; + DigitalOut pwdn(P3_15); + DigitalOut rstb(P3_14); + pwdn = 0; + rstb = 0; + Thread::wait(10 + 1); + rstb = 1; + Thread::wait(1 + 1); + + /* camera input port setting */ + error = os::primitives::display.Graphics_Dvinput_Port_Init(cmos_camera_pin, 11); + if( error != DisplayBase::GRAPHICS_OK ) { + return false; + } + + ext_in_config.inp_format = DisplayBase::VIDEO_EXTIN_FORMAT_BT601; /* BT601 8bit YCbCr format */ + ext_in_config.inp_pxd_edge = DisplayBase::EDGE_RISING; /* Clock edge select for capturing data */ + ext_in_config.inp_vs_edge = DisplayBase::EDGE_RISING; /* Clock edge select for capturing Vsync signals */ + ext_in_config.inp_hs_edge = DisplayBase::EDGE_RISING; /* Clock edge select for capturing Hsync signals */ + ext_in_config.inp_endian_on = DisplayBase::OFF; /* External input bit endian change on/off */ + ext_in_config.inp_swap_on = DisplayBase::OFF; /* External input B/R signal swap on/off */ + ext_in_config.inp_vs_inv = DisplayBase::SIG_POL_NOT_INVERTED; /* External input DV_VSYNC inversion control */ + ext_in_config.inp_hs_inv = DisplayBase::SIG_POL_NOT_INVERTED; /* External input DV_HSYNC inversion control */ + ext_in_config.inp_f525_625 = DisplayBase::EXTIN_LINE_525; /* Number of lines for BT.656 external input */ + ext_in_config.inp_h_pos = DisplayBase::EXTIN_H_POS_YCBYCR; /* Y/Cb/Y/Cr data string start timing to Hsync reference */ + ext_in_config.cap_vs_pos = 4+21; /* Capture start position from Vsync */ + ext_in_config.cap_hs_pos = 68; /* Capture start position form Hsync */ + ext_in_config.cap_width = 640; /* Capture width Max */ + ext_in_config.cap_height = 480; /* Capture height Max */ + + if(!camera_initialize()) { + return false; + } + error = os::primitives::display.Graphics_Video_init(DisplayBase::INPUT_SEL_EXT, &ext_in_config); + if( error != DisplayBase::GRAPHICS_OK ) { + return false; + } + + this->video_source = video_source; + + return true; + } + + bool Video::close(void) { + bool ret = true; + + if(isStarted) { + ret = stop(); + } + + return ret; + } + + bool Video::start(void* buf) { + DisplayBase::graphics_error_t error; + // Video capture setting (progressive form fixed) + os::primitives::display.Video_Write_Setting( + DisplayBase::VIDEO_INPUT_CHANNEL_0, + DisplayBase::COL_SYS_NTSC_358, + buf, + this->video_source.width * this->video_source.pixel_bytes, + convert_video_format(this->video_source.pixel_format), + get_swap_setting(this->video_source.pixel_format), + this->video_source.height, + this->video_source.width + ); + + /* Video write process start */ + error = os::primitives::display.Video_Start(DisplayBase::VIDEO_INPUT_CHANNEL_0); + if (error != DisplayBase::GRAPHICS_OK) { + return false; + } + + /* Video write process stop */ + error = os::primitives::display.Video_Stop(DisplayBase::VIDEO_INPUT_CHANNEL_0); + if (error != DisplayBase::GRAPHICS_OK) { + return false; + } + + /* Video write process start */ + error = os::primitives::display.Video_Start(DisplayBase::VIDEO_INPUT_CHANNEL_0); + if (error != DisplayBase::GRAPHICS_OK) { + return false; + } + isStarted = true; + return true; + } + + bool Video::stop() { + DisplayBase::graphics_error_t error; + /* Video write process stop */ + error = os::primitives::display.Video_Stop(DisplayBase::VIDEO_INPUT_CHANNEL_0); + if (error != DisplayBase::GRAPHICS_OK) { + return false; + } + isStarted = false; + return true; + } + +}} // namespace os::video:: + +namespace os { namespace lcd { + + std::list<lcd_layer_id_t> using_layer; // 使用中レイヤー + + DisplayBase::graphics_format_t convert_graphics_format(display_pixel_format_t format) { + switch(format) { + case DISPLAY_PIXELFORMAT_YCBCR422: return DisplayBase::GRAPHICS_FORMAT_YCBCR422; + case DISPLAY_PIXELFORMAT_RGB565: return DisplayBase::GRAPHICS_FORMAT_RGB565; + case DISPLAY_PIXELFORMAT_RGB888: return DisplayBase::GRAPHICS_FORMAT_RGB888; + case DISPLAY_PIXELFORMAT_ARGB8888: return DisplayBase::GRAPHICS_FORMAT_ARGB8888; + case DISPLAY_PIXELFORMAT_ARGB4444: return DisplayBase::GRAPHICS_FORMAT_ARGB4444; + default: return DisplayBase::GRAPHICS_FORMAT_YCBCR422; + } + } + + DisplayBase::graphics_layer_t convert_layer_id(lcd_layer_id_t id) { + switch(id) { + case LCDLAYER_0: return DisplayBase::GRAPHICS_LAYER_0; + case LCDLAYER_1: return DisplayBase::GRAPHICS_LAYER_1; + case LCDLAYER_2: return DisplayBase::GRAPHICS_LAYER_2; + case LCDLAYER_3: return DisplayBase::GRAPHICS_LAYER_3; + default: return DisplayBase::GRAPHICS_LAYER_0; + } + } + + DisplayBase::wr_rd_swa_t get_swap_setting(display_pixel_format_t format) { + switch(format) { + case DISPLAY_PIXELFORMAT_YCBCR422: return DisplayBase::WR_RD_WRSWA_32_16BIT; + case DISPLAY_PIXELFORMAT_RGB565: return DisplayBase::WR_RD_WRSWA_32_16BIT; + case DISPLAY_PIXELFORMAT_RGB888: return DisplayBase::WR_RD_WRSWA_32BIT; + case DISPLAY_PIXELFORMAT_ARGB8888: return DisplayBase::WR_RD_WRSWA_32BIT; + case DISPLAY_PIXELFORMAT_ARGB4444: return DisplayBase::WR_RD_WRSWA_32_16BIT; + default: return DisplayBase::WR_RD_WRSWA_NON; + } + } + + bool Lcd::open(lcd_t* lcd) { + DisplayBase::graphics_error_t err; + DisplayBase::lcd_config_t lcd_config; + switch(lcd->type) { + case LCDTYPE_4_3INCH: + PinName lvds_pin[8] = { + /* data pin */ + P5_7, P5_6, P5_5, P5_4, P5_3, P5_2, P5_1, P5_0 + }; + lcd->width = 480u; + lcd->height = 272u; + + lcd_config = { + /* GR_PEACH_4_3INCH_SHIELD Config */ + DisplayBase::LCD_TYPE_LVDS /* lcd_type */ + , (66.67) /* intputClock */ + , (13.40f) /* outputClock */ + , DisplayBase::LCD_OUTFORMAT_RGB888 /* lcd_outformat */ + , DisplayBase::EDGE_RISING /* lcd_edge */ + , ((lcd->width) + (52u) + (43u) + (41u)) /* h_toatal_period */ + , ((lcd->height) + (2u) + (12u) + (10u)) /* v_toatal_period */ + , (lcd->width) /* h_disp_widht */ + , (lcd->height) /* v_disp_widht */ + , (43u) /* h_back_porch */ + , (12u) /* v_back_porch */ + , DisplayBase::LCD_TCON_PIN_2 /* h_sync_port */ + , DisplayBase::SIG_POL_NOT_INVERTED /* h_sync_port_polarity */ + , (41u) /* h_sync_width */ + , DisplayBase::LCD_TCON_PIN_0 /* v_sync_port */ + , DisplayBase::SIG_POL_NOT_INVERTED /* v_sync_port_polarity */ + , (10u) /* v_sync_width */ + , DisplayBase::LCD_TCON_PIN_3 /* de_port */ + , DisplayBase::SIG_POL_NOT_INVERTED /* de_port_polarity */ + }; + + DigitalOut lcd_pwon(P7_15, 0); + DigitalOut lcd_blon(P8_1, 0); + Thread::wait(100); + lcd_pwon = 1; + lcd_blon = 1; + + err = os::primitives::display.Graphics_Lvds_Port_Init(lvds_pin, 8); + if(err != DisplayBase::GRAPHICS_OK) { + return false; + } + } + + if(!os::primitives::isLcdInitialized) { + err = os::primitives::display.Graphics_init((const DisplayBase::lcd_config_t*)&lcd_config); + if(err != DisplayBase::GRAPHICS_OK) { + return false; + } + os::primitives::isLcdInitialized = true; + } + + this->lcd = *lcd; + + return true; + } + + bool Lcd::start(lcd_layer_t lcd_layer) { + if( using_layer.end() != std::find( using_layer.begin(), using_layer.end(), lcd_layer.id ) ) { + return false; + } + + DisplayBase::graphics_error_t err; + DisplayBase::graphics_layer_t layer_id = convert_layer_id(lcd_layer.id); + DisplayBase::rect_t rect; + rect.hs = 0; + rect.vs = 0; + rect.hw = this->lcd.width; + rect.vw = this->lcd.height; + + err = os::primitives::display.Graphics_Read_Setting( + layer_id, + lcd_layer.frame_buffer, + this->lcd.width * lcd_layer.pixel_bytes, + convert_graphics_format(lcd_layer.buffer_format), + get_swap_setting(lcd_layer.buffer_format), + &rect + ); +// if(err != DisplayBase::GRAPHICS_OK) { +// return false; +// } + + err = os::primitives::display.Graphics_Start(layer_id); + if(err != DisplayBase::GRAPHICS_OK) { + return false; + } + Thread::wait(50); + + switch(this->lcd.type) { + case LCDTYPE_4_3INCH: + { + DigitalOut lcd_cntrst(P8_15, 1); + } + break; + default: + break; + } + + using_layer.push_back(lcd_layer.id); + + return true; + } + + bool Lcd::stop(lcd_layer_id_t id) { + if( using_layer.end() == std::find( using_layer.begin(), using_layer.end(), id ) ) { + return false; + } + DisplayBase::graphics_error_t err; + err = os::primitives::display.Graphics_Stop(convert_layer_id(id)); + if(err != DisplayBase::GRAPHICS_OK) { + return false; + } + using_layer.remove(id); + return true; + } + + bool Lcd::update(lcd_layer_t lcd_layer) { + if( using_layer.end() == std::find( using_layer.begin(), using_layer.end(), lcd_layer.id ) ) { + return false; + } + + DisplayBase::graphics_error_t err; + err = os::primitives::display.Graphics_Read_Change( + convert_layer_id(lcd_layer.id), + lcd_layer.frame_buffer); + if(err != DisplayBase::GRAPHICS_OK) { + return false; + } + + return true; + } + + bool Lcd::close(void) { + bool ret = true; + + while(!using_layer.empty()) { + ret &= stop(using_layer.front()); + } + + switch(this->lcd.type) { + case LCDTYPE_4_3INCH: + { + DigitalOut lcd_cntrst(P8_15, 0); + DigitalOut lcd_blon(P8_1, 0); + DigitalOut lcd_pwon(P7_15, 0); + } + break; + default: + break; + } + + return ret; + } + +}} // namespace os::lcd:: + +namespace os { namespace jpeg { + + JPEG_Converter::wr_rd_format_t convert_jpeg_format(jpeg_pixel_format_t format) { + switch(format) { + case JPEG_PIXELFORMAT_YCBCR422: return JPEG_Converter::WR_RD_YCbCr422; + case JPEG_PIXELFORMAT_ARGB8888: return JPEG_Converter::WR_RD_ARGB8888; + case JPEG_PIXELFORMAT_RGB565: return JPEG_Converter::WR_RD_RGB565; + default: return JPEG_Converter::WR_RD_YCbCr422; + } + } + + JPEG_Converter::wr_rd_swa_t get_swap_setting(jpeg_pixel_format_t format) { + switch(format) { + case JPEG_PIXELFORMAT_YCBCR422: return JPEG_Converter::WR_RD_WRSWA_32_16_8BIT; + case JPEG_PIXELFORMAT_ARGB8888: return JPEG_Converter::WR_RD_WRSWA_32BIT; + case JPEG_PIXELFORMAT_RGB565: return JPEG_Converter::WR_RD_WRSWA_32_16BIT; + default: return JPEG_Converter::WR_RD_WRSWA_NON; + } + } + + int Jpeg::encode(jpeg_convert_data_t encode_data) { + JPEG_Converter::bitmap_buff_info_t bitmap_buff_info; + JPEG_Converter::encode_options_t encode_options; + size_t encode_size; + + bitmap_buff_info.width = encode_data.width; + bitmap_buff_info.height = encode_data.height; + bitmap_buff_info.format = convert_jpeg_format(encode_data.pixel_format); + bitmap_buff_info.buffer_address = encode_data.src.buf; + + encode_options.encode_buff_size = encode_data.src.len; + encode_options.input_swapsetting = JPEG_Converter::WR_RD_WRSWA_32_16_8BIT; + + dcache_clean(encode_data.src.buf, encode_data.src.len); + dcache_invalid(encode_data.dst.buf, encode_data.dst.len); + if (Jcu.encode(&bitmap_buff_info, encode_data.dst.buf, + &encode_size, &encode_options) != JPEG_Converter::JPEG_CONV_OK) { + return -1; + } + dcache_invalid(encode_data.dst.buf, encode_data.dst.len); + return encode_size; + } + + bool Jpeg::decode(jpeg_convert_data_t decode_data) { + JPEG_Converter::bitmap_buff_info_t bitmap_buff_info; + JPEG_Converter::decode_options_t decode_options; + JPEG_Converter::jpeg_conv_error_t error; + + bitmap_buff_info.width = decode_data.width; + bitmap_buff_info.height = decode_data.height; + bitmap_buff_info.format = convert_jpeg_format(decode_data.pixel_format); + bitmap_buff_info.buffer_address = decode_data.dst.buf; + + if(bitmap_buff_info.format == JPEG_Converter::WR_RD_YCbCr422) { + decode_options.output_cb_cr_offset = JPEG_Converter::CBCR_OFFSET_128; + } else { + decode_options.output_cb_cr_offset = JPEG_Converter::CBCR_OFFSET_0; + } + decode_options.output_swapsetting = get_swap_setting(decode_data.pixel_format); + decode_options.alpha = decode_data.alpha; + + dcache_clean(decode_data.src.buf, decode_data.src.len); + dcache_invalid(decode_data.dst.buf, decode_data.dst.len); + error = Jcu.decode(decode_data.src.buf, &bitmap_buff_info, &decode_options); + if(error != JPEG_Converter::JPEG_CONV_OK) { + return false; + } + dcache_invalid(decode_data.dst.buf, decode_data.dst.len); + return true; + } + +}} // namespace os::jpeg:: + + +namespace os { namespace graphics { + enum { + FRAME_LEFT = (1<<0), + FRAME_TOP = (1<<1), + FRAME_RIGHT = (1<<2), + FRAME_BOTTOM = (1<<3), + }; + + /** + * @private + * 0から遠い方の最も近い整数値に丸める。(C99のlroundfと等価) + * @param x 丸めるべき浮動小数点値 + * @return 丸められた整数値 + */ + static + int roundf2i(float x) + { + return (x >= 0.0f) ? (int)(x + 0.5f) : (int)(x - 0.5f); + } + + /** + * @private + * 反転(ミラー)を考慮した範囲チェックを行い、範囲外のとき真を返す。 + * x = max(|a|,|b|), y = min(|a|,|b|) + * とするとき、(x < s)または(-x >= e)のとき真を返す。 + * filledが偽の場合、(-y < s)かつ(y >= e)の場合も真を返す。 + * @param a 値1 + * @param b 値2 + * @param s 最低値 + * @param e 最高値+1 + * @param filled 0を含む中央部を範囲内とみなすかどうか + * @retval 1 範囲外 + * @retval 0 範囲内 + */ + static + int outOfMirroredRange(int a, int b, int s, int e, int filled) + { + int a_abs = abs(a); + int b_abs = abs(b); + int x; + int y; + + if (a_abs < b_abs) { + x = b_abs; + y = a_abs; + } else { + x = a_abs; + y = b_abs; + } + + return (((x < s) || (-x >= e)) || + ((!filled) && (-y < s) && (y >= e))) ? 1 : 0; + } + + /** + * グラフィックス描画クラスのコンストラクタ + */ + Graphics::Graphics() + : m_buf(NULL), m_width(0), m_height(0), m_format(-1) + { + } + + /** + * グラフィックスの描画を行うフレームバッファの設定を行います。 + * @param buf フレームバッファとして使用するバッファ。 + * @param width フレームバッファの横幅(ピクセル数)。 + * @param height フレームバッファの高さ(ピクセル数)。 + * @param format フレームバッファのピクセルフォーマット。0 : "rgb565", 1 : "rgb888" のいずれか。 + * @return 0 : 正常終了、負の値 : 異常終了 + */ + int Graphics::initFrameBuffer(char *buf, int width, int height, int format) + { + if ((buf == NULL) || (width <= 0) || (height <= 0)) { + // 引数が不正 + return -1; + } + + if ((format != FORMAT_RGB565) && (format != FORMAT_RGB888) + && (format != FORMAT_ARGB8888) && (format != FORMAT_ARGB4444)) { + // 引数が不正 + return -1; + } + + m_buf = buf; + m_width = width; + m_height = height; + m_format = format; + + return 0; + } + + /** + * @private + * 斜め直線描画の本体(移動量の多い座標がP座標、少ない座標がQ座標とする) + * @param ps 始点P座標 + * @param qs 始点Q座標 + * @param pe 終点P座標 + * @param qe 終点Q座標 + * @param pm P座標の最大値+1 + * @param qm Q座標の最大値+1 + * @param pb P座標のバッファ増分(ピクセル数単位で) + * @param qb Q座標のバッファ増分(ピクセル数単位で) + * @param color 色 + * @return 常に成功し、0を返す。 + */ + template <typename T> + int Graphics::drawLineImpl(int ps, int qs, int pe, int qe, int pm, int qm, int pb, int qb, T color) + { + int p0; + int q0; + int p1; + int q1; + + // P座標を昇順に並び替え(Q座標とセットで) + if (pe < ps) { + p0 = pe; + q0 = qe; + p1 = ps; + q1 = qs; + } else { + p0 = ps; + q0 = qs; + p1 = pe; + q1 = qe; + } + + if ((p0 >= pm) || (p1 < 0)) { + // P座標が範囲外のため、何もしない + return 0; + } + + // P座標移動量(0以上) + int dp = p1 - p0; + + // Q座標移動量とQ座標移動ステップ(±1)を計算 + int dq; + int qstep; + if (q0 < q1) { + if ((q1 < 0) || (q0 >= qm)) { + // Q座標が範囲外のため、何もしない + return 0; + } + dq = q1 - q0; + qstep = +1; + } else if (q0 > q1) { + if ((q0 < 0) || (q1 >= qm)) { + // Q座標が範囲外のため、何もしない + return 0; + } + dq = q0 - q1; + qstep = -1; + } else { + // 傾きが0の場合(高速化できる特殊ケース) + + if ((q0 < 0) || (q0 >= qm)) { + // Q座標が範囲外のため、何もしない + return 0; + } + + // P座標をバッファ範囲内に絞る + if (p0 < 0) { + p0 = 0; + } + if (p1 >= pm) { + p1 = pm - 1; + } + + // バッファ上の位置を計算 + T *ptr = getBuffer<T>(0, 0) + (pb * p0) + (qb * q0); + + // 描画(すべての点は既にバッファ範囲内に絞られている) + for (int p = p0; p <= p1; ++p) { + *ptr = color; + ptr += pb; + } + return 0; + } + + // ブレゼンハムのアルゴリズム(整数化版)を用いて傾斜を描画 + + // 初期誤差を計算 + int error = 2 * dq - dp; + + // 初期位置を設定(バッファ範囲外の可能性あり) + int p = p0; + int q = q0; + T *ptr = getBuffer<T>(0, 0) + (pb * p) + (qb * q); + + // P座標の終点を(pm-1)までに絞る(≧pm 以降の座標はすべてバッファ範囲外になるため) + if (p1 >= pm) { + p1 = pm - 1; + } + + while (p <= p1) { + if ((p >= 0) && (q >= 0) && (q < qm)) { + // バッファ範囲内のため、点を描画 + *ptr = color; + } + + // P座標を一つ進める + ++p; + ptr += pb; + + // 累積誤差に基づいてQ座標を一つすすめる + if (error > 0) { + q += qstep; + ptr += (qb * qstep); + error += 2 * (dq - dp); + } else { + error += 2 * dq; + } + } + + return 0; + } + + /** + * フレームバッファに線を描画します。処理が完了すると呼び出し元に戻ります。失敗するとエラーを返します。 + * @param startX 線の始点のX座標 + * @param startY 線の始点のY座標 + * @param endX 線の終点のX座標 + * @param endY 線の終点のY座標 + * @param color 線の色(1ピクセルあたりの色データ) + * @return 0 : 正常終了、負の値 : 異常終了 + */ + int Graphics::drawLine(int startX, int startY, int endX, int endY, uint32_t color) + { + if (!m_buf) { + // 未初期化 + return -2; + } + + if (abs(endX - startX) >= abs(endY - startY)) { + // P=X, Q=Y (転置なし) で描画する + switch (m_format) { + case FORMAT_RGB565: + case FORMAT_ARGB4444: + return drawLineImpl<uint16_t>(startX, startY, endX, endY, m_width, m_height, 1, m_width, (uint16_t)color); + case FORMAT_RGB888: + case FORMAT_ARGB8888: + return drawLineImpl<uint32_t>(startX, startY, endX, endY, m_width, m_height, 1, m_width, color); + default: + // フォーマット不正(=> 未初期化) + return -2; + } + } else { + // P=Y, Q=X (転置あり) で描画する + switch (m_format) { + case FORMAT_RGB565: + case FORMAT_ARGB4444: + return drawLineImpl<uint16_t>(startY, startX, endY, endX, m_height, m_width, m_width, 1, (uint16_t)color); + case FORMAT_RGB888: + case FORMAT_ARGB8888: + return drawLineImpl<uint32_t>(startY, startX, endY, endX, m_height, m_width, m_width, 1, color); + default: + // フォーマット不正(=> 未初期化) + return -2; + } + } + } + + /** + * @private + * 矩形描画の本体 + * @param xs 左端X座標(バッファ範囲内に限定した座標) + * @param ys 上端Y座標(バッファ範囲内に限定した座標) + * @param xe 右端X座標(バッファ範囲内に限定した座標) + * @param ye 下端Y座標(バッファ範囲内に限定した座標) + * @param color 色 + * @param fill 塗りつぶし指定 + * @param frames 枠の描画対象(FRAME_xxxの組み合わせ) + * @return 常に成功し、0を返す。 + */ + template <typename T> + int Graphics::drawRectImpl(int xs, int ys, int xe, int ye, T color, int fill, int frames) + { + if (fill) { + T *line = getBuffer<T>(xs, ys); + for (int yd = ys; yd <= ye; ++yd) { + T *ptr = line; + for (int xd = xs; xd <= xe; ++xd) { + *ptr = color; + ++ptr; + } + line += m_width; + } + // 塗りつぶし有りの場合はここまで + return 0; + } + if (frames & FRAME_TOP) { + T *ptr = getBuffer<T>(xs, ys); + for (int xd = xs; xd <= xe; ++xd) { + *ptr = color; + ++ptr; + } + } + if ((frames & FRAME_BOTTOM) && (ye > ys)) { + T *ptr = getBuffer<T>(xs, ye); + for (int xd = xs; xd <= xe; ++xd) { + *ptr = color; + ++ptr; + } + } + if (frames & FRAME_LEFT) { + T *ptr = getBuffer<T>(xs, ys); + for (int yd = ys; yd <= ye; ++yd) { + *ptr = color; + ptr += m_width; + } + } + if ((frames & FRAME_RIGHT) && (xe > xs)) { + T *ptr = getBuffer<T>(xe, ys); + for (int yd = ys; yd <= ye; ++yd) { + *ptr = color; + ptr += m_width; + } + } + return 0; + } + + /** + * フレームバッファに矩形を描画します。処理が完了すると呼び出し元に戻ります。失敗するとエラーを返します。 + * @param x 矩形の基点のX座標 + * @param y 矩形の基点のY座標 + * @param width 矩形の幅 + * @param height 矩形の高さ + * @param color 矩形の色 + * @param fill 0 : 塗りつぶさない、それ以外 : 塗りつぶす + * @return 0 : 正常終了、負の値 : 異常終了 + */ + int Graphics::drawRect(int x, int y, int width, int height, uint32_t color, int fill) + { + if (!m_buf) { + // 未初期化 + return -2; + } + + if ((width < 0) || (height < 0)) { + // 引数が不正(何もしない) + return 0; + } + + if ((width == 0) || (height == 0)) { + // 描画領域なし(何もしない) + return 0; + } + + // 枠フラグの初期化 + int frames = FRAME_LEFT | FRAME_TOP | FRAME_RIGHT | FRAME_BOTTOM; + + // 始点側の描画領域内座標を計算 => (xs, ys) + int xs = x; + if (xs < 0) { + frames &= ~FRAME_LEFT; + xs = 0; + } + int ys = y; + if (ys < 0) { + frames &= ~FRAME_TOP; + ys = 0; + } + + if ((xs >= m_width) || (ys >= m_height)) { + // 描画領域なし(何もしない) + return 0; + } + + // 終点側の描画領域内座標を計算 => (xe, ye) + int xe = x + width - 1; + if (xe >= m_width) { + frames &= ~FRAME_RIGHT; + xe = m_width - 1; + } + int ye = y + height - 1; + if (ye >= m_height) { + frames &= ~FRAME_BOTTOM; + ye = m_height - 1; + } + + if ((xe < 0) || (ye < 0)) { + // 描画領域なし(何もしない) + return 0; + } + + // 描画実行 + switch (m_format) { + case FORMAT_RGB565: + case FORMAT_ARGB4444: + return drawRectImpl<uint16_t>(xs, ys, xe, ye, (uint16_t)color, fill, frames); + case FORMAT_RGB888: + case FORMAT_ARGB8888: + return drawRectImpl<uint32_t>(xs, ys, xe, ye, color, fill, frames); + default: + // フォーマット不正(=> 未初期化) + return -2; + } + } + + /** + * @private + * 円弧描画のプロット点判定関数 + * @param x 判定対象X座標 + * @param y 判定対象Y座標 + * @param xs 始点X座標 + * @param ys 始点Y座標 + * @param as 始点角度(-360以上360未満) + * @param xe 終点X座標 + * @param ye 終点Y座標 + * @param ae 終点角度(-360以上360未満) + * @return 0 : プロットしない、それ以外 : プロットする + */ + static inline + int judgeArcPlot(int x, int y, int xs, int ys, int as, int xe, int ye, int ae) + { + if (as < 0) { + as += 360; + } + if (ae < 0) { + ae += 360; + } + + if (as <= ae) { + if (ae <= 45) { + return ((x <= xs) && (y >= ys)) && ((x >= xe) && (y <= ye)); + } else if (as <= 45) { + return ((x <= xs) && (y >= ys)); + } else { + return 0; + } + } else { + if (as <= 45) { + return ((x >= xe) && (y <= ye)) || ((x <= xs) && (y >= ys)); + } else if (ae <= 45) { + return ((x >= xe) && (y <= ye)); + } else { + return 1; + } + } + } + + /** + * @private + * 円弧描画の本体 + * @param xc 中心X座標 + * @param yc 中心Y座標 + * @param r 半径 + * @param xs 始点X座標(原点を円中心とする座標系にて) + * @param ys 始点Y座標(原点を円中心とし、Y軸正方向が上向きの座標系にて) + * @param as 始点の角度(0以上360未満) + * @param xe 終点X座標(原点を円中心とする座標系にて) + * @param ye 終点Y座標(原点を円中心とし、Y軸正方向が上向きの座標系にて) + * @param ae 終点の角度(0以上360未満) + * @param color 色 + * @note 終点座標の角度は始点座標の角度と等しいか大きい + * @return 常に成功し、0を返す。 + */ + template <typename T> + int Graphics::drawArcImpl(int xc, int yc, int r, int xs, int ys, int as, int xe, int ye, int ae, T color) + { + /* + 正円のラスタライズでしばしば利用されるブレゼンハムのアルゴリズムの + 改良版である、ミッチェナーのアルゴリズムを利用する。 + + 参考サイト + http://atarasevich.blogspot.com/2015/07/on-circle-rasterization-algorithms.html + */ + + int x = r; + int y = 0; + + int D = 1 - r; + + while (y <= x) { + // 45度ずつ分けた8つの区間について、それぞれプロットする + + // 0~45度 + if (judgeArcPlot(x, y, +xs, +ys, as, +xe, +ye, ae)) { + int xp = xc + x; + int yp = yc - y; + if ((0 <= xp) && (xp < m_width) && (0 <= yp) && (yp < m_height)) { + *getBuffer<T>(xp, yp) = color; + } + } + + // 45~90度 + if (judgeArcPlot(x, y, +ye, +xe, 90 - ae, +ys, +xs, 90 - as)) { + int xp = xc + y; + int yp = yc - x; + if ((0 <= xp) && (xp < m_width) && (0 <= yp) && (yp < m_height)) { + *getBuffer<T>(xp, yp) = color; + } + } + + // 90~135度 + if (judgeArcPlot(x, y, +ys, -xs, as - 90, +ye, -xe, ae - 90)) { + int xp = xc - y; + int yp = yc - x; + if ((0 <= xp) && (xp < m_width) && (0 <= yp) && (yp < m_height)) { + *getBuffer<T>(xp, yp) = color; + } + } + + // 135~180度 + if (judgeArcPlot(x, y, -xe, +ye, 180 - ae, -xs, +ys, 180 - as)) { + int xp = xc - x; + int yp = yc - y; + if ((0 <= xp) && (xp < m_width) && (0 <= yp) && (yp < m_height)) { + *getBuffer<T>(xp, yp) = color; + } + } + + // 180~225度 + if (judgeArcPlot(x, y, -xs, -ys, as - 180, -xe, -ye, ae - 180)) { + int xp = xc - x; + int yp = yc + y; + if ((0 <= xp) && (xp < m_width) && (0 <= yp) && (yp < m_height)) { + *getBuffer<T>(xp, yp) = color; + } + } + + // 225~270度 + if (judgeArcPlot(x, y, -ye, -xe, 270 - ae, -ys, -xs, 270 - as)) { + int xp = xc - y; + int yp = yc + x; + if ((0 <= xp) && (xp < m_width) && (0 <= yp) && (yp < m_height)) { + *getBuffer<T>(xp, yp) = color; + } + } + + // 270~315度 + if (judgeArcPlot(x, y, -ys, +xs, as - 270, -ye, +xe, ae - 270)) { + int xp = xc + y; + int yp = yc + x; + if ((0 <= xp) && (xp < m_width) && (0 <= yp) && (yp < m_height)) { + *getBuffer<T>(xp, yp) = color; + } + } + + // 315~360度 + if (judgeArcPlot(x, y, +xe, -ye, -ae, +xs, -ys, -as)) { + int xp = xc + x; + int yp = yc + y; + if ((0 <= xp) && (xp < m_width) && (0 <= yp) && (yp < m_height)) { + *getBuffer<T>(xp, yp) = color; + } + } + + if (D <= 0) { + ++y; + D += 2 * y + 1; + } else { + --x; + ++y; + D += 2 * (y - x) + 1; + } + } + + return 0; + } + + /** + * フレームバッファに弧を描画します。処理が完了すると呼び出し元に戻ります。失敗するとエラーを返します。 + * @param centerX 弧の中心点のX座標 + * @param centerY 弧の中心点のY座標 + * @param radius 弧の半径 + * @param startAngle 弧の始点の角度(単位:度) + * @param endAngle 弧の終点の角度(単位:度) + * @param color 弧の色(1ピクセルあたりの色データ) + * @note 角度は反時計回りを正とする。 + * @note startAngleとendAngleの差が360以上ある場合、単なる1周の正円を描画する。 + * @note startAngleがendAngleより大きい場合、時計回りに描画する。 + * @return 0 : 正常終了、負の値 : 異常終了 + */ + int Graphics::drawArc(int centerX, int centerY, int radius, int startAngle, int endAngle, uint32_t color) + { + if (!m_buf) { + // 未初期化 + return -2; + } + + if (radius < 0) { + // 引数が不正(何もしない) + return 0; + } + + if (((centerX + radius) < 0) || ((centerX - radius) >= m_width) || + ((centerY + radius) < 0) || ((centerY - radius) >= m_height)) { + // 円を囲む矩形がバッファ範囲外、何もしない + return 0; + } + + if (startAngle > endAngle) { + // 角度の入れ替え + int angle = startAngle; + startAngle = endAngle; + endAngle = angle; + } + + int diffAngle = endAngle - startAngle; + if (diffAngle >= 360) { + // 正円描画に置き換え + return drawCircle(centerX, centerY, radius, color, 0); + } else if (diffAngle == 0) { + // 角度なし(=> 何もしない) + return 0; + } + + // 開始角度、終了角度をそれぞれ正規化 + startAngle %= 360; + if (startAngle < 0) { + startAngle += 360; + } + endAngle = startAngle + diffAngle; + if (endAngle >= 360) { + endAngle -= 360; + } + + // 開始座標、終了座標を計算(原点を円中心とし、Y軸正方向が上向きの座標系で) + float startRad = startAngle * (atan2f(1.0f, 1.0f) * 4 / 180); + int xs = roundf2i(cosf(startRad) * radius); + int ys = roundf2i(sinf(startRad) * radius); + float endRad = endAngle * (atan2f(1.0f, 1.0f) * 4 / 180); + int xe = roundf2i(cosf(endRad) * radius); + int ye = roundf2i(sinf(endRad) * radius); + + switch (m_format) { + case FORMAT_RGB565: + case FORMAT_ARGB4444: + return drawArcImpl<uint16_t>(centerX, centerY, radius, xs, ys, startAngle, xe, ye, endAngle, (uint16_t)color); + case FORMAT_RGB888: + case FORMAT_ARGB8888: + return drawArcImpl<uint32_t>(centerX, centerY, radius, xs, ys, startAngle, xe, ye, endAngle, color); + default: + // フォーマット不正(=> 未初期化) + return -2; + } + } + + /** + * フレームバッファに円を描画します。処理が完了すると呼び出し元に戻ります。失敗するとエラーを返します。 + * @param centerX 円の中心点のX座標 + * @param centerY 円の中心点のY座標 + * @param radius 円の半径 + * @param color 円の色(1ピクセルあたりの色データ) + * @param fill 0 : 塗りつぶさない、それ以外 : 塗りつぶす + * @return 0 : 正常終了、負の値 : 異常終了 + */ + int Graphics::drawCircle(int centerX, int centerY, int radius, uint32_t color, int fill) + { + // X方向とY方向の半径が等しい楕円として処理する + return drawEllipse(centerX, centerY, radius, radius, color, fill); + } + + /** + * @private + * 楕円描画の本体 + * @param xc 中心X座標 + * @param yc 中心Y座標 + * @param a X軸半径 + * @param b Y軸半径 + * @param color 色 + * @param fill 塗りつぶし指定 + * @return 常に成功し、0を返す。 + */ + template <typename T> + int Graphics::drawEllipseImpl(int xc, int yc, int a, int b, T color, int fill) + { + /* + 正円のラスタライズでしばしば利用されるブレゼンハムのアルゴリズムを、 + 楕円の方程式に当てはめて応用する。 + + 楕円の方程式を x^2/a^2 + y^2/b^2 = 1 とする。 + + ある点(x,y)が楕円の[内側|円周上|外側]にあるかを求める方程式をD(x,y)とすると、 + D(x,y) := x^2*b^2 + y^2*a^2 - a^2*b^2 + + 楕円のうち x=[a..0], y=[0..b] となる範囲(4分の1)の描画のみに注目する。 + (残り4分の3は、この4分の1のミラーで計算できるため) + + ある点(x,y)をプロットしたのち、次にプロットすべき点は + 点P=(x-1,y+1) 点Q=( x ,y+1) + 点R=(x-1, y ) + のいずれかである。次にプロットすべき点は、まず + D(x-1,y+1)の値によって選択される。 + + D(x-1,y+1) = x^2*b^2 + y^2*a^2 - a^2*b^2 + b^2*(1-2*x) + a^2*(1+2*y) + = D(x,y) + b^2*(1-2*x) + a^2*(1+2*y) + が、 + (ア) 負のとき 点Pまたは点Q + (イ) 零のとき 点P (ちょうど点Pが円周上) + (ウ) 正のとき 点Pまたは点R + + (ア)のとき、 + d = |D(x,y+1)| - |D(x-1,y+1)| + = D(x-1,y+1) + D(x,y+1) + = 2*D(x-1,y+1) - b^2*(1-2*x) + とすると、 + d > 0 のとき、点Pの方が点Qより円周に近いので、点Pをプロットする。 + d <= 0 のとき、点Qをプロットする。 + + (イ)のとき、点Pをプロットする。 + + (ウ)のとき、 + d = |D(x-1,y+1)| - |D(x-1,y)| + = D(x-1,y+1) + D(x-1,y) + = 2*D(x-1,y+1) - a^2*(1+2*y) + とすると、 + d < 0 のとき、点Pの方が点Rより円周に近いので、点Pをプロットする。 + d >= 0 のとき、点Rをプロットする。 + */ + + const int asq = a * a; + const int bsq = b * b; + + // (x,y)=(a,0) における D(x-1,y+1) を計算 + long long int D = bsq * (1 - 2 * a) + asq * (1 + 2 * 0); + + int x = a; + int y = 0; + + // fillの場合は、最後に処理したY座標を覚えておく + // (ある一つのY座標に到達した初回でX方向に塗りつぶし、 + // その後の同Y座標では塗りつぶしが不要なため) + int ylast = -1; + + while (x > 0) { + // 中心座標を足す + int xp = xc + x; + int yp = yc + y; + int xm = xc - x; + int ym = yc - y; + int yp_in = (0 <= yp) && (yp < m_height); + int ym_in = (0 <= ym) && (ym < m_height); + + if (fill) { + // 塗りつぶし有り + if (y > ylast) { + ylast = y; + + // X座標の範囲を絞る + if (xp >= m_width) { + xp = m_width - 1; + } + if (xm < 0) { + xm = 0; + } + + if (ym_in) { + // 上側 + T *ptr = getBuffer<T>(xm, ym); + for (int x = xm; x <= xp; ++x) { + *ptr = color; + ++ptr; + } + } + + if (yp_in) { + // 下側 + T *ptr = getBuffer<T>(xm, yp); + for (int x = xm; x <= xp; ++x) { + *ptr = color; + ++ptr; + } + } + } + } else { + // 塗りつぶし無し(円周のみプロット) + int xp_in = (0 <= xp) && (xp < m_width); + int xm_in = (0 <= xm) && (xm < m_width); + + if (xp_in && yp_in) { + *getBuffer<T>(xp, yp) = color; // 第一象限 + } + if (xm_in && yp_in) { + *getBuffer<T>(xm, yp) = color; // 第二象限 + } + if (xm_in && ym_in) { + *getBuffer<T>(xm, ym) = color; // 第三象限 + } + if (xp_in && ym_in) { + *getBuffer<T>(xp, ym) = color; // 第四象限 + } + } + + if (D < 0) { + // 円周は 点P(x-1,y-1) と 点Q(x,y-1) の間を通る + long long int d = 2 * D - bsq * (1 - 2 * x); + + if (d <= 0) { + // 点Q(x,y-1)の方が近いか等距離 + ++y; + D += asq * (1 + 2 * y); + continue; + } + } else if (D > 0) { + // 円周は 点P(x-1,y-1) と 点R(x-1,y) の間を通る + long long int d = 2 * D - asq * (1 + 2 * y); + + if (d >= 0) { + // 点R(x-1,y)の方が近いか等距離 + --x; + D += bsq * (1 - 2 * x); + continue; + } + } + + // 円周はちょうど 点P(x-1,y-1) を通るか、または点Pに近い + --x; + ++y; + D += asq * (1 + 2 * y) + bsq * (1 - 2 * x); + } + + // x=0 のときは特殊扱い + // (yは現在値からbまで全てプロット) + + if ((0 <= xc) && (xc < m_width)) { + int yp = yc + y; + int ym = yc - y; + T *ptrp = getBuffer<T>(xc, yp); + T *ptrm = getBuffer<T>(xc, ym); + + for (; y <= b; ++y, ++yp, --ym) { + if ((0 <= yp) && (yp < m_height)) { + *ptrp = color; + } + ptrp += m_width; + if ((0 <= ym) && (ym < m_height)) { + *ptrm = color; + } + ptrm -= m_width; + } + } + + return 0; + } + + /** + * フレームバッファに楕円を描画します。処理が完了すると呼び出し元に戻ります。失敗するとエラーを返します。 + * @param centerX 楕円の中心点のX座標 + * @param centerY 楕円の中心点のY座標 + * @param radiusX 楕円のX方向の半径 + * @param radiusY 楕円のY方向の半径 + * @param color 楕円の色(1ピクセルあたりの色データ) + * @param fill 0 : 塗りつぶさない、それ以外 : 塗りつぶす + * @return 0 : 正常終了、負の値 : 異常終了 + */ + int Graphics::drawEllipse(int centerX, int centerY, int radiusX, int radiusY, uint32_t color, int fill) + { + if (!m_buf) { + // 未初期化 + return -2; + } + + if ((radiusX < 0) || (radiusY < 0)) { + // 引数が不正(何もしない) + return 0; + } + + if (((centerX + radiusX) < 0) || ((centerX - radiusX) >= m_width) || + ((centerY + radiusY) < 0) || ((centerY - radiusY) >= m_height)) { + // 円を囲む矩形がバッファ範囲外、何もしない + return 0; + } + + switch (m_format) { + case FORMAT_RGB565: + case FORMAT_ARGB4444: + return drawEllipseImpl<uint16_t>(centerX, centerY, radiusX, radiusY, (uint16_t)color, fill); + case FORMAT_RGB888: + case FORMAT_ARGB8888: + return drawEllipseImpl<uint32_t>(centerX, centerY, radiusX, radiusY, color, fill); + default: + // フォーマット不正(=> 未初期化) + return -2; + } + } + + /** + * @private + * 正多角形描画で使用する斜め直線描画の本体(移動量の多い座標がP座標、少ない座標がQ座標とする) + * @param ps 始点P座標(ポリゴン中心を原点とする相対座標にて) + * @param qs 始点Q座標(ポリゴン中心を原点とする相対座標にて。常にps以上) + * @param pe 終点P座標(ポリゴン中心を原点とする相対座標にて) + * @param qe 終点Q座標(ポリゴン中心を原点とする相対座標にて) + * @param pc P座標系の原点の、バッファ座標系における座標 + * @param qc Q座標系の原点の、バッファ座標系における座標 + * @param pm P座標の最大値+1 (ポリゴン中心を原点とする相対座標にて) + * @param qm Q座標の最大値+1 (ポリゴン中心を原点とする相対座標にて) + * @param pb P座標のバッファ増分(ピクセル数単位で) + * @param qb Q座標のバッファ増分(ピクセル数単位で) + * @param color 色 + * @param mirrors 鏡像指定(0:鏡像なし、1:Q軸対称(P座標反転)あり、2:P軸対称(Q座標反転)あり、3:両軸対称あり) + * @param fillDir 塗りつぶし方向指定(0:塗りつぶしなし、1:P軸方向に塗りつぶし、2:Q軸方向に塗りつぶし) + */ + template <typename T> + void Graphics::drawPolygonLineImpl(int ps, int qs, int pe, int qe, int pc, int qc, int pm, int qm, int pb, int qb, T color, int mirrors, int fillDir) + { + int p0; + int q0; + int p1; + int q1; + + // P座標を昇順に並び替え(Q座標とセットで) + if (pe < ps) { + p0 = pe; + q0 = qe; + p1 = ps; + q1 = qs; + } else { + p0 = ps; + q0 = qs; + p1 = pe; + q1 = qe; + } + + if (outOfMirroredRange(p0, p1, -pc, pm, fillDir & 1)) { + // P座標がミラーを考慮しても範囲外のため、何もしない + return; + } + + if (outOfMirroredRange(q0, q1, -qc, qm, fillDir & 2)) { + // Q座標がミラーを考慮しても範囲外のため、何もしない + return; + } + + // P座標移動量(0以上) + int dp = p1 - p0; + + // Q座標移動量とQ座標移動ステップ(±1)を計算 + int dq; + int qstep; + if (q0 <= q1) { + dq = q1 - q0; + qstep = +1; + } else if (q0 > q1) { + dq = q0 - q1; + qstep = -1; + } + + // ブレゼンハムのアルゴリズム(整数化版)を用いて傾斜を描画 + + // 初期誤差を計算 + int error = 2 * dq - dp; + + // 初期位置を設定(バッファ範囲外の可能性あり) + int p = p0; + int q = q0; + T *ptr0 = getBuffer<T>(0, 0) + (pb * (pc + p)) + (qb * (qc + q)); + T *ptr1 = getBuffer<T>(0, 0) + (pb * (pc - p)) + (qb * (qc + q)); + T *ptr2 = getBuffer<T>(0, 0) + (pb * (pc + p)) + (qb * (qc - q)); + T *ptr3 = getBuffer<T>(0, 0) + (pb * (pc - p)) + (qb * (qc - q)); + + int last = (fillDir == 1) ? (q - qstep) : (p - 1); + + while (p <= p1) { + // 現在位置がバッファ内であればプロットする + if ((p >= -pc) && (p < pm)) { + if ((q >= -qc) && (q < qm)) { + *ptr0 = color; + } + if ((mirrors & 2) && (-q >= -qc) && (-q < qm)) { + *ptr2 = color; + } + } + if ((mirrors & 1) && (-p >= -pc) && (-p < pm)) { + if ((q >= -qc) && (q < qm)) { + *ptr1 = color; + } + if ((mirrors & 2) && (-q >= -qc) && (-q < qm)) { + *ptr3 = color; + } + } + + if (fillDir == 1) { + // P座標方向塗りつぶし + if (last == q) { + goto skipFill; + } + last = q; + + // P座標を絞り込み(P座標が負の場合、pf0 < pf1になるよう反転する) + int pf0; + int pf1; + if (p < 0) { + pf0 = p - 1; + pf1 = -p + 1; + } else { + pf0 = -p + 1; + pf1 = p - 1; + } + if (pf0 < -pc) { + pf0 = -pc; + } + if (pf1 >= pm) { + pf1 = pm - 1; + } + + if (pf0 <= pf1) { + T *ptrf0 = ((q >= -qc) && (q < qm)) ? + (getBuffer<T>(0, 0) + (pb * (pc + pf0)) + (qb * (qc + q))) : NULL; + T *ptrf1 = ((mirrors & 2) && (-q >= -qc) && (-q < qm)) ? + (getBuffer<T>(0, 0) + (pb * (pc + pf0)) + (qb * (qc - q))) : NULL; + + if (!ptrf0 && !ptrf1) { + // +q,-qともに範囲外のため塗りつぶし不要 + goto skipFill; + } + + for (int pd = pf0; pd <= pf1; ++pd) { + if (ptrf0) { + *ptrf0 = color; + ptrf0 += pb; + } + if (ptrf1) { + *ptrf1 = color; + ptrf1 += pb; + } + } + } + } else if (fillDir == 2) { + // Q座標方向塗りつぶし + if (last == p) { + goto skipFill; + } + last = p; + + // Q座標を絞り込み(Q座標が負の場合、qf0 < qf1になるよう反転する) + int qf0; + int qf1; + if (q < 0) { + qf0 = q - 1; + qf1 = -q + 1; + } else { + qf0 = -q + 1; + qf1 = q - 1; + } + if (qf0 < -qc) { + qf0 = -qc; + } + if (qf1 >= qm) { + qf1 = qm - 1; + } + + if (qf0 <= qf1) { + T *ptrf0 = ((p >= -pc) && (p < pm)) ? + (getBuffer<T>(0, 0) + (pb * (pc + p)) + (qb * (qc + qf0))) : NULL; + T *ptrf1 = ((mirrors & 1) && (-p >= -pc) && (-p < pm)) ? + (getBuffer<T>(0, 0) + (pb * (pc - p)) + (qb * (qc + qf0))) : NULL; + + if (!ptrf0 && !ptrf1) { + // +p,-pともに範囲外のため塗りつぶし不要 + goto skipFill; + } + + for (int qd = qf0; qd <= qf1; ++qd) { + if (ptrf0) { + *ptrf0 = color; + ptrf0 += qb; + } + if (ptrf1) { + *ptrf1 = color; + ptrf1 += qb; + } + } + } + } + skipFill: + + // P座標を一つ進める + ++p; + ptr0 += pb; + ptr1 -= pb; + ptr2 += pb; + ptr3 -= pb; + + // 累積誤差に基づいてQ座標を一つすすめる + if (error > 0) { + q += qstep; + ptr0 += (qb * qstep); + ptr1 += (qb * qstep); + ptr2 -= (qb * qstep); + ptr3 -= (qb * qstep); + error += 2 * (dq - dp); + } else { + error += 2 * dq; + } + } + } + + /** + * フレームバッファに多角形を描画します。処理が完了すると呼び出し元に戻ります。失敗するとエラーを返します。 + * @param centerX 多角形の中心点のX座標 + * @param centerY 多角形の中心点のY座標 + * @param radius 多角形の中心点と頂点の距離(外接円の半径) + * @param sides 多角形の辺の数 + * @param color 多角形の色(1ピクセルあたりの色データ) + * @param fill 0 : 塗りつぶさない、それ以外 : 塗りつぶす + * @note sidesが4(つまり正方形)の場合、開始点の角度は45度となり底辺が水平な正方形が描画されます。 + * @note sidesが4以外の場合、開始点の角度は90度(真上)となり、そこから指定した辺の数を持つ正多角形が描画されます。 + * @return 0 : 正常終了、負の値 : 異常終了 + */ + int Graphics::drawPolygon(int centerX, int centerY, int radius, int sides, uint32_t color, int fill) + { + if (!m_buf) { + // 未初期化 + return -2; + } + + if ((radius < 0) || (sides < 3)) { + // 引数が不正(何もしない) + return 0; + } + + if (sides == 4) { + // 四角形は特殊扱い(45度始まりのため、矩形描画を流用) + int halfWidth = (int)floorf(radius / sqrtf(2.0f)); + return drawRect(centerX - halfWidth, centerY - halfWidth, halfWidth * 2 + 1, halfWidth * 2 + 1, color, fill); + } + + if (((centerX + radius) < 0) || ((centerX - radius) >= m_width) || + ((centerY + radius) < 0) || ((centerY - radius) >= m_height)) { + // 外接円を囲む矩形がバッファ範囲外(=> 何もしない) + return 0; + } + + // 中心と各辺を結ぶ二等辺三角形の、中心側の角度を求める + float rad = atan2f(1.0f, 1.0f) * 8 / sides; + + // 開始点は上側、つまり(x,y)=(0,-r)なので、Y軸で線対称な図形となるため、 + // 半分の頂点について処理し、残りはY軸でミラーすればよい。 + // なお、頂点数が偶数の場合はX軸で線対称な図形でもあるので、さらに半分の頂点のみ + // 処理する。 + int verticies = (sides & 1) ? (sides >> 1) : (sides >> 2); + + int x = 0; // sinf(rad * 0) * radius + int y = -radius; // cosf(rad * 0) * -radius + + for (int vertex = 1; vertex <= verticies; ++vertex) { + // 次の頂点の位置を求める + int xg = roundf2i(sinf(rad * vertex) * radius); + int yg = roundf2i(cosf(rad * vertex) * -radius); + + // 次の頂点へ向けてブレゼンハムのアルゴリズムで辺を描画する + if ((yg == y) && (xg == x)) { + // 次の頂点が現在位置上にある(頂点同士が整数化すると重なっている) + // => プロット必要なし。次の頂点へ。 + if (vertex == 1) { + // ただしループ初回はその点を描画する(ドット抜け対策) + (void)drawLine(centerX + x, centerY + y, centerX + x, centerY + y, color); + } + continue; + } + + if (abs(xg - x) >= (yg - y)) { + // P=X, Q=Y (転置なし) で描画する + int mirrors = (sides & 1) ? (1) : (3); + int fillDir = fill ? 1 : 0; + switch (m_format) { + case FORMAT_RGB565: + case FORMAT_ARGB4444: + drawPolygonLineImpl<uint16_t>( + x, y, xg, yg, + centerX, centerY, m_width - centerX, m_height - centerY, + 1, m_width, (uint16_t)color, mirrors, fillDir); + break; + case FORMAT_RGB888: + case FORMAT_ARGB8888: + drawPolygonLineImpl<uint32_t>( + x, y, xg, yg, + centerX, centerY, m_width - centerX, m_height - centerY, + 1, m_width, (uint32_t)color, mirrors, fillDir); + break; + default: + // フォーマット不正(=> 未初期化) + return -2; + } + } else { + // P=Y, Q=X (転置あり) で描画する + int mirrors = (sides & 1) ? (2) : (3); + int fillDir = fill ? 2 : 0; + switch (m_format) { + case FORMAT_RGB565: + case FORMAT_ARGB4444: + drawPolygonLineImpl<uint16_t>( + y, x, yg, xg, + centerY, centerX, m_height - centerY, m_width - centerX, + m_width, 1, (uint16_t)color, mirrors, fillDir); + break; + case FORMAT_RGB888: + case FORMAT_ARGB8888: + drawPolygonLineImpl<uint32_t>( + y, x, yg, xg, + centerY, centerX, m_height - centerY, m_width - centerX, + m_width, 1, (uint32_t)color, mirrors, fillDir); + break; + default: + // フォーマット不正(=> 未初期化) + return -2; + } + } + + // 現在位置を更新 + x = xg; + y = yg; + + if ((centerY + y) >= m_height) { + // 現在位置がバッファ範囲外にでた + // => これ以上の描画処理は不要 + return 0; + } + } + + if (sides & 1) { + // 頂点数が奇数の場合、最後の位置から水平(X方向)に結んで図形を閉じる + // (ただし、fillした場合はすでに閉じられているので不要) + // (また、外接円半径が小さすぎてx==0となっている場合も不要) + if ((!fill) && (x > 0)) { + int yp = centerY + y; + // (yp >= m_height)のケースは上記の頂点描画ループでreturn済みのため、 + // ここでは(yp < m_height)が常に真になる。 + if ((0 <= yp)/* && (yp < m_height)*/) { + (void)drawLine(centerX - x + 1, yp, centerX + x - 1, yp, color); + } + } + } else if (sides & 2) { + // 頂点数が偶数かつ、4で割って2余る数の場合、 + // 次の頂点へ垂直(Y方向)に結んで図形を閉じる。 + + int frames = FRAME_LEFT | FRAME_RIGHT; + + // Y座標の範囲を絞る + int yp_min = centerY + y + 1; + if (yp_min < 0) { + yp_min = 0; + } + int yp_max = centerY - y - 1; + if (yp_max >= m_height) { + yp_max = m_height - 1; + } + + // X座標の範囲を絞る + int xp_min = centerX - x; + if (xp_min < 0) { + frames &= ~FRAME_LEFT; + xp_min = 0; + } + int xp_max = centerX + x; + if (xp_max >= m_width) { + frames &= ~FRAME_RIGHT; + xp_max = m_width - 1; + } + + // プロット(矩形描画を流用) + switch (m_format) { + case FORMAT_RGB565: + case FORMAT_ARGB4444: + (void)drawRectImpl<uint16_t>(xp_min, yp_min, xp_max, yp_max, (uint16_t)color, fill, frames); + break; + case FORMAT_RGB888: + case FORMAT_ARGB8888: + (void)drawRectImpl<uint32_t>(xp_min, yp_min, xp_max, yp_max, color, fill, frames); + break; + default: + // フォーマット不正(=> 未初期化) + return -2; + } + } + + return 0; + } + + int Graphics::drawText(char* text, int x, int y, int size, uint32_t color, uint32_t background) { + int byte_per_pixel; + switch (m_format) { + case FORMAT_RGB565: + case FORMAT_ARGB4444: + byte_per_pixel = 2; + color = (color & 0xFF00) >> 8 | (color & 0x00FF) << 8; + background = (background & 0xFF00) >> 8 | (background & 0x00FF) << 8; + break; + case FORMAT_RGB888: + case FORMAT_ARGB8888: + byte_per_pixel = 4; + color = (color & 0xFF000000) >> 24 | (color & 0x00FF0000) >> 8 + | (color & 0x0000FF00) << 8 | (color & 0x000000FF) << 24; + background = (background & 0xFF000000) >> 24 | (background & 0x00FF0000) >> 8 + | (background & 0x0000FF00) << 8 | (background & 0x000000FF) << 24; + break; + default: + // フォーマット不正(=> 未初期化) + return -2; + } + AsciiFont ascii((uint8_t*)m_buf, m_width, m_height, m_width*byte_per_pixel, byte_per_pixel, background); + ascii.DrawStr(text, x, y, color, size); + return 0; + } + + template <typename T> + int Graphics::drawImageImpl(T* image, int xs, int ys, int xe, int ye, int dx, int dy, int width) + { + T *dst_line = getBuffer<T>(xs, ys); + T *src_line = image + dx + dy * width; + for (int yd = ys; yd <= ye; ++yd) { + T *dst_ptr = dst_line; + T *src_ptr = src_line; + for (int xd = xs; xd <= xe; ++xd) { + *dst_ptr = *src_ptr; + ++dst_ptr;++src_ptr; + } + dst_line += m_width; + src_line += width; + } + return 0; + } + + int Graphics::drawImage(char* image, int x, int y, int width, int height) + { + if (!m_buf) { + // 未初期化 + return -2; + } + + if ((image == NULL) || (width < 0) || (height < 0)) { + // 引数が不正(何もしない) + return 0; + } + + if ((width == 0) || (height == 0)) { + // 描画領域なし(何もしない) + return 0; + } + + // 始点側の描画領域内座標を計算 => (xs, ys) + int xs = x; + if (xs < 0) { + xs = 0; + } + int ys = y; + if (ys < 0) { + ys = 0; + } + + if ((xs >= m_width) || (ys >= m_height)) { + // 描画領域なし(何もしない) + return 0; + } + + // 終点側の描画領域内座標を計算 => (xe, ye) + int xe = x + width - 1; + if (xe >= m_width) { + xe = m_width - 1; + } + int ye = y + height - 1; + if (ye >= m_height) { + ye = m_height - 1; + } + + if ((xe < 0) || (ye < 0)) { + // 描画領域なし(何もしない) + return 0; + } + + // 描画実行 + switch (m_format) { + case FORMAT_RGB565: + case FORMAT_ARGB4444: + return drawImageImpl<uint16_t>((uint16_t*)image, xs, ys, xe, ye, xs-x, ys-y, width); + case FORMAT_RGB888: + case FORMAT_ARGB8888: + return drawImageImpl<uint32_t>((uint32_t*)image, xs, ys, xe, ye, xs-x, ys-y, width); + default: + // フォーマット不正(=> 未初期化) + return -2; + } + } + + void Graphics::flush(void) { + switch (m_format) { + case FORMAT_RGB565: + case FORMAT_ARGB4444: + dcache_clean(m_buf, (m_width*m_height*2 + 31)&~31); + break; + case FORMAT_RGB888: + case FORMAT_ARGB8888: + dcache_clean(m_buf, (m_width*m_height*4 + 31)&~31); + break; + default: + break; + } + } +}} // namespace os::graphics::
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/iotjs/deps/posix/platform/mbedos5/primitives.h Thu Jul 11 18:48:09 2019 +0900 @@ -0,0 +1,234 @@ +/* Copyright 2017-present Renesas Electronics Corporation and other contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT 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 PRIMITIVES_INCL +#define PRIMITIVES_INCL + +#include <list> +#include <map> + +#include <mbed.h> + #define LWIP_DONT_PROVIDE_BYTEORDER_FUNCTIONS + #define LWIP_HDR_IP_ADDR_H +#include <EthernetInterface.h> + +#include "DisplayBace.h" +#include "JPEG_Converter.h" + +#define os mbed + +namespace os { namespace primitives { + +typedef ::Mutex Mutex; + +class lock_guard { + Mutex& m_; + lock_guard( const lock_guard& ); + lock_guard& operator=( const lock_guard& ); +public: + explicit lock_guard( Mutex& m ) : m_( m ) { m_.lock(); } + ~lock_guard() { m_.unlock(); } +}; + +typedef ::Semaphore Semaphore; + +class CondVar { // condition variable + Mutex mutex_; + std::list<Semaphore*> sems_; + CondVar( const CondVar& ); + CondVar& operator=( const CondVar& ); +public: + CondVar(); + void notify_one(); + void wait( P4(pthread_mutex_t)* lock ); +}; + +typedef ::Thread Thread; + +typedef ::nsapi_version_t nsapi_version_t; +typedef ::nsapi_addr_t nsapi_addr_t; + +typedef P4(in_addr) ip4_addr_t; +typedef P4(in6_addr) ip6_addr_t; +struct ip_addr_t { + enum { UNSPEC=0, IPv4=4, IPv6=6 } version; + bool v4() const { return version == IPv4; } + bool v6() const { return version == IPv6; } + bool valid() const { return v4() || v6(); } + union { + ip4_addr_t ip4; + ip6_addr_t ip6; + u16_t u16[8]; + u8_t bytes[16]; + } value; +}; + +typedef ::nsapi_error_t nsapi_error_t; +typedef ::nsapi_size_or_error_t nsapi_error_t; +typedef ::nsapi_size_t nsapi_size_t; + +class SocketAddress : public ::SocketAddress { +public: + SocketAddress(const char* addr, uint16_t port=0) : ::SocketAddress(addr, port) {} + SocketAddress(const void* bytes, nsapi_version_t version, uint16_t port=0) : ::SocketAddress(bytes, version, port) {} + SocketAddress(nsapi_addr_t addr=nsapi_addr_t(), uint16_t port=0) : ::SocketAddress(addr, port) {} + void dbg() const; + static SocketAddress trans(const P4(sockaddr)& addr); + static int trans(const SocketAddress& sa, void* addr, P4(socklen_t)* addrlen); +}; + +typedef ::EthernetInterface EthernetInterface; +typedef ::Socket Socket; +typedef ::UDPSocket UDPSocket; +typedef ::TCPSocket TCPSocket; +typedef ::TCPServer TCPServer; + +class Nic { + mutable EthernetInterface eth_; + bool connect(); + bool disconnect(); + Nic( const Nic& ); + Nic& operator=( const Nic& ); + bool is_ip_assigned() const; + typedef std::map<std::string, std::string> Params; + Params parse_params( const std::string& str_params ) const; + const char* targetIF() const { return "ETHERNET"; } +public: + EthernetInterface& iface() { connect(); return eth_; } + Nic() : eth_() {} + ~Nic() { disconnect(); } + static char* enumerate(); + bool ifup(const std::string& nic, const std::string& str_params); + bool ifdown(const std::string& nic); + char* ifconfig(const std::string& nic); + bool ntpdate(const std::string& nic, const char* server="0.pool.ntp.org", int port=123, int timeout=10*1000); +}; + +}} // namespace os::primitives:: + +namespace os { namespace video { + +class Video { + bool camera_initialize(); + video_source_t video_source; +public: + Video() {}; + ~Video() {}; + bool open(video_source_t video_source); + bool close(void); + bool start(void* buf); + bool stop(); +}; + +}} // namespace os::video:: + +namespace os { namespace lcd { + +class Lcd { + lcd_t lcd; +public: + Lcd() {}; + ~Lcd() {}; + bool open(lcd_t *lcd); + bool close(void); + bool start(lcd_layer_t lcd_layer); + bool stop(lcd_layer_id_t id); + bool update(lcd_layer_t lcd_layer); +}; + +}} // namespace os::lcd:: + +namespace os { namespace jpeg { + +class Jpeg { + JPEG_Converter Jcu; +public: + int encode(jpeg_convert_data_t encode_data); + bool decode(jpeg_convert_data_t decode_data); +}; + +}} // namespace os::jpeg:: + +namespace os { namespace graphics { + +class Graphics { +public: + + Graphics(); + + int initFrameBuffer(char *buf, int width, int height, int format); + int drawLine(int startX, int startY, int endX, int endY, uint32_t color); + int drawRect(int x, int y, int width, int height, uint32_t color, int fill); + int drawArc(int centerX, int centerY, int radius, int startAngle, int endAngle, uint32_t color); + int drawCircle(int centerX, int centerY, int radius, uint32_t color, int fill); + int drawEllipse(int centerX, int centerY, int radiusX, int radiusY, uint32_t color, int fill); + int drawPolygon(int centerX, int centerY, int radius, int sides, uint32_t color, int fill); + int drawText(char* text, int x, int y, int size, uint32_t color, uint32_t background); + int drawImage(char* image, int x, int y, int width, int height); + void flush(void); + + enum { + FORMAT_RGB565 = 0, + FORMAT_RGB888 = 1, + FORMAT_ARGB8888 = 2, + FORMAT_ARGB4444 = 3, + }; + +private: + + char *m_buf; + int m_width; + int m_height; + int m_format; + + template <typename T> int drawLineImpl(int ps, int qs, int pe, int qe, int pm, int qm, int pb, int qb, T color); + template <typename T> int drawRectImpl(int xs, int ys, int xe, int ye, T color, int fill, int frames); + template <typename T> int drawArcImpl(int xc, int yc, int r, int xs, int ys, int as, int xe, int ye, int ae, T color); + template <typename T> int drawEllipseImpl(int xc, int yc, int a, int b, T color, int fill); + template <typename T> void drawPolygonLineImpl(int ps, int qs, int pe, int qe, int pc, int qc, int pm, int qm, int pb, int qb, T color, int mirrors, int fillDir); + template <typename T> int drawImageImpl(T* image, int xs, int ys, int xe, int ye, int dx, int dy, int width); + + template <typename T> inline T *getBuffer(int x, int y) { return &((T *)m_buf)[x + y * m_width]; } +}; + +}} // namespace os::graphics:: + +namespace helper { + + inline uint32_t htonl(uint32_t hostlong) { return __REV ( hostlong ); } + inline uint32_t ntohl(uint32_t netlong) { return __REV ( netlong ); } + inline uint16_t htons(uint16_t hostshort) { return __REV16( hostshort ); } + inline uint16_t ntohs(uint16_t netshort) { return __REV16( netshort ); } + + std::string& cwd(); + + int set_errno(int num); + int clear_errno(); + + union sockaddrs { + P4(sockaddr_storage)* sas; + const P4(sockaddr_storage)* csas; + P4(sockaddr)* sa; + const P4(sockaddr)* csa; + P4(sockaddr_in)* sa4; + const P4(sockaddr_in)* csa4; + P4(sockaddr_in6)* sa6; + const P4(sockaddr_in6)* csa6; + }; + +} // namespace helper:: + +#endif // #ifndef PRIMITIVES_INCL +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/iotjs/deps/posix/posix4.cpp Thu Jul 11 18:48:09 2019 +0900 @@ -0,0 +1,762 @@ +/* Copyright 2017-present Renesas Electronics Corporation and other contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT 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 "./posix4_target.h" + +inline const char* safe_str(const char* in) { return in ? in : "<null>"; } + +char* P4(getcwd)(char* buf, P4(size_t) size) +{ + TRACE(ENTER "getcwd(buf=%p, size=%u)", buf, size); + char* rc = posix::getcwd( buf, size ); + TRACE(LEAVE "getcwd(buf=%p, size=%u) = %s(errno:%d)", buf, size, safe_str(rc), errno); + return rc; +} + +int P4(chdir)(const char* path) +{ + TRACE(ENTER "chdir(path=%s)", safe_str(path)); + int rc = posix::chdir( path ); + TRACE(LEAVE "chdir(path=%s) = %d(errno:%d)", safe_str(path), rc, errno); + return rc; +} + +int P4(fdatasync)(int fd) +{ + TRACE(ENTER "fdatasync(fd=%d)", fd); + int rc = posix::fdatasync( fd ); + TRACE(LEAVE "fdatasync(fd=%d) = %d(errno:%d)", fd, rc, errno); + return rc; +} + +int P4(fsync)(int fd) +{ + TRACE(ENTER "fsync(fd=%d)", fd); + int rc = posix::fsync( fd ); + TRACE(LEAVE "fsync(fd=%d) = %d(errno:%d)", fd, rc, errno); + return rc; +} + +int P4(ftruncate)(int fd, P4(off_t) length) +{ + TRACE(ENTER "ftruncate(fd=%d, length=%ld)", fd, length); + int rc = posix::ftruncate( fd, length ); + TRACE(LEAVE "ftruncate(fd=%d, length=%ld) = %d(errno:%d)", fd, length, rc, errno); + return rc; +} + +int P4(scandir)(const char* dirp, struct P4(dirent)*** namelist, int (*filter)(const struct P4(dirent)*), int (*compar)(const struct P4(dirent)**, const struct P4(dirent)**)) +{ + TRACE(ENTER "scandir(dirp=%s, namelist=%p, filter=%p, compar=%p)", safe_str(dirp), namelist, filter, compar); + int rc = posix::scandir( dirp, namelist, filter, compar ); + TRACE(LEAVE "scandir(dirp=%s, namelist=%p, filter=%p, compar=%p) = %d(errno:%d)", safe_str(dirp), namelist, filter, compar, rc, errno); + return rc; +} + +int P4(utime)(const char* filename, const struct P4(utimbuf)* times) +{ + TRACE(ENTER "utime(filename=%s, times=%p)", safe_str(filename), times); + int rc = posix::utime( filename, times ); + TRACE(LEAVE "utime(filename=%s, times=%p) = %d(errno:%d)", safe_str(filename), times, rc, errno); + return rc; +} + +int P4(utimes)(const char* filename, const struct P4(timeval) times[2]) +{ + TRACE(ENTER "utimes(filename=%s, times[2]=maybe_later)", safe_str(filename)); + int rc = posix::utimes( filename, times ); + TRACE(LEAVE "utimes(filename=%s, times[2]=maybe_later) = %d(errno:%d)", safe_str(filename), rc, errno); + return rc; +} + +P4(ssize_t) P4(pread)(int fd, void* buf, P4(size_t) count, P4(off_t) offset) +{ + TRACE(ENTER "pread(fd=%d, buf=%p, count=%d, offset=%ld)", fd, buf, count, offset); + P4(ssize_t) rc = posix::pread( fd, buf, count, offset ); + TRACE(LEAVE "pread(fd=%d, buf=%p, count=%d, offset=%ld) = %d(errno:%d)", fd, buf, count, offset, rc, errno); + return rc; +} + +P4(ssize_t) P4(pwrite)(int fd, const void* buf, P4(size_t) count, P4(off_t) offset) +{ + TRACE(ENTER "pwrite(fd=%d, buf=%p, count=%d, offset=%ld)", fd, buf, count, offset); + P4(ssize_t) rc = posix::pwrite( fd, buf, count, offset ); + TRACE(LEAVE "pwrite(fd=%d, buf=%p, count=%d, offset=%ld) = %d(errno:%d)", fd, buf, count, offset, rc, errno); + return rc; +} + +P4(ssize_t) P4(readv)(int fd, const struct P4(iovec)* iov, int iovcnt) +{ + TRACE(ENTER "readv(fd=%d, iov=%p, iovcnt=%d)", fd, iov, iovcnt); + P4(ssize_t) rc = posix::readv( fd, iov, iovcnt ); + TRACE(LEAVE "readv(fd=%d, iov=%p, iovcnt=%d) = %d(errno:%d)", fd, iov, iovcnt, rc, errno); + return rc; +} + +P4(ssize_t) P4(writev)(int fd, const struct P4(iovec)* iov, int iovcnt) +{ + TRACE(ENTER "writev(fd=%d, iov=%p, iovcnt=%d)", fd, iov, iovcnt); + P4(ssize_t) rc = posix::writev( fd, iov, iovcnt ); + TRACE(LEAVE "writev(fd=%d, iov=%p, iovcnt=%d) = %d(errno:%d)", fd, iov, iovcnt, rc, errno); + return rc; +} + +int P4(utimensat)(int dirfd, const char* pathname, const struct P4(timespec) times[2], int flags) +{ + TRACE(ENTER "utimensat(dirfd=%d, pathname=%s, times=%p, flags=%d)", dirfd, safe_str(pathname), times, flags); + int rc = posix::utimensat( dirfd, pathname, times, flags ); + TRACE(LEAVE "utimensat(dirfd=%d, pathname=%s, times=%p, flags=%d) = %d(errno:%d)", dirfd, safe_str(pathname), times, flags, rc, errno); + return rc; +} + +int P4(clock_getres)(P4(clockid_t) clk_id, struct P4(timespec)* res) +{ + TRACE(ENTER "clock_getres(clk_id=%lu, res=%p)", clk_id, res); + int rc = posix::clock::getres( clk_id, res ); + TRACE(LEAVE "clock_getres(clk_id=%lu, res={%ld.%09ld}) = %d(errno:%d)", clk_id, res->tv_sec, res->tv_nsec, rc, errno); + return rc; +} + +int P4(clock_gettime)(P4(clockid_t) clk_id, struct P4(timespec)* tp) +{ + TRACE(ENTER "clock_gettime(clk_id=%lu, tp=%p)", clk_id, tp); + int rc = posix::clock::gettime( clk_id, tp ); + TRACE(LEAVE "clock_gettime(clk_id=%lu, tp={%ld.%09ld}) = %d(errno:%d)", clk_id, tp->tv_sec, tp->tv_nsec, rc, errno); + return rc; +} + +int P4(pthread_create)(P4(pthread_t)* thread, P4(pthread_attr_t)* attr, void* (*start_routine)(void*), void* arg) +{ + TRACE(ENTER "pthread_create(thread=%p, attr=%p, start_routine=%p, arg=%p)", thread, attr, start_routine, arg); + int rc = posix::pthread::create( thread, attr, start_routine, arg ); + TRACE(LEAVE "pthread_create(thread={%p}, attr=%p, start_routine=%p, arg=%p) = %d", *thread, attr, start_routine, arg, rc); + return rc; +} + +int P4(pthread_join)(P4(pthread_t) thread, void** retval) +{ + TRACE(ENTER "pthread_join(thread=%p, retval=%p)", thread, retval); + int rc = posix::pthread::join( thread, retval ); + TRACE(LEAVE "pthread_join(thread=%p, retval=%p) = %d", thread, retval, rc); + return rc; +} + +int P4(pthread_once)(P4(pthread_once_t)* once_control, void (*init_routine)(void)) +{ + TRACE(ENTER "pthread_once(once_control={0x%08X}, init_routine=%p)", *once_control, init_routine); + int rc = posix::pthread::once( once_control, init_routine ); + TRACE(LEAVE "pthread_once(once_control={0x%08X}, init_routine=%p) = %d", *once_control, init_routine, rc); + return rc; +} + +int P4(pthread_sigmask)(int how, const P4(sigset_t)* set, P4(sigset_t)* oldset) +{ + TRACE(ENTER "pthread_sigmask(how=%d, set=%p, oldset=%p)", how, set, oldset); + int rc = posix::pthread::sigmask( how, set, oldset ); + TRACE(LEAVE "pthread_sigmask(how=%d, set=%p, oldset=%p) = %d", how, set, oldset, rc); + return rc; +} + +int P4(pthread_attr_destroy)(P4(pthread_attr_t)* attr) +{ + TRACE(ENTER "pthread_attr_destroy(attr=%p)", attr); + int rc = posix::pthread::attr::destroy( attr ); + TRACE(LEAVE "pthread_attr_destroy(attr=%p) = %d", attr, rc); + return rc; +} + +int P4(pthread_cond_destroy)(P4(pthread_cond_t)* cond) +{ + TRACE(ENTER "pthread_cond_destroy(cond=%p)", cond); + int rc = posix::pthread::cond::destroy( cond ); + TRACE(LEAVE "pthread_cond_destroy(cond=%p) = %d", cond, rc); + return rc; +} + +int P4(pthread_cond_init)(P4(pthread_cond_t)* cond, P4(pthread_condattr_t)* cond_attr) +{ + TRACE(ENTER "pthread_cond_init(cond=%p, cond_attr=%p)", cond, cond_attr); + int rc = posix::pthread::cond::init( cond, cond_attr ); + TRACE(LEAVE "pthread_cond_init(cond=%p, cond_attr=%p) = %d", cond, cond_attr, rc); + return rc; +} + +int P4(pthread_cond_signal)(P4(pthread_cond_t)* cond) +{ + TRACE(ENTER "pthread_cond_signal(cond=%p)", cond); + int rc = posix::pthread::cond::signal( cond ); + TRACE(LEAVE "pthread_cond_signal(cond=%p) = %d", cond, rc); + return rc; +} + +int P4(pthread_cond_wait)(P4(pthread_cond_t)* cond, P4(pthread_mutex_t)* mutex) +{ + TRACE(ENTER "pthread_cond_wait(cond=%p, mutex=%p)", cond, mutex); + int rc = posix::pthread::cond::wait( cond, mutex ); + TRACE(LEAVE "pthread_cond_wait(cond=%p, mutex=%p) = %d", cond, mutex, rc); + return rc; +} + +int P4(pthread_condattr_destroy)(P4(pthread_condattr_t)* attr) +{ + TRACE(ENTER "pthread_condattr_destroy(attr=%p)", attr); + int rc = posix::pthread::condattr::destroy( attr ); + TRACE(LEAVE "pthread_condattr_destroy(attr=%p) = %d", attr, rc); + return rc; +} + +int P4(pthread_condattr_init)(P4(pthread_condattr_t)* attr) +{ + TRACE(ENTER "pthread_condattr_init(attr=%p)", attr); + int rc = posix::pthread::condattr::init( attr ); + TRACE(LEAVE "pthread_condattr_init(attr=%p) = %d", attr, rc); + return rc; +} + +int P4(pthread_condattr_setclock)(P4(pthread_condattr_t)* attr, P4(clockid_t) clock_id) +{ + TRACE(ENTER "pthread_condattr_setclock(attr=%p, clock_id=%lu)", attr, clock_id); + int rc = posix::pthread::condattr::setclock( attr, clock_id ); + TRACE(LEAVE "pthread_condattr_setclock(attr=%p, clock_id=%lu) = %d", attr, clock_id, rc); + return rc; +} + +int P4(pthread_mutex_destroy)(P4(pthread_mutex_t)* mutex) +{ + TRACE(ENTER "pthread_mutex_destroy(mutex=%p)", mutex); + int rc = posix::pthread::mutex::destroy( mutex ); + TRACE(LEAVE "pthread_mutex_destroy(mutex=%p) = %d", mutex, rc); + return rc; +} + +int P4(pthread_mutex_init)(P4(pthread_mutex_t)* mutex, const P4(pthread_mutexattr_t)* mutexattr) +{ + TRACE(ENTER "pthread_mutex_init(mutex=%p, mutexattr=%p)", mutex, mutexattr); + int rc = posix::pthread::mutex::init( mutex, mutexattr ); + TRACE(LEAVE "pthread_mutex_init(mutex=%p, mutexattr=%p) = %d", mutex, mutexattr, rc); + return rc; +} + +int P4(pthread_mutex_lock)(P4(pthread_mutex_t)* mutex) +{ + TRACE(ENTER "pthread_mutex_lock(mutex=%p)", mutex); + int rc = posix::pthread::mutex::lock( mutex ); + TRACE(LEAVE "pthread_mutex_lock(mutex=%p) = %d", mutex, rc); + return rc; +} + +int P4(pthread_mutex_unlock)(P4(pthread_mutex_t)* mutex) +{ + TRACE(ENTER "pthread_mutex_unlock(mutex=%p)", mutex); + int rc = posix::pthread::mutex::unlock( mutex ); + TRACE(LEAVE "pthread_mutex_unlock(mutex=%p) = %d", mutex, rc); + return rc; +} + +int P4(pthread_rwlock_destroy)(P4(pthread_rwlock_t)* rwlock) +{ + TRACE(ENTER "pthread_rwlock_destroy(rwlock=%p)", rwlock); + int rc = posix::pthread::rwlock::destroy( rwlock ); + TRACE(LEAVE "pthread_rwlock_destroy(rwlock=%p) = %d", rwlock, rc); + return rc; +} + +int P4(pthread_rwlock_init)(P4(pthread_rwlock_t)* rwlock, const P4(pthread_rwlockattr_t)* attr) +{ + TRACE(ENTER "pthread_rwlock_init(rwlock=%p, attr=%p)", rwlock, attr); + int rc = posix::pthread::rwlock::init( rwlock, attr ); + TRACE(LEAVE "pthread_rwlock_init(rwlock=%p, attr=%p) = %d", rwlock, attr, rc); + return rc; +} + +int P4(pthread_rwlock_rdlock)(P4(pthread_rwlock_t)* rwlock) +{ + TRACE(ENTER "pthread_rwlock_rdlock(rwlock=%p)", rwlock); + int rc = posix::pthread::rwlock::rdlock( rwlock ); + TRACE(LEAVE "pthread_rwlock_rdlock(rwlock=%p) = %d", rwlock, rc); + return rc; +} + +int P4(pthread_rwlock_unlock)(P4(pthread_rwlock_t)* rwlock) +{ + TRACE(ENTER "pthread_rwlock_unlock(rwlock=%p)", rwlock); + int rc = posix::pthread::rwlock::unlock( rwlock ); + TRACE(LEAVE "pthread_rwlock_unlock(rwlock=%p) = %d", rwlock, rc); + return rc; +} + +struct P4(cmsghdr)* P4(cmsg_nxthdr)(struct P4(msghdr)* mhdr, struct P4(cmsghdr)* cmsg) +{ +#define OFFSET(addr, bytes) ((void*)((char*)addr + bytes)) + if((P4(size_t))cmsg->cmsg_len < sizeof( struct P4(cmsghdr) )) { + return 0; + } + cmsg = (struct P4(cmsghdr)*)OFFSET( cmsg, CMSG_ALIGN( cmsg->cmsg_len ) ); + if( cmsg + 1 > OFFSET( mhdr->msg_control, mhdr->msg_controllen ) ) { + return 0; + } + if( OFFSET( cmsg, CMSG_ALIGN( cmsg->cmsg_len ) ) > OFFSET( mhdr->msg_control, mhdr->msg_controllen ) ) { + return 0; + } +#undef OFFSET + return cmsg; +} + +int P4(accept)(int sockfd, struct P4(sockaddr)* addr, P4(socklen_t)* addrlen) +{ + TRACE(ENTER "accept(sockfd=%d, addr=%p, addrlen=%p)", sockfd, addr, addrlen); + int rc = posix::sock::accept( sockfd, addr, addrlen ); + TRACE(LEAVE "accept(sockfd=%d, addr=%p, addrlen=%p) = %d(errno:%d)", sockfd, addr, addrlen, rc, errno); + return rc; +} + +int P4(bind)(int sockfd, const struct P4(sockaddr)* addr, P4(socklen_t) addrlen) +{ + TRACE(ENTER "bind(sockfd=%d, addr=%p, addrlen=%lu)", sockfd, addr, addrlen); + int rc = posix::sock::bind( sockfd, addr, addrlen ); + TRACE(LEAVE "bind(sockfd=%d, addr=%p, addrlen=%lu) = %d(errno:%d)", sockfd, addr, addrlen, rc, errno); + return rc; +} + +int P4(connect)(int sockfd, const struct P4(sockaddr)* addr, P4(socklen_t) addrlen) +{ + TRACE(ENTER "connect(sockfd=%d, addr=%p, addrlen=%lu)", sockfd, addr, addrlen); + int rc = posix::sock::connect( sockfd, addr, addrlen ); + TRACE(LEAVE "connect(sockfd=%d, addr=%p, addrlen=%lu) = %d(errno:%d)", sockfd, addr, addrlen, rc, errno); + return rc; +} + +void P4(freeaddrinfo)(struct P4(addrinfo)* res) +{ + TRACE(ENTER "freeaddrinfo(res=%p)", res); + posix::sock::freeaddrinfo( res ); + TRACE(LEAVE "freeaddrinfo(res=%p)", res); +} + +int P4(getaddrinfo)(const char* node, const char* service, const struct P4(addrinfo)* hints, struct P4(addrinfo)** res) +{ + TRACE(ENTER "getaddrinfo(node={%s}, service={%s}, hints=%p, res=%p)", safe_str(node), safe_str(service), hints, res); + int rc = posix::sock::getaddrinfo( node, service, hints, res ); + TRACE(LEAVE "getaddrinfo(node={%s}, service={%s}, hints=%p, res=%p) = %d", safe_str(node), safe_str(service), hints, res, rc); + return rc; +} + +int P4(getsockname)(int sockfd, struct P4(sockaddr)* addr, P4(socklen_t)* addrlen) +{ + TRACE(ENTER "getsockname(sockfd=%d, addr=%p, addrlen={%ld})", sockfd, addr, *addrlen); + int rc = posix::sock::getsockname( sockfd, addr, addrlen ); + TRACE(LEAVE "getsockname(sockfd=%d, addr=%p, addrlen={%ld}) = %d(errno:%d)", sockfd, addr, *addrlen, rc, errno); + return rc; +} + +int P4(getsockopt)(int sockfd, int level, int optname, void* optval, P4(socklen_t)* optlen) +{ + TRACE(ENTER "getsockopt(sockfd=%d, level=%d, optname=%d, optval=%p, optlen=%p)", sockfd, level, optname, optval, optlen); + uint32_t rc = posix::sock::getsockopt( sockfd, level, optname, optval, optlen ); + TRACE(LEAVE "getsockopt(sockfd=%d, level=%d, optname=%d, optval=%p, optlen=%p) = %lu(errno:%d)", sockfd, level, optname, optval, optlen, rc, errno); + return rc; +} + +uint32_t P4(htonl)(uint32_t hostlong) +{ + TRACE(ENTER "htonl(hostlong=0x%08lX)", hostlong); + uint32_t rc = posix::sock::htonl( hostlong ); + TRACE(LEAVE "htonl(hostlong=0x%08lX) = 0x%08lX", hostlong, rc); + return rc; +} + +uint16_t P4(htons)(uint16_t hostshort) +{ + TRACE(ENTER "htons(hostshort=0x%04X)", hostshort); + uint16_t rc = posix::sock::htons( hostshort ); + TRACE(LEAVE "htons(hostshort=0x%04X) = 0x%04X", hostshort, rc); + return rc; +} + +unsigned int P4(if_nametoindex)(const char* ifname) +{ + TRACE(ENTER "if_nametoindex(ifname={%s})", safe_str(ifname)); + unsigned int rc = posix::sock::if_nametoindex( ifname ); + TRACE(LEAVE "if_nametoindex(ifname={%s}) = %u(errno:%d)", safe_str(ifname), rc, errno); + return rc; +} + +int P4(listen)(int sockfd, int backlog) +{ + TRACE(ENTER "listen(sockfd=%d, backlog=%d)", sockfd, backlog); + int rc = posix::sock::listen( sockfd, backlog ); + TRACE(LEAVE "listen(sockfd=%d, backlog=%d) = %d(errno:%d)", sockfd, backlog, rc, errno); + return rc; +} + +uint16_t P4(ntohs)(uint16_t netshort) +{ + TRACE(ENTER "ntohs(netshort=0x%04X)", netshort); + uint16_t rc = posix::sock::ntohs( netshort ); + TRACE(LEAVE "ntohs(netshort=0x%04X) = 0x%04X", netshort, rc); + return rc; +} + +P4(ssize_t) P4(recvmsg)(int sockfd, struct P4(msghdr)* msg, int flags) +{ + TRACE(ENTER "recvmsg(sockfd=%d, msg=%p, flags=%d)", sockfd, msg, flags); + P4(ssize_t) rc = posix::sock::recvmsg( sockfd, msg, flags ); + TRACE(LEAVE "recvmsg(sockfd=%d, msg=%p, flags=%d) = %d(errno:%d)", sockfd, msg, flags, rc, errno); + return rc; +} + +P4(ssize_t) P4(sendmsg)(int sockfd, const struct P4(msghdr)* msg, int flags) +{ + TRACE(ENTER "sendmsg(sockfd=%d, msg=%p, flags=%d)", sockfd, msg, flags); + P4(ssize_t) rc = posix::sock::sendmsg( sockfd, msg, flags ); + TRACE(LEAVE "sendmsg(sockfd=%d, msg=%p, flags=%d) = %d(errno:%d)", sockfd, msg, flags, rc, errno); + return rc; +} + +int P4(setsockopt)(int sockfd, int level, int optname, const void* optval, P4(socklen_t) optlen) +{ + TRACE(ENTER "setsockopt(sockfd=%d, level=%d, optname=%d, optval=%p, optlen=%lu)", sockfd, level, optname, optval, optlen); + int rc = posix::sock::setsockopt( sockfd, level, optname, optval, optlen ); + TRACE(LEAVE "setsockopt(sockfd=%d, level=%d, optname=%d, optval=%p, optlen=%lu) = %d(errno:%d)", sockfd, level, optname, optval, optlen, rc, errno); + return rc; +} + +int P4(shutdown)(int sockfd, int how) +{ + TRACE(ENTER "shutdown(sockfd=%d, how=%d)", sockfd, how); + int rc = posix::sock::shutdown( sockfd, how ); + TRACE(LEAVE "shutdown(sockfd=%d, how=%d) = %d(errno:%d)", sockfd, how, rc, errno); + return rc; +} + +int P4(socket)(int domain, int type, int protocol) +{ + TRACE(ENTER "socket(domain=%d, type=%d, protocol=%d)", domain, type, protocol); + int rc = posix::sock::socket( domain, type, protocol ); + TRACE(LEAVE "socket(domain=%d, type=%d, protocol=%d) = %d(errno:%d)", domain, type, protocol, rc, errno); + return rc; +} + +int P4(nanosleep)(const struct P4(timespec)* req, struct P4(timespec)* rem) +{ + return posix::sys::nanosleep( req, rem ); +} + +int P4(pipe)(int pipefd[2]) +{ + TRACE(ENTER "pipe(pipefd[2]=[%d,%d])", pipefd[0], pipefd[1]); + int rc = posix::sys::pipe( pipefd ); + TRACE(LEAVE "pipe(pipefd[2]=[%d,%d]) = %d(errno:%d)", pipefd[0], pipefd[1], rc, errno); + return rc; +} + +long P4(sysconf)(int name) +{ + TRACE(ENTER "sysconf(name=%d)", name); + long rc = posix::sys::sysconf( name ); + TRACE(LEAVE "sysconf(name=%d) = %ld(errno:%d)", name, rc, errno); + return rc; +} + + +P4(ssize_t) P4(preadv)(int fd, const struct P4(iovec)* iov, int iovcnt, P4(off_t) offset) +{ + TRACE(ENTER "preadv(fd=%d, iov=%p, iovcnt=%d, offset=%ld)", fd, iov, iovcnt, offset); + P4(ssize_t) rc = linux::preadv( fd, iov, iovcnt, offset ); + TRACE(LEAVE "preadv(fd=%d, iov=%p, iovcnt=%d, offset=%ld) = %d(errno:%d)", fd, iov, iovcnt, offset, rc, errno); + return rc; +} + +P4(ssize_t) P4(pwritev)(int fd, const struct P4(iovec)* iov, int iovcnt, P4(off_t) offset) +{ + TRACE(ENTER "pwritev(fd=%d, iov=%p, iovcnt=%d, offset=%ld)", fd, iov, iovcnt, offset); + P4(ssize_t) rc = linux::pwritev( fd, iov, iovcnt, offset ); + TRACE(LEAVE "pwritev(fd=%d, iov=%p, iovcnt=%d, offset=%ld) = %d(errno:%d)", fd, iov, iovcnt, offset, rc, errno); + return rc; +} + +int P4(epoll_create)(int size) +{ + TRACE(ENTER "epoll_create(size=%d)", size); + int rc = linux::epoll::create( size ); + TRACE(LEAVE "epoll_create(size=%d) = %d(errno:%d)", size, rc, errno); + return rc; +} + +int P4(epoll_create1)(int flags) +{ + TRACE(ENTER "epoll_create1(flags=0x%08X)", flags); + int rc = linux::epoll::create1( flags ); + TRACE(LEAVE "epoll_create1(flags=0x%08X) = %d(errno:%d)", flags, rc, errno); + return rc; +} + +int P4(epoll_ctl)(int epfd, int op, int fd, struct P4(poll_event)* event) +{ + TRACE(ENTER "epoll_ctl(epfd=%d, op=%d, fd=%d, event=%p{0x%08lX})", epfd, op, fd, event, event->events); + int rc = linux::epoll::ctl( epfd, op, fd, event ); + TRACE(LEAVE "epoll_ctl(epfd=%d, op=%d, fd=%d, event=%p) = %d(errno:%d)", epfd, op, fd, event, rc, errno); + return rc; +} + +int P4(epoll_pwait)(int epfd, struct P4(poll_event)* events, int maxevents, int timeout, const P4(sigset_t)* sigmask) +{ + TRACE(ENTER "epoll_pwait(epfd=%d, events=%p, maxevents=%d, timeout=%d, sigmask=%p)", epfd, events, maxevents, timeout, sigmask); + int rc = linux::epoll::pwait( epfd, events, maxevents, timeout, sigmask ); + TRACE(LEAVE "epoll_pwait(epfd=%d, events=%p, maxevents=%d, timeout=%d, sigmask=%p) = %d(errno:%d)", epfd, events, maxevents, timeout, sigmask, rc, errno); + return rc; +} + +int P4(epoll_wait)(int epfd, struct P4(poll_event)* events, int maxevents, int timeout) +{ + TRACE(ENTER "epoll_wait(epfd=%d, events=%p, maxevents=%d, timeout=%d)", epfd, events, maxevents, timeout); + int rc = linux::epoll::wait( epfd, events, maxevents, timeout ); + TRACE(LEAVE "epoll_wait(epfd=%d, events=%p, maxevents=%d, timeout=%d) = %d(errno:%d)", epfd, events, maxevents, timeout, rc, errno); + return rc; +} + +int P4(eventfd)(unsigned int initval, int flags) +{ + TRACE(ENTER "eventfd(initval=%u, flags=%d)", initval, flags); + int rc = linux::epoll::eventfd( initval, flags ); + TRACE(LEAVE "eventfd(initval=%u, flags=%d) = %d(errno:%d)", initval, flags, rc, errno); + return rc; +} + +int P4(eventfd2)(unsigned int initval, int flags) +{ + TRACE(ENTER "eventfd2(initval=%u, flags=0x%08X)", initval, flags); + int rc = linux::epoll::eventfd2( initval, flags ); + TRACE(LEAVE "eventfd2(initval=%u, flags=0x%08X) = %d(errno:%d)", initval, flags, rc, errno); + return rc; +} + +int P4(accept4)(int fd, struct P4(sockaddr)* addr, P4(socklen_t)* addr_len, int flags) +{ + TRACE(ENTER "accept4(fd=%d, addr=%p, addr_len=%p, flags=%d)", fd, addr, addr_len, flags); + int rc = linux::sock::accept4( fd, addr, addr_len, flags ); + TRACE(LEAVE "accept4(fd=%d, addr=%p, addr_len=%p, flags=%d) = %d(errno:%d)", fd, addr, addr_len, flags, rc, errno); + return rc; +} + +int P4(socketcall)(int call, unsigned long* args) +{ + TRACE(ENTER "socketcall(call=%d, args=%p)", call, args); + int rc = linux::sock::socketcall( call, args ); + TRACE(LEAVE "socketcall(call=%d, args=%p) = %d(errno:%d)", call, args, rc, errno); + return rc; +} + +int P4(ioctl)(int fd, unsigned long request, ...) +{ + TRACE(ENTER "ioctl(fd=%d, request=0x%08lX, ...)", fd, request); + va_list args; + va_start( args, request ); + int rc = linux::sys::ioctl( fd, request, args ); + va_end( args ); + TRACE(LEAVE "ioctl(fd=%d, request=0x%08lX, ...) = %d(errno:%d)", fd, request, rc, errno); + return rc; +} + +long P4(syscall)(long number, ...) +{ + TRACE(ENTER "syscall(number=%ld, ...)", number); + va_list args; + va_start( args, number ); + long rc = linux::sys::syscall( number, args ); + va_end( args ); + TRACE(LEAVE "syscall(number=%ld, ...) = %ld(errno:%d)", number, rc, errno); + return rc; +} + +int P4(pipe2)(int pipefd[2], int flags) +{ + TRACE(ENTER "pipe2(pipefd[]=[%d, %d], flags=%d)", pipefd[0], pipefd[1], flags); + int rc = linux::sys::pipe2( pipefd, flags ); + TRACE(LEAVE "pipe2(pipefd[]=[%d, %d], flags=%d) = %d(errno:%d)", pipefd[0], pipefd[1], flags, rc, errno); + return rc; +} + +void* P4(dlopen)(const char* filename, int flag) +{ + TRACE(ENTER "dlopen(filename=%s, flag=%d)", safe_str(filename), flag); + void* rc = linux::sys::dlopen( filename, flag ); + TRACE(ENTER "dlopen(filename=%s, flag=%d) = %p", safe_str(filename), flag, rc); + return rc; +} + +void* P4(dlsym)(void* handle, char* symbol) +{ + TRACE(ENTER "dlsym(handle=%p, symbol=%s)", handle, safe_str(symbol)); + void* rc = linux::sys::dlsym( handle, symbol ); + TRACE(ENTER "dlsym(handle=%p, symbol=%s) = %p", handle, safe_str(symbol), rc); + return rc; +} + +int P4(dlclose)(void* handle) +{ + TRACE(ENTER "dlclose(handle=%p)", handle); + int rc = linux::sys::dlclose( handle ); + TRACE(ENTER "dlclose(handle=%p) = %d", handle, rc); + return rc; +} + +char** P4(backtrace_symbols)(void*const* buffer, int size) +{ + TRACE(ENTER "backtrace_symbols(buffer=%p, size=%d)", buffer, size); + char** rc = linux::debug::backtrace_symbols( buffer, size ); + TRACE(LEAVE "backtrace_symbols(buffer=%p, size=%d) = %p", buffer, size, rc); + return rc; +} + +int P4(backtrace)(void** buffer, int size) +{ + TRACE(ENTER "backtrace(buffer=%p, size=%d)", buffer, size); + int rc = linux::debug::backtrace( buffer, size ); + TRACE(LEAVE "backtrace(buffer=%p, size=%d) = %d", buffer, size, rc); + return rc; +} + + +void P4(abort)(void) +{ + TRACE(INFO "abort called from [%p]", CALLED_FROM); + overridden::abort(); +} + +int P4(gettimeofday)(struct P4(timeval)* tv, void* tz) +{ + TRACE(ENTER "overridden_gettimeofday(tv=%d, tz=%p)", tv, tz); + int rc = overridden::gettimeofday( tv, tz ); + TRACE(LEAVE "overridden_gettimeofday(tv=%d, tz=%p) = %d(errno:%d)", tv, tz, rc, errno); + return rc; +} + +P4(ssize_t) P4(read)(int fd, void* buf, P4(size_t) count) +{ + TRACE(ENTER "overridden_read(fd=%d, buf=%p, count=%u)", fd, buf, count); + P4(ssize_t) rc = overridden::read( fd, buf, count ); + TRACE(LEAVE "overridden_read(fd=%d, buf=%p, count=%u) = %d(errno:%d)", fd, buf, count, rc, errno); + return rc; +} + +P4(ssize_t) P4(write)(int fd, const void* buf, P4(size_t) count) +{ + TRACE(ENTER "overridden_write(fd=%d, buf=%p, count=%u)", fd, buf, count); + P4(ssize_t) rc = overridden::write( fd, buf, count ); + TRACE(LEAVE "overridden_write(fd=%d, buf=%p, count=%u) = %d(errno:%d)", fd, buf, count, rc, errno); + return rc; +} + +int P4(open)(const char* pathname, ...) +{ + TRACE(ENTER "overridden_open(pathname=%s, ...)", safe_str(pathname)); + va_list args; + va_start( args, pathname ); + int rc = overridden::open( pathname, args ); + va_end( args ); + TRACE(LEAVE "overridden_open(pathname=%s, ...) = %d(errno:%d)", safe_str(pathname), rc, errno); + return rc; +} + +int P4(close)(int fd) +{ + TRACE(ENTER "overridden_close(fd=%d)", fd); + int rc = overridden::close( fd ); + TRACE(LEAVE "overridden_close(fd=%d) = %d(errno:%d)", fd, rc, errno); + return rc; +} + +int P4(unlink)(const char* pathname) +{ + TRACE(ENTER "overridden_unlink(pathname=%s)", safe_str(pathname)); + int rc = overridden::unlink( pathname ); + TRACE(LEAVE "overridden_unlink(pathname=%s) = %d(errno:%d)", safe_str(pathname), rc, errno); + return rc; +} + +int P4(mkdir)(const char* pathname, P4(mode_t) mode) +{ + TRACE(ENTER "overridden_mkdir(pathname=%s, mode=0x%04X)", safe_str(pathname), mode); + int rc = overridden::mkdir( pathname, mode ); + TRACE(LEAVE "overridden_mkdir(pathname=%s, mode=0x%04X) = %d(errno:%d)", safe_str(pathname), mode, rc, errno); + return rc; +} + +int P4(rmdir)(const char* pathname) +{ + TRACE(ENTER "overridden_rmdir(pathname=%s)", safe_str(pathname)); + int rc = overridden::rmdir( pathname ); + TRACE(LEAVE "overridden_rmdir(pathname=%s) = %d(errno:%d)", safe_str(pathname), rc, errno); + return rc; +} + +int P4(stat)(const char* pathname, P4(stat_t)* buf) +{ + TRACE(ENTER "overridden_stat(pathname=%s, buf=%p)", safe_str(pathname), buf); + int rc = overridden::stat( pathname, buf ); + TRACE(LEAVE "overridden_stat(pathname=%s, buf=%p) = %d(errno:%d)", safe_str(pathname), buf, rc, errno); + return rc; +} + +int P4(fstat)(int fd, P4(stat_t)* buf) +{ + TRACE(ENTER "overridden_fstat(fd=%d, buf=%p)", fd, buf); + int rc = overridden::fstat( fd, buf ); + TRACE(LEAVE "overridden_fstat(fd=%d, buf=%p) = %d(errno:%d)", fd, buf, rc, errno); + return rc; +} + + +char* P4(nic_enumerate)(void) +{ + TRACE(ENTER "nic_enumerate()"); + char* rc = nic::enumerate(); + TRACE(LEAVE "nic_enumerate() = {%s}", safe_str(rc)); + return rc; +} + +int P4(nic_ifup)(const char* nic, const char* params) +{ + TRACE(ENTER "nic_ifup(nic={%s}, params={%s})", safe_str(nic), safe_str(params)); + int rc = nic::ifup( nic, params ); + TRACE(LEAVE "nic_ifup(nic={%s}, params={%s}) = %d", safe_str(nic), safe_str(params), rc); + return rc; +} + +int P4(nic_ifdown)(const char* nic) +{ + TRACE(ENTER "nic_ifdown(nic={%s})", safe_str(nic)); + int rc = nic::ifdown( nic ); + TRACE(LEAVE "nic_ifdown(nic={%s}) = %d", safe_str(nic), rc); + return rc; +} + +char* P4(nic_ifconfig)(const char* nic) +{ + TRACE(ENTER "nic_ifconfig(nic={%s})", safe_str(nic)); + char* rc = nic::ifconfig( nic ); + TRACE(LEAVE "nic_ifconfig(nic={%s}) = {%s}", safe_str(nic), safe_str(rc)); + return rc; +} + +int P4(nic_ntpdate)(const char* nic, const char* server, int port, int timeout) +{ + TRACE(ENTER "nic_ntpdate(nic={%s}, server={%s}, port=%d, timeout=%d)", safe_str(nic), safe_str(server), port, timeout); + int rc = nic::ntpdate( nic, server, port, timeout ); + TRACE(LEAVE "nic_ntpdate(nic={%s}, server={%s}, port=%d, timeout=%d) = %d", safe_str(nic), safe_str(server), port, timeout, rc); + return rc; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/iotjs/deps/posix/posix4.h Thu Jul 11 18:48:09 2019 +0900 @@ -0,0 +1,333 @@ +/* Copyright 2017-present Renesas Electronics Corporation and other contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT 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 POSIX4_INCL +#define POSIX4_INCL + +#include "./posix4_aux.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define P4_API(type,func) type P4(func) +#define POSIX_API P4_API +#define LINUX_API P4_API +#define OVRDN_API P4_API +#define NIC_API P4_API + +POSIX_API(char*, getcwd(char* buf, P4(size_t) size)); +POSIX_API(int, chdir(const char* path)); +POSIX_API(int, fdatasync(int fd)); +POSIX_API(int, fsync(int fd)); +POSIX_API(int, ftruncate(int fd, P4(off_t) length)); +POSIX_API(int, scandir(const char* dirp, struct P4(dirent)*** namelist, int (*filter)(const struct P4(dirent)*), int (*compar)(const struct P4(dirent)**, const struct P4(dirent)**))); +POSIX_API(int, utime(const char* filename, const struct utimbuf* times)); +POSIX_API(int, utimes(const char* filename, const struct timeval times[2])); +POSIX_API(P4(ssize_t), pread(int fd, void* buf, P4(size_t) count, P4(off_t) offset)); +POSIX_API(P4(ssize_t), pwrite(int fd, const void* buf, P4(size_t) count, P4(off_t) offset)); +POSIX_API(P4(ssize_t), readv(int fd, const struct P4(iovec)* iov, int iovcnt)); +POSIX_API(P4(ssize_t), writev(int fd, const struct P4(iovec)* iov, int iovcnt)); +POSIX_API(int, utimensat(int dirfd, const char* pathname, const struct P4(timespec) times[2], int flags)); + +POSIX_API(int, clock_getres(P4(clockid_t) clk_id, struct P4(timespec)* res)); +POSIX_API(int, clock_gettime(P4(clockid_t) clk_id, struct P4(timespec)* tp)); + +POSIX_API(int, pthread_create(P4(pthread_t)* thread, P4(pthread_attr_t)* attr, void* (*start_routine)(void*), void* arg)); +POSIX_API(int, pthread_join(P4(pthread_t) thread, void** retval)); +POSIX_API(int, pthread_once(P4(pthread_once_t)* once_control, void (*init_routine)(void))); +POSIX_API(int, pthread_sigmask(int how, const P4(sigset_t)* set, P4(sigset_t)* oldset)); +POSIX_API(int, pthread_attr_destroy(P4(pthread_attr_t)* attr)); +POSIX_API(int, pthread_cond_destroy(P4(pthread_cond_t)* cond)); +POSIX_API(int, pthread_cond_init(P4(pthread_cond_t)* cond, P4(pthread_condattr_t)* cond_attr)); +POSIX_API(int, pthread_cond_signal(P4(pthread_cond_t)* cond)); +POSIX_API(int, pthread_cond_wait(P4(pthread_cond_t)* cond, P4(pthread_mutex_t)* mutex)); +POSIX_API(int, pthread_condattr_destroy(P4(pthread_condattr_t)* attr)); +POSIX_API(int, pthread_condattr_init(P4(pthread_condattr_t)* attr)); +POSIX_API(int, pthread_condattr_setclock(P4(pthread_condattr_t)* attr, clockid_t clock_id)); +POSIX_API(int, pthread_mutex_destroy(P4(pthread_mutex_t)* mutex)); +POSIX_API(int, pthread_mutex_init(P4(pthread_mutex_t)* mutex, const P4(pthread_mutexattr_t)* mutexattr)); +POSIX_API(int, pthread_mutex_lock(P4(pthread_mutex_t)* mutex)); +POSIX_API(int, pthread_mutex_unlock(P4(pthread_mutex_t)* mutex)); +POSIX_API(int, pthread_rwlock_destroy(P4(pthread_rwlock_t)* rwlock)); +POSIX_API(int, pthread_rwlock_init(P4(pthread_rwlock_t)* rwlock, const P4(pthread_rwlockattr_t)* attr)); +POSIX_API(int, pthread_rwlock_rdlock(P4(pthread_rwlock_t)* rwlock)); +POSIX_API(int, pthread_rwlock_unlock(P4(pthread_rwlock_t)* rwlock)); + POSIX_API(int, pthread_cond_broadcast(P4(pthread_cond_t)* cond)); + POSIX_API(int, pthread_cond_timedwait(P4(pthread_cond_t)* cond, P4(pthread_mutex_t)* mutex, const struct P4(timespec)* abstime)); + POSIX_API(P4(pthread_t), pthread_self(void)); + POSIX_API(int, pthread_equal(P4(pthread_t) t1, P4(pthread_t) t2)); + POSIX_API(int, pthread_mutex_trylock(P4(pthread_mutex_t)* mutex)); + POSIX_API(int, pthread_rwlock_tryrdlock(P4(pthread_rwlock_t)* rwlock)); + POSIX_API(int, pthread_rwlock_trywrlock(P4(pthread_rwlock_t)* rwlock)); + POSIX_API(int, pthread_rwlock_wrlock(P4(pthread_rwlock_t)* rwlock)); + POSIX_API(int, sem_init(P4(sem_t)* sem, int pshared, unsigned int value)); + POSIX_API(int, sem_destroy(P4(sem_t)* sem)); + POSIX_API(int, sem_wait(P4(sem_t)* sem)); + POSIX_API(int, sem_trywait(P4(sem_t)* sem)); + POSIX_API(int, sem_post(P4(sem_t)* sem)); + +#define CMSG_ALIGN(len) (((len) + sizeof(P4(size_t)) - 1) & (P4(size_t))~(sizeof(P4(size_t)) - 1)) +#define CMSG_SPACE(len) (CMSG_ALIGN(len) + CMSG_ALIGN(sizeof(struct P4(cmsghdr)))) +#define CMSG_LEN(len) (CMSG_ALIGN(sizeof(struct P4(cmsghdr))) + (len)) +#define CMSG_FIRSTHDR(mhdr) ( \ + (P4(size_t))(mhdr)->msg_controllen >= sizeof(struct P4(cmsghdr)) \ + ? (struct P4(cmsghdr)*)(mhdr)->msg_control : (struct P4(cmsghdr)*)0 \ +) +P4_API(struct P4(cmsghdr)*, cmsg_nxthdr(struct P4(msghdr)* mhdr, struct P4(cmsghdr)* cmsg)); +#define CMSG_NXTHDR(mhdr, cmsg) P4(cmsg_nxthdr)(mhdr, cmsg) +#define CMSG_DATA(cmsg) ((unsigned char*)((struct P4(cmsghdr)*)(cmsg) + 1)) + +POSIX_API(int, accept(int sockfd, struct P4(sockaddr)* addr, P4(socklen_t)* addrlen)); +POSIX_API(int, bind(int sockfd, const struct P4(sockaddr)* addr, P4(socklen_t) addrlen)); +POSIX_API(int, connect(int sockfd, const struct P4(sockaddr)* addr, P4(socklen_t) addrlen)); +POSIX_API(void, freeaddrinfo(struct P4(addrinfo)* res)); +POSIX_API(int, getaddrinfo(const char* node, const char* service, const struct P4(addrinfo)* hints, struct P4(addrinfo)** res)); + POSIX_API(int, getpeername(int sockfd, struct P4(sockaddr)* addr, P4(socklen_t)* addrlen)); +POSIX_API(int, getsockname(int sockfd, struct P4(sockaddr)* addr, P4(socklen_t)* addrlen)); +POSIX_API(int, getsockopt(int sockfd, int level, int optname, void* optval, P4(socklen_t)* optlen)); +POSIX_API(uint32_t, htonl(uint32_t hostlong)); +POSIX_API(uint16_t, htons(uint16_t hostshort)); +POSIX_API(unsigned int, if_nametoindex(const char* ifname)); +POSIX_API(int, listen(int sockfd, int backlog)); +POSIX_API(uint16_t, ntohs(uint16_t netshort)); +POSIX_API(P4(ssize_t), recvmsg(int sockfd, struct P4(msghdr)* msg, int flags)); +POSIX_API(P4(ssize_t), sendmsg(int sockfd, const struct P4(msghdr)* msg, int flags)); +POSIX_API(int, setsockopt(int sockfd, int level, int optname, const void* optval, P4(socklen_t) optlen)); +POSIX_API(int, shutdown(int sockfd, int how)); +POSIX_API(int, socket(int domain, int type, int protocol)); + +POSIX_API(int, nanosleep(const struct P4(timespec)* req, struct P4(timespec)* rem)); +POSIX_API(int, pipe(int pipefd[2])); +POSIX_API(long, sysconf(int name)); + +LINUX_API(P4(ssize_t), preadv(int fd, const struct P4(iovec)* iov, int iovcnt, P4(off_t) offset)); +LINUX_API(P4(ssize_t), pwritev(int fd, const struct P4(iovec)* iov, int iovcnt, P4(off_t) offset)); + +LINUX_API(int, epoll_create(int size)); +LINUX_API(int, epoll_create1(int flags)); +LINUX_API(int, epoll_ctl(int epfd, int op, int fd, struct P4(poll_event)* event)); +LINUX_API(int, epoll_pwait(int epfd, struct P4(poll_event)* events, int maxevents, int timeout, const P4(sigset_t)* sigmask)); +LINUX_API(int, epoll_wait(int epfd, struct P4(poll_event)* events, int maxevents, int timeout)); +LINUX_API(int, eventfd(unsigned int initval, int flags)); +LINUX_API(int, eventfd2(unsigned int initval, int flags)); + +LINUX_API(int, accept4(int fd, struct P4(sockaddr)* addr, P4(socklen_t)* addr_len, int flags)); +LINUX_API(int, socketcall(int call, unsigned long* args)); + +LINUX_API(int, ioctl(int fd, unsigned long request, ...)); +LINUX_API(long, syscall(long number, ...)); +LINUX_API(int, pipe2(int pipefd[2], int flags)); + +LINUX_API(void*, dlopen(const char* filename, int flag)); +LINUX_API(void*, dlsym(void* handle, char* symbol)); +LINUX_API(int, dlclose(void* handle)); + +LINUX_API(char**, backtrace_symbols(void*const* buffer, int size)); +LINUX_API(int, backtrace(void** buffer, int size)); + +OVRDN_API(void, abort(void)); +OVRDN_API(int, gettimeofday(struct timeval* tv, void* tz)); +OVRDN_API(P4(ssize_t), read(int fd, void* buf, P4(size_t) count)); +OVRDN_API(P4(ssize_t), write(int fd, const void* buf, P4(size_t) count)); +OVRDN_API(int, open(const char* pathname, ...)); +OVRDN_API(int, close(int fd)); +OVRDN_API(int, unlink(const char* pathname)); +OVRDN_API(int, mkdir(const char* pathname, P4(mode_t) mode)); +OVRDN_API(int, rmdir(const char* pathname)); +OVRDN_API(int, stat(const char* pathname, P4(stat_t)* buf)); +OVRDN_API(int, fstat(int fd, P4(stat_t)* buf)); + +NIC_API(char*, nic_enumerate(void)); +NIC_API(int, nic_ifup(const char* nic, const char* params)); +NIC_API(int, nic_ifdown(const char* nic)); +NIC_API(char*, nic_ifconfig(const char* nic)); +NIC_API(int, nic_ntpdate(const char* nic, const char* server, int port, int timeout)); + +#undef NIC_API +#undef OVRDN_API +#undef LINUX_API +#undef POSIX_API + +#if !defined( POSIX4_ITSELF ) + + // functions + #define getcwd P4(getcwd) + #define chdir P4(chdir) + #define fdatasync P4(fdatasync) + #define fsync P4(fsync) + #define ftruncate P4(ftruncate) + #define scandir P4(scandir) + #define utime P4(utime) + #define utimes P4(utimes) + #define pread P4(pread) + #define pwrite P4(pwrite) + #define readv P4(readv) + #define writev P4(writev) + #define utimensat P4(utimensat) + + #define clock_getres P4(clock_getres) + #define clock_gettime P4(clock_gettime) + + #define pthread_create P4(pthread_create) + #define pthread_join P4(pthread_join) + #define pthread_once P4(pthread_once) + #define pthread_sigmask P4(pthread_sigmask) + #define pthread_attr_destroy P4(pthread_attr_destroy) + #define pthread_cond_destroy P4(pthread_cond_destroy) + #define pthread_cond_init P4(pthread_cond_init) + #define pthread_cond_signal P4(pthread_cond_signal) + #define pthread_cond_wait P4(pthread_cond_wait) + #define pthread_condattr_destroy P4(pthread_condattr_destroy) + #define pthread_condattr_init P4(pthread_condattr_init) + #define pthread_condattr_setclock P4(pthread_condattr_setclock) + #define pthread_mutex_destroy P4(pthread_mutex_destroy) + #define pthread_mutex_init P4(pthread_mutex_init) + #define pthread_mutex_lock P4(pthread_mutex_lock) + #define pthread_mutex_unlock P4(pthread_mutex_unlock) + #define pthread_rwlock_destroy P4(pthread_rwlock_destroy) + #define pthread_rwlock_init P4(pthread_rwlock_init) + #define pthread_rwlock_rdlock P4(pthread_rwlock_rdlock) + #define pthread_rwlock_unlock P4(pthread_rwlock_unlock) + #define pthread_cond_broadcast P4(pthread_cond_broadcast) + #define pthread_cond_timedwait P4(pthread_cond_timedwait) + #define pthread_self P4(pthread_self) + #define pthread_equal P4(pthread_equal) + #define pthread_mutex_trylock P4(pthread_mutex_trylock) + #define pthread_rwlock_tryrdlock P4(pthread_rwlock_tryrdlock) + #define pthread_rwlock_trywrlock P4(pthread_rwlock_trywrlock) + #define pthread_rwlock_wrlock P4(pthread_rwlock_wrlock) + #define sem_init P4(sem_init) + #define sem_destroy P4(sem_destroy) + #define sem_wait P4(sem_wait) + #define sem_trywait P4(sem_trywait) + #define sem_post P4(sem_post) + + #define accept P4(accept) + #define bind P4(bind) + #define connect P4(connect) + #define freeaddrinfo P4(freeaddrinfo) + #define getaddrinfo P4(getaddrinfo) + #define getpeername P4(getpeername) + #define getsockname P4(getsockname) + #define getsockopt P4(getsockopt) + #define htonl P4(htonl) + #define htons P4(htons) + #define if_nametoindex P4(if_nametoindex) + #define listen P4(listen) + #define ntohs P4(ntohs) + #define recvmsg P4(recvmsg) + #define sendmsg P4(sendmsg) + #define setsockopt P4(setsockopt) + #define shutdown P4(shutdown) + #define socket(d,t,p) P4(socket)(d, t, p) + + #define nanosleep P4(nanosleep) + #define pipe P4(pipe) + #define sysconf P4(sysconf) + + #define preadv P4(preadv) + #define pwritev P4(pwritev) + + #define epoll_create P4(epoll_create) + #define epoll_create1 P4(epoll_create1) + #define epoll_ctl P4(epoll_ctl) + #define epoll_pwait P4(epoll_pwait) + #define epoll_wait P4(epoll_wait) + #define eventfd P4(eventfd) + #define eventfd2 P4(eventfd2) + + #define accept4 P4(accept4) + #define socketcall P4(socketcall) + + #define ioctl P4(ioctl) + #define syscall(n, ...) P4(syscall)(n, __VA_ARGS__) + #define pipe2 P4(pipe2) + + #define dlopen P4(dlopen) + #define dlsym P4(dlsym) + #define dlclose P4(dlclose) + + #define backtrace_symbols P4(backtrace_symbols) + #define backtrace P4(backtrace) + + #define abort P4(abort) + #define gettimeofday(tv,tz) P4(gettimeofday)(tv, tz) + #define read(fd,buf,count) P4(read)(fd, buf, count) + #define write(fd,buf,count) P4(write)(fd, buf, count) + #define open(pathname, ...) P4(open)(pathname, __VA_ARGS__) + #define close(fd) P4(close)(fd) + #define unlink(pathname) P4(unlink)(pathname) + #define mkdir(pathname,mode) P4(mkdir)(pathname,mode) + #define rmdir(pathname) P4(rmdir)(pathname) + #define stat(pathname,buf) P4(stat)(pathname, buf) + #define fstat(fd,buf) P4(fstat)(fd, buf) + + #define nic_enumerate P4(nic_enumerate) + #define nic_ifup P4(nic_ifup) + #define nic_ifdown P4(nic_ifdown) + #define nic_ifconfig P4(nic_ifconfig) + #define nic_ntpdate P4(nic_ntpdate) + + // structs + #define addrinfo P4(addrinfo) + #define cmsghdr P4(cmsghdr) + #define dirent P4(dirent) + #define in_addr P4(in_addr) + #define in6_addr P4(in6_addr) + #define iovec P4(iovec) + #define msghdr P4(msghdr) + #define poll_event P4(poll_event) + #define sockaddr P4(sockaddr) + #define sockaddr_in P4(sockaddr_in) + #define sockaddr_in6 P4(sockaddr_in6) + #define sockaddr_storage P4(sockaddr_storage) + #define termios P4(termios) + #define timespec P4(timespec) + #define timeval P4(timeval) + #define utimbuf P4(utimbuf) + + // typedefs + #define clockid_t P4(clockid_t) + #define ip_mreq P4(ip_mreq) + #define ipv6_mreq P4(ipv6_mreq) + #define in_addr_t P4(in_addr_t) + #define in_port_t P4(in_port_t) + #define off_t P4(off_t) + #define pthread_attr_t P4(pthread_attr_t) + #define pthread_cond_t P4(pthread_cond_t) + #define pthread_condattr_t P4(pthread_condattr_t) + #define pthread_key_t P4(pthread_key_t) + #define pthread_mutex_t P4(pthread_mutex_t) + #define pthread_mutexattr_t P4(pthread_mutexattr_t) + #define pthread_once_t P4(pthread_once_t) + #define pthread_rwlock_t P4(pthread_rwlock_t) + #define pthread_rwlockattr_t P4(pthread_rwlockattr_t) + #define pthread_t P4(pthread_t) + #define sa_family_t P4(sa_family_t) + #define sem_t P4(sem_t) + #define sigset_t P4(sigset_t) + #define size_t P4(size_t) + #define socklen_t P4(socklen_t) + #define ssize_t P4(ssize_t) + #define stat_t P4(stat_t) + +#endif // #if !defined( POSIX4_ITSELF ) + +#ifdef __cplusplus +} +#endif + +#endif // #ifndef POSIX4_INCL
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/iotjs/deps/posix/posix4_aux.h Thu Jul 11 18:48:09 2019 +0900 @@ -0,0 +1,27 @@ +/* Copyright 2017-present Renesas Electronics Corporation and other contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT 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 POSIX4_AUX_INCL +#define POSIX4_AUX_INCL + +#if defined(__MBED_OS__) + #include "platform/mbedos5/posix4mbed_aux.h" +#endif // #if defined(__MBED_OS__) + +#if defined(__UC3__) + #include "platform/uC3/posix4uC3_aux.h" +#endif // #if defined(__UC3__) + +#endif // #ifndef POSIX4_AUX_INCL
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/iotjs/deps/posix/posix4_target.h Thu Jul 11 18:48:09 2019 +0900 @@ -0,0 +1,27 @@ +/* Copyright 2017-present Renesas Electronics Corporation and other contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT 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 POSIX4_TARGET_INCL +#define POSIX4_TARGET_INCL + +#if defined(__MBED_OS__) + #include "./platform/mbedos5/posix4mbed.h" +#endif // #if defined(__MBED_OS__) + +#if defined(__UC3__) + #include "./platform/uC3/posix4uC3.h" +#endif // #if defined(__UC3__) + +#endif // #ifndef POSIX4_TARGET_INCL
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/iotjs/src/modules/_common/js/fixup.js Thu Jul 11 18:48:09 2019 +0900 @@ -0,0 +1,50 @@ +/* Copyright 2017-present Renesas Electronics Corporation and other contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT 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 isArray(arg) { return arg instanceof Array; } +function isFixup(arg) { return arg instanceof Fixup; } + +function Fixup(modules) { + modules = isArray( modules ) ? modules : [].slice.call( arguments ); + if( !isFixup( this ) ) { + return new Fixup( modules ); + } + + for( var i=0; i<modules.length; ++i ) { + switch( modules[ i ] ) { + case 'http': + case 'https': fixup_http(); break; +// case 'etc': fixup_etc(); break; + } + } +} + +function fixup_http() { + var http = require('http'); + if( http.ClientRequest.prototype.original_write ) { + return; + } + http.ClientRequest.prototype.original_write = http.ClientRequest.prototype.write; + http.ClientRequest.prototype.write = function( data ) { + var block_size = 4096; + for( var i=0; i<data.length; i+=block_size ) { + this.original_write( data.slice( i, i+block_size ) ); + } + }; +} + +module.exports = Fixup; +module.exports.Fixup = Fixup; +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/iotjs/src/modules/mbedos5/iotjs_ext_module_periph_common.c Thu Jul 11 18:48:09 2019 +0900 @@ -0,0 +1,196 @@ +/* Copyright 2017-present Renesas Electronics Corporation and other contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT 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(USE_POSIX_BRIDGE) +#include "iotjs_def.h" + +#include "peripheral_io.h" +#include "iotjs_ext_module_periph_common.h" +#include "modules/iotjs_module_buffer.h" +#include "iotjs_module_video.h" +#include "iotjs_module_display.h" +#include "iotjs_module_jpeg.h" +#include "iotjs_module_aligned_buffer.h" + +const char* iotjs_ext_periph_error_str(uint8_t op) { + switch (op) { +#if ENABLE_MODULE_VIDEO + case kVideoOpOpen: + return "Open error, cannot open Video"; + case kVideoOpStart: + return "Start error, cannot start Video"; + case kVideoOpStop: + return "Stop error, cannot stop Video"; + case kVideoOpReadFrame: + return "ReadFrame error, cannot readFrame Video"; + case kVideoOpClose: + return "Close error, cannot close Video"; +#endif /* ENABLE_MODULE_VIDEO */ +#if ENABLE_MODULE_DISPLAY + case kDisplayOpOpen: + return "Open error, cannot open Display"; + case kDisplayOpStart: + return "Start error, cannot start Display"; + case kDisplayOpStop: + return "Stop error, cannot stop Display"; + case kDisplayOpUpdate: + return "Update error, cannot update Display"; + case kDisplayOpClose: + return "Close error, cannot close Display"; +#endif /* ENABLE_MODULE_VIDEO */ +#if ENABLE_MODULE_JPEG + case kJpegOpEncode: + return "Encode error, cannot encode Jpeg"; + case kJpegOpDecode: + return "Decode error, cannot decode Jpeg"; +#endif /* ENABLE_MODULE_JPEG */ +#if ENABLE_MODULE_GRAPHICS + case kGraphicsOpDrawImage: + return "Draw error, cannot draw Image"; + case kGraphicsOpDrawLine: + return "Draw error, cannot draw Line"; + case kGraphicsOpDrawRect: + return "Draw error, cannot draw Rect"; + case kGraphicsOpDrawArc: + return "Draw error, cannot draw Arc"; + case kGraphicsOpDrawCircle: + return "Draw error, cannot draw Circle"; + case kGraphicsOpDrawEllipse: + return "Draw error, cannot draw Ellipse"; + case kGraphicsOpDrawPolygon: + return "Draw error, cannot draw Polygon"; + case kGraphicsOpDrawText: + return "Draw error, cannot draw Text"; +#endif /* ENABLE_MODULE_GRAPHICS */ + default: + return "Unknown error"; + } +} + +static void after_worker(uv_work_t* work_req, int status) { + iotjs_periph_reqwrap_t* reqwrap = + (iotjs_periph_reqwrap_t*)iotjs_reqwrap_from_request((uv_req_t*)work_req); + + size_t jargc = 0; + jerry_value_t jargs[2] = { 0 }; + + if (status) { + jargs[jargc++] = iotjs_jval_create_error_without_error_flag("System error"); + } else { + if (!reqwrap->result) { + jargs[jargc++] = iotjs_jval_create_error_without_error_flag( + iotjs_ext_periph_error_str(reqwrap->op)); + } else { + jargs[jargc++] = jerry_create_null(); + switch (reqwrap->op) { + case kVideoOpStart: + case kVideoOpStop: + case kVideoOpReadFrame: + case kVideoOpClose: + case kDisplayOpStart: + case kDisplayOpStop: + case kDisplayOpUpdate: + case kDisplayOpClose: + case kGraphicsOpDrawImage: + case kGraphicsOpDrawLine: + case kGraphicsOpDrawRect: + case kGraphicsOpDrawArc: + case kGraphicsOpDrawCircle: + case kGraphicsOpDrawEllipse: + case kGraphicsOpDrawPolygon: + case kGraphicsOpDrawText: { + break; + } + case kVideoOpOpen: { +#if ENABLE_MODULE_VIDEO +// iotjs_video_t* video = (iotjs_video_t*)reqwrap->data; +// jargs[jargc++] = video->jobject; +#endif /* ENABLE_MODULE_VIDEO */ + break; + } + case kDisplayOpOpen: { +#if ENABLE_MODULE_DISPLAY +// iotjs_display_t* display = (iotjs_display_t*)reqwrap->data; +// jargs[jargc++] = display->jobject; +#endif /* ENABLE_MODULE_DISPLAY */ + break; + } + case kJpegOpEncode: { +#if ENABLE_MODULE_JPEG + iotjs_jpeg_t* jpeg = (iotjs_jpeg_t*)reqwrap->data; + jerry_value_t jbuf = iotjs_aligned_buffer_wrap_create_buffer((size_t)jpeg->encode_data.dst.len, 32); + if (jerry_value_is_error(jbuf)) { + jerry_release_value(jargs[--jargc]); + } else { + iotjs_aligned_buffer_wrap_t* buf_wrap = iotjs_aligned_buffer_wrap_from_jbuffer(jbuf); + iotjs_aligned_buffer_wrap_copy(buf_wrap, jpeg->encode_data.dst.buf, jpeg->encode_data.dst.len); + } + jargs[jargc++] = jbuf; + IOTJS_RELEASE(jpeg->encode_data.dst.buf); +#endif /* ENABLE_MODULE_JPEG */ + break; + } + case kJpegOpDecode: { +#if ENABLE_MODULE_JPEG + iotjs_jpeg_t* jpeg = (iotjs_jpeg_t*)reqwrap->data; + jerry_value_t jbuf = iotjs_aligned_buffer_wrap_create_buffer((size_t)jpeg->decode_data.dst.len, 32); + if (jerry_value_is_error(jbuf)) { + jerry_release_value(jargs[--jargc]); + } else { + iotjs_aligned_buffer_wrap_t* buf_wrap = iotjs_aligned_buffer_wrap_from_jbuffer(jbuf); + iotjs_aligned_buffer_wrap_copy(buf_wrap, jpeg->decode_data.dst.buf, jpeg->decode_data.dst.len); + } + jargs[jargc++] = jbuf; + IOTJS_RELEASE(jpeg->decode_data.dst.buf); +#endif /* ENABLE_MODULE_JPEG */ + break; + } + default: { + IOTJS_ASSERT(!"Unreachable"); + break; + } + } + } + } + + jerry_value_t jcallback = iotjs_reqwrap_jcallback(&reqwrap->reqwrap); + if (jerry_value_is_function(jcallback)) { + iotjs_invoke_callback(jcallback, jerry_create_undefined(), jargs, jargc); + } + + for (size_t i = 0; i < jargc; i++) { + jerry_release_value(jargs[i]); + } + + iotjs_reqwrap_destroy(&reqwrap->reqwrap); + IOTJS_RELEASE(reqwrap); +} + +static iotjs_periph_reqwrap_t* reqwrap_create(const jerry_value_t jcallback, + void* data, uint8_t op) { + iotjs_periph_reqwrap_t* reqwrap = IOTJS_ALLOC(iotjs_periph_reqwrap_t); + iotjs_reqwrap_initialize((iotjs_reqwrap_t*)reqwrap, jcallback, + (uv_req_t*)&reqwrap->req); + reqwrap->op = op; + reqwrap->data = data; + return (iotjs_periph_reqwrap_t*)reqwrap; +} + +void iotjs_ext_periph_call_async(void* data, jerry_value_t jcallback, uint8_t op, + uv_work_cb worker) { + uv_loop_t* loop = iotjs_environment_loop(iotjs_environment_get()); + iotjs_periph_reqwrap_t* req_wrap = reqwrap_create(jcallback, data, op); + uv_queue_work(loop, &req_wrap->req, worker, after_worker); +} +#endif // #if defined(USE_POSIX_BRIDGE)
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/iotjs/src/modules/mbedos5/iotjs_ext_module_periph_common.h Thu Jul 11 18:48:09 2019 +0900 @@ -0,0 +1,68 @@ +/* Copyright 2017-present Renesas Electronics Corporation and other contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT 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_PERIPH_COMMON_H +#ifndef IOTJS_EXT_MODULE_PERIPH_COMMON_H +#define IOTJS_EXT_MODULE_PERIPH_COMMON_H + +#include "iotjs_def.h" +#include "iotjs_reqwrap.h" + +typedef enum { + kVideoOpOpen=100, + kVideoOpStart, + kVideoOpStop, + kVideoOpReadFrame, + kVideoOpClose, + kDisplayOpOpen, + kDisplayOpStart, + kDisplayOpStop, + kDisplayOpUpdate, + kDisplayOpClose, + kJpegOpEncode, + kJpegOpDecode, + kGraphicsOpDrawImage, + kGraphicsOpDrawLine, + kGraphicsOpDrawRect, + kGraphicsOpDrawArc, + kGraphicsOpDrawCircle, + kGraphicsOpDrawEllipse, + kGraphicsOpDrawPolygon, + kGraphicsOpDrawText, +} iotjs_periph_op_t; + +typedef struct { + iotjs_reqwrap_t reqwrap; /* Note: must be the first */ + uv_work_t req; + uint8_t op; + bool result; + void* data; +} iotjs_periph_reqwrap_t; + +const char* iotjs_ext_periph_error_str(uint8_t op); +void iotjs_ext_periph_call_async(void* type_p, jerry_value_t jcallback, uint8_t op, + uv_work_cb worker); + +#define IOTJS_DEFINE_PERIPH_CREATE_FUNCTION(name) \ + static iotjs_##name##_t* name##_create(const jerry_value_t jobject) { \ + iotjs_##name##_t* data = IOTJS_ALLOC(iotjs_##name##_t); \ + iotjs_##name##_create_platform_data(data); \ + data->jobject = jobject; \ + jerry_set_object_native_pointer(jobject, data, &this_module_native_info); \ + return data; \ + } + +#endif /* IOTJS_EXT_MODULE_PERIPH_COMMON_H */ +#endif /* IOTJS_MODULE_PERIPH_COMMON_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/iotjs/src/modules/mbedos5/iotjs_module_aligned_buffer.c Thu Jul 11 18:48:09 2019 +0900 @@ -0,0 +1,258 @@ +/* Copyright 2017-present Renesas Electronics Corporation and other contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT 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 "modules/iotjs_module_buffer.h" +#include "iotjs_module_aligned_buffer.h" + +#include <math.h> +#include <stdlib.h> +#include <string.h> +#include <malloc.h> + + +IOTJS_DEFINE_NATIVE_HANDLE_INFO_THIS_MODULE(aligned_buffer_wrap); + +static bool isPow2(size_t value) +{ + if( value == 0 ) { + return false; + } + while( 1 < value ) { + if( value % 2 ) { + return false; + } + value /= 2; + } + return true; +} + +static int aligned( int value, int align ) +{ + return ( value + ( align - 1 ) ) / align * align; +} + +iotjs_aligned_buffer_wrap_t* iotjs_aligned_buffer_wrap_create(const jerry_value_t jobject, + size_t length, size_t alignment) { + iotjs_aligned_buffer_wrap_t* bufferwrap; + size_t metadata_size = sizeof(iotjs_aligned_buffer_wrap_t); + uint32_t alloc_size = 0; + uint32_t offset; + + if(!isPow2(alignment)) { + /* アライメントが2の累乗でない */ + return NULL; + } + + alloc_size += aligned( metadata_size, alignment ); + offset = alloc_size - metadata_size; + alloc_size += aligned( length, alignment ); + + bufferwrap = (iotjs_aligned_buffer_wrap_t*)memalign(alignment, alloc_size); + if(bufferwrap == NULL) { + return NULL; + } + memset(bufferwrap, 0, alloc_size); + + bufferwrap->jobject = jobject; + jerry_set_object_native_pointer(jobject, bufferwrap, + &this_module_native_info); + + bufferwrap->length = length; + bufferwrap->alignment = alignment; + bufferwrap->offset = offset; + + IOTJS_ASSERT( + bufferwrap == + (iotjs_aligned_buffer_wrap_t*)(iotjs_jval_get_object_native_handle(jobject))); + + return bufferwrap; +} + + +static void iotjs_aligned_buffer_wrap_destroy(iotjs_aligned_buffer_wrap_t* bufferwrap) { + free(bufferwrap); +} + + +iotjs_aligned_buffer_wrap_t* iotjs_aligned_buffer_wrap_from_jbuffer(const jerry_value_t jbuffer) { + IOTJS_ASSERT(jerry_value_is_object(jbuffer)); + iotjs_aligned_buffer_wrap_t* buffer = + (iotjs_aligned_buffer_wrap_t*)iotjs_jval_get_object_native_handle(jbuffer); + IOTJS_ASSERT(buffer != NULL); + return buffer; +} + + +char* iotjs_aligned_buffer_wrap_native_buffer_ptr(iotjs_aligned_buffer_wrap_t* bufferwrap) { + IOTJS_ASSERT(bufferwrap != NULL); + return &bufferwrap->buffer[bufferwrap->offset]; +} + + +jerry_value_t iotjs_aligned_buffer_wrap_create_buffer(size_t len, size_t alignment) { + jerry_value_t jres_buffer = jerry_create_object(); + + iotjs_aligned_buffer_wrap_t* bufferwrap = + iotjs_aligned_buffer_wrap_create(jres_buffer, len, alignment); + if(bufferwrap == NULL) { + return JS_CREATE_ERROR(COMMON, "Memory allocation error"); + } + + iotjs_jval_set_property_number(jres_buffer, IOTJS_MAGIC_STRING_LENGTH, len); + iotjs_jval_set_property_number(jres_buffer, "alignment", alignment); + + // Support for 'instanceof' operator + jerry_value_t jglobal = jerry_get_global_object(); + jerry_value_t jbuffer = + iotjs_jval_get_property(jglobal, "AlignedBuffer"); + jerry_release_value(jglobal); + + if (!jerry_value_is_error(jbuffer) && jerry_value_is_object(jbuffer)) { + jerry_value_t jbuffer_proto = + iotjs_jval_get_property(jbuffer, IOTJS_MAGIC_STRING_PROTOTYPE); + + if (!jerry_value_is_error(jbuffer_proto) && + jerry_value_is_object(jbuffer_proto)) { + jerry_set_prototype(jres_buffer, jbuffer_proto); + } + + jerry_release_value(jbuffer_proto); + } + jerry_release_value(jbuffer); + + return jres_buffer; +} + + +size_t iotjs_aligned_buffer_wrap_copy_internal(iotjs_aligned_buffer_wrap_t* bufferwrap, + const char* src, size_t src_from, + size_t src_to, size_t dst_from) { + size_t copied = 0; + size_t dst_length = bufferwrap->length; + char *dst_ptr = iotjs_aligned_buffer_wrap_native_buffer_ptr(bufferwrap); + for (size_t i = src_from, j = dst_from; i < src_to && j < dst_length; + ++i, ++j) { + *(dst_ptr + j) = *(src + i); + ++copied; + } + return copied; +} + + +size_t iotjs_aligned_buffer_wrap_copy(iotjs_aligned_buffer_wrap_t* bufferwrap, const char* src, + size_t len) { + return iotjs_aligned_buffer_wrap_copy_internal(bufferwrap, src, 0, len, 0); +} + + +JS_FUNCTION(AlignedBuffer) { + DJS_CHECK_ARGS(3, object, number, number); + + const jerry_value_t jobject = JS_GET_ARG(0, object); + size_t length = JS_GET_ARG(1, number); + size_t alignment = JS_GET_ARG(2, number); + + iotjs_aligned_buffer_wrap_t* bufferwrap = + iotjs_aligned_buffer_wrap_create(jobject, length, alignment); + if(bufferwrap == NULL) { + return JS_CREATE_ERROR(COMMON, "Memory allocation error"); + } + return jerry_create_undefined(); +} + + +JS_FUNCTION(CopyFromBuffer) { + DJS_CHECK_ARGS(2, object, object); + JS_DECLARE_OBJECT_PTR(0, aligned_buffer_wrap, dst_buffer_wrap); + + const jerry_value_t jsrc_buffer = JS_GET_ARG(1, object); + iotjs_bufferwrap_t* src_buffer_wrap = + iotjs_bufferwrap_from_jbuffer(jsrc_buffer); + + size_t src_length = src_buffer_wrap->length; +// size_t dst_length = dst_buffer_wrap->length; + size_t src_start = 0; + size_t dst_start = 0; + size_t src_end = src_length; + + const char* src_data = src_buffer_wrap->buffer; + size_t copied = iotjs_aligned_buffer_wrap_copy_internal(dst_buffer_wrap, src_data, + src_start, src_end, dst_start); + + return jerry_create_number(copied); +} + + +JS_FUNCTION(CopyFromAlignedBuffer) { + DJS_CHECK_ARGS(2, object, object); + JS_DECLARE_OBJECT_PTR(0, aligned_buffer_wrap, dst_buffer_wrap); + + const jerry_value_t jsrc_buffer = JS_GET_ARG(1, object); + iotjs_aligned_buffer_wrap_t* src_buffer_wrap = + iotjs_aligned_buffer_wrap_from_jbuffer(jsrc_buffer); + + size_t src_length = src_buffer_wrap->length; +// size_t dst_length = dst_buffer_wrap->length; + size_t src_start = 0; + size_t dst_start = 0; + size_t src_end = src_length; + + const char* src_data = iotjs_aligned_buffer_wrap_native_buffer_ptr(src_buffer_wrap); + size_t copied = iotjs_aligned_buffer_wrap_copy_internal(dst_buffer_wrap, src_data, + src_start, src_end, dst_start); + + return jerry_create_number(copied); +} + + +JS_FUNCTION(ToBuffer) { + DJS_CHECK_ARGS(3, object, number, number); + JS_DECLARE_OBJECT_PTR(0, aligned_buffer_wrap, aligned_buffer_wrap); + + size_t start = JS_GET_ARG(1, number); + size_t end = JS_GET_ARG(2, number); + + if (end < start) { + end = start; + } + + if (start > aligned_buffer_wrap->length) { + start = aligned_buffer_wrap->length; + } + + if (end > aligned_buffer_wrap->length) { + end = aligned_buffer_wrap->length; + } + + size_t length = end - start; + + const char* data = iotjs_aligned_buffer_wrap_native_buffer_ptr(aligned_buffer_wrap) + start; + + jerry_value_t jbuffer = iotjs_bufferwrap_create_buffer(length); + iotjs_bufferwrap_t* buffer_wrap = iotjs_bufferwrap_from_jbuffer(jbuffer); + iotjs_bufferwrap_copy(buffer_wrap, data, length); + + return jbuffer; +} + + +jerry_value_t InitAlignedBuffer() { + jerry_value_t buffer = jerry_create_external_function(AlignedBuffer); + iotjs_jval_set_method(buffer, "copyFromBuffer", CopyFromBuffer); + iotjs_jval_set_method(buffer, "copyFromAlignedBuffer", CopyFromAlignedBuffer); + iotjs_jval_set_method(buffer, "toBuffer", ToBuffer); + return buffer; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/iotjs/src/modules/mbedos5/iotjs_module_aligned_buffer.h Thu Jul 11 18:48:09 2019 +0900 @@ -0,0 +1,41 @@ +/* Copyright 2017-present Renesas Electronics Corporation and other contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT 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_ALIGNED_BUFFER_H +#define IOTJS_MODULE_ALIGNED_BUFFER_H + + +typedef struct { + jerry_value_t jobject; + size_t length; + uint32_t alignment; + uint32_t offset; + char buffer[]; +} iotjs_aligned_buffer_wrap_t; + + +iotjs_aligned_buffer_wrap_t* iotjs_aligned_buffer_wrap_create(const jerry_value_t jbuiltin, + size_t length, size_t alignment); + +iotjs_aligned_buffer_wrap_t* iotjs_aligned_buffer_wrap_from_jbuffer(const jerry_value_t jbuffer); +char* iotjs_aligned_buffer_wrap_native_buffer_ptr(iotjs_aligned_buffer_wrap_t* bufferwrap); + +// Fail-safe creation of AlignedBuffer object. +jerry_value_t iotjs_aligned_buffer_wrap_create_buffer(size_t len, size_t alignment); + +size_t iotjs_aligned_buffer_wrap_copy(iotjs_aligned_buffer_wrap_t* bufferwrap, const char* src, + size_t len); + +#endif /* IOTJS_MODULE_ALIGNED_BUFFER_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/iotjs/src/modules/mbedos5/iotjs_module_display.c Thu Jul 11 18:48:09 2019 +0900 @@ -0,0 +1,476 @@ +/* Copyright 2017-present Renesas Electronics Corporation and other contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT 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" + +#if defined(USE_POSIX_BRIDGE) +#include "peripheral_io.h" +#include "iotjs_module_aligned_buffer.h" +#include "iotjs_module_display.h" + + +IOTJS_DEFINE_NATIVE_HANDLE_INFO_THIS_MODULE(display); + +struct iotjs_display_platform_data_s { + lcd_h handle; +}; + +jerry_value_t iotjs_display_set_platform_config(iotjs_display_t* display, + const jerry_value_t jconfig) { + return jerry_create_undefined(); +} + +void iotjs_display_create_platform_data(iotjs_display_t* display) { + display->platform_data = IOTJS_ALLOC(iotjs_display_platform_data_t); +} + +void iotjs_display_destroy_platform_data( + iotjs_display_platform_data_t* platform_data) { + IOTJS_RELEASE(platform_data); +} + + +IOTJS_DEFINE_PERIPH_CREATE_FUNCTION(display); + +static uint32_t get_pixel_bytes(display_pixel_format_t format) { + switch(format) { + case DISPLAY_PIXELFORMAT_YCBCR422: + case DISPLAY_PIXELFORMAT_RGB565: + case DISPLAY_PIXELFORMAT_ARGB4444: + return 2; + case DISPLAY_PIXELFORMAT_RGB888: + case DISPLAY_PIXELFORMAT_ARGB8888: + return 4; + default: + return 0; + } +} + +static int push_lcd_layer(iotjs_display_t* display, lcd_layer_t layer) { + lcd_layer_t* lcd_layer_ptr = display->lcd_layer; + int i; + for(i = 0; i < LCDLAYER_MAX; i++) { + if(lcd_layer_ptr->id >= LCDLAYER_MAX) { + *lcd_layer_ptr = layer; + break; + } + lcd_layer_ptr++; + } + return (i < LCDLAYER_MAX) ? 0 : -1; +} + +static lcd_layer_t pop_lcd_layer(iotjs_display_t* display) { + lcd_layer_t ret_lcd_layer = display->lcd_layer[0]; + lcd_layer_t* lcd_layer_ptr = display->lcd_layer; + int i; + for(i = 0; i < LCDLAYER_MAX - 1; i++) { + *lcd_layer_ptr = *(lcd_layer_ptr+1); + lcd_layer_ptr++; + } + lcd_layer_ptr->id = LCDLAYER_MAX; + lcd_layer_ptr->frame_buffer = NULL; + + return ret_lcd_layer; +} + +static int push_lcd_layer_id(iotjs_display_t* display, lcd_layer_id_t id) { + lcd_layer_id_t* layer_id_ptr = display->layer_id; + int i; + for(i = 0; i < LCDLAYER_MAX; i++) { + if(*layer_id_ptr >= LCDLAYER_MAX) { + *layer_id_ptr = id; + break; + } + layer_id_ptr++; + } + return (i < LCDLAYER_MAX) ? 0 : -1; +} + +static lcd_layer_id_t pop_lcd_layer_id(iotjs_display_t* display) { + lcd_layer_id_t ret_layer_id = display->layer_id[0]; + lcd_layer_id_t* layer_id_ptr = display->layer_id; + int i; + for(i = 0; i < LCDLAYER_MAX - 1; i++) { + *layer_id_ptr = *(layer_id_ptr+1); + layer_id_ptr++; + } + *layer_id_ptr = LCDLAYER_MAX; + + return ret_layer_id; +} + +bool iotjs_display_open(iotjs_display_t* display) { + lcd_t* lcd = &display->lcd; + + lcd_h handle = lcd_open(lcd); + if( !handle ) { + return false; + } + display->platform_data->handle = handle; + + jerry_value_t jdisplay = display->jobject; + iotjs_jval_set_property_number(jdisplay, "width", lcd->width); + iotjs_jval_set_property_number(jdisplay, "height", lcd->height); + + return true; +} + +bool iotjs_display_start(iotjs_display_t* display) { + return lcd_start(display->platform_data->handle, pop_lcd_layer(display)); +} + +bool iotjs_display_stop(iotjs_display_t* display) { + return lcd_stop(display->platform_data->handle, pop_lcd_layer_id(display)); +} + +bool iotjs_display_update(iotjs_display_t* display) { + return lcd_update(display->platform_data->handle, pop_lcd_layer(display)); +} + +bool iotjs_display_close(iotjs_display_t* display) { + bool ret = lcd_close(display->platform_data->handle); + display->platform_data->handle = 0; + return ret; +} + +static void iotjs_display_destroy(iotjs_display_t* display) { + iotjs_display_destroy_platform_data(display->platform_data); + IOTJS_RELEASE(display); +} + +static void display_worker(uv_work_t* work_req) { + iotjs_periph_reqwrap_t* req_wrap = + (iotjs_periph_reqwrap_t*)(iotjs_reqwrap_from_request( + (uv_req_t*)work_req)); + iotjs_display_t* display = (iotjs_display_t*)req_wrap->data; + + switch (req_wrap->op) { + case kDisplayOpOpen: + req_wrap->result = iotjs_display_open(display); + break; + case kDisplayOpStart: + req_wrap->result = iotjs_display_start(display); + break; + case kDisplayOpStop: + req_wrap->result = iotjs_display_stop(display); + break; + case kDisplayOpUpdate: + req_wrap->result = iotjs_display_update(display); + break; + case kDisplayOpClose: + req_wrap->result = iotjs_display_close(display); + break; + default: + IOTJS_ASSERT(!"Invalid Operation"); + } +} + +static jerry_value_t display_set_configuration(iotjs_display_t* display, + jerry_value_t jconfig) { + jerry_value_t jtype = iotjs_jval_get_property(jconfig, "type"); + if (jerry_value_is_number(jtype)) { + display->lcd.type = (lcd_type_t)iotjs_jval_as_number(jtype); + } else { + display->lcd.type = LCDTYPE_MAX; + } + jerry_release_value(jtype); + if(display->lcd.type >= LCDTYPE_MAX) { + return JS_CREATE_ERROR(TYPE, "Invalid config.type"); + } + + return jerry_create_undefined(); +} + +static jerry_value_t display_get_start_param(iotjs_display_t* display, + const jerry_value_t jargv[], + const jerry_length_t jargc) { + if(jargc < 4) { + return JS_CREATE_ERROR(TYPE, "Invalid Arguments"); + } + + lcd_layer_t lcd_layer; + + lcd_layer_id_t layer_id = (lcd_layer_id_t)JS_GET_ARG(1, number); + if(layer_id >= LCDLAYER_MAX) { + return JS_CREATE_ERROR(TYPE, "Invalid Layer ID"); + } + lcd_layer.id = layer_id; + + const jerry_value_t jbuffer = JS_GET_ARG(2, object); + iotjs_aligned_buffer_wrap_t* buffer_wrap = iotjs_aligned_buffer_wrap_from_jbuffer(jbuffer); + lcd_layer.frame_buffer = iotjs_aligned_buffer_wrap_native_buffer_ptr(buffer_wrap); + if(((buffer_wrap->alignment % 32) != 0) || (((int)lcd_layer.frame_buffer % 32) != 0)) { + return JS_CREATE_ERROR(TYPE, "Invalid buffer alignment"); + } + + display_pixel_format_t format = (display_pixel_format_t)JS_GET_ARG(3, number); + if(format >= DISPLAY_PIXELFORMAT_MAX) { + return JS_CREATE_ERROR(TYPE, "Invalid Buffer Format"); + } + lcd_layer.buffer_format = format; + lcd_layer.pixel_bytes = get_pixel_bytes(format); + + int ret = push_lcd_layer(display, lcd_layer); + if(ret < 0) { + return JS_CREATE_ERROR(COMMON, "Event Queue Full"); + } + + return jerry_create_undefined(); +} + + +static jerry_value_t display_get_stop_param(iotjs_display_t* display, + const jerry_value_t jargv[], + const jerry_length_t jargc) { + if(jargc < 1) { + return JS_CREATE_ERROR(TYPE, "Invalid Arguments"); + } + + lcd_layer_id_t layer_id = (lcd_layer_id_t)JS_GET_ARG(0, number); + if(layer_id >= LCDLAYER_MAX) { + return JS_CREATE_ERROR(TYPE, "Invalid Layer ID"); + } + int ret = push_lcd_layer_id(display, layer_id); + if(ret < 0) { + return JS_CREATE_ERROR(COMMON, "Event Queue Full"); + } + + return jerry_create_undefined(); +} + + +static jerry_value_t display_get_update_param(iotjs_display_t* display, + const jerry_value_t jargv[], + const jerry_length_t jargc) { + if(jargc < 2) { + return JS_CREATE_ERROR(TYPE, "Invalid Arguments"); + } + + lcd_layer_t lcd_layer; + + lcd_layer_id_t layer_id = (lcd_layer_id_t)JS_GET_ARG(0, number); + if(layer_id >= LCDLAYER_MAX) { + return JS_CREATE_ERROR(TYPE, "Invalid Layer ID"); + } + lcd_layer.id = layer_id; + + const jerry_value_t jbuffer = JS_GET_ARG(1, object); + iotjs_aligned_buffer_wrap_t* buffer_wrap = iotjs_aligned_buffer_wrap_from_jbuffer(jbuffer); + lcd_layer.frame_buffer = iotjs_aligned_buffer_wrap_native_buffer_ptr(buffer_wrap); + if(((buffer_wrap->alignment % 32) != 0) || (((int)lcd_layer.frame_buffer % 32) != 0)) { + return JS_CREATE_ERROR(TYPE, "Invalid buffer alignment"); + } + + int ret = push_lcd_layer(display, lcd_layer); + if(ret < 0) { + return JS_CREATE_ERROR(COMMON, "Event Queue Full"); + } + + return jerry_create_undefined(); +} + + +JS_FUNCTION(DisplayCons) { + DJS_CHECK_THIS(); + DJS_CHECK_ARGS(1, object); + DJS_CHECK_ARG_IF_EXIST(1, function); + + // Create Display object + jerry_value_t jdisplay = JS_GET_THIS(); + iotjs_display_t* display = display_create(jdisplay); + + jerry_value_t jconfig = JS_GET_ARG(0, object); + + // set configuration + jerry_value_t res = iotjs_display_set_platform_config(display, jconfig); + if (jerry_value_is_error(res)) { + return res; + } + + res = display_set_configuration(display, jconfig); + if (jerry_value_is_error(res)) { + return res; + } + + for(int i = 0; i < LCDLAYER_MAX; i++) { + display->lcd_layer[i].id = LCDLAYER_MAX; + display->layer_id[i] = LCDLAYER_MAX; + } + + jerry_value_t jcallback = JS_GET_ARG_IF_EXIST(1, function); + + // If the callback doesn't exist, it is completed synchronously. + // Otherwise, it will be executed asynchronously. + if (!jerry_value_is_null(jcallback)) { + iotjs_ext_periph_call_async(display, jcallback, kDisplayOpOpen, display_worker); + } else if (!iotjs_display_open(display)) { + return JS_CREATE_ERROR(COMMON, iotjs_ext_periph_error_str(kDisplayOpOpen)); + } + + return jerry_create_undefined(); +} + + +JS_FUNCTION(Start) { + DJS_CHECK_ARGS(4, object, number, object, number); + JS_DECLARE_OBJECT_PTR(0, display, display); + + jerry_value_t res = display_get_start_param(display, jargv, jargc); + if (jerry_value_is_error(res)) { + return res; + } + + iotjs_ext_periph_call_async(display, JS_GET_ARG_IF_EXIST(4, function), kDisplayOpStart, + display_worker); + return jerry_create_undefined(); +} + +JS_FUNCTION(StartSync) { + DJS_CHECK_ARGS(4, object, number, object, number); + JS_DECLARE_OBJECT_PTR(0, display, display); + + jerry_value_t res = display_get_start_param(display, jargv, jargc); + if (jerry_value_is_error(res)) { + return res; + } + + if(!iotjs_display_start(display)) { + return JS_CREATE_ERROR(COMMON, iotjs_ext_periph_error_str(kDisplayOpStart)); + } + + return jerry_create_undefined(); +} + +JS_FUNCTION(Stop) { + JS_DECLARE_THIS_PTR(display, display); + DJS_CHECK_ARGS(1, number); + + jerry_value_t res = display_get_stop_param(display, jargv, jargc); + if (jerry_value_is_error(res)) { + return res; + } + + iotjs_ext_periph_call_async(display, JS_GET_ARG_IF_EXIST(1, function), kDisplayOpStop, + display_worker); + return jerry_create_undefined(); +} + +JS_FUNCTION(StopSync) { + JS_DECLARE_THIS_PTR(display, display); + DJS_CHECK_ARGS(1, number); + + jerry_value_t res = display_get_stop_param(display, jargv, jargc); + if (jerry_value_is_error(res)) { + return res; + } + + if(!iotjs_display_stop(display)) { + return JS_CREATE_ERROR(COMMON, iotjs_ext_periph_error_str(kDisplayOpStop)); + } + + return jerry_create_undefined(); +} + +JS_FUNCTION(Update) { + JS_DECLARE_THIS_PTR(display, display); + DJS_CHECK_ARGS(2, number, object); + + jerry_value_t res = display_get_update_param(display, jargv, jargc); + if (jerry_value_is_error(res)) { + return res; + } + + iotjs_ext_periph_call_async(display, JS_GET_ARG_IF_EXIST(2, function), kDisplayOpUpdate, + display_worker); + return jerry_create_undefined(); +} + +JS_FUNCTION(UpdateSync) { + JS_DECLARE_THIS_PTR(display, display); + DJS_CHECK_ARGS(2, number, object); + + jerry_value_t res = display_get_update_param(display, jargv, jargc); + if (jerry_value_is_error(res)) { + return res; + } + + if(!iotjs_display_update(display)) { + return JS_CREATE_ERROR(COMMON, iotjs_ext_periph_error_str(kDisplayOpUpdate)); + } + + return jerry_create_undefined(); +} + +JS_FUNCTION(Close) { + JS_DECLARE_OBJECT_PTR(0, display, display); + iotjs_ext_periph_call_async(display, JS_GET_ARG_IF_EXIST(1, function), kDisplayOpClose, + display_worker); + return jerry_create_undefined(); +} + +JS_FUNCTION(CloseSync) { + JS_DECLARE_OBJECT_PTR(0, display, display); + if(!iotjs_display_close(display)) { + return JS_CREATE_ERROR(COMMON, iotjs_ext_periph_error_str(kDisplayOpClose)); + } + return jerry_create_undefined(); +} + +#endif // #if defined(USE_POSIX_BRIDGE) + + +jerry_value_t InitDisplay() { + +#if defined(USE_POSIX_BRIDGE) + jerry_value_t jdisplay_cons = jerry_create_external_function(DisplayCons); + iotjs_jval_set_method(jdisplay_cons, "startImpl", Start); + iotjs_jval_set_method(jdisplay_cons, "startSyncImpl", StartSync); + iotjs_jval_set_method(jdisplay_cons, "closeImpl", Close); + iotjs_jval_set_method(jdisplay_cons, "closeSyncImpl", CloseSync); + + jerry_value_t prototype = jerry_create_object(); + iotjs_jval_set_method(prototype, "stop", Stop); + iotjs_jval_set_method(prototype, "stopSync", StopSync); + iotjs_jval_set_method(prototype, "update", Update); + iotjs_jval_set_method(prototype, "updateSync", UpdateSync); + + iotjs_jval_set_property_jval(jdisplay_cons, IOTJS_MAGIC_STRING_PROTOTYPE, + prototype); + jerry_release_value(prototype); + + // LCD Type + jerry_value_t jlcd = jerry_create_object(); + iotjs_jval_set_property_number(jlcd, "4_3INCH", LCDTYPE_4_3INCH); + iotjs_jval_set_property_number(jlcd, "MAX", LCDTYPE_MAX); + iotjs_jval_set_property_jval(jdisplay_cons, "LCDTYPE", jlcd); + jerry_release_value(jlcd); + + // Buffer Format + jerry_value_t jpixel = jerry_create_object(); + iotjs_jval_set_property_number(jpixel, "YCBCR422", DISPLAY_PIXELFORMAT_YCBCR422); + iotjs_jval_set_property_number(jpixel, "RGB565", DISPLAY_PIXELFORMAT_RGB565); + iotjs_jval_set_property_number(jpixel, "RGB888", DISPLAY_PIXELFORMAT_RGB888); + iotjs_jval_set_property_number(jpixel, "ARGB8888", DISPLAY_PIXELFORMAT_ARGB8888); + iotjs_jval_set_property_number(jpixel, "ARGB4444", DISPLAY_PIXELFORMAT_ARGB4444); + iotjs_jval_set_property_number(jpixel, "MAX", DISPLAY_PIXELFORMAT_MAX); + iotjs_jval_set_property_jval(jdisplay_cons, "BUFFERFORMAT", jpixel); + jerry_release_value(jpixel); + +#else // #if defined(USE_POSIX_BRIDGE) + jerry_value_t jdisplay_cons = jerry_create_object(); +#endif // #if defined(USE_POSIX_BRIDGE) + + return jdisplay_cons; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/iotjs/src/modules/mbedos5/iotjs_module_display.h Thu Jul 11 18:48:09 2019 +0900 @@ -0,0 +1,46 @@ +/* Copyright 2017-present Renesas Electronics Corporation and other contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT 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_DISPLAY_H +#define IOTJS_MODULE_DISPLAY_H + +#include "iotjs_def.h" +#include "iotjs_handlewrap.h" +#include "iotjs_ext_module_periph_common.h" +#include "iotjs_reqwrap.h" + +typedef struct iotjs_display_platform_data_s iotjs_display_platform_data_t; + +typedef struct { + jerry_value_t jobject; + iotjs_display_platform_data_t* platform_data; + + lcd_t lcd; /* display.open() */ + lcd_layer_t lcd_layer[LCDLAYER_MAX]; /* lcd.start() */ + lcd_layer_id_t layer_id[LCDLAYER_MAX]; /* lcd.stop() */ +} iotjs_display_t; + +bool iotjs_display_open(iotjs_display_t* display); +bool iotjs_display_start(iotjs_display_t* display); +bool iotjs_display_stop(iotjs_display_t* display); +bool iotjs_display_update(iotjs_display_t* display); +bool iotjs_display_close(iotjs_display_t* display); + +void iotjs_display_create_platform_data(iotjs_display_t* display); +void iotjs_display_destroy_platform_data(iotjs_display_platform_data_t* pdata); +jerry_value_t iotjs_display_set_platform_config(iotjs_display_t* display, + const jerry_value_t jconfig); + +#endif /* IOTJS_MODULE_DISPLAY_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/iotjs/src/modules/mbedos5/iotjs_module_graphics.c Thu Jul 11 18:48:09 2019 +0900 @@ -0,0 +1,702 @@ +/* Copyright 2017-present Renesas Electronics Corporation and other contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT 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" + +#if defined(USE_POSIX_BRIDGE) +#include "peripheral_io.h" +#include "iotjs_module_aligned_buffer.h" +#include "iotjs_module_graphics.h" + + +IOTJS_DEFINE_NATIVE_HANDLE_INFO_THIS_MODULE(graphics); + +struct iotjs_graphics_platform_data_s { + graphics_h handle; +}; + +jerry_value_t iotjs_graphics_set_platform_config(iotjs_graphics_t* graphics, + const jerry_value_t jconfig) { + return jerry_create_undefined(); +} + +void iotjs_graphics_create_platform_data(iotjs_graphics_t* graphics) { + graphics->platform_data = IOTJS_ALLOC(iotjs_graphics_platform_data_t); +} + +void iotjs_graphics_destroy_platform_data( + iotjs_graphics_platform_data_t* platform_data) { + IOTJS_RELEASE(platform_data); +} + + +IOTJS_DEFINE_PERIPH_CREATE_FUNCTION(graphics); + +bool iotjs_graphics_init(iotjs_graphics_t* graphics) { + graphics_h handle = initFrameBuffer(graphics->frame_buffer.addr, + graphics->frame_buffer.width, + graphics->frame_buffer.height, + graphics->frame_buffer.format); + if( !handle ) { + return false; + } + graphics->platform_data->handle = handle; + + return true; +} + +bool iotjs_graphics_draw_image(iotjs_graphics_t* graphics) { + int ret = drawImage(graphics->platform_data->handle, + graphics->shape.image.bitmap, + graphics->shape.image.x, + graphics->shape.image.y, + graphics->shape.image.width, + graphics->shape.image.height); + return (ret == 0); +} + +bool iotjs_graphics_draw_line(iotjs_graphics_t* graphics) { + int ret = drawLine(graphics->platform_data->handle, + graphics->shape.line.startX, + graphics->shape.line.startY, + graphics->shape.line.endX, + graphics->shape.line.endY, + graphics->shape.line.color); + return (ret == 0); +} + +bool iotjs_graphics_draw_rect(iotjs_graphics_t* graphics) { + int ret = drawRect(graphics->platform_data->handle, + graphics->shape.rect.x, + graphics->shape.rect.y, + graphics->shape.rect.width, + graphics->shape.rect.height, + graphics->shape.rect.color, + graphics->shape.rect.fill); + return (ret == 0); +} + +bool iotjs_graphics_draw_arc(iotjs_graphics_t* graphics) { + int ret = drawArc(graphics->platform_data->handle, + graphics->shape.arc.centerX, + graphics->shape.arc.centerY, + graphics->shape.arc.radius, + graphics->shape.arc.startAngle, + graphics->shape.arc.endAngle, + graphics->shape.arc.color); + return (ret == 0); +} + +bool iotjs_graphics_draw_circle(iotjs_graphics_t* graphics) { + int ret = drawCircle(graphics->platform_data->handle, + graphics->shape.circle.centerX, + graphics->shape.circle.centerY, + graphics->shape.circle.radius, + graphics->shape.circle.color, + graphics->shape.circle.fill); + return (ret == 0); +} + +bool iotjs_graphics_draw_ellipse(iotjs_graphics_t* graphics) { + int ret = drawEllipse(graphics->platform_data->handle, + graphics->shape.ellipse.centerX, + graphics->shape.ellipse.centerY, + graphics->shape.ellipse.radiusX, + graphics->shape.ellipse.radiusY, + graphics->shape.ellipse.color, + graphics->shape.ellipse.fill); + return (ret == 0); +} + +bool iotjs_graphics_draw_polygon(iotjs_graphics_t* graphics) { + int ret = drawPolygon(graphics->platform_data->handle, + graphics->shape.polygon.centerX, + graphics->shape.polygon.centerY, + graphics->shape.polygon.radius, + graphics->shape.polygon.sides, + graphics->shape.polygon.color, + graphics->shape.polygon.fill); + return (ret == 0); +} + +bool iotjs_graphics_draw_text(iotjs_graphics_t* graphics) { + const char* text = iotjs_string_data( &graphics->shape.text.text ); + int ret = drawText(graphics->platform_data->handle, + text, + graphics->shape.text.x, + graphics->shape.text.y, + graphics->shape.text.size, + graphics->shape.text.color, + graphics->shape.text.background); + iotjs_string_destroy( &graphics->shape.text.text ); + return (ret == 0); +} + +static void iotjs_graphics_destroy(iotjs_graphics_t* graphics) { + deinitFrameBuffer(graphics->platform_data->handle); + iotjs_graphics_destroy_platform_data(graphics->platform_data); + IOTJS_RELEASE(graphics); +} + +static void graphics_worker(uv_work_t* work_req) { + iotjs_periph_reqwrap_t* req_wrap = + (iotjs_periph_reqwrap_t*)(iotjs_reqwrap_from_request( + (uv_req_t*)work_req)); + iotjs_graphics_t* graphics = (iotjs_graphics_t*)req_wrap->data; + + switch (req_wrap->op) { + case kGraphicsOpDrawImage: + req_wrap->result = iotjs_graphics_draw_image(graphics); + break; + case kGraphicsOpDrawLine: + req_wrap->result = iotjs_graphics_draw_line(graphics); + break; + case kGraphicsOpDrawRect: + req_wrap->result = iotjs_graphics_draw_rect(graphics); + break; + case kGraphicsOpDrawArc: + req_wrap->result = iotjs_graphics_draw_arc(graphics); + break; + case kGraphicsOpDrawCircle: + req_wrap->result = iotjs_graphics_draw_circle(graphics); + break; + case kGraphicsOpDrawEllipse: + req_wrap->result = iotjs_graphics_draw_ellipse(graphics); + break; + case kGraphicsOpDrawPolygon: + req_wrap->result = iotjs_graphics_draw_polygon(graphics); + break; + case kGraphicsOpDrawText: + req_wrap->result = iotjs_graphics_draw_text(graphics); + break; + default: + IOTJS_ASSERT(!"Invalid Operation"); + } +} + +static jerry_value_t graphics_set_configuration(iotjs_graphics_t* graphics, + jerry_value_t jconfig) { + jerry_value_t jbuf = iotjs_jval_get_property(jconfig, "buf"); + if (jerry_value_is_object(jbuf)) { + iotjs_aligned_buffer_wrap_t* buffer_wrap = iotjs_aligned_buffer_wrap_from_jbuffer(jbuf); + graphics->frame_buffer.addr = iotjs_aligned_buffer_wrap_native_buffer_ptr(buffer_wrap); + } else { + jerry_release_value(jbuf); + return JS_CREATE_ERROR(TYPE, "Invalid config.buf"); + } + jerry_release_value(jbuf); + + jerry_value_t jwidth = iotjs_jval_get_property(jconfig, "width"); + if (jerry_value_is_number(jwidth)) { + graphics->frame_buffer.width = iotjs_jval_as_number(jwidth); + } else { + jerry_release_value(jwidth); + return JS_CREATE_ERROR(TYPE, "Invalid config.width"); + } + jerry_release_value(jwidth); + + jerry_value_t jheight = iotjs_jval_get_property(jconfig, "height"); + if (jerry_value_is_number(jheight)) { + graphics->frame_buffer.height = iotjs_jval_as_number(jheight); + } else { + jerry_release_value(jheight); + return JS_CREATE_ERROR(TYPE, "Invalid config.height"); + } + jerry_release_value(jheight); + + jerry_value_t jformat = iotjs_jval_get_property(jconfig, "format"); + if (jerry_value_is_number(jformat)) { + graphics->frame_buffer.format = (display_pixel_format_t)iotjs_jval_as_number(jformat); + } else { + graphics->frame_buffer.format = DISPLAY_PIXELFORMAT_MAX; + } + jerry_release_value(jformat); + if(graphics->frame_buffer.format >= DISPLAY_PIXELFORMAT_MAX) { + return JS_CREATE_ERROR(TYPE, "Invalid config.format"); + } + + return jerry_create_undefined(); +} + + +static jerry_value_t graphics_get_image_param(iotjs_graphics_t* graphics, + const jerry_value_t jargv[], + const jerry_length_t jargc) { + if(jargc < 4) { + return JS_CREATE_ERROR(TYPE, "Invalid Arguments"); + } + + jerry_value_t jimage = JS_GET_ARG(1, object); + jerry_value_t jbuf = iotjs_jval_get_property(jimage, "bitmap"); + if (jerry_value_is_object(jbuf)) { + iotjs_aligned_buffer_wrap_t* buffer_wrap = iotjs_aligned_buffer_wrap_from_jbuffer(jbuf); + graphics->shape.image.bitmap = iotjs_aligned_buffer_wrap_native_buffer_ptr(buffer_wrap); + } else { + jerry_release_value(jbuf); + return JS_CREATE_ERROR(TYPE, "Invalid image.bitmap"); + } + jerry_release_value(jbuf); + + jerry_value_t jwidth = iotjs_jval_get_property(jimage, "width"); + if (jerry_value_is_number(jwidth)) { + graphics->shape.image.width = iotjs_jval_as_number(jwidth); + } else { + jerry_release_value(jwidth); + return JS_CREATE_ERROR(TYPE, "Invalid image.width"); + } + jerry_release_value(jwidth); + + jerry_value_t jheight = iotjs_jval_get_property(jimage, "height"); + if (jerry_value_is_number(jheight)) { + graphics->shape.image.height = iotjs_jval_as_number(jheight); + } else { + jerry_release_value(jheight); + return JS_CREATE_ERROR(TYPE, "Invalid image.height"); + } + jerry_release_value(jheight); + + graphics->shape.image.x = JS_GET_ARG(2, number); + graphics->shape.image.y = JS_GET_ARG(3, number); + + return jerry_create_undefined(); +} + +static jerry_value_t graphics_get_line_param(iotjs_graphics_t* graphics, + const jerry_value_t jargv[], + const jerry_length_t jargc) { + if(jargc < 6) { + return JS_CREATE_ERROR(TYPE, "Invalid Arguments"); + } + + graphics->shape.line.startX = JS_GET_ARG(1, number); + graphics->shape.line.startY = JS_GET_ARG(2, number); + graphics->shape.line.endX = JS_GET_ARG(3, number); + graphics->shape.line.endY = JS_GET_ARG(4, number); + graphics->shape.line.color = JS_GET_ARG(5, number); + + return jerry_create_undefined(); +} + +static jerry_value_t graphics_get_rect_param(iotjs_graphics_t* graphics, + const jerry_value_t jargv[], + const jerry_length_t jargc) { + if(jargc < 7) { + return JS_CREATE_ERROR(TYPE, "Invalid Arguments"); + } + + graphics->shape.rect.x = JS_GET_ARG(1, number); + graphics->shape.rect.y = JS_GET_ARG(2, number); + graphics->shape.rect.width = JS_GET_ARG(3, number); + graphics->shape.rect.height = JS_GET_ARG(4, number); + graphics->shape.rect.color = JS_GET_ARG(5, number); + graphics->shape.rect.fill = JS_GET_ARG(6, boolean); + + return jerry_create_undefined(); +} + +static jerry_value_t graphics_get_arc_param(iotjs_graphics_t* graphics, + const jerry_value_t jargv[], + const jerry_length_t jargc) { + if(jargc < 7) { + return JS_CREATE_ERROR(TYPE, "Invalid Arguments"); + } + + graphics->shape.arc.centerX = JS_GET_ARG(1, number); + graphics->shape.arc.centerY = JS_GET_ARG(2, number); + graphics->shape.arc.radius = JS_GET_ARG(3, number); + graphics->shape.arc.startAngle = JS_GET_ARG(4, number); + graphics->shape.arc.endAngle = JS_GET_ARG(5, number); + graphics->shape.arc.color = JS_GET_ARG(6, number); + + return jerry_create_undefined(); +} + +static jerry_value_t graphics_get_circle_param(iotjs_graphics_t* graphics, + const jerry_value_t jargv[], + const jerry_length_t jargc) { + if(jargc < 6) { + return JS_CREATE_ERROR(TYPE, "Invalid Arguments"); + } + + graphics->shape.circle.centerX = JS_GET_ARG(1, number); + graphics->shape.circle.centerY = JS_GET_ARG(2, number); + graphics->shape.circle.radius = JS_GET_ARG(3, number); + graphics->shape.circle.color = JS_GET_ARG(4, number); + graphics->shape.circle.fill = JS_GET_ARG(5, boolean); + + return jerry_create_undefined(); +} + +static jerry_value_t graphics_get_ellipse_param(iotjs_graphics_t* graphics, + const jerry_value_t jargv[], + const jerry_length_t jargc) { + if(jargc < 7) { + return JS_CREATE_ERROR(TYPE, "Invalid Arguments"); + } + + graphics->shape.ellipse.centerX = JS_GET_ARG(1, number); + graphics->shape.ellipse.centerY = JS_GET_ARG(2, number); + graphics->shape.ellipse.radiusX = JS_GET_ARG(3, number); + graphics->shape.ellipse.radiusY = JS_GET_ARG(4, number); + graphics->shape.ellipse.color = JS_GET_ARG(5, number); + graphics->shape.ellipse.fill = JS_GET_ARG(6, boolean); + + return jerry_create_undefined(); +} + +static jerry_value_t graphics_get_polygon_param(iotjs_graphics_t* graphics, + const jerry_value_t jargv[], + const jerry_length_t jargc) { + if(jargc < 7) { + return JS_CREATE_ERROR(TYPE, "Invalid Arguments"); + } + + graphics->shape.polygon.centerX = JS_GET_ARG(1, number); + graphics->shape.polygon.centerY = JS_GET_ARG(2, number); + graphics->shape.polygon.radius = JS_GET_ARG(3, number); + graphics->shape.polygon.sides = JS_GET_ARG(4, number); + graphics->shape.polygon.color = JS_GET_ARG(5, number); + graphics->shape.polygon.fill = JS_GET_ARG(6, boolean); + + return jerry_create_undefined(); +} + +static jerry_value_t graphics_get_text_param(iotjs_graphics_t* graphics, + const jerry_value_t jargv[], + const jerry_length_t jargc) { + if(jargc < 7) { + return JS_CREATE_ERROR(TYPE, "Invalid Arguments"); + } + + graphics->shape.text.text = JS_GET_ARG(1, string); + graphics->shape.text.x = JS_GET_ARG(2, number); + graphics->shape.text.y = JS_GET_ARG(3, number); + graphics->shape.text.size = JS_GET_ARG(4, number); + graphics->shape.text.color = JS_GET_ARG(5, number); + graphics->shape.text.background = JS_GET_ARG(6, number); + + return jerry_create_undefined(); +} + +JS_FUNCTION(GraphicsCons) { +// DJS_CHECK_THIS(); + DJS_CHECK_ARGS(2, object, object); + + // Create Graphics object + jerry_value_t jgraphics = JS_GET_ARG(0, object); + iotjs_graphics_t* graphics = graphics_create(jgraphics); + + jerry_value_t jconfig = JS_GET_ARG(1, object); + + // set configuration + jerry_value_t res = iotjs_graphics_set_platform_config(graphics, jconfig); + if (jerry_value_is_error(res)) { + return res; + } + + res = graphics_set_configuration(graphics, jconfig); + if (jerry_value_is_error(res)) { + return res; + } + + if (!iotjs_graphics_init(graphics)) { + return JS_CREATE_ERROR(COMMON, "Init error, cannot init Frame Buffer"); + } + + return jerry_create_undefined(); +} + + +JS_FUNCTION(DrawImage) { + DJS_CHECK_ARGS(4, object, object, number, number); + JS_DECLARE_OBJECT_PTR(0, graphics, graphics); + + jerry_value_t res = graphics_get_image_param(graphics, jargv, jargc); + if (jerry_value_is_error(res)) { + return res; + } + + iotjs_ext_periph_call_async(graphics, JS_GET_ARG_IF_EXIST(4, function), kGraphicsOpDrawImage, + graphics_worker); + return jerry_create_undefined(); +} + +JS_FUNCTION(DrawImageSync) { + DJS_CHECK_ARGS(4, object, object, number, number); + JS_DECLARE_OBJECT_PTR(0, graphics, graphics); + + jerry_value_t res = graphics_get_image_param(graphics, jargv, jargc); + if (jerry_value_is_error(res)) { + return res; + } + + if(!iotjs_graphics_draw_image(graphics)) { + return JS_CREATE_ERROR(COMMON, "Draw error, cannot draw Image"); + } + + return jerry_create_undefined(); +} + +JS_FUNCTION(DrawLine) { +// DJS_CHECK_ARGS(6, object, number, number, number, number, number); + JS_DECLARE_OBJECT_PTR(0, graphics, graphics); + + jerry_value_t res = graphics_get_line_param(graphics, jargv, jargc); + if (jerry_value_is_error(res)) { + return res; + } + + iotjs_ext_periph_call_async(graphics, JS_GET_ARG_IF_EXIST(6, function), kGraphicsOpDrawLine, + graphics_worker); + return jerry_create_undefined(); +} + +JS_FUNCTION(DrawLineSync) { +// DJS_CHECK_ARGS(6, object, number, number, number, number, number); + JS_DECLARE_OBJECT_PTR(0, graphics, graphics); + + jerry_value_t res = graphics_get_line_param(graphics, jargv, jargc); + if (jerry_value_is_error(res)) { + return res; + } + + if(!iotjs_graphics_draw_line(graphics)) { + return JS_CREATE_ERROR(COMMON, "Draw error, cannot draw Line"); + } + + return jerry_create_undefined(); +} + +JS_FUNCTION(DrawRect) { +// DJS_CHECK_ARGS(7, object, number, number, number, number, number, boolean); + JS_DECLARE_OBJECT_PTR(0, graphics, graphics); + + jerry_value_t res = graphics_get_rect_param(graphics, jargv, jargc); + if (jerry_value_is_error(res)) { + return res; + } + + iotjs_ext_periph_call_async(graphics, JS_GET_ARG_IF_EXIST(7, function), kGraphicsOpDrawRect, + graphics_worker); + return jerry_create_undefined(); +} + +JS_FUNCTION(DrawRectSync) { +// DJS_CHECK_ARGS(7, object, number, number, number, number, number, boolean); + JS_DECLARE_OBJECT_PTR(0, graphics, graphics); + + jerry_value_t res = graphics_get_rect_param(graphics, jargv, jargc); + if (jerry_value_is_error(res)) { + return res; + } + + if(!iotjs_graphics_draw_rect(graphics)) { + return JS_CREATE_ERROR(COMMON, "Draw error, cannot draw Rectangle"); + } + + return jerry_create_undefined(); +} + +JS_FUNCTION(DrawArc) { +// DJS_CHECK_ARGS(7, object, number, number, number, number, number, number); + JS_DECLARE_OBJECT_PTR(0, graphics, graphics); + + jerry_value_t res = graphics_get_arc_param(graphics, jargv, jargc); + if (jerry_value_is_error(res)) { + return res; + } + + iotjs_ext_periph_call_async(graphics, JS_GET_ARG_IF_EXIST(7, function), kGraphicsOpDrawArc, + graphics_worker); + return jerry_create_undefined(); +} + +JS_FUNCTION(DrawArcSync) { +// DJS_CHECK_ARGS(7, object, number, number, number, number, number, number); + JS_DECLARE_OBJECT_PTR(0, graphics, graphics); + + jerry_value_t res = graphics_get_arc_param(graphics, jargv, jargc); + if (jerry_value_is_error(res)) { + return res; + } + + if(!iotjs_graphics_draw_arc(graphics)) { + return JS_CREATE_ERROR(COMMON, "Draw error, cannot draw Arc"); + } + + return jerry_create_undefined(); +} + +JS_FUNCTION(DrawCircle) { +// DJS_CHECK_ARGS(6, object, number, number, number, number, boolean); + JS_DECLARE_OBJECT_PTR(0, graphics, graphics); + + jerry_value_t res = graphics_get_circle_param(graphics, jargv, jargc); + if (jerry_value_is_error(res)) { + return res; + } + + iotjs_ext_periph_call_async(graphics, JS_GET_ARG_IF_EXIST(6, function), kGraphicsOpDrawCircle, + graphics_worker); + return jerry_create_undefined(); +} + +JS_FUNCTION(DrawCircleSync) { +// DJS_CHECK_ARGS(6, object, number, number, number, number, boolean); + JS_DECLARE_OBJECT_PTR(0, graphics, graphics); + + jerry_value_t res = graphics_get_circle_param(graphics, jargv, jargc); + if (jerry_value_is_error(res)) { + return res; + } + + if(!iotjs_graphics_draw_circle(graphics)) { + return JS_CREATE_ERROR(COMMON, "Draw error, cannot draw Circle"); + } + + return jerry_create_undefined(); +} + +JS_FUNCTION(DrawEllipse) { +// DJS_CHECK_ARGS(7, object, number, number, number, number, number, boolean); + JS_DECLARE_OBJECT_PTR(0, graphics, graphics); + + jerry_value_t res = graphics_get_ellipse_param(graphics, jargv, jargc); + if (jerry_value_is_error(res)) { + return res; + } + + iotjs_ext_periph_call_async(graphics, JS_GET_ARG_IF_EXIST(7, function), kGraphicsOpDrawEllipse, + graphics_worker); + return jerry_create_undefined(); +} + +JS_FUNCTION(DrawEllipseSync) { +// DJS_CHECK_ARGS(7, object, number, number, number, number, number, boolean); + JS_DECLARE_OBJECT_PTR(0, graphics, graphics); + + jerry_value_t res = graphics_get_ellipse_param(graphics, jargv, jargc); + if (jerry_value_is_error(res)) { + return res; + } + + if(!iotjs_graphics_draw_ellipse(graphics)) { + return JS_CREATE_ERROR(COMMON, "Draw error, cannot draw Ellipse"); + } + + return jerry_create_undefined(); +} + +JS_FUNCTION(DrawPolygon) { +// DJS_CHECK_ARGS(7, object, number, number, number, number, number, boolean); + JS_DECLARE_OBJECT_PTR(0, graphics, graphics); + + jerry_value_t res = graphics_get_polygon_param(graphics, jargv, jargc); + if (jerry_value_is_error(res)) { + return res; + } + + iotjs_ext_periph_call_async(graphics, JS_GET_ARG_IF_EXIST(7, function), kGraphicsOpDrawPolygon, + graphics_worker); + return jerry_create_undefined(); +} + +JS_FUNCTION(DrawPolygonSync) { +// DJS_CHECK_ARGS(7, object, number, number, number, number, number, boolean); + JS_DECLARE_OBJECT_PTR(0, graphics, graphics); + + jerry_value_t res = graphics_get_polygon_param(graphics, jargv, jargc); + if (jerry_value_is_error(res)) { + return res; + } + + if(!iotjs_graphics_draw_polygon(graphics)) { + return JS_CREATE_ERROR(COMMON, "Draw error, cannot draw Polygon"); + } + + return jerry_create_undefined(); +} + +JS_FUNCTION(DrawText) { +// DJS_CHECK_ARGS(7, object, string, number, number, number, number, number); + JS_DECLARE_OBJECT_PTR(0, graphics, graphics); + + jerry_value_t res = graphics_get_text_param(graphics, jargv, jargc); + if (jerry_value_is_error(res)) { + return res; + } + + iotjs_ext_periph_call_async(graphics, JS_GET_ARG_IF_EXIST(7, function), kGraphicsOpDrawText, + graphics_worker); + return jerry_create_undefined(); +} + +JS_FUNCTION(DrawTextSync) { +// DJS_CHECK_ARGS(7, object, string, number, number, number, number, number); + JS_DECLARE_OBJECT_PTR(0, graphics, graphics); + + jerry_value_t res = graphics_get_text_param(graphics, jargv, jargc); + if (jerry_value_is_error(res)) { + return res; + } + + if(!iotjs_graphics_draw_text(graphics)) { + return JS_CREATE_ERROR(COMMON, "Draw error, cannot draw Text"); + } + + return jerry_create_undefined(); +} + +#endif // #if defined(USE_POSIX_BRIDGE) + + +jerry_value_t InitGraphics() { + +#if defined(USE_POSIX_BRIDGE) + jerry_value_t jgraphics_cons = jerry_create_external_function(GraphicsCons); + iotjs_jval_set_method(jgraphics_cons, "drawImage", DrawImageSync); + iotjs_jval_set_method(jgraphics_cons, "drawImageSync", DrawImageSync); + iotjs_jval_set_method(jgraphics_cons, "drawLine", DrawLineSync); + iotjs_jval_set_method(jgraphics_cons, "drawLineSync", DrawLineSync); + iotjs_jval_set_method(jgraphics_cons, "drawRect", DrawRectSync); + iotjs_jval_set_method(jgraphics_cons, "drawRectSync", DrawRectSync); + iotjs_jval_set_method(jgraphics_cons, "drawArc", DrawArcSync); + iotjs_jval_set_method(jgraphics_cons, "drawArcSync", DrawArcSync); + iotjs_jval_set_method(jgraphics_cons, "drawCircle", DrawCircleSync); + iotjs_jval_set_method(jgraphics_cons, "drawCircleSync", DrawCircleSync); + iotjs_jval_set_method(jgraphics_cons, "drawEllipse", DrawEllipseSync); + iotjs_jval_set_method(jgraphics_cons, "drawEllipseSync", DrawEllipseSync); + iotjs_jval_set_method(jgraphics_cons, "drawPolygon", DrawPolygonSync); + iotjs_jval_set_method(jgraphics_cons, "drawPolygonSync", DrawPolygonSync); + iotjs_jval_set_method(jgraphics_cons, "drawText", DrawTextSync); + iotjs_jval_set_method(jgraphics_cons, "drawTextSync", DrawTextSync); + + // Buffer Format + jerry_value_t jformat = jerry_create_object(); +// iotjs_jval_set_property_number(jformat, "YCBCR422", DISPLAY_PIXELFORMAT_YCBCR422); + iotjs_jval_set_property_number(jformat, "RGB565", DISPLAY_PIXELFORMAT_RGB565); + iotjs_jval_set_property_number(jformat, "RGB888", DISPLAY_PIXELFORMAT_RGB888); + iotjs_jval_set_property_number(jformat, "ARGB8888", DISPLAY_PIXELFORMAT_ARGB8888); + iotjs_jval_set_property_number(jformat, "ARGB4444", DISPLAY_PIXELFORMAT_ARGB4444); + iotjs_jval_set_property_number(jformat, "MAX", DISPLAY_PIXELFORMAT_MAX); + iotjs_jval_set_property_jval(jgraphics_cons, "BUFFERFORMAT", jformat); + jerry_release_value(jformat); + +#else // #if defined(USE_POSIX_BRIDGE) + jerry_value_t jgraphics_cons = jerry_create_object(); +#endif // #if defined(USE_POSIX_BRIDGE) + + return jgraphics_cons; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/iotjs/src/modules/mbedos5/iotjs_module_graphics.h Thu Jul 11 18:48:09 2019 +0900 @@ -0,0 +1,135 @@ +/* Copyright 2017-present Renesas Electronics Corporation and other contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT 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_GRAPHICS_H +#define IOTJS_MODULE_GRAPHICS_H + +#include "iotjs_def.h" +#include "iotjs_handlewrap.h" +#include "iotjs_ext_module_periph_common.h" +#include "iotjs_reqwrap.h" + +typedef struct iotjs_graphics_platform_data_s iotjs_graphics_platform_data_t; + +typedef struct { + int x; + int y; + int width; + int height; + char* bitmap; +} graphics_image_t; + +typedef struct { + int startX; + int startY; + int endX; + int endY; + uint32_t color; +} graphics_line_t; + +typedef struct { + int x; + int y; + int width; + int height; + uint32_t color; + bool fill; +} graphics_rect_t; + +typedef struct { + int centerX; + int centerY; + int radius; + int startAngle; + int endAngle; + uint32_t color; +} graphics_arc_t; + +typedef struct { + int centerX; + int centerY; + int radius; + uint32_t color; + bool fill; +} graphics_circle_t; + +typedef struct { + int centerX; + int centerY; + int radiusX; + int radiusY; + uint32_t color; + bool fill; +} graphics_ellipse_t; + +typedef struct { + int centerX; + int centerY; + int radius; + int sides; + uint32_t color; + bool fill; +} graphics_polygon_t; + +typedef struct { + iotjs_string_t text; + int x; + int y; + int size; + uint32_t color; + uint32_t background; +} graphics_text_t; + +typedef struct { + uint8_t* addr; + uint32_t width; + uint32_t height; + display_pixel_format_t format; +} graphics_frame_buffer_t; + +typedef struct { + jerry_value_t jobject; + iotjs_graphics_platform_data_t* platform_data; + + graphics_frame_buffer_t frame_buffer; + + union { + graphics_image_t image; + graphics_line_t line; + graphics_rect_t rect; + graphics_arc_t arc; + graphics_circle_t circle; + graphics_ellipse_t ellipse; + graphics_polygon_t polygon; + graphics_text_t text; + } shape; +} iotjs_graphics_t; + +bool iotjs_graphics_init(iotjs_graphics_t* graphics); +bool iotjs_graphics_draw_image(iotjs_graphics_t* graphics); +bool iotjs_graphics_draw_line(iotjs_graphics_t* graphics); +bool iotjs_graphics_draw_rect(iotjs_graphics_t* graphics); +bool iotjs_graphics_draw_arc(iotjs_graphics_t* graphics); +bool iotjs_graphics_draw_circle(iotjs_graphics_t* graphics); +bool iotjs_graphics_draw_ellipse(iotjs_graphics_t* graphics); +bool iotjs_graphics_draw_polygon(iotjs_graphics_t* graphics); +bool iotjs_graphics_draw_text(iotjs_graphics_t* graphics); + +void iotjs_graphics_create_platform_data(iotjs_graphics_t* graphics); +void iotjs_graphics_destroy_platform_data(iotjs_graphics_platform_data_t* pdata); +jerry_value_t iotjs_graphics_set_platform_config(iotjs_graphics_t* graphics, + const jerry_value_t jconfig); + +#endif /* IOTJS_MODULE_GRAPHICS_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/iotjs/src/modules/mbedos5/iotjs_module_jpeg.c Thu Jul 11 18:48:09 2019 +0900 @@ -0,0 +1,386 @@ +/* Copyright 2017-present Renesas Electronics Corporation and other contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT 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" + +#if defined(USE_POSIX_BRIDGE) +#include "peripheral_io.h" +#include "iotjs_module_aligned_buffer.h" +#include "iotjs_module_jpeg.h" +#include <malloc.h> + +IOTJS_DEFINE_NATIVE_HANDLE_INFO_THIS_MODULE(jpeg); + +struct iotjs_jpeg_platform_data_s { + int dummy; +}; + +jerry_value_t iotjs_jpeg_set_platform_config(iotjs_jpeg_t* jpeg, + const jerry_value_t jconfig) { + return jerry_create_undefined(); +} + +void iotjs_jpeg_create_platform_data(iotjs_jpeg_t* jpeg) { + jpeg->platform_data = IOTJS_ALLOC(iotjs_jpeg_platform_data_t); +} + +void iotjs_jpeg_destroy_platform_data( + iotjs_jpeg_platform_data_t* platform_data) { + IOTJS_RELEASE(platform_data); +} + +IOTJS_DEFINE_PERIPH_CREATE_FUNCTION(jpeg); + +static uint32_t get_pixel_bytes(jpeg_pixel_format_t format) { + switch(format) { + case JPEG_PIXELFORMAT_YCBCR422: + case JPEG_PIXELFORMAT_RGB565: + return 2; + case JPEG_PIXELFORMAT_ARGB8888: + return 4; + default: + return 0; + } +} + +bool iotjs_jpeg_encode(iotjs_jpeg_t* jpeg) { + uint32_t width = (jpeg->encode_data.width + 31)&~31; + uint32_t height = (jpeg->encode_data.height + 15)&~15; + uint32_t encode_len = width * height * get_pixel_bytes(jpeg->encode_data.pixel_format); + jpeg->encode_data.dst.buf = memalign(32, encode_len); + if(jpeg->encode_data.dst.buf == NULL) { + return false; + } + jpeg->encode_data.src.len = encode_len; + jpeg->encode_data.dst.len = encode_len; + + int ret = jpeg_encode(jpeg->encode_data); + if(ret < 0) { + IOTJS_RELEASE(jpeg->encode_data.dst.buf); + return false; + } + + jpeg->encode_data.dst.len = ret; + + return true; +} + +bool iotjs_jpeg_decode(iotjs_jpeg_t* jpeg) { + uint32_t width = (jpeg->decode_data.width + 31)&~31; + uint32_t height = (jpeg->decode_data.height + 15)&~15; + uint32_t decode_len = width * height * get_pixel_bytes(jpeg->decode_data.pixel_format); + jpeg->decode_data.dst.buf = memalign(32, decode_len); + if(jpeg->decode_data.dst.buf == NULL) { + return false; + } + memset(jpeg->decode_data.dst.buf, 0, decode_len); + jpeg->decode_data.dst.len = decode_len; + + bool ret = jpeg_decode(jpeg->decode_data); + if(!ret) { + IOTJS_RELEASE(jpeg->decode_data.dst.buf); + return false; + } + + return true; +} + +static void iotjs_jpeg_destroy(iotjs_jpeg_t* jpeg) { + iotjs_jpeg_destroy_platform_data(jpeg->platform_data); + IOTJS_RELEASE(jpeg); +} + +static void jpeg_worker(uv_work_t* work_req) { + iotjs_periph_reqwrap_t* req_wrap = + (iotjs_periph_reqwrap_t*)(iotjs_reqwrap_from_request( + (uv_req_t*)work_req)); + iotjs_jpeg_t* jpeg = (iotjs_jpeg_t*)req_wrap->data; + + switch (req_wrap->op) { + case kJpegOpEncode: + req_wrap->result = iotjs_jpeg_encode(jpeg); + break; + case kJpegOpDecode: + req_wrap->result = iotjs_jpeg_decode(jpeg); + break; + default: + IOTJS_ASSERT(!"Invalid Operation"); + } +} + +static jerry_value_t jpeg_set_configuration(iotjs_jpeg_t* jpeg, + jerry_value_t jconfig) { + return jerry_create_undefined(); +} + + +static jerry_value_t jpeg_get_encode_param(iotjs_jpeg_t* jpeg, + const jerry_value_t jargv[], + const jerry_length_t jargc) { + if(jargc < 1) { + return JS_CREATE_ERROR(TYPE, "Invalid Arguments"); + } + + jerry_value_t jimage = JS_GET_ARG(0, object); + jerry_value_t jwidth = iotjs_jval_get_property(jimage, "width"); + if (jerry_value_is_number(jwidth)) { + jpeg->encode_data.width = iotjs_jval_as_number(jwidth); + } else { + jerry_release_value(jwidth); + return JS_CREATE_ERROR( + TYPE, "Invalid image.width"); + } + jerry_release_value(jwidth); + + jerry_value_t jheight = iotjs_jval_get_property(jimage, "height"); + if (jerry_value_is_number(jheight)) { + jpeg->encode_data.height = iotjs_jval_as_number(jheight); + } else { + jerry_release_value(jheight); + return JS_CREATE_ERROR( + TYPE, "Invalid image.height"); + } + jerry_release_value(jheight); + + jerry_value_t jformat = iotjs_jval_get_property(jimage, "format"); + if (jerry_value_is_number(jformat)) { + jpeg->encode_data.pixel_format = iotjs_jval_as_number(jformat); + } else { + jpeg->encode_data.pixel_format = JPEG_PIXELFORMAT_MAX; + } + jerry_release_value(jformat); + if(jpeg->encode_data.pixel_format != JPEG_PIXELFORMAT_YCBCR422) { + return JS_CREATE_ERROR(TYPE, "Invalid image.format"); + } + + jerry_value_t jbitmap = iotjs_jval_get_property(jimage, "bitmap"); + iotjs_aligned_buffer_wrap_t* buffer_wrap = iotjs_aligned_buffer_wrap_from_jbuffer(jbitmap); + jpeg->encode_data.src.buf = (uint8_t*)iotjs_aligned_buffer_wrap_native_buffer_ptr(buffer_wrap); + jerry_release_value(jbitmap); + if(((buffer_wrap->alignment % 32) != 0) || (((int)jpeg->encode_data.src.buf % 32) != 0)) { + return JS_CREATE_ERROR(TYPE, "Invalid image.bitmap alignment"); + } + + return jerry_create_undefined(); +} + + +static jerry_value_t jpeg_get_decode_param(iotjs_jpeg_t* jpeg, + const jerry_value_t jargv[], + const jerry_length_t jargc) { + if(jargc < 2) { + return JS_CREATE_ERROR(TYPE, "Invalid Arguments"); + } + + const jerry_value_t jjpeg_data = JS_GET_ARG(0, object); + iotjs_aligned_buffer_wrap_t* buffer_wrap = iotjs_aligned_buffer_wrap_from_jbuffer(jjpeg_data); + jpeg->decode_data.src.buf = iotjs_aligned_buffer_wrap_native_buffer_ptr(buffer_wrap); + jpeg->decode_data.src.len = buffer_wrap->length; + if(((buffer_wrap->alignment % 32) != 0) || (((int)jpeg->decode_data.src.buf % 32) != 0)) { + return JS_CREATE_ERROR(TYPE, "Invalid jpegData alignment"); + } + + const jerry_value_t jconfig = JS_GET_ARG(1, object); + + jerry_value_t jwidth = iotjs_jval_get_property(jconfig, "width"); + if (jerry_value_is_number(jwidth)) { + jpeg->decode_data.width = iotjs_jval_as_number(jwidth); + } else { + jerry_release_value(jwidth); + return JS_CREATE_ERROR( + TYPE, "Invalid options.width"); + } + jerry_release_value(jwidth); + + jerry_value_t jheight = iotjs_jval_get_property(jconfig, "height"); + if (jerry_value_is_number(jheight)) { + jpeg->decode_data.height = iotjs_jval_as_number(jheight); + } else { + jerry_release_value(jheight); + return JS_CREATE_ERROR( + TYPE, "Invalid options.height"); + } + jerry_release_value(jheight); + + jerry_value_t jformat = iotjs_jval_get_property(jconfig, "format"); + if (jerry_value_is_number(jformat)) { + jpeg->decode_data.pixel_format = iotjs_jval_as_number(jformat); + } else { + jpeg->decode_data.pixel_format = JPEG_PIXELFORMAT_MAX; + } + jerry_release_value(jformat); + if(jpeg->decode_data.pixel_format >= JPEG_PIXELFORMAT_MAX) { + return JS_CREATE_ERROR(TYPE, "Invalid options.format"); + } + + if(jpeg->decode_data.pixel_format == JPEG_PIXELFORMAT_ARGB8888) { + jerry_value_t jalpha = iotjs_jval_get_property(jconfig, "alpha"); + if (jerry_value_is_undefined(jalpha)) { + jpeg->decode_data.alpha = 0xFF; + } else { + if (jerry_value_is_number(jalpha)) { + jpeg->decode_data.alpha = iotjs_jval_as_number(jalpha); + } else { + jerry_release_value(jalpha); + return JS_CREATE_ERROR(TYPE, "Invalid options.alpha"); + } + } + jerry_release_value(jalpha); + } else { + jpeg->decode_data.alpha = 0; + } + + return jerry_create_undefined(); +} + +JS_FUNCTION(JpegCons) { + DJS_CHECK_THIS(); + + // Create Jpeg object + jerry_value_t jjpeg = JS_GET_THIS(); + iotjs_jpeg_t* jpeg = jpeg_create(jjpeg); + + jerry_value_t jconfig = JS_GET_ARG(0, object); + + // set configuration + jerry_value_t res = iotjs_jpeg_set_platform_config(jpeg, jconfig); + if (jerry_value_is_error(res)) { + return res; + } + + res = jpeg_set_configuration(jpeg, jconfig); + if (jerry_value_is_error(res)) { + return res; + } + + return jerry_create_undefined(); +} + + +JS_FUNCTION(Encode) { + JS_DECLARE_THIS_PTR(jpeg, jpeg); + DJS_CHECK_ARGS(1, object); + + jerry_value_t jerr = jpeg_get_encode_param(jpeg, jargv, jargc); + if(jerry_value_is_error(jerr)) { + return jerr; + } + iotjs_ext_periph_call_async(jpeg, JS_GET_ARG_IF_EXIST(1, function), kJpegOpEncode, + jpeg_worker); + return jerry_create_undefined(); +} + + +JS_FUNCTION(EncodeSync) { + JS_DECLARE_THIS_PTR(jpeg, jpeg); + DJS_CHECK_ARGS(1, object); + + jerry_value_t jerr = jpeg_get_encode_param(jpeg, jargv, jargc); + if(jerry_value_is_error(jerr)) { + return jerr; + } + + if(!iotjs_jpeg_encode(jpeg)) { + return JS_CREATE_ERROR(COMMON, "Encode error, cannot encode Jpeg"); + } + + jerry_value_t jbuf = iotjs_aligned_buffer_wrap_create_buffer((size_t)jpeg->encode_data.dst.len, 32); + if (jerry_value_is_error(jbuf)) { + IOTJS_RELEASE(jpeg->encode_data.dst.buf); + return jbuf; + } + + iotjs_aligned_buffer_wrap_t* buf_wrap = iotjs_aligned_buffer_wrap_from_jbuffer(jbuf); + iotjs_aligned_buffer_wrap_copy(buf_wrap, jpeg->encode_data.dst.buf, jpeg->encode_data.dst.len); + IOTJS_RELEASE(jpeg->encode_data.dst.buf); + + return jbuf; +} + + +JS_FUNCTION(Decode) { + JS_DECLARE_THIS_PTR(jpeg, jpeg); + DJS_CHECK_ARGS(2, object, object); + + jerry_value_t res = jpeg_get_decode_param(jpeg, jargv, jargc); + if (jerry_value_is_error(res)) { + return res; + } + + iotjs_ext_periph_call_async(jpeg, JS_GET_ARG_IF_EXIST(2, function), kJpegOpDecode, + jpeg_worker); + return jerry_create_undefined(); +} + + +JS_FUNCTION(DecodeSync) { + JS_DECLARE_THIS_PTR(jpeg, jpeg); + DJS_CHECK_ARGS(2, object, object); + + jerry_value_t res = jpeg_get_decode_param(jpeg, jargv, jargc); + if (jerry_value_is_error(res)) { + return res; + } + + if(!iotjs_jpeg_decode(jpeg)) { + return JS_CREATE_ERROR(COMMON, "Decode error, cannot decode Jpeg"); + } + + jerry_value_t jbuf = iotjs_aligned_buffer_wrap_create_buffer((size_t)jpeg->decode_data.dst.len, 32); + if (jerry_value_is_error(jbuf)) { + IOTJS_RELEASE(jpeg->decode_data.dst.buf); + return jbuf; + } + + iotjs_aligned_buffer_wrap_t* buf_wrap = iotjs_aligned_buffer_wrap_from_jbuffer(jbuf); + iotjs_aligned_buffer_wrap_copy(buf_wrap, jpeg->decode_data.dst.buf, jpeg->decode_data.dst.len); + IOTJS_RELEASE(jpeg->decode_data.dst.buf); + + return jbuf; +} + +#endif // #if defined(USE_POSIX_BRIDGE) + + +jerry_value_t InitJpeg() { + +#if defined(USE_POSIX_BRIDGE) + jerry_value_t jjpeg_cons = jerry_create_external_function(JpegCons); + + jerry_value_t prototype = jerry_create_object(); + iotjs_jval_set_method(prototype, "encode", Encode); + iotjs_jval_set_method(prototype, "encodeSync", EncodeSync); + iotjs_jval_set_method(prototype, "decode", Decode); + iotjs_jval_set_method(prototype, "decodeSync", DecodeSync); + + // JPEG Pixel Format + jerry_value_t jformat = jerry_create_object(); + iotjs_jval_set_property_number(jformat, "YCBCR422", JPEG_PIXELFORMAT_YCBCR422); + iotjs_jval_set_property_number(jformat, "ARGB8888", JPEG_PIXELFORMAT_ARGB8888); + iotjs_jval_set_property_number(jformat, "RGB565", JPEG_PIXELFORMAT_RGB565); + iotjs_jval_set_property_number(jformat, "MAX", JPEG_PIXELFORMAT_MAX); + iotjs_jval_set_property_jval(prototype, "PIXELFORMAT", jformat); + jerry_release_value(jformat); + + iotjs_jval_set_property_jval(jjpeg_cons, IOTJS_MAGIC_STRING_PROTOTYPE, + prototype); + jerry_release_value(prototype); + +#else // #if defined(USE_POSIX_BRIDGE) + jerry_value_t jjpeg_cons = jerry_create_object(); +#endif // #if defined(USE_POSIX_BRIDGE) + + return jjpeg_cons; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/iotjs/src/modules/mbedos5/iotjs_module_jpeg.h Thu Jul 11 18:48:09 2019 +0900 @@ -0,0 +1,42 @@ +/* Copyright 2017-present Renesas Electronics Corporation and other contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT 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_JPEG_H +#define IOTJS_MODULE_JPEG_H + +#include "iotjs_def.h" +#include "iotjs_handlewrap.h" +#include "iotjs_ext_module_periph_common.h" +#include "iotjs_reqwrap.h" + +typedef struct iotjs_jpeg_platform_data_s iotjs_jpeg_platform_data_t; + +typedef struct { + jerry_value_t jobject; + iotjs_jpeg_platform_data_t* platform_data; + + jpeg_convert_data_t encode_data; + jpeg_convert_data_t decode_data; +} iotjs_jpeg_t; + +bool iotjs_jpeg_encode(iotjs_jpeg_t* jpeg); +bool iotjs_jpeg_decode(iotjs_jpeg_t* jpeg); + +void iotjs_jpeg_create_platform_data(iotjs_jpeg_t* jpeg); +void iotjs_jpeg_destroy_platform_data(iotjs_jpeg_platform_data_t* pdata); +jerry_value_t iotjs_jpeg_set_platform_config(iotjs_jpeg_t* jpeg, + const jerry_value_t jconfig); + +#endif /* IOTJS_MODULE_JPEG_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/iotjs/src/modules/mbedos5/iotjs_module_nic.c Thu Jul 11 18:48:09 2019 +0900 @@ -0,0 +1,111 @@ +/* Copyright 2017-present Renesas Electronics Corporation and other contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT 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" + +#if defined(USE_POSIX_BRIDGE) + #include <stdlib.h> + #include <nic.h> + +JS_FUNCTION(Ifup) { + JS_CHECK_ARGS(2, string, string); + + iotjs_string_t nic = JS_GET_ARG(0, string); + iotjs_string_t params = JS_GET_ARG(1, string); + const char* cstr_nic = iotjs_string_data( &nic ); + const char* cstr_params = iotjs_string_data( ¶ms ); + int rc = nic_ifup( cstr_nic, cstr_params ); + iotjs_string_destroy( ¶ms ); + iotjs_string_destroy( &nic ); + + return jerry_create_boolean( rc == 0 ); +} + +JS_FUNCTION(Ifdown) { + JS_CHECK_ARGS(1, string); + + iotjs_string_t nic = JS_GET_ARG(0, string); + const char* cstr_nic = iotjs_string_data( &nic ); + int rc = nic_ifdown( cstr_nic ); + iotjs_string_destroy( &nic ); + + return jerry_create_boolean( rc == 0 ); +} + +JS_FUNCTION(Ifconfig) { + JS_CHECK_ARGS(1, string); + + iotjs_string_t nic = JS_GET_ARG(0, string); + const char* cstr_nic = iotjs_string_data( &nic ); + char* json_conf = nic_ifconfig( cstr_nic ); + iotjs_string_t str = iotjs_string_create_with_size( json_conf, strlen( json_conf ) ); + jerry_value_t rc = iotjs_jval_create_string( &str ); + iotjs_string_destroy( &str ); + iotjs_string_destroy( &nic ); + free( json_conf ); + return rc; +} + +JS_FUNCTION(Ntpdate) { + JS_CHECK_ARGS(2, string, object); + + iotjs_string_t nic = JS_GET_ARG(0, string); + const jerry_value_t obj = JS_GET_ARG(1, object); + + jerry_value_t prop_server = iotjs_jval_get_property( obj, "server" ); + iotjs_string_t server = iotjs_jval_as_string( prop_server ); + jerry_value_t prop_port = iotjs_jval_get_property( obj, "port" ); + int port = (int)( iotjs_jval_as_number( prop_port ) ); + jerry_value_t prop_timeout = iotjs_jval_get_property( obj, "timeout" ); + int timeout = (int)( iotjs_jval_as_number( prop_timeout ) ); + + const char* cstr_nic = iotjs_string_data( &nic ); + const char* cstr_server = iotjs_string_data( &server ); + int rc = nic_ntpdate( cstr_nic, cstr_server, port, timeout ); + + jerry_release_value( prop_timeout ); + jerry_release_value( prop_port ); + iotjs_string_destroy( &server ); + jerry_release_value( prop_server ); + iotjs_string_destroy( &nic ); + + return jerry_create_boolean( rc == 0 ); +} + +JS_FUNCTION(Enumerate) { + char* json_nics = nic_enumerate(); + iotjs_string_t str = iotjs_string_create_with_size( json_nics, strlen( json_nics ) ); + jerry_value_t rc = iotjs_jval_create_string( &str ); + iotjs_string_destroy( &str ); + free( json_nics ); + return rc; +} + +#endif // #if defined(USE_POSIX_BRIDGE) + + +jerry_value_t InitNic() { + jerry_value_t nic = jerry_create_object(); + +#if defined(USE_POSIX_BRIDGE) + iotjs_jval_set_method(nic, "ifup", Ifup); + iotjs_jval_set_method(nic, "ifdown", Ifdown); + iotjs_jval_set_method(nic, "ifconfig", Ifconfig); + iotjs_jval_set_method(nic, "ntpdate", Ntpdate); + iotjs_jval_set_method(nic, "enumerate", Enumerate); +#endif // #if defined(USE_POSIX_BRIDGE) + + return nic; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/iotjs/src/modules/mbedos5/iotjs_module_video.c Thu Jul 11 18:48:09 2019 +0900 @@ -0,0 +1,402 @@ +/* Copyright 2017-present Renesas Electronics Corporation and other contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT 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" + +#if defined(USE_POSIX_BRIDGE) +#include "peripheral_io.h" +#include "iotjs_module_aligned_buffer.h" +#include "iotjs_module_video.h" + +IOTJS_DEFINE_NATIVE_HANDLE_INFO_THIS_MODULE(video); + +struct iotjs_video_platform_data_s { + video_h handle; +}; + +jerry_value_t iotjs_video_set_platform_config(iotjs_video_t* video, + const jerry_value_t jconfig) { + return jerry_create_undefined(); +} + +void iotjs_video_create_platform_data(iotjs_video_t* video) { + video->platform_data = IOTJS_ALLOC(iotjs_video_platform_data_t); +} + +void iotjs_video_destroy_platform_data( + iotjs_video_platform_data_t* platform_data) { + IOTJS_RELEASE(platform_data); +} + +IOTJS_DEFINE_PERIPH_CREATE_FUNCTION(video); + +static uint32_t get_pixel_bytes(video_pixel_format_t format) { + switch(format) { + case VIDEO_PIXELFORMAT_YCBCR422: + case VIDEO_PIXELFORMAT_RGB565: + return 2; + case VIDEO_PIXELFORMAT_RGB888: + return 4; + default: + return 0; + } +} + +bool iotjs_video_open(iotjs_video_t* video) { + + video_h handle = video_open(video->video_source); + if( !handle ) { + return false; + } + video->platform_data->handle = handle; + + jerry_value_t jvideo = video->jobject; + iotjs_jval_set_property_number(jvideo, "width", video->video_source.width); + iotjs_jval_set_property_number(jvideo, "height", video->video_source.height); + iotjs_jval_set_property_number(jvideo, "pixelBytes", video->video_source.pixel_bytes); + + return true; +} + +bool iotjs_video_start(iotjs_video_t* video) { + return video_start(video->platform_data->handle, video->video_source.frame_buffer); +} + +bool iotjs_video_stop(iotjs_video_t* video) { + return video_stop(video->platform_data->handle); +} + +bool iotjs_video_read_frame(iotjs_video_t* video) { + return true; +} + +bool iotjs_video_close(iotjs_video_t* video) { + bool ret = video_close(video->platform_data->handle); + video->platform_data->handle = 0; + return ret; +} + +static void iotjs_video_destroy(iotjs_video_t* video) { + iotjs_video_destroy_platform_data(video->platform_data); + IOTJS_RELEASE(video); +} + +static void video_worker(uv_work_t* work_req) { + iotjs_periph_reqwrap_t* req_wrap = + (iotjs_periph_reqwrap_t*)(iotjs_reqwrap_from_request( + (uv_req_t*)work_req)); + iotjs_video_t* video = (iotjs_video_t*)req_wrap->data; + + switch (req_wrap->op) { + case kVideoOpOpen: + req_wrap->result = iotjs_video_open(video); + break; + case kVideoOpStart: + req_wrap->result = iotjs_video_start(video); + break; + case kVideoOpStop: + req_wrap->result = iotjs_video_stop(video); + break; + case kVideoOpReadFrame: + req_wrap->result = iotjs_video_read_frame(video); + break; + case kVideoOpClose: + req_wrap->result = iotjs_video_close(video); + break; + default: + IOTJS_ASSERT(!"Invalid Operation"); + } +} + +static jerry_value_t video_set_configuration(iotjs_video_t* video, + jerry_value_t jconfig) { + video_source_t* video_source = &video->video_source; + jerry_value_t jwidth = iotjs_jval_get_property(jconfig, "width"); + if (jerry_value_is_number(jwidth)) { + video_source->width = iotjs_jval_as_number(jwidth); + } else { + jerry_release_value(jwidth); + return JS_CREATE_ERROR(TYPE, "Invalid config.width"); + } + jerry_release_value(jwidth); + + jerry_value_t jheight = iotjs_jval_get_property(jconfig, "height"); + if (jerry_value_is_number(jheight)) { + video_source->height = iotjs_jval_as_number(jheight); + } else { + jerry_release_value(jheight); + return JS_CREATE_ERROR(TYPE, "Invalid config.height"); + } + jerry_release_value(jheight); + + jerry_value_t jformat = iotjs_jval_get_property(jconfig, "format"); + if (jerry_value_is_number(jformat)) { + video_source->pixel_format = (video_pixel_format_t)iotjs_jval_as_number(jformat); + } else { + video_source->pixel_format = VIDEO_PIXELFORMAT_MAX; + } + jerry_release_value(jformat); + if(video_source->pixel_format >= VIDEO_PIXELFORMAT_MAX) { + return JS_CREATE_ERROR(TYPE, "Invalid config.format"); + } + video_source->pixel_bytes = get_pixel_bytes(video_source->pixel_format); + + switch (video_source->device) { + case DEVICETYPE_CMOSCAMERA: + { + jerry_value_t jtype = iotjs_jval_get_property(jconfig, "type"); + if (jerry_value_is_number(jtype)) { + video_source->camera = (camera_type_t)iotjs_jval_as_number(jtype); + } else { + video_source->camera = CAMERATYPE_OV7725; + } + jerry_release_value(jtype); + if(video_source->camera >= CAMERATYPE_MAX) { + return JS_CREATE_ERROR(TYPE, "Invalid config.type"); + } + } + break; + case DEVICETYPE_COMPOSITESIGNAL: + { + jerry_value_t jchannel = iotjs_jval_get_property(jconfig, "channel"); + if (jerry_value_is_number(jchannel)) { + video_source->channel = iotjs_jval_as_number(jchannel); + } else { + video_source->channel = CHANNEL_MAX; + } + jerry_release_value(jchannel); + if(video_source->channel >= CHANNEL_MAX) { + return JS_CREATE_ERROR(TYPE, "Invalid config.channel"); + } + + jerry_value_t jsignalFormat = iotjs_jval_get_property(jconfig, "signalFormat"); + if (jerry_value_is_number(jsignalFormat)) { + video_source->signal_format = (signal_format_t)iotjs_jval_as_number(jsignalFormat); + } else { + video_source->signal_format = SIGNALFORMAT_NTSC; + } + jerry_release_value(jsignalFormat); + if(video_source->signal_format >= SIGNALFORMAT_MAX) { + return JS_CREATE_ERROR(TYPE, "Invalid config.signalFormat"); + } + } + break; + default: + IOTJS_ASSERT(!"Invalid Device Type"); + return JS_CREATE_ERROR(TYPE, "Invalid Device Type"); + } + + return jerry_create_undefined(); +} + +static jerry_value_t video_get_start_param(iotjs_video_t* video, + const jerry_value_t jargv[], + const jerry_length_t jargc) { + if(jargc < 1) { + return JS_CREATE_ERROR(TYPE, "Invalid Arguments"); + } + + const jerry_value_t jbuffer = JS_GET_ARG(0, object); + iotjs_aligned_buffer_wrap_t* buffer_wrap = iotjs_aligned_buffer_wrap_from_jbuffer(jbuffer); + video->video_source.frame_buffer = iotjs_aligned_buffer_wrap_native_buffer_ptr(buffer_wrap); + if(((buffer_wrap->alignment % 32) != 0) || (((int)video->video_source.frame_buffer % 32) != 0)) { + return JS_CREATE_ERROR(TYPE, "Invalid buffer alignment"); + } + + return jerry_create_undefined(); +} + + +JS_FUNCTION(VideoCons) { + DJS_CHECK_THIS(); + DJS_CHECK_ARGS(2, object, number); + DJS_CHECK_ARG_IF_EXIST(2, function); + // Create Video object + jerry_value_t jvideo = JS_GET_THIS(); + iotjs_video_t* video = video_create(jvideo); + + jerry_value_t jconfig = JS_GET_ARG(0, object); + + uint32_t device_type = JS_GET_ARG(1, number); + if(device_type >= DEVICETYPE_MAX) { + IOTJS_ASSERT(!"Invalid Device Type"); + } + video->video_source.device = (device_type_t)device_type; + + // set configuration + jerry_value_t res = iotjs_video_set_platform_config(video, jconfig); + if (jerry_value_is_error(res)) { + return res; + } + + res = video_set_configuration(video, jconfig); + if (jerry_value_is_error(res)) { + return res; + } + + jerry_value_t jcallback = JS_GET_ARG_IF_EXIST(2, function); + + // If the callback doesn't exist, it is completed synchronously. + // Otherwise, it will be executed asynchronously. + if (!jerry_value_is_null(jcallback)) { + iotjs_ext_periph_call_async(video, jcallback, kVideoOpOpen, video_worker); + } else if (!iotjs_video_open(video)) { + return JS_CREATE_ERROR(COMMON, iotjs_ext_periph_error_str(kVideoOpOpen)); + } + + return jerry_create_undefined(); +} + + +JS_FUNCTION(Start) { + JS_DECLARE_THIS_PTR(video, video); + DJS_CHECK_ARGS(1, object); + + jerry_value_t jerr = video_get_start_param(video, jargv, jargc); + if(jerry_value_is_error(jerr)) { + return jerr; + } + + iotjs_ext_periph_call_async(video, JS_GET_ARG_IF_EXIST(1, function), kVideoOpStart, + video_worker); + return jerry_create_undefined(); +} + +JS_FUNCTION(StartSync) { + JS_DECLARE_THIS_PTR(video, video); + DJS_CHECK_ARGS(1, object); + + jerry_value_t jerr = video_get_start_param(video, jargv, jargc); + if(jerry_value_is_error(jerr)) { + return jerr; + } + + if(!iotjs_video_start(video)) { + return JS_CREATE_ERROR(COMMON, iotjs_ext_periph_error_str(kVideoOpStart)); + } + return jerry_create_undefined(); +} + +JS_FUNCTION(Stop) { + JS_DECLARE_THIS_PTR(video, video); + iotjs_ext_periph_call_async(video, JS_GET_ARG_IF_EXIST(0, function), kVideoOpStop, + video_worker); + return jerry_create_undefined(); +} + +JS_FUNCTION(StopSync) { + JS_DECLARE_THIS_PTR(video, video); + if(!iotjs_video_stop(video)) { + return JS_CREATE_ERROR(COMMON, iotjs_ext_periph_error_str(kVideoOpStop)); + } + return jerry_create_undefined(); +} + +JS_FUNCTION(ReadFrame) { + JS_DECLARE_THIS_PTR(video, video); + iotjs_ext_periph_call_async(video, JS_GET_ARG_IF_EXIST(1, function), kVideoOpReadFrame, + video_worker); + return jerry_create_undefined(); +} + +JS_FUNCTION(ReadFrameSync) { + JS_DECLARE_THIS_PTR(video, video); + iotjs_video_read_frame(video); + return jerry_create_undefined(); +} + +JS_FUNCTION(Close) { + JS_DECLARE_OBJECT_PTR(0, video, video); + iotjs_ext_periph_call_async(video, JS_GET_ARG_IF_EXIST(1, function), kVideoOpClose, + video_worker); + return jerry_create_undefined(); +} + +JS_FUNCTION(CloseSync) { + JS_DECLARE_OBJECT_PTR(0, video, video); + if(!iotjs_video_close(video)) { + return JS_CREATE_ERROR(COMMON, iotjs_ext_periph_error_str(kVideoOpClose)); + } + return jerry_create_undefined(); +} + +#endif // #if defined(USE_POSIX_BRIDGE) + + +jerry_value_t InitVideo() { + +#if defined(USE_POSIX_BRIDGE) + jerry_value_t jvideo_cons = jerry_create_external_function(VideoCons); + iotjs_jval_set_method(jvideo_cons, "closeImpl", Close); + iotjs_jval_set_method(jvideo_cons, "closeSyncImpl", CloseSync); + + jerry_value_t prototype = jerry_create_object(); + iotjs_jval_set_method(prototype, "start", Start); + iotjs_jval_set_method(prototype, "startSync", StartSync); + iotjs_jval_set_method(prototype, "stop", Stop); + iotjs_jval_set_method(prototype, "stopSync", StopSync); +// iotjs_jval_set_method(prototype, "readFrame", ReadFrame); +// iotjs_jval_set_method(prototype, "readFrameSync", ReadFrameSync); + + iotjs_jval_set_property_jval(jvideo_cons, IOTJS_MAGIC_STRING_PROTOTYPE, + prototype); + jerry_release_value(prototype); + + // Device Type + jerry_value_t jdevice = jerry_create_object(); + iotjs_jval_set_property_number(jdevice, "CMOSCAMERA", DEVICETYPE_CMOSCAMERA); + iotjs_jval_set_property_number(jdevice, "COMPOSITESIGNAL", DEVICETYPE_COMPOSITESIGNAL); + iotjs_jval_set_property_number(jdevice, "MAX", DEVICETYPE_MAX); + iotjs_jval_set_property_jval(jvideo_cons, "DEVICETYPE", jdevice); + jerry_release_value(jdevice); + + // Pixel Format + jerry_value_t jpixel = jerry_create_object(); + iotjs_jval_set_property_number(jpixel, "YCBCR422", VIDEO_PIXELFORMAT_YCBCR422); + iotjs_jval_set_property_number(jpixel, "RGB565", VIDEO_PIXELFORMAT_RGB565); + iotjs_jval_set_property_number(jpixel, "RGB888", VIDEO_PIXELFORMAT_RGB888); + iotjs_jval_set_property_number(jpixel, "MAX", VIDEO_PIXELFORMAT_MAX); + iotjs_jval_set_property_jval(jvideo_cons, "PIXELFORMAT", jpixel); + jerry_release_value(jpixel); + + // Camera Type + jerry_value_t jcamera = jerry_create_object(); + iotjs_jval_set_property_number(jcamera, "OV7725", CAMERATYPE_OV7725); + iotjs_jval_set_property_number(jcamera, "MAX", CAMERATYPE_MAX); + iotjs_jval_set_property_jval(jvideo_cons, "CAMERATYPE", jcamera); + jerry_release_value(jcamera); + + // Channel Number + jerry_value_t jchannel = jerry_create_object(); + iotjs_jval_set_property_number(jchannel, "CHANNEL_0", CHANNEL_0); + iotjs_jval_set_property_number(jchannel, "CHANNEL_1", CHANNEL_1); + iotjs_jval_set_property_number(jchannel, "MAX", CHANNEL_MAX); + iotjs_jval_set_property_jval(jvideo_cons, "CHANNEL", jchannel); + jerry_release_value(jchannel); + + // Signal Format + jerry_value_t jsignal = jerry_create_object(); + iotjs_jval_set_property_number(jsignal, "NTSC", SIGNALFORMAT_NTSC); + iotjs_jval_set_property_number(jsignal, "PAL", SIGNALFORMAT_PAL); + iotjs_jval_set_property_number(jsignal, "MAX", SIGNALFORMAT_MAX); + iotjs_jval_set_property_jval(jvideo_cons, "SIGNALFORMAT", jsignal); + jerry_release_value(jsignal); + +#else // #if defined(USE_POSIX_BRIDGE) + jerry_value_t jvideo_cons = jerry_create_object(); +#endif // #if defined(USE_POSIX_BRIDGE) + + return jvideo_cons; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/iotjs/src/modules/mbedos5/iotjs_module_video.h Thu Jul 11 18:48:09 2019 +0900 @@ -0,0 +1,44 @@ +/* Copyright 2017-present Renesas Electronics Corporation and other contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT 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_VIDEO_H +#define IOTJS_MODULE_VIDEO_H + +#include "iotjs_def.h" +#include "iotjs_handlewrap.h" +#include "iotjs_ext_module_periph_common.h" +#include "iotjs_reqwrap.h" + +typedef struct iotjs_video_platform_data_s iotjs_video_platform_data_t; + +typedef struct { + jerry_value_t jobject; + iotjs_video_platform_data_t* platform_data; + + video_source_t video_source; +} iotjs_video_t; + +bool iotjs_video_open(iotjs_video_t* video); +bool iotjs_video_start(iotjs_video_t* video); +bool iotjs_video_stop(iotjs_video_t* video); +bool iotjs_video_read_frame(iotjs_video_t* video); +bool iotjs_video_close(iotjs_video_t* video); + +void iotjs_video_create_platform_data(iotjs_video_t* video); +void iotjs_video_destroy_platform_data(iotjs_video_platform_data_t* pdata); +jerry_value_t iotjs_video_set_platform_config(iotjs_video_t* video, + const jerry_value_t jconfig); + +#endif /* IOTJS_MODULE_VIDEO_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/iotjs/src/modules/mbedos5/js/aligned_buffer.js Thu Jul 11 18:48:09 2019 +0900 @@ -0,0 +1,70 @@ +/* Copyright 2017-present Renesas Electronics Corporation and other contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES 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'); + + +isAlignedBuffer = function(arg) { + return arg instanceof AlignedBuffer; +} + + +// AlignedBuffer constructor +// [1] new AlignedBuffer(size, alignment) +// [2] new AlignedBuffer(buffer, alignment) +function AlignedBuffer(subject, alignment) { + if (!isAlignedBuffer(this)) { + return new AlignedBuffer(subject, alignment); + } + + if (util.isNumber(subject)) { + this.length = subject > 0 ? subject >>> 0 : 0; + } else if (util.isBuffer(subject) || isAlignedBuffer(subject)) { + this.length = subject.length; + } else { + throw new TypeError('Bad arguments: AlignedBuffer(number|Buffer|AlignedBuffer, number)'); + } + + if (util.isNumber(alignment)) { + this.alignment = alignment; + } else { + throw new TypeError('Bad arguments: AlignedBuffer(number|Buffer|AlignedBuffer, number)'); + } + + // 'native' is the aligned_buffer object created via the C API. + native(this, this.length, alignment); + + if (util.isBuffer(subject)) { + native.copyFromBuffer(this, subject); + } else if (isAlignedBuffer(subject)) { + native.copyFromAlignedBuffer(this, subject); + } +} + + +AlignedBuffer.prototype.toBuffer = function(start, end) { + start = start === undefined ? 0 : ~~start; + end = end === undefined ? this.length : ~~end; + + return native.toBuffer(this, start, end); +}; + + +AlignedBuffer.isAlignedBuffer = isAlignedBuffer; + +global.AlignedBuffer = AlignedBuffer; + +module.exports = AlignedBuffer; +module.exports.AlignedBuffer = AlignedBuffer;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/iotjs/src/modules/mbedos5/js/display.js Thu Jul 11 18:48:09 2019 +0900 @@ -0,0 +1,89 @@ +/* Copyright 2017-present Renesas Electronics Corporation and other contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +var display = exports; + +var lcd; + +function convert_lcd_type(type) { + switch(type) { + case '4.3inch': return native.LCDTYPE['4_3INCH']; + default: return native.LCDTYPE['4_3INCH']; + } +} + +function convert_buffer_format(format) { + switch(format) { + case 'ycbcr422': return native.BUFFERFORMAT.YCBCR422; + case 'rgb565': return native.BUFFERFORMAT.RGB565; + case 'rgb888': return native.BUFFERFORMAT.RGB888; + case 'argb8888': return native.BUFFERFORMAT.ARGB8888; + case 'argb4444': return native.BUFFERFORMAT.ARGB4444; + default: return native.BUFFERFORMAT.MAX; + } +} + +display.openLCD = function(config, callback) { + if(!lcd) { + lcd = new native({ + type: convert_lcd_type(config.type) + }, function(err) { + if(callback) { + lcd.type = config.type; + callback(err, lcd); + } + }); + } else { + if(callback) { + callback(new Error('LCD is already opened.')); + } + } +}; + + +display.openLCDSync = function(config) { + if(!lcd) { + lcd = new native({ + type: convert_lcd_type(config.type) + }); + lcd.type = config.type; + return lcd; + } else { + throw new Error('LCD is already opened.'); + } +}; + +native.prototype.start = function(layer, buf, format, callback) { + native.startImpl(this, layer, buf, convert_buffer_format(format), callback); +}; + +native.prototype.startSync = function(layer, buf, format) { + native.startSyncImpl(this, layer, buf, convert_buffer_format(format)); +}; + +native.prototype.close = function(callback) { + native.closeImpl(this, function(err) { + lcd = null; + if(callback) { + callback(err); + } + }); +}; + +native.prototype.closeSync = function() { + native.closeSyncImpl(this); + lcd = null; +}; +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/iotjs/src/modules/mbedos5/js/graphics.js Thu Jul 11 18:48:09 2019 +0900 @@ -0,0 +1,81 @@ +/* Copyright 2017-present Renesas Electronics Corporation and other contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +isGraphics = function(arg) { + return arg instanceof Graphics; +} + +function convert_buffer_format(format) { + switch(format) { +// case 'ycbcr422': return native.BUFFERFORMAT.YCBCR422; + case 'rgb565': return native.BUFFERFORMAT.RGB565; + case 'rgb888': return native.BUFFERFORMAT.RGB888; + case 'argb8888': return native.BUFFERFORMAT.ARGB8888; + case 'argb4444': return native.BUFFERFORMAT.ARGB4444; + default: return native.BUFFERFORMAT.MAX; + } +} + +function Graphics(config) { + if (!isGraphics(this)) { + return new Graphics(config); + } + native(this, { + buf: config.buf, + width: config.width, + height: config.height, + format: convert_buffer_format(config.format) + }); + this.frameBuffer = config.buf; + this.bufferWidth = config.width; + this.bufferHeight = config.height; + this.bufferFormat = config.format; +} + +Graphics.prototype.drawImage = function(image, x, y) { + native.drawImage(this, image, x, y); +}; + +Graphics.prototype.drawLine = function(startX, startY, endX, endY, color) { + native.drawLine(this, startX, startY, endX, endY, color); +}; + +Graphics.prototype.drawRect = function(x, y, width, height, color, fill) { + native.drawRect(this, x, y, width, height, color, fill ? true : false); +}; + +Graphics.prototype.drawArc = function(centerX, centerY, radius, startAngle, endAngle, color) { + native.drawArc(this, centerX, centerY, radius, startAngle, endAngle, color); +}; + +Graphics.prototype.drawCircle = function(centerX, centerY, radius, color, fill) { + native.drawCircle(this, centerX, centerY, radius, color, fill ? true : false); +}; + +Graphics.prototype.drawEllipse = function(centerX, centerY, radiusX, radiusY, color, fill) { + native.drawEllipse(this, centerX, centerY, radiusX, radiusY, color, fill ? true : false); +}; + +Graphics.prototype.drawPolygon = function(centerX, centerY, radius, sides, color, fill) { + native.drawPolygon(this, centerX, centerY, radius, sides, color, fill ? true : false); +}; + +Graphics.prototype.drawText = function(text, x, y, size, color, background) { + native.drawText(this, text, x, y, size, color, background); +}; + +module.exports = Graphics; +module.exports.Graphics = Graphics;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/iotjs/src/modules/mbedos5/js/jpeg.js Thu Jul 11 18:48:09 2019 +0900 @@ -0,0 +1,92 @@ +/* Copyright 2017-present Renesas Electronics Corporation and other contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +var handle = new native({}); + +function convert_pixel_format(format) { + switch(format) { + case 'ycbcr422': return handle.PIXELFORMAT.YCBCR422; + case 'argb8888': return handle.PIXELFORMAT.ARGB8888; + case 'rgb565': return handle.PIXELFORMAT.RGB565; + default: return handle.PIXELFORMAT.MAX; + } +} + +function Jpeg() { +} + + +Jpeg.prototype.encode = function(image, callback) { + handle.encode({ + width: image.width, + height: image.height, + format: convert_pixel_format(image.format), + bitmap: image.bitmap + }, callback); +}; + + +Jpeg.prototype.encodeSync = function(image) { + return handle.encodeSync({ + width: image.width, + height: image.height, + format: convert_pixel_format(image.format), + bitmap: image.bitmap + }); +}; + + +Jpeg.prototype.decode = function(jpegData, config, callback) { + handle.decode(jpegData, { + width: config.width, + height: config.height, + format: convert_pixel_format(config.format), + alpha: config.alpha + }, function(err, bitmap) { + if(callback) { + var ret; + if(!err) { + ret = { + width : config.width, + height : config.height, + format : config.format, + bitmap : bitmap + }; + } + callback(err, ret); + } + }); +}; + + +Jpeg.prototype.decodeSync = function(jpegData, config) { + var bitmap = handle.decodeSync(jpegData, { + width: config.width, + height: config.height, + format: convert_pixel_format(config.format), + alpha: config.alpha + }); + var ret = { + width : config.width, + height : config.height, + format : config.format, + bitmap : bitmap + }; + return ret; +}; + + +module.exports = new Jpeg(); +module.exports.Jpeg = Jpeg;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/iotjs/src/modules/mbedos5/js/nic.js Thu Jul 11 18:48:09 2019 +0900 @@ -0,0 +1,78 @@ +/* Copyright 2017-present Renesas Electronics Corporation and other contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT 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 Nic() { +} + +function func_ifup(nic, param) { + param = param || {}; + var dhcp = !param.ip || !param.netmask || !param.gateway; + var obj = []; + obj.push("dhcp:"); obj.push(dhcp ? "1" : "0"); + if(!dhcp) { + if(param.ip) { obj.push("ip:"); obj.push(param.ip); } + if(param.netmask) { obj.push("netmask:"); obj.push(param.netmask); } + if(param.gateway) { obj.push("gateway:"); obj.push(param.gateway); } + } + if(param.dns) { obj.push("dns:"); obj.push(param.dns); } + if(param.wifi) { + obj.push("wifi.ssid:"); obj.push(param.wifi.ssid || "<SSID>"); + obj.push("wifi.password:"); obj.push(param.wifi.password || "<PASSWORD>"); + obj.push("wifi.security:"); obj.push(param.wifi.security || "<WEP/WPA/WPA2>"); + obj.push("wifi.ch:"); obj.push(param.wifi.ch || 11); + } + return native.ifup(nic, obj.join('\n')); +} + +function func_ifdown(nic) { + return native.ifdown(nic); +} + +function func_ifconfig(nic) { + return JSON.parse(native.ifconfig(nic)); +} + +function func_ntpdate(nic, param) { + param = param || {}; + var obj = { + server : param.server || "0.pool.ntp.org", + port : param.port || 123, + timeout: param.timeout || 10 * 1000, + }; + return native.ntpdate(nic, obj); +} + +Nic.prototype.enumerate = function() { + var nics = JSON.parse(native.enumerate()); + Object.keys(nics).forEach(function(nic) { + nics[nic].ifup = function(param) { + return func_ifup(nic, param); + }; + nics[nic].ifdown = function() { + return func_ifdown(nic); + }; + nics[nic].ifconfig = function() { + return func_ifconfig(nic); + }; + nics[nic].ntpdate = function(param) { + return func_ntpdate(nic, param); + }; + }); + return nics; +} + +module.exports = new Nic(); +module.exports.Nic = Nic; +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/iotjs/src/modules/mbedos5/js/video.js Thu Jul 11 18:48:09 2019 +0900 @@ -0,0 +1,104 @@ +/* Copyright 2017-present Renesas Electronics Corporation and other contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +var video = exports; + +var videoSource; + +function convert_pixel_format(format) { + switch(format) { + case 'ycbcr422': return native.PIXELFORMAT.YCBCR422; + case 'rgb565': return native.PIXELFORMAT.RGB565; + case 'rgb888': return native.PIXELFORMAT.RGB888; + default: return native.PIXELFORMAT.MAX; + } +} + +function convert_camera_type(type) { + switch(type) { + case 'ov7725': return native.CAMERATYPE.OV7725; + default: return native.CAMERATYPE.OV7725; + } +} + +function convert_channel_num(channel) { + switch(channel) { + case 0: return native.CHANNEL.CHANNEL_0; + case 1: return native.CHANNEL.CHANNEL_1; + default: return native.CHANNEL.MAX; + } +} + +function convert_signal_format(signal) { + switch(signal) { + case 'ntsc': return native.SIGNALFORMAT.NTSC; + case 'pal': return native.SIGNALFORMAT.PAL; + default: return native.SIGNALFORMAT.NTSC; + } +} + +video.openCMOSCamera = function(config, callback) { + if(!videoSource) { + videoSource = new native({ + width: config.width, + height: config.height, + format: convert_pixel_format(config.format), + type: convert_camera_type(config.type) + }, native.DEVICETYPE.CMOSCAMERA, function(err) { + if(callback) { + videoSource.pixelFormat = config.format; + videoSource.type = config.type; + callback(err, videoSource); + } + }); + } else { + if(callback) { + callback(new Error('Camera is already opened.')); + } + } +}; + + +video.openCMOSCameraSync = function(config) { + if(!videoSource) { + videoSource = new native({ + width: config.width, + height: config.height, + format: convert_pixel_format(config.format), + type: convert_camera_type(config.type) + }, native.DEVICETYPE.CMOSCAMERA); + + videoSource.pixelFormat = config.format; + videoSource.type = config.type; + return videoSource; + } else { + throw new Error('Camera is already opened.'); + } +}; + + +native.prototype.close = function(callback) { + native.closeImpl(this, function(err) { + videoSource = null; + if(callback) { + callback(err); + } + }); +}; + +native.prototype.closeSync = function() { + native.closeSyncImpl(this); + videoSource = null; +};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/iotjs/src/modules/mbedos5/modules.json Thu Jul 11 18:48:09 2019 +0900 @@ -0,0 +1,37 @@ +{ + "modules": { + "fixup": { + "js_file": "../_common/js/fixup.js" + }, + "nic": { + "native_files": ["iotjs_module_nic.c"], + "init": "InitNic", + "js_file": "js/nic.js" + }, + "aligned_buffer": { + "native_files": ["iotjs_module_aligned_buffer.c"], + "init": "InitAlignedBuffer", + "js_file": "js/aligned_buffer.js" + }, + "video": { + "native_files": ["iotjs_module_video.c", "iotjs_ext_module_periph_common.c"], + "init": "InitVideo", + "js_file": "js/video.js" + }, + "jpeg": { + "native_files": ["iotjs_module_jpeg.c", "iotjs_ext_module_periph_common.c"], + "init": "InitJpeg", + "js_file": "js/jpeg.js" + }, + "display": { + "native_files": ["iotjs_module_display.c", "iotjs_ext_module_periph_common.c"], + "init": "InitDisplay", + "js_file": "js/display.js" + }, + "graphics": { + "native_files": ["iotjs_module_graphics.c", "iotjs_ext_module_periph_common.c"], + "init": "InitGraphics", + "js_file": "js/graphics.js" + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/iotjs/src/platform/mbedos5/.mbed Thu Jul 11 18:48:09 2019 +0900 @@ -0,0 +1,3 @@ +TOOLCHAIN=GCC_ARM +ROOT=. +TARGET=RZ_A1H
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/iotjs/src/platform/mbedos5/Makefile Thu Jul 11 18:48:09 2019 +0900 @@ -0,0 +1,129 @@ +# Copyright JS Foundation and other contributors, http://js.foundation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# USAGE: +# specify the board using the command line: +# make BOARD=[mbed board name] + +BOARD=$(subst [mbed] ,,$(shell mbed target)) + +DEBUG?=0 +MBED_VERBOSE?=0 + +MBED_CLI_FLAGS=-j0 --source ../../../ + +EXTRA_SRC= + +IOTJS_JS_MODULES= --external-modules=./src/modules/mbedos5 \ + --cmake-param=-DENABLE_MODULE_FIXUP=ON \ + --cmake-param=-DENABLE_MODULE_NIC=ON \ + --cmake-param=-DENABLE_MODULE_DGRAM=ON \ + --cmake-param=-DENABLE_MODULE_HTTPS=ON \ + --cmake-param=-DENABLE_MODULE_TLS=ON \ + --cmake-param=-DENABLE_MODULE_UART=OFF \ + --cmake-param=-DENABLE_MODULE_GPIO=OFF \ + --cmake-param=-DENABLE_MODULE_I2C=OFF \ + --cmake-param=-DENABLE_MODULE_SPI=OFF \ + --cmake-param=-DENABLE_MODULE_VIDEO=ON \ + --cmake-param=-DENABLE_MODULE_JPEG=ON \ + --cmake-param=-DENABLE_MODULE_DISPLAY=ON \ + --cmake-param=-DENABLE_MODULE_ALIGNED_BUFFER=ON \ + --cmake-param=-DENABLE_MODULE_GRAPHICS=ON \ + --no-snapshot + +ifneq ($(EXTRA_SRC),) +EXTRA_SRC_MOD=--source $(subst :, --source ,$(EXTRA_SRC)) +MBED_CLI_FLAGS += $(EXTRA_SRC_MOD) +endif + +EXTERN_BUILD_DIR= + +ifneq ($(EXTERN_BUILD_DIR),) +MBED_CLI_FLAGS += --build $(EXTERN_BUILD_DIR) +endif + +ifeq ($(DEBUG), 1) +MBED_CLI_FLAGS += --profile ./profiles/debug.json +else +MBED_CLI_FLAGS += --profile ./profiles/release.json +endif + +MBED_CLI_FLAGS += --app-config ./mbed_app.json + +ifeq ($(MBED_VERBOSE), 1) +MBED_CLI_FLAGS += -v +else ifeq ($(MBED_VERBOSE), 2) +MBED_CLI_FLAGS += -vv +endif + +MBED_CLI_FLAGS += -D JERRY_SYSTEM_ALLOCATOR -D JERRY_CPOINTER_32_BIT +MBED_CLI_FLAGS += -t GCC_ARM +ifeq ($(OS),Windows_NT) +MBED_CLI_FLAGS += -f +endif + +.PHONY: all js2c getlibs rebuild library +all: ../../../src/iotjs_js.c .mbed ../../../iotjs_def.h ../../../.mbedignore + mbed target $(BOARD) + mbed compile $(MBED_CLI_FLAGS) + +library: .mbed ../../../.mbedignore + # delete encoded js code if it exists + -rm -f ../../../src/iotjs_js.c + -rm -f ../../../src/iotjs_js.h + -rm -f ../../../src/iotjs_module_inl.h + -rm -f ../../../src/iotjs_string_ext.inl.h + -rm -f ../../../iotjs_def.h + -rm -f ../../../.mbedignore + mbed target $(BOARD) + mbed compile $(MBED_CLI_FLAGS) --library + +clean: + -rm -rf ./BUILD/$(BOARD) + ###../../../tools/build.py --clean + -rm -f ../../../src/iotjs_js.c + -rm -f ../../../src/iotjs_js.h + -rm -f ../../../src/iotjs_module_inl.h + -rm -f ../../../src/iotjs_string_ext.inl.h + -rm -f ../../../iotjs_def.h + -rm -f ../../../.mbedignore + +js2c: + ###python ../../../tools/js2c.py --buildtype=release --modules "$(IOTJS_JS_MODULES)" + ../../../tools/build.py $(IOTJS_JS_MODULES) + +../../../src/iotjs_js.c: js2c + +getlibs: .mbed + +.mbed: + echo 'ROOT=.' > .mbed + mbed config root . + mbed toolchain GCC_ARM + mbed target $(BOARD) + mbed deploy + +../../../iotjs_def.h: +ifeq ($(OS),Windows_NT) + copy template.iotjs_def.h.txt ..\..\..\iotjs_def.h +else + cp ./template.iotjs_def.h.txt ../../../iotjs_def.h +endif + +../../../.mbedignore: +ifeq ($(OS),Windows_NT) + copy template.mbedignore.txt ..\..\..\.mbedignore +else + cp ./template.mbedignore.txt ../../../.mbedignore +endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/iotjs/src/platform/mbedos5/iotjs_mbed.cpp Thu Jul 11 18:48:09 2019 +0900 @@ -0,0 +1,123 @@ +/* Copyright 2017-present Renesas Electronics Corporation and other contributors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT 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 <iostream> +#include <fstream> +#include <string> +#include <algorithm> + +#define NAME_STRINGIZER_(name) #name +#define NAME_STRINGIZER(name) NAME_STRINGIZER_(name) + +#include "mbed.h" +#include "iotjs.h" + +// git clone https://github.com/ARMmbed/sd-driver.git +#include "FATFileSystem.h" +#include "SDBlockDevice.h" + +namespace { + + #if defined(SD_MOUNT_NAME) + const std::string mount_name_ = NAME_STRINGIZER(SD_MOUNT_NAME); + #else + const std::string mount_name_ = "sd"; + #endif + + bool by_file( std::string& fullpath ) + { + fullpath.clear(); + std::cout << std::endl << "input js fullpath here: "; + std::string path; + std::getline( std::cin, path ); + path.erase( std::remove( path.begin(), path.end(), '\r' ), path.end() ); + if( path.empty() || path[ path.size() - 1 ] == '!' ) { // quit + return false; + } + if( path[ path.size() - 1 ] == '@' ) { // re-try + return true; + } + fullpath = path; + return false; + } + + bool by_code( std::string& fullpath ) + { + fullpath.clear(); + std::cout << std::endl << "input javascript code here: "; + std::string code; + while( true ) { + std::string line; + std::getline( std::cin, line ); + line.erase( std::remove( line.begin(), line.end(), '\r' ), line.end() ); + code += line + "\n"; + if( line.empty() ) { // ignore + ; + } + else if( line[ line.size() - 1 ] == '!' ) { // quit + return false; + } + else if( line[ line.size() - 1 ] == '@' ) { // re-try + return true; + } + else if( line.find("//eoc") != std::string::npos ) { + break; + } + } + + fullpath = "/" + mount_name_ + "/_temp_code.js"; + std::ofstream ofs( fullpath.c_str() ); + ofs << code; + return false; + } + + void iotjs_main() + { + printf("IoT.js for mbed-os...\n"); + printf(" mbed-os version: %d.%d.%d \n", MBED_MAJOR_VERSION, MBED_MINOR_VERSION, MBED_PATCH_VERSION); + printf(" build timestamp: " __DATE__ " " __TIME__ " \n"); + + std::string path; + for(;;) { + while( by_file( path ) ); if( !path.empty() ) break; + while( by_code( path ) ); if( !path.empty() ) break; + /// while( by_http( path ) ); if( !path.empty() ) break; + } + + int ac = 2; + const char* av[] = {"iotjs", &path[0], 0}; + iotjs_entry(ac, (char**)av); + } + +} // namespace file-local + +int main() +{ + Serial pc( USBTX, USBRX ); + pc.baud( 115200 ); + + SDBlockDevice bd( P8_5, P8_6, P8_3, P8_4 ); + FATFileSystem fs( mount_name_.c_str() ); + int error = fs.mount( &bd ); (void)error; // Mounting the filesystem on /<mount_name> + + const uint32_t stack_size = 32 * 1024; + Thread iotjsThread( osPriorityNormal, stack_size ); + iotjsThread.start( callback( iotjs_main ) ); + iotjsThread.join(); + + std::cout << "bye!" << std::endl; + return 0; +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/iotjs/src/platform/mbedos5/mbed-os/lwip_improve.patch Thu Jul 11 18:48:09 2019 +0900 @@ -0,0 +1,76 @@ +diff --git a/features/FEATURE_LWIP/lwip-interface/lwipopts.h b/features/FEATURE_LWIP/lwip-interface/lwipopts.h +index a9a1dd5..e21b11d 100644 +--- a/features/FEATURE_LWIP/lwip-interface/lwipopts.h ++++ b/features/FEATURE_LWIP/lwip-interface/lwipopts.h +@@ -139,6 +139,26 @@ + + #define LWIP_RAM_HEAP_POINTER lwip_ram_heap + ++// Number of simultaneously queued TCP segments. ++#ifdef MBED_CONF_LWIP_MEMP_NUM_TCP_SEG ++#define MEMP_NUM_TCP_SEG MBED_CONF_LWIP_MEMP_NUM_TCP_SEG ++#endif ++ ++// TCP Maximum segment size. ++#ifdef MBED_CONF_LWIP_TCP_MSS ++#define TCP_MSS MBED_CONF_LWIP_TCP_MSS ++#endif ++ ++// TCP sender buffer space (bytes). ++#ifdef MBED_CONF_LWIP_TCP_SND_BUF ++#define TCP_SND_BUF MBED_CONF_LWIP_TCP_SND_BUF ++#endif ++ ++// TCP sender buffer space (bytes). ++#ifdef MBED_CONF_LWIP_TCP_WND ++#define TCP_WND MBED_CONF_LWIP_TCP_WND ++#endif ++ + // Number of pool pbufs. + // Each requires 684 bytes of RAM (if MSS=536 and PBUF_POOL_BUFSIZE defaulting to be based on MSS) + #ifdef MBED_CONF_LWIP_PBUF_POOL_SIZE +diff --git a/features/FEATURE_LWIP/lwip-interface/mbed_lib.json b/features/FEATURE_LWIP/lwip-interface/mbed_lib.json +index 83266ea..e9c0949 100644 +--- a/features/FEATURE_LWIP/lwip-interface/mbed_lib.json ++++ b/features/FEATURE_LWIP/lwip-interface/mbed_lib.json +@@ -72,6 +72,22 @@ + "help": "Maximum number of open UDPSocket instances allowed, including one used internally for DNS. Each requires 84 bytes of pre-allocated RAM", + "value": 4 + }, ++ "memp-num-tcp-seg": { ++ "help": "Number of simultaneously queued TCP segments. Current default (used if null here) is set to 16 in opt.h, unless overridden by target Ethernet drivers.", ++ "value": null ++ }, ++ "tcp-mss": { ++ "help": "TCP Maximum segment size. Current default (used if null here) is set to 536 in opt.h, unless overridden by target Ethernet drivers.", ++ "value": null ++ }, ++ "tcp-snd-buf": { ++ "help": "TCP sender buffer space (bytes). Current default (used if null here) is set to (2 * TCP_MSS) in opt.h, unless overridden by target Ethernet drivers.", ++ "value": null ++ }, ++ "tcp-wnd": { ++ "help": "TCP sender buffer space (bytes). Current default (used if null here) is set to (4 * TCP_MSS) in opt.h, unless overridden by target Ethernet drivers.", ++ "value": null ++ }, + "pbuf-pool-size": { + "help": "Number of pbufs in pool - usually used for received packets, so this determines how much data can be buffered between reception and the application reading. If a driver uses PBUF_RAM for reception, less pool may be needed. Current default (used if null here) is set to 5 in lwipopts.h, unless overridden by target Ethernet drivers.", + "value": null +@@ -124,6 +140,17 @@ + }, + "LPC546XX": { + "mem-size": 36496 ++ }, ++ "RZ_A1H": { ++ "tcpip-thread-stacksize": 1328, ++ "default-thread-stacksize": 640, ++ "ppp-thread-stacksize": 896, ++ "memp-num-tcp-seg": 32, ++ "tcp-mss": 1440, ++ "tcp-snd-buf": "(8 * TCP_MSS)", ++ "tcp-wnd": "(TCP_MSS * 8)", ++ "pbuf-pool-size": 16, ++ "mem-size": 51200 + } + } + }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/iotjs/src/platform/mbedos5/mbed-os/trng_support.patch Thu Jul 11 18:48:09 2019 +0900 @@ -0,0 +1,133 @@ +diff --git a/targets/TARGET_RENESAS/TARGET_RZ_A1XX/TARGET_RZ_A1H/trng_api_esp32.cpp b/targets/TARGET_RENESAS/TARGET_RZ_A1XX/TARGET_RZ_A1H/trng_api_esp32.cpp +new file mode 100755 +index 0000000..239aa46 +--- /dev/null ++++ b/targets/TARGET_RENESAS/TARGET_RZ_A1XX/TARGET_RZ_A1H/trng_api_esp32.cpp +@@ -0,0 +1,101 @@ ++/* mbed Microcontroller Library ++ * Copyright (c) 2006-2017 ARM Limited ++ * ++ * Licensed under the Apache License, Version 2.0 (the "License"); ++ * you may not use this file except in compliance with the License. ++ * You may obtain a copy of the License at ++ * ++ * http://www.apache.org/licenses/LICENSE-2.0 ++ * ++ * Unless required by applicable law or agreed to in writing, software ++ * distributed under the License is distributed on an "AS IS" BASIS, ++ * WITHOUT 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(DEVICE_TRNG) ++#include "drivers/I2C.h" ++#include "platform/mbed_wait_api.h" ++ ++#define ESP32_I2C_ADDR (0x28<<1) ++#define RETRY_CNT_MAX (20) ++ ++/* Implementation that should never be optimized out by the compiler */ ++static void mbedtls_zeroize( void *v, size_t n ) { ++ volatile unsigned char *p = (unsigned char *)v; while( n-- ) *p++ = 0; ++} ++ ++extern "C" void trng_init_esp32(void) ++{ ++ /* P3_10(EN), P3_9(IO0) */ ++ if (((GPIOP3 & 0x0400) == 0) ++ || ((GPIOPMC3 & 0x0400) != 0) ++ || ((GPIOPM3 & 0x0400) != 0) ++ ++ || ((GPIOP3 & 0x0200) == 0) ++ || ((GPIOPMC3 & 0x0200) != 0) ++ || ((GPIOPM3 & 0x0200) != 0)) { ++ ++ /* P3_10(EN) */ ++ GPIOP3 &= ~0x0400; /* Outputs low level */ ++ GPIOPMC3 &= ~0x0400; /* Port mode */ ++ GPIOPM3 &= ~0x0400; /* Output mode */ ++ ++ /* P3_9(IO0) */ ++ GPIOP3 &= ~0x0200; /* Outputs low level */ ++ GPIOPMC3 &= ~0x0200; /* Port mode */ ++ GPIOPM3 &= ~0x0200; /* Output mode */ ++ ++ GPIOP3 |= 0x0200; /* Outputs hi level */ ++ wait_ms(5); ++ GPIOP3 |= 0x0400; /* Outputs hi level */ ++ } ++} ++ ++extern "C" void trng_free_esp32(void) ++{ ++ // do nothing ++} ++ ++extern "C" int trng_get_bytes_esp32(uint8_t *output, size_t length, size_t *output_length) ++{ ++ mbed::I2C mI2c(I2C_SDA, I2C_SCL); ++ int ret; ++ char send_data[1]; ++ char recv_data[4]; ++ size_t idx = 0; ++ int i; ++ int retry_cnt = 0; ++ ++ if ((output == NULL) || (output_length == NULL)) { ++ return -1; ++ } ++ ++ while ((retry_cnt < RETRY_CNT_MAX) && (idx < length)) { ++ send_data[0] = 0; ++ ret = mI2c.write(ESP32_I2C_ADDR, send_data, sizeof(send_data)); ++ if (ret == 0) { ++ ret = mI2c.read(ESP32_I2C_ADDR, recv_data, sizeof(recv_data)); ++ if (ret == 0) { ++ for (i = 0; (i < sizeof(recv_data)) && (idx < length); i++) { ++ output[idx++] = recv_data[i]; ++ } ++ } ++ } ++ if (ret != 0) { ++ retry_cnt++; ++ wait_ms(100); ++ } ++ } ++ if (retry_cnt >= RETRY_CNT_MAX) { ++ idx = 0; ++ mbedtls_zeroize(output, length); ++ } ++ *output_length = idx; ++ ++ mbedtls_zeroize(recv_data, sizeof(recv_data)); ++ ++ return (idx != 0 ? 0 : -1); ++} ++#endif +diff --git a/targets/TARGET_RENESAS/TARGET_RZ_A1XX/trng_api.c b/targets/TARGET_RENESAS/TARGET_RZ_A1XX/trng_api.c +index de4cbd3..595fbf6 100644 +--- a/targets/TARGET_RENESAS/TARGET_RZ_A1XX/trng_api.c ++++ b/targets/TARGET_RENESAS/TARGET_RZ_A1XX/trng_api.c +@@ -17,7 +17,7 @@ + #if defined(DEVICE_TRNG) + #include "trng_api.h" + +-#if defined(TARGET_GR_LYCHEE) ++#if defined(TARGET_GR_LYCHEE) || (TARGET_RZ_A1H) + + extern void trng_init_esp32(void); + extern void trng_free_esp32(void); +diff --git a/targets/targets.json b/targets/targets.json +index 6cf7cea..d1e30bc 100755 +--- a/targets/targets.json ++++ b/targets/targets.json +@@ -2859,7 +2859,7 @@ + "inherits": ["RZ_A1XX"], + "supported_form_factors": ["ARDUINO"], + "extra_labels_add": ["RZA1H", "MBRZA1H", "RZ_A1_EMAC"], +- "device_has_add": ["EMAC", "FLASH"], ++ "device_has_add": ["EMAC", "FLASH", "TRNG"], + "release_versions": ["2", "5"], + "device_name": "R7S72100", + "bootloader_supported": true
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/iotjs/src/platform/mbedos5/mbed_app.json Thu Jul 11 18:48:09 2019 +0900 @@ -0,0 +1,177 @@ +{ + "artifact_name": "iotjs", + "config": { + "platform-name": { + "help": "configure the platform name for 'process.platform' property", + "macro_name": "PLATFORM_NAME", + "value": "mbedos" + }, + "target-name": { + "help": "configure the target board name", + "macro_name": "TARGET_BOARD", + "value": "GR-PEACH" + }, + "sd-mount-name": { + "help": "configure the name to add filesystem to tree as", + "macro_name": "SD_MOUNT_NAME", + "value": "sd" + }, + "default-working-dir": { + "help": "configure the default working directory", + "macro_name": "DEFAULT_WORKING_DIR", + "default": "/", + "example": "/sd/test", + "value": "/" + }, + "virtual-FIN-packet": { + "help": "configure the virtual FIN packet string", + "macro_name": "VIRTUAL_FIN_PACKET", + "value": "@FINFIN@" + } + }, + + "macros": [ + "USE_POSIX_BRIDGE", + + "__MBED_OS__", + "__LINUX__", "__linux__", + + "LWIP_HAVE_LOOPIF=1", + + "JERRY_JS_PARSER", "JSMBED_OVERRIDE_JERRY_PORT_LOG", + + "FEATURE_JS_PARSER=1", "JERRY_JS_PARSER", + "FEATURE_SNAPSHOT_EXEC=0", + "FEATURE_SNAPSHOT_SAVE=0", + "FEATURE_VM_EXEC_STOP=1", "JERRY_VM_EXEC_STOP", + + "ENABLE_MODULE_NIC=1", + "ENABLE_MODULE_ADC=0", + "ENABLE_MODULE_ASSERT=1", + "ENABLE_MODULE_BLE=0", + "ENABLE_MODULE_BLE_CHARACTERISTIC=0", + "ENABLE_MODULE_BLE_DESCRIPTOR=0", + "ENABLE_MODULE_BLE_HCI_SOCKET=0", + "ENABLE_MODULE_BLE_HCI_SOCKET_ACL_STREAM=0", + "ENABLE_MODULE_BLE_HCI_SOCKET_BINDINGS=0", + "ENABLE_MODULE_BLE_HCI_SOCKET_CRYPTO=0", + "ENABLE_MODULE_BLE_HCI_SOCKET_GAP=0", + "ENABLE_MODULE_BLE_HCI_SOCKET_GATT=0", + "ENABLE_MODULE_BLE_HCI_SOCKET_HCI=0", + "ENABLE_MODULE_BLE_HCI_SOCKET_HCI_STATUS=0", + "ENABLE_MODULE_BLE_HCI_SOCKET_MGMT=0", + "ENABLE_MODULE_BLE_HCI_SOCKET_SMP=0", + "ENABLE_MODULE_BLE_PRIMARY_SERVICE=0", + "ENABLE_MODULE_BLE_UUID_UTIL=0", + "ENABLE_MODULE_BRIDGE=0", + "ENABLE_MODULE_BUFFER=1", + "ENABLE_MODULE_CONSOLE=1", + "ENABLE_MODULE_CONSTANTS=1", + "ENABLE_MODULE_DGRAM=1", + "ENABLE_MODULE_DNS=1", + "ENABLE_MODULE_DYNAMICLOADER=1", + "ENABLE_MODULE_EVENTS=1", + "ENABLE_MODULE_FS=1", + "ENABLE_MODULE_GPIO=0", + "ENABLE_MODULE_HTTP=1", + "ENABLE_MODULE_HTTPS=1", + "ENABLE_MODULE_HTTP_CLIENT=1", + "ENABLE_MODULE_HTTP_COMMON=1", + "ENABLE_MODULE_HTTP_INCOMING=1", + "ENABLE_MODULE_HTTP_OUTGOING=1", + "ENABLE_MODULE_HTTP_PARSER=1", + "ENABLE_MODULE_HTTP_SERVER=1", + "ENABLE_MODULE_I2C=0", + "ENABLE_MODULE_IOTJS_BASIC_MODULES=1", + "ENABLE_MODULE_IOTJS_CORE_MODULES=1", + "ENABLE_MODULE_MODULE=1", + "ENABLE_MODULE_MQTT=0", + "ENABLE_MODULE_NET=1", + "ENABLE_MODULE_PROCESS=1", + "ENABLE_MODULE_PWM=0", + "ENABLE_MODULE_SPI=0", + "ENABLE_MODULE_STM32F4DIS=0", + "ENABLE_MODULE_STREAM=1", + "ENABLE_MODULE_STREAM_DUPLEX=1", + "ENABLE_MODULE_STREAM_INTERNAL=1", + "ENABLE_MODULE_STREAM_READABLE=1", + "ENABLE_MODULE_STREAM_WRITABLE=1", + "ENABLE_MODULE_TCP=1", + "ENABLE_MODULE_TIMERS=1", + "ENABLE_MODULE_TIZEN=0", + "ENABLE_MODULE_TLS=1", + "ENABLE_MODULE_UART=0", + "ENABLE_MODULE_UDP=1", + "ENABLE_MODULE_UTIL=1", + "ENABLE_MODULE_WEBSOCKET=0", + "ENABLE_MODULE_VIDEO=1", + "ENABLE_MODULE_DISPLAY=1", + "ENABLE_MODULE_JPEG=1", + "ENABLE_MODULE_ALIGNED_BUFFER=1", + "ENABLE_MODULE_GRAPHICS=1", + + "MBEDTLS_ENTROPY_HARDWARE_ALT", + "MBEDTLS_HAVE_ASM", + "MBEDTLS_HAVE_TIME", + "MBEDTLS_AES_ROM_TABLES", + "MBEDTLS_CIPHER_MODE_CBC", + "MBEDTLS_REMOVE_ARC4_CIPHERSUITES", + "MBEDTLS_ECP_DP_SECP256R1_ENABLED", + "MBEDTLS_ECP_DP_SECP384R1_ENABLED", + "MBEDTLS_ECP_DP_SECP256K1_ENABLED", + "MBEDTLS_ECP_DP_BP256R1_ENABLED", + "MBEDTLS_ECP_DP_BP384R1_ENABLED", + "MBEDTLS_KEY_EXCHANGE_RSA_ENABLED", + "MBEDTLS_KEY_EXCHANGE_DHE_RSA_ENABLED", + "MBEDTLS_KEY_EXCHANGE_ECDHE_RSA_ENABLED", + "MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED", + "MBEDTLS_KEY_EXCHANGE_ECDH_ECDSA_ENABLED", + "MBEDTLS_KEY_EXCHANGE_ECDH_RSA_ENABLED", + "MBEDTLS_PKCS1_V15", + "MBEDTLS_PKCS1_V21", + "MBEDTLS_SHA256_SMALLER", + "MBEDTLS_SSL_PROTO_TLS1", + "MBEDTLS_SSL_PROTO_TLS1_1", + "MBEDTLS_SSL_PROTO_TLS1_2", + "MBEDTLS_SSL_SERVER_NAME_INDICATION", + "MBEDTLS_AES_C", + "MBEDTLS_ASN1_PARSE_C", + "MBEDTLS_ASN1_WRITE_C", + "MBEDTLS_BASE64_C", + "MBEDTLS_BIGNUM_C", + "MBEDTLS_CIPHER_C", + "MBEDTLS_CTR_DRBG_C", + "MBEDTLS_DHM_C", + "MBEDTLS_ECDH_C", + "MBEDTLS_ECDSA_C", + "MBEDTLS_ECP_C", + "MBEDTLS_ENTROPY_C", + "MBEDTLS_GCM_C", + "MBEDTLS_MD_C", + "MBEDTLS_MD5_C", + "MBEDTLS_OID_C", + "MBEDTLS_PEM_PARSE_C", + "MBEDTLS_PK_C", + "MBEDTLS_PK_PARSE_C", + "MBEDTLS_RSA_C", + "MBEDTLS_SHA1_C", + "MBEDTLS_SHA256_C", + "MBEDTLS_SSL_CLI_C", + "MBEDTLS_SSL_SRV_C", + "MBEDTLS_SSL_TLS_C", + "MBEDTLS_X509_USE_C", + "MBEDTLS_X509_CRT_PARSE_C" + ], + + "target_overrides": { + "*": { + "lwip.socket-max": 60, + "lwip.tcp-server-max": 60, + "lwip.tcp-socket-max": 60, + "lwip.udp-socket-max": 60, + "lwip.pbuf-pool-size": 16, + "lwip.pbuf-pool-bufsize": null, + "lwip.mem-size": 51200 + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/iotjs/src/platform/mbedos5/profiles/debug.json Thu Jul 11 18:48:09 2019 +0900 @@ -0,0 +1,78 @@ +{ + "GCC_ARM": { + "common": ["-c", "-Wall", "-Wextra", + "-Wno-unused-parameter", "-Wno-missing-field-initializers", + "-fmessage-length=0", "-fno-exceptions", "-fno-builtin", + "-ffunction-sections", "-fdata-sections", "-funsigned-char", + "-MMD", "-fno-delete-null-pointer-checks", + "-fomit-frame-pointer", "-O0", "-g3", "-DMBED_DEBUG", + "-DMBED_TRAP_ERRORS_ENABLED=1"], + "asm": ["-x", "assembler-with-cpp"], + "c": ["-std=gnu99"], + "cxx": ["-std=gnu++11", "-fno-rtti", "-Wvla"], + "ld": ["-Wl,--gc-sections", "-Wl,--wrap,main", "-Wl,--wrap,_malloc_r", + "-Wl,--wrap,_free_r", "-Wl,--wrap,_realloc_r", "-Wl,--wrap,_memalign_r", + "-Wl,--wrap,_calloc_r", "-Wl,--wrap,exit", "-Wl,--wrap,atexit", + "-Wl,--wrap,tcp_write", + "-Wl,--wrap,mbedtls_hardware_poll", + "-Wl,-n"] + }, + "GCC_ARM_org": { + "common": ["-c", "-Wall", "-Wextra", + "-Wno-unused-parameter", "-Wno-missing-field-initializers", + "-fmessage-length=0", "-fno-exceptions", "-fno-builtin", + "-ffunction-sections", "-fdata-sections", "-funsigned-char", + "-MMD", "-fno-delete-null-pointer-checks", + "-fomit-frame-pointer", "-O0", "-g3", "-DMBED_DEBUG", + "-DMBED_TRAP_ERRORS_ENABLED=1"], + "asm": ["-x", "assembler-with-cpp"], + "c": ["-std=gnu99"], + "cxx": ["-std=gnu++98", "-fno-rtti", "-Wvla"], + "ld": ["-Wl,--gc-sections", "-Wl,--wrap,main", "-Wl,--wrap,_malloc_r", + "-Wl,--wrap,_free_r", "-Wl,--wrap,_realloc_r", "-Wl,--wrap,_memalign_r", + "-Wl,--wrap,_calloc_r", "-Wl,--wrap,exit", "-Wl,--wrap,atexit", + "-Wl,-n"] + }, + "ARMC6": { + "common": ["-c", "--target=arm-arm-none-eabi", "-mthumb", "-g", "-O0", + "-Wno-armcc-pragma-push-pop", "-Wno-armcc-pragma-anon-unions", + "-DMULADDC_CANNOT_USE_R7", "-fdata-sections", + "-fno-exceptions", "-MMD", "-D_LIBCPP_EXTERN_TEMPLATE(...)="], + "asm": [], + "c": ["-D__ASSERT_MSG", "-std=gnu99"], + "cxx": ["-fno-rtti", "-std=gnu++98"], + "ld": ["--verbose", "--remove", "--legacyalign", "--no_strict_wchar_size", + "--no_strict_enum_size", "--show_full_path"] + }, + "ARM": { + "common": ["-c", "--gnu", "-Otime", "--split_sections", + "--apcs=interwork", "--brief_diagnostics", "--restrict", + "--multibyte_chars", "-O0", "-g", "-DMBED_DEBUG", + "-DMBED_TRAP_ERRORS_ENABLED=1"], + "asm": [], + "c": ["--md", "--no_depend_system_headers", "--c99", "-D__ASSERT_MSG"], + "cxx": ["--cpp", "--no_rtti", "--no_vla"], + "ld": ["--show_full_path"] + }, + "uARM": { + "common": ["-c", "--gnu", "-Otime", "--split_sections", + "--apcs=interwork", "--brief_diagnostics", "--restrict", + "--multibyte_chars", "-O0", "-D__MICROLIB", "-g", + "--library_type=microlib", "-DMBED_RTOS_SINGLE_THREAD", "-DMBED_DEBUG", + "-DMBED_TRAP_ERRORS_ENABLED=1"], + "asm": [], + "c": ["--md", "--no_depend_system_headers", "--c99", "-D__ASSERT_MSG"], + "cxx": ["--cpp", "--no_rtti", "--no_vla"], + "ld": ["--library_type=microlib"] + }, + "IAR": { + "common": [ + "--no_wrap_diagnostics", "-e", + "--diag_suppress=Pa050,Pa084,Pa093,Pa082", "-On", "-r", "-DMBED_DEBUG", + "-DMBED_TRAP_ERRORS_ENABLED=1", "--enable_restrict"], + "asm": [], + "c": ["--vla", "--diag_suppress=Pe546"], + "cxx": ["--guard_calls", "--no_static_destruction"], + "ld": ["--skip_dynamic_initialization", "--threaded_lib"] + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/iotjs/src/platform/mbedos5/profiles/release.json Thu Jul 11 18:48:09 2019 +0900 @@ -0,0 +1,73 @@ +{ + "GCC_ARM": { + "common": ["-c", "-Wall", "-Wextra", + "-Wno-unused-parameter", "-Wno-missing-field-initializers", + "-fmessage-length=0", "-fno-exceptions", "-fno-builtin", + "-ffunction-sections", "-fdata-sections", "-funsigned-char", + "-MMD", "-fno-delete-null-pointer-checks", + "-fomit-frame-pointer", "-Os", "-DNDEBUG", "-g1"], + "asm": ["-x", "assembler-with-cpp"], + "c": ["-std=gnu99"], + "cxx": ["-std=gnu++11", "-fno-rtti", "-Wvla"], + "ld": ["-Wl,--gc-sections", "-Wl,--wrap,main", "-Wl,--wrap,_malloc_r", + "-Wl,--wrap,_free_r", "-Wl,--wrap,_realloc_r", "-Wl,--wrap,_memalign_r", + "-Wl,--wrap,_calloc_r", "-Wl,--wrap,exit", "-Wl,--wrap,atexit", + "-Wl,--wrap,tcp_write", + "-Wl,--wrap,mbedtls_hardware_poll", + "-Wl,-n"] + }, + "GCC_ARM_org": { + "common": ["-c", "-Wall", "-Wextra", + "-Wno-unused-parameter", "-Wno-missing-field-initializers", + "-fmessage-length=0", "-fno-exceptions", "-fno-builtin", + "-ffunction-sections", "-fdata-sections", "-funsigned-char", + "-MMD", "-fno-delete-null-pointer-checks", + "-fomit-frame-pointer", "-Os", "-DNDEBUG", "-g1"], + "asm": ["-x", "assembler-with-cpp"], + "c": ["-std=gnu99"], + "cxx": ["-std=gnu++98", "-fno-rtti", "-Wvla"], + "ld": ["-Wl,--gc-sections", "-Wl,--wrap,main", "-Wl,--wrap,_malloc_r", + "-Wl,--wrap,_free_r", "-Wl,--wrap,_realloc_r", "-Wl,--wrap,_memalign_r", + "-Wl,--wrap,_calloc_r", "-Wl,--wrap,exit", "-Wl,--wrap,atexit", + "-Wl,-n"] + }, + "ARMC6": { + "common": ["-c", "--target=arm-arm-none-eabi", "-mthumb", "-Oz", + "-Wno-armcc-pragma-push-pop", "-Wno-armcc-pragma-anon-unions", + "-DMULADDC_CANNOT_USE_R7", "-fdata-sections", + "-fno-exceptions", "-MMD", "-D_LIBCPP_EXTERN_TEMPLATE(...)="], + "asm": [], + "c": ["-D__ASSERT_MSG", "-std=gnu99"], + "cxx": ["-fno-rtti", "-std=gnu++98"], + "ld": ["--legacyalign", "--no_strict_wchar_size", "--no_strict_enum_size", + "--show_full_path"] + }, + "ARM": { + "common": ["-c", "--gnu", "-Ospace", "--split_sections", + "--apcs=interwork", "--brief_diagnostics", "--restrict", + "--multibyte_chars", "-O3", "-DNDEBUG"], + "asm": [], + "c": ["--md", "--no_depend_system_headers", "--c99", "-D__ASSERT_MSG"], + "cxx": ["--cpp", "--no_rtti", "--no_vla"], + "ld": ["--show_full_path"] + }, + "uARM": { + "common": ["-c", "--gnu", "-Ospace", "--split_sections", + "--apcs=interwork", "--brief_diagnostics", "--restrict", + "--multibyte_chars", "-O3", "-D__MICROLIB", + "--library_type=microlib", "-DMBED_RTOS_SINGLE_THREAD", "-DNDEBUG"], + "asm": [], + "c": ["--md", "--no_depend_system_headers", "--c99", "-D__ASSERT_MSG"], + "cxx": ["--cpp", "--no_rtti", "--no_vla"], + "ld": ["--library_type=microlib"] + }, + "IAR": { + "common": [ + "--no_wrap_diagnostics", "-e", + "--diag_suppress=Pa050,Pa084,Pa093,Pa082", "-Ohz", "-DNDEBUG", "--enable_restrict"], + "asm": [], + "c": ["--vla", "--diag_suppress=Pe546"], + "cxx": ["--guard_calls", "--no_static_destruction"], + "ld": ["--skip_dynamic_initialization", "--threaded_lib"] + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/iotjs/src/platform/mbedos5/template.iotjs_def.h.txt Thu Jul 11 18:48:09 2019 +0900 @@ -0,0 +1,10 @@ +// fake iotjs_def.h to replace TARGET_OS macro + +#include "src/iotjs_def.h" + +#undef TARGET_OS + +#define NAME_STRINGIZER_(name) #name +#define NAME_STRINGIZER(name) NAME_STRINGIZER_(name) +#define TARGET_OS NAME_STRINGIZER(PLATFORM_NAME) +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/iotjs/src/platform/mbedos5/template.mbedignore.txt Thu Jul 11 18:48:09 2019 +0900 @@ -0,0 +1,104 @@ + +build/* +cmake/* +config/* +docs/* +profiles/* +samples/* +test/* +tools/* + +deps/http-parser/bench.c +deps/http-parser/test.c +deps/http-parser/contrib/* + +deps/jerry/cmake/* +deps/jerry/docs/* +RESPECT_deps/jerry/jerry-core/* +RESPECT_deps/jerry/jerry-debugger/* +RESPECT_deps/jerry/jerry-ext/* +deps/jerry/jerry-libc/* +deps/jerry/jerry-libm/* +deps/jerry/jerry-main/* +RESPECT_deps/jerry/jerry-port/* +deps/jerry/targets/* +deps/jerry/tests/* +deps/jerry/third-party/* +deps/jerry/tools/* + +deps/libtuv/src/fs-poll.c +deps/libtuv/src/version.c +deps/libtuv/src/unix/aix.c +deps/libtuv/src/unix/android-ifaddrs.c +deps/libtuv/src/unix/darwin-proctitle.c +deps/libtuv/src/unix/darwin.c +deps/libtuv/src/unix/dl.c +deps/libtuv/src/unix/freebsd.c +deps/libtuv/src/unix/fsevents.c +deps/libtuv/src/unix/getnameinfo.c +deps/libtuv/src/unix/kqueue.c +deps/libtuv/src/unix/linux-inotify.c +deps/libtuv/src/unix/netbsd.c +deps/libtuv/src/unix/nuttx.c +deps/libtuv/src/unix/openbsd.c +deps/libtuv/src/unix/os390.c +deps/libtuv/src/unix/pipe.c +deps/libtuv/src/unix/proctitle.c +deps/libtuv/src/unix/pthread-barrier.c +deps/libtuv/src/unix/pthread-fixes.c +deps/libtuv/src/unix/signal.c +deps/libtuv/src/unix/sunos.c +deps/libtuv/src/unix/tizenrt.c +deps/libtuv/src/unix/tty.c +deps/libtuv/src/win/* +deps/libtuv/test/* + +deps/mbedtls/* + +src/modules/iotjs_module_adc.c +src/modules/iotjs_module_blehcisocket.c +src/modules/iotjs_module_bridge.c +RESPECT_src/modules/iotjs_module_buffer.c +RESPECT_src/modules/iotjs_module_console.c +RESPECT_src/modules/iotjs_module_constants.c +RESPECT_src/modules/iotjs_module_dns.c +RESPECT_src/modules/iotjs_module_dynamicloader.c +RESPECT_src/modules/iotjs_module_fs.c +src/modules/iotjs_module_gpio.c +RESPECT_src/modules/iotjs_module_http_parser.c +src/modules/iotjs_module_i2c.c +src/modules/iotjs_module_mqtt.c +src/modules/iotjs_module_periph_common.c +RESPECT_src/modules/iotjs_module_process.c +src/modules/iotjs_module_pwm.c +src/modules/iotjs_module_spi.c +src/modules/iotjs_module_stm32f4dis.c +RESPECT_src/modules/iotjs_module_tcp.c +RESPECT_src/modules/iotjs_module_timer.c +src/modules/iotjs_module_tizen.c +RESPECT_src/modules/iotjs_module_tls.c +src/modules/iotjs_module_uart.c +RESPECT_src/modules/iotjs_module_udp.c +src/modules/iotjs_module_websocket.c + +src/modules/linux/iotjs_module_adc-linux.c +src/modules/linux/iotjs_module_blehcisocket-linux.c +src/modules/linux/iotjs_module_gpio-linux.c +src/modules/linux/iotjs_module_i2c-linux.c +src/modules/linux/iotjs_module_pwm-linux.c +src/modules/linux/iotjs_module_spi-linux.c +src/modules/linux/iotjs_module_uart-linux.c +src/modules/nuttx/* +src/modules/tizen/* +src/modules/tizenrt/* +src/modules/uC3/* + +src/platform/linux/* +RESPECT_src/platform/mbedos5/* +src/platform/nuttx/* +src/platform/tizen/* +src/platform/tizenrt/* +src/platform/uC3/* + +src/platform/mbedos5/mbed-gr-libs/SDBlockDevice_GRBoard/TARGET_RZ_A1XX/sd-driver-master/* +