mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2024-11-26 07:21:54 +00:00
Separate app-manager and app-framework from WAMR (#3129)
As planned, the app-manager and app-framework are to be migrated to https://github.com/bytecodealliance/wamr-app-framework. ps. https://github.com/bytecodealliance/wasm-micro-runtime/issues/2329 https://github.com/bytecodealliance/wasm-micro-runtime/wiki/TSC-meeting-notes
This commit is contained in:
parent
b9db23b983
commit
63cd567b3f
25
.github/workflows/build_wamr_sdk.yml
vendored
25
.github/workflows/build_wamr_sdk.yml
vendored
|
@ -30,6 +30,10 @@ on:
|
|||
description: download WASI_SDK from this URL
|
||||
type: string
|
||||
required: true
|
||||
wamr_app_framework_url:
|
||||
description: download WAMR app framework to get wamr_sdk
|
||||
type: string
|
||||
required: true
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
@ -37,6 +41,14 @@ jobs:
|
|||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: download wamr-app-framework
|
||||
run: |
|
||||
git clone ${{ inputs.wamr_app_framework_url }}
|
||||
cd wamr-app-framework
|
||||
git submodule init
|
||||
git submodule update
|
||||
working-directory: wamr-sdk
|
||||
|
||||
- name: download and install wasi-sdk
|
||||
run: |
|
||||
cd /opt
|
||||
|
@ -48,14 +60,16 @@ jobs:
|
|||
|
||||
- name: generate wamr-sdk release
|
||||
run: |
|
||||
cd ./wamr-app-framework/wamr-sdk
|
||||
./build_sdk.sh -n wamr-sdk -x $(pwd)/${{ inputs.config_file }}
|
||||
working-directory: wamr-sdk
|
||||
|
||||
- name: compress the binary
|
||||
run: |
|
||||
cd wamr-app-framework/wamr-sdk/out
|
||||
tar czf wamr-sdk-${{ inputs.ver_num }}-${{ inputs.runner }}.tar.gz wamr-sdk
|
||||
zip -r wamr-sdk-${{ inputs.ver_num }}-${{ inputs.runner }}.zip wamr-sdk
|
||||
working-directory: wamr-sdk/out
|
||||
working-directory: wamr-sdk
|
||||
|
||||
- name: upload release tar.gz
|
||||
uses: actions/upload-release-asset@v1
|
||||
|
@ -63,7 +77,7 @@ jobs:
|
|||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ inputs.upload_url }}
|
||||
asset_path: wamr-sdk/out/wamr-sdk-${{ inputs.ver_num }}-${{ inputs.runner }}.tar.gz
|
||||
asset_path: wamr-sdk/wamr-app-framework/wamr-sdk/out/wamr-sdk-${{ inputs.ver_num }}-${{ inputs.runner }}.tar.gz
|
||||
asset_name: wamr-sdk-${{ inputs.ver_num }}-${{ inputs.arch }}-${{ inputs.runner }}.tar.gz
|
||||
asset_content_type: application/x-gzip
|
||||
|
||||
|
@ -73,6 +87,11 @@ jobs:
|
|||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ inputs.upload_url }}
|
||||
asset_path: wamr-sdk/out/wamr-sdk-${{ inputs.ver_num }}-${{ inputs.runner }}.zip
|
||||
asset_path: wamr-sdk/wamr-app-framework/wamr-sdk/out/wamr-sdk-${{ inputs.ver_num }}-${{ inputs.runner }}.zip
|
||||
asset_name: wamr-sdk-${{ inputs.ver_num }}-${{ inputs.arch }}-${{ inputs.runner }}.zip
|
||||
asset_content_type: application/zip
|
||||
|
||||
- name: delete wamr-app-framework
|
||||
run: |
|
||||
rm -rf wamr-app-framework
|
||||
working-directory: wamr-sdk
|
||||
|
|
|
@ -20,7 +20,6 @@ on:
|
|||
- "!samples/workload/**"
|
||||
- "tests/wamr-test-suites/**"
|
||||
- "wamr-compiler/**"
|
||||
- "wamr-sdk/**"
|
||||
- "test-tools/wamr-ide/**"
|
||||
# will be triggered on push events
|
||||
push:
|
||||
|
@ -38,7 +37,6 @@ on:
|
|||
- "!samples/workload/**"
|
||||
- "tests/wamr-test-suites/**"
|
||||
- "wamr-compiler/**"
|
||||
- "wamr-sdk/**"
|
||||
- "test-tools/wamr-ide/**"
|
||||
# allow to be triggered manually
|
||||
workflow_dispatch:
|
||||
|
@ -430,13 +428,6 @@ jobs:
|
|||
cmake --build . --config Debug --parallel 4
|
||||
./hello
|
||||
|
||||
- name: Build Sample [simple]
|
||||
run: |
|
||||
./build.sh -p host-interp
|
||||
python3 ./sample_test_run.py $(pwd)/out
|
||||
exit $?
|
||||
working-directory: ./samples/simple
|
||||
|
||||
- name: Build Sample [wasi-threads]
|
||||
run: |
|
||||
cd samples/wasi-threads
|
||||
|
|
2
.github/workflows/compilation_on_macos.yml
vendored
2
.github/workflows/compilation_on_macos.yml
vendored
|
@ -20,7 +20,6 @@ on:
|
|||
- "!samples/workload/**"
|
||||
- "tests/wamr-test-suites/**"
|
||||
- "wamr-compiler/**"
|
||||
- "wamr-sdk/**"
|
||||
# will be triggered on push events
|
||||
push:
|
||||
branches:
|
||||
|
@ -37,7 +36,6 @@ on:
|
|||
- "!samples/workload/**"
|
||||
- "tests/wamr-test-suites/**"
|
||||
- "wamr-compiler/**"
|
||||
- "wamr-sdk/**"
|
||||
# allow to be triggered manually
|
||||
workflow_dispatch:
|
||||
|
||||
|
|
2
.github/workflows/compilation_on_nuttx.yml
vendored
2
.github/workflows/compilation_on_nuttx.yml
vendored
|
@ -19,7 +19,6 @@ on:
|
|||
- "!samples/workload/**"
|
||||
- "tests/wamr-test-suites/**"
|
||||
- "wamr-compiler/**"
|
||||
- "wamr-sdk/**"
|
||||
# will be triggered on push events
|
||||
push:
|
||||
branches:
|
||||
|
@ -35,7 +34,6 @@ on:
|
|||
- "!samples/workload/**"
|
||||
- "tests/wamr-test-suites/**"
|
||||
- "wamr-compiler/**"
|
||||
- "wamr-sdk/**"
|
||||
# allow to be triggered manually
|
||||
workflow_dispatch:
|
||||
|
||||
|
|
2
.github/workflows/compilation_on_sgx.yml
vendored
2
.github/workflows/compilation_on_sgx.yml
vendored
|
@ -20,7 +20,6 @@ on:
|
|||
- "!samples/workload/**"
|
||||
- "tests/wamr-test-suites/**"
|
||||
- "wamr-compiler/**"
|
||||
- "wamr-sdk/**"
|
||||
# will be triggered on push events
|
||||
push:
|
||||
branches:
|
||||
|
@ -37,7 +36,6 @@ on:
|
|||
- "!samples/workload/**"
|
||||
- "tests/wamr-test-suites/**"
|
||||
- "wamr-compiler/**"
|
||||
- "wamr-sdk/**"
|
||||
# allow to be triggered manually
|
||||
workflow_dispatch:
|
||||
|
||||
|
|
2
.github/workflows/compilation_on_windows.yml
vendored
2
.github/workflows/compilation_on_windows.yml
vendored
|
@ -19,7 +19,6 @@ on:
|
|||
- "!samples/workload/**"
|
||||
- "tests/wamr-test-suites/**"
|
||||
- "wamr-compiler/**"
|
||||
- "wamr-sdk/**"
|
||||
# will be triggered on push events
|
||||
push:
|
||||
branches:
|
||||
|
@ -35,7 +34,6 @@ on:
|
|||
- "!samples/workload/**"
|
||||
- "tests/wamr-test-suites/**"
|
||||
- "wamr-compiler/**"
|
||||
- "wamr-sdk/**"
|
||||
# allow to be triggered manually
|
||||
workflow_dispatch:
|
||||
|
||||
|
|
8
.github/workflows/nightly_run.yml
vendored
8
.github/workflows/nightly_run.yml
vendored
|
@ -13,7 +13,7 @@ on:
|
|||
paths:
|
||||
- ".github/workflows/nightly_run.yml"
|
||||
- "core/iwasm/libraries/lib-wasi-threads/stress-test/**"
|
||||
|
||||
|
||||
# midnight UTC
|
||||
schedule:
|
||||
- cron: "0 0 * * *"
|
||||
|
@ -489,12 +489,6 @@ jobs:
|
|||
cmake ..
|
||||
cmake --build . --config Release --parallel 4
|
||||
./hello
|
||||
- name: Build Sample [simple]
|
||||
run: |
|
||||
./build.sh -p host-interp
|
||||
python3 ./sample_test_run.py $(pwd)/out
|
||||
exit $?
|
||||
working-directory: ./samples/simple
|
||||
|
||||
- name: Build Sample [wasi-threads]
|
||||
run: |
|
||||
|
|
3
.github/workflows/release_process.yml
vendored
3
.github/workflows/release_process.yml
vendored
|
@ -147,6 +147,7 @@ jobs:
|
|||
upload_url: ${{ needs.create_release.outputs.upload_url }}
|
||||
ver_num: ${{ needs.create_tag.outputs.new_ver}}
|
||||
wasi_sdk_url: https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-19/wasi-sdk-19.0-linux.tar.gz
|
||||
wamr_app_framework_url: https://github.com/bytecodealliance/wamr-app-framework.git
|
||||
|
||||
release_wamr_sdk_on_ubuntu_2204:
|
||||
needs: [create_tag, create_release]
|
||||
|
@ -157,6 +158,7 @@ jobs:
|
|||
upload_url: ${{ needs.create_release.outputs.upload_url }}
|
||||
ver_num: ${{ needs.create_tag.outputs.new_ver}}
|
||||
wasi_sdk_url: https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-19/wasi-sdk-19.0-linux.tar.gz
|
||||
wamr_app_framework_url: https://github.com/bytecodealliance/wamr-app-framework.git
|
||||
|
||||
release_wamr_sdk_on_macos:
|
||||
needs: [create_tag, create_release]
|
||||
|
@ -167,6 +169,7 @@ jobs:
|
|||
upload_url: ${{ needs.create_release.outputs.upload_url }}
|
||||
ver_num: ${{ needs.create_tag.outputs.new_ver}}
|
||||
wasi_sdk_url: https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-19/wasi-sdk-19.0-macos.tar.gz
|
||||
wamr_app_framework_url: https://github.com/bytecodealliance/wamr-app-framework.git
|
||||
|
||||
#
|
||||
# vscode extension cross-platform
|
||||
|
|
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -14,13 +14,9 @@
|
|||
|
||||
core/deps/**
|
||||
core/shared/mem-alloc/tlsf
|
||||
core/app-framework/wgl
|
||||
core/iwasm/libraries/lib-wasi-threads/test/*.wasm
|
||||
core/iwasm/libraries/lib-socket/test/*.wasm
|
||||
|
||||
wamr-sdk/out/
|
||||
wamr-sdk/runtime/build_runtime_sdk/
|
||||
test-tools/host-tool/bin/
|
||||
product-mini/app-samples/hello-world/test.wasm
|
||||
product-mini/platforms/linux-sgx/enclave-sample/App/
|
||||
product-mini/platforms/linux-sgx/enclave-sample/Enclave/
|
||||
|
|
|
@ -2,10 +2,10 @@ WebAssembly Micro Runtime Attributions
|
|||
======================================
|
||||
|
||||
WAMR project reused some components from other open source project:
|
||||
- **cJson**: used in the host_tool for remotely managing wasm applications
|
||||
- **cJson**: in the repository [wamr-app-framework](https://github.com/bytecodealliance/wamr-app-framework/), used in the host_tool for remotely managing wasm applications
|
||||
- **contiki-ng**: for the coap protocol implementation
|
||||
- **freebsd libm**: used in core/shared/platform/alios/bh_math.c
|
||||
- **LVGL**: for the gui samples and wrapped the wasm graphic layer
|
||||
- **LVGL**: in the repository [wamr-app-framework](https://github.com/bytecodealliance/wamr-app-framework/), for the gui samples and wrapped the wasm graphic layer
|
||||
- **llvm**: for the AOT/JIT compilation
|
||||
- **wasm-c-api**: to implement the C-APIs of wasm. using headers and sameples
|
||||
- **wasmtime**: for the wasi libc implementation
|
||||
|
@ -42,7 +42,7 @@ The WAMR fast interpreter is a clean room development. We would acknowledge the
|
|||
|
||||
### cJson
|
||||
|
||||
[LICENSE](./test-tools/host-tool/external/cJSON/LICENSE)
|
||||
[LICENSE](https://github.com/bytecodealliance/wamr-app-framework/blob/main/test-tools/host-tool/external/cJSON/LICENSE)
|
||||
|
||||
### contiki-ng
|
||||
|
||||
|
@ -54,9 +54,9 @@ The WAMR fast interpreter is a clean room development. We would acknowledge the
|
|||
|
||||
### LVGL
|
||||
|
||||
[LICENSE](./samples/littlevgl/LICENCE.txt)
|
||||
[LICENSE](https://github.com/bytecodealliance/wamr-app-framework/blob/main/samples/littlevgl/LICENCE.txt)
|
||||
|
||||
[LICENSE](./core/app-framework/wgl/app/wa-inc/lvgl/LICENCE.txt)
|
||||
[LICENSE](https://github.com/bytecodealliance/wamr-app-framework/blob/main/app-framework/wgl/app/wa-inc/lvgl/LICENCE.txt)
|
||||
|
||||
### llvm
|
||||
|
||||
|
@ -64,7 +64,7 @@ The WAMR fast interpreter is a clean room development. We would acknowledge the
|
|||
|
||||
### wasm-c-api
|
||||
|
||||
[LICENSE](./samples/wasm-c-api/src/LICENSE)
|
||||
[LICENSE](https://github.com/bytecodealliance/wamr-app-framework/blob/main/samples/wasm-c-api/src/LICENSE)
|
||||
|
||||
### wasmtime
|
||||
|
||||
|
@ -76,7 +76,7 @@ The WAMR fast interpreter is a clean room development. We would acknowledge the
|
|||
|
||||
### zephyr
|
||||
|
||||
[LICENSE](./samples/gui/wasm-runtime-wgl/src/platform/zephyr/LICENSE)
|
||||
[LICENSE](https://github.com/bytecodealliance/wamr-app-framework/blob/main/samples/gui/wasm-runtime-wgl/src/platform/zephyr/LICENSE)
|
||||
|
||||
### wac
|
||||
|
||||
|
|
|
@ -14,8 +14,8 @@ WebAssembly Micro Runtime (WAMR) is a lightweight standalone WebAssembly (Wasm)
|
|||
- [**iwasm**](./product-mini/): The executable binary built with WAMR VMcore supports WASI and command line interface.
|
||||
- [**wamrc**](./wamr-compiler/): The AOT compiler to compile Wasm file into AOT file
|
||||
- Useful components and tools for building real solutions with WAMR vmcore:
|
||||
- [App-framework](./core/app-framework/README.md): A framework for supporting APIs for the Wasm applications
|
||||
- [App-manager](./core/app-mgr/README.md): a framework for dynamical loading the Wasm module remotely
|
||||
- [App-framework](https://github.com/bytecodealliance/wamr-app-framework/blob/main/app-framework/README.md): A framework for supporting APIs for the Wasm applications
|
||||
- [App-manager](https://github.com/bytecodealliance/wamr-app-framework/blob/main/app-mgr/README.md): a framework for dynamical loading the Wasm module remotely
|
||||
- [WAMR-IDE](./test-tools/wamr-ide): An experimental VSCode extension for developping WebAssembly applications with C/C++
|
||||
|
||||
|
||||
|
|
1
assembly-script/.gitignore
vendored
1
assembly-script/.gitignore
vendored
|
@ -1 +0,0 @@
|
|||
/node_modules
|
|
@ -1,124 +0,0 @@
|
|||
# AssemblyScript_on_WAMR
|
||||
This project is based on [Wasm Micro Runtime](https://github.com/bytecodealliance/wasm-micro-runtime) (WAMR) and [AssemblyScript](https://github.com/AssemblyScript/assemblyscript). It implements some of the `wamr app framework` in *assemblyscript*, which allows you to write some applications in *assemblyscript* and dynamically installed on *WAMR Runtime*
|
||||
|
||||
## Building
|
||||
To build the samples in this repo, you need `npm` on your system
|
||||
``` bash
|
||||
sudo apt install npm
|
||||
```
|
||||
|
||||
Then install all the dependencies under the repo's root dir
|
||||
``` bash
|
||||
cd $repo_root
|
||||
npm install
|
||||
```
|
||||
|
||||
Use the command to build all samples:
|
||||
``` bash
|
||||
npm run build:all
|
||||
```
|
||||
or you can build every sample individually:
|
||||
``` bash
|
||||
npm run build:timer
|
||||
npm run build:publisher
|
||||
npm run build:subscriber
|
||||
# ...
|
||||
```
|
||||
You will get the compiled wasm file under `build` folder
|
||||
|
||||
Please refer to [package.json](./package.json) for more commands.
|
||||
|
||||
## Run
|
||||
These applications require WAMR's application framework, you need to build WAMR first.
|
||||
|
||||
``` bash
|
||||
cd ${WAMR_ROOT}/samples/simple
|
||||
./build.sh
|
||||
```
|
||||
|
||||
You will get two executable files under `out` folder:
|
||||
|
||||
`simple`: The wamr runtime with application framework
|
||||
|
||||
`host_tool`: The tool used to dynamically install/uninstall applications
|
||||
|
||||
1. Start the runtime:
|
||||
``` bash
|
||||
./simple -s
|
||||
```
|
||||
|
||||
2. Install the compiled wasm file using `host_tool`:
|
||||
``` bash
|
||||
./host_tool -i app_name -f your_compiled_wasm_file.wasm
|
||||
```
|
||||
You can also use the WAMR's AoT compiler `wamrc` to compile the wasm bytecode into native code before you run them. Please refer to this [guide](../README.md#build-wamrc-aot-compiler) to build and install `WAMR AoT compiler`.
|
||||
|
||||
After installing `wamrc`, you can compile the wasm file using command:
|
||||
``` bash
|
||||
wamrc -o file_name.aot file_name.wasm
|
||||
```
|
||||
and you can install the AoT file to the runtime:
|
||||
``` bash
|
||||
./host_tool -i app_name -f your_compiled_aot_file.aot
|
||||
```
|
||||
|
||||
## Development
|
||||
You can develop your own application based on the `wamr_app_lib` APIs.
|
||||
|
||||
### Console APIs
|
||||
``` typescript
|
||||
function log(a: string): void;
|
||||
function log_number(a: number): void;
|
||||
```
|
||||
|
||||
### Timer APIs
|
||||
``` typescript
|
||||
function setTimeout(cb: () => void, timeout: i32): user_timer;
|
||||
function setInterval(cb: () => void, timeout: i32): user_timer;
|
||||
function timer_cancel(timer: user_timer): void;
|
||||
function timer_restart(timer: user_timer, interval: number): void;
|
||||
function now(): i32;
|
||||
|
||||
// export to runtime
|
||||
function on_timer_callback(on_timer_id: i32): void;
|
||||
```
|
||||
|
||||
### Request APIs
|
||||
``` typescript
|
||||
// register handler
|
||||
function register_resource_handler(url: string,
|
||||
request_handle: request_handler_f): void;
|
||||
// request
|
||||
function post(url: string, payload: ArrayBuffer, payload_len: number,
|
||||
tag: string, cb: (resp: wamr_response) => void): void;
|
||||
function get(url: string, tag: string,
|
||||
cb: (resp: wamr_response) => void): void;
|
||||
function put(url: string, payload: ArrayBuffer, payload_len: number, tag: string,
|
||||
cb: (resp: wamr_response) => void): void;
|
||||
function del(url: string, tag: string,
|
||||
cb: (resp: wamr_response) => void): void;
|
||||
|
||||
// response
|
||||
function make_response_for_request(req: wamr_request): wamr_response;
|
||||
function api_response_send(resp: wamr_response): void;
|
||||
|
||||
// event
|
||||
function publish_event(url: string, fmt: number,
|
||||
payload: ArrayBuffer, payload_len: number): void;
|
||||
function subscribe_event(url: string, cb: request_handler_f): void;
|
||||
|
||||
// export to runtime
|
||||
function on_request(buffer_offset: i32, size: i32): void;
|
||||
function on_response(buffer_offset : i32, size: i32): void;
|
||||
```
|
||||
|
||||
You should export the `on_timer_callback`, `on_request` and `on_response` in your application entry file, refer to the samples for example.
|
||||
|
||||
To build your application, you can use `asc`:
|
||||
``` bash
|
||||
asc app.ts -b build/app.wasm -t build/app.wat --sourceMap --validate --optimize
|
||||
```
|
||||
or you can add a command into [package.json](./package.json):
|
||||
``` json
|
||||
"build:app": "asc app.ts -b build/app.wasm -t build/app.wat --sourceMap --validate --optimize",
|
||||
```
|
30
assembly-script/package-lock.json
generated
30
assembly-script/package-lock.json
generated
|
@ -1,30 +0,0 @@
|
|||
{
|
||||
"name": "assembly_script",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"assemblyscript": {
|
||||
"version": "0.17.4",
|
||||
"resolved": "https://registry.npm.taobao.org/assemblyscript/download/assemblyscript-0.17.4.tgz",
|
||||
"integrity": "sha1-1GEduJpClDNa1H7DxmYaJqRCh3E=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"binaryen": "98.0.0-nightly.20201109",
|
||||
"long": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"binaryen": {
|
||||
"version": "98.0.0-nightly.20201109",
|
||||
"resolved": "https://registry.npm.taobao.org/binaryen/download/binaryen-98.0.0-nightly.20201109.tgz",
|
||||
"integrity": "sha1-USv2yhXGe/dAIURzSkg25jmTqgU=",
|
||||
"dev": true
|
||||
},
|
||||
"long": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npm.taobao.org/long/download/long-4.0.0.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Flong%2Fdownload%2Flong-4.0.0.tgz",
|
||||
"integrity": "sha1-mntxz7fTYaGU6lVSQckvdGjVvyg=",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
{
|
||||
"name": "assembly_script",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"build:request_handler": "asc samples/request_handler.ts -b build/request_handler.wasm -t build/request_handler.wat --sourceMap --optimize --exportRuntime --use abort=",
|
||||
"build:request_sender": "asc samples/request_sender.ts -b build/request_sender.wasm -t build/request_sender.wat --sourceMap --optimize --exportRuntime --use abort=",
|
||||
"build:timer": "asc samples/timer.ts -b build/timer.wasm -t build/timer.wat --sourceMap --optimize --exportRuntime --use abort=",
|
||||
"build:publisher": "asc samples/event_publisher.ts -b build/event_publisher.wasm -t build/event_publisher.wat --sourceMap --optimize --exportRuntime --use abort=",
|
||||
"build:subscriber": "asc samples/event_subscriber.ts -b build/event_subscriber.wasm -t build/event_subscriber.wat --sourceMap --optimize --exportRuntime --use abort=",
|
||||
"build:all": "npm run build:request_handler; npm run build:request_sender; npm run build:timer; npm run build:subscriber; npm run build:publisher"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"devDependencies": {
|
||||
"assemblyscript": "^0.18.15"
|
||||
}
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
// The entry file of your WebAssembly module.
|
||||
import * as console from "../wamr_app_lib/console"
|
||||
import * as timer from "../wamr_app_lib/timer"
|
||||
import * as request from "../wamr_app_lib/request"
|
||||
|
||||
function publish_overheat_event(): void {
|
||||
var payload = String.UTF8.encode("warning: temperature is over high");
|
||||
request.publish_event("alert/overheat", 0, payload, payload.byteLength);
|
||||
}
|
||||
|
||||
export function on_init() : void {
|
||||
timer.setInterval(publish_overheat_event, 2000);
|
||||
}
|
||||
|
||||
export function on_destroy() : void {
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Function below are requred by wamr runtime, don't remove or modify them */
|
||||
export function _on_timer_callback(on_timer_id: i32): void {
|
||||
timer.on_timer_callback(on_timer_id);
|
||||
}
|
||||
|
||||
export function _on_request(buffer_offset: i32, size: i32): void {
|
||||
request.on_request(buffer_offset, size);
|
||||
}
|
||||
|
||||
export function _on_response(buffer_offset : i32, size: i32): void {
|
||||
request.on_response(buffer_offset, size);
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
// The entry file of your WebAssembly module.
|
||||
import * as console from "../wamr_app_lib/console"
|
||||
import * as timer from "../wamr_app_lib/timer"
|
||||
import * as request from "../wamr_app_lib/request"
|
||||
|
||||
export function on_init() : void {
|
||||
request.subscribe_event("alert/overheat", (req) => {
|
||||
console.log("### user over heat event handler called:");
|
||||
|
||||
console.log("");
|
||||
console.log(" " + String.UTF8.decode(req.payload) + "\n");
|
||||
})
|
||||
}
|
||||
|
||||
export function on_destroy() : void {
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Function below are requred by wamr runtime, don't remove or modify them */
|
||||
export function _on_timer_callback(on_timer_id: i32): void {
|
||||
timer.on_timer_callback(on_timer_id);
|
||||
}
|
||||
|
||||
export function _on_request(buffer_offset: i32, size: i32): void {
|
||||
request.on_request(buffer_offset, size);
|
||||
}
|
||||
|
||||
export function _on_response(buffer_offset : i32, size: i32): void {
|
||||
request.on_response(buffer_offset, size);
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
// The entry file of your WebAssembly module.
|
||||
import * as console from "../wamr_app_lib/console"
|
||||
import * as timer from "../wamr_app_lib/timer"
|
||||
import * as request from "../wamr_app_lib/request"
|
||||
|
||||
export function on_init() : void {
|
||||
request.register_resource_handler("/test", (req) => {
|
||||
console.log("### Req: /test " + String.UTF8.decode(req.payload));
|
||||
|
||||
console.log(" request payload:");
|
||||
console.log(" " + String.UTF8.decode(req.payload) + "\n");
|
||||
|
||||
var resp = request.make_response_for_request(req);
|
||||
resp.set_payload(String.UTF8.encode("Ok"), 2);
|
||||
request.api_response_send(resp);
|
||||
});
|
||||
}
|
||||
|
||||
export function on_destroy() : void {
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Function below are requred by wamr runtime, don't remove or modify them */
|
||||
export function _on_timer_callback(on_timer_id: i32): void {
|
||||
timer.on_timer_callback(on_timer_id);
|
||||
}
|
||||
|
||||
export function _on_request(buffer_offset: i32, size: i32): void {
|
||||
request.on_request(buffer_offset, size);
|
||||
}
|
||||
|
||||
export function _on_response(buffer_offset : i32, size: i32): void {
|
||||
request.on_response(buffer_offset, size);
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
// The entry file of your WebAssembly module.
|
||||
import * as console from "../wamr_app_lib/console"
|
||||
import * as timer from "../wamr_app_lib/timer"
|
||||
import * as request from "../wamr_app_lib/request"
|
||||
|
||||
export function on_init() : void {
|
||||
var payload = String.UTF8.encode("test message");
|
||||
request.post("/test", payload, payload.byteLength, "", (resp) => {
|
||||
if (resp != null) {
|
||||
console.log("Post Success");
|
||||
|
||||
if (resp.payload != null) {
|
||||
console.log(" response payload:")
|
||||
console.log(" " + String.UTF8.decode(resp.payload!) + "\n");
|
||||
}
|
||||
}
|
||||
else
|
||||
console.log("Post Timeout");
|
||||
});
|
||||
}
|
||||
|
||||
export function on_destroy() : void {
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* Function below are requred by wamr runtime, don't remove or modify them */
|
||||
export function _on_timer_callback(on_timer_id: i32): void {
|
||||
timer.on_timer_callback(on_timer_id);
|
||||
}
|
||||
|
||||
export function _on_request(buffer_offset: i32, size: i32): void {
|
||||
request.on_request(buffer_offset, size);
|
||||
}
|
||||
|
||||
export function _on_response(buffer_offset : i32, size: i32): void {
|
||||
request.on_response(buffer_offset, size);
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
// The entry file of your WebAssembly module.
|
||||
import * as console from '../wamr_app_lib/console'
|
||||
import * as timer from '../wamr_app_lib/timer'
|
||||
|
||||
/* clousure is not implemented yet, we need to declare global variables
|
||||
so that they can be accessed inside a callback function */
|
||||
var cnt = 0;
|
||||
var my_timer: timer.user_timer;
|
||||
|
||||
export function on_init(): void {
|
||||
/* The callback function will be called every 2 second,
|
||||
and will stop after 10 calls */
|
||||
my_timer = timer.setInterval(() => {
|
||||
cnt ++;
|
||||
console.log((cnt * 2).toString() + " seconds passed");
|
||||
|
||||
if (cnt >= 10) {
|
||||
timer.timer_cancel(my_timer);
|
||||
console.log("Stop Timer");
|
||||
}
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
export function on_destroy(): void {
|
||||
|
||||
}
|
||||
|
||||
/* Function below are requred by wamr runtime, don't remove or modify them */
|
||||
export function _on_timer_callback(on_timer_id: i32): void {
|
||||
timer.on_timer_callback(on_timer_id);
|
||||
}
|
|
@ -1,6 +0,0 @@
|
|||
{
|
||||
"extends": "../node_modules/assemblyscript/std/assembly.json",
|
||||
"include": [
|
||||
"./**/*.ts"
|
||||
]
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
@external("env", "puts")
|
||||
declare function printf(a: ArrayBuffer): i32;
|
||||
|
||||
export function log(a: string): void {
|
||||
printf(String.UTF8.encode(a, true));
|
||||
}
|
||||
|
||||
export function log_number(a: number): void {
|
||||
printf(String.UTF8.encode(a.toString()));
|
||||
}
|
|
@ -1,495 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
import * as console from './console'
|
||||
import * as timer from './timer'
|
||||
|
||||
@external("env", "wasm_response_send")
|
||||
declare function wasm_response_send(buffer: ArrayBuffer, size: i32): bool;
|
||||
|
||||
@external("env", "wasm_register_resource")
|
||||
declare function wasm_register_resource(url: ArrayBuffer): void;
|
||||
|
||||
@external("env", "wasm_post_request")
|
||||
declare function wasm_post_request(buffer: ArrayBuffer, size: i32): void;
|
||||
|
||||
@external("env", "wasm_sub_event")
|
||||
declare function wasm_sub_event(url: ArrayBuffer): void;
|
||||
|
||||
var COAP_GET = 1;
|
||||
var COAP_POST = 2;
|
||||
var COAP_PUT = 3;
|
||||
var COAP_DELETE = 4;
|
||||
var COAP_EVENT = COAP_DELETE + 2;
|
||||
|
||||
/* CoAP response codes */
|
||||
export enum CoAP_Status {
|
||||
NO_ERROR = 0,
|
||||
|
||||
CREATED_2_01 = 65, /* CREATED */
|
||||
DELETED_2_02 = 66, /* DELETED */
|
||||
VALID_2_03 = 67, /* NOT_MODIFIED */
|
||||
CHANGED_2_04 = 68, /* CHANGED */
|
||||
CONTENT_2_05 = 69, /* OK */
|
||||
CONTINUE_2_31 = 95, /* CONTINUE */
|
||||
|
||||
BAD_REQUEST_4_00 = 128, /* BAD_REQUEST */
|
||||
UNAUTHORIZED_4_01 = 129, /* UNAUTHORIZED */
|
||||
BAD_OPTION_4_02 = 130, /* BAD_OPTION */
|
||||
FORBIDDEN_4_03 = 131, /* FORBIDDEN */
|
||||
NOT_FOUND_4_04 = 132, /* NOT_FOUND */
|
||||
METHOD_NOT_ALLOWED_4_05 = 133, /* METHOD_NOT_ALLOWED */
|
||||
NOT_ACCEPTABLE_4_06 = 134, /* NOT_ACCEPTABLE */
|
||||
PRECONDITION_FAILED_4_12 = 140, /* BAD_REQUEST */
|
||||
REQUEST_ENTITY_TOO_LARGE_4_13 = 141, /* REQUEST_ENTITY_TOO_LARGE */
|
||||
UNSUPPORTED_MEDIA_TYPE_4_15 = 143, /* UNSUPPORTED_MEDIA_TYPE */
|
||||
|
||||
INTERNAL_SERVER_ERROR_5_00 = 160, /* INTERNAL_SERVER_ERROR */
|
||||
NOT_IMPLEMENTED_5_01 = 161, /* NOT_IMPLEMENTED */
|
||||
BAD_GATEWAY_5_02 = 162, /* BAD_GATEWAY */
|
||||
SERVICE_UNAVAILABLE_5_03 = 163, /* SERVICE_UNAVAILABLE */
|
||||
GATEWAY_TIMEOUT_5_04 = 164, /* GATEWAY_TIMEOUT */
|
||||
PROXYING_NOT_SUPPORTED_5_05 = 165, /* PROXYING_NOT_SUPPORTED */
|
||||
|
||||
/* Erbium errors */
|
||||
MEMORY_ALLOCATION_ERROR = 192, PACKET_SERIALIZATION_ERROR,
|
||||
|
||||
/* Erbium hooks */
|
||||
MANUAL_RESPONSE, PING_RESPONSE
|
||||
};
|
||||
|
||||
var g_mid: i32 = 0;
|
||||
class wamr_request {
|
||||
mid: i32 = 0;
|
||||
url: string = "";
|
||||
action: i32 = 0;
|
||||
fmt: i32 = 0;
|
||||
payload: ArrayBuffer;
|
||||
payload_len: i32 = 0;
|
||||
|
||||
sender: i32 = 0;
|
||||
|
||||
constructor(mid: i32, url: string, action: i32, fmt: i32,
|
||||
payload: ArrayBuffer, payload_len: number) {
|
||||
this.mid = mid;
|
||||
this.url = url;
|
||||
this.action = action;
|
||||
this.fmt = fmt;
|
||||
this.payload = payload;
|
||||
this.payload_len = i32(payload_len);
|
||||
}
|
||||
}
|
||||
|
||||
class wamr_response {
|
||||
mid: i32 = 0;
|
||||
status: i32 = 0;
|
||||
fmt: i32 = 0;
|
||||
payload: ArrayBuffer | null;
|
||||
payload_len: i32 = 0;
|
||||
|
||||
receiver: i32 = 0;
|
||||
|
||||
constructor(mid: i32, status: i32, fmt: i32,
|
||||
payload: ArrayBuffer | null, payload_len: i32) {
|
||||
this.mid = mid;
|
||||
this.status = status;
|
||||
this.fmt = fmt;
|
||||
this.payload = payload;
|
||||
this.payload_len = payload_len;
|
||||
}
|
||||
|
||||
set_status(status: number): void {
|
||||
this.status = i32(status);
|
||||
}
|
||||
|
||||
set_payload(payload: ArrayBuffer, payload_len: number): void {
|
||||
this.payload = payload;
|
||||
this.payload_len = i32(payload_len);
|
||||
}
|
||||
}
|
||||
|
||||
class wamr_resource {
|
||||
url: string;
|
||||
type: number;
|
||||
cb: request_handler_f;
|
||||
|
||||
constructor(url: string, type: number, cb: request_handler_f) {
|
||||
this.url = url;
|
||||
this.type = type;
|
||||
this.cb = cb;
|
||||
}
|
||||
}
|
||||
|
||||
function is_expire(trans: wamr_transaction, index: i32, array: Array<wamr_transaction>): bool {
|
||||
var now = timer.now();
|
||||
|
||||
var elapsed_ms = (now < trans.time) ?
|
||||
(now + (0xFFFFFFFF - trans.time) + 1) : (now - trans.time);
|
||||
|
||||
return elapsed_ms >= TRANSACTION_TIMEOUT_MS;
|
||||
}
|
||||
|
||||
function not_expire(trans: wamr_transaction, index: i32, array: Array<wamr_transaction>): bool {
|
||||
var now = timer.now();
|
||||
|
||||
var elapsed_ms = (now < trans.time) ?
|
||||
(now + (0xFFFFFFFF - trans.time) + 1) : (now - trans.time);
|
||||
|
||||
return elapsed_ms < TRANSACTION_TIMEOUT_MS;
|
||||
}
|
||||
|
||||
function transaction_timeout_handler(): void {
|
||||
var now = timer.now();
|
||||
|
||||
var expired = transaction_list.filter(is_expire);
|
||||
transaction_list = transaction_list.filter(not_expire);
|
||||
|
||||
expired.forEach(item => {
|
||||
item.cb(null);
|
||||
transaction_remove(item);
|
||||
})
|
||||
|
||||
if (transaction_list.length > 0) {
|
||||
var elpased_ms: number, ms_to_expiry: number;
|
||||
now = timer.now();
|
||||
if (now < transaction_list[0].time) {
|
||||
elpased_ms = now + (0xFFFFFFFF - transaction_list[0].time) + 1;
|
||||
} else {
|
||||
elpased_ms = now - transaction_list[0].time;
|
||||
}
|
||||
ms_to_expiry = TRANSACTION_TIMEOUT_MS - elpased_ms;
|
||||
timer.timer_restart(g_trans_timer, ms_to_expiry);
|
||||
} else {
|
||||
timer.timer_cancel(g_trans_timer);
|
||||
}
|
||||
}
|
||||
|
||||
function transaction_find(mid: number): wamr_transaction | null {
|
||||
for (let i = 0; i < transaction_list.length; i++) {
|
||||
if (transaction_list[i].mid == mid)
|
||||
return transaction_list[i];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function transaction_add(trans: wamr_transaction): void {
|
||||
transaction_list.push(trans);
|
||||
|
||||
if (transaction_list.length == 1) {
|
||||
g_trans_timer = timer.setTimeout(
|
||||
transaction_timeout_handler,
|
||||
TRANSACTION_TIMEOUT_MS
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function transaction_remove(trans: wamr_transaction): void {
|
||||
var index = transaction_list.indexOf(trans);
|
||||
transaction_list.splice(index, 1);
|
||||
}
|
||||
|
||||
var transaction_list = new Array<wamr_transaction>();
|
||||
class wamr_transaction {
|
||||
mid: number;
|
||||
time: number;
|
||||
cb: (resp: wamr_response | null) => void;
|
||||
|
||||
constructor(mid: number, time: number, cb: (resp: wamr_response) => void) {
|
||||
this.mid = mid;
|
||||
this.time = time;
|
||||
this.cb = cb;
|
||||
}
|
||||
}
|
||||
|
||||
var REQUEST_PACKET_FIX_PART_LEN = 18;
|
||||
var RESPONSE_PACKET_FIX_PART_LEN = 16;
|
||||
var TRANSACTION_TIMEOUT_MS = 5000;
|
||||
var g_trans_timer: timer.user_timer;
|
||||
|
||||
var Reg_Event = 0;
|
||||
var Reg_Request = 1;
|
||||
|
||||
function pack_request(req: wamr_request): DataView {
|
||||
var url_len = req.url.length + 1;
|
||||
var len = REQUEST_PACKET_FIX_PART_LEN + url_len + req.payload_len
|
||||
var buf = new ArrayBuffer(len);
|
||||
|
||||
var dataview = new DataView(buf, 0, len);
|
||||
|
||||
dataview.setUint8(0, 1);
|
||||
dataview.setUint8(1, u8(req.action));
|
||||
dataview.setUint16(2, u16(req.fmt));
|
||||
dataview.setUint32(4, req.mid);
|
||||
dataview.setUint32(8, req.sender);
|
||||
dataview.setUint16(12, u16(url_len))
|
||||
dataview.setUint32(14, req.payload_len);
|
||||
|
||||
var i = 0;
|
||||
for (i = 0; i < url_len - 1; i++) {
|
||||
dataview.setUint8(i + 18, u8(req.url.codePointAt(i)));
|
||||
}
|
||||
dataview.setUint8(i + 18, 0);
|
||||
|
||||
var payload_view = new DataView(req.payload);
|
||||
for (i = 0; i < req.payload_len; i++) {
|
||||
dataview.setUint8(i + 18 + url_len, u8(payload_view.getUint8(i)));
|
||||
}
|
||||
|
||||
return dataview;
|
||||
}
|
||||
|
||||
function unpack_request(packet: ArrayBuffer, size: i32): wamr_request {
|
||||
var dataview = new DataView(packet, 0, size);
|
||||
|
||||
if (dataview.getUint8(0) != 1)
|
||||
throw new Error("packet version mismatch");
|
||||
|
||||
if (size < REQUEST_PACKET_FIX_PART_LEN)
|
||||
throw new Error("packet size error");
|
||||
|
||||
var url_len = dataview.getUint16(12);
|
||||
var payload_len = dataview.getUint32(14);
|
||||
|
||||
if (size != (REQUEST_PACKET_FIX_PART_LEN + url_len + payload_len))
|
||||
throw new Error("packet size error");
|
||||
|
||||
var action = dataview.getUint8(1);
|
||||
var fmt = dataview.getUint16(2);
|
||||
var mid = dataview.getUint32(4);
|
||||
var sender = dataview.getUint32(8);
|
||||
|
||||
var url = packet.slice(REQUEST_PACKET_FIX_PART_LEN, REQUEST_PACKET_FIX_PART_LEN + url_len - 1);
|
||||
var payload = packet.slice(REQUEST_PACKET_FIX_PART_LEN + url_len, REQUEST_PACKET_FIX_PART_LEN + url_len + payload_len);
|
||||
|
||||
var req = new wamr_request(mid, String.UTF8.decode(url), action, fmt, payload, payload_len);
|
||||
req.sender = sender;
|
||||
|
||||
return req;
|
||||
}
|
||||
|
||||
function pack_response(resp: wamr_response): DataView {
|
||||
var len = RESPONSE_PACKET_FIX_PART_LEN + resp.payload_len
|
||||
var buf = new ArrayBuffer(len);
|
||||
|
||||
var dataview = new DataView(buf, 0, len);
|
||||
|
||||
dataview.setUint8(0, 1);
|
||||
dataview.setUint8(1, u8(resp.status));
|
||||
dataview.setUint16(2, u16(resp.fmt));
|
||||
dataview.setUint32(4, resp.mid);
|
||||
dataview.setUint32(8, resp.receiver);
|
||||
dataview.setUint32(12, resp.payload_len)
|
||||
|
||||
if (resp.payload != null) {
|
||||
var payload_view = new DataView(resp.payload!);
|
||||
for (let i = 0; i < resp.payload_len; i++) {
|
||||
dataview.setUint8(i + 16, payload_view.getUint8(i));
|
||||
}
|
||||
}
|
||||
|
||||
return dataview;
|
||||
}
|
||||
|
||||
function unpack_response(packet: ArrayBuffer, size: i32): wamr_response {
|
||||
var dataview = new DataView(packet, 0, size);
|
||||
|
||||
if (dataview.getUint8(0) != 1)
|
||||
throw new Error("packet version mismatch");
|
||||
|
||||
if (size < RESPONSE_PACKET_FIX_PART_LEN)
|
||||
throw new Error("packet size error");
|
||||
|
||||
var payload_len = dataview.getUint32(12);
|
||||
if (size != RESPONSE_PACKET_FIX_PART_LEN + payload_len)
|
||||
throw new Error("packet size error");
|
||||
|
||||
var status = dataview.getUint8(1);
|
||||
var fmt = dataview.getUint16(2);
|
||||
var mid = dataview.getUint32(4);
|
||||
var receiver = dataview.getUint32(8);
|
||||
|
||||
var payload = packet.slice(RESPONSE_PACKET_FIX_PART_LEN);
|
||||
|
||||
var resp = new wamr_response(mid, status, fmt, payload, payload_len);
|
||||
resp.receiver = receiver;
|
||||
|
||||
return resp;
|
||||
}
|
||||
|
||||
function do_request(req: wamr_request, cb: (resp: wamr_response) => void): void {
|
||||
var trans = new wamr_transaction(req.mid, timer.now(), cb);
|
||||
var msg = pack_request(req);
|
||||
|
||||
transaction_add(trans);
|
||||
|
||||
wasm_post_request(msg.buffer, msg.byteLength);
|
||||
}
|
||||
|
||||
function do_response(resp: wamr_response): void {
|
||||
var msg = pack_response(resp);
|
||||
|
||||
wasm_response_send(msg.buffer, msg.byteLength);
|
||||
}
|
||||
|
||||
var resource_list = new Array<wamr_resource>();
|
||||
type request_handler_f = (req: wamr_request) => void;
|
||||
|
||||
function registe_url_handler(url: string, cb: request_handler_f, type: number): void {
|
||||
for (let i = 0; i < resource_list.length; i++) {
|
||||
if (resource_list[i].type == type && resource_list[i].url == url) {
|
||||
resource_list[i].cb = cb;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
var res = new wamr_resource(url, type, cb);
|
||||
resource_list.push(res);
|
||||
|
||||
if (type == Reg_Request)
|
||||
wasm_register_resource(String.UTF8.encode(url));
|
||||
else
|
||||
wasm_sub_event(String.UTF8.encode(url));
|
||||
}
|
||||
|
||||
function is_event_type(req: wamr_request): bool {
|
||||
return req.action == COAP_EVENT;
|
||||
}
|
||||
|
||||
function check_url_start(url: string, leading_str: string): bool {
|
||||
return url.split('/')[0] == leading_str.split('/')[0];
|
||||
}
|
||||
|
||||
/* User APIs below */
|
||||
export function post(url: string, payload: ArrayBuffer, payload_len: number, tag: string,
|
||||
cb: (resp: wamr_response) => void): void {
|
||||
var req = new wamr_request(g_mid++, url, COAP_POST, 0, payload, payload_len);
|
||||
|
||||
do_request(req, cb);
|
||||
}
|
||||
|
||||
export function get(url: string, tag: string,
|
||||
cb: (resp: wamr_response) => void): void {
|
||||
var req = new wamr_request(g_mid++, url, COAP_GET, 0, new ArrayBuffer(0), 0);
|
||||
|
||||
do_request(req, cb);
|
||||
}
|
||||
|
||||
export function put(url: string, payload: ArrayBuffer, payload_len: number, tag: string,
|
||||
cb: (resp: wamr_response) => void): void {
|
||||
var req = new wamr_request(g_mid++, url, COAP_PUT, 0, payload, payload_len);
|
||||
|
||||
do_request(req, cb);
|
||||
}
|
||||
|
||||
export function del(url: string, tag: string,
|
||||
cb: (resp: wamr_response) => void): void {
|
||||
var req = new wamr_request(g_mid++, url, COAP_DELETE, 0, new ArrayBuffer(0), 0);
|
||||
|
||||
do_request(req, cb);
|
||||
}
|
||||
|
||||
export function make_response_for_request(req: wamr_request): wamr_response {
|
||||
var resp = new wamr_response(req.mid, CoAP_Status.CONTENT_2_05, 0, null, 0);
|
||||
resp.receiver = req.sender;
|
||||
|
||||
return resp;
|
||||
}
|
||||
|
||||
export function api_response_send(resp: wamr_response): void {
|
||||
do_response(resp);
|
||||
}
|
||||
|
||||
export function register_resource_handler(url: string,
|
||||
request_handle: request_handler_f): void {
|
||||
registe_url_handler(url, request_handle, Reg_Request);
|
||||
}
|
||||
|
||||
export function publish_event(url: string, fmt: number,
|
||||
payload: ArrayBuffer, payload_len: number): void {
|
||||
var req = new wamr_request(g_mid++, url, COAP_EVENT, i32(fmt), payload, payload_len);
|
||||
|
||||
var msg = pack_request(req);
|
||||
|
||||
wasm_post_request(msg.buffer, msg.byteLength);
|
||||
}
|
||||
|
||||
export function subscribe_event(url: string, cb: request_handler_f): void {
|
||||
registe_url_handler(url, cb, Reg_Event);
|
||||
}
|
||||
|
||||
|
||||
/* These two APIs are required by wamr runtime,
|
||||
use a wrapper to export them in the entry file
|
||||
|
||||
e.g:
|
||||
|
||||
import * as request from '.wamr_app_lib/request'
|
||||
|
||||
// Your code here ...
|
||||
|
||||
export function _on_request(buffer_offset: i32, size: i32): void {
|
||||
on_request(buffer_offset, size);
|
||||
}
|
||||
|
||||
export function _on_response(buffer_offset: i32, size: i32): void {
|
||||
on_response(buffer_offset, size);
|
||||
}
|
||||
*/
|
||||
export function on_request(buffer_offset: i32, size: i32): void {
|
||||
var buffer = new ArrayBuffer(size);
|
||||
var dataview = new DataView(buffer);
|
||||
|
||||
for (let i = 0; i < size; i++) {
|
||||
dataview.setUint8(i, load<i8>(buffer_offset + i, 0, 1));
|
||||
}
|
||||
|
||||
var req = unpack_request(buffer, size);
|
||||
|
||||
var is_event = is_event_type(req);
|
||||
|
||||
for (let i = 0; i < resource_list.length; i++) {
|
||||
if ((is_event && resource_list[i].type == Reg_Event)
|
||||
|| (!is_event && resource_list[i].type == Reg_Request)) {
|
||||
if (check_url_start(req.url, resource_list[i].url)) {
|
||||
resource_list[i].cb(req);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
console.log("on_request: exit. no service handler.");
|
||||
}
|
||||
|
||||
export function on_response(buffer_offset: i32, size: i32): void {
|
||||
var buffer = new ArrayBuffer(size);
|
||||
var dataview = new DataView(buffer);
|
||||
|
||||
for (let i = 0; i < size; i++) {
|
||||
dataview.setUint8(i, load<i8>(buffer_offset + i, 0, 1));
|
||||
}
|
||||
|
||||
var resp = unpack_response(buffer, size);
|
||||
var trans = transaction_find(resp.mid);
|
||||
|
||||
if (trans != null) {
|
||||
if (transaction_list.indexOf(trans) == 0) {
|
||||
if (transaction_list.length >= 2) {
|
||||
var elpased_ms: number, ms_to_expiry: number;
|
||||
var now = timer.now();
|
||||
if (now < transaction_list[1].time) {
|
||||
elpased_ms = now + (0xFFFFFFFF - transaction_list[1].time) + 1;
|
||||
} else {
|
||||
elpased_ms = now - transaction_list[1].time;
|
||||
}
|
||||
ms_to_expiry = TRANSACTION_TIMEOUT_MS - elpased_ms;
|
||||
timer.timer_restart(g_trans_timer, ms_to_expiry);
|
||||
} else {
|
||||
timer.timer_cancel(g_trans_timer);
|
||||
}
|
||||
}
|
||||
|
||||
trans.cb(resp);
|
||||
}
|
||||
}
|
|
@ -1,80 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
@external("env", "wasm_create_timer")
|
||||
declare function wasm_create_timer(a: i32, b: bool, c: bool): i32;
|
||||
|
||||
@external("env", "wasm_timer_cancel")
|
||||
declare function wasm_timer_cancel(a: i32): void;
|
||||
|
||||
@external("env", "wasm_timer_restart")
|
||||
declare function wasm_timer_restart(a: i32, b: i32): void;
|
||||
|
||||
@external("env", "wasm_get_sys_tick_ms")
|
||||
declare function wasm_get_sys_tick_ms(): i32;
|
||||
|
||||
export var timer_list = new Array<user_timer>();
|
||||
|
||||
export class user_timer {
|
||||
timer_id: i32 = 0;
|
||||
timeout: i32;
|
||||
period: bool = false;
|
||||
cb: () => void;
|
||||
|
||||
constructor(cb: () => void, timeout: i32, period: bool) {
|
||||
this.cb = cb;
|
||||
this.timeout = timeout;
|
||||
this.period = period
|
||||
this.timer_id = timer_create(this.timeout, this.period, true);
|
||||
}
|
||||
}
|
||||
|
||||
export function timer_create(a: i32, b: bool, c: bool): i32 {
|
||||
return wasm_create_timer(a, b, c);
|
||||
}
|
||||
|
||||
export function setTimeout(cb: () => void, timeout: i32): user_timer {
|
||||
var timer = new user_timer(cb, timeout, false);
|
||||
timer_list.push(timer);
|
||||
|
||||
return timer;
|
||||
}
|
||||
|
||||
export function setInterval(cb: () => void, timeout: i32): user_timer {
|
||||
var timer = new user_timer(cb, timeout, true);
|
||||
timer_list.push(timer);
|
||||
|
||||
return timer;
|
||||
}
|
||||
|
||||
export function timer_cancel(timer: user_timer): void {
|
||||
wasm_timer_cancel(timer.timer_id);
|
||||
|
||||
var i = 0;
|
||||
for (i = 0; i < timer_list.length; i++) {
|
||||
if (timer_list[i].timer_id == timer.timer_id)
|
||||
break;
|
||||
}
|
||||
|
||||
timer_list.splice(i, 1);
|
||||
}
|
||||
|
||||
export function timer_restart(timer: user_timer, interval: number): void {
|
||||
wasm_timer_restart(timer.timer_id, i32(interval));
|
||||
}
|
||||
|
||||
export function now(): i32 {
|
||||
return wasm_get_sys_tick_ms();
|
||||
}
|
||||
|
||||
// This export function need to be copied to the top application file
|
||||
//
|
||||
export function on_timer_callback(on_timer_id: i32): void {
|
||||
for (let i = 0; i < timer_list.length; i++) {
|
||||
if (timer_list[i].timer_id == on_timer_id) {
|
||||
timer_list[i].cb();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +0,0 @@
|
|||
{
|
||||
"extends": "../node_modules/assemblyscript/std/assembly.json",
|
||||
"include": [
|
||||
"./**/*.ts"
|
||||
]
|
||||
}
|
|
@ -13,8 +13,6 @@ objs = []
|
|||
WAMR_ROOT_DIR = os.path.join(cwd, "..")
|
||||
SHARED_DIR = os.path.join(WAMR_ROOT_DIR, 'core', 'shared')
|
||||
IWASM_DIR = os.path.join(WAMR_ROOT_DIR, 'core', 'iwasm')
|
||||
APP_MGR_DIR = os.path.join(WAMR_ROOT_DIR, 'core', 'app-mgr')
|
||||
APP_FRAMEWORK_DIR = os.path.join(WAMR_ROOT_DIR, 'core', 'app-framework')
|
||||
DEPS_DIR = os.path.join(WAMR_ROOT_DIR, 'core', 'deps')
|
||||
|
||||
if GetDepend(['WAMR_BUILD_INTERP']):
|
||||
|
@ -28,12 +26,6 @@ if GetDepend(['WAMR_BUILD_AOT']):
|
|||
script_path = os.path.join(IWASM_DIR, 'compilation', 'SConscript')
|
||||
objs += SConscript(script_path)
|
||||
|
||||
if GetDepend(['WAMR_BUILD_APP_FRAMEWORK']):
|
||||
objs += SConscript(os.path.join(APP_FRAMEWORK_DIR, 'SConscript'))
|
||||
objs += SConscript(os.path.join(SHARED_DIR, 'coap', 'SConscript'))
|
||||
objs += SConscript(os.path.join(APP_MGR_DIR, 'app-manager', 'SConscript'))
|
||||
objs += SConscript(os.path.join(APP_MGR_DIR, 'app-mgr-shared', 'SConscript'))
|
||||
|
||||
if GetDepend(['WAMR_BUILD_LIBC_BUILTIN']):
|
||||
objs += SConscript(os.path.join(IWASM_DIR, 'libraries', 'libc-builtin', 'SConscript'))
|
||||
|
||||
|
|
|
@ -10,12 +10,6 @@ endif ()
|
|||
if (NOT DEFINED IWASM_DIR)
|
||||
set (IWASM_DIR ${WAMR_ROOT_DIR}/core/iwasm)
|
||||
endif ()
|
||||
if (NOT DEFINED APP_MGR_DIR)
|
||||
set (APP_MGR_DIR ${WAMR_ROOT_DIR}/core/app-mgr)
|
||||
endif ()
|
||||
if (NOT DEFINED APP_FRAMEWORK_DIR)
|
||||
set (APP_FRAMEWORK_DIR ${WAMR_ROOT_DIR}/core/app-framework)
|
||||
endif ()
|
||||
if (NOT DEFINED DEPS_DIR)
|
||||
set (DEPS_DIR ${WAMR_ROOT_DIR}/core/deps)
|
||||
endif ()
|
||||
|
@ -88,13 +82,6 @@ if (WAMR_BUILD_GC EQUAL 1)
|
|||
set (WAMR_BUILD_REF_TYPES 1)
|
||||
endif ()
|
||||
|
||||
if (WAMR_BUILD_APP_FRAMEWORK EQUAL 1)
|
||||
include (${APP_FRAMEWORK_DIR}/app_framework.cmake)
|
||||
include (${SHARED_DIR}/coap/lib_coap.cmake)
|
||||
include (${APP_MGR_DIR}/app-manager/app_mgr.cmake)
|
||||
include (${APP_MGR_DIR}/app-mgr-shared/app_mgr_shared.cmake)
|
||||
endif ()
|
||||
|
||||
if (WAMR_BUILD_LIBC_BUILTIN EQUAL 1)
|
||||
include (${IWASM_DIR}/libraries/libc-builtin/libc_builtin.cmake)
|
||||
endif ()
|
||||
|
@ -200,9 +187,6 @@ set (source_all
|
|||
${IWASM_COMPL_SOURCE}
|
||||
${IWASM_FAST_JIT_SOURCE}
|
||||
${IWASM_GC_SOURCE}
|
||||
${WASM_APP_LIB_SOURCE_ALL}
|
||||
${NATIVE_INTERFACE_SOURCE}
|
||||
${APP_MGR_SOURCE}
|
||||
${LIB_WASI_THREADS_SOURCE}
|
||||
${LIB_PTHREAD_SOURCE}
|
||||
${THREAD_MGR_SOURCE}
|
||||
|
|
|
@ -21,7 +21,6 @@ EXCLUDE_PATHS = [
|
|||
"**/.git/*",
|
||||
"**/.github/*",
|
||||
"**/.vscode/*",
|
||||
"**/assembly-script/*",
|
||||
"**/build/*",
|
||||
"**/build-scripts/*",
|
||||
"**/ci/*",
|
||||
|
@ -30,9 +29,7 @@ EXCLUDE_PATHS = [
|
|||
"**/samples/wasm-c-api/src/*.*",
|
||||
"**/samples/workload/*",
|
||||
"**/test-tools/wasi-sdk/*",
|
||||
"**/test-tools/IoT-APP-Store-Demo/*",
|
||||
"**/tests/wamr-test-suites/workspace/*",
|
||||
"**/wamr-sdk/*",
|
||||
]
|
||||
|
||||
C_SUFFIXES = [".c", ".cpp", ".h"]
|
||||
|
|
|
@ -1,120 +0,0 @@
|
|||
# Application framework
|
||||
|
||||
By using the WAMR VM core, we are flexible to build different application frameworks for the specific domains, although it would take quite some effort.
|
||||
|
||||
The WAMR has offered a comprehensive framework for programming WASM applications for device and IoT usages. The framework supports running multiple applications, that are based on the event driven programming model. Here are the supporting API sets by the [WAMR application framework library](../doc/wamr_api.md) :
|
||||
|
||||
- Timer, Inter-app communication (request/response and pub/sub), Sensor, Connectivity and data transmission, 2D graphic UI
|
||||
|
||||
Browse the folder [core/app-framework](./app-framework) for how to extend the application framework.
|
||||
|
||||
|
||||
## Directory structure
|
||||
This folder "app-native-shared" is for the source files shared by both WASM APP and native runtime
|
||||
|
||||
- The c files in this directory are compiled into both the WASM APP and runtime.
|
||||
- The header files for distributing to SDK are placed in the "bi-inc" folder.
|
||||
|
||||
This folder "template" contains a pre-defined directory structure for a framework component. The developers can copy the template folder to create new components to the application framework.
|
||||
|
||||
Every other subfolder is framework component. Each component contains two library parts: **app and native**.
|
||||
|
||||
- The "base" component provide timer API and inter-app communication support. It must be enabled if other components are selected.
|
||||
- Under the "app" folder of a component, the subfolder "wa_inc" holds all header files that should be included by the WASM applications
|
||||
|
||||
## Application framework basic model
|
||||
|
||||
The app framework is built on top of two fundamental operations:
|
||||
|
||||
- [Native calls into WASM function](../../doc/embed_wamr.md)
|
||||
|
||||
- [WASM app calls into native API](../../doc/export_native_api.md)
|
||||
|
||||
Asynchronized programming model is supported for WASM applications
|
||||
|
||||
- Every WASM app has its own sandbox and thread
|
||||
|
||||
- Queue and messaging
|
||||
|
||||
<img src="../../doc/pics/app_framework.PNG" style="zoom:67%;" />
|
||||
|
||||
|
||||
|
||||
## Customized building of app framework
|
||||
|
||||
A component can be compilation configurable to the runtime. The wamr SDK tool "build_sdk.sh" supports menu config to select app components for building a customized runtime.
|
||||
|
||||
A number of CMAKE variables are defined to control build of framework and components. You can create a cmake file for defining these variables and include it in the CMakeList.txt for your software, or pass it in "-x" argument when run the [build_sdk.sh](../../wamr-sdk/build_sdk.sh) for building the runtime SDK.
|
||||
|
||||
```cmake
|
||||
set (WAMR_BUILD_APP_FRAMEWORK 1)
|
||||
set (WAMR_BUILD_APP_LIST WAMR_APP_BUILD_BASE)
|
||||
```
|
||||
|
||||
Variables:
|
||||
|
||||
- **WAMR_BUILD_APP_FRAMEWORK**: enable the application framework
|
||||
- **WAMR_BUILD_APP_LIST**: the selected components to be built into the final runtime
|
||||
|
||||
|
||||
|
||||
The configuration file can be generated through the wamr-sdk menu config:
|
||||
|
||||
```bash
|
||||
cd wamr-sdk
|
||||
./build_sdk -n [profile] -i
|
||||
```
|
||||
|
||||
|
||||
|
||||
## Create new components
|
||||
|
||||
Generally you should follow following steps to create a new component:
|
||||
|
||||
- Copy the “template” for creating a new folder
|
||||
|
||||
- Implement the app part
|
||||
|
||||
- If your component exports native function to WASM, ensure your created a header file under app for declaring the function prototype.
|
||||
- If you component provides header files for the WASM applications to include, ensure it is placed under subfolder "wa_inc".
|
||||
|
||||
- Implement the native part
|
||||
|
||||
- If your native function is exported to WASM, you need to create an inl file for the registration. It can be any file name, assuming the file name is "my_component.inl" here:
|
||||
|
||||
```c
|
||||
//use right signature for your functions
|
||||
EXPORT_WASM_API_WITH_SIG(wasm_my_component_api_1, "(i*~)i"),
|
||||
EXPORT_WASM_API_WITH_SIG(wasm_my_component_api_2, "(i)i"),
|
||||
```
|
||||
|
||||
- Ensure "wasm_lib.cmake" is provided as it will be included by the WAMR SDK building script
|
||||
|
||||
- Add a definition in "wasm_lib.cmake" for your component, e.g.
|
||||
|
||||
```cmake
|
||||
add_definitions (-DAPP_FRAMEWORK_MY_COMPONENT)
|
||||
```
|
||||
|
||||
- Modify the file [app_ext_lib_export.c](./app_ext_lib_export.c) to register native APIs exported for the new introduced component. Skip it if not exporting native functions.
|
||||
|
||||
```
|
||||
#include "lib_export.h"
|
||||
|
||||
...
|
||||
#ifdef APP_FRAMEWORK_MY_COMPONENT // this definition is created in wasm_lib.cmake
|
||||
#include "my_component_native_api.h"
|
||||
#endif
|
||||
|
||||
static NativeSymbol extended_native_symbol_defs[] = {
|
||||
...
|
||||
#ifdef APP_FRAMEWORK_MY_COMPONENT
|
||||
#include "my_component.inl"
|
||||
#endif
|
||||
};
|
||||
```
|
||||
|
||||
|
||||
## Sensor component working flow
|
||||
![](../../doc/pics/sensor_callflow.PNG)
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
Notes:
|
||||
=======
|
||||
This folder is for the source files shared by both WASM APP and native runtime
|
||||
|
||||
- The c files in this directory are compiled into both the WASM APP and runtime.
|
||||
- The header files for distributing to SDK are placed in the "bi-inc" folder.
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,986 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#include "bi-inc/attr_container.h"
|
||||
|
||||
typedef union jvalue {
|
||||
bool z;
|
||||
int8_t i8;
|
||||
uint8_t u8;
|
||||
int16_t i16;
|
||||
uint16_t u16;
|
||||
int32_t i32;
|
||||
uint32_t u32;
|
||||
int64_t i64;
|
||||
uint64_t u64;
|
||||
float f;
|
||||
double d;
|
||||
} jvalue;
|
||||
|
||||
static inline int16_t
|
||||
get_int16(const char *buf)
|
||||
{
|
||||
int16_t ret;
|
||||
bh_memcpy_s(&ret, sizeof(int16_t), buf, sizeof(int16_t));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline uint16_t
|
||||
get_uint16(const char *buf)
|
||||
{
|
||||
uint16_t ret;
|
||||
bh_memcpy_s(&ret, sizeof(uint16_t), buf, sizeof(uint16_t));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline int32_t
|
||||
get_int32(const char *buf)
|
||||
{
|
||||
int32_t ret;
|
||||
bh_memcpy_s(&ret, sizeof(int32_t), buf, sizeof(int32_t));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
get_uint32(const char *buf)
|
||||
{
|
||||
uint32_t ret;
|
||||
bh_memcpy_s(&ret, sizeof(uint32_t), buf, sizeof(uint32_t));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline int64_t
|
||||
get_int64(const char *buf)
|
||||
{
|
||||
int64_t ret;
|
||||
bh_memcpy_s(&ret, sizeof(int64_t), buf, sizeof(int64_t));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline uint64_t
|
||||
get_uint64(const char *buf)
|
||||
{
|
||||
uint64_t ret;
|
||||
bh_memcpy_s(&ret, sizeof(uint64_t), buf, sizeof(uint64_t));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline void
|
||||
set_int16(char *buf, int16_t v)
|
||||
{
|
||||
bh_memcpy_s(buf, sizeof(int16_t), &v, sizeof(int16_t));
|
||||
}
|
||||
|
||||
static inline void
|
||||
set_uint16(char *buf, uint16_t v)
|
||||
{
|
||||
bh_memcpy_s(buf, sizeof(uint16_t), &v, sizeof(uint16_t));
|
||||
}
|
||||
|
||||
static inline void
|
||||
set_int32(char *buf, int32_t v)
|
||||
{
|
||||
bh_memcpy_s(buf, sizeof(int32_t), &v, sizeof(int32_t));
|
||||
}
|
||||
|
||||
static inline void
|
||||
set_uint32(char *buf, uint32_t v)
|
||||
{
|
||||
bh_memcpy_s(buf, sizeof(uint32_t), &v, sizeof(uint32_t));
|
||||
}
|
||||
|
||||
static inline void
|
||||
set_int64(char *buf, int64_t v)
|
||||
{
|
||||
bh_memcpy_s(buf, sizeof(int64_t), &v, sizeof(int64_t));
|
||||
}
|
||||
|
||||
static inline void
|
||||
set_uint64(char *buf, uint64_t v)
|
||||
{
|
||||
bh_memcpy_s(buf, sizeof(uint64_t), &v, sizeof(uint64_t));
|
||||
}
|
||||
|
||||
char *
|
||||
attr_container_get_attr_begin(const attr_container_t *attr_cont,
|
||||
uint32_t *p_total_length, uint16_t *p_attr_num)
|
||||
{
|
||||
char *p = (char *)attr_cont->buf;
|
||||
uint16_t str_len, attr_num;
|
||||
uint32_t total_length;
|
||||
|
||||
/* skip total length */
|
||||
total_length = get_uint32(p);
|
||||
p += sizeof(uint32_t);
|
||||
if (!total_length)
|
||||
return NULL;
|
||||
|
||||
/* tag length */
|
||||
str_len = get_uint16(p);
|
||||
p += sizeof(uint16_t);
|
||||
if (!str_len)
|
||||
return NULL;
|
||||
|
||||
/* tag content */
|
||||
p += str_len;
|
||||
if ((uint32_t)(p - attr_cont->buf) >= total_length)
|
||||
return NULL;
|
||||
|
||||
/* attribute num */
|
||||
attr_num = get_uint16(p);
|
||||
p += sizeof(uint16_t);
|
||||
if ((uint32_t)(p - attr_cont->buf) >= total_length)
|
||||
return NULL;
|
||||
|
||||
if (p_total_length)
|
||||
*p_total_length = total_length;
|
||||
|
||||
if (p_attr_num)
|
||||
*p_attr_num = attr_num;
|
||||
|
||||
/* first attribute */
|
||||
return p;
|
||||
}
|
||||
|
||||
static char *
|
||||
attr_container_get_attr_next(const char *curr_attr)
|
||||
{
|
||||
char *p = (char *)curr_attr;
|
||||
uint8_t type;
|
||||
|
||||
/* key length and key */
|
||||
p += sizeof(uint16_t) + get_uint16(p);
|
||||
type = *p++;
|
||||
|
||||
/* Byte type to Boolean type */
|
||||
if (type >= ATTR_TYPE_BYTE && type <= ATTR_TYPE_BOOLEAN) {
|
||||
p += 1 << (type & 3);
|
||||
return p;
|
||||
}
|
||||
/* String type */
|
||||
else if (type == ATTR_TYPE_STRING) {
|
||||
p += sizeof(uint16_t) + get_uint16(p);
|
||||
return p;
|
||||
}
|
||||
/* ByteArray type */
|
||||
else if (type == ATTR_TYPE_BYTEARRAY) {
|
||||
p += sizeof(uint32_t) + get_uint32(p);
|
||||
return p;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const char *
|
||||
attr_container_find_attr(const attr_container_t *attr_cont, const char *key)
|
||||
{
|
||||
uint32_t total_length;
|
||||
uint16_t str_len, attr_num, i;
|
||||
const char *p = attr_cont->buf;
|
||||
|
||||
if (!key)
|
||||
return NULL;
|
||||
|
||||
if (!(p = attr_container_get_attr_begin(attr_cont, &total_length,
|
||||
&attr_num)))
|
||||
return NULL;
|
||||
|
||||
for (i = 0; i < attr_num; i++) {
|
||||
/* key length */
|
||||
if (!(str_len = get_uint16(p)))
|
||||
return NULL;
|
||||
|
||||
if (str_len == strlen(key) + 1
|
||||
&& memcmp(p + sizeof(uint16_t), key, str_len) == 0) {
|
||||
if ((uint32_t)(p + sizeof(uint16_t) + str_len - attr_cont->buf)
|
||||
>= total_length)
|
||||
return NULL;
|
||||
return p;
|
||||
}
|
||||
|
||||
if (!(p = attr_container_get_attr_next(p)))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *
|
||||
attr_container_get_attr_end(const attr_container_t *attr_cont)
|
||||
{
|
||||
uint32_t total_length;
|
||||
uint16_t attr_num, i;
|
||||
char *p;
|
||||
|
||||
if (!(p = attr_container_get_attr_begin(attr_cont, &total_length,
|
||||
&attr_num)))
|
||||
return NULL;
|
||||
|
||||
for (i = 0; i < attr_num; i++)
|
||||
if (!(p = attr_container_get_attr_next(p)))
|
||||
return NULL;
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
static char *
|
||||
attr_container_get_msg_end(attr_container_t *attr_cont)
|
||||
{
|
||||
char *p = attr_cont->buf;
|
||||
return p + get_uint32(p);
|
||||
}
|
||||
|
||||
uint16_t
|
||||
attr_container_get_attr_num(const attr_container_t *attr_cont)
|
||||
{
|
||||
uint16_t str_len;
|
||||
/* skip total length */
|
||||
const char *p = attr_cont->buf + sizeof(uint32_t);
|
||||
|
||||
str_len = get_uint16(p);
|
||||
/* skip tag length and tag */
|
||||
p += sizeof(uint16_t) + str_len;
|
||||
|
||||
/* attribute num */
|
||||
return get_uint16(p);
|
||||
}
|
||||
|
||||
static void
|
||||
attr_container_inc_attr_num(attr_container_t *attr_cont)
|
||||
{
|
||||
uint16_t str_len, attr_num;
|
||||
/* skip total length */
|
||||
char *p = attr_cont->buf + sizeof(uint32_t);
|
||||
|
||||
str_len = get_uint16(p);
|
||||
/* skip tag length and tag */
|
||||
p += sizeof(uint16_t) + str_len;
|
||||
|
||||
/* attribute num */
|
||||
attr_num = get_uint16(p) + 1;
|
||||
set_uint16(p, attr_num);
|
||||
}
|
||||
|
||||
attr_container_t *
|
||||
attr_container_create(const char *tag)
|
||||
{
|
||||
attr_container_t *attr_cont;
|
||||
int length, tag_length;
|
||||
char *p;
|
||||
|
||||
tag_length = tag ? strlen(tag) + 1 : 1;
|
||||
length = offsetof(attr_container_t, buf) +
|
||||
/* total length + tag length + tag + reserved 100 bytes */
|
||||
sizeof(uint32_t) + sizeof(uint16_t) + tag_length + 100;
|
||||
|
||||
if (!(attr_cont = attr_container_malloc(length))) {
|
||||
attr_container_printf(
|
||||
"Create attr_container failed: allocate memory failed.\r\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(attr_cont, 0, length);
|
||||
p = attr_cont->buf;
|
||||
|
||||
/* total length */
|
||||
set_uint32(p, length - offsetof(attr_container_t, buf));
|
||||
p += 4;
|
||||
|
||||
/* tag length, tag */
|
||||
set_uint16(p, tag_length);
|
||||
p += 2;
|
||||
if (tag)
|
||||
bh_memcpy_s(p, tag_length, tag, tag_length);
|
||||
|
||||
return attr_cont;
|
||||
}
|
||||
|
||||
void
|
||||
attr_container_destroy(const attr_container_t *attr_cont)
|
||||
{
|
||||
if (attr_cont)
|
||||
attr_container_free((char *)attr_cont);
|
||||
}
|
||||
|
||||
static bool
|
||||
check_set_attr(attr_container_t **p_attr_cont, const char *key)
|
||||
{
|
||||
uint32_t flags;
|
||||
|
||||
if (!p_attr_cont || !*p_attr_cont || !key || strlen(key) == 0) {
|
||||
attr_container_printf(
|
||||
"Set attribute failed: invalid input arguments.\r\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
flags = get_uint32((char *)*p_attr_cont);
|
||||
if (flags & ATTR_CONT_READONLY_SHIFT) {
|
||||
attr_container_printf(
|
||||
"Set attribute failed: attribute container is readonly.\r\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
attr_container_set_attr(attr_container_t **p_attr_cont, const char *key,
|
||||
int type, const void *value, int value_length)
|
||||
{
|
||||
attr_container_t *attr_cont, *attr_cont1;
|
||||
uint16_t str_len;
|
||||
uint32_t total_length, attr_len;
|
||||
char *p, *p1, *attr_end, *msg_end, *attr_buf;
|
||||
|
||||
if (!check_set_attr(p_attr_cont, key)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
attr_cont = *p_attr_cont;
|
||||
p = attr_cont->buf;
|
||||
total_length = get_uint32(p);
|
||||
|
||||
if (!(attr_end = attr_container_get_attr_end(attr_cont))) {
|
||||
attr_container_printf("Set attr failed: get attr end failed.\r\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
msg_end = attr_container_get_msg_end(attr_cont);
|
||||
|
||||
/* key len + key + '\0' + type */
|
||||
attr_len = sizeof(uint16_t) + strlen(key) + 1 + 1;
|
||||
if (type >= ATTR_TYPE_BYTE && type <= ATTR_TYPE_BOOLEAN)
|
||||
attr_len += 1 << (type & 3);
|
||||
else if (type == ATTR_TYPE_STRING)
|
||||
attr_len += sizeof(uint16_t) + value_length;
|
||||
else if (type == ATTR_TYPE_BYTEARRAY)
|
||||
attr_len += sizeof(uint32_t) + value_length;
|
||||
|
||||
if (!(p = attr_buf = attr_container_malloc(attr_len))) {
|
||||
attr_container_printf("Set attr failed: allocate memory failed.\r\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Set the attr buf */
|
||||
str_len = (uint16_t)(strlen(key) + 1);
|
||||
set_uint16(p, str_len);
|
||||
p += sizeof(uint16_t);
|
||||
bh_memcpy_s(p, str_len, key, str_len);
|
||||
p += str_len;
|
||||
|
||||
*p++ = type;
|
||||
if (type >= ATTR_TYPE_BYTE && type <= ATTR_TYPE_BOOLEAN)
|
||||
bh_memcpy_s(p, 1 << (type & 3), value, 1 << (type & 3));
|
||||
else if (type == ATTR_TYPE_STRING) {
|
||||
set_uint16(p, value_length);
|
||||
p += sizeof(uint16_t);
|
||||
bh_memcpy_s(p, value_length, value, value_length);
|
||||
}
|
||||
else if (type == ATTR_TYPE_BYTEARRAY) {
|
||||
set_uint32(p, value_length);
|
||||
p += sizeof(uint32_t);
|
||||
bh_memcpy_s(p, value_length, value, value_length);
|
||||
}
|
||||
|
||||
if ((p = (char *)attr_container_find_attr(attr_cont, key))) {
|
||||
/* key found */
|
||||
p1 = attr_container_get_attr_next(p);
|
||||
|
||||
if (p1 - p == attr_len) {
|
||||
bh_memcpy_s(p, attr_len, attr_buf, attr_len);
|
||||
attr_container_free(attr_buf);
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((uint32_t)(p1 - p + msg_end - attr_end) >= attr_len) {
|
||||
memmove(p, p1, attr_end - p1);
|
||||
bh_memcpy_s(p + (attr_end - p1), attr_len, attr_buf, attr_len);
|
||||
attr_container_free(attr_buf);
|
||||
return true;
|
||||
}
|
||||
|
||||
total_length += attr_len + 100;
|
||||
if (!(attr_cont1 = attr_container_malloc(offsetof(attr_container_t, buf)
|
||||
+ total_length))) {
|
||||
attr_container_printf(
|
||||
"Set attr failed: allocate memory failed.\r\n");
|
||||
attr_container_free(attr_buf);
|
||||
return false;
|
||||
}
|
||||
|
||||
bh_memcpy_s(attr_cont1, p - (char *)attr_cont, attr_cont,
|
||||
p - (char *)attr_cont);
|
||||
bh_memcpy_s((char *)attr_cont1 + (unsigned)(p - (char *)attr_cont),
|
||||
attr_end - p1, p1, attr_end - p1);
|
||||
bh_memcpy_s((char *)attr_cont1 + (unsigned)(p - (char *)attr_cont)
|
||||
+ (unsigned)(attr_end - p1),
|
||||
attr_len, attr_buf, attr_len);
|
||||
p = attr_cont1->buf;
|
||||
set_uint32(p, total_length);
|
||||
*p_attr_cont = attr_cont1;
|
||||
/* Free original buffer */
|
||||
attr_container_free(attr_cont);
|
||||
attr_container_free(attr_buf);
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
/* key not found */
|
||||
if ((uint32_t)(msg_end - attr_end) >= attr_len) {
|
||||
bh_memcpy_s(attr_end, msg_end - attr_end, attr_buf, attr_len);
|
||||
attr_container_inc_attr_num(attr_cont);
|
||||
attr_container_free(attr_buf);
|
||||
return true;
|
||||
}
|
||||
|
||||
total_length += attr_len + 100;
|
||||
if (!(attr_cont1 = attr_container_malloc(offsetof(attr_container_t, buf)
|
||||
+ total_length))) {
|
||||
attr_container_printf(
|
||||
"Set attr failed: allocate memory failed.\r\n");
|
||||
attr_container_free(attr_buf);
|
||||
return false;
|
||||
}
|
||||
|
||||
bh_memcpy_s(attr_cont1, attr_end - (char *)attr_cont, attr_cont,
|
||||
attr_end - (char *)attr_cont);
|
||||
bh_memcpy_s((char *)attr_cont1
|
||||
+ (unsigned)(attr_end - (char *)attr_cont),
|
||||
attr_len, attr_buf, attr_len);
|
||||
attr_container_inc_attr_num(attr_cont1);
|
||||
p = attr_cont1->buf;
|
||||
set_uint32(p, total_length);
|
||||
*p_attr_cont = attr_cont1;
|
||||
/* Free original buffer */
|
||||
attr_container_free(attr_cont);
|
||||
attr_container_free(attr_buf);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
attr_container_set_short(attr_container_t **p_attr_cont, const char *key,
|
||||
short value)
|
||||
{
|
||||
return attr_container_set_attr(p_attr_cont, key, ATTR_TYPE_SHORT, &value,
|
||||
2);
|
||||
}
|
||||
|
||||
bool
|
||||
attr_container_set_int16(attr_container_t **p_attr_cont, const char *key,
|
||||
int16_t value)
|
||||
{
|
||||
return attr_container_set_attr(p_attr_cont, key, ATTR_TYPE_INT16, &value,
|
||||
2);
|
||||
}
|
||||
|
||||
bool
|
||||
attr_container_set_int(attr_container_t **p_attr_cont, const char *key,
|
||||
int value)
|
||||
{
|
||||
return attr_container_set_attr(p_attr_cont, key, ATTR_TYPE_INT, &value, 4);
|
||||
}
|
||||
|
||||
bool
|
||||
attr_container_set_int32(attr_container_t **p_attr_cont, const char *key,
|
||||
int32_t value)
|
||||
{
|
||||
return attr_container_set_attr(p_attr_cont, key, ATTR_TYPE_INT32, &value,
|
||||
4);
|
||||
}
|
||||
|
||||
bool
|
||||
attr_container_set_uint32(attr_container_t **p_attr_cont, const char *key,
|
||||
uint32_t value)
|
||||
{
|
||||
return attr_container_set_attr(p_attr_cont, key, ATTR_TYPE_UINT32, &value,
|
||||
4);
|
||||
}
|
||||
|
||||
bool
|
||||
attr_container_set_int64(attr_container_t **p_attr_cont, const char *key,
|
||||
int64_t value)
|
||||
{
|
||||
return attr_container_set_attr(p_attr_cont, key, ATTR_TYPE_INT64, &value,
|
||||
8);
|
||||
}
|
||||
|
||||
bool
|
||||
attr_container_set_uint64(attr_container_t **p_attr_cont, const char *key,
|
||||
uint64_t value)
|
||||
{
|
||||
return attr_container_set_attr(p_attr_cont, key, ATTR_TYPE_UINT64, &value,
|
||||
8);
|
||||
}
|
||||
|
||||
bool
|
||||
attr_container_set_byte(attr_container_t **p_attr_cont, const char *key,
|
||||
int8_t value)
|
||||
{
|
||||
return attr_container_set_attr(p_attr_cont, key, ATTR_TYPE_BYTE, &value, 1);
|
||||
}
|
||||
|
||||
bool
|
||||
attr_container_set_int8(attr_container_t **p_attr_cont, const char *key,
|
||||
int8_t value)
|
||||
{
|
||||
return attr_container_set_attr(p_attr_cont, key, ATTR_TYPE_INT8, &value, 1);
|
||||
}
|
||||
|
||||
bool
|
||||
attr_container_set_uint8(attr_container_t **p_attr_cont, const char *key,
|
||||
uint8_t value)
|
||||
{
|
||||
return attr_container_set_attr(p_attr_cont, key, ATTR_TYPE_UINT8, &value,
|
||||
1);
|
||||
}
|
||||
|
||||
bool
|
||||
attr_container_set_uint16(attr_container_t **p_attr_cont, const char *key,
|
||||
uint16_t value)
|
||||
{
|
||||
return attr_container_set_attr(p_attr_cont, key, ATTR_TYPE_UINT16, &value,
|
||||
2);
|
||||
}
|
||||
|
||||
bool
|
||||
attr_container_set_float(attr_container_t **p_attr_cont, const char *key,
|
||||
float value)
|
||||
{
|
||||
return attr_container_set_attr(p_attr_cont, key, ATTR_TYPE_FLOAT, &value,
|
||||
4);
|
||||
}
|
||||
|
||||
bool
|
||||
attr_container_set_double(attr_container_t **p_attr_cont, const char *key,
|
||||
double value)
|
||||
{
|
||||
return attr_container_set_attr(p_attr_cont, key, ATTR_TYPE_DOUBLE, &value,
|
||||
8);
|
||||
}
|
||||
|
||||
bool
|
||||
attr_container_set_bool(attr_container_t **p_attr_cont, const char *key,
|
||||
bool value)
|
||||
{
|
||||
int8_t value1 = value ? 1 : 0;
|
||||
return attr_container_set_attr(p_attr_cont, key, ATTR_TYPE_BOOLEAN, &value1,
|
||||
1);
|
||||
}
|
||||
|
||||
bool
|
||||
attr_container_set_string(attr_container_t **p_attr_cont, const char *key,
|
||||
const char *value)
|
||||
{
|
||||
if (!value) {
|
||||
attr_container_printf("Set attr failed: invald input arguments.\r\n");
|
||||
return false;
|
||||
}
|
||||
return attr_container_set_attr(p_attr_cont, key, ATTR_TYPE_STRING, value,
|
||||
strlen(value) + 1);
|
||||
}
|
||||
|
||||
bool
|
||||
attr_container_set_bytearray(attr_container_t **p_attr_cont, const char *key,
|
||||
const int8_t *value, unsigned length)
|
||||
{
|
||||
if (!value) {
|
||||
attr_container_printf("Set attr failed: invald input arguments.\r\n");
|
||||
return false;
|
||||
}
|
||||
return attr_container_set_attr(p_attr_cont, key, ATTR_TYPE_BYTEARRAY, value,
|
||||
length);
|
||||
}
|
||||
|
||||
static const char *
|
||||
attr_container_get_attr(const attr_container_t *attr_cont, const char *key)
|
||||
{
|
||||
const char *attr_addr;
|
||||
|
||||
if (!attr_cont || !key) {
|
||||
attr_container_printf(
|
||||
"Get attribute failed: invalid input arguments.\r\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!(attr_addr = attr_container_find_attr(attr_cont, key))) {
|
||||
attr_container_printf("Get attribute failed: lookup key failed.\r\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* key len + key + '\0' */
|
||||
return attr_addr + 2 + strlen(key) + 1;
|
||||
}
|
||||
|
||||
#define TEMPLATE_ATTR_BUF_TO_VALUE(attr, key, var_name) \
|
||||
do { \
|
||||
jvalue val; \
|
||||
const char *addr = attr_container_get_attr(attr, key); \
|
||||
uint8_t type; \
|
||||
if (!addr) \
|
||||
return 0; \
|
||||
val.i64 = 0; \
|
||||
type = *(uint8_t *)addr++; \
|
||||
switch (type) { \
|
||||
case ATTR_TYPE_BYTE: /* = ATTR_TYPE_INT8 */ \
|
||||
case ATTR_TYPE_SHORT: /* = ATTR_TYPE_INT16 */ \
|
||||
case ATTR_TYPE_INT: /* = ATTR_TYPE_INT32 */ \
|
||||
case ATTR_TYPE_INT64: \
|
||||
case ATTR_TYPE_UINT8: \
|
||||
case ATTR_TYPE_UINT16: \
|
||||
case ATTR_TYPE_UINT32: \
|
||||
case ATTR_TYPE_UINT64: \
|
||||
case ATTR_TYPE_FLOAT: \
|
||||
case ATTR_TYPE_DOUBLE: \
|
||||
case ATTR_TYPE_BOOLEAN: \
|
||||
bh_memcpy_s(&val, sizeof(val.var_name), addr, \
|
||||
1 << (type & 3)); \
|
||||
break; \
|
||||
case ATTR_TYPE_STRING: \
|
||||
{ \
|
||||
unsigned len = get_uint16(addr); \
|
||||
addr += 2; \
|
||||
if (len > sizeof(val.var_name)) \
|
||||
len = sizeof(val.var_name); \
|
||||
bh_memcpy_s(&val.var_name, sizeof(val.var_name), addr, len); \
|
||||
break; \
|
||||
} \
|
||||
case ATTR_TYPE_BYTEARRAY: \
|
||||
{ \
|
||||
unsigned len = get_uint32(addr); \
|
||||
addr += 4; \
|
||||
if (len > sizeof(val.var_name)) \
|
||||
len = sizeof(val.var_name); \
|
||||
bh_memcpy_s(&val.var_name, sizeof(val.var_name), addr, len); \
|
||||
break; \
|
||||
} \
|
||||
default: \
|
||||
bh_assert(0); \
|
||||
break; \
|
||||
} \
|
||||
return val.var_name; \
|
||||
} while (0)
|
||||
|
||||
short
|
||||
attr_container_get_as_short(const attr_container_t *attr_cont, const char *key)
|
||||
{
|
||||
TEMPLATE_ATTR_BUF_TO_VALUE(attr_cont, key, i16);
|
||||
}
|
||||
|
||||
int16_t
|
||||
attr_container_get_as_int16(const attr_container_t *attr_cont, const char *key)
|
||||
{
|
||||
return (int16_t)attr_container_get_as_short(attr_cont, key);
|
||||
}
|
||||
|
||||
int
|
||||
attr_container_get_as_int(const attr_container_t *attr_cont, const char *key)
|
||||
{
|
||||
TEMPLATE_ATTR_BUF_TO_VALUE(attr_cont, key, i32);
|
||||
}
|
||||
|
||||
int32_t
|
||||
attr_container_get_as_int32(const attr_container_t *attr_cont, const char *key)
|
||||
{
|
||||
return (int32_t)attr_container_get_as_int(attr_cont, key);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
attr_container_get_as_uint32(const attr_container_t *attr_cont, const char *key)
|
||||
{
|
||||
return (uint32_t)attr_container_get_as_int(attr_cont, key);
|
||||
}
|
||||
|
||||
int64_t
|
||||
attr_container_get_as_int64(const attr_container_t *attr_cont, const char *key)
|
||||
{
|
||||
TEMPLATE_ATTR_BUF_TO_VALUE(attr_cont, key, i64);
|
||||
}
|
||||
|
||||
uint64_t
|
||||
attr_container_get_as_uint64(const attr_container_t *attr_cont, const char *key)
|
||||
{
|
||||
return (uint64_t)attr_container_get_as_int64(attr_cont, key);
|
||||
}
|
||||
|
||||
int8_t
|
||||
attr_container_get_as_byte(const attr_container_t *attr_cont, const char *key)
|
||||
{
|
||||
TEMPLATE_ATTR_BUF_TO_VALUE(attr_cont, key, i8);
|
||||
}
|
||||
|
||||
int8_t
|
||||
attr_container_get_as_int8(const attr_container_t *attr_cont, const char *key)
|
||||
{
|
||||
return attr_container_get_as_byte(attr_cont, key);
|
||||
}
|
||||
|
||||
uint8_t
|
||||
attr_container_get_as_uint8(const attr_container_t *attr_cont, const char *key)
|
||||
{
|
||||
return (uint8_t)attr_container_get_as_byte(attr_cont, key);
|
||||
}
|
||||
|
||||
uint16_t
|
||||
attr_container_get_as_uint16(const attr_container_t *attr_cont, const char *key)
|
||||
{
|
||||
return (uint16_t)attr_container_get_as_short(attr_cont, key);
|
||||
}
|
||||
|
||||
float
|
||||
attr_container_get_as_float(const attr_container_t *attr_cont, const char *key)
|
||||
{
|
||||
TEMPLATE_ATTR_BUF_TO_VALUE(attr_cont, key, f);
|
||||
}
|
||||
|
||||
double
|
||||
attr_container_get_as_double(const attr_container_t *attr_cont, const char *key)
|
||||
{
|
||||
TEMPLATE_ATTR_BUF_TO_VALUE(attr_cont, key, d);
|
||||
}
|
||||
|
||||
bool
|
||||
attr_container_get_as_bool(const attr_container_t *attr_cont, const char *key)
|
||||
{
|
||||
TEMPLATE_ATTR_BUF_TO_VALUE(attr_cont, key, z);
|
||||
}
|
||||
|
||||
const int8_t *
|
||||
attr_container_get_as_bytearray(const attr_container_t *attr_cont,
|
||||
const char *key, unsigned *array_length)
|
||||
{
|
||||
const char *addr = attr_container_get_attr(attr_cont, key);
|
||||
uint8_t type;
|
||||
uint32_t length;
|
||||
|
||||
if (!addr)
|
||||
return NULL;
|
||||
|
||||
if (!array_length) {
|
||||
attr_container_printf("Get attribute failed: invalid input arguments.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
type = *(uint8_t *)addr++;
|
||||
switch (type) {
|
||||
case ATTR_TYPE_BYTE: /* = ATTR_TYPE_INT8 */
|
||||
case ATTR_TYPE_SHORT: /* = ATTR_TYPE_INT16 */
|
||||
case ATTR_TYPE_INT: /* = ATTR_TYPE_INT32 */
|
||||
case ATTR_TYPE_INT64:
|
||||
case ATTR_TYPE_UINT8:
|
||||
case ATTR_TYPE_UINT16:
|
||||
case ATTR_TYPE_UINT32:
|
||||
case ATTR_TYPE_UINT64:
|
||||
case ATTR_TYPE_FLOAT:
|
||||
case ATTR_TYPE_DOUBLE:
|
||||
case ATTR_TYPE_BOOLEAN:
|
||||
length = 1 << (type & 3);
|
||||
break;
|
||||
case ATTR_TYPE_STRING:
|
||||
length = get_uint16(addr);
|
||||
addr += 2;
|
||||
break;
|
||||
case ATTR_TYPE_BYTEARRAY:
|
||||
length = get_uint32(addr);
|
||||
addr += 4;
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*array_length = length;
|
||||
return (const int8_t *)addr;
|
||||
}
|
||||
|
||||
char *
|
||||
attr_container_get_as_string(const attr_container_t *attr_cont, const char *key)
|
||||
{
|
||||
unsigned array_length;
|
||||
return (char *)attr_container_get_as_bytearray(attr_cont, key,
|
||||
&array_length);
|
||||
}
|
||||
|
||||
const char *
|
||||
attr_container_get_tag(const attr_container_t *attr_cont)
|
||||
{
|
||||
return attr_cont ? attr_cont->buf + sizeof(uint32_t) + sizeof(uint16_t)
|
||||
: NULL;
|
||||
}
|
||||
|
||||
bool
|
||||
attr_container_contain_key(const attr_container_t *attr_cont, const char *key)
|
||||
{
|
||||
if (!attr_cont || !key || !strlen(key)) {
|
||||
attr_container_printf(
|
||||
"Check contain key failed: invalid input arguments.\r\n");
|
||||
return false;
|
||||
}
|
||||
return attr_container_find_attr(attr_cont, key) ? true : false;
|
||||
}
|
||||
|
||||
unsigned int
|
||||
attr_container_get_serialize_length(const attr_container_t *attr_cont)
|
||||
{
|
||||
const char *p;
|
||||
|
||||
if (!attr_cont) {
|
||||
attr_container_printf("Get container serialize length failed: invalid "
|
||||
"input arguments.\r\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
p = attr_cont->buf;
|
||||
return sizeof(uint16_t) + get_uint32(p);
|
||||
}
|
||||
|
||||
bool
|
||||
attr_container_serialize(char *buf, const attr_container_t *attr_cont)
|
||||
{
|
||||
const char *p;
|
||||
uint16_t flags;
|
||||
uint32_t length;
|
||||
|
||||
if (!buf || !attr_cont) {
|
||||
attr_container_printf(
|
||||
"Container serialize failed: invalid input arguments.\r\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
p = attr_cont->buf;
|
||||
length = sizeof(uint16_t) + get_uint32(p);
|
||||
bh_memcpy_s(buf, length, attr_cont, length);
|
||||
/* Set readonly */
|
||||
flags = get_uint16((const char *)attr_cont);
|
||||
set_uint16(buf, flags | (1 << ATTR_CONT_READONLY_SHIFT));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
attr_container_is_constant(const attr_container_t *attr_cont)
|
||||
{
|
||||
uint16_t flags;
|
||||
|
||||
if (!attr_cont) {
|
||||
attr_container_printf(
|
||||
"Container check const: invalid input arguments.\r\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
flags = get_uint16((const char *)attr_cont);
|
||||
return (flags & (1 << ATTR_CONT_READONLY_SHIFT)) ? true : false;
|
||||
}
|
||||
|
||||
void
|
||||
attr_container_dump(const attr_container_t *attr_cont)
|
||||
{
|
||||
uint32_t total_length;
|
||||
uint16_t attr_num, i, type;
|
||||
const char *p, *tag, *key;
|
||||
jvalue value;
|
||||
|
||||
if (!attr_cont)
|
||||
return;
|
||||
|
||||
tag = attr_container_get_tag(attr_cont);
|
||||
if (!tag)
|
||||
return;
|
||||
|
||||
attr_container_printf("Attribute container dump:\n");
|
||||
attr_container_printf("Tag: %s\n", tag);
|
||||
|
||||
p = attr_container_get_attr_begin(attr_cont, &total_length, &attr_num);
|
||||
if (!p)
|
||||
return;
|
||||
|
||||
attr_container_printf("Attribute list:\n");
|
||||
for (i = 0; i < attr_num; i++) {
|
||||
key = p + 2;
|
||||
/* Skip key len and key */
|
||||
p += 2 + get_uint16(p);
|
||||
type = *p++;
|
||||
attr_container_printf(" key: %s", key);
|
||||
|
||||
switch (type) {
|
||||
case ATTR_TYPE_BYTE: /* = ATTR_TYPE_INT8 */
|
||||
bh_memcpy_s(&value.i8, 1, p, 1);
|
||||
attr_container_printf(", type: byte, value: 0x%x\n",
|
||||
value.i8 & 0xFF);
|
||||
p++;
|
||||
break;
|
||||
case ATTR_TYPE_SHORT: /* = ATTR_TYPE_INT16 */
|
||||
bh_memcpy_s(&value.i16, sizeof(int16_t), p, sizeof(int16_t));
|
||||
attr_container_printf(", type: short, value: 0x%x\n",
|
||||
value.i16 & 0xFFFF);
|
||||
p += 2;
|
||||
break;
|
||||
case ATTR_TYPE_INT: /* = ATTR_TYPE_INT32 */
|
||||
bh_memcpy_s(&value.i32, sizeof(int32_t), p, sizeof(int32_t));
|
||||
attr_container_printf(", type: int, value: 0x%x\n", value.i32);
|
||||
p += 4;
|
||||
break;
|
||||
case ATTR_TYPE_INT64:
|
||||
bh_memcpy_s(&value.i64, sizeof(int64_t), p, sizeof(int64_t));
|
||||
attr_container_printf(", type: int64, value: 0x%llx\n",
|
||||
(long long unsigned int)(value.i64));
|
||||
p += 8;
|
||||
break;
|
||||
case ATTR_TYPE_UINT8:
|
||||
bh_memcpy_s(&value.u8, 1, p, 1);
|
||||
attr_container_printf(", type: uint8, value: 0x%x\n", value.u8);
|
||||
p++;
|
||||
break;
|
||||
case ATTR_TYPE_UINT16:
|
||||
bh_memcpy_s(&value.u16, sizeof(uint16_t), p, sizeof(uint16_t));
|
||||
attr_container_printf(", type: uint16, value: 0x%x\n",
|
||||
value.u16);
|
||||
p += 2;
|
||||
break;
|
||||
case ATTR_TYPE_UINT32:
|
||||
bh_memcpy_s(&value.u32, sizeof(uint32_t), p, sizeof(uint32_t));
|
||||
attr_container_printf(", type: uint32, value: 0x%x\n",
|
||||
value.u32);
|
||||
p += 4;
|
||||
break;
|
||||
case ATTR_TYPE_UINT64:
|
||||
bh_memcpy_s(&value.u64, sizeof(uint64_t), p, sizeof(uint64_t));
|
||||
attr_container_printf(", type: int64, value: 0x%llx\n",
|
||||
(long long unsigned int)(value.u64));
|
||||
p += 8;
|
||||
break;
|
||||
case ATTR_TYPE_FLOAT:
|
||||
bh_memcpy_s(&value.f, sizeof(float), p, sizeof(float));
|
||||
attr_container_printf(", type: float, value: %f\n", value.f);
|
||||
p += 4;
|
||||
break;
|
||||
case ATTR_TYPE_DOUBLE:
|
||||
bh_memcpy_s(&value.d, sizeof(double), p, sizeof(double));
|
||||
attr_container_printf(", type: double, value: %f\n", value.d);
|
||||
p += 8;
|
||||
break;
|
||||
case ATTR_TYPE_BOOLEAN:
|
||||
bh_memcpy_s(&value.z, 1, p, 1);
|
||||
attr_container_printf(", type: bool, value: 0x%x\n", value.z);
|
||||
p++;
|
||||
break;
|
||||
case ATTR_TYPE_STRING:
|
||||
attr_container_printf(", type: string, value: %s\n",
|
||||
p + sizeof(uint16_t));
|
||||
p += sizeof(uint16_t) + get_uint16(p);
|
||||
break;
|
||||
case ATTR_TYPE_BYTEARRAY:
|
||||
attr_container_printf(", type: byte array, length: %d\n",
|
||||
get_uint32(p));
|
||||
p += sizeof(uint32_t) + get_uint32(p);
|
||||
break;
|
||||
default:
|
||||
bh_assert(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
attr_container_printf("\n");
|
||||
}
|
|
@ -1,596 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#ifndef _ATTR_CONTAINER_H_
|
||||
#define _ATTR_CONTAINER_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include "bh_platform.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Attribute type */
|
||||
enum {
|
||||
ATTR_TYPE_BEGIN = 0,
|
||||
ATTR_TYPE_BYTE = ATTR_TYPE_BEGIN,
|
||||
ATTR_TYPE_INT8 = ATTR_TYPE_BYTE,
|
||||
ATTR_TYPE_SHORT,
|
||||
ATTR_TYPE_INT16 = ATTR_TYPE_SHORT,
|
||||
ATTR_TYPE_INT,
|
||||
ATTR_TYPE_INT32 = ATTR_TYPE_INT,
|
||||
ATTR_TYPE_INT64,
|
||||
ATTR_TYPE_UINT8,
|
||||
ATTR_TYPE_UINT16,
|
||||
ATTR_TYPE_UINT32,
|
||||
ATTR_TYPE_UINT64,
|
||||
/**
|
||||
* Why ATTR_TYPE_FLOAT = 10?
|
||||
* We determine the number of bytes that should be copied through 1<<(type &
|
||||
* 3). ATTR_TYPE_BYTE = 0, so the number of bytes is 1 << 0 = 1.
|
||||
* ATTR_TYPE_UINT64 = 7, so the number of bytes is 1 << 3 = 8.
|
||||
* Since the float type takes up 4 bytes, ATTR_TYPE_FLOAT should be 10.
|
||||
* Calculation: (1 << (10&3)) = (1 << 2) = 4
|
||||
*/
|
||||
ATTR_TYPE_FLOAT = 10,
|
||||
ATTR_TYPE_DOUBLE,
|
||||
ATTR_TYPE_BOOLEAN,
|
||||
ATTR_TYPE_STRING,
|
||||
ATTR_TYPE_BYTEARRAY,
|
||||
ATTR_TYPE_END = ATTR_TYPE_BYTEARRAY
|
||||
};
|
||||
|
||||
#define ATTR_CONT_READONLY_SHIFT 2
|
||||
|
||||
typedef struct attr_container {
|
||||
/* container flag:
|
||||
* bit0, bit1 denote the implemenation algorithm, 00: buffer, 01: link list
|
||||
* bit2 denotes the readonly flag: 1 is readonly and attr cannot be set
|
||||
*/
|
||||
char flags[2];
|
||||
/**
|
||||
* Buffer format
|
||||
* for buffer implementation:
|
||||
* buf length (4 bytes)
|
||||
* tag length (2 bytes)
|
||||
* tag
|
||||
* attr num (2bytes)
|
||||
* attr[0..n-1]:
|
||||
* attr key length (2 bytes)
|
||||
* attr type (1byte)
|
||||
* attr value (length depends on attr type)
|
||||
*/
|
||||
char buf[1];
|
||||
} attr_container_t;
|
||||
|
||||
/**
|
||||
* Create attribute container
|
||||
*
|
||||
* @param tag tag of current attribute container
|
||||
*
|
||||
* @return the created attribute container, NULL if failed
|
||||
*/
|
||||
attr_container_t *
|
||||
attr_container_create(const char *tag);
|
||||
|
||||
/**
|
||||
* Destroy attribute container
|
||||
*
|
||||
* @param attr_cont the attribute container to destroy
|
||||
*/
|
||||
void
|
||||
attr_container_destroy(const attr_container_t *attr_cont);
|
||||
|
||||
/**
|
||||
* Set short attribute in attribute container
|
||||
*
|
||||
* @param p_attr_cont pointer to attribute container to set attribute, and
|
||||
* return the new attribute container if it is re-created
|
||||
* @param key the attribute key
|
||||
* @param value the attribute value
|
||||
*
|
||||
* @return true if success, false otherwise
|
||||
*/
|
||||
bool
|
||||
attr_container_set_short(attr_container_t **p_attr_cont, const char *key,
|
||||
short value);
|
||||
|
||||
/**
|
||||
* Set int16 attribute in attribute container
|
||||
*
|
||||
* @param p_attr_cont pointer to attribute container to set attribute, and
|
||||
* return the new attribute container if it is re-created
|
||||
* @param key the attribute key
|
||||
* @param value the attribute value
|
||||
*
|
||||
* @return true if success, false otherwise
|
||||
*/
|
||||
bool
|
||||
attr_container_set_int16(attr_container_t **p_attr_cont, const char *key,
|
||||
int16_t value);
|
||||
|
||||
/**
|
||||
* Set int attribute in attribute container
|
||||
*
|
||||
* @param p_attr_cont pointer to attribute container to set attribute, and
|
||||
* return the new attribute container if it is re-created
|
||||
* @param key the attribute key
|
||||
* @param value the attribute value
|
||||
*
|
||||
* @return true if success, false otherwise
|
||||
*/
|
||||
bool
|
||||
attr_container_set_int(attr_container_t **p_attr_cont, const char *key,
|
||||
int value);
|
||||
|
||||
/**
|
||||
* Set int32 attribute in attribute container
|
||||
*
|
||||
* @param p_attr_cont pointer to attribute container to set attribute, and
|
||||
* return the new attribute container if it is re-created
|
||||
* @param key the attribute key
|
||||
* @param value the attribute value
|
||||
*
|
||||
* @return true if success, false otherwise
|
||||
*/
|
||||
bool
|
||||
attr_container_set_int32(attr_container_t **p_attr_cont, const char *key,
|
||||
int32_t value);
|
||||
|
||||
/**
|
||||
* Set uint32 attribute in attribute container
|
||||
*
|
||||
* @param p_attr_cont pointer to attribute container to set attribute, and
|
||||
* return the new attribute container if it is re-created
|
||||
* @param key the attribute key
|
||||
* @param value the attribute value
|
||||
*
|
||||
* @return true if success, false otherwise
|
||||
*/
|
||||
bool
|
||||
attr_container_set_uint32(attr_container_t **p_attr_cont, const char *key,
|
||||
uint32_t value);
|
||||
|
||||
/**
|
||||
* Set int64 attribute in attribute container
|
||||
*
|
||||
* @param p_attr_cont pointer to attribute container to set attribute, and
|
||||
* return the new attribute container if it is re-created
|
||||
* @param key the attribute key
|
||||
* @param value the attribute value
|
||||
*
|
||||
* @return true if success, false otherwise
|
||||
*/
|
||||
bool
|
||||
attr_container_set_int64(attr_container_t **p_attr_cont, const char *key,
|
||||
int64_t value);
|
||||
|
||||
/**
|
||||
* Set uint64 attribute in attribute container
|
||||
*
|
||||
* @param p_attr_cont pointer to attribute container to set attribute, and
|
||||
* return the new attribute container if it is re-created
|
||||
* @param key the attribute key
|
||||
* @param value the attribute value
|
||||
*
|
||||
* @return true if success, false otherwise
|
||||
*/
|
||||
bool
|
||||
attr_container_set_uint64(attr_container_t **p_attr_cont, const char *key,
|
||||
uint64_t value);
|
||||
|
||||
/**
|
||||
* Set byte attribute in attribute container
|
||||
*
|
||||
* @param p_attr_cont pointer to attribute container to set attribute, and
|
||||
* return the new attribute container if it is re-created
|
||||
* @param key the attribute key
|
||||
* @param value the attribute value
|
||||
*
|
||||
* @return true if success, false otherwise
|
||||
*/
|
||||
bool
|
||||
attr_container_set_byte(attr_container_t **p_attr_cont, const char *key,
|
||||
int8_t value);
|
||||
|
||||
/**
|
||||
* Set int8 attribute in attribute container
|
||||
*
|
||||
* @param p_attr_cont pointer to attribute container to set attribute, and
|
||||
* return the new attribute container if it is re-created
|
||||
* @param key the attribute key
|
||||
* @param value the attribute value
|
||||
*
|
||||
* @return true if success, false otherwise
|
||||
*/
|
||||
bool
|
||||
attr_container_set_int8(attr_container_t **p_attr_cont, const char *key,
|
||||
int8_t value);
|
||||
|
||||
/**
|
||||
* Set uint8 attribute in attribute container
|
||||
*
|
||||
* @param p_attr_cont pointer to attribute container to set attribute, and
|
||||
* return the new attribute container if it is re-created
|
||||
* @param key the attribute key
|
||||
* @param value the attribute value
|
||||
*
|
||||
* @return true if success, false otherwise
|
||||
*/
|
||||
bool
|
||||
attr_container_set_uint8(attr_container_t **p_attr_cont, const char *key,
|
||||
uint8_t value);
|
||||
|
||||
/**
|
||||
* Set uint16 attribute in attribute container
|
||||
*
|
||||
* @param p_attr_cont pointer to attribute container to set attribute, and
|
||||
* return the new attribute container if it is re-created
|
||||
* @param key the attribute key
|
||||
* @param value the attribute value
|
||||
*
|
||||
* @return true if success, false otherwise
|
||||
*/
|
||||
bool
|
||||
attr_container_set_uint16(attr_container_t **p_attr_cont, const char *key,
|
||||
uint16_t value);
|
||||
|
||||
/**
|
||||
* Set float attribute in attribute container
|
||||
*
|
||||
* @param p_attr_cont pointer to attribute container to set attribute, and
|
||||
* return the new attribute container if it is re-created
|
||||
* @param key the attribute key
|
||||
* @param value the attribute value
|
||||
*
|
||||
* @return true if success, false otherwise
|
||||
*/
|
||||
bool
|
||||
attr_container_set_float(attr_container_t **p_attr_cont, const char *key,
|
||||
float value);
|
||||
|
||||
/**
|
||||
* Set double attribute in attribute container
|
||||
*
|
||||
* @param p_attr_cont pointer to attribute container to set attribute, and
|
||||
* return the new attribute container if it is re-created
|
||||
* @param key the attribute key
|
||||
* @param value the attribute value
|
||||
*
|
||||
* @return true if success, false otherwise
|
||||
*/
|
||||
bool
|
||||
attr_container_set_double(attr_container_t **p_attr_cont, const char *key,
|
||||
double value);
|
||||
|
||||
/**
|
||||
* Set bool attribute in attribute container
|
||||
*
|
||||
* @param p_attr_cont pointer to attribute container to set attribute, and
|
||||
* return the new attribute container if it is re-created
|
||||
* @param key the attribute key
|
||||
* @param value the attribute value
|
||||
*
|
||||
* @return true if success, false otherwise
|
||||
*/
|
||||
bool
|
||||
attr_container_set_bool(attr_container_t **p_attr_cont, const char *key,
|
||||
bool value);
|
||||
|
||||
/**
|
||||
* Set string attribute in attribute container
|
||||
*
|
||||
* @param p_attr_cont pointer to attribute container to set attribute, and
|
||||
* return the new attribute container if it is re-created
|
||||
* @param key the attribute key
|
||||
* @param value the attribute value
|
||||
*
|
||||
* @return true if success, false otherwise
|
||||
*/
|
||||
bool
|
||||
attr_container_set_string(attr_container_t **p_attr_cont, const char *key,
|
||||
const char *value);
|
||||
|
||||
/**
|
||||
* Set bytearray attribute in attribute container
|
||||
*
|
||||
* @param p_attr_cont pointer to attribute container to set attribute, and
|
||||
* return the new attribute container if it is re-created
|
||||
* @param key the attribute key
|
||||
* @param value the bytearray buffer
|
||||
* @param length the bytearray length
|
||||
*
|
||||
* @return true if success, false otherwise
|
||||
*/
|
||||
bool
|
||||
attr_container_set_bytearray(attr_container_t **p_attr_cont, const char *key,
|
||||
const int8_t *value, unsigned length);
|
||||
|
||||
/**
|
||||
* Get tag of current attribute container
|
||||
*
|
||||
* @param attr_cont the attribute container
|
||||
*
|
||||
* @return tag of current attribute container
|
||||
*/
|
||||
const char *
|
||||
attr_container_get_tag(const attr_container_t *attr_cont);
|
||||
|
||||
/**
|
||||
* Get attribute number of current attribute container
|
||||
*
|
||||
* @param attr_cont the attribute container
|
||||
*
|
||||
* @return attribute number of current attribute container
|
||||
*/
|
||||
uint16_t
|
||||
attr_container_get_attr_num(const attr_container_t *attr_cont);
|
||||
|
||||
/**
|
||||
* Whether the attribute container contains an attribute key.
|
||||
*
|
||||
* @param attr_cont the attribute container
|
||||
* @param key the attribute key
|
||||
*
|
||||
* @return true if key is contained in message, false otherwise
|
||||
*/
|
||||
bool
|
||||
attr_container_contain_key(const attr_container_t *attr_cont, const char *key);
|
||||
|
||||
/**
|
||||
* Get attribute from attribute container and return it as short value,
|
||||
* return 0 if attribute isn't found in message.
|
||||
*
|
||||
* @param attr_cont the attribute container
|
||||
* @param key the attribute key
|
||||
*
|
||||
* @return the short value of the attribute, 0 if key isn't found
|
||||
*/
|
||||
short
|
||||
attr_container_get_as_short(const attr_container_t *attr_cont, const char *key);
|
||||
|
||||
/**
|
||||
* Get attribute from attribute container and return it as int16 value,
|
||||
* return 0 if attribute isn't found in message.
|
||||
*
|
||||
* @param attr_cont the attribute container
|
||||
* @param key the attribute key
|
||||
*
|
||||
* @return the short value of the attribute, 0 if key isn't found
|
||||
*/
|
||||
int16_t
|
||||
attr_container_get_as_int16(const attr_container_t *attr_cont, const char *key);
|
||||
|
||||
/**
|
||||
* Get attribute from attribute container and return it as int value,
|
||||
* return 0 if attribute isn't found in message.
|
||||
*
|
||||
* @param attr_cont the attribute container
|
||||
* @param key the attribute key
|
||||
*
|
||||
* @return the int value of the attribute, 0 if key isn't found
|
||||
*/
|
||||
int
|
||||
attr_container_get_as_int(const attr_container_t *attr_cont, const char *key);
|
||||
|
||||
/**
|
||||
* Get attribute from attribute container and return it as int32 value,
|
||||
* return 0 if attribute isn't found in message.
|
||||
*
|
||||
* @param attr_cont the attribute container
|
||||
* @param key the attribute key
|
||||
*
|
||||
* @return the int value of the attribute, 0 if key isn't found
|
||||
*/
|
||||
int32_t
|
||||
attr_container_get_as_int32(const attr_container_t *attr_cont, const char *key);
|
||||
|
||||
/**
|
||||
* Get attribute from attribute container and return it as uint32 value,
|
||||
* return 0 if attribute isn't found in message.
|
||||
*
|
||||
* @param attr_cont the attribute container
|
||||
* @param key the attribute key
|
||||
*
|
||||
* @return the unsigned int value of the attribute, 0 if key isn't found
|
||||
*/
|
||||
uint32_t
|
||||
attr_container_get_as_uint32(const attr_container_t *attr_cont,
|
||||
const char *key);
|
||||
|
||||
/**
|
||||
* Get attribute from attribute container and return it as int64 value,
|
||||
* return 0 if attribute isn't found in attribute container.
|
||||
*
|
||||
* @param attr_cont the attribute container
|
||||
* @param key the attribute key
|
||||
*
|
||||
* @return the long value of the attribute, 0 if key isn't found
|
||||
*/
|
||||
int64_t
|
||||
attr_container_get_as_int64(const attr_container_t *attr_cont, const char *key);
|
||||
|
||||
/**
|
||||
* Get attribute from attribute container and return it as uint64 value,
|
||||
* return 0 if attribute isn't found in attribute container.
|
||||
*
|
||||
* @param attr_cont the attribute container
|
||||
* @param key the attribute key
|
||||
*
|
||||
* @return the unsigned long value of the attribute, 0 if key isn't found
|
||||
*/
|
||||
uint64_t
|
||||
attr_container_get_as_uint64(const attr_container_t *attr_cont,
|
||||
const char *key);
|
||||
|
||||
/**
|
||||
* Get attribute from attribute container and return it as byte value,
|
||||
* return 0 if attribute isn't found in attribute container.
|
||||
*
|
||||
* @param attr_cont the attribute container
|
||||
* @param key the attribute key
|
||||
*
|
||||
* @return the byte value of the attribute, 0 if key isn't found
|
||||
*/
|
||||
int8_t
|
||||
attr_container_get_as_byte(const attr_container_t *attr_cont, const char *key);
|
||||
|
||||
/**
|
||||
* Get attribute from attribute container and return it as int8 value,
|
||||
* return 0 if attribute isn't found in attribute container.
|
||||
*
|
||||
* @param attr_cont the attribute container
|
||||
* @param key the attribute key
|
||||
*
|
||||
* @return the byte value of the attribute, 0 if key isn't found
|
||||
*/
|
||||
int8_t
|
||||
attr_container_get_as_int8(const attr_container_t *attr_cont, const char *key);
|
||||
|
||||
/**
|
||||
* Get attribute from attribute container and return it as uint8 value,
|
||||
* return 0 if attribute isn't found in attribute container.
|
||||
*
|
||||
* @param attr_cont the attribute container
|
||||
* @param key the attribute key
|
||||
*
|
||||
* @return the uint8 value of the attribute, 0 if key isn't found
|
||||
*/
|
||||
uint8_t
|
||||
attr_container_get_as_uint8(const attr_container_t *attr_cont, const char *key);
|
||||
|
||||
/**
|
||||
* Get attribute from attribute container and return it as uint16 value,
|
||||
* return 0 if attribute isn't found in attribute container.
|
||||
*
|
||||
* @param attr_cont the attribute container
|
||||
* @param key the attribute key
|
||||
*
|
||||
* @return the char value of the attribute, 0 if key isn't found
|
||||
*/
|
||||
uint16_t
|
||||
attr_container_get_as_uint16(const attr_container_t *attr_cont,
|
||||
const char *key);
|
||||
|
||||
/**
|
||||
* Get attribute from attribute container and return it as float value,
|
||||
* return 0 if attribute isn't found in attribute container.
|
||||
*
|
||||
* @param attr_cont the attribute container
|
||||
* @param key the attribute key
|
||||
*
|
||||
* @return the float value of the attribute, 0 if key isn't found
|
||||
*/
|
||||
float
|
||||
attr_container_get_as_float(const attr_container_t *attr_cont, const char *key);
|
||||
|
||||
/**
|
||||
* Get attribute from attribute container and return it as double value,
|
||||
* return 0 if attribute isn't found in attribute container.
|
||||
*
|
||||
* @param attr_cont the attribute container
|
||||
* @param key the attribute key
|
||||
*
|
||||
* @return the double value of the attribute, 0 if key isn't found
|
||||
*/
|
||||
double
|
||||
attr_container_get_as_double(const attr_container_t *attr_cont,
|
||||
const char *key);
|
||||
|
||||
/**
|
||||
* Get attribute from attribute container and return it as bool value,
|
||||
* return false if attribute isn't found in attribute container.
|
||||
*
|
||||
* @param attr_cont the attribute container
|
||||
* @param key the attribute key
|
||||
*
|
||||
* @return the bool value of the attribute, 0 if key isn't found
|
||||
*/
|
||||
bool
|
||||
attr_container_get_as_bool(const attr_container_t *attr_cont, const char *key);
|
||||
|
||||
/**
|
||||
* Get attribute from attribute container and return it as string value,
|
||||
* return NULL if attribute isn't found in attribute container.
|
||||
*
|
||||
* @param attr_cont the attribute container
|
||||
* @param key the attribute key
|
||||
*
|
||||
* @return the string value of the attribute, NULL if key isn't found
|
||||
*/
|
||||
char *
|
||||
attr_container_get_as_string(const attr_container_t *attr_cont,
|
||||
const char *key);
|
||||
|
||||
/**
|
||||
* Get attribute from attribute container and return it as bytearray value,
|
||||
* return 0 if attribute isn't found in attribute container.
|
||||
*
|
||||
* @param attr_cont the attribute container
|
||||
* @param key the attribute key
|
||||
*
|
||||
* @return the bytearray value of the attribute, NULL if key isn't found
|
||||
*/
|
||||
const int8_t *
|
||||
attr_container_get_as_bytearray(const attr_container_t *attr_cont,
|
||||
const char *key, unsigned *array_length);
|
||||
|
||||
/**
|
||||
* Get the buffer size of attribute container
|
||||
*
|
||||
* @param attr_cont the attribute container
|
||||
*
|
||||
* @return the buffer size of attribute container
|
||||
*/
|
||||
unsigned
|
||||
attr_container_get_serialize_length(const attr_container_t *attr_cont);
|
||||
|
||||
/**
|
||||
* Serialize attribute container to a buffer
|
||||
*
|
||||
* @param buf the buffer to receive the serialized data
|
||||
* @param attr_cont the attribute container to be serialized
|
||||
*
|
||||
* @return true if success, false otherwise
|
||||
*/
|
||||
bool
|
||||
attr_container_serialize(char *buf, const attr_container_t *attr_cont);
|
||||
|
||||
/**
|
||||
* Whether the attribute container is const, or set attribute isn't supported
|
||||
*
|
||||
* @param attr_cont the attribute container
|
||||
*
|
||||
* @return true if const, false otherwise
|
||||
*/
|
||||
bool
|
||||
attr_container_is_constant(const attr_container_t *attr_cont);
|
||||
|
||||
void
|
||||
attr_container_dump(const attr_container_t *attr_cont);
|
||||
|
||||
#ifndef attr_container_malloc
|
||||
#define attr_container_malloc WA_MALLOC
|
||||
#endif
|
||||
|
||||
#ifndef attr_container_free
|
||||
#define attr_container_free WA_FREE
|
||||
#endif
|
||||
|
||||
#ifndef attr_container_printf
|
||||
#define attr_container_printf printf
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* end of extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* end of _ATTR_CONTAINER_H_ */
|
|
@ -1,155 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#ifndef _SHARED_UTILS_H_
|
||||
#define _SHARED_UTILS_H_
|
||||
|
||||
#include "bh_platform.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define FMT_ATTR_CONTAINER 99
|
||||
#define FMT_APP_RAW_BINARY 98
|
||||
|
||||
/* the request structure */
|
||||
typedef struct request {
|
||||
// message id
|
||||
uint32 mid;
|
||||
|
||||
// url of the request
|
||||
char *url;
|
||||
|
||||
// action of the request, can be PUT/GET/POST/DELETE
|
||||
int action;
|
||||
|
||||
// payload format, currently only support attr_container_t type
|
||||
int fmt;
|
||||
|
||||
// payload of the request, currently only support attr_container_t type
|
||||
void *payload;
|
||||
|
||||
// length in bytes of the payload
|
||||
int payload_len;
|
||||
|
||||
// sender of the request
|
||||
unsigned long sender;
|
||||
} request_t;
|
||||
|
||||
/* the response structure */
|
||||
typedef struct response {
|
||||
// message id
|
||||
uint32 mid;
|
||||
|
||||
// status of the response
|
||||
int status;
|
||||
|
||||
// payload format
|
||||
int fmt;
|
||||
|
||||
// payload of the response,
|
||||
void *payload;
|
||||
|
||||
// length in bytes of the payload
|
||||
int payload_len;
|
||||
|
||||
// receiver of the response
|
||||
unsigned long reciever;
|
||||
} response_t;
|
||||
|
||||
int
|
||||
check_url_start(const char *url, int url_len, const char *leading_str);
|
||||
|
||||
bool
|
||||
match_url(char *pattern, char *matched);
|
||||
|
||||
char *
|
||||
find_key_value(char *buffer, int buffer_len, char *key, char *value,
|
||||
int value_len, char delimiter);
|
||||
|
||||
request_t *
|
||||
clone_request(request_t *request);
|
||||
|
||||
void
|
||||
request_cleaner(request_t *request);
|
||||
|
||||
response_t *
|
||||
clone_response(response_t *response);
|
||||
|
||||
void
|
||||
response_cleaner(response_t *response);
|
||||
|
||||
/**
|
||||
* @brief Set fields of response.
|
||||
*
|
||||
* @param response pointer of the response to be set
|
||||
* @param status status of response
|
||||
* @param fmt format of the response payload
|
||||
* @param payload payload of the response
|
||||
* @param payload_len length in bytes of the response payload
|
||||
*
|
||||
* @return pointer to the response
|
||||
*
|
||||
* @warning the response pointer MUST NOT be NULL
|
||||
*/
|
||||
response_t *
|
||||
set_response(response_t *response, int status, int fmt, const char *payload,
|
||||
int payload_len);
|
||||
|
||||
/**
|
||||
* @brief Make a response for a request.
|
||||
*
|
||||
* @param request pointer of the request
|
||||
* @param response pointer of the response to be made
|
||||
*
|
||||
* @return pointer to the response
|
||||
*
|
||||
* @warning the request and response pointers MUST NOT be NULL
|
||||
*/
|
||||
response_t *
|
||||
make_response_for_request(request_t *request, response_t *response);
|
||||
|
||||
/**
|
||||
* @brief Initialize a request.
|
||||
*
|
||||
* @param request pointer of the request to be initialized
|
||||
* @param url url of the request
|
||||
* @param action action of the request
|
||||
* @param fmt format of the request payload
|
||||
* @param payload payload of the request
|
||||
* @param payload_len length in bytes of the request payload
|
||||
*
|
||||
* @return pointer to the request
|
||||
*
|
||||
* @warning the request pointer MUST NOT be NULL
|
||||
*/
|
||||
request_t *
|
||||
init_request(request_t *request, char *url, int action, int fmt, void *payload,
|
||||
int payload_len);
|
||||
|
||||
char *
|
||||
pack_request(request_t *request, int *size);
|
||||
|
||||
request_t *
|
||||
unpack_request(char *packet, int size, request_t *request);
|
||||
|
||||
char *
|
||||
pack_response(response_t *response, int *size);
|
||||
|
||||
response_t *
|
||||
unpack_response(char *packet, int size, response_t *response);
|
||||
|
||||
void
|
||||
free_req_resp_packet(char *packet);
|
||||
|
||||
char *
|
||||
wa_strdup(const char *str);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* end of _SHARED_UTILS_H_ */
|
|
@ -1,101 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#ifndef WAMR_GRAPHIC_LIBRARY_SHARED_UTILS_H
|
||||
#define WAMR_GRAPHIC_LIBRARY_SHARED_UTILS_H
|
||||
|
||||
#include "bh_platform.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
/* Object native function IDs */
|
||||
enum {
|
||||
OBJ_FUNC_ID_DEL,
|
||||
OBJ_FUNC_ID_DEL_ASYNC,
|
||||
OBJ_FUNC_ID_CLEAN,
|
||||
OBJ_FUNC_ID_SET_EVT_CB,
|
||||
OBJ_FUNC_ID_ALIGN,
|
||||
|
||||
/* Number of functions */
|
||||
_OBJ_FUNC_ID_NUM,
|
||||
};
|
||||
|
||||
/* Button native function IDs */
|
||||
enum {
|
||||
BTN_FUNC_ID_CREATE,
|
||||
BTN_FUNC_ID_SET_TOGGLE,
|
||||
BTN_FUNC_ID_SET_STATE,
|
||||
BTN_FUNC_ID_TOGGLE,
|
||||
BTN_FUNC_ID_SET_INK_IN_TIME,
|
||||
BTN_FUNC_ID_SET_INK_WAIT_TIME,
|
||||
BTN_FUNC_ID_SET_INK_OUT_TIME,
|
||||
BTN_FUNC_ID_GET_STATE,
|
||||
BTN_FUNC_ID_GET_TOGGLE,
|
||||
BTN_FUNC_ID_GET_INK_IN_TIME,
|
||||
BTN_FUNC_ID_GET_INK_WAIT_TIME,
|
||||
BTN_FUNC_ID_GET_INK_OUT_TIME,
|
||||
/* Number of functions */
|
||||
_BTN_FUNC_ID_NUM,
|
||||
};
|
||||
|
||||
/* Check box native function IDs */
|
||||
enum {
|
||||
CB_FUNC_ID_CREATE,
|
||||
CB_FUNC_ID_SET_TEXT,
|
||||
CB_FUNC_ID_SET_STATIC_TEXT,
|
||||
CB_FUNC_ID_GET_TEXT,
|
||||
CB_FUNC_ID_GET_TEXT_LENGTH,
|
||||
|
||||
/* Number of functions */
|
||||
_CB_FUNC_ID_NUM,
|
||||
};
|
||||
|
||||
/* List native function IDs */
|
||||
enum {
|
||||
LIST_FUNC_ID_CREATE,
|
||||
LIST_FUNC_ID_ADD_BTN,
|
||||
|
||||
/* Number of functions */
|
||||
_LIST_FUNC_ID_NUM,
|
||||
};
|
||||
|
||||
/* Label native function IDs */
|
||||
enum {
|
||||
LABEL_FUNC_ID_CREATE,
|
||||
LABEL_FUNC_ID_SET_TEXT,
|
||||
LABEL_FUNC_ID_SET_ARRAY_TEXT,
|
||||
LABEL_FUNC_ID_SET_STATIC_TEXT,
|
||||
LABEL_FUNC_ID_SET_LONG_MODE,
|
||||
LABEL_FUNC_ID_SET_ALIGN,
|
||||
LABEL_FUNC_ID_SET_RECOLOR,
|
||||
LABEL_FUNC_ID_SET_BODY_DRAW,
|
||||
LABEL_FUNC_ID_SET_ANIM_SPEED,
|
||||
LABEL_FUNC_ID_SET_TEXT_SEL_START,
|
||||
LABEL_FUNC_ID_SET_TEXT_SEL_END,
|
||||
LABEL_FUNC_ID_GET_TEXT,
|
||||
LABEL_FUNC_ID_GET_TEXT_LENGTH,
|
||||
LABEL_FUNC_ID_GET_LONG_MODE,
|
||||
LABEL_FUNC_ID_GET_ALIGN,
|
||||
LABEL_FUNC_ID_GET_RECOLOR,
|
||||
LABEL_FUNC_ID_GET_BODY_DRAW,
|
||||
LABEL_FUNC_ID_GET_ANIM_SPEED,
|
||||
LABEL_FUNC_ID_GET_LETTER_POS,
|
||||
LABEL_FUNC_ID_GET_TEXT_SEL_START,
|
||||
LABEL_FUNC_ID_GET_TEXT_SEL_END,
|
||||
LABEL_FUNC_ID_INS_TEXT,
|
||||
LABEL_FUNC_ID_CUT_TEXT,
|
||||
/* Number of functions */
|
||||
_LABEL_FUNC_ID_NUM,
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* WAMR_GRAPHIC_LIBRARY_SHARED_UTILS_H */
|
|
@ -1,15 +0,0 @@
|
|||
# Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
set (NATIVE_INTERFACE_DIR ${CMAKE_CURRENT_LIST_DIR})
|
||||
|
||||
include_directories(${NATIVE_INTERFACE_DIR})
|
||||
|
||||
|
||||
file (GLOB_RECURSE source_all ${NATIVE_INTERFACE_DIR}/*.c)
|
||||
|
||||
set (NATIVE_INTERFACE_SOURCE ${source_all})
|
||||
|
||||
set (WASM_APP_BI_INC_DIR "${NATIVE_INTERFACE_DIR}/bi-inc")
|
||||
LIST (APPEND RUNTIME_LIB_HEADER_LIST "${NATIVE_INTERFACE_DIR}/native_interface.h")
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#ifndef _NATIVE_INTERFACE_H_
|
||||
#define _NATIVE_INTERFACE_H_
|
||||
|
||||
/* Note: the bh_plaform.h is the only head file separately
|
||||
implemented by both [app] and [native] worlds */
|
||||
#include "bh_platform.h"
|
||||
|
||||
#endif /* end of _NATIVE_INTERFACE_H */
|
|
@ -1,493 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "bi-inc/shared_utils.h"
|
||||
|
||||
/* Serialization of request and response message
|
||||
*
|
||||
* Choices:
|
||||
* We considered a few options:
|
||||
* 1. coap
|
||||
* 2. flatbuffer
|
||||
* 3. cbor
|
||||
* 4. attr-containers of our own
|
||||
* 5. customized serialization for request/response
|
||||
*
|
||||
* Now we choose the #5 mainly because we need to quickly get the URL for
|
||||
* dispatching and sometimes we want to change the URL in the original packet.
|
||||
* the request format: fixed part: version: (1 byte), code (1 byte), fmt(2
|
||||
* byte), mid (4 bytes), sender_id(4 bytes), url_len(2 bytes),
|
||||
* payload_len(4bytes) dynamic part: url (bytes in url_len), payload
|
||||
*
|
||||
* response format:
|
||||
* fixed part: (1 byte), code (1 byte), fmt(2 byte), mid (4 bytes), sender_id(4
|
||||
* bytes), payload_len(4bytes) dynamic part: payload
|
||||
*/
|
||||
#define REQUES_PACKET_VER 1
|
||||
#define REQUEST_PACKET_FIX_PART_LEN 18
|
||||
#define REQUEST_PACKET_URL_OFFSET REQUEST_PACKET_FIX_PART_LEN
|
||||
#define REQUEST_PACKET_URL_LEN \
|
||||
*((uint16 *)((char *)buffer + 12)) /* to ensure little endian */
|
||||
#define REQUEST_PACKET_PAYLOAD_LEN \
|
||||
*((uint32 *)((char *)buffer + 14)) /* to ensure little endian */
|
||||
#define REQUEST_PACKET_URL(buffer) ((char *)buffer + REQUEST_PACKET_URL_OFFSET)
|
||||
#define REQUEST_PACKET_PAYLOAD(buffer) \
|
||||
((char *)buffer + REQUEST_PACKET_URL_OFFSET \
|
||||
+ REQUEST_PACKET_URL_LEN(buffer))
|
||||
|
||||
#define RESPONSE_PACKET_FIX_PART_LEN 16
|
||||
|
||||
char *
|
||||
pack_request(request_t *request, int *size)
|
||||
{
|
||||
int url_len = strlen(request->url) + 1;
|
||||
int len = REQUEST_PACKET_FIX_PART_LEN + url_len + request->payload_len;
|
||||
uint16 u16;
|
||||
uint32 u32;
|
||||
char *packet;
|
||||
|
||||
if ((packet = (char *)WA_MALLOC(len)) == NULL)
|
||||
return NULL;
|
||||
|
||||
/* TODO: ensure little endian for words and dwords */
|
||||
*packet = REQUES_PACKET_VER;
|
||||
*((uint8 *)(packet + 1)) = request->action;
|
||||
|
||||
u16 = htons(request->fmt);
|
||||
memcpy(packet + 2, &u16, 2);
|
||||
|
||||
u32 = htonl(request->mid);
|
||||
memcpy(packet + 4, &u32, 4);
|
||||
|
||||
u32 = htonl(request->sender);
|
||||
memcpy(packet + 8, &u32, 4);
|
||||
|
||||
u16 = htons(url_len);
|
||||
memcpy(packet + 12, &u16, 2);
|
||||
|
||||
u32 = htonl(request->payload_len);
|
||||
memcpy(packet + 14, &u32, 4);
|
||||
|
||||
strcpy(packet + REQUEST_PACKET_URL_OFFSET, request->url);
|
||||
memcpy(packet + REQUEST_PACKET_URL_OFFSET + url_len, request->payload,
|
||||
request->payload_len);
|
||||
|
||||
*size = len;
|
||||
return packet;
|
||||
}
|
||||
|
||||
void
|
||||
free_req_resp_packet(char *packet)
|
||||
{
|
||||
WA_FREE(packet);
|
||||
}
|
||||
|
||||
request_t *
|
||||
unpack_request(char *packet, int size, request_t *request)
|
||||
{
|
||||
uint16 url_len, u16;
|
||||
uint32 payload_len, u32;
|
||||
|
||||
if (*packet != REQUES_PACKET_VER) {
|
||||
return NULL;
|
||||
}
|
||||
if (size < REQUEST_PACKET_FIX_PART_LEN) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memcpy(&u16, packet + 12, 2);
|
||||
url_len = ntohs(u16);
|
||||
|
||||
memcpy(&u32, packet + 14, 4);
|
||||
payload_len = ntohl(u32);
|
||||
|
||||
if (size != (REQUEST_PACKET_FIX_PART_LEN + url_len + payload_len)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (*(packet + REQUEST_PACKET_FIX_PART_LEN + url_len - 1) != 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
request->action = *((uint8 *)(packet + 1));
|
||||
|
||||
memcpy(&u16, packet + 2, 2);
|
||||
request->fmt = ntohs(u16);
|
||||
|
||||
memcpy(&u32, packet + 4, 4);
|
||||
request->mid = ntohl(u32);
|
||||
|
||||
memcpy(&u32, packet + 8, 4);
|
||||
request->sender = ntohl(u32);
|
||||
|
||||
request->payload_len = payload_len;
|
||||
request->url = REQUEST_PACKET_URL(packet);
|
||||
|
||||
if (payload_len > 0)
|
||||
request->payload = packet + REQUEST_PACKET_URL_OFFSET + url_len;
|
||||
else
|
||||
request->payload = NULL;
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
char *
|
||||
pack_response(response_t *response, int *size)
|
||||
{
|
||||
int len = RESPONSE_PACKET_FIX_PART_LEN + response->payload_len;
|
||||
uint16 u16;
|
||||
uint32 u32;
|
||||
char *packet;
|
||||
|
||||
if ((packet = (char *)WA_MALLOC(len)) == NULL)
|
||||
return NULL;
|
||||
|
||||
/* TODO: ensure little endian for words and dwords */
|
||||
*packet = REQUES_PACKET_VER;
|
||||
*((uint8 *)(packet + 1)) = response->status;
|
||||
|
||||
u16 = htons(response->fmt);
|
||||
memcpy(packet + 2, &u16, 2);
|
||||
|
||||
u32 = htonl(response->mid);
|
||||
memcpy(packet + 4, &u32, 4);
|
||||
|
||||
u32 = htonl(response->reciever);
|
||||
memcpy(packet + 8, &u32, 4);
|
||||
|
||||
u32 = htonl(response->payload_len);
|
||||
memcpy(packet + 12, &u32, 4);
|
||||
|
||||
memcpy(packet + RESPONSE_PACKET_FIX_PART_LEN, response->payload,
|
||||
response->payload_len);
|
||||
|
||||
*size = len;
|
||||
return packet;
|
||||
}
|
||||
|
||||
response_t *
|
||||
unpack_response(char *packet, int size, response_t *response)
|
||||
{
|
||||
uint16 u16;
|
||||
uint32 payload_len, u32;
|
||||
|
||||
if (*packet != REQUES_PACKET_VER)
|
||||
return NULL;
|
||||
|
||||
if (size < RESPONSE_PACKET_FIX_PART_LEN)
|
||||
return NULL;
|
||||
|
||||
memcpy(&u32, packet + 12, 4);
|
||||
payload_len = ntohl(u32);
|
||||
if (size != (RESPONSE_PACKET_FIX_PART_LEN + payload_len))
|
||||
return NULL;
|
||||
|
||||
response->status = *((uint8 *)(packet + 1));
|
||||
|
||||
memcpy(&u16, packet + 2, 2);
|
||||
response->fmt = ntohs(u16);
|
||||
|
||||
memcpy(&u32, packet + 4, 4);
|
||||
response->mid = ntohl(u32);
|
||||
|
||||
memcpy(&u32, packet + 8, 4);
|
||||
response->reciever = ntohl(u32);
|
||||
|
||||
response->payload_len = payload_len;
|
||||
if (payload_len > 0)
|
||||
response->payload = packet + RESPONSE_PACKET_FIX_PART_LEN;
|
||||
else
|
||||
response->payload = NULL;
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
request_t *
|
||||
clone_request(request_t *request)
|
||||
{
|
||||
/* deep clone */
|
||||
request_t *req = (request_t *)WA_MALLOC(sizeof(request_t));
|
||||
if (req == NULL)
|
||||
return NULL;
|
||||
|
||||
memset(req, 0, sizeof(*req));
|
||||
req->action = request->action;
|
||||
req->fmt = request->fmt;
|
||||
req->url = wa_strdup(request->url);
|
||||
req->sender = request->sender;
|
||||
req->mid = request->mid;
|
||||
|
||||
if (req->url == NULL)
|
||||
goto fail;
|
||||
|
||||
req->payload_len = request->payload_len;
|
||||
|
||||
if (request->payload_len) {
|
||||
req->payload = (char *)WA_MALLOC(request->payload_len);
|
||||
if (!req->payload)
|
||||
goto fail;
|
||||
memcpy(req->payload, request->payload, request->payload_len);
|
||||
}
|
||||
else {
|
||||
/* when payload_len is 0, the payload may be used for
|
||||
carrying some handle or integer */
|
||||
req->payload = request->payload;
|
||||
}
|
||||
|
||||
return req;
|
||||
|
||||
fail:
|
||||
request_cleaner(req);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
request_cleaner(request_t *request)
|
||||
{
|
||||
if (request->url != NULL)
|
||||
WA_FREE(request->url);
|
||||
if (request->payload != NULL && request->payload_len > 0)
|
||||
WA_FREE(request->payload);
|
||||
|
||||
WA_FREE(request);
|
||||
}
|
||||
|
||||
void
|
||||
response_cleaner(response_t *response)
|
||||
{
|
||||
if (response->payload != NULL && response->payload_len > 0)
|
||||
WA_FREE(response->payload);
|
||||
|
||||
WA_FREE(response);
|
||||
}
|
||||
|
||||
response_t *
|
||||
clone_response(response_t *response)
|
||||
{
|
||||
response_t *clone = (response_t *)WA_MALLOC(sizeof(response_t));
|
||||
|
||||
if (clone == NULL)
|
||||
return NULL;
|
||||
|
||||
memset(clone, 0, sizeof(*clone));
|
||||
clone->fmt = response->fmt;
|
||||
clone->mid = response->mid;
|
||||
clone->status = response->status;
|
||||
clone->reciever = response->reciever;
|
||||
clone->payload_len = response->payload_len;
|
||||
if (clone->payload_len) {
|
||||
clone->payload = (char *)WA_MALLOC(response->payload_len);
|
||||
if (!clone->payload)
|
||||
goto fail;
|
||||
memcpy(clone->payload, response->payload, response->payload_len);
|
||||
}
|
||||
else {
|
||||
/* when payload_len is 0, the payload may be used for
|
||||
carrying some handle or integer */
|
||||
clone->payload = response->payload;
|
||||
}
|
||||
return clone;
|
||||
|
||||
fail:
|
||||
response_cleaner(clone);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
response_t *
|
||||
set_response(response_t *response, int status, int fmt, const char *payload,
|
||||
int payload_len)
|
||||
{
|
||||
response->payload = (void *)payload;
|
||||
response->payload_len = payload_len;
|
||||
response->status = status;
|
||||
response->fmt = fmt;
|
||||
return response;
|
||||
}
|
||||
|
||||
response_t *
|
||||
make_response_for_request(request_t *request, response_t *response)
|
||||
{
|
||||
response->mid = request->mid;
|
||||
response->reciever = request->sender;
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
static unsigned int mid = 0;
|
||||
|
||||
request_t *
|
||||
init_request(request_t *request, char *url, int action, int fmt, void *payload,
|
||||
int payload_len)
|
||||
{
|
||||
request->url = url;
|
||||
request->action = action;
|
||||
request->fmt = fmt;
|
||||
request->payload = payload;
|
||||
request->payload_len = payload_len;
|
||||
request->mid = ++mid;
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
/*
|
||||
check if the "url" is starting with "leading_str"
|
||||
return: 0 - not match; >0 - the offset of matched url, include any "/" at the
|
||||
end notes:
|
||||
1. it ensures the leading_str "/abc" can pass "/abc/cde" and "/abc/, but fail
|
||||
"/ab" and "/abcd". leading_str "/abc/" can pass "/abc"
|
||||
2. it omit the '/' at the first char
|
||||
3. it ensure the leading_str "/abc" can pass "/abc?cde
|
||||
*/
|
||||
|
||||
int
|
||||
check_url_start(const char *url, int url_len, const char *leading_str)
|
||||
{
|
||||
int offset = 0;
|
||||
if (*leading_str == '/')
|
||||
leading_str++;
|
||||
if (url_len > 0 && *url == '/') {
|
||||
url_len--;
|
||||
url++;
|
||||
offset++;
|
||||
}
|
||||
|
||||
int len = strlen(leading_str);
|
||||
if (len == 0)
|
||||
return 0;
|
||||
|
||||
/* ensure leading_str not end with "/" */
|
||||
if (leading_str[len - 1] == '/') {
|
||||
len--;
|
||||
if (len == 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* equal length */
|
||||
if (url_len == len) {
|
||||
if (memcmp(url, leading_str, url_len) == 0) {
|
||||
return (offset + len);
|
||||
}
|
||||
else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (url_len < len)
|
||||
return 0;
|
||||
else if (memcmp(url, leading_str, len) != 0)
|
||||
return 0;
|
||||
else if (url[len] != '/' && url[len] != '?')
|
||||
return 0;
|
||||
else
|
||||
return (offset + len + 1);
|
||||
}
|
||||
|
||||
// * @pattern:
|
||||
// * sample 1: /abcd, match /abcd only
|
||||
// * sample 2: /abcd/ match match "/abcd" and "/abcd/*"
|
||||
// * sample 3: /abcd*, match any url started with "/abcd"
|
||||
// * sample 4: /abcd/*, exclude "/abcd"
|
||||
|
||||
bool
|
||||
match_url(char *pattern, char *matched)
|
||||
{
|
||||
if (*pattern == '/')
|
||||
pattern++;
|
||||
if (*matched == '/')
|
||||
matched++;
|
||||
|
||||
int matched_len = strlen(matched);
|
||||
if (matched_len == 0)
|
||||
return false;
|
||||
|
||||
if (matched[matched_len - 1] == '/') {
|
||||
matched_len--;
|
||||
if (matched_len == 0)
|
||||
return false;
|
||||
}
|
||||
|
||||
int len = strlen(pattern);
|
||||
if (len == 0)
|
||||
return false;
|
||||
|
||||
if (pattern[len - 1] == '/') {
|
||||
len--;
|
||||
if (strncmp(pattern, matched, len) != 0)
|
||||
return false;
|
||||
|
||||
if (len == matched_len)
|
||||
return true;
|
||||
|
||||
if (matched_len > len && matched[len] == '/')
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
else if (pattern[len - 1] == '*') {
|
||||
if (pattern[len - 2] == '/') {
|
||||
if (strncmp(pattern, matched, len - 1) == 0)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
return (strncmp(pattern, matched, len - 1) == 0);
|
||||
}
|
||||
}
|
||||
else {
|
||||
return (strcmp(pattern, matched) == 0);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* get the value of the key from following format buffer:
|
||||
* key1=value1;key2=value2;key3=value3
|
||||
*/
|
||||
char *
|
||||
find_key_value(char *buffer, int buffer_len, char *key, char *value,
|
||||
int value_len, char delimiter)
|
||||
{
|
||||
char *p = buffer;
|
||||
int remaining = buffer_len;
|
||||
int key_len = strlen(key);
|
||||
|
||||
while (*p != 0 && remaining > 0) {
|
||||
while (*p == ' ' || *p == delimiter) {
|
||||
p++;
|
||||
remaining--;
|
||||
}
|
||||
|
||||
if (remaining <= key_len)
|
||||
return NULL;
|
||||
|
||||
/* find the key */
|
||||
if (0 == strncmp(p, key, key_len) && p[key_len] == '=') {
|
||||
p += (key_len + 1);
|
||||
remaining -= (key_len + 1);
|
||||
char *v = value;
|
||||
memset(value, 0, value_len);
|
||||
value_len--; /* ensure last char is 0 */
|
||||
while (*p != delimiter && remaining > 0 && value_len > 0) {
|
||||
*v++ = *p++;
|
||||
remaining--;
|
||||
value_len--;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/* goto next key */
|
||||
while (*p != delimiter && remaining > 0) {
|
||||
p++;
|
||||
remaining--;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
#include "lib_export.h"
|
||||
|
||||
#ifdef APP_FRAMEWORK_SENSOR
|
||||
#include "sensor_native_api.h"
|
||||
#endif
|
||||
|
||||
#ifdef APP_FRAMEWORK_CONNECTION
|
||||
#include "connection_native_api.h"
|
||||
#endif
|
||||
|
||||
#ifdef APP_FRAMEWORK_WGL
|
||||
#include "gui_native_api.h"
|
||||
#endif
|
||||
|
||||
/* More header file here */
|
||||
|
||||
static NativeSymbol extended_native_symbol_defs[] = {
|
||||
#ifdef APP_FRAMEWORK_SENSOR
|
||||
#include "runtime_sensor.inl"
|
||||
#endif
|
||||
|
||||
#ifdef APP_FRAMEWORK_CONNECTION
|
||||
#include "connection.inl"
|
||||
#endif
|
||||
|
||||
#ifdef APP_FRAMEWORK_WGL
|
||||
#include "wamr_gui.inl"
|
||||
#endif
|
||||
|
||||
/* More inl file here */
|
||||
};
|
||||
|
||||
int
|
||||
get_ext_lib_export_apis(NativeSymbol **p_ext_lib_apis)
|
||||
{
|
||||
*p_ext_lib_apis = extended_native_symbol_defs;
|
||||
return sizeof(extended_native_symbol_defs) / sizeof(NativeSymbol);
|
||||
}
|
|
@ -1,93 +0,0 @@
|
|||
# Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
|
||||
add_definitions (-DWASM_ENABLE_APP_FRAMEWORK=1)
|
||||
|
||||
set (APP_FRAMEWORK_ROOT_DIR ${CMAKE_CURRENT_LIST_DIR})
|
||||
|
||||
if ( NOT DEFINED APP_FRAMEWORK_INCLUDE_TYPE )
|
||||
LIST (APPEND WASM_APP_LIB_SOURCE_ALL ${CMAKE_CURRENT_LIST_DIR}/app_ext_lib_export.c)
|
||||
endif()
|
||||
|
||||
# app-native-shared and base are required
|
||||
include (${APP_FRAMEWORK_ROOT_DIR}/app-native-shared/native_interface.cmake)
|
||||
LIST (APPEND WASM_APP_SOURCE_ALL ${NATIVE_INTERFACE_SOURCE})
|
||||
|
||||
MACRO(SUBDIRLIST result curdir)
|
||||
FILE(GLOB children RELATIVE ${curdir} ${curdir}/*)
|
||||
SET(dirlist "")
|
||||
FOREACH(child ${children})
|
||||
IF(IS_DIRECTORY ${curdir}/${child})
|
||||
LIST(APPEND dirlist ${child})
|
||||
ENDIF()
|
||||
ENDFOREACH()
|
||||
SET(${result} ${dirlist})
|
||||
ENDMACRO()
|
||||
|
||||
function (add_module_native arg)
|
||||
message ("Add native module ${ARGV0}")
|
||||
include (${APP_FRAMEWORK_ROOT_DIR}/${ARGV0}/native/wasm_lib.cmake)
|
||||
|
||||
file (GLOB header
|
||||
${APP_FRAMEWORK_ROOT_DIR}/${ARGV0}/native/*.h
|
||||
${APP_FRAMEWORK_ROOT_DIR}/${ARGV0}/native/*.inl
|
||||
)
|
||||
|
||||
LIST (APPEND WASM_APP_LIBS_DIR ${APP_FRAMEWORK_ROOT_DIR}/${ARGV0}/native)
|
||||
set (WASM_APP_LIBS_DIR ${WASM_APP_LIBS_DIR} PARENT_SCOPE)
|
||||
|
||||
LIST (APPEND RUNTIME_LIB_HEADER_LIST ${header})
|
||||
set (RUNTIME_LIB_HEADER_LIST ${RUNTIME_LIB_HEADER_LIST} PARENT_SCOPE)
|
||||
|
||||
LIST (APPEND WASM_APP_LIB_SOURCE_ALL ${WASM_APP_LIB_CURRENT_SOURCE})
|
||||
set (WASM_APP_LIB_SOURCE_ALL ${WASM_APP_LIB_SOURCE_ALL} PARENT_SCOPE)
|
||||
endfunction ()
|
||||
|
||||
function (add_module_app arg)
|
||||
message ("Add app module ${ARGV0}")
|
||||
include (${APP_FRAMEWORK_ROOT_DIR}/${ARGV0}/app/wasm_app.cmake)
|
||||
|
||||
LIST (APPEND WASM_APP_WA_INC_DIR_LIST "${APP_FRAMEWORK_ROOT_DIR}/${ARGV0}/app/wa-inc")
|
||||
set (WASM_APP_WA_INC_DIR_LIST ${WASM_APP_WA_INC_DIR_LIST} PARENT_SCOPE)
|
||||
|
||||
LIST (APPEND WASM_APP_NAME ${ARGV0})
|
||||
set (WASM_APP_NAME ${WASM_APP_NAME} PARENT_SCOPE)
|
||||
|
||||
LIST (APPEND WASM_APP_SOURCE_ALL ${WASM_APP_CURRENT_SOURCE})
|
||||
set (WASM_APP_SOURCE_ALL ${WASM_APP_SOURCE_ALL} PARENT_SCOPE)
|
||||
endfunction ()
|
||||
|
||||
if ("${WAMR_BUILD_APP_LIST}" STREQUAL "WAMR_APP_BUILD_ALL")
|
||||
# add all modules under this folder
|
||||
SUBDIRLIST(SUBDIRS ${APP_FRAMEWORK_ROOT_DIR})
|
||||
|
||||
FOREACH(subdir ${SUBDIRS})
|
||||
if ("${subdir}" STREQUAL "app-native-shared")
|
||||
continue()
|
||||
endif ()
|
||||
if ("${subdir}" STREQUAL "template")
|
||||
continue()
|
||||
endif ()
|
||||
|
||||
if ( NOT DEFINED APP_FRAMEWORK_INCLUDE_TYPE )
|
||||
add_module_native (${subdir})
|
||||
else ()
|
||||
add_module_app (${subdir})
|
||||
endif ()
|
||||
ENDFOREACH()
|
||||
|
||||
else ()
|
||||
# add each module in the list
|
||||
FOREACH (dir IN LISTS WAMR_BUILD_APP_LIST)
|
||||
string(REPLACE "WAMR_APP_BUILD_" "" dir ${dir})
|
||||
string(TOLOWER ${dir} dir)
|
||||
|
||||
if ( NOT DEFINED APP_FRAMEWORK_INCLUDE_TYPE )
|
||||
add_module_native (${dir})
|
||||
else ()
|
||||
add_module_app (${dir})
|
||||
endif ()
|
||||
ENDFOREACH (dir)
|
||||
|
||||
endif()
|
|
@ -1,89 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#include "bh_platform.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/*
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
static bool
|
||||
is_little_endian()
|
||||
{
|
||||
long i = 0x01020304;
|
||||
unsigned char *c = (unsigned char *)&i;
|
||||
return (*c == 0x04) ? true : false;
|
||||
}
|
||||
|
||||
static void
|
||||
swap32(uint8 *pData)
|
||||
{
|
||||
uint8 value = *pData;
|
||||
*pData = *(pData + 3);
|
||||
*(pData + 3) = value;
|
||||
|
||||
value = *(pData + 1);
|
||||
*(pData + 1) = *(pData + 2);
|
||||
*(pData + 2) = value;
|
||||
}
|
||||
|
||||
static void
|
||||
swap16(uint8 *pData)
|
||||
{
|
||||
uint8 value = *pData;
|
||||
*(pData) = *(pData + 1);
|
||||
*(pData + 1) = value;
|
||||
}
|
||||
|
||||
uint32
|
||||
htonl(uint32 value)
|
||||
{
|
||||
uint32 ret;
|
||||
if (is_little_endian()) {
|
||||
ret = value;
|
||||
swap32((uint8 *)&ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
uint32
|
||||
ntohl(uint32 value)
|
||||
{
|
||||
return htonl(value);
|
||||
}
|
||||
|
||||
uint16
|
||||
htons(uint16 value)
|
||||
{
|
||||
uint16 ret;
|
||||
if (is_little_endian()) {
|
||||
ret = value;
|
||||
swap16((uint8 *)&ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
uint16
|
||||
ntohs(uint16 value)
|
||||
{
|
||||
return htons(value);
|
||||
}
|
||||
|
||||
char *
|
||||
wa_strdup(const char *s)
|
||||
{
|
||||
char *s1 = NULL;
|
||||
if (s && (s1 = WA_MALLOC(strlen(s) + 1)))
|
||||
memcpy(s1, s, strlen(s) + 1);
|
||||
return s1;
|
||||
}
|
|
@ -1,65 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#ifndef DEPS_IWASM_APP_LIBS_BASE_BH_PLATFORM_H_
|
||||
#define DEPS_IWASM_APP_LIBS_BASE_BH_PLATFORM_H_
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
typedef unsigned char uint8;
|
||||
typedef char int8;
|
||||
typedef unsigned short uint16;
|
||||
typedef short int16;
|
||||
typedef unsigned int uint32;
|
||||
typedef int int32;
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL ((void *)0)
|
||||
#endif
|
||||
|
||||
#ifndef __cplusplus
|
||||
#define true 1
|
||||
#define false 0
|
||||
#define inline __inline
|
||||
#endif
|
||||
|
||||
// all wasm-app<->native shared source files should use WA_MALLOC/WA_FREE.
|
||||
// they will be mapped to different implementations in each side
|
||||
#ifndef WA_MALLOC
|
||||
#define WA_MALLOC malloc
|
||||
#endif
|
||||
|
||||
#ifndef WA_FREE
|
||||
#define WA_FREE free
|
||||
#endif
|
||||
|
||||
uint32
|
||||
htonl(uint32 value);
|
||||
uint32
|
||||
ntohl(uint32 value);
|
||||
uint16
|
||||
htons(uint16 value);
|
||||
uint16
|
||||
ntohs(uint16 value);
|
||||
|
||||
// We are not worried for the WASM world since the sandbox will catch it.
|
||||
#define bh_memcpy_s(dst, dst_len, src, src_len) memcpy(dst, src, src_len)
|
||||
|
||||
#ifdef NDEBUG
|
||||
#define bh_assert(v) (void)0
|
||||
#else
|
||||
#define bh_assert(v) \
|
||||
do { \
|
||||
if (!(v)) { \
|
||||
int _count; \
|
||||
printf("ASSERTION FAILED: %s, at %s, line %d", #v, __FILE__, \
|
||||
__LINE__); \
|
||||
_count = printf("\n"); \
|
||||
printf("%d\n", _count / (_count - 1)); \
|
||||
} \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#endif /* DEPS_IWASM_APP_LIBS_BASE_BH_PLATFORM_H_ */
|
|
@ -1,31 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#ifndef _REQ_RESP_API_H_
|
||||
#define _REQ_RESP_API_H_
|
||||
|
||||
#include "bh_platform.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
bool
|
||||
wasm_response_send(const char *buf, int size);
|
||||
|
||||
void
|
||||
wasm_register_resource(const char *url);
|
||||
|
||||
void
|
||||
wasm_post_request(const char *buf, int size);
|
||||
|
||||
void
|
||||
wasm_sub_event(const char *url);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* end of _REQ_RESP_API_H_ */
|
|
@ -1,365 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#include "bi-inc/attr_container.h"
|
||||
#include "wa-inc/request.h"
|
||||
#include "wa-inc/timer_wasm_app.h"
|
||||
#include "bi-inc/shared_utils.h"
|
||||
#include "wasm_app.h"
|
||||
#include "req_resp_api.h"
|
||||
#include "timer_api.h"
|
||||
|
||||
#define TRANSACTION_TIMEOUT_MS 5000
|
||||
|
||||
typedef enum { Reg_Event, Reg_Request } reg_type_t;
|
||||
|
||||
typedef struct _res_register {
|
||||
struct _res_register *next;
|
||||
const char *url;
|
||||
reg_type_t reg_type;
|
||||
void (*request_handler)(request_t *);
|
||||
} res_register_t;
|
||||
|
||||
typedef struct transaction {
|
||||
struct transaction *next;
|
||||
int mid;
|
||||
unsigned int time; /* start time */
|
||||
response_handler_f handler;
|
||||
void *user_data;
|
||||
} transaction_t;
|
||||
|
||||
static res_register_t *g_resources = NULL;
|
||||
|
||||
static transaction_t *g_transactions = NULL;
|
||||
|
||||
static user_timer_t g_trans_timer = NULL;
|
||||
|
||||
static transaction_t *
|
||||
transaction_find(int mid)
|
||||
{
|
||||
transaction_t *t = g_transactions;
|
||||
|
||||
while (t) {
|
||||
if (t->mid == mid)
|
||||
return t;
|
||||
t = t->next;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* new transaction is added to the tail of the list, so the list
|
||||
* is sorted by expiry time naturally.
|
||||
*/
|
||||
static void
|
||||
transaction_add(transaction_t *trans)
|
||||
{
|
||||
transaction_t *t;
|
||||
|
||||
if (g_transactions == NULL) {
|
||||
g_transactions = trans;
|
||||
return;
|
||||
}
|
||||
|
||||
t = g_transactions;
|
||||
while (t) {
|
||||
if (t->next == NULL) {
|
||||
t->next = trans;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
transaction_remove(transaction_t *trans)
|
||||
{
|
||||
transaction_t *prev = NULL, *current = g_transactions;
|
||||
|
||||
while (current) {
|
||||
if (current == trans) {
|
||||
if (prev == NULL) {
|
||||
g_transactions = current->next;
|
||||
free(current);
|
||||
return;
|
||||
}
|
||||
prev->next = current->next;
|
||||
free(current);
|
||||
return;
|
||||
}
|
||||
prev = current;
|
||||
current = current->next;
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
is_event_type(request_t *req)
|
||||
{
|
||||
return req->action == COAP_EVENT;
|
||||
}
|
||||
|
||||
static bool
|
||||
register_url_handler(const char *url, request_handler_f request_handler,
|
||||
reg_type_t reg_type)
|
||||
{
|
||||
res_register_t *r = g_resources;
|
||||
|
||||
while (r) {
|
||||
if (reg_type == r->reg_type && strcmp(r->url, url) == 0) {
|
||||
r->request_handler = request_handler;
|
||||
return true;
|
||||
}
|
||||
r = r->next;
|
||||
}
|
||||
|
||||
r = (res_register_t *)malloc(sizeof(res_register_t));
|
||||
if (r == NULL)
|
||||
return false;
|
||||
|
||||
memset(r, 0, sizeof(*r));
|
||||
|
||||
r->url = strdup(url);
|
||||
if (!r->url) {
|
||||
free(r);
|
||||
return false;
|
||||
}
|
||||
|
||||
r->request_handler = request_handler;
|
||||
r->reg_type = reg_type;
|
||||
r->next = g_resources;
|
||||
g_resources = r;
|
||||
|
||||
// tell app mgr to route this url to me
|
||||
if (reg_type == Reg_Request)
|
||||
wasm_register_resource(url);
|
||||
else
|
||||
wasm_sub_event(url);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
api_register_resource_handler(const char *url,
|
||||
request_handler_f request_handler)
|
||||
{
|
||||
return register_url_handler(url, request_handler, Reg_Request);
|
||||
}
|
||||
|
||||
static void
|
||||
transaction_timeout_handler(user_timer_t timer)
|
||||
{
|
||||
transaction_t *cur, *expired = NULL;
|
||||
unsigned int elpased_ms, now = wasm_get_sys_tick_ms();
|
||||
|
||||
/*
|
||||
* Since he transaction list is sorted by expiry time naturally,
|
||||
* we can easily get all expired transactions.
|
||||
* */
|
||||
cur = g_transactions;
|
||||
while (cur) {
|
||||
if (now < cur->time)
|
||||
elpased_ms = now + (0xFFFFFFFF - cur->time) + 1;
|
||||
else
|
||||
elpased_ms = now - cur->time;
|
||||
|
||||
if (elpased_ms >= TRANSACTION_TIMEOUT_MS) {
|
||||
g_transactions = cur->next;
|
||||
cur->next = expired;
|
||||
expired = cur;
|
||||
cur = g_transactions;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* call each transaction's handler with response set to NULL */
|
||||
cur = expired;
|
||||
while (cur) {
|
||||
transaction_t *tmp = cur;
|
||||
cur->handler(NULL, cur->user_data);
|
||||
cur = cur->next;
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
/*
|
||||
* If the transaction list is not empty, restart the timer according
|
||||
* to the first transaction. Otherwise, stop the timer.
|
||||
*/
|
||||
if (g_transactions != NULL) {
|
||||
unsigned int elpased_ms, ms_to_expiry, now = wasm_get_sys_tick_ms();
|
||||
if (now < g_transactions->time) {
|
||||
elpased_ms = now + (0xFFFFFFFF - g_transactions->time) + 1;
|
||||
}
|
||||
else {
|
||||
elpased_ms = now - g_transactions->time;
|
||||
}
|
||||
ms_to_expiry = TRANSACTION_TIMEOUT_MS - elpased_ms;
|
||||
api_timer_restart(g_trans_timer, ms_to_expiry);
|
||||
}
|
||||
else {
|
||||
api_timer_cancel(g_trans_timer);
|
||||
g_trans_timer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
api_send_request(request_t *request, response_handler_f response_handler,
|
||||
void *user_data)
|
||||
{
|
||||
int size;
|
||||
char *buffer;
|
||||
transaction_t *trans;
|
||||
|
||||
if ((trans = (transaction_t *)malloc(sizeof(transaction_t))) == NULL) {
|
||||
printf(
|
||||
"send request: allocate memory for request transaction failed!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
memset(trans, 0, sizeof(transaction_t));
|
||||
trans->handler = response_handler;
|
||||
trans->mid = request->mid;
|
||||
trans->time = wasm_get_sys_tick_ms();
|
||||
trans->user_data = user_data;
|
||||
|
||||
if ((buffer = pack_request(request, &size)) == NULL) {
|
||||
printf("send request: pack request failed!\n");
|
||||
free(trans);
|
||||
return;
|
||||
}
|
||||
|
||||
transaction_add(trans);
|
||||
|
||||
/* if the trans is the 1st one, start the timer */
|
||||
if (trans == g_transactions) {
|
||||
/* assert(g_trans_timer == NULL); */
|
||||
if (g_trans_timer == NULL) {
|
||||
g_trans_timer = api_timer_create(TRANSACTION_TIMEOUT_MS, false,
|
||||
true, transaction_timeout_handler);
|
||||
}
|
||||
}
|
||||
|
||||
wasm_post_request(buffer, size);
|
||||
|
||||
free_req_resp_packet(buffer);
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* APIs for the native layers to callback for request/response arrived to this
|
||||
* app
|
||||
*
|
||||
*/
|
||||
|
||||
void
|
||||
on_response(char *buffer, int size)
|
||||
{
|
||||
response_t response[1];
|
||||
transaction_t *trans;
|
||||
|
||||
if (NULL == unpack_response(buffer, size, response)) {
|
||||
printf("unpack response failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if ((trans = transaction_find(response->mid)) == NULL) {
|
||||
printf("cannot find the transaction\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* When the 1st transaction get response:
|
||||
* 1. If the 2nd trans exist, restart the timer according to its expiry
|
||||
* time;
|
||||
* 2. Otherwise, stop the timer since there is no more transactions;
|
||||
*/
|
||||
if (trans == g_transactions) {
|
||||
if (trans->next != NULL) {
|
||||
unsigned int elpased_ms, ms_to_expiry, now = wasm_get_sys_tick_ms();
|
||||
if (now < trans->next->time) {
|
||||
elpased_ms = now + (0xFFFFFFFF - trans->next->time) + 1;
|
||||
}
|
||||
else {
|
||||
elpased_ms = now - trans->next->time;
|
||||
}
|
||||
ms_to_expiry = TRANSACTION_TIMEOUT_MS - elpased_ms;
|
||||
api_timer_restart(g_trans_timer, ms_to_expiry);
|
||||
}
|
||||
else {
|
||||
api_timer_cancel(g_trans_timer);
|
||||
g_trans_timer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
trans->handler(response, trans->user_data);
|
||||
transaction_remove(trans);
|
||||
}
|
||||
|
||||
void
|
||||
on_request(char *buffer, int size)
|
||||
{
|
||||
request_t request[1];
|
||||
bool is_event;
|
||||
res_register_t *r = g_resources;
|
||||
|
||||
if (NULL == unpack_request(buffer, size, request)) {
|
||||
printf("unpack request failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
is_event = is_event_type(request);
|
||||
|
||||
while (r) {
|
||||
if ((is_event && r->reg_type == Reg_Event)
|
||||
|| (!is_event && r->reg_type == Reg_Request)) {
|
||||
if (check_url_start(request->url, strlen(request->url), r->url)
|
||||
> 0) {
|
||||
r->request_handler(request);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
r = r->next;
|
||||
}
|
||||
|
||||
printf("on_request: exit. no service handler\n");
|
||||
}
|
||||
|
||||
void
|
||||
api_response_send(response_t *response)
|
||||
{
|
||||
int size;
|
||||
char *buffer = pack_response(response, &size);
|
||||
if (buffer == NULL)
|
||||
return;
|
||||
|
||||
wasm_response_send(buffer, size);
|
||||
free_req_resp_packet(buffer);
|
||||
}
|
||||
|
||||
/// event api
|
||||
|
||||
bool
|
||||
api_publish_event(const char *url, int fmt, void *payload, int payload_len)
|
||||
{
|
||||
int size;
|
||||
request_t request[1];
|
||||
init_request(request, (char *)url, COAP_EVENT, fmt, payload, payload_len);
|
||||
char *buffer = pack_request(request, &size);
|
||||
if (buffer == NULL)
|
||||
return false;
|
||||
wasm_post_request(buffer, size);
|
||||
|
||||
free_req_resp_packet(buffer);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
api_subscribe_event(const char *url, request_handler_f handler)
|
||||
{
|
||||
return register_url_handler(url, handler, Reg_Event);
|
||||
}
|
|
@ -1,100 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "wa-inc/timer_wasm_app.h"
|
||||
#include "timer_api.h"
|
||||
|
||||
#if 1
|
||||
#include <stdio.h>
|
||||
#else
|
||||
#define printf (...)
|
||||
#endif
|
||||
|
||||
struct user_timer {
|
||||
struct user_timer *next;
|
||||
int timer_id;
|
||||
void (*user_timer_callback)(user_timer_t);
|
||||
};
|
||||
|
||||
struct user_timer *g_timers = NULL;
|
||||
|
||||
user_timer_t
|
||||
api_timer_create(int interval, bool is_period, bool auto_start,
|
||||
on_user_timer_update_f on_timer_update)
|
||||
{
|
||||
|
||||
int timer_id = wasm_create_timer(interval, is_period, auto_start);
|
||||
|
||||
// TODO
|
||||
struct user_timer *timer =
|
||||
(struct user_timer *)malloc(sizeof(struct user_timer));
|
||||
if (timer == NULL) {
|
||||
// TODO: remove the timer_id
|
||||
printf("### api_timer_create malloc faild!!! \n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(timer, 0, sizeof(*timer));
|
||||
timer->timer_id = timer_id;
|
||||
timer->user_timer_callback = on_timer_update;
|
||||
|
||||
if (g_timers == NULL)
|
||||
g_timers = timer;
|
||||
else {
|
||||
timer->next = g_timers;
|
||||
g_timers = timer;
|
||||
}
|
||||
|
||||
return timer;
|
||||
}
|
||||
|
||||
void
|
||||
api_timer_cancel(user_timer_t timer)
|
||||
{
|
||||
user_timer_t t = g_timers, prev = NULL;
|
||||
|
||||
wasm_timer_cancel(timer->timer_id);
|
||||
|
||||
while (t) {
|
||||
if (t == timer) {
|
||||
if (prev == NULL) {
|
||||
g_timers = t->next;
|
||||
free(t);
|
||||
}
|
||||
else {
|
||||
prev->next = t->next;
|
||||
free(t);
|
||||
}
|
||||
return;
|
||||
}
|
||||
else {
|
||||
prev = t;
|
||||
t = t->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
api_timer_restart(user_timer_t timer, int interval)
|
||||
{
|
||||
wasm_timer_restart(timer->timer_id, interval);
|
||||
}
|
||||
|
||||
void
|
||||
on_timer_callback(int timer_id)
|
||||
{
|
||||
struct user_timer *t = g_timers;
|
||||
|
||||
while (t) {
|
||||
if (t->timer_id == timer_id) {
|
||||
t->user_timer_callback(t);
|
||||
break;
|
||||
}
|
||||
t = t->next;
|
||||
}
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#ifndef _TIMER_API_H_
|
||||
#define _TIMER_API_H_
|
||||
|
||||
#include "bh_platform.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef unsigned int timer_id_t;
|
||||
|
||||
timer_id_t
|
||||
wasm_create_timer(int interval, bool is_period, bool auto_start);
|
||||
|
||||
void
|
||||
wasm_timer_destroy(timer_id_t timer_id);
|
||||
|
||||
void
|
||||
wasm_timer_cancel(timer_id_t timer_id);
|
||||
|
||||
void
|
||||
wasm_timer_restart(timer_id_t timer_id, int interval);
|
||||
|
||||
uint32
|
||||
wasm_get_sys_tick_ms(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* end of _TIMER_API_H_ */
|
|
@ -1,171 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#ifndef _AEE_REQUEST_H_
|
||||
#define _AEE_REQUEST_H_
|
||||
|
||||
#include "bi-inc/shared_utils.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* CoAP request method codes */
|
||||
typedef enum {
|
||||
COAP_GET = 1,
|
||||
COAP_POST,
|
||||
COAP_PUT,
|
||||
COAP_DELETE,
|
||||
COAP_EVENT = (COAP_DELETE + 2)
|
||||
} coap_method_t;
|
||||
|
||||
/* CoAP response codes */
|
||||
typedef enum {
|
||||
NO_ERROR = 0,
|
||||
|
||||
CREATED_2_01 = 65, /* CREATED */
|
||||
DELETED_2_02 = 66, /* DELETED */
|
||||
VALID_2_03 = 67, /* NOT_MODIFIED */
|
||||
CHANGED_2_04 = 68, /* CHANGED */
|
||||
CONTENT_2_05 = 69, /* OK */
|
||||
CONTINUE_2_31 = 95, /* CONTINUE */
|
||||
|
||||
BAD_REQUEST_4_00 = 128, /* BAD_REQUEST */
|
||||
UNAUTHORIZED_4_01 = 129, /* UNAUTHORIZED */
|
||||
BAD_OPTION_4_02 = 130, /* BAD_OPTION */
|
||||
FORBIDDEN_4_03 = 131, /* FORBIDDEN */
|
||||
NOT_FOUND_4_04 = 132, /* NOT_FOUND */
|
||||
METHOD_NOT_ALLOWED_4_05 = 133, /* METHOD_NOT_ALLOWED */
|
||||
NOT_ACCEPTABLE_4_06 = 134, /* NOT_ACCEPTABLE */
|
||||
PRECONDITION_FAILED_4_12 = 140, /* BAD_REQUEST */
|
||||
REQUEST_ENTITY_TOO_LARGE_4_13 = 141, /* REQUEST_ENTITY_TOO_LARGE */
|
||||
UNSUPPORTED_MEDIA_TYPE_4_15 = 143, /* UNSUPPORTED_MEDIA_TYPE */
|
||||
|
||||
INTERNAL_SERVER_ERROR_5_00 = 160, /* INTERNAL_SERVER_ERROR */
|
||||
NOT_IMPLEMENTED_5_01 = 161, /* NOT_IMPLEMENTED */
|
||||
BAD_GATEWAY_5_02 = 162, /* BAD_GATEWAY */
|
||||
SERVICE_UNAVAILABLE_5_03 = 163, /* SERVICE_UNAVAILABLE */
|
||||
GATEWAY_TIMEOUT_5_04 = 164, /* GATEWAY_TIMEOUT */
|
||||
PROXYING_NOT_SUPPORTED_5_05 = 165, /* PROXYING_NOT_SUPPORTED */
|
||||
|
||||
/* Erbium errors */
|
||||
MEMORY_ALLOCATION_ERROR = 192,
|
||||
PACKET_SERIALIZATION_ERROR,
|
||||
|
||||
/* Erbium hooks */
|
||||
MANUAL_RESPONSE,
|
||||
PING_RESPONSE
|
||||
} coap_status_t;
|
||||
|
||||
/**
|
||||
* @typedef request_handler_f
|
||||
*
|
||||
* @brief Define the signature of callback function for API
|
||||
* api_register_resource_handler() to handle request or for API
|
||||
* api_subscribe_event() to handle event.
|
||||
*
|
||||
* @param request pointer of the request to be handled
|
||||
*
|
||||
* @see api_register_resource_handler
|
||||
* @see api_subscribe_event
|
||||
*/
|
||||
typedef void (*request_handler_f)(request_t *request);
|
||||
|
||||
/**
|
||||
* @typedef response_handler_f
|
||||
*
|
||||
* @brief Define the signature of callback function for API
|
||||
* api_send_request() to handle response of a request.
|
||||
*
|
||||
* @param response pointer of the response to be handled
|
||||
* @param user_data user data associated with the request which is set when
|
||||
* calling api_send_request().
|
||||
*
|
||||
* @see api_send_request
|
||||
*/
|
||||
typedef void (*response_handler_f)(response_t *response, void *user_data);
|
||||
|
||||
/*
|
||||
*****************
|
||||
* Request APIs
|
||||
*****************
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Register resource.
|
||||
*
|
||||
* @param url url of the resource
|
||||
* @param handler callback function to handle the request to the resource
|
||||
*
|
||||
* @return true if success, false otherwise
|
||||
*/
|
||||
bool
|
||||
api_register_resource_handler(const char *url, request_handler_f handler);
|
||||
|
||||
/**
|
||||
* @brief Send request asynchronously.
|
||||
*
|
||||
* @param request pointer of the request to be sent
|
||||
* @param response_handler callback function to handle the response
|
||||
* @param user_data user data
|
||||
*/
|
||||
void
|
||||
api_send_request(request_t *request, response_handler_f response_handler,
|
||||
void *user_data);
|
||||
|
||||
/**
|
||||
* @brief Send response.
|
||||
*
|
||||
* @param response pointer of the response to be sent
|
||||
*
|
||||
* @par
|
||||
* @code
|
||||
* void res1_handler(request_t *request)
|
||||
* {
|
||||
* response_t response[1];
|
||||
* make_response_for_request(request, response);
|
||||
* set_response(response, DELETED_2_02, 0, NULL, 0);
|
||||
* api_response_send(response);
|
||||
* }
|
||||
* @endcode
|
||||
*/
|
||||
void
|
||||
api_response_send(response_t *response);
|
||||
|
||||
/*
|
||||
*****************
|
||||
* Event APIs
|
||||
*****************
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Publish an event.
|
||||
*
|
||||
* @param url url of the event
|
||||
* @param fmt format of the event payload
|
||||
* @param payload payload of the event
|
||||
* @param payload_len length in bytes of the event payload
|
||||
*
|
||||
* @return true if success, false otherwise
|
||||
*/
|
||||
bool
|
||||
api_publish_event(const char *url, int fmt, void *payload, int payload_len);
|
||||
|
||||
/**
|
||||
* @brief Subscribe an event.
|
||||
*
|
||||
* @param url url of the event
|
||||
* @param handler callback function to handle the event.
|
||||
*
|
||||
* @return true if success, false otherwise
|
||||
*/
|
||||
bool
|
||||
api_subscribe_event(const char *url, request_handler_f handler);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,71 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#ifndef _AEE_TIMER_H_
|
||||
#define _AEE_TIMER_H_
|
||||
|
||||
#include "bh_platform.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* board producer define user_timer */
|
||||
struct user_timer;
|
||||
typedef struct user_timer *user_timer_t;
|
||||
|
||||
/**
|
||||
* @typedef on_user_timer_update_f
|
||||
*
|
||||
* @brief Define the signature of callback function for API api_timer_create().
|
||||
*
|
||||
* @param timer the timer
|
||||
*
|
||||
* @see api_timer_create
|
||||
*/
|
||||
typedef void (*on_user_timer_update_f)(user_timer_t timer);
|
||||
|
||||
/*
|
||||
*****************
|
||||
* Timer APIs
|
||||
*****************
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Create timer.
|
||||
*
|
||||
* @param interval timer interval
|
||||
* @param is_period whether the timer is periodic
|
||||
* @param auto_start whether start the timer immediately after created
|
||||
* @param on_timer_update callback function called when timer expired
|
||||
*
|
||||
* @return the timer created if success, NULL otherwise
|
||||
*/
|
||||
user_timer_t
|
||||
api_timer_create(int interval, bool is_period, bool auto_start,
|
||||
on_user_timer_update_f on_timer_update);
|
||||
|
||||
/**
|
||||
* @brief Cancel timer.
|
||||
*
|
||||
* @param timer the timer to cancel
|
||||
*/
|
||||
void
|
||||
api_timer_cancel(user_timer_t timer);
|
||||
|
||||
/**
|
||||
* @brief Restart timer.
|
||||
*
|
||||
* @param timer the timer to cancel
|
||||
* @param interval the timer interval
|
||||
*/
|
||||
void
|
||||
api_timer_restart(user_timer_t timer, int interval);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,13 +0,0 @@
|
|||
# Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
set (WASM_APP_BASE_DIR ${CMAKE_CURRENT_LIST_DIR})
|
||||
|
||||
include_directories(${WASM_APP_BASE_DIR})
|
||||
|
||||
add_definitions (-DWASM_ENABLE_BASE_LIB)
|
||||
|
||||
file (GLOB_RECURSE source_all ${WASM_APP_BASE_DIR}/*.c)
|
||||
|
||||
set (WASM_APP_CURRENT_SOURCE ${source_all})
|
||||
set (WASM_APP_BASE_DIR ${WASM_APP_BASE_DIR} PARENT_SCOPE)
|
|
@ -1,20 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#ifndef _LIB_AEE_H_
|
||||
#define _LIB_AEE_H_
|
||||
|
||||
#include "bi-inc/shared_utils.h"
|
||||
#include "bi-inc/attr_container.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* end of _LIB_AEE_H_ */
|
|
@ -1,14 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
EXPORT_WASM_API_WITH_SIG(wasm_register_resource, "($)"),
|
||||
EXPORT_WASM_API_WITH_SIG(wasm_response_send, "(*~)i"),
|
||||
EXPORT_WASM_API_WITH_SIG(wasm_post_request, "(*~)"),
|
||||
EXPORT_WASM_API_WITH_SIG(wasm_sub_event, "($)"),
|
||||
EXPORT_WASM_API_WITH_SIG(wasm_create_timer, "(iii)i"),
|
||||
EXPORT_WASM_API_WITH_SIG(wasm_timer_destroy, "(i)"),
|
||||
EXPORT_WASM_API_WITH_SIG(wasm_timer_cancel, "(i)"),
|
||||
EXPORT_WASM_API_WITH_SIG(wasm_timer_restart, "(ii)"),
|
||||
EXPORT_WASM_API_WITH_SIG(wasm_get_sys_tick_ms, "()i"),
|
|
@ -1,24 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "lib_export.h"
|
||||
#include "req_resp_native_api.h"
|
||||
#include "timer_native_api.h"
|
||||
|
||||
static NativeSymbol extended_native_symbol_defs[] = {
|
||||
/* TODO: use macro EXPORT_WASM_API() or EXPORT_WASM_API2() to
|
||||
add functions to register. */
|
||||
#include "base_lib.inl"
|
||||
};
|
||||
|
||||
uint32
|
||||
get_base_lib_export_apis(NativeSymbol **p_base_lib_apis)
|
||||
{
|
||||
*p_base_lib_apis = extended_native_symbol_defs;
|
||||
return sizeof(extended_native_symbol_defs) / sizeof(NativeSymbol);
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#ifndef _REQ_RESP_API_H_
|
||||
#define _REQ_RESP_API_H_
|
||||
|
||||
#include "bh_platform.h"
|
||||
#include "wasm_export.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
bool
|
||||
wasm_response_send(wasm_exec_env_t exec_env, char *buffer, int size);
|
||||
void
|
||||
wasm_register_resource(wasm_exec_env_t exec_env, char *url);
|
||||
void
|
||||
wasm_post_request(wasm_exec_env_t exec_env, char *buffer, int size);
|
||||
void
|
||||
wasm_sub_event(wasm_exec_env_t exec_env, char *url);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* end of _REQ_RESP_API_H_ */
|
|
@ -1,84 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#include "app_manager_export.h"
|
||||
#include "coap_ext.h"
|
||||
#include "wasm_export.h"
|
||||
#include "bh_assert.h"
|
||||
|
||||
extern void
|
||||
module_request_handler(request_t *request, void *user_data);
|
||||
|
||||
bool
|
||||
wasm_response_send(wasm_exec_env_t exec_env, char *buffer, int size)
|
||||
{
|
||||
if (buffer != NULL) {
|
||||
response_t response[1];
|
||||
|
||||
if (NULL == unpack_response(buffer, size, response))
|
||||
return false;
|
||||
|
||||
am_send_response(response);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
wasm_register_resource(wasm_exec_env_t exec_env, char *url)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
|
||||
if (url != NULL) {
|
||||
unsigned int mod_id =
|
||||
app_manager_get_module_id(Module_WASM_App, module_inst);
|
||||
bh_assert(mod_id != ID_NONE);
|
||||
am_register_resource(url, module_request_handler, mod_id);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
wasm_post_request(wasm_exec_env_t exec_env, char *buffer, int size)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
|
||||
if (buffer != NULL) {
|
||||
request_t req[1];
|
||||
|
||||
if (!unpack_request(buffer, size, req))
|
||||
return;
|
||||
|
||||
// TODO: add permission check, ensure app can't do harm
|
||||
|
||||
// set sender to help dispatch the response to the sender ap
|
||||
unsigned int mod_id =
|
||||
app_manager_get_module_id(Module_WASM_App, module_inst);
|
||||
bh_assert(mod_id != ID_NONE);
|
||||
req->sender = mod_id;
|
||||
|
||||
if (req->action == COAP_EVENT) {
|
||||
am_publish_event(req);
|
||||
return;
|
||||
}
|
||||
|
||||
am_dispatch_request(req);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
wasm_sub_event(wasm_exec_env_t exec_env, char *url)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
|
||||
if (url != NULL) {
|
||||
unsigned int mod_id =
|
||||
app_manager_get_module_id(Module_WASM_App, module_inst);
|
||||
|
||||
bh_assert(mod_id != ID_NONE);
|
||||
am_register_event(url, mod_id);
|
||||
}
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#ifndef LIB_BASE_RUNTIME_LIB_H_
|
||||
#define LIB_BASE_RUNTIME_LIB_H_
|
||||
|
||||
#include "runtime_timer.h"
|
||||
|
||||
bool
|
||||
init_wasm_timer();
|
||||
void
|
||||
exit_wasm_timer();
|
||||
timer_ctx_t
|
||||
get_wasm_timer_ctx();
|
||||
timer_ctx_t
|
||||
create_wasm_timer_ctx(unsigned int module_id, int prealloc_num);
|
||||
void
|
||||
destroy_module_timer_ctx(unsigned int module_id);
|
||||
|
||||
#endif /* LIB_BASE_RUNTIME_LIB_H_ */
|
|
@ -1,40 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#ifndef _TIMER_API_H_
|
||||
#define _TIMER_API_H_
|
||||
|
||||
#include "bh_platform.h"
|
||||
#include "wasm_export.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef unsigned int timer_id_t;
|
||||
|
||||
/*
|
||||
* timer interfaces
|
||||
*/
|
||||
|
||||
typedef unsigned int timer_id_t;
|
||||
|
||||
timer_id_t
|
||||
wasm_create_timer(wasm_exec_env_t exec_env, int interval, bool is_period,
|
||||
bool auto_start);
|
||||
void
|
||||
wasm_timer_destroy(wasm_exec_env_t exec_env, timer_id_t timer_id);
|
||||
void
|
||||
wasm_timer_cancel(wasm_exec_env_t exec_env, timer_id_t timer_id);
|
||||
void
|
||||
wasm_timer_restart(wasm_exec_env_t exec_env, timer_id_t timer_id, int interval);
|
||||
uint32
|
||||
wasm_get_sys_tick_ms(wasm_exec_env_t exec_env);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* end of _TIMER_API_H_ */
|
|
@ -1,220 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#include "bh_platform.h"
|
||||
#include "app_manager_export.h"
|
||||
#include "../app-manager/module_wasm_app.h"
|
||||
#include "timer_native_api.h"
|
||||
|
||||
typedef struct {
|
||||
bh_list_link l;
|
||||
timer_ctx_t timer_ctx;
|
||||
} timer_ctx_node_t;
|
||||
|
||||
static bool timer_thread_run = true;
|
||||
|
||||
static bh_list g_timer_ctx_list;
|
||||
static korp_cond g_timer_ctx_list_cond;
|
||||
static korp_mutex g_timer_ctx_list_mutex;
|
||||
|
||||
void
|
||||
wasm_timer_callback(timer_id_t id, unsigned int mod_id)
|
||||
{
|
||||
module_data *module = module_data_list_lookup_id(mod_id);
|
||||
if (module == NULL)
|
||||
return;
|
||||
|
||||
// !!! the length parameter must be 0, so the receiver will
|
||||
// not free the payload pointer.
|
||||
bh_post_msg(module->queue, TIMER_EVENT_WASM, (char *)(uintptr_t)id, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* why we create a separate link for module timer contexts
|
||||
* rather than traverse the module list?
|
||||
* It helps to reduce the lock frequency for the module list.
|
||||
* Also when we lock the module list and then call the callback for
|
||||
* timer expire, the callback is request the list lock again for lookup
|
||||
* the module from module id. It is for avoiding that situation.
|
||||
*/
|
||||
|
||||
void *
|
||||
thread_modulers_timer_check(void *arg)
|
||||
{
|
||||
uint32 ms_to_expiry;
|
||||
uint64 us_to_wait;
|
||||
|
||||
while (timer_thread_run) {
|
||||
ms_to_expiry = (uint32)-1;
|
||||
os_mutex_lock(&g_timer_ctx_list_mutex);
|
||||
timer_ctx_node_t *elem =
|
||||
(timer_ctx_node_t *)bh_list_first_elem(&g_timer_ctx_list);
|
||||
while (elem) {
|
||||
uint32 next = check_app_timers(elem->timer_ctx);
|
||||
if (next != (uint32)-1) {
|
||||
if (ms_to_expiry == (uint32)-1 || ms_to_expiry > next)
|
||||
ms_to_expiry = next;
|
||||
}
|
||||
|
||||
elem = (timer_ctx_node_t *)bh_list_elem_next(elem);
|
||||
}
|
||||
os_mutex_unlock(&g_timer_ctx_list_mutex);
|
||||
|
||||
if (ms_to_expiry == (uint32)-1)
|
||||
us_to_wait = BHT_WAIT_FOREVER;
|
||||
else
|
||||
us_to_wait = (uint64)ms_to_expiry * 1000;
|
||||
os_mutex_lock(&g_timer_ctx_list_mutex);
|
||||
os_cond_reltimedwait(&g_timer_ctx_list_cond, &g_timer_ctx_list_mutex,
|
||||
us_to_wait);
|
||||
os_mutex_unlock(&g_timer_ctx_list_mutex);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
wakeup_modules_timer_thread(timer_ctx_t ctx)
|
||||
{
|
||||
os_mutex_lock(&g_timer_ctx_list_mutex);
|
||||
os_cond_signal(&g_timer_ctx_list_cond);
|
||||
os_mutex_unlock(&g_timer_ctx_list_mutex);
|
||||
}
|
||||
|
||||
bool
|
||||
init_wasm_timer()
|
||||
{
|
||||
korp_tid tm_tid;
|
||||
bh_list_init(&g_timer_ctx_list);
|
||||
|
||||
if (os_cond_init(&g_timer_ctx_list_cond) != 0) {
|
||||
return false;
|
||||
}
|
||||
/* temp solution for: thread_modulers_timer_check thread
|
||||
would recursive lock the mutex */
|
||||
if (os_recursive_mutex_init(&g_timer_ctx_list_mutex) != 0) {
|
||||
goto fail1;
|
||||
}
|
||||
|
||||
if (0
|
||||
!= os_thread_create(&tm_tid, thread_modulers_timer_check, NULL,
|
||||
BH_APPLET_PRESERVED_STACK_SIZE)) {
|
||||
goto fail2;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
fail2:
|
||||
os_mutex_destroy(&g_timer_ctx_list_mutex);
|
||||
|
||||
fail1:
|
||||
os_cond_destroy(&g_timer_ctx_list_cond);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
exit_wasm_timer()
|
||||
{
|
||||
timer_thread_run = false;
|
||||
}
|
||||
|
||||
timer_ctx_t
|
||||
create_wasm_timer_ctx(unsigned int module_id, int prealloc_num)
|
||||
{
|
||||
timer_ctx_t ctx =
|
||||
create_timer_ctx(wasm_timer_callback, wakeup_modules_timer_thread,
|
||||
prealloc_num, module_id);
|
||||
|
||||
if (ctx == NULL)
|
||||
return NULL;
|
||||
|
||||
timer_ctx_node_t *node =
|
||||
(timer_ctx_node_t *)wasm_runtime_malloc(sizeof(timer_ctx_node_t));
|
||||
if (node == NULL) {
|
||||
destroy_timer_ctx(ctx);
|
||||
return NULL;
|
||||
}
|
||||
memset(node, 0, sizeof(*node));
|
||||
node->timer_ctx = ctx;
|
||||
|
||||
os_mutex_lock(&g_timer_ctx_list_mutex);
|
||||
bh_list_insert(&g_timer_ctx_list, node);
|
||||
os_mutex_unlock(&g_timer_ctx_list_mutex);
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
void
|
||||
destroy_module_timer_ctx(unsigned int module_id)
|
||||
{
|
||||
timer_ctx_node_t *elem;
|
||||
|
||||
os_mutex_lock(&g_timer_ctx_list_mutex);
|
||||
elem = (timer_ctx_node_t *)bh_list_first_elem(&g_timer_ctx_list);
|
||||
while (elem) {
|
||||
if (timer_ctx_get_owner(elem->timer_ctx) == module_id) {
|
||||
bh_list_remove(&g_timer_ctx_list, elem);
|
||||
destroy_timer_ctx(elem->timer_ctx);
|
||||
wasm_runtime_free(elem);
|
||||
break;
|
||||
}
|
||||
|
||||
elem = (timer_ctx_node_t *)bh_list_elem_next(elem);
|
||||
}
|
||||
os_mutex_unlock(&g_timer_ctx_list_mutex);
|
||||
}
|
||||
|
||||
timer_ctx_t
|
||||
get_wasm_timer_ctx(wasm_module_inst_t module_inst)
|
||||
{
|
||||
module_data *m = app_manager_get_module_data(Module_WASM_App, module_inst);
|
||||
if (m == NULL)
|
||||
return NULL;
|
||||
return m->timer_ctx;
|
||||
}
|
||||
|
||||
timer_id_t
|
||||
wasm_create_timer(wasm_exec_env_t exec_env, int interval, bool is_period,
|
||||
bool auto_start)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
timer_ctx_t timer_ctx = get_wasm_timer_ctx(module_inst);
|
||||
bh_assert(timer_ctx);
|
||||
return sys_create_timer(timer_ctx, interval, is_period, auto_start);
|
||||
}
|
||||
|
||||
void
|
||||
wasm_timer_destroy(wasm_exec_env_t exec_env, timer_id_t timer_id)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
timer_ctx_t timer_ctx = get_wasm_timer_ctx(module_inst);
|
||||
bh_assert(timer_ctx);
|
||||
sys_timer_destroy(timer_ctx, timer_id);
|
||||
}
|
||||
|
||||
void
|
||||
wasm_timer_cancel(wasm_exec_env_t exec_env, timer_id_t timer_id)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
timer_ctx_t timer_ctx = get_wasm_timer_ctx(module_inst);
|
||||
bh_assert(timer_ctx);
|
||||
sys_timer_cancel(timer_ctx, timer_id);
|
||||
}
|
||||
|
||||
void
|
||||
wasm_timer_restart(wasm_exec_env_t exec_env, timer_id_t timer_id, int interval)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
timer_ctx_t timer_ctx = get_wasm_timer_ctx(module_inst);
|
||||
bh_assert(timer_ctx);
|
||||
sys_timer_restart(timer_ctx, timer_id, interval);
|
||||
}
|
||||
|
||||
uint32
|
||||
wasm_get_sys_tick_ms(wasm_exec_env_t exec_env)
|
||||
{
|
||||
return (uint32)bh_get_tick_ms();
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
# Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
set (WASM_LIB_BASE_DIR ${CMAKE_CURRENT_LIST_DIR})
|
||||
|
||||
add_definitions (-DWASM_ENABLE_BASE_LIB)
|
||||
|
||||
include_directories(${WASM_LIB_BASE_DIR})
|
||||
|
||||
file (GLOB_RECURSE source_all ${WASM_LIB_BASE_DIR}/*.c)
|
||||
|
||||
set (WASM_APP_LIB_CURRENT_SOURCE ${source_all})
|
||||
|
|
@ -1,118 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#include "wa-inc/connection.h"
|
||||
#include "connection_api.h"
|
||||
|
||||
/* Raw connection structure */
|
||||
typedef struct _connection {
|
||||
/* Next connection */
|
||||
struct _connection *next;
|
||||
|
||||
/* Handle of the connection */
|
||||
uint32 handle;
|
||||
|
||||
/* Callback function called when event on this connection occurs */
|
||||
on_connection_event_f on_event;
|
||||
|
||||
/* User data */
|
||||
void *user_data;
|
||||
} connection_t;
|
||||
|
||||
/* Raw connections list */
|
||||
static connection_t *g_conns = NULL;
|
||||
|
||||
connection_t *
|
||||
api_open_connection(const char *name, attr_container_t *args,
|
||||
on_connection_event_f on_event, void *user_data)
|
||||
{
|
||||
connection_t *conn;
|
||||
char *args_buffer = (char *)args;
|
||||
uint32 handle, args_len = attr_container_get_serialize_length(args);
|
||||
|
||||
handle = wasm_open_connection(name, args_buffer, args_len);
|
||||
if (handle == -1)
|
||||
return NULL;
|
||||
|
||||
conn = (connection_t *)malloc(sizeof(*conn));
|
||||
if (conn == NULL) {
|
||||
wasm_close_connection(handle);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(conn, 0, sizeof(*conn));
|
||||
conn->handle = handle;
|
||||
conn->on_event = on_event;
|
||||
conn->user_data = user_data;
|
||||
|
||||
if (g_conns != NULL) {
|
||||
conn->next = g_conns;
|
||||
g_conns = conn;
|
||||
}
|
||||
else {
|
||||
g_conns = conn;
|
||||
}
|
||||
|
||||
return conn;
|
||||
}
|
||||
|
||||
void
|
||||
api_close_connection(connection_t *c)
|
||||
{
|
||||
connection_t *conn = g_conns, *prev = NULL;
|
||||
|
||||
while (conn) {
|
||||
if (conn == c) {
|
||||
wasm_close_connection(c->handle);
|
||||
if (prev != NULL)
|
||||
prev->next = conn->next;
|
||||
else
|
||||
g_conns = conn->next;
|
||||
free(conn);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
prev = conn;
|
||||
conn = conn->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
api_send_on_connection(connection_t *conn, const char *data, uint32 len)
|
||||
{
|
||||
return wasm_send_on_connection(conn->handle, data, len);
|
||||
}
|
||||
|
||||
bool
|
||||
api_config_connection(connection_t *conn, attr_container_t *cfg)
|
||||
{
|
||||
char *cfg_buffer = (char *)cfg;
|
||||
uint32 cfg_len = attr_container_get_serialize_length(cfg);
|
||||
|
||||
return wasm_config_connection(conn->handle, cfg_buffer, cfg_len);
|
||||
}
|
||||
|
||||
void
|
||||
on_connection_data(uint32 handle, char *buffer, uint32 len)
|
||||
{
|
||||
connection_t *conn = g_conns;
|
||||
|
||||
while (conn != NULL) {
|
||||
if (conn->handle == handle) {
|
||||
if (len == 0) {
|
||||
conn->on_event(conn, CONN_EVENT_TYPE_DISCONNECT, NULL, 0,
|
||||
conn->user_data);
|
||||
}
|
||||
else {
|
||||
conn->on_event(conn, CONN_EVENT_TYPE_DATA, buffer, len,
|
||||
conn->user_data);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
conn = conn->next;
|
||||
}
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#ifndef CONNECTION_API_H_
|
||||
#define CONNECTION_API_H_
|
||||
|
||||
#include "bh_platform.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
uint32
|
||||
wasm_open_connection(const char *name, char *args_buf, uint32 args_buf_len);
|
||||
|
||||
void
|
||||
wasm_close_connection(uint32 handle);
|
||||
|
||||
int
|
||||
wasm_send_on_connection(uint32 handle, const char *data, uint32 data_len);
|
||||
|
||||
bool
|
||||
wasm_config_connection(uint32 handle, const char *cfg_buf, uint32 cfg_buf_len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* end of CONNECTION_API_H_ */
|
|
@ -1,94 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#ifndef _CONNECTION_H_
|
||||
#define _CONNECTION_H_
|
||||
|
||||
#include "bi-inc/attr_container.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
struct _connection;
|
||||
typedef struct _connection connection_t;
|
||||
|
||||
/* Connection event type */
|
||||
typedef enum {
|
||||
/* Data is received */
|
||||
CONN_EVENT_TYPE_DATA = 1,
|
||||
/* Connection is disconnected */
|
||||
CONN_EVENT_TYPE_DISCONNECT
|
||||
} conn_event_type_t;
|
||||
|
||||
/*
|
||||
* @typedef on_connection_event_f
|
||||
*
|
||||
* @param conn the connection that the event belongs to
|
||||
* @param type event type
|
||||
* @param data the data received for CONN_EVENT_TYPE_DATA event
|
||||
* @param len length of the data in byte
|
||||
* @param user_data user data
|
||||
*/
|
||||
typedef void (*on_connection_event_f)(connection_t *conn,
|
||||
conn_event_type_t type, const char *data,
|
||||
uint32 len, void *user_data);
|
||||
|
||||
/*
|
||||
*****************
|
||||
* Connection API's
|
||||
*****************
|
||||
*/
|
||||
|
||||
/*
|
||||
* @brief Open a connection.
|
||||
*
|
||||
* @param name name of the connection, "TCP", "UDP" or "UART"
|
||||
* @param args connection arguments, such as: ip:127.0.0.1, port:8888
|
||||
* @param on_event callback function called when event occurs
|
||||
* @param user_data user data
|
||||
*
|
||||
* @return the connection or NULL means fail
|
||||
*/
|
||||
connection_t *
|
||||
api_open_connection(const char *name, attr_container_t *args,
|
||||
on_connection_event_f on_event, void *user_data);
|
||||
|
||||
/*
|
||||
* @brief Close a connection.
|
||||
*
|
||||
* @param conn connection
|
||||
*/
|
||||
void
|
||||
api_close_connection(connection_t *conn);
|
||||
|
||||
/*
|
||||
* Send data to the connection in non-blocking manner which returns immediately
|
||||
*
|
||||
* @param conn the connection
|
||||
* @param data data buffer to be sent
|
||||
* @param len length of the data in byte
|
||||
*
|
||||
* @return actual length sent, or -1 if fail(maybe underlying buffer is full)
|
||||
*/
|
||||
int
|
||||
api_send_on_connection(connection_t *conn, const char *data, uint32 len);
|
||||
|
||||
/*
|
||||
* @brief Configure connection.
|
||||
*
|
||||
* @param conn the connection
|
||||
* @param cfg configurations
|
||||
*
|
||||
* @return true if success, false otherwise
|
||||
*/
|
||||
bool
|
||||
api_config_connection(connection_t *conn, attr_container_t *cfg);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,11 +0,0 @@
|
|||
# Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
set (WASM_APP_CONN_DIR ${CMAKE_CURRENT_LIST_DIR})
|
||||
|
||||
include_directories(${WASM_APP_CONN_DIR})
|
||||
|
||||
|
||||
file (GLOB source_all ${WASM_APP_CONN_DIR}/*.c)
|
||||
|
||||
set (WASM_APP_CURRENT_SOURCE ${source_all})
|
|
@ -1,9 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
EXPORT_WASM_API_WITH_SIG(wasm_open_connection, "($*~)i"),
|
||||
EXPORT_WASM_API_WITH_SIG(wasm_close_connection, "(i)"),
|
||||
EXPORT_WASM_API_WITH_SIG(wasm_send_on_connection, "(i*~)i"),
|
||||
EXPORT_WASM_API_WITH_SIG(wasm_config_connection, "(i*~)i"),
|
|
@ -1,75 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#ifndef CONNECTION_LIB_H_
|
||||
#define CONNECTION_LIB_H_
|
||||
|
||||
#include "bi-inc/attr_container.h"
|
||||
#include "wasm_export.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* This file defines connection library which should be implemented by
|
||||
* different platforms
|
||||
*/
|
||||
|
||||
/*
|
||||
* @brief Open a connection.
|
||||
*
|
||||
* @param name name of the connection, "TCP", "UDP" or "UART"
|
||||
* @param args connection arguments, such as: ip:127.0.0.1, port:8888
|
||||
*
|
||||
* @return 0~0xFFFFFFFE means id of the connection, otherwise(-1) means fail
|
||||
*/
|
||||
typedef uint32 (*connection_open_f)(wasm_module_inst_t module_inst,
|
||||
const char *name, attr_container_t *args);
|
||||
|
||||
/*
|
||||
* @brief Close a connection.
|
||||
*
|
||||
* @param handle of the connection
|
||||
*/
|
||||
typedef void (*connection_close_f)(uint32 handle);
|
||||
|
||||
/*
|
||||
* @brief Send data to the connection in non-blocking manner.
|
||||
*
|
||||
* @param handle of the connection
|
||||
* @param data data buffer to be sent
|
||||
* @param len length of the data in byte
|
||||
*
|
||||
* @return actual length sent, -1 if fail
|
||||
*/
|
||||
typedef int (*connection_send_f)(uint32 handle, const char *data, int len);
|
||||
|
||||
/*
|
||||
* @brief Configure connection.
|
||||
*
|
||||
* @param handle of the connection
|
||||
* @param cfg configurations
|
||||
*
|
||||
* @return true if success, false otherwise
|
||||
*/
|
||||
typedef bool (*connection_config_f)(uint32 handle, attr_container_t *cfg);
|
||||
|
||||
/* Raw connection interface for platform to implement */
|
||||
typedef struct _connection_interface {
|
||||
connection_open_f _open;
|
||||
connection_close_f _close;
|
||||
connection_send_f _send;
|
||||
connection_config_f _config;
|
||||
} connection_interface_t;
|
||||
|
||||
/* Platform must define this interface */
|
||||
extern connection_interface_t connection_impl;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* CONNECTION_LIB_H_ */
|
|
@ -1,36 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#ifndef CONNECTION_API_H_
|
||||
#define CONNECTION_API_H_
|
||||
|
||||
#include "bh_platform.h"
|
||||
#include "wasm_export.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* connection interfaces
|
||||
*/
|
||||
|
||||
uint32
|
||||
wasm_open_connection(wasm_exec_env_t exec_env, char *name, char *args_buf,
|
||||
uint32 len);
|
||||
void
|
||||
wasm_close_connection(wasm_exec_env_t exec_env, uint32 handle);
|
||||
int
|
||||
wasm_send_on_connection(wasm_exec_env_t exec_env, uint32 handle, char *data,
|
||||
uint32 len);
|
||||
bool
|
||||
wasm_config_connection(wasm_exec_env_t exec_env, uint32 handle, char *cfg_buf,
|
||||
uint32 len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* end of CONNECTION_API_H_ */
|
|
@ -1,61 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#include "connection_lib.h"
|
||||
#include "wasm_export.h"
|
||||
#include "native_interface.h"
|
||||
#include "connection_native_api.h"
|
||||
|
||||
/* Note:
|
||||
*
|
||||
* This file is the consumer of connection lib which is implemented by different
|
||||
* platforms
|
||||
*/
|
||||
|
||||
uint32
|
||||
wasm_open_connection(wasm_exec_env_t exec_env, char *name, char *args_buf,
|
||||
uint32 len)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
attr_container_t *args;
|
||||
|
||||
args = (attr_container_t *)args_buf;
|
||||
|
||||
if (connection_impl._open != NULL)
|
||||
return connection_impl._open(module_inst, name, args);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void
|
||||
wasm_close_connection(wasm_exec_env_t exec_env, uint32 handle)
|
||||
{
|
||||
if (connection_impl._close != NULL)
|
||||
connection_impl._close(handle);
|
||||
}
|
||||
|
||||
int
|
||||
wasm_send_on_connection(wasm_exec_env_t exec_env, uint32 handle, char *data,
|
||||
uint32 len)
|
||||
{
|
||||
if (connection_impl._send != NULL)
|
||||
return connection_impl._send(handle, data, len);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool
|
||||
wasm_config_connection(wasm_exec_env_t exec_env, uint32 handle, char *cfg_buf,
|
||||
uint32 len)
|
||||
{
|
||||
attr_container_t *cfg;
|
||||
|
||||
cfg = (attr_container_t *)cfg_buf;
|
||||
|
||||
if (connection_impl._config != NULL)
|
||||
return connection_impl._config(handle, cfg);
|
||||
|
||||
return false;
|
||||
}
|
|
@ -1,54 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#include "conn_tcp.h"
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int
|
||||
tcp_open(char *address, uint16 port)
|
||||
{
|
||||
int sock, ret;
|
||||
struct sockaddr_in servaddr;
|
||||
|
||||
memset(&servaddr, 0, sizeof(servaddr));
|
||||
servaddr.sin_family = AF_INET;
|
||||
servaddr.sin_addr.s_addr = inet_addr(address);
|
||||
servaddr.sin_port = htons(port);
|
||||
|
||||
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
if (sock == -1)
|
||||
return -1;
|
||||
|
||||
ret = connect(sock, (struct sockaddr *)&servaddr, sizeof(servaddr));
|
||||
if (ret == -1) {
|
||||
close(sock);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Put the socket in non-blocking mode */
|
||||
if (fcntl(sock, F_SETFL, fcntl(sock, F_GETFL) | O_NONBLOCK) < 0) {
|
||||
close(sock);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return sock;
|
||||
}
|
||||
|
||||
int
|
||||
tcp_send(int sock, const char *data, int size)
|
||||
{
|
||||
return send(sock, data, size, 0);
|
||||
}
|
||||
|
||||
int
|
||||
tcp_recv(int sock, char *buffer, int buf_size)
|
||||
{
|
||||
return recv(sock, buffer, buf_size, 0);
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#ifndef CONN_LINUX_TCP_H_
|
||||
#define CONN_LINUX_TCP_H_
|
||||
|
||||
#include "bh_platform.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int
|
||||
tcp_open(char *address, uint16 port);
|
||||
|
||||
int
|
||||
tcp_send(int sock, const char *data, int size);
|
||||
|
||||
int
|
||||
tcp_recv(int sock, char *buffer, int buf_size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,103 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#include "conn_uart.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static int
|
||||
parse_baudrate(int baud)
|
||||
{
|
||||
switch (baud) {
|
||||
case 9600:
|
||||
return B9600;
|
||||
case 19200:
|
||||
return B19200;
|
||||
case 38400:
|
||||
return B38400;
|
||||
case 57600:
|
||||
return B57600;
|
||||
case 115200:
|
||||
return B115200;
|
||||
case 230400:
|
||||
return B230400;
|
||||
case 460800:
|
||||
return B460800;
|
||||
case 500000:
|
||||
return B500000;
|
||||
case 576000:
|
||||
return B576000;
|
||||
case 921600:
|
||||
return B921600;
|
||||
case 1000000:
|
||||
return B1000000;
|
||||
case 1152000:
|
||||
return B1152000;
|
||||
case 1500000:
|
||||
return B1500000;
|
||||
case 2000000:
|
||||
return B2000000;
|
||||
case 2500000:
|
||||
return B2500000;
|
||||
case 3000000:
|
||||
return B3000000;
|
||||
case 3500000:
|
||||
return B3500000;
|
||||
case 4000000:
|
||||
return B4000000;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
uart_open(char *device, int baudrate)
|
||||
{
|
||||
int uart_fd;
|
||||
struct termios uart_term;
|
||||
|
||||
uart_fd = open(device, O_RDWR | O_NOCTTY);
|
||||
|
||||
if (uart_fd < 0)
|
||||
return -1;
|
||||
|
||||
memset(&uart_term, 0, sizeof(uart_term));
|
||||
uart_term.c_cflag = parse_baudrate(baudrate) | CS8 | CLOCAL | CREAD;
|
||||
uart_term.c_iflag = IGNPAR;
|
||||
uart_term.c_oflag = 0;
|
||||
|
||||
/* set noncanonical mode */
|
||||
uart_term.c_lflag = 0;
|
||||
uart_term.c_cc[VTIME] = 30;
|
||||
uart_term.c_cc[VMIN] = 1;
|
||||
tcflush(uart_fd, TCIFLUSH);
|
||||
|
||||
if (tcsetattr(uart_fd, TCSANOW, &uart_term) != 0) {
|
||||
close(uart_fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Put the fd in non-blocking mode */
|
||||
if (fcntl(uart_fd, F_SETFL, fcntl(uart_fd, F_GETFL) | O_NONBLOCK) < 0) {
|
||||
close(uart_fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return uart_fd;
|
||||
}
|
||||
|
||||
int
|
||||
uart_send(int fd, const char *data, int size)
|
||||
{
|
||||
return write(fd, data, size);
|
||||
}
|
||||
|
||||
int
|
||||
uart_recv(int fd, char *buffer, int buf_size)
|
||||
{
|
||||
return read(fd, buffer, buf_size);
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#ifndef CONN_LINUX_UART_H_
|
||||
#define CONN_LINUX_UART_H_
|
||||
|
||||
#include "bh_platform.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int
|
||||
uart_open(char *device, int baudrate);
|
||||
|
||||
int
|
||||
uart_send(int fd, const char *data, int size);
|
||||
|
||||
int
|
||||
uart_recv(int fd, char *buffer, int buf_size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,58 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#include "conn_udp.h"
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
|
||||
int
|
||||
udp_open(uint16 port)
|
||||
{
|
||||
int sock, ret;
|
||||
struct sockaddr_in addr;
|
||||
|
||||
sock = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (sock == -1)
|
||||
return -1;
|
||||
|
||||
memset(&addr, 0, sizeof(addr));
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
addr.sin_port = htons(port);
|
||||
|
||||
ret = bind(sock, (struct sockaddr *)&addr, sizeof(addr));
|
||||
if (ret == -1) {
|
||||
close(sock);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Put the socket in non-blocking mode */
|
||||
if (fcntl(sock, F_SETFL, fcntl(sock, F_GETFL) | O_NONBLOCK) < 0) {
|
||||
close(sock);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return sock;
|
||||
}
|
||||
|
||||
int
|
||||
udp_send(int sock, struct sockaddr *dest, const char *data, int size)
|
||||
{
|
||||
return sendto(sock, data, size, MSG_CONFIRM, dest, sizeof(*dest));
|
||||
}
|
||||
|
||||
int
|
||||
udp_recv(int sock, char *buffer, int buf_size)
|
||||
{
|
||||
struct sockaddr_in remaddr;
|
||||
socklen_t addrlen = sizeof(remaddr);
|
||||
|
||||
return recvfrom(sock, buffer, buf_size, 0, (struct sockaddr *)&remaddr,
|
||||
&addrlen);
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#ifndef CONN_LINUX_UDP_H_
|
||||
#define CONN_LINUX_UDP_H_
|
||||
|
||||
#include "bh_platform.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
int
|
||||
udp_open(uint16 port);
|
||||
|
||||
int
|
||||
udp_send(int sock, struct sockaddr *dest, const char *data, int size);
|
||||
|
||||
int
|
||||
udp_recv(int sock, char *buffer, int buf_size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,609 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
/*
|
||||
* Note:
|
||||
* This file implements the linux version connection library which is
|
||||
* defined in connection_lib.h.
|
||||
* It also provides a reference implementation of connections manager.
|
||||
*/
|
||||
|
||||
#include "connection_lib.h"
|
||||
#include "bh_platform.h"
|
||||
#include "app_manager_export.h"
|
||||
#include "module_wasm_app.h"
|
||||
#include "conn_tcp.h"
|
||||
#include "conn_udp.h"
|
||||
#include "conn_uart.h"
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/epoll.h>
|
||||
#include <sys/types.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#define MAX_EVENTS 10
|
||||
#define IO_BUF_SIZE 256
|
||||
|
||||
static bool polling_thread_run = true;
|
||||
|
||||
/* Connection type */
|
||||
typedef enum conn_type {
|
||||
CONN_TYPE_TCP,
|
||||
CONN_TYPE_UDP,
|
||||
CONN_TYPE_UART,
|
||||
CONN_TYPE_UNKNOWN
|
||||
} conn_type_t;
|
||||
|
||||
/* Sys connection */
|
||||
typedef struct sys_connection {
|
||||
/* Next connection */
|
||||
struct sys_connection *next;
|
||||
|
||||
/* Type */
|
||||
conn_type_t type;
|
||||
|
||||
/* Handle to interact with wasm app */
|
||||
uint32 handle;
|
||||
|
||||
/* Underlying connection ID, may be socket fd */
|
||||
int fd;
|
||||
|
||||
/* Module id that the connection belongs to */
|
||||
uint32 module_id;
|
||||
|
||||
/* Argument, such as dest addr for udp */
|
||||
void *arg;
|
||||
} sys_connection_t;
|
||||
|
||||
/* Epoll instance */
|
||||
static int epollfd;
|
||||
|
||||
/* Connections list */
|
||||
static sys_connection_t *g_connections = NULL;
|
||||
|
||||
/* Max handle */
|
||||
static uint32 g_handle_max = 0;
|
||||
|
||||
/* Lock to protect g_connections and g_handle_max */
|
||||
static korp_mutex g_lock;
|
||||
|
||||
/* Epoll events */
|
||||
static struct epoll_event epoll_events[MAX_EVENTS];
|
||||
|
||||
/* Buffer to receive data */
|
||||
static char io_buf[IO_BUF_SIZE];
|
||||
|
||||
static uint32
|
||||
_conn_open(wasm_module_inst_t module_inst, const char *name,
|
||||
attr_container_t *args);
|
||||
static void
|
||||
_conn_close(uint32 handle);
|
||||
static int
|
||||
_conn_send(uint32 handle, const char *data, int len);
|
||||
static bool
|
||||
_conn_config(uint32 handle, attr_container_t *cfg);
|
||||
|
||||
/* clang-format off */
|
||||
/*
|
||||
* Platform implementation of connection library
|
||||
*/
|
||||
connection_interface_t connection_impl = {
|
||||
._open = _conn_open,
|
||||
._close = _conn_close,
|
||||
._send = _conn_send,
|
||||
._config = _conn_config
|
||||
};
|
||||
/* clang-format on */
|
||||
|
||||
static void
|
||||
add_connection(sys_connection_t *conn)
|
||||
{
|
||||
os_mutex_lock(&g_lock);
|
||||
|
||||
g_handle_max++;
|
||||
if (g_handle_max == -1)
|
||||
g_handle_max++;
|
||||
conn->handle = g_handle_max;
|
||||
|
||||
if (g_connections) {
|
||||
conn->next = g_connections;
|
||||
g_connections = conn;
|
||||
}
|
||||
else {
|
||||
g_connections = conn;
|
||||
}
|
||||
|
||||
os_mutex_unlock(&g_lock);
|
||||
}
|
||||
|
||||
#define FREE_CONNECTION(conn) \
|
||||
do { \
|
||||
if (conn->arg) \
|
||||
wasm_runtime_free(conn->arg); \
|
||||
wasm_runtime_free(conn); \
|
||||
} while (0)
|
||||
|
||||
static int
|
||||
get_app_conns_num(uint32 module_id)
|
||||
{
|
||||
sys_connection_t *conn;
|
||||
int num = 0;
|
||||
|
||||
os_mutex_lock(&g_lock);
|
||||
|
||||
conn = g_connections;
|
||||
while (conn) {
|
||||
if (conn->module_id == module_id)
|
||||
num++;
|
||||
conn = conn->next;
|
||||
}
|
||||
|
||||
os_mutex_unlock(&g_lock);
|
||||
|
||||
return num;
|
||||
}
|
||||
|
||||
static sys_connection_t *
|
||||
find_connection(uint32 handle, bool remove_found)
|
||||
{
|
||||
sys_connection_t *conn, *prev = NULL;
|
||||
|
||||
os_mutex_lock(&g_lock);
|
||||
|
||||
conn = g_connections;
|
||||
while (conn) {
|
||||
if (conn->handle == handle) {
|
||||
if (remove_found) {
|
||||
if (prev != NULL) {
|
||||
prev->next = conn->next;
|
||||
}
|
||||
else {
|
||||
g_connections = conn->next;
|
||||
}
|
||||
}
|
||||
os_mutex_unlock(&g_lock);
|
||||
return conn;
|
||||
}
|
||||
else {
|
||||
prev = conn;
|
||||
conn = conn->next;
|
||||
}
|
||||
}
|
||||
|
||||
os_mutex_unlock(&g_lock);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
cleanup_connections(uint32 module_id)
|
||||
{
|
||||
sys_connection_t *conn, *prev = NULL;
|
||||
|
||||
os_mutex_lock(&g_lock);
|
||||
|
||||
conn = g_connections;
|
||||
while (conn) {
|
||||
if (conn->module_id == module_id) {
|
||||
epoll_ctl(epollfd, EPOLL_CTL_DEL, conn->fd, NULL);
|
||||
close(conn->fd);
|
||||
|
||||
if (prev != NULL) {
|
||||
prev->next = conn->next;
|
||||
FREE_CONNECTION(conn);
|
||||
conn = prev->next;
|
||||
}
|
||||
else {
|
||||
g_connections = conn->next;
|
||||
FREE_CONNECTION(conn);
|
||||
conn = g_connections;
|
||||
}
|
||||
}
|
||||
else {
|
||||
prev = conn;
|
||||
conn = conn->next;
|
||||
}
|
||||
}
|
||||
|
||||
os_mutex_unlock(&g_lock);
|
||||
}
|
||||
|
||||
static conn_type_t
|
||||
get_conn_type(const char *name)
|
||||
{
|
||||
if (strcmp(name, "TCP") == 0)
|
||||
return CONN_TYPE_TCP;
|
||||
if (strcmp(name, "UDP") == 0)
|
||||
return CONN_TYPE_UDP;
|
||||
if (strcmp(name, "UART") == 0)
|
||||
return CONN_TYPE_UART;
|
||||
|
||||
return CONN_TYPE_UNKNOWN;
|
||||
}
|
||||
|
||||
/* --- connection lib function --- */
|
||||
static uint32
|
||||
_conn_open(wasm_module_inst_t module_inst, const char *name,
|
||||
attr_container_t *args)
|
||||
{
|
||||
int fd;
|
||||
sys_connection_t *conn;
|
||||
struct epoll_event ev;
|
||||
uint32 module_id = app_manager_get_module_id(Module_WASM_App, module_inst);
|
||||
bh_assert(module_id != ID_NONE);
|
||||
|
||||
if (get_app_conns_num(module_id) >= MAX_CONNECTION_PER_APP)
|
||||
return -1;
|
||||
|
||||
conn = (sys_connection_t *)wasm_runtime_malloc(sizeof(*conn));
|
||||
if (conn == NULL)
|
||||
return -1;
|
||||
|
||||
memset(conn, 0, sizeof(*conn));
|
||||
conn->module_id = module_id;
|
||||
conn->type = get_conn_type(name);
|
||||
|
||||
/* Generate a handle and add to list */
|
||||
add_connection(conn);
|
||||
|
||||
if (conn->type == CONN_TYPE_TCP) {
|
||||
char *address;
|
||||
uint16 port;
|
||||
|
||||
/* Check and parse connection parameters */
|
||||
if (!attr_container_contain_key(args, "address")
|
||||
|| !attr_container_contain_key(args, "port"))
|
||||
goto fail;
|
||||
|
||||
address = attr_container_get_as_string(args, "address");
|
||||
port = attr_container_get_as_uint16(args, "port");
|
||||
|
||||
/* Connect to TCP server */
|
||||
if (!address || (fd = tcp_open(address, port)) == -1)
|
||||
goto fail;
|
||||
}
|
||||
else if (conn->type == CONN_TYPE_UDP) {
|
||||
uint16 port;
|
||||
|
||||
/* Check and parse connection parameters */
|
||||
if (!attr_container_contain_key(args, "bind port"))
|
||||
goto fail;
|
||||
port = attr_container_get_as_uint16(args, "bind port");
|
||||
|
||||
/* Bind port */
|
||||
if ((fd = udp_open(port)) == -1)
|
||||
goto fail;
|
||||
}
|
||||
else if (conn->type == CONN_TYPE_UART) {
|
||||
char *device;
|
||||
int baud;
|
||||
|
||||
/* Check and parse connection parameters */
|
||||
if (!attr_container_contain_key(args, "device")
|
||||
|| !attr_container_contain_key(args, "baudrate"))
|
||||
goto fail;
|
||||
device = attr_container_get_as_string(args, "device");
|
||||
baud = attr_container_get_as_int(args, "baudrate");
|
||||
|
||||
/* Open device */
|
||||
if (!device || (fd = uart_open(device, baud)) == -1)
|
||||
goto fail;
|
||||
}
|
||||
else {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
conn->fd = fd;
|
||||
|
||||
/* Set current connection as event data */
|
||||
ev.events = EPOLLIN;
|
||||
ev.data.ptr = conn;
|
||||
|
||||
/* Monitor incoming data */
|
||||
if (epoll_ctl(epollfd, EPOLL_CTL_ADD, fd, &ev) == -1) {
|
||||
close(fd);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
return conn->handle;
|
||||
|
||||
fail:
|
||||
find_connection(conn->handle, true);
|
||||
wasm_runtime_free(conn);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* --- connection lib function --- */
|
||||
static void
|
||||
_conn_close(uint32 handle)
|
||||
{
|
||||
sys_connection_t *conn = find_connection(handle, true);
|
||||
|
||||
if (conn != NULL) {
|
||||
epoll_ctl(epollfd, EPOLL_CTL_DEL, conn->fd, NULL);
|
||||
close(conn->fd);
|
||||
FREE_CONNECTION(conn);
|
||||
}
|
||||
}
|
||||
|
||||
/* --- connection lib function --- */
|
||||
static int
|
||||
_conn_send(uint32 handle, const char *data, int len)
|
||||
{
|
||||
sys_connection_t *conn = find_connection(handle, false);
|
||||
|
||||
if (conn == NULL)
|
||||
return -1;
|
||||
|
||||
if (conn->type == CONN_TYPE_TCP)
|
||||
return tcp_send(conn->fd, data, len);
|
||||
|
||||
if (conn->type == CONN_TYPE_UDP) {
|
||||
struct sockaddr *addr = (struct sockaddr *)conn->arg;
|
||||
return udp_send(conn->fd, addr, data, len);
|
||||
}
|
||||
|
||||
if (conn->type == CONN_TYPE_UART)
|
||||
return uart_send(conn->fd, data, len);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* --- connection lib function --- */
|
||||
static bool
|
||||
_conn_config(uint32 handle, attr_container_t *cfg)
|
||||
{
|
||||
sys_connection_t *conn = find_connection(handle, false);
|
||||
|
||||
if (conn == NULL)
|
||||
return false;
|
||||
|
||||
if (conn->type == CONN_TYPE_UDP) {
|
||||
char *address;
|
||||
uint16_t port;
|
||||
struct sockaddr_in *addr;
|
||||
|
||||
/* Parse remote address/port */
|
||||
if (!attr_container_contain_key(cfg, "address")
|
||||
|| !attr_container_contain_key(cfg, "port"))
|
||||
return false;
|
||||
if (!(address = attr_container_get_as_string(cfg, "address")))
|
||||
return false;
|
||||
port = attr_container_get_as_uint16(cfg, "port");
|
||||
|
||||
if (conn->arg == NULL) {
|
||||
addr = (struct sockaddr_in *)wasm_runtime_malloc(sizeof(*addr));
|
||||
if (addr == NULL)
|
||||
return false;
|
||||
|
||||
memset(addr, 0, sizeof(*addr));
|
||||
addr->sin_family = AF_INET;
|
||||
addr->sin_addr.s_addr = inet_addr(address);
|
||||
addr->sin_port = htons(port);
|
||||
|
||||
/* Set remote address as connection arg */
|
||||
conn->arg = addr;
|
||||
}
|
||||
else {
|
||||
addr = (struct sockaddr_in *)conn->arg;
|
||||
addr->sin_addr.s_addr = inet_addr(address);
|
||||
addr->sin_port = htons(port);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* --- connection manager reference implementation ---*/
|
||||
|
||||
typedef struct connection_event {
|
||||
uint32 handle;
|
||||
char *data;
|
||||
uint32 len;
|
||||
} connection_event_t;
|
||||
|
||||
static void
|
||||
connection_event_cleaner(connection_event_t *conn_event)
|
||||
{
|
||||
if (conn_event->data != NULL)
|
||||
wasm_runtime_free(conn_event->data);
|
||||
wasm_runtime_free(conn_event);
|
||||
}
|
||||
|
||||
static void
|
||||
post_msg_to_module(sys_connection_t *conn, char *data, uint32 len)
|
||||
{
|
||||
module_data *module = module_data_list_lookup_id(conn->module_id);
|
||||
char *data_copy = NULL;
|
||||
connection_event_t *conn_data_event;
|
||||
bh_message_t msg;
|
||||
|
||||
if (module == NULL)
|
||||
return;
|
||||
|
||||
conn_data_event =
|
||||
(connection_event_t *)wasm_runtime_malloc(sizeof(*conn_data_event));
|
||||
if (conn_data_event == NULL)
|
||||
return;
|
||||
|
||||
if (len > 0) {
|
||||
data_copy = (char *)wasm_runtime_malloc(len);
|
||||
if (data_copy == NULL) {
|
||||
wasm_runtime_free(conn_data_event);
|
||||
return;
|
||||
}
|
||||
bh_memcpy_s(data_copy, len, data, len);
|
||||
}
|
||||
|
||||
memset(conn_data_event, 0, sizeof(*conn_data_event));
|
||||
conn_data_event->handle = conn->handle;
|
||||
conn_data_event->data = data_copy;
|
||||
conn_data_event->len = len;
|
||||
|
||||
msg = bh_new_msg(CONNECTION_EVENT_WASM, conn_data_event,
|
||||
sizeof(*conn_data_event), connection_event_cleaner);
|
||||
if (!msg) {
|
||||
connection_event_cleaner(conn_data_event);
|
||||
return;
|
||||
}
|
||||
|
||||
bh_post_msg2(module->queue, msg);
|
||||
}
|
||||
|
||||
static void *
|
||||
polling_thread_routine(void *arg)
|
||||
{
|
||||
while (polling_thread_run) {
|
||||
int i, n;
|
||||
|
||||
n = epoll_wait(epollfd, epoll_events, MAX_EVENTS, -1);
|
||||
|
||||
if (n == -1 && errno != EINTR)
|
||||
continue;
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
sys_connection_t *conn =
|
||||
(sys_connection_t *)epoll_events[i].data.ptr;
|
||||
|
||||
if (conn->type == CONN_TYPE_TCP) {
|
||||
int count = tcp_recv(conn->fd, io_buf, IO_BUF_SIZE);
|
||||
if (count <= 0) {
|
||||
/* Connection is closed by peer */
|
||||
post_msg_to_module(conn, NULL, 0);
|
||||
_conn_close(conn->handle);
|
||||
}
|
||||
else {
|
||||
/* Data is received */
|
||||
post_msg_to_module(conn, io_buf, count);
|
||||
}
|
||||
}
|
||||
else if (conn->type == CONN_TYPE_UDP) {
|
||||
int count = udp_recv(conn->fd, io_buf, IO_BUF_SIZE);
|
||||
if (count > 0)
|
||||
post_msg_to_module(conn, io_buf, count);
|
||||
}
|
||||
else if (conn->type == CONN_TYPE_UART) {
|
||||
int count = uart_recv(conn->fd, io_buf, IO_BUF_SIZE);
|
||||
if (count > 0)
|
||||
post_msg_to_module(conn, io_buf, count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
app_mgr_connection_event_callback(module_data *m_data, bh_message_t msg)
|
||||
{
|
||||
uint32 argv[3];
|
||||
wasm_function_inst_t func_on_conn_data;
|
||||
bh_assert(CONNECTION_EVENT_WASM == bh_message_type(msg));
|
||||
wasm_data *wasm_app_data = (wasm_data *)m_data->internal_data;
|
||||
wasm_module_inst_t inst = wasm_app_data->wasm_module_inst;
|
||||
connection_event_t *conn_event =
|
||||
(connection_event_t *)bh_message_payload(msg);
|
||||
int32 data_offset;
|
||||
|
||||
if (conn_event == NULL)
|
||||
return;
|
||||
|
||||
func_on_conn_data = wasm_runtime_lookup_function(
|
||||
inst, "_on_connection_data", "(i32i32i32)");
|
||||
if (!func_on_conn_data)
|
||||
func_on_conn_data = wasm_runtime_lookup_function(
|
||||
inst, "on_connection_data", "(i32i32i32)");
|
||||
if (!func_on_conn_data) {
|
||||
printf("Cannot find function on_connection_data\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* 0 len means connection closed */
|
||||
if (conn_event->len == 0) {
|
||||
argv[0] = conn_event->handle;
|
||||
argv[1] = 0;
|
||||
argv[2] = 0;
|
||||
if (!wasm_runtime_call_wasm(wasm_app_data->exec_env, func_on_conn_data,
|
||||
3, argv)) {
|
||||
const char *exception = wasm_runtime_get_exception(inst);
|
||||
bh_assert(exception);
|
||||
printf(":Got exception running wasm code: %s\n", exception);
|
||||
wasm_runtime_clear_exception(inst);
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
data_offset = wasm_runtime_module_dup_data(inst, conn_event->data,
|
||||
conn_event->len);
|
||||
if (data_offset == 0) {
|
||||
const char *exception = wasm_runtime_get_exception(inst);
|
||||
if (exception) {
|
||||
printf("Got exception running wasm code: %s\n", exception);
|
||||
wasm_runtime_clear_exception(inst);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
argv[0] = conn_event->handle;
|
||||
argv[1] = (uint32)data_offset;
|
||||
argv[2] = conn_event->len;
|
||||
if (!wasm_runtime_call_wasm(wasm_app_data->exec_env, func_on_conn_data,
|
||||
3, argv)) {
|
||||
const char *exception = wasm_runtime_get_exception(inst);
|
||||
bh_assert(exception);
|
||||
printf(":Got exception running wasm code: %s\n", exception);
|
||||
wasm_runtime_clear_exception(inst);
|
||||
wasm_runtime_module_free(inst, data_offset);
|
||||
return;
|
||||
}
|
||||
wasm_runtime_module_free(inst, data_offset);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
init_connection_framework()
|
||||
{
|
||||
korp_tid tid;
|
||||
|
||||
epollfd = epoll_create(MAX_EVENTS);
|
||||
if (epollfd == -1)
|
||||
return false;
|
||||
|
||||
if (os_mutex_init(&g_lock) != 0) {
|
||||
close(epollfd);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!wasm_register_cleanup_callback(cleanup_connections)) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!wasm_register_msg_callback(CONNECTION_EVENT_WASM,
|
||||
app_mgr_connection_event_callback)) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (os_thread_create(&tid, polling_thread_routine, NULL,
|
||||
BH_APPLET_PRESERVED_STACK_SIZE)
|
||||
!= 0) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
fail:
|
||||
os_mutex_destroy(&g_lock);
|
||||
close(epollfd);
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
exit_connection_framework()
|
||||
{
|
||||
polling_thread_run = false;
|
||||
}
|
|
@ -1,13 +0,0 @@
|
|||
# Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
set (WASM_LIB_CONN_MGR_DIR ${CMAKE_CURRENT_LIST_DIR})
|
||||
|
||||
include_directories(${WASM_LIB_CONN_MGR_DIR})
|
||||
|
||||
|
||||
file (GLOB_RECURSE source_all ${WASM_LIB_CONN_MGR_DIR}/*.c)
|
||||
|
||||
set (WASM_LIB_CONN_MGR_SOURCE ${source_all})
|
||||
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
# Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
set (WASM_LIB_CONN_DIR ${CMAKE_CURRENT_LIST_DIR})
|
||||
|
||||
include_directories(${WASM_LIB_CONN_DIR})
|
||||
|
||||
add_definitions (-DAPP_FRAMEWORK_CONNECTION)
|
||||
|
||||
|
||||
include (${CMAKE_CURRENT_LIST_DIR}/${WAMR_BUILD_PLATFORM}/connection_mgr.cmake)
|
||||
|
||||
file (GLOB source_all
|
||||
${WASM_LIB_CONN_MGR_SOURCE}
|
||||
${WASM_LIB_CONN_DIR}/*.c
|
||||
)
|
||||
|
||||
set (WASM_APP_LIB_CURRENT_SOURCE ${source_all})
|
|
@ -1,25 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
/*
|
||||
* Note:
|
||||
* This file implements the linux version connection library which is
|
||||
* defined in connection_lib.h.
|
||||
* It also provides a reference impl of connections manager.
|
||||
*/
|
||||
|
||||
#include "connection_lib.h"
|
||||
|
||||
/* clang-format off */
|
||||
/*
|
||||
* Platform implementation of connection library
|
||||
*/
|
||||
connection_interface_t connection_impl = {
|
||||
._open = NULL,
|
||||
._close = NULL,
|
||||
._send = NULL,
|
||||
._config = NULL
|
||||
};
|
||||
/* clang-format on */
|
|
@ -1,13 +0,0 @@
|
|||
# Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
set (WASM_LIB_CONN_MGR_DIR ${CMAKE_CURRENT_LIST_DIR})
|
||||
|
||||
include_directories(${WASM_LIB_CONN_MGR_DIR})
|
||||
|
||||
|
||||
file (GLOB_RECURSE source_all ${WASM_LIB_CONN_MGR_DIR}/*.c)
|
||||
|
||||
set (WASM_LIB_CONN_MGR_SOURCE ${source_all})
|
||||
|
||||
|
|
@ -1,122 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#include "wa-inc/sensor.h"
|
||||
|
||||
#include "sensor_api.h"
|
||||
|
||||
typedef struct _sensor {
|
||||
struct _sensor *next;
|
||||
char *name;
|
||||
uint32 handle;
|
||||
void (*sensor_callback)(sensor_t, attr_container_t *, void *);
|
||||
void *user_data;
|
||||
} sensor;
|
||||
|
||||
static sensor_t g_sensors = NULL;
|
||||
|
||||
sensor_t
|
||||
sensor_open(const char *name, int index,
|
||||
sensor_event_handler_f sensor_event_handler, void *user_data)
|
||||
{
|
||||
uint32 id = wasm_sensor_open(name, index);
|
||||
if (id == -1)
|
||||
return NULL;
|
||||
|
||||
// create local node for holding the user callback
|
||||
sensor_t sensor = (sensor_t)malloc(sizeof(struct _sensor));
|
||||
if (sensor == NULL)
|
||||
return NULL;
|
||||
|
||||
memset(sensor, 0, sizeof(struct _sensor));
|
||||
sensor->handle = id;
|
||||
sensor->name = strdup(name);
|
||||
sensor->user_data = user_data;
|
||||
sensor->sensor_callback = sensor_event_handler;
|
||||
|
||||
if (!sensor->name) {
|
||||
free(sensor);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (g_sensors == NULL) {
|
||||
g_sensors = sensor;
|
||||
}
|
||||
else {
|
||||
sensor->next = g_sensors;
|
||||
g_sensors = sensor;
|
||||
}
|
||||
|
||||
return sensor;
|
||||
}
|
||||
|
||||
bool
|
||||
sensor_config_with_attr_container(sensor_t sensor, attr_container_t *cfg)
|
||||
{
|
||||
char *buffer = (char *)cfg;
|
||||
int len = attr_container_get_serialize_length(cfg);
|
||||
|
||||
return wasm_sensor_config_with_attr_container(sensor->handle, buffer, len);
|
||||
}
|
||||
|
||||
bool
|
||||
sensor_config(sensor_t sensor, int interval, int bit_cfg, int delay)
|
||||
{
|
||||
bool ret = wasm_sensor_config(sensor->handle, interval, bit_cfg, delay);
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool
|
||||
sensor_close(sensor_t sensor)
|
||||
{
|
||||
wasm_sensor_close(sensor->handle);
|
||||
|
||||
// remove local node
|
||||
sensor_t s = g_sensors;
|
||||
sensor_t prev = NULL;
|
||||
while (s) {
|
||||
if (s == sensor) {
|
||||
if (prev == NULL) {
|
||||
g_sensors = s->next;
|
||||
}
|
||||
else {
|
||||
prev->next = s->next;
|
||||
}
|
||||
free(s->name);
|
||||
free(s);
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
prev = s;
|
||||
s = s->next;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* API for native layer to callback for sensor events
|
||||
*
|
||||
*/
|
||||
|
||||
void
|
||||
on_sensor_event(uint32 sensor_id, char *buffer, int len)
|
||||
{
|
||||
attr_container_t *sensor_data = (attr_container_t *)buffer;
|
||||
|
||||
// lookup the sensor and call the handlers
|
||||
sensor_t s = g_sensors;
|
||||
sensor_t prev = NULL;
|
||||
while (s) {
|
||||
if (s->handle == sensor_id) {
|
||||
s->sensor_callback(s, sensor_data, s->user_data);
|
||||
break;
|
||||
}
|
||||
|
||||
s = s->next;
|
||||
}
|
||||
}
|
|
@ -1,31 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#ifndef _SENSOR_API_H_
|
||||
#define _SENSOR_API_H_
|
||||
|
||||
#include "bh_platform.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
uint32
|
||||
wasm_sensor_open(const char *name, int instance);
|
||||
|
||||
bool
|
||||
wasm_sensor_config(uint32 sensor, uint32 interval, int bit_cfg, uint32 delay);
|
||||
|
||||
bool
|
||||
wasm_sensor_config_with_attr_container(uint32 sensor, char *buffer, uint32 len);
|
||||
|
||||
bool
|
||||
wasm_sensor_close(uint32 sensor);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* end of _SENSOR_API_H_ */
|
|
@ -1,94 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#ifndef _AEE_SENSOR_H_
|
||||
#define _AEE_SENSOR_H_
|
||||
|
||||
#include "bi-inc/attr_container.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* board producer define sensor */
|
||||
struct _sensor;
|
||||
typedef struct _sensor *sensor_t;
|
||||
|
||||
/**
|
||||
* @typedef sensor_event_handler_f
|
||||
*
|
||||
* @brief Define the signature of callback function for API
|
||||
* sensor_open() to handle sensor event.
|
||||
*
|
||||
* @param sensor the sensor which the event belong to
|
||||
* @param sensor_event the sensor event
|
||||
* @param user_data user data associated with the sensor which is set when
|
||||
* calling sensor_open().
|
||||
*
|
||||
* @see sensor_open
|
||||
*/
|
||||
typedef void (*sensor_event_handler_f)(sensor_t sensor,
|
||||
attr_container_t *sensor_event,
|
||||
void *user_data);
|
||||
|
||||
/*
|
||||
*****************
|
||||
* Sensor APIs
|
||||
*****************
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Open sensor.
|
||||
*
|
||||
* @param name sensor name
|
||||
* @param index sensor index
|
||||
* @param handler callback function to handle the sensor event
|
||||
* @param user_data user data
|
||||
*
|
||||
* @return the sensor opened if success, NULL otherwise
|
||||
*/
|
||||
sensor_t
|
||||
sensor_open(const char *name, int index, sensor_event_handler_f handler,
|
||||
void *user_data);
|
||||
|
||||
/**
|
||||
* @brief Configure sensor with interval/bit_cfg/delay values.
|
||||
*
|
||||
* @param sensor the sensor to be configured
|
||||
* @param interval sensor event interval
|
||||
* @param bit_cfg sensor bit config
|
||||
* @param delay sensor delay
|
||||
*
|
||||
* @return true if success, false otherwise
|
||||
*/
|
||||
bool
|
||||
sensor_config(sensor_t sensor, int interval, int bit_cfg, int delay);
|
||||
|
||||
/**
|
||||
* @brief Configure sensor with attr_container_t object.
|
||||
*
|
||||
* @param sensor the sensor to be configured
|
||||
* @param cfg the configuration
|
||||
*
|
||||
* @return true if success, false otherwise
|
||||
*/
|
||||
bool
|
||||
sensor_config_with_attr_container(sensor_t sensor, attr_container_t *cfg);
|
||||
|
||||
/**
|
||||
* @brief Close sensor.
|
||||
*
|
||||
* @param sensor the sensor to be closed
|
||||
*
|
||||
* @return true if success, false otherwise
|
||||
*/
|
||||
bool
|
||||
sensor_close(sensor_t sensor);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,11 +0,0 @@
|
|||
# Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
set (WASM_APP_SENSOR_DIR ${CMAKE_CURRENT_LIST_DIR})
|
||||
|
||||
include_directories(${WASM_APP_SENSOR_DIR})
|
||||
|
||||
|
||||
file (GLOB_RECURSE source_all ${WASM_APP_SENSOR_DIR}/*.c)
|
||||
|
||||
set (WASM_APP_CURRENT_SOURCE ${source_all})
|
|
@ -1,434 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#include "runtime_sensor.h"
|
||||
#include "app_manager_export.h"
|
||||
#include "module_wasm_app.h"
|
||||
#include "bh_platform.h"
|
||||
|
||||
static sys_sensor_t *g_sys_sensors = NULL;
|
||||
static uint32 g_sensor_id_max = 0;
|
||||
|
||||
static sensor_client_t *
|
||||
find_sensor_client(sys_sensor_t *sensor, unsigned int client_id,
|
||||
bool remove_if_found);
|
||||
|
||||
void (*rechedule_sensor_callback)() = NULL;
|
||||
|
||||
/*
|
||||
* API for the applications to call - don't call it from the runtime
|
||||
*
|
||||
*/
|
||||
|
||||
static void
|
||||
sensor_event_cleaner(sensor_event_data_t *sensor_event)
|
||||
{
|
||||
if (sensor_event->data != NULL) {
|
||||
if (sensor_event->data_fmt == FMT_ATTR_CONTAINER)
|
||||
attr_container_destroy(sensor_event->data);
|
||||
else
|
||||
wasm_runtime_free(sensor_event->data);
|
||||
}
|
||||
|
||||
wasm_runtime_free(sensor_event);
|
||||
}
|
||||
|
||||
static void
|
||||
wasm_sensor_callback(void *client, uint32 sensor_id, void *user_data)
|
||||
{
|
||||
attr_container_t *sensor_data = (attr_container_t *)user_data;
|
||||
attr_container_t *sensor_data_clone;
|
||||
int sensor_data_len;
|
||||
sensor_event_data_t *sensor_event;
|
||||
bh_message_t msg;
|
||||
sensor_client_t *c = (sensor_client_t *)client;
|
||||
|
||||
module_data *module = module_data_list_lookup_id(c->client_id);
|
||||
if (module == NULL)
|
||||
return;
|
||||
|
||||
if (sensor_data == NULL)
|
||||
return;
|
||||
|
||||
sensor_data_len = attr_container_get_serialize_length(sensor_data);
|
||||
sensor_data_clone =
|
||||
(attr_container_t *)wasm_runtime_malloc(sensor_data_len);
|
||||
if (sensor_data_clone == NULL)
|
||||
return;
|
||||
|
||||
/* multiple sensor clients may use/free the sensor data, so make a copy */
|
||||
bh_memcpy_s(sensor_data_clone, sensor_data_len, sensor_data,
|
||||
sensor_data_len);
|
||||
|
||||
sensor_event =
|
||||
(sensor_event_data_t *)wasm_runtime_malloc(sizeof(*sensor_event));
|
||||
if (sensor_event == NULL) {
|
||||
wasm_runtime_free(sensor_data_clone);
|
||||
return;
|
||||
}
|
||||
|
||||
memset(sensor_event, 0, sizeof(*sensor_event));
|
||||
sensor_event->sensor_id = sensor_id;
|
||||
sensor_event->data = sensor_data_clone;
|
||||
sensor_event->data_fmt = FMT_ATTR_CONTAINER;
|
||||
|
||||
msg = bh_new_msg(SENSOR_EVENT_WASM, sensor_event, sizeof(*sensor_event),
|
||||
sensor_event_cleaner);
|
||||
if (!msg) {
|
||||
sensor_event_cleaner(sensor_event);
|
||||
return;
|
||||
}
|
||||
|
||||
bh_post_msg2(module->queue, msg);
|
||||
}
|
||||
|
||||
bool
|
||||
wasm_sensor_config(wasm_exec_env_t exec_env, uint32 sensor, uint32 interval,
|
||||
int bit_cfg, uint32 delay)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
attr_container_t *attr_cont;
|
||||
sensor_client_t *c;
|
||||
sensor_obj_t s = find_sys_sensor_id(sensor);
|
||||
if (s == NULL)
|
||||
return false;
|
||||
|
||||
unsigned int mod_id =
|
||||
app_manager_get_module_id(Module_WASM_App, module_inst);
|
||||
bh_assert(mod_id != ID_NONE);
|
||||
|
||||
os_mutex_lock(&s->lock);
|
||||
|
||||
c = find_sensor_client(s, mod_id, false);
|
||||
if (c == NULL) {
|
||||
os_mutex_unlock(&s->lock);
|
||||
return false;
|
||||
}
|
||||
|
||||
c->interval = interval;
|
||||
c->bit_cfg = bit_cfg;
|
||||
c->delay = delay;
|
||||
|
||||
os_mutex_unlock(&s->lock);
|
||||
|
||||
if (s->config != NULL) {
|
||||
attr_cont = attr_container_create("config sensor");
|
||||
attr_container_set_int(&attr_cont, "interval", (int)interval);
|
||||
attr_container_set_int(&attr_cont, "bit_cfg", bit_cfg);
|
||||
attr_container_set_int(&attr_cont, "delay", (int)delay);
|
||||
s->config(s, attr_cont);
|
||||
attr_container_destroy(attr_cont);
|
||||
}
|
||||
|
||||
refresh_read_interval(s);
|
||||
|
||||
reschedule_sensor_read();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
uint32
|
||||
wasm_sensor_open(wasm_exec_env_t exec_env, char *name, int instance)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
|
||||
if (name != NULL) {
|
||||
sensor_client_t *c;
|
||||
sys_sensor_t *s = find_sys_sensor(name, instance);
|
||||
if (s == NULL)
|
||||
return (uint32)-1;
|
||||
|
||||
unsigned int mod_id =
|
||||
app_manager_get_module_id(Module_WASM_App, module_inst);
|
||||
bh_assert(mod_id != ID_NONE);
|
||||
|
||||
os_mutex_lock(&s->lock);
|
||||
|
||||
c = find_sensor_client(s, mod_id, false);
|
||||
if (c) {
|
||||
// the app already opened this sensor
|
||||
os_mutex_unlock(&s->lock);
|
||||
return (uint32)-1;
|
||||
}
|
||||
|
||||
sensor_client_t *client =
|
||||
(sensor_client_t *)wasm_runtime_malloc(sizeof(sensor_client_t));
|
||||
if (client == NULL) {
|
||||
os_mutex_unlock(&s->lock);
|
||||
return (uint32)-1;
|
||||
}
|
||||
|
||||
memset(client, 0, sizeof(sensor_client_t));
|
||||
client->client_id = mod_id;
|
||||
client->client_callback = (void *)wasm_sensor_callback;
|
||||
client->interval = s->default_interval;
|
||||
client->next = s->clients;
|
||||
s->clients = client;
|
||||
|
||||
os_mutex_unlock(&s->lock);
|
||||
|
||||
refresh_read_interval(s);
|
||||
|
||||
reschedule_sensor_read();
|
||||
|
||||
return s->sensor_id;
|
||||
}
|
||||
|
||||
return (uint32)-1;
|
||||
}
|
||||
|
||||
bool
|
||||
wasm_sensor_config_with_attr_container(wasm_exec_env_t exec_env, uint32 sensor,
|
||||
char *buffer, int len)
|
||||
{
|
||||
if (buffer != NULL) {
|
||||
attr_container_t *cfg = (attr_container_t *)buffer;
|
||||
sensor_obj_t s = find_sys_sensor_id(sensor);
|
||||
if (s == NULL)
|
||||
return false;
|
||||
|
||||
if (s->config == NULL)
|
||||
return false;
|
||||
|
||||
return s->config(s, cfg);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
wasm_sensor_close(wasm_exec_env_t exec_env, uint32 sensor)
|
||||
{
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
unsigned int mod_id =
|
||||
app_manager_get_module_id(Module_WASM_App, module_inst);
|
||||
unsigned int client_id = mod_id;
|
||||
sensor_obj_t s = find_sys_sensor_id(sensor);
|
||||
sensor_client_t *c;
|
||||
|
||||
bh_assert(mod_id != ID_NONE);
|
||||
|
||||
if (s == NULL)
|
||||
return false;
|
||||
|
||||
os_mutex_lock(&s->lock);
|
||||
if ((c = find_sensor_client(s, client_id, true)) != NULL)
|
||||
wasm_runtime_free(c);
|
||||
os_mutex_unlock(&s->lock);
|
||||
|
||||
refresh_read_interval(s);
|
||||
|
||||
reschedule_sensor_read();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* sensor framework API - don't expose to the applications
|
||||
*
|
||||
*/
|
||||
void
|
||||
set_sensor_reshceduler(void (*callback)())
|
||||
{
|
||||
rechedule_sensor_callback = callback;
|
||||
}
|
||||
|
||||
// used for other threads to wakeup the sensor read thread
|
||||
void
|
||||
reschedule_sensor_read()
|
||||
{
|
||||
if (rechedule_sensor_callback)
|
||||
rechedule_sensor_callback();
|
||||
}
|
||||
|
||||
void
|
||||
refresh_read_interval(sensor_obj_t sensor)
|
||||
{
|
||||
sensor_client_t *c;
|
||||
uint32 interval = sensor->default_interval;
|
||||
os_mutex_lock(&sensor->lock);
|
||||
|
||||
c = sensor->clients;
|
||||
if (c)
|
||||
interval = c->interval;
|
||||
|
||||
while (c) {
|
||||
if (c->interval < interval)
|
||||
interval = c->interval;
|
||||
c = c->next;
|
||||
}
|
||||
|
||||
os_mutex_unlock(&sensor->lock);
|
||||
|
||||
sensor->read_interval = interval;
|
||||
}
|
||||
|
||||
sensor_obj_t
|
||||
add_sys_sensor(char *name, char *description, int instance,
|
||||
uint32 default_interval, void *read_func, void *config_func)
|
||||
{
|
||||
sys_sensor_t *s = (sys_sensor_t *)wasm_runtime_malloc(sizeof(sys_sensor_t));
|
||||
if (s == NULL)
|
||||
return NULL;
|
||||
|
||||
memset(s, 0, sizeof(*s));
|
||||
s->name = bh_strdup(name);
|
||||
s->sensor_instance = instance;
|
||||
s->default_interval = default_interval;
|
||||
|
||||
if (!s->name) {
|
||||
wasm_runtime_free(s);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (description) {
|
||||
s->description = bh_strdup(description);
|
||||
if (!s->description) {
|
||||
wasm_runtime_free(s->name);
|
||||
wasm_runtime_free(s);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
g_sensor_id_max++;
|
||||
if (g_sensor_id_max == UINT32_MAX)
|
||||
g_sensor_id_max++;
|
||||
s->sensor_id = g_sensor_id_max;
|
||||
|
||||
s->read = read_func;
|
||||
s->config = config_func;
|
||||
|
||||
if (g_sys_sensors == NULL) {
|
||||
g_sys_sensors = s;
|
||||
}
|
||||
else {
|
||||
s->next = g_sys_sensors;
|
||||
g_sys_sensors = s;
|
||||
}
|
||||
|
||||
if (os_mutex_init(&s->lock) != 0) {
|
||||
if (s->description) {
|
||||
wasm_runtime_free(s->description);
|
||||
}
|
||||
wasm_runtime_free(s->name);
|
||||
wasm_runtime_free(s);
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
sensor_obj_t
|
||||
find_sys_sensor(const char *name, int instance)
|
||||
{
|
||||
sys_sensor_t *s = g_sys_sensors;
|
||||
while (s) {
|
||||
if (strcmp(s->name, name) == 0 && s->sensor_instance == instance)
|
||||
return s;
|
||||
|
||||
s = s->next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sensor_obj_t
|
||||
find_sys_sensor_id(uint32 sensor_id)
|
||||
{
|
||||
sys_sensor_t *s = g_sys_sensors;
|
||||
while (s) {
|
||||
if (s->sensor_id == sensor_id)
|
||||
return s;
|
||||
|
||||
s = s->next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sensor_client_t *
|
||||
find_sensor_client(sys_sensor_t *sensor, unsigned int client_id,
|
||||
bool remove_if_found)
|
||||
{
|
||||
sensor_client_t *prev = NULL, *c = sensor->clients;
|
||||
|
||||
while (c) {
|
||||
sensor_client_t *next = c->next;
|
||||
if (c->client_id == client_id) {
|
||||
if (remove_if_found) {
|
||||
if (prev)
|
||||
prev->next = next;
|
||||
else
|
||||
sensor->clients = next;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
else {
|
||||
prev = c;
|
||||
c = c->next;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// return the milliseconds to next check
|
||||
uint32
|
||||
check_sensor_timers()
|
||||
{
|
||||
uint32 ms_to_next_check = UINT32_MAX;
|
||||
uint32 now = (uint32)bh_get_tick_ms();
|
||||
|
||||
sys_sensor_t *s = g_sys_sensors;
|
||||
while (s) {
|
||||
uint32 last_read = s->last_read;
|
||||
uint32 elpased_ms = bh_get_elpased_ms(&last_read);
|
||||
|
||||
if (s->read_interval <= 0 || s->clients == NULL) {
|
||||
s = s->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (elpased_ms >= s->read_interval) {
|
||||
attr_container_t *data = s->read(s);
|
||||
if (data) {
|
||||
sensor_client_t *client = s->clients;
|
||||
while (client) {
|
||||
client->client_callback(client, s->sensor_id, data);
|
||||
client = client->next;
|
||||
}
|
||||
attr_container_destroy(data);
|
||||
}
|
||||
|
||||
s->last_read = now;
|
||||
|
||||
if (s->read_interval < ms_to_next_check)
|
||||
ms_to_next_check = s->read_interval;
|
||||
}
|
||||
else {
|
||||
uint32 remaining = s->read_interval - elpased_ms;
|
||||
if (remaining < ms_to_next_check)
|
||||
ms_to_next_check = remaining;
|
||||
}
|
||||
|
||||
s = s->next;
|
||||
}
|
||||
|
||||
return ms_to_next_check;
|
||||
}
|
||||
|
||||
void
|
||||
sensor_cleanup_callback(uint32 module_id)
|
||||
{
|
||||
sys_sensor_t *s = g_sys_sensors;
|
||||
|
||||
while (s) {
|
||||
sensor_client_t *c;
|
||||
os_mutex_lock(&s->lock);
|
||||
if ((c = find_sensor_client(s, module_id, true)) != NULL) {
|
||||
wasm_runtime_free(c);
|
||||
}
|
||||
os_mutex_unlock(&s->lock);
|
||||
s = s->next;
|
||||
}
|
||||
}
|
|
@ -1,69 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#ifndef LIB_EXTENSION_RUNTIME_SENSOR_H_
|
||||
#define LIB_EXTENSION_RUNTIME_SENSOR_H_
|
||||
|
||||
#include "bh_platform.h"
|
||||
#include "bi-inc/attr_container.h"
|
||||
#include "wasm_export.h"
|
||||
#include "sensor_native_api.h"
|
||||
|
||||
struct _sys_sensor;
|
||||
typedef struct _sys_sensor *sensor_obj_t;
|
||||
|
||||
typedef struct _sensor_client {
|
||||
struct _sensor_client *next;
|
||||
unsigned int client_id; // the app id
|
||||
uint32 interval;
|
||||
int bit_cfg;
|
||||
uint32 delay;
|
||||
void (*client_callback)(void *client, uint32, attr_container_t *);
|
||||
} sensor_client_t;
|
||||
|
||||
typedef struct _sys_sensor {
|
||||
struct _sys_sensor *next;
|
||||
char *name;
|
||||
int sensor_instance;
|
||||
char *description;
|
||||
uint32 sensor_id;
|
||||
sensor_client_t *clients;
|
||||
/* app, sensor mgr and app mgr may access the clients at the same time,
|
||||
so need a lock to protect the clients */
|
||||
korp_mutex lock;
|
||||
uint32 last_read;
|
||||
uint32 read_interval;
|
||||
uint32 default_interval;
|
||||
|
||||
/* TODO: may support other type return value, such as 'cbor' */
|
||||
attr_container_t *(*read)(void *);
|
||||
bool (*config)(void *, void *);
|
||||
|
||||
} sys_sensor_t;
|
||||
|
||||
sensor_obj_t
|
||||
add_sys_sensor(char *name, char *description, int instance,
|
||||
uint32 default_interval, void *read_func, void *config_func);
|
||||
sensor_obj_t
|
||||
find_sys_sensor(const char *name, int instance);
|
||||
sensor_obj_t
|
||||
find_sys_sensor_id(uint32 sensor_id);
|
||||
void
|
||||
refresh_read_interval(sensor_obj_t sensor);
|
||||
void
|
||||
sensor_cleanup_callback(uint32 module_id);
|
||||
uint32
|
||||
check_sensor_timers();
|
||||
void
|
||||
reschedule_sensor_read();
|
||||
|
||||
bool
|
||||
init_sensor_framework();
|
||||
void
|
||||
start_sensor_framework();
|
||||
void
|
||||
exit_sensor_framework();
|
||||
|
||||
#endif /* LIB_EXTENSION_RUNTIME_SENSOR_H_ */
|
|
@ -1,9 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
EXPORT_WASM_API_WITH_SIG(wasm_sensor_open, "($i)i"),
|
||||
EXPORT_WASM_API_WITH_SIG(wasm_sensor_config, "(iiii)i"),
|
||||
EXPORT_WASM_API_WITH_SIG(wasm_sensor_config_with_attr_container, "(i*~)i"),
|
||||
EXPORT_WASM_API_WITH_SIG(wasm_sensor_close, "(i)i"),
|
|
@ -1,148 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#include "bh_platform.h"
|
||||
#include "runtime_sensor.h"
|
||||
#include "bi-inc/attr_container.h"
|
||||
#include "module_wasm_app.h"
|
||||
#include "wasm_export.h"
|
||||
|
||||
/*
|
||||
*
|
||||
* One reference implementation for sensor manager
|
||||
*
|
||||
*
|
||||
*/
|
||||
static korp_cond cond;
|
||||
static korp_mutex mutex;
|
||||
static bool sensor_check_thread_run = true;
|
||||
|
||||
void
|
||||
app_mgr_sensor_event_callback(module_data *m_data, bh_message_t msg)
|
||||
{
|
||||
uint32 argv[3];
|
||||
wasm_function_inst_t func_onSensorEvent;
|
||||
|
||||
bh_assert(SENSOR_EVENT_WASM == bh_message_type(msg));
|
||||
wasm_data *wasm_app_data = (wasm_data *)m_data->internal_data;
|
||||
wasm_module_inst_t inst = wasm_app_data->wasm_module_inst;
|
||||
|
||||
sensor_event_data_t *payload =
|
||||
(sensor_event_data_t *)bh_message_payload(msg);
|
||||
if (payload == NULL)
|
||||
return;
|
||||
|
||||
func_onSensorEvent =
|
||||
wasm_runtime_lookup_function(inst, "_on_sensor_event", "(i32i32i32)");
|
||||
if (!func_onSensorEvent)
|
||||
func_onSensorEvent = wasm_runtime_lookup_function(
|
||||
inst, "on_sensor_event", "(i32i32i32)");
|
||||
if (!func_onSensorEvent) {
|
||||
printf("Cannot find function on_sensor_event\n");
|
||||
}
|
||||
else {
|
||||
int32 sensor_data_offset;
|
||||
uint32 sensor_data_len;
|
||||
|
||||
if (payload->data_fmt == FMT_ATTR_CONTAINER) {
|
||||
sensor_data_len =
|
||||
attr_container_get_serialize_length(payload->data);
|
||||
}
|
||||
else {
|
||||
printf("Unsupported sensor data format: %d\n", payload->data_fmt);
|
||||
return;
|
||||
}
|
||||
|
||||
sensor_data_offset =
|
||||
wasm_runtime_module_dup_data(inst, payload->data, sensor_data_len);
|
||||
if (sensor_data_offset == 0) {
|
||||
const char *exception = wasm_runtime_get_exception(inst);
|
||||
if (exception) {
|
||||
printf("Got exception running wasm code: %s\n", exception);
|
||||
wasm_runtime_clear_exception(inst);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
argv[0] = payload->sensor_id;
|
||||
argv[1] = (uint32)sensor_data_offset;
|
||||
argv[2] = sensor_data_len;
|
||||
|
||||
if (!wasm_runtime_call_wasm(wasm_app_data->exec_env, func_onSensorEvent,
|
||||
3, argv)) {
|
||||
const char *exception = wasm_runtime_get_exception(inst);
|
||||
bh_assert(exception);
|
||||
printf(":Got exception running wasm code: %s\n", exception);
|
||||
wasm_runtime_clear_exception(inst);
|
||||
wasm_runtime_module_free(inst, sensor_data_offset);
|
||||
return;
|
||||
}
|
||||
|
||||
wasm_runtime_module_free(inst, sensor_data_offset);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
thread_sensor_check(void *arg)
|
||||
{
|
||||
while (sensor_check_thread_run) {
|
||||
uint32 ms_to_expiry = check_sensor_timers();
|
||||
if (ms_to_expiry == UINT32_MAX)
|
||||
ms_to_expiry = 5000;
|
||||
os_mutex_lock(&mutex);
|
||||
os_cond_reltimedwait(&cond, &mutex, ms_to_expiry * 1000);
|
||||
os_mutex_unlock(&mutex);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
cb_wakeup_thread()
|
||||
{
|
||||
os_cond_signal(&cond);
|
||||
}
|
||||
|
||||
void
|
||||
set_sensor_reshceduler(void (*callback)());
|
||||
|
||||
bool
|
||||
init_sensor_framework()
|
||||
{
|
||||
/* init the mutext and conditions */
|
||||
if (os_cond_init(&cond) != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (os_mutex_init(&mutex) != 0) {
|
||||
os_cond_destroy(&cond);
|
||||
return false;
|
||||
}
|
||||
|
||||
set_sensor_reshceduler(cb_wakeup_thread);
|
||||
|
||||
wasm_register_msg_callback(SENSOR_EVENT_WASM,
|
||||
app_mgr_sensor_event_callback);
|
||||
|
||||
wasm_register_cleanup_callback(sensor_cleanup_callback);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
start_sensor_framework()
|
||||
{
|
||||
korp_tid tid;
|
||||
|
||||
os_thread_create(&tid, (void *)thread_sensor_check, NULL,
|
||||
BH_APPLET_PRESERVED_STACK_SIZE);
|
||||
}
|
||||
|
||||
void
|
||||
exit_sensor_framework()
|
||||
{
|
||||
sensor_check_thread_run = false;
|
||||
reschedule_sensor_read();
|
||||
|
||||
// todo: wait the sensor thread termination
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#ifndef _SENSOR_NATIVE_API_H_
|
||||
#define _SENSOR_NATIVE_API_H_
|
||||
|
||||
#include "bh_platform.h"
|
||||
#include "wasm_export.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
bool
|
||||
wasm_sensor_config(wasm_exec_env_t exec_env, uint32 sensor, uint32 interval,
|
||||
int bit_cfg, uint32 delay);
|
||||
uint32
|
||||
wasm_sensor_open(wasm_exec_env_t exec_env, char *name, int instance);
|
||||
|
||||
bool
|
||||
wasm_sensor_config_with_attr_container(wasm_exec_env_t exec_env, uint32 sensor,
|
||||
char *buffer, int len);
|
||||
|
||||
bool
|
||||
wasm_sensor_close(wasm_exec_env_t exec_env, uint32 sensor);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* end of _SENSOR_NATIVE_API_H_ */
|
|
@ -1,14 +0,0 @@
|
|||
# Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
set (WASM_LIB_SENSOR_DIR ${CMAKE_CURRENT_LIST_DIR})
|
||||
|
||||
add_definitions (-DAPP_FRAMEWORK_SENSOR)
|
||||
|
||||
include_directories(${WASM_LIB_SENSOR_DIR})
|
||||
|
||||
|
||||
file (GLOB_RECURSE source_all ${WASM_LIB_SENSOR_DIR}/*.c)
|
||||
|
||||
set (WASM_APP_LIB_CURRENT_SOURCE ${source_all})
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
/*
|
||||
header file for wasm application
|
||||
*/
|
|
@ -1,16 +0,0 @@
|
|||
# Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
set (WASM_APP_CURRENT_DIR ${CMAKE_CURRENT_LIST_DIR})
|
||||
|
||||
include_directories(
|
||||
${WASM_APP_CURRENT_DIR}
|
||||
# Add your include dir here
|
||||
)
|
||||
|
||||
file (GLOB_RECURSE source_all
|
||||
${WASM_APP_CURRENT_DIR}/*.c
|
||||
# Add your source file here
|
||||
)
|
||||
|
||||
set (WASM_APP_CURRENT_SOURCE ${source_all})
|
|
@ -1,6 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
/* EXPORT_WASM_API(your_api_here), */
|
|
@ -1,17 +0,0 @@
|
|||
# Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
|
||||
set (WASM_LIB_CURRENT_DIR ${CMAKE_CURRENT_LIST_DIR})
|
||||
|
||||
include_directories(
|
||||
${WASM_LIB_CURRENT_DIR}
|
||||
# Add your include dir here
|
||||
)
|
||||
|
||||
file (GLOB_RECURSE source_all
|
||||
${WASM_LIB_CURRENT_DIR}/*.c
|
||||
# Add your source file here
|
||||
)
|
||||
|
||||
set (WASM_APP_LIB_CURRENT_SOURCE ${source_all})
|
||||
|
|
@ -1,35 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#ifndef _GUI_API_H_
|
||||
#define _GUI_API_H_
|
||||
|
||||
#include "bh_platform.h"
|
||||
#include "bi-inc/wgl_shared_utils.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void
|
||||
wasm_obj_native_call(int32 func_id, uint32 *argv, uint32 argc);
|
||||
|
||||
void
|
||||
wasm_btn_native_call(int32 func_id, uint32 *argv, uint32 argc);
|
||||
|
||||
void
|
||||
wasm_label_native_call(int32 func_id, uint32 *argv, uint32 argc);
|
||||
|
||||
void
|
||||
wasm_cb_native_call(int32 func_id, uint32 *argv, uint32 argc);
|
||||
|
||||
void
|
||||
wasm_list_native_call(int32 func_id, uint32 *argv, uint32 argc);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* end of _GUI_API_H_ */
|
|
@ -1,46 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
WGL_ROOT=$(cd "$(dirname "$0")/" && pwd)
|
||||
LVGL_REPO_DIR=${WGL_ROOT}/../../../deps/lvgl
|
||||
ls $LVGL_REPO_DIR
|
||||
|
||||
#if [ ! -d "${LVGL_REPO_DIR}" ]; then
|
||||
# echo "lvgl repo not exist, please git pull the lvgl v6.0 first"
|
||||
# exit 1
|
||||
#fi
|
||||
|
||||
cd ${WGL_ROOT}/wa-inc/lvgl
|
||||
pwd
|
||||
|
||||
if [ -d src ]; then
|
||||
rm -rf src
|
||||
echo "deleted the src folder from previous preparation."
|
||||
fi
|
||||
|
||||
mkdir src
|
||||
cd src
|
||||
|
||||
cp ${LVGL_REPO_DIR}/src/*.h ./
|
||||
|
||||
for folder in lv_core lv_draw lv_hal lv_objx lv_font lv_misc lv_themes
|
||||
do
|
||||
echo "Prepare fold $folder...done"
|
||||
mkdir $folder
|
||||
cp ${LVGL_REPO_DIR}/src/${folder}/*.h ./${folder}/
|
||||
done
|
||||
|
||||
cp -f ../lv_obj.h ./lv_core/lv_obj.h
|
||||
|
||||
echo "test the header files..."
|
||||
cd ..
|
||||
|
||||
gcc test.c -o test.out
|
||||
if [ $? != 0 ];then
|
||||
echo "failed to compile the test.c"
|
||||
exit 1
|
||||
else
|
||||
echo "okay"
|
||||
rm test.out
|
||||
fi
|
||||
|
||||
echo "lvgl header files for WASM application ready."
|
|
@ -1,135 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#include "wa-inc/lvgl/lvgl.h"
|
||||
#include "bh_platform.h"
|
||||
#include "gui_api.h"
|
||||
|
||||
#define ARGC sizeof(argv) / sizeof(uint32)
|
||||
#define CALL_BTN_NATIVE_FUNC(id) wasm_btn_native_call(id, argv, ARGC)
|
||||
|
||||
lv_obj_t *
|
||||
lv_btn_create(lv_obj_t *par, const lv_obj_t *copy)
|
||||
{
|
||||
uint32 argv[2] = { 0 };
|
||||
|
||||
argv[0] = (uint32)par;
|
||||
argv[1] = (uint32)copy;
|
||||
CALL_BTN_NATIVE_FUNC(BTN_FUNC_ID_CREATE);
|
||||
return (lv_obj_t *)argv[0];
|
||||
}
|
||||
|
||||
void
|
||||
lv_btn_set_toggle(lv_obj_t *btn, bool tgl)
|
||||
{
|
||||
uint32 argv[2] = { 0 };
|
||||
argv[0] = (uint32)btn;
|
||||
argv[1] = tgl;
|
||||
CALL_BTN_NATIVE_FUNC(BTN_FUNC_ID_SET_TOGGLE);
|
||||
}
|
||||
|
||||
void
|
||||
lv_btn_set_state(lv_obj_t *btn, lv_btn_state_t state)
|
||||
{
|
||||
uint32 argv[2] = { 0 };
|
||||
argv[0] = (uint32)btn;
|
||||
argv[1] = state;
|
||||
CALL_BTN_NATIVE_FUNC(BTN_FUNC_ID_SET_STATE);
|
||||
}
|
||||
|
||||
void
|
||||
lv_btn_toggle(lv_obj_t *btn)
|
||||
{
|
||||
uint32 argv[1] = { 0 };
|
||||
argv[0] = (uint32)btn;
|
||||
CALL_BTN_NATIVE_FUNC(BTN_FUNC_ID_TOGGLE);
|
||||
}
|
||||
|
||||
void
|
||||
lv_btn_set_ink_in_time(lv_obj_t *btn, uint16_t time)
|
||||
{
|
||||
uint32 argv[2] = { 0 };
|
||||
argv[0] = (uint32)btn;
|
||||
argv[1] = time;
|
||||
CALL_BTN_NATIVE_FUNC(BTN_FUNC_ID_SET_INK_IN_TIME);
|
||||
}
|
||||
|
||||
void
|
||||
lv_btn_set_ink_wait_time(lv_obj_t *btn, uint16_t time)
|
||||
{
|
||||
uint32 argv[2] = { 0 };
|
||||
argv[0] = (uint32)btn;
|
||||
argv[1] = time;
|
||||
CALL_BTN_NATIVE_FUNC(BTN_FUNC_ID_SET_INK_WAIT_TIME);
|
||||
}
|
||||
|
||||
void
|
||||
lv_btn_set_ink_out_time(lv_obj_t *btn, uint16_t time)
|
||||
{
|
||||
uint32 argv[2] = { 0 };
|
||||
argv[0] = (uint32)btn;
|
||||
argv[1] = time;
|
||||
CALL_BTN_NATIVE_FUNC(BTN_FUNC_ID_SET_INK_OUT_TIME);
|
||||
}
|
||||
|
||||
// void wgl_btn_set_style(wgl_obj_t btn, wgl_btn_style_t type,
|
||||
// const wgl_style_t *style)
|
||||
//{
|
||||
// //TODO: pack style
|
||||
// //wasm_btn_set_style(btn, type, style);
|
||||
//}
|
||||
//
|
||||
lv_btn_state_t
|
||||
lv_btn_get_state(const lv_obj_t *btn)
|
||||
{
|
||||
uint32 argv[1] = { 0 };
|
||||
argv[0] = (uint32)btn;
|
||||
CALL_BTN_NATIVE_FUNC(BTN_FUNC_ID_GET_STATE);
|
||||
return (lv_btn_state_t)argv[0];
|
||||
}
|
||||
|
||||
bool
|
||||
lv_btn_get_toggle(const lv_obj_t *btn)
|
||||
{
|
||||
uint32 argv[1] = { 0 };
|
||||
argv[0] = (uint32)btn;
|
||||
CALL_BTN_NATIVE_FUNC(BTN_FUNC_ID_GET_TOGGLE);
|
||||
return (bool)argv[0];
|
||||
}
|
||||
|
||||
uint16_t
|
||||
lv_btn_get_ink_in_time(const lv_obj_t *btn)
|
||||
{
|
||||
uint32 argv[1] = { 0 };
|
||||
argv[0] = (uint32)btn;
|
||||
CALL_BTN_NATIVE_FUNC(BTN_FUNC_ID_GET_INK_IN_TIME);
|
||||
return (uint16_t)argv[0];
|
||||
}
|
||||
|
||||
uint16_t
|
||||
lv_btn_get_ink_wait_time(const lv_obj_t *btn)
|
||||
{
|
||||
uint32 argv[1] = { 0 };
|
||||
argv[0] = (uint32)btn;
|
||||
CALL_BTN_NATIVE_FUNC(BTN_FUNC_ID_GET_INK_WAIT_TIME);
|
||||
return (uint16_t)argv[0];
|
||||
}
|
||||
|
||||
uint16_t
|
||||
lv_btn_get_ink_out_time(const lv_obj_t *btn)
|
||||
{
|
||||
uint32 argv[1] = { 0 };
|
||||
argv[0] = (uint32)btn;
|
||||
CALL_BTN_NATIVE_FUNC(BTN_FUNC_ID_GET_INK_OUT_TIME);
|
||||
return (uint16_t)argv[0];
|
||||
}
|
||||
//
|
||||
// const wgl_style_t * wgl_btn_get_style(const wgl_obj_t btn,
|
||||
// wgl_btn_style_t type)
|
||||
//{
|
||||
// //TODO: pack style
|
||||
// //wasm_btn_get_style(btn, type);
|
||||
// return NULL;
|
||||
//}
|
|
@ -1,86 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#include "wa-inc/lvgl/lvgl.h"
|
||||
#include "gui_api.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#define ARGC sizeof(argv) / sizeof(uint32)
|
||||
#define CALL_CB_NATIVE_FUNC(id) wasm_cb_native_call(id, argv, ARGC)
|
||||
|
||||
lv_obj_t *
|
||||
lv_cb_create(lv_obj_t *par, const lv_obj_t *copy)
|
||||
{
|
||||
uint32 argv[2] = { 0 };
|
||||
|
||||
argv[0] = (uint32)par;
|
||||
argv[1] = (uint32)copy;
|
||||
CALL_CB_NATIVE_FUNC(CB_FUNC_ID_CREATE);
|
||||
return (lv_obj_t *)argv[0];
|
||||
}
|
||||
|
||||
void
|
||||
lv_cb_set_text(lv_obj_t *cb, const char *txt)
|
||||
{
|
||||
uint32 argv[3] = { 0 };
|
||||
argv[0] = (uint32)cb;
|
||||
argv[1] = (uint32)txt;
|
||||
argv[2] = strlen(txt) + 1;
|
||||
CALL_CB_NATIVE_FUNC(CB_FUNC_ID_SET_TEXT);
|
||||
}
|
||||
|
||||
void
|
||||
lv_cb_set_static_text(lv_obj_t *cb, const char *txt)
|
||||
{
|
||||
uint32 argv[3] = { 0 };
|
||||
argv[0] = (uint32)cb;
|
||||
argv[1] = (uint32)txt;
|
||||
argv[2] = strlen(txt) + 1;
|
||||
CALL_CB_NATIVE_FUNC(CB_FUNC_ID_SET_STATIC_TEXT);
|
||||
}
|
||||
|
||||
// void wgl_cb_set_style(wgl_obj_t cb, wgl_cb_style_t type,
|
||||
// const wgl_style_t *style)
|
||||
//{
|
||||
// //TODO:
|
||||
//}
|
||||
//
|
||||
|
||||
static unsigned int
|
||||
wgl_cb_get_text_length(lv_obj_t *cb)
|
||||
{
|
||||
uint32 argv[1] = { 0 };
|
||||
argv[0] = (uint32)cb;
|
||||
CALL_CB_NATIVE_FUNC(CB_FUNC_ID_GET_TEXT_LENGTH);
|
||||
return argv[0];
|
||||
}
|
||||
|
||||
static char *
|
||||
wgl_cb_get_text(lv_obj_t *cb, char *buffer, int buffer_len)
|
||||
{
|
||||
uint32 argv[3] = { 0 };
|
||||
argv[0] = (uint32)cb;
|
||||
argv[1] = (uint32)buffer;
|
||||
argv[2] = buffer_len;
|
||||
CALL_CB_NATIVE_FUNC(CB_FUNC_ID_GET_TEXT);
|
||||
return (char *)argv[0];
|
||||
}
|
||||
|
||||
// TODO: need to use a global data buffer for the returned text
|
||||
const char *
|
||||
lv_cb_get_text(const lv_obj_t *cb)
|
||||
{
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// const wgl_style_t * wgl_cb_get_style(const wgl_obj_t cb,
|
||||
// wgl_cb_style_t type)
|
||||
//{
|
||||
// //TODO
|
||||
// return NULL;
|
||||
//}
|
||||
//
|
|
@ -1,260 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#include "wa-inc/lvgl/lvgl.h"
|
||||
#include "gui_api.h"
|
||||
#include <string.h>
|
||||
|
||||
#define ARGC sizeof(argv) / sizeof(uint32)
|
||||
#define CALL_LABEL_NATIVE_FUNC(id) wasm_label_native_call(id, argv, ARGC)
|
||||
|
||||
lv_obj_t *
|
||||
lv_label_create(lv_obj_t *par, const lv_obj_t *copy)
|
||||
{
|
||||
uint32 argv[2] = { 0 };
|
||||
|
||||
argv[0] = (uint32)par;
|
||||
argv[1] = (uint32)copy;
|
||||
CALL_LABEL_NATIVE_FUNC(LABEL_FUNC_ID_CREATE);
|
||||
return (lv_obj_t *)argv[0];
|
||||
}
|
||||
|
||||
void
|
||||
lv_label_set_text(lv_obj_t *label, const char *text)
|
||||
{
|
||||
uint32 argv[3] = { 0 };
|
||||
argv[0] = (uint32)label;
|
||||
argv[1] = (uint32)text;
|
||||
argv[2] = strlen(text) + 1;
|
||||
CALL_LABEL_NATIVE_FUNC(LABEL_FUNC_ID_SET_TEXT);
|
||||
}
|
||||
|
||||
void
|
||||
lv_label_set_array_text(lv_obj_t *label, const char *array, uint16_t size)
|
||||
{
|
||||
uint32 argv[3] = { 0 };
|
||||
argv[0] = (uint32)label;
|
||||
argv[1] = (uint32)array;
|
||||
argv[2] = size;
|
||||
CALL_LABEL_NATIVE_FUNC(LABEL_FUNC_ID_SET_ARRAY_TEXT);
|
||||
}
|
||||
|
||||
void
|
||||
lv_label_set_static_text(lv_obj_t *label, const char *text)
|
||||
{
|
||||
uint32 argv[3] = { 0 };
|
||||
argv[0] = (uint32)label;
|
||||
argv[1] = (uint32)text;
|
||||
argv[2] = strlen(text) + 1;
|
||||
CALL_LABEL_NATIVE_FUNC(LABEL_FUNC_ID_SET_STATIC_TEXT);
|
||||
}
|
||||
|
||||
void
|
||||
lv_label_set_long_mode(lv_obj_t *label, lv_label_long_mode_t long_mode)
|
||||
{
|
||||
uint32 argv[2] = { 0 };
|
||||
argv[0] = (uint32)label;
|
||||
argv[1] = long_mode;
|
||||
CALL_LABEL_NATIVE_FUNC(LABEL_FUNC_ID_SET_LONG_MODE);
|
||||
}
|
||||
|
||||
void
|
||||
lv_label_set_align(lv_obj_t *label, lv_label_align_t align)
|
||||
{
|
||||
uint32 argv[2] = { 0 };
|
||||
argv[0] = (uint32)label;
|
||||
argv[1] = align;
|
||||
CALL_LABEL_NATIVE_FUNC(LABEL_FUNC_ID_SET_ALIGN);
|
||||
}
|
||||
|
||||
void
|
||||
lv_label_set_recolor(lv_obj_t *label, bool en)
|
||||
{
|
||||
uint32 argv[2] = { 0 };
|
||||
argv[0] = (uint32)label;
|
||||
argv[1] = en;
|
||||
CALL_LABEL_NATIVE_FUNC(LABEL_FUNC_ID_SET_RECOLOR);
|
||||
}
|
||||
|
||||
void
|
||||
lv_label_set_body_draw(lv_obj_t *label, bool en)
|
||||
{
|
||||
uint32 argv[2] = { 0 };
|
||||
argv[0] = (uint32)label;
|
||||
argv[1] = en;
|
||||
CALL_LABEL_NATIVE_FUNC(LABEL_FUNC_ID_SET_BODY_DRAW);
|
||||
}
|
||||
|
||||
void
|
||||
lv_label_set_anim_speed(lv_obj_t *label, uint16_t anim_speed)
|
||||
{
|
||||
uint32 argv[2] = { 0 };
|
||||
argv[0] = (uint32)label;
|
||||
argv[1] = anim_speed;
|
||||
CALL_LABEL_NATIVE_FUNC(LABEL_FUNC_ID_SET_ANIM_SPEED);
|
||||
}
|
||||
|
||||
void
|
||||
lv_label_set_text_sel_start(lv_obj_t *label, uint16_t index)
|
||||
{
|
||||
uint32 argv[2] = { 0 };
|
||||
argv[0] = (uint32)label;
|
||||
argv[1] = index;
|
||||
CALL_LABEL_NATIVE_FUNC(LABEL_FUNC_ID_SET_TEXT_SEL_START);
|
||||
}
|
||||
|
||||
void
|
||||
lv_label_set_text_sel_end(lv_obj_t *label, uint16_t index)
|
||||
{
|
||||
uint32 argv[2] = { 0 };
|
||||
argv[0] = (uint32)label;
|
||||
argv[1] = index;
|
||||
CALL_LABEL_NATIVE_FUNC(LABEL_FUNC_ID_SET_TEXT_SEL_END);
|
||||
}
|
||||
|
||||
unsigned int
|
||||
wgl_label_get_text_length(lv_obj_t *label)
|
||||
{
|
||||
uint32 argv[1] = { 0 };
|
||||
argv[0] = (uint32)label;
|
||||
CALL_LABEL_NATIVE_FUNC(LABEL_FUNC_ID_GET_TEXT_LENGTH);
|
||||
return argv[0];
|
||||
}
|
||||
|
||||
char *
|
||||
wgl_label_get_text(lv_obj_t *label, char *buffer, int buffer_len)
|
||||
{
|
||||
uint32 argv[3] = { 0 };
|
||||
argv[0] = (uint32)label;
|
||||
argv[1] = (uint32)buffer;
|
||||
argv[2] = buffer_len;
|
||||
CALL_LABEL_NATIVE_FUNC(LABEL_FUNC_ID_GET_TEXT);
|
||||
return (char *)argv[0];
|
||||
}
|
||||
|
||||
// TODO:
|
||||
char *
|
||||
lv_label_get_text(const lv_obj_t *label)
|
||||
{
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lv_label_long_mode_t
|
||||
lv_label_get_long_mode(const lv_obj_t *label)
|
||||
{
|
||||
uint32 argv[1] = { 0 };
|
||||
argv[0] = (uint32)label;
|
||||
CALL_LABEL_NATIVE_FUNC(LABEL_FUNC_ID_GET_LONG_MODE);
|
||||
return (lv_label_long_mode_t)argv[0];
|
||||
}
|
||||
|
||||
lv_label_align_t
|
||||
lv_label_get_align(const lv_obj_t *label)
|
||||
{
|
||||
uint32 argv[1] = { 0 };
|
||||
argv[0] = (uint32)label;
|
||||
CALL_LABEL_NATIVE_FUNC(LABEL_FUNC_ID_GET_ALIGN);
|
||||
return (lv_label_align_t)argv[0];
|
||||
}
|
||||
|
||||
bool
|
||||
lv_label_get_recolor(const lv_obj_t *label)
|
||||
{
|
||||
uint32 argv[1] = { 0 };
|
||||
argv[0] = (uint32)label;
|
||||
CALL_LABEL_NATIVE_FUNC(LABEL_FUNC_ID_GET_RECOLOR);
|
||||
return (bool)argv[0];
|
||||
}
|
||||
|
||||
bool
|
||||
lv_label_get_body_draw(const lv_obj_t *label)
|
||||
{
|
||||
uint32 argv[1] = { 0 };
|
||||
argv[0] = (uint32)label;
|
||||
CALL_LABEL_NATIVE_FUNC(LABEL_FUNC_ID_GET_BODY_DRAW);
|
||||
return (bool)argv[0];
|
||||
}
|
||||
|
||||
uint16_t
|
||||
lv_label_get_anim_speed(const lv_obj_t *label)
|
||||
{
|
||||
uint32 argv[1] = { 0 };
|
||||
argv[0] = (uint32)label;
|
||||
CALL_LABEL_NATIVE_FUNC(LABEL_FUNC_ID_GET_ANIM_SPEED);
|
||||
return (uint16_t)argv[0];
|
||||
}
|
||||
|
||||
void
|
||||
lv_label_get_letter_pos(const lv_obj_t *label, uint16_t index, lv_point_t *pos)
|
||||
{
|
||||
uint32 argv[4] = { 0 };
|
||||
argv[0] = (uint32)label;
|
||||
argv[1] = index;
|
||||
CALL_LABEL_NATIVE_FUNC(LABEL_FUNC_ID_GET_LETTER_POS);
|
||||
pos->x = argv[2];
|
||||
pos->y = argv[3];
|
||||
}
|
||||
|
||||
uint16_t
|
||||
lv_label_get_letter_on(const lv_obj_t *label, lv_point_t *pos)
|
||||
{
|
||||
uint32 argv[3] = { 0 };
|
||||
argv[0] = (uint32)label;
|
||||
argv[1] = pos->x;
|
||||
argv[2] = pos->y;
|
||||
CALL_LABEL_NATIVE_FUNC(LABEL_FUNC_ID_GET_LETTER_POS);
|
||||
return (uint16_t)argv[0];
|
||||
}
|
||||
|
||||
bool
|
||||
lv_label_is_char_under_pos(const lv_obj_t *label, lv_point_t *pos)
|
||||
{
|
||||
uint32 argv[3] = { 0 };
|
||||
argv[0] = (uint32)label;
|
||||
argv[1] = pos->x;
|
||||
argv[2] = pos->y;
|
||||
CALL_LABEL_NATIVE_FUNC(LABEL_FUNC_ID_GET_LETTER_POS);
|
||||
return (bool)argv[0];
|
||||
}
|
||||
|
||||
uint16_t
|
||||
lv_label_get_text_sel_start(const lv_obj_t *label)
|
||||
{
|
||||
uint32 argv[1] = { 0 };
|
||||
argv[0] = (uint32)label;
|
||||
CALL_LABEL_NATIVE_FUNC(LABEL_FUNC_ID_GET_TEXT_SEL_START);
|
||||
return (uint16_t)argv[0];
|
||||
}
|
||||
|
||||
uint16_t
|
||||
lv_label_get_text_sel_end(const lv_obj_t *label)
|
||||
{
|
||||
uint32 argv[1] = { 0 };
|
||||
argv[0] = (uint32)label;
|
||||
CALL_LABEL_NATIVE_FUNC(LABEL_FUNC_ID_GET_TEXT_SEL_END);
|
||||
return (uint16_t)argv[0];
|
||||
}
|
||||
|
||||
void
|
||||
lv_label_ins_text(lv_obj_t *label, uint32_t pos, const char *txt)
|
||||
{
|
||||
uint32 argv[4] = { 0 };
|
||||
argv[0] = (uint32)label;
|
||||
argv[1] = pos;
|
||||
argv[2] = (uint32)txt;
|
||||
argv[3] = strlen(txt) + 1;
|
||||
CALL_LABEL_NATIVE_FUNC(LABEL_FUNC_ID_INS_TEXT);
|
||||
}
|
||||
|
||||
void
|
||||
lv_label_cut_text(lv_obj_t *label, uint32_t pos, uint32_t cnt)
|
||||
{
|
||||
uint32 argv[3] = { 0 };
|
||||
argv[0] = (uint32)label;
|
||||
argv[1] = pos;
|
||||
argv[2] = cnt;
|
||||
CALL_LABEL_NATIVE_FUNC(LABEL_FUNC_ID_CUT_TEXT);
|
||||
}
|
|
@ -1,155 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#include "wa-inc/lvgl/lvgl.h"
|
||||
#include "gui_api.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#define ARGC sizeof(argv) / sizeof(uint32)
|
||||
#define CALL_LIST_NATIVE_FUNC(id) wasm_list_native_call(id, argv, ARGC)
|
||||
|
||||
lv_obj_t *
|
||||
lv_list_create(lv_obj_t *par, const lv_obj_t *copy)
|
||||
{
|
||||
uint32 argv[2] = { 0 };
|
||||
|
||||
argv[0] = (uint32)par;
|
||||
argv[1] = (uint32)copy;
|
||||
|
||||
CALL_LIST_NATIVE_FUNC(LIST_FUNC_ID_CREATE);
|
||||
return (lv_obj_t *)argv[0];
|
||||
}
|
||||
//
|
||||
//
|
||||
// void wgl_list_clean(wgl_obj_t obj)
|
||||
//{
|
||||
// wasm_list_clean(obj);
|
||||
//}
|
||||
//
|
||||
|
||||
lv_obj_t *
|
||||
lv_list_add_btn(lv_obj_t *list, const void *img_src, const char *txt)
|
||||
{
|
||||
uint32 argv[3] = { 0 };
|
||||
|
||||
(void)img_src; /* doesn't support img src currently */
|
||||
|
||||
argv[0] = (uint32)list;
|
||||
argv[1] = (uint32)txt;
|
||||
argv[2] = strlen(txt) + 1;
|
||||
CALL_LIST_NATIVE_FUNC(LIST_FUNC_ID_ADD_BTN);
|
||||
return (lv_obj_t *)argv[0];
|
||||
}
|
||||
//
|
||||
//
|
||||
// bool wgl_list_remove(const wgl_obj_t list, uint16_t index)
|
||||
//{
|
||||
// return wasm_list_remove(list, index);
|
||||
//}
|
||||
//
|
||||
//
|
||||
// void wgl_list_set_single_mode(wgl_obj_t list, bool mode)
|
||||
//{
|
||||
// wasm_list_set_single_mode(list, mode);
|
||||
//}
|
||||
//
|
||||
//#if LV_USE_GROUP
|
||||
//
|
||||
//
|
||||
// void wgl_list_set_btn_selected(wgl_obj_t list, wgl_obj_t btn)
|
||||
//{
|
||||
// wasm_list_set_btn_selected(list, btn);
|
||||
//}
|
||||
//#endif
|
||||
//
|
||||
//
|
||||
// void wgl_list_set_style(wgl_obj_t list, wgl_list_style_t type,
|
||||
// const wgl_style_t * style)
|
||||
//{
|
||||
// //TODO
|
||||
//}
|
||||
//
|
||||
//
|
||||
// bool wgl_list_get_single_mode(wgl_obj_t list)
|
||||
//{
|
||||
// return wasm_list_get_single_mode(list);
|
||||
//}
|
||||
//
|
||||
//
|
||||
// const char * wgl_list_get_btn_text(const wgl_obj_t btn)
|
||||
//{
|
||||
// return wasm_list_get_btn_text(btn);
|
||||
//}
|
||||
//
|
||||
// wgl_obj_t wgl_list_get_btn_label(const wgl_obj_t btn)
|
||||
//{
|
||||
// return wasm_list_get_btn_label(btn);
|
||||
//}
|
||||
//
|
||||
//
|
||||
// wgl_obj_t wgl_list_get_btn_img(const wgl_obj_t btn)
|
||||
//{
|
||||
// return wasm_list_get_btn_img(btn);
|
||||
//}
|
||||
//
|
||||
//
|
||||
// wgl_obj_t wgl_list_get_prev_btn(const wgl_obj_t list, wgl_obj_t prev_btn)
|
||||
//{
|
||||
// return wasm_list_get_prev_btn(list, prev_btn);
|
||||
//}
|
||||
//
|
||||
//
|
||||
// wgl_obj_t wgl_list_get_next_btn(const wgl_obj_t list, wgl_obj_t prev_btn)
|
||||
//{
|
||||
// return wasm_list_get_next_btn(list, prev_btn);
|
||||
//}
|
||||
//
|
||||
//
|
||||
// int32_t wgl_list_get_btn_index(const wgl_obj_t list, const wgl_obj_t btn)
|
||||
//{
|
||||
// return wasm_list_get_btn_index(list, btn);
|
||||
//}
|
||||
//
|
||||
//
|
||||
// uint16_t wgl_list_get_size(const wgl_obj_t list)
|
||||
//{
|
||||
// return wasm_list_get_size(list);
|
||||
//}
|
||||
//
|
||||
//#if LV_USE_GROUP
|
||||
//
|
||||
// wgl_obj_t wgl_list_get_btn_selected(const wgl_obj_t list)
|
||||
//{
|
||||
// return wasm_list_get_btn_selected(list);
|
||||
//}
|
||||
//#endif
|
||||
//
|
||||
//
|
||||
//
|
||||
// const wgl_style_t * wgl_list_get_style(const wgl_obj_t list,
|
||||
// wgl_list_style_t type)
|
||||
//{
|
||||
// //TODO
|
||||
// return NULL;
|
||||
//}
|
||||
//
|
||||
//
|
||||
// void wgl_list_up(const wgl_obj_t list)
|
||||
//{
|
||||
// wasm_list_up(list);
|
||||
//}
|
||||
//
|
||||
// void wgl_list_down(const wgl_obj_t list)
|
||||
//{
|
||||
// wasm_list_down(list);
|
||||
//}
|
||||
//
|
||||
//
|
||||
// void wgl_list_focus(const wgl_obj_t btn, wgl_anim_enable_t anim)
|
||||
//{
|
||||
// wasm_list_focus(btn, anim);
|
||||
//}
|
||||
//
|
|
@ -1,124 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#include "wa-inc/lvgl/lvgl.h"
|
||||
#include "gui_api.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define ARGC sizeof(argv) / sizeof(uint32)
|
||||
#define CALL_OBJ_NATIVE_FUNC(id) wasm_obj_native_call(id, argv, ARGC)
|
||||
|
||||
typedef struct _obj_evt_cb {
|
||||
struct _obj_evt_cb *next;
|
||||
|
||||
lv_obj_t *obj;
|
||||
lv_event_cb_t event_cb;
|
||||
} obj_evt_cb_t;
|
||||
|
||||
static obj_evt_cb_t *g_obj_evt_cb_list = NULL;
|
||||
|
||||
/* For lvgl compatible */
|
||||
char g_widget_text[100];
|
||||
|
||||
lv_res_t
|
||||
lv_obj_del(lv_obj_t *obj)
|
||||
{
|
||||
uint32 argv[1] = { 0 };
|
||||
argv[0] = (uint32)obj;
|
||||
CALL_OBJ_NATIVE_FUNC(OBJ_FUNC_ID_DEL);
|
||||
return (lv_res_t)argv[0];
|
||||
}
|
||||
|
||||
void
|
||||
lv_obj_del_async(struct _lv_obj_t *obj)
|
||||
{
|
||||
uint32 argv[1] = { 0 };
|
||||
argv[0] = (uint32)obj;
|
||||
CALL_OBJ_NATIVE_FUNC(OBJ_FUNC_ID_DEL_ASYNC);
|
||||
}
|
||||
|
||||
void
|
||||
lv_obj_clean(lv_obj_t *obj)
|
||||
{
|
||||
uint32 argv[1] = { 0 };
|
||||
argv[0] = (uint32)obj;
|
||||
CALL_OBJ_NATIVE_FUNC(OBJ_FUNC_ID_CLEAN);
|
||||
}
|
||||
|
||||
void
|
||||
lv_obj_align(lv_obj_t *obj, const lv_obj_t *base, lv_align_t align,
|
||||
lv_coord_t x_mod, lv_coord_t y_mod)
|
||||
{
|
||||
uint32 argv[5] = { 0 };
|
||||
argv[0] = (uint32)obj;
|
||||
argv[1] = (uint32)base;
|
||||
argv[2] = align;
|
||||
argv[3] = x_mod;
|
||||
argv[4] = y_mod;
|
||||
CALL_OBJ_NATIVE_FUNC(OBJ_FUNC_ID_ALIGN);
|
||||
}
|
||||
|
||||
lv_event_cb_t
|
||||
lv_obj_get_event_cb(const lv_obj_t *obj)
|
||||
{
|
||||
obj_evt_cb_t *obj_evt_cb = g_obj_evt_cb_list;
|
||||
while (obj_evt_cb != NULL) {
|
||||
if (obj_evt_cb->obj == obj) {
|
||||
return obj_evt_cb->event_cb;
|
||||
}
|
||||
obj_evt_cb = obj_evt_cb->next;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
lv_obj_set_event_cb(lv_obj_t *obj, lv_event_cb_t event_cb)
|
||||
{
|
||||
obj_evt_cb_t *obj_evt_cb;
|
||||
uint32 argv[1] = { 0 };
|
||||
|
||||
obj_evt_cb = g_obj_evt_cb_list;
|
||||
while (obj_evt_cb) {
|
||||
if (obj_evt_cb->obj == obj) {
|
||||
obj_evt_cb->event_cb = event_cb;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
obj_evt_cb = (obj_evt_cb_t *)malloc(sizeof(*obj_evt_cb));
|
||||
if (obj_evt_cb == NULL)
|
||||
return;
|
||||
|
||||
memset(obj_evt_cb, 0, sizeof(*obj_evt_cb));
|
||||
obj_evt_cb->obj = obj;
|
||||
obj_evt_cb->event_cb = event_cb;
|
||||
|
||||
if (g_obj_evt_cb_list != NULL) {
|
||||
obj_evt_cb->next = g_obj_evt_cb_list;
|
||||
g_obj_evt_cb_list = obj_evt_cb;
|
||||
}
|
||||
else {
|
||||
g_obj_evt_cb_list = obj_evt_cb;
|
||||
}
|
||||
|
||||
argv[0] = (uint32)obj;
|
||||
CALL_OBJ_NATIVE_FUNC(OBJ_FUNC_ID_SET_EVT_CB);
|
||||
}
|
||||
|
||||
void
|
||||
on_widget_event(lv_obj_t *obj, lv_event_t event)
|
||||
{
|
||||
obj_evt_cb_t *obj_evt_cb = g_obj_evt_cb_list;
|
||||
|
||||
while (obj_evt_cb != NULL) {
|
||||
if (obj_evt_cb->obj == obj) {
|
||||
obj_evt_cb->event_cb(obj, event);
|
||||
return;
|
||||
}
|
||||
obj_evt_cb = obj_evt_cb->next;
|
||||
}
|
||||
}
|
|
@ -1,497 +0,0 @@
|
|||
/**
|
||||
* @file lv_conf.h
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* COPY THIS FILE AS `lv_conf.h` NEXT TO the `lvgl` FOLDER
|
||||
*/
|
||||
|
||||
#if 1 /*Set it to "1" to enable content*/
|
||||
|
||||
#ifndef LV_CONF_H
|
||||
#define LV_CONF_H
|
||||
/* clang-format off */
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
|
||||
|
||||
/*====================
|
||||
Graphical settings
|
||||
*====================*/
|
||||
|
||||
/* Maximal horizontal and vertical resolution to support by the library.*/
|
||||
#define LV_HOR_RES_MAX (480)
|
||||
#define LV_VER_RES_MAX (320)
|
||||
|
||||
/* Color depth:
|
||||
* - 1: 1 byte per pixel
|
||||
* - 8: RGB233
|
||||
* - 16: RGB565
|
||||
* - 32: ARGB8888
|
||||
*/
|
||||
#define LV_COLOR_DEPTH 16
|
||||
|
||||
/* Swap the 2 bytes of RGB565 color.
|
||||
* Useful if the display has a 8 bit interface (e.g. SPI)*/
|
||||
#define LV_COLOR_16_SWAP 0
|
||||
|
||||
/* 1: Enable screen transparency.
|
||||
* Useful for OSD or other overlapping GUIs.
|
||||
* Requires `LV_COLOR_DEPTH = 32` colors and the screen's style should be modified: `style.body.opa = ...`*/
|
||||
#define LV_COLOR_SCREEN_TRANSP 0
|
||||
|
||||
/*Images pixels with this color will not be drawn (with chroma keying)*/
|
||||
#define LV_COLOR_TRANSP LV_COLOR_LIME /*LV_COLOR_LIME: pure green*/
|
||||
|
||||
/* Enable anti-aliasing (lines, and radiuses will be smoothed) */
|
||||
#define LV_ANTIALIAS 1
|
||||
|
||||
/* Default display refresh period.
|
||||
* Can be changed in the display driver (`lv_disp_drv_t`).*/
|
||||
#define LV_DISP_DEF_REFR_PERIOD 30 /*[ms]*/
|
||||
|
||||
/* Dot Per Inch: used to initialize default sizes.
|
||||
* E.g. a button with width = LV_DPI / 2 -> half inch wide
|
||||
* (Not so important, you can adjust it to modify default sizes and spaces)*/
|
||||
#define LV_DPI 100 /*[px]*/
|
||||
|
||||
/* Type of coordinates. Should be `int16_t` (or `int32_t` for extreme cases) */
|
||||
typedef int16_t lv_coord_t;
|
||||
|
||||
/*=========================
|
||||
Memory manager settings
|
||||
*=========================*/
|
||||
|
||||
/* LittelvGL's internal memory manager's settings.
|
||||
* The graphical objects and other related data are stored here. */
|
||||
|
||||
/* 1: use custom malloc/free, 0: use the built-in `lv_mem_alloc` and `lv_mem_free` */
|
||||
#define LV_MEM_CUSTOM 0
|
||||
#if LV_MEM_CUSTOM == 0
|
||||
/* Size of the memory used by `lv_mem_alloc` in bytes (>= 2kB)*/
|
||||
# define LV_MEM_SIZE (32U * 1024U)
|
||||
|
||||
/* Complier prefix for a big array declaration */
|
||||
# define LV_MEM_ATTR
|
||||
|
||||
/* Set an address for the memory pool instead of allocating it as an array.
|
||||
* Can be in external SRAM too. */
|
||||
# define LV_MEM_ADR 0
|
||||
|
||||
/* Automatically defrag. on free. Defrag. means joining the adjacent free cells. */
|
||||
# define LV_MEM_AUTO_DEFRAG 1
|
||||
#else /*LV_MEM_CUSTOM*/
|
||||
# define LV_MEM_CUSTOM_INCLUDE <stdlib.h> /*Header for the dynamic memory function*/
|
||||
# define LV_MEM_CUSTOM_ALLOC malloc /*Wrapper to malloc*/
|
||||
# define LV_MEM_CUSTOM_FREE free /*Wrapper to free*/
|
||||
#endif /*LV_MEM_CUSTOM*/
|
||||
|
||||
/* Garbage Collector settings
|
||||
* Used if lvgl is binded to higher level language and the memory is managed by that language */
|
||||
#define LV_ENABLE_GC 0
|
||||
#if LV_ENABLE_GC != 0
|
||||
# define LV_GC_INCLUDE "gc.h" /*Include Garbage Collector related things*/
|
||||
# define LV_MEM_CUSTOM_REALLOC your_realloc /*Wrapper to realloc*/
|
||||
# define LV_MEM_CUSTOM_GET_SIZE your_mem_get_size /*Wrapper to lv_mem_get_size*/
|
||||
#endif /* LV_ENABLE_GC */
|
||||
|
||||
/*=======================
|
||||
Input device settings
|
||||
*=======================*/
|
||||
|
||||
/* Input device default settings.
|
||||
* Can be changed in the Input device driver (`lv_indev_drv_t`)*/
|
||||
|
||||
/* Input device read period in milliseconds */
|
||||
#define LV_INDEV_DEF_READ_PERIOD 30
|
||||
|
||||
/* Drag threshold in pixels */
|
||||
#define LV_INDEV_DEF_DRAG_LIMIT 10
|
||||
|
||||
/* Drag throw slow-down in [%]. Greater value -> faster slow-down */
|
||||
#define LV_INDEV_DEF_DRAG_THROW 20
|
||||
|
||||
/* Long press time in milliseconds.
|
||||
* Time to send `LV_EVENT_LONG_PRESSSED`) */
|
||||
#define LV_INDEV_DEF_LONG_PRESS_TIME 400
|
||||
|
||||
/* Repeated trigger period in long press [ms]
|
||||
* Time between `LV_EVENT_LONG_PRESSED_REPEAT */
|
||||
#define LV_INDEV_DEF_LONG_PRESS_REP_TIME 100
|
||||
|
||||
/*==================
|
||||
* Feature usage
|
||||
*==================*/
|
||||
|
||||
/*1: Enable the Animations */
|
||||
#define LV_USE_ANIMATION 1
|
||||
#if LV_USE_ANIMATION
|
||||
|
||||
/*Declare the type of the user data of animations (can be e.g. `void *`, `int`, `struct`)*/
|
||||
typedef void * lv_anim_user_data_t;
|
||||
|
||||
#endif
|
||||
|
||||
/* 1: Enable shadow drawing*/
|
||||
#define LV_USE_SHADOW 1
|
||||
|
||||
/* 1: Enable object groups (for keyboard/encoder navigation) */
|
||||
#define LV_USE_GROUP 1
|
||||
#if LV_USE_GROUP
|
||||
typedef void * lv_group_user_data_t;
|
||||
#endif /*LV_USE_GROUP*/
|
||||
|
||||
/* 1: Enable GPU interface*/
|
||||
#define LV_USE_GPU 1
|
||||
|
||||
/* 1: Enable file system (might be required for images */
|
||||
#define LV_USE_FILESYSTEM 1
|
||||
#if LV_USE_FILESYSTEM
|
||||
/*Declare the type of the user data of file system drivers (can be e.g. `void *`, `int`, `struct`)*/
|
||||
typedef void * lv_fs_drv_user_data_t;
|
||||
#endif
|
||||
|
||||
/*1: Add a `user_data` to drivers and objects*/
|
||||
#define LV_USE_USER_DATA 0
|
||||
|
||||
/*========================
|
||||
* Image decoder and cache
|
||||
*========================*/
|
||||
|
||||
/* 1: Enable indexed (palette) images */
|
||||
#define LV_IMG_CF_INDEXED 1
|
||||
|
||||
/* 1: Enable alpha indexed images */
|
||||
#define LV_IMG_CF_ALPHA 1
|
||||
|
||||
/* Default image cache size. Image caching keeps the images opened.
|
||||
* If only the built-in image formats are used there is no real advantage of caching.
|
||||
* (I.e. no new image decoder is added)
|
||||
* With complex image decoders (e.g. PNG or JPG) caching can save the continuous open/decode of images.
|
||||
* However the opened images might consume additional RAM.
|
||||
* LV_IMG_CACHE_DEF_SIZE must be >= 1 */
|
||||
#define LV_IMG_CACHE_DEF_SIZE 1
|
||||
|
||||
/*Declare the type of the user data of image decoder (can be e.g. `void *`, `int`, `struct`)*/
|
||||
typedef void * lv_img_decoder_user_data_t;
|
||||
|
||||
/*=====================
|
||||
* Compiler settings
|
||||
*====================*/
|
||||
/* Define a custom attribute to `lv_tick_inc` function */
|
||||
#define LV_ATTRIBUTE_TICK_INC
|
||||
|
||||
/* Define a custom attribute to `lv_task_handler` function */
|
||||
#define LV_ATTRIBUTE_TASK_HANDLER
|
||||
|
||||
/* With size optimization (-Os) the compiler might not align data to
|
||||
* 4 or 8 byte boundary. This alignment will be explicitly applied where needed.
|
||||
* E.g. __attribute__((aligned(4))) */
|
||||
#define LV_ATTRIBUTE_MEM_ALIGN
|
||||
|
||||
/* Attribute to mark large constant arrays for example
|
||||
* font's bitmaps */
|
||||
#define LV_ATTRIBUTE_LARGE_CONST
|
||||
|
||||
/*===================
|
||||
* HAL settings
|
||||
*==================*/
|
||||
|
||||
/* 1: use a custom tick source.
|
||||
* It removes the need to manually update the tick with `lv_tick_inc`) */
|
||||
#define LV_TICK_CUSTOM 0
|
||||
#if LV_TICK_CUSTOM == 1
|
||||
#define LV_TICK_CUSTOM_INCLUDE "something.h" /*Header for the sys time function*/
|
||||
#define LV_TICK_CUSTOM_SYS_TIME_EXPR (millis()) /*Expression evaluating to current systime in ms*/
|
||||
#endif /*LV_TICK_CUSTOM*/
|
||||
|
||||
typedef void * lv_disp_drv_user_data_t; /*Type of user data in the display driver*/
|
||||
typedef void * lv_indev_drv_user_data_t; /*Type of user data in the input device driver*/
|
||||
|
||||
/*================
|
||||
* Log settings
|
||||
*===============*/
|
||||
|
||||
/*1: Enable the log module*/
|
||||
#define LV_USE_LOG 0
|
||||
#if LV_USE_LOG
|
||||
/* How important log should be added:
|
||||
* LV_LOG_LEVEL_TRACE A lot of logs to give detailed information
|
||||
* LV_LOG_LEVEL_INFO Log important events
|
||||
* LV_LOG_LEVEL_WARN Log if something unwanted happened but didn't cause a problem
|
||||
* LV_LOG_LEVEL_ERROR Only critical issue, when the system may fail
|
||||
* LV_LOG_LEVEL_NONE Do not log anything
|
||||
*/
|
||||
# define LV_LOG_LEVEL LV_LOG_LEVEL_WARN
|
||||
|
||||
/* 1: Print the log with 'printf';
|
||||
* 0: user need to register a callback with `lv_log_register_print`*/
|
||||
# define LV_LOG_PRINTF 0
|
||||
#endif /*LV_USE_LOG*/
|
||||
|
||||
/*================
|
||||
* THEME USAGE
|
||||
*================*/
|
||||
#define LV_THEME_LIVE_UPDATE 0 /*1: Allow theme switching at run time. Uses 8..10 kB of RAM*/
|
||||
|
||||
#define LV_USE_THEME_TEMPL 0 /*Just for test*/
|
||||
#define LV_USE_THEME_DEFAULT 0 /*Built mainly from the built-in styles. Consumes very few RAM*/
|
||||
#define LV_USE_THEME_ALIEN 0 /*Dark futuristic theme*/
|
||||
#define LV_USE_THEME_NIGHT 0 /*Dark elegant theme*/
|
||||
#define LV_USE_THEME_MONO 0 /*Mono color theme for monochrome displays*/
|
||||
#define LV_USE_THEME_MATERIAL 0 /*Flat theme with bold colors and light shadows*/
|
||||
#define LV_USE_THEME_ZEN 0 /*Peaceful, mainly light theme */
|
||||
#define LV_USE_THEME_NEMO 0 /*Water-like theme based on the movie "Finding Nemo"*/
|
||||
|
||||
/*==================
|
||||
* FONT USAGE
|
||||
*===================*/
|
||||
|
||||
/* The built-in fonts contains the ASCII range and some Symbols with 4 bit-per-pixel.
|
||||
* The symbols are available via `LV_SYMBOL_...` defines
|
||||
* More info about fonts: https://docs.littlevgl.com/#Fonts
|
||||
* To create a new font go to: https://littlevgl.com/ttf-font-to-c-array
|
||||
*/
|
||||
|
||||
/* Robot fonts with bpp = 4
|
||||
* https://fonts.google.com/specimen/Roboto */
|
||||
#define LV_FONT_ROBOTO_12 0
|
||||
#define LV_FONT_ROBOTO_16 1
|
||||
#define LV_FONT_ROBOTO_22 0
|
||||
#define LV_FONT_ROBOTO_28 0
|
||||
|
||||
/*Pixel perfect monospace font
|
||||
* http://pelulamu.net/unscii/ */
|
||||
#define LV_FONT_UNSCII_8 0
|
||||
|
||||
/* Optionally declare your custom fonts here.
|
||||
* You can use these fonts as default font too
|
||||
* and they will be available globally. E.g.
|
||||
* #define LV_FONT_CUSTOM_DECLARE LV_FONT_DECLARE(my_font_1) \
|
||||
* LV_FONT_DECLARE(my_font_2)
|
||||
*/
|
||||
#define LV_FONT_CUSTOM_DECLARE
|
||||
|
||||
/*Always set a default font from the built-in fonts*/
|
||||
#define LV_FONT_DEFAULT &lv_font_roboto_16
|
||||
|
||||
/* Enable it if you have fonts with a lot of characters.
|
||||
* The limit depends on the font size, font face and bpp
|
||||
* but with > 10,000 characters if you see issues probably you need to enable it.*/
|
||||
#define LV_FONT_FMT_TXT_LARGE 0
|
||||
|
||||
/*Declare the type of the user data of fonts (can be e.g. `void *`, `int`, `struct`)*/
|
||||
typedef void * lv_font_user_data_t;
|
||||
|
||||
/*=================
|
||||
* Text settings
|
||||
*=================*/
|
||||
|
||||
/* Select a character encoding for strings.
|
||||
* Your IDE or editor should have the same character encoding
|
||||
* - LV_TXT_ENC_UTF8
|
||||
* - LV_TXT_ENC_ASCII
|
||||
* */
|
||||
#define LV_TXT_ENC LV_TXT_ENC_UTF8
|
||||
|
||||
/*Can break (wrap) texts on these chars*/
|
||||
#define LV_TXT_BREAK_CHARS " ,.;:-_"
|
||||
|
||||
/*===================
|
||||
* LV_OBJ SETTINGS
|
||||
*==================*/
|
||||
|
||||
/*Declare the type of the user data of object (can be e.g. `void *`, `int`, `struct`)*/
|
||||
typedef void * lv_obj_user_data_t;
|
||||
|
||||
/*1: enable `lv_obj_realaign()` based on `lv_obj_align()` parameters*/
|
||||
#define LV_USE_OBJ_REALIGN 1
|
||||
|
||||
/* Enable to make the object clickable on a larger area.
|
||||
* LV_EXT_CLICK_AREA_OFF or 0: Disable this feature
|
||||
* LV_EXT_CLICK_AREA_TINY: The extra area can be adjusted horizontally and vertically (0..255 px)
|
||||
* LV_EXT_CLICK_AREA_FULL: The extra area can be adjusted in all 4 directions (-32k..+32k px)
|
||||
*/
|
||||
#define LV_USE_EXT_CLICK_AREA LV_EXT_CLICK_AREA_OFF
|
||||
|
||||
/*==================
|
||||
* LV OBJ X USAGE
|
||||
*================*/
|
||||
/*
|
||||
* Documentation of the object types: https://docs.littlevgl.com/#Object-types
|
||||
*/
|
||||
|
||||
/*Arc (dependencies: -)*/
|
||||
#define LV_USE_ARC 1
|
||||
|
||||
/*Bar (dependencies: -)*/
|
||||
#define LV_USE_BAR 1
|
||||
|
||||
/*Button (dependencies: lv_cont*/
|
||||
#define LV_USE_BTN 1
|
||||
#if LV_USE_BTN != 0
|
||||
/*Enable button-state animations - draw a circle on click (dependencies: LV_USE_ANIMATION)*/
|
||||
# define LV_BTN_INK_EFFECT 0
|
||||
#endif
|
||||
|
||||
/*Button matrix (dependencies: -)*/
|
||||
#define LV_USE_BTNM 1
|
||||
|
||||
/*Calendar (dependencies: -)*/
|
||||
#define LV_USE_CALENDAR 1
|
||||
|
||||
/*Canvas (dependencies: lv_img)*/
|
||||
#define LV_USE_CANVAS 1
|
||||
|
||||
/*Check box (dependencies: lv_btn, lv_label)*/
|
||||
#define LV_USE_CB 1
|
||||
|
||||
/*Chart (dependencies: -)*/
|
||||
#define LV_USE_CHART 1
|
||||
#if LV_USE_CHART
|
||||
# define LV_CHART_AXIS_TICK_LABEL_MAX_LEN 20
|
||||
#endif
|
||||
|
||||
/*Container (dependencies: -*/
|
||||
#define LV_USE_CONT 1
|
||||
|
||||
/*Drop down list (dependencies: lv_page, lv_label, lv_symbol_def.h)*/
|
||||
#define LV_USE_DDLIST 1
|
||||
#if LV_USE_DDLIST != 0
|
||||
/*Open and close default animation time [ms] (0: no animation)*/
|
||||
# define LV_DDLIST_DEF_ANIM_TIME 200
|
||||
#endif
|
||||
|
||||
/*Gauge (dependencies:lv_bar, lv_lmeter)*/
|
||||
#define LV_USE_GAUGE 1
|
||||
|
||||
/*Image (dependencies: lv_label*/
|
||||
#define LV_USE_IMG 1
|
||||
|
||||
/*Image Button (dependencies: lv_btn*/
|
||||
#define LV_USE_IMGBTN 1
|
||||
#if LV_USE_IMGBTN
|
||||
/*1: The imgbtn requires left, mid and right parts and the width can be set freely*/
|
||||
# define LV_IMGBTN_TILED 0
|
||||
#endif
|
||||
|
||||
/*Keyboard (dependencies: lv_btnm)*/
|
||||
#define LV_USE_KB 1
|
||||
|
||||
/*Label (dependencies: -*/
|
||||
#define LV_USE_LABEL 1
|
||||
#if LV_USE_LABEL != 0
|
||||
/*Hor, or ver. scroll speed [px/sec] in 'LV_LABEL_LONG_ROLL/ROLL_CIRC' mode*/
|
||||
# define LV_LABEL_DEF_SCROLL_SPEED 25
|
||||
|
||||
/* Waiting period at beginning/end of animation cycle */
|
||||
# define LV_LABEL_WAIT_CHAR_COUNT 3
|
||||
|
||||
/*Enable selecting text of the label */
|
||||
# define LV_LABEL_TEXT_SEL 0
|
||||
|
||||
/*Store extra some info in labels (12 bytes) to speed up drawing of very long texts*/
|
||||
# define LV_LABEL_LONG_TXT_HINT 0
|
||||
#endif
|
||||
|
||||
/*LED (dependencies: -)*/
|
||||
#define LV_USE_LED 1
|
||||
|
||||
/*Line (dependencies: -*/
|
||||
#define LV_USE_LINE 1
|
||||
|
||||
/*List (dependencies: lv_page, lv_btn, lv_label, (lv_img optionally for icons ))*/
|
||||
#define LV_USE_LIST 1
|
||||
#if LV_USE_LIST != 0
|
||||
/*Default animation time of focusing to a list element [ms] (0: no animation) */
|
||||
# define LV_LIST_DEF_ANIM_TIME 100
|
||||
#endif
|
||||
|
||||
/*Line meter (dependencies: *;)*/
|
||||
#define LV_USE_LMETER 1
|
||||
|
||||
/*Message box (dependencies: lv_rect, lv_btnm, lv_label)*/
|
||||
#define LV_USE_MBOX 1
|
||||
|
||||
/*Page (dependencies: lv_cont)*/
|
||||
#define LV_USE_PAGE 1
|
||||
#if LV_USE_PAGE != 0
|
||||
/*Focus default animation time [ms] (0: no animation)*/
|
||||
# define LV_PAGE_DEF_ANIM_TIME 400
|
||||
#endif
|
||||
|
||||
/*Preload (dependencies: lv_arc, lv_anim)*/
|
||||
#define LV_USE_PRELOAD 1
|
||||
#if LV_USE_PRELOAD != 0
|
||||
# define LV_PRELOAD_DEF_ARC_LENGTH 60 /*[deg]*/
|
||||
# define LV_PRELOAD_DEF_SPIN_TIME 1000 /*[ms]*/
|
||||
# define LV_PRELOAD_DEF_ANIM LV_PRELOAD_TYPE_SPINNING_ARC
|
||||
#endif
|
||||
|
||||
/*Roller (dependencies: lv_ddlist)*/
|
||||
#define LV_USE_ROLLER 1
|
||||
#if LV_USE_ROLLER != 0
|
||||
/*Focus animation time [ms] (0: no animation)*/
|
||||
# define LV_ROLLER_DEF_ANIM_TIME 200
|
||||
|
||||
/*Number of extra "pages" when the roller is infinite*/
|
||||
# define LV_ROLLER_INF_PAGES 7
|
||||
#endif
|
||||
|
||||
/*Slider (dependencies: lv_bar)*/
|
||||
#define LV_USE_SLIDER 1
|
||||
|
||||
/*Spinbox (dependencies: lv_ta)*/
|
||||
#define LV_USE_SPINBOX 1
|
||||
|
||||
/*Switch (dependencies: lv_slider)*/
|
||||
#define LV_USE_SW 1
|
||||
|
||||
/*Text area (dependencies: lv_label, lv_page)*/
|
||||
#define LV_USE_TA 1
|
||||
#if LV_USE_TA != 0
|
||||
# define LV_TA_DEF_CURSOR_BLINK_TIME 400 /*ms*/
|
||||
# define LV_TA_DEF_PWD_SHOW_TIME 1500 /*ms*/
|
||||
#endif
|
||||
|
||||
/*Table (dependencies: lv_label)*/
|
||||
#define LV_USE_TABLE 1
|
||||
#if LV_USE_TABLE
|
||||
# define LV_TABLE_COL_MAX 12
|
||||
#endif
|
||||
|
||||
/*Tab (dependencies: lv_page, lv_btnm)*/
|
||||
#define LV_USE_TABVIEW 1
|
||||
# if LV_USE_TABVIEW != 0
|
||||
/*Time of slide animation [ms] (0: no animation)*/
|
||||
# define LV_TABVIEW_DEF_ANIM_TIME 300
|
||||
#endif
|
||||
|
||||
/*Tileview (dependencies: lv_page) */
|
||||
#define LV_USE_TILEVIEW 1
|
||||
#if LV_USE_TILEVIEW
|
||||
/*Time of slide animation [ms] (0: no animation)*/
|
||||
# define LV_TILEVIEW_DEF_ANIM_TIME 300
|
||||
#endif
|
||||
|
||||
/*Window (dependencies: lv_cont, lv_btn, lv_label, lv_img, lv_page)*/
|
||||
#define LV_USE_WIN 1
|
||||
|
||||
/*==================
|
||||
* Non-user section
|
||||
*==================*/
|
||||
|
||||
#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS) /* Disable warnings for Visual Studio*/
|
||||
# define _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
|
||||
/*--END OF LV_CONF_H--*/
|
||||
|
||||
/*Be sure every define has a default value*/
|
||||
//#include "../lv_conf_checker.h"
|
||||
|
||||
#endif /*LV_CONF_H*/
|
||||
|
||||
#endif /*End of "Content enable"*/
|
|
@ -1,8 +0,0 @@
|
|||
MIT licence
|
||||
Copyright (c) 2016 Gábor Kiss-Vámosi
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user