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:
Wenyong Huang 2024-02-20 18:12:36 +08:00 committed by GitHub
parent b9db23b983
commit 63cd567b3f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
359 changed files with 45 additions and 37923 deletions

View File

@ -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

View File

@ -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

View File

@ -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:

View File

@ -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:

View File

@ -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:

View File

@ -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:

View File

@ -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: |

View File

@ -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
View File

@ -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/

View File

@ -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

View File

@ -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++

View File

@ -1 +0,0 @@
/node_modules

View File

@ -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",
```

View File

@ -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
}
}
}

View File

@ -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"
}
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -1,6 +0,0 @@
{
"extends": "../node_modules/assemblyscript/std/assembly.json",
"include": [
"./**/*.ts"
]
}

View File

@ -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()));
}

View File

@ -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);
}
}

View File

@ -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();
}
}
}

View File

@ -1,6 +0,0 @@
{
"extends": "../node_modules/assemblyscript/std/assembly.json",
"include": [
"./**/*.ts"
]
}

View File

@ -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'))

View File

@ -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}

View File

@ -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"]

View File

@ -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)

View File

@ -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.

View File

@ -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");
}

View File

@ -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_ */

View File

@ -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_ */

View File

@ -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 */

View File

@ -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")

View File

@ -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 */

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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()

View File

@ -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;
}

View File

@ -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_ */

View File

@ -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_ */

View File

@ -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);
}

View File

@ -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;
}
}

View File

@ -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_ */

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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_ */

View File

@ -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"),

View File

@ -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);
}

View File

@ -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_ */

View File

@ -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);
}
}

View File

@ -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_ */

View File

@ -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_ */

View File

@ -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();
}

View File

@ -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})

View File

@ -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;
}
}

View File

@ -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_ */

View File

@ -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

View File

@ -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})

View File

@ -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"),

View File

@ -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_ */

View File

@ -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_ */

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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;
}

View File

@ -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})

View File

@ -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})

View File

@ -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 */

View File

@ -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})

View File

@ -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;
}
}

View File

@ -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_ */

View File

@ -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

View File

@ -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})

View File

@ -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;
}
}

View File

@ -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_ */

View File

@ -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"),

View File

@ -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
}

View File

@ -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_ */

View File

@ -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})

View File

@ -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
*/

View File

@ -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})

View File

@ -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), */

View File

@ -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})

View File

@ -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_ */

View File

@ -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."

View File

@ -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;
//}

View File

@ -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;
//}
//

View File

@ -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);
}

View File

@ -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);
//}
//

View File

@ -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;
}
}

View File

@ -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"*/

View File

@ -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