diff --git a/.gitmodules b/.gitmodules index 12148d5df992f6..045ea3d309000b 100644 --- a/.gitmodules +++ b/.gitmodules @@ -273,3 +273,18 @@ url = https://github.com/bouffalolab/bl_iot_sdk.git branch = master platforms = bl602 +[submodule "third_party/mt793x_sdk/filogic"] + path = third_party/mt793x_sdk/filogic + url = https://github.com/MediaTek-Labs/genio-matter-bsp.git + branch = main + platforms = genio +[submodule "third_party/mt793x_sdk/lwip"] + path = third_party/mt793x_sdk/lwip + url = https://github.com/matter-mtk/genio-matter-lwip.git + branch = main + platforms = genio +[submodule "third_party/mt793x_sdk/mDNSResponder"] + path = third_party/mt793x_sdk/mDNSResponder + url = https://github.com/matter-mtk/genio-matter-mdnsresponder.git + branch = main + platforms = genio diff --git a/BUILD.gn b/BUILD.gn index 7dbbb83d3cc77b..e40fa17fa3ca65 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -285,6 +285,9 @@ if (current_toolchain != "${dir_pw_toolchain}/default:default") { # Set this to true to enable mw320 builds by default. enable_mw320_builds = false + + # Set this to true to enable mt793x builds by default. + enable_mt793x_builds = false } declare_args() { @@ -391,6 +394,9 @@ if (current_toolchain != "${dir_pw_toolchain}/default:default") { # Build the mw320 shell app example. enable_mw320_shell_build = enable_mw320_builds + # Build the mt793x shell app example. + enable_mt793x_shell_app_build = enable_mt793x_builds + enable_fake_tests = enable_default_builds && host_os == "linux" enable_tizen_lighting_app = enable_tizen_builds @@ -682,6 +688,12 @@ if (current_toolchain != "${dir_pw_toolchain}/default:default") { extra_build_deps += [ ":mw320_shell" ] } + if (enable_mt793x_shell_app_build) { + group("mt793x_shell_app") { + deps = [ "${chip_root}/examples/shell/k32w(${chip_root}/config/mt793x/toolchain:mt793x_shell_app)" ] + } + } + group("default") { deps = extra_build_deps + builds } diff --git a/build_overrides/mt793x_sdk.gni b/build_overrides/mt793x_sdk.gni new file mode 100644 index 00000000000000..1b4768b026a531 --- /dev/null +++ b/build_overrides/mt793x_sdk.gni @@ -0,0 +1,19 @@ +# Copyright (c) 2022 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +declare_args() { + # Root directory for mt793x SDK build files. + mt793x_sdk_build_root = "//third_party/mt793x_sdk" +} + diff --git a/config/mt793x/BUILD.gn b/config/mt793x/BUILD.gn new file mode 100644 index 00000000000000..01f7928721bc2e --- /dev/null +++ b/config/mt793x/BUILD.gn @@ -0,0 +1,37 @@ +# Copyright (c) 2020 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Options from standalone-chip.mk that differ from configure defaults. These +# options are used from examples/. + +import("//build_overrides/build.gni") +import("//build_overrides/chip.gni") + +import("${chip_root}/build/chip/tests.gni") + +declare_args() { + chip_build_pw_rpc_lib = false +} + +group("mt793x") { + deps = [ "${chip_root}/src/lib" ] + + if (chip_build_pw_rpc_lib) { + deps += [ "//lib/pw_rpc" ] + } + + if (chip_build_tests) { + deps += [ "${chip_root}/src:tests" ] + } +} diff --git a/config/mt793x/args.gni b/config/mt793x/args.gni new file mode 100644 index 00000000000000..0bac514b7ec581 --- /dev/null +++ b/config/mt793x/args.gni @@ -0,0 +1,37 @@ +# Copyright (c) 2022 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Options from standalone-chip.mk that differ from configure defaults. These +# options are used from examples/. + +#chip_device_platform = "mt793x" + +chip_project_config_include = "" +chip_system_project_config_include = "" +chip_ble_project_config_include = "" + +mbedtls_target = "//mbedtls:mbedtls" +lwip_platform = "external" + +chip_build_tests = true + +#Enabling this causes some error +#chip_inet_config_enable_tun_endpoint = false +chip_inet_config_enable_tcp_endpoint = true +chip_inet_config_enable_udp_endpoint = true + +custom_toolchain = "//third_party/connectedhomeip/config/mt793x/toolchain:mt793x" + +pw_build_PIP_CONSTRAINTS = + [ "//third_party/connectedhomeip/scripts/constraints.txt" ] diff --git a/config/mt793x/toolchain/BUILD.gn b/config/mt793x/toolchain/BUILD.gn new file mode 100644 index 00000000000000..cc924d9e3d4383 --- /dev/null +++ b/config/mt793x/toolchain/BUILD.gn @@ -0,0 +1,25 @@ +# Copyright (c) 2022 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/build.gni") +import("//build_overrides/chip.gni") + +import("${build_root}/toolchain/arm_gcc/arm_toolchain.gni") + +arm_toolchain("mt793x_shell_app") { + toolchain_args = { + current_os = "freertos" + import("${chip_root}/examples/shell/mt793x/args.gni") + } +} diff --git a/examples/build_overrides/mt793x_sdk.gni b/examples/build_overrides/mt793x_sdk.gni new file mode 100644 index 00000000000000..24c0c3e8464cde --- /dev/null +++ b/examples/build_overrides/mt793x_sdk.gni @@ -0,0 +1,18 @@ +# Copyright (c) 2022 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +declare_args() { + # Root directory for mt793x SDK build files. + mt793x_sdk_build_root = "//third_party/connectedhomeip/third_party/mt793x_sdk" +} diff --git a/examples/lighting-app/mtk/.gn b/examples/lighting-app/mtk/.gn new file mode 100644 index 00000000000000..0adefc6ff99c6a --- /dev/null +++ b/examples/lighting-app/mtk/.gn @@ -0,0 +1,27 @@ +# Copyright (c) 2020 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/build.gni") + +# The location of the build configuration file. +buildconfig = "${build_root}/config/BUILDCONFIG.gn" + +# CHIP uses angle bracket includes. +check_system_includes = true + +default_args = { + target_cpu = "arm" + target_os = "freertos" + import("//args.gni") +} diff --git a/examples/lighting-app/mtk/BUILD.gn b/examples/lighting-app/mtk/BUILD.gn new file mode 100644 index 00000000000000..1cd0422b8f78c4 --- /dev/null +++ b/examples/lighting-app/mtk/BUILD.gn @@ -0,0 +1,117 @@ +# Copyright (c) 2022 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/build.gni") +import("//build_overrides/chip.gni") +import("//build_overrides/mt793x_sdk.gni") +import("//build_overrides/pigweed.gni") + +import("${build_root}/config/defaults.gni") +import("${mt793x_sdk_build_root}/mt793x_executable.gni") +import("${mt793x_sdk_build_root}/mt793x_sdk.gni") + +import("${chip_root}/examples/common/pigweed/pigweed_rpcs.gni") +import("${chip_root}/src/platform/device.gni") + +if (chip_enable_pw_rpc) { + import("//build_overrides/pigweed.gni") + import("$dir_pw_build/target_types.gni") +} + +assert(current_os == "freertos") + +mt793x_project_dir = "${chip_root}/examples/lighting-app/mtk" +mt793x_examples_plat_dir = "${chip_root}/examples/platform/mt793x" + +declare_args() { + # Dump memory usage at link time. + chip_print_memory_usage = true + + # PIN code for PASE session establishment. + setupPinCode = 20202021 + setupDiscriminator = 3840 +} + +mt793x_sdk("sdk") { + sources = [ + "${mt793x_project_dir}/include/CHIPProjectConfig.h", + "${mt793x_project_dir}/include/FreeRTOSConfig.h", + ] + + include_dirs = [ + "${chip_root}/src/platform/mt793x", + "${mt793x_project_dir}/include", + "${mt793x_examples_plat_dir}", + "${chip_root}/src/lib", + ] + + defines = [ "OPENTHREAD_CONFIG_CLI_TRANSPORT=OT_CLI_TRANSPORT_CONSOLE" ] + + defines += [ + "CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE=${setupPinCode}", + "CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR=${setupDiscriminator}", + ] +} + +mt793x_executable("lighting_app") { + output_name = "chip-mt793x-lighting-app-example.out" + include_dirs = [ "include" ] + defines = [] + + sources = [ + "src/LEDWidget.cpp", + "src/AppTask.cpp", + "src/LightingManager.cpp", + "src/ZclCallbacks.cpp", + "src/main.cpp", + ] + + deps = [ + ":sdk", + "${chip_root}/examples/common/QRCode", + "${chip_root}/examples/lighting-app/lighting-common", + "${chip_root}/examples/providers:device_info_provider", + "${chip_root}/src/lib", + "${chip_root}/src/setup_payload", + "${mt793x_examples_plat_dir}:mtk-matter-shell", + ] + + if (chip_enable_ota_requestor) { + defines += [ "MT793X_OTA_ENABLED" ] + sources += [ "${examples_plat_dir}/OTAConfig.cpp" ] + } + + ldscript = "mt793x_xip.ld" + + inputs = [ ldscript ] + + ldflags = [ "-T" + rebase_path(ldscript, root_build_dir) ] + + if (chip_print_memory_usage) { + ldflags += [ + "-Wl,--print-memory-usage", + "-fstack-usage", + ] + } + + output_dir = root_out_dir +} + +group("mt793x") { + deps = [ ":lighting_app" ] +} + +group("default") { + deps = [ ":mt793x" ] +} diff --git a/examples/lighting-app/mtk/README.md b/examples/lighting-app/mtk/README.md new file mode 100644 index 00000000000000..59fcb8fe0cb05f --- /dev/null +++ b/examples/lighting-app/mtk/README.md @@ -0,0 +1,256 @@ +#CHIP MT793X Lighting Example + +An example showing the use of CHIP on the MediaTek MT793X. + +
+ +- [CHIP MT793X Lighting Example](#chip-mt793x-lighting-example) + - [Introduction](#introduction) + - [Building](#building) + - [Note](#note) + - [Flashing the Application](#flashing-the-application) + - [Viewing Logging Output](#viewing-logging-output) + - [Running the Complete Example](#running-the-complete-example) + - [Notes](#notes) + - [Running RPC console](#running-rpc-console) + +
+ + + +## Introduction + +The MT793X lighting example provides a baseline demonstration of a Light control +device, built using CHIP and the MediaTek Filogic SDK. It can be controlled by +a Chip controller over Wi-Fi network.. + +The MT793X device can be commissioned over Bluetooth Low Energy where the device +and the Chip controller will exchange security information with the Rendez-vous +procedure. Network credentials are then provided to the MT793X device +which will then join the network. + +The lighting example is intended to serve both as a means to explore the +workings of CHIP as well as a template for creating real products based on the +Silicon Labs platform. + + + +## Building + +- Download the + [Simplicity Commander](https://www.silabs.com/mcu/programming-options) + command line tool, and ensure that `commander` is your shell search path. + (For Mac OS X, `commander` is located inside + `Commander.app/Contents/MacOS/`.) + +- Download and install a suitable ARM gcc tool chain: + [GNU Arm Embedded Toolchain 9-2019-q4-major](https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads) + +- Install some additional tools(likely already present for CHIP developers): + +#Linux \$ sudo apt-get install git libwebkitgtk-1.0-0 ninja-build + +#Mac OS X \$ brew install ninja + +- Supported hardware: + +* Build the example application: + + + Use GN/Ninja directly + + $ cd ~/connectedhomeip/examples/lighting-app/mtk + $ git submodule update --init + $ source third_party/connectedhomeip/scripts/activate.sh + $ gn gen out/debug + $ ninja -C out/debug + +- To delete generated executable, libraries and object files use: + + $ cd ~/connectedhomeip/examples/lighting-app/mtk + $ rm -rf out/ + + + +## Viewing Logging Output + +The example application is built to use the SEGGER Real Time Transfer (RTT) +facility for log output. RTT is a feature built-in to the J-Link Interface MCU +on the WSTK development board. It allows bi-directional communication with an +embedded application without the need for a dedicated UART. + +Using the RTT facility requires downloading and installing the _SEGGER J-Link +Software and Documentation Pack_ +([web site](https://www.segger.com/downloads/jlink#J-LinkSoftwareAndDocumentationPack)). + +Alternatively, SEGGER Ozone J-Link debugger can be used to view RTT logs too +after flashing the .out file. + +- Download the J-Link installer by navigating to the appropriate URL and + agreeing to the license agreement. + +- [JLink_Linux_x86_64.deb](https://www.segger.com/downloads/jlink/JLink_Linux_x86_64.deb) +- [JLink_MacOSX.pkg](https://www.segger.com/downloads/jlink/JLink_MacOSX.pkg) + +* Install the J-Link software + + $ cd ~/Downloads + $ sudo dpkg -i JLink_Linux_V*_x86_64.deb + +* In Linux, grant the logged in user the ability to talk to the development + hardware via the linux tty device (/dev/ttyACMx) by adding them to the + dialout group. + + $ sudo usermod -a -G dialout ${USER} + +Once the above is complete, log output can be viewed using the JLinkExe tool in +combination with JLinkRTTClient as follows: + +- Run the JLinkExe tool with arguments to autoconnect to the WSTK board: + + For MG12 use: + + $ JLinkExe -device MT793XMG12PXXXF1024 -if JTAG -speed 4000 -autoconnect 1 + + For MG21 use: + + $ JLinkExe -device MT793XMG21AXXXF1024 -if SWD -speed 4000 -autoconnect 1 + +- In a second terminal, run the JLinkRTTClient to view logs: + + $ JLinkRTTClient + + + +## Running the Complete Example + +- It is assumed here that you already have an OpenThread border router + configured and running. If not see the following guide + [Openthread_border_router](https://github.com/project-chip/connectedhomeip/blob/master/docs/guides/openthread_border_router_pi.md) + for more information on how to setup a border router on a raspberryPi. + + Take note that the RCP code is available directly through + [Simplicity Studio 5](https://www.silabs.com/products/development-tools/software/simplicity-studio/simplicity-studio-5) + under File->New->Project Wizard->Examples->Thread : ot-rcp + +- User interface : **LCD** The LCD on Silabs WSTK shows a QR Code. This QR + Code is be scanned by the CHIP Tool app For the Rendez-vous procedure over + BLE + + * On devices that do not have or support the LCD Display like the BRD4166A Thunderboard Sense 2, + a URL can be found in the RTT logs. + + [SVR] Copy/paste the below URL in a browser to see the QR Code: + [SVR] https://dhrishi.github.io/connectedhomeip/qrcode.html?data=CH%3AI34NM%20-00%200C9SS0 + + **LED 0** shows the overall state of the device and its connectivity. The + following states are possible: + + - _Short Flash On (50 ms on/950 ms off)_ ; The device is in the + unprovisioned (unpaired) state and is waiting for a commissioning + application to connect. + + - _Rapid Even Flashing_ ; (100 ms on/100 ms off)_ — The device is in the + unprovisioned state and a commissioning application is connected through + Bluetooth LE. + + - _Short Flash Off_ ; (950ms on/50ms off)_ — The device is fully + provisioned, but does not yet have full Thread network or service + connectivity. + + - _Solid On_ ; The device is fully provisioned and has full Thread + network and service connectivity. + + **LED 1** Simulates the Light The following states are possible: + + - _Solid On_ ; Light is on + - _Off_ ; Light is off + + **Push Button 0** + + - _Press and Release_ : Start, or restart, BLE advertisement in fast mode. It will advertise in this mode + for 30 seconds. The device will then switch to a slower interval advertisement. + After 15 minutes, the advertisement stops. + + - _Pressed and hold for 6 s_ : Initiates the factory reset of the device. + Releasing the button within the 6-second window cancels the factory reset + procedure. **LEDs** blink in unison when the factory reset procedure is + initiated. + + **Push Button 1** Toggles the light state On/Off + +* You can provision and control the Chip device using the python controller, + Chip tool standalone, Android or iOS app + + [Python Controller](https://github.com/project-chip/connectedhomeip/blob/master/src/controller/python/README.md) + + Here is an example with the Python controller: + + ``` + chip-device-ctrl + + connect -ble 3840 73141520 1234 + + zcl NetworkCommissioning AddOrUpdateThreadNetwork 1234 0 0 operationalDataset=hex:0e080000000000000000000300000b35060004001fffe00208dead00beef00cafe0708fddead00beef000005108e11d8ea8ffaa875713699f59e8807e0030a4f70656e5468726561640102c2980410edc641eb63b100b87e90a9980959befc0c0402a0fff8 breadcrumb=0 + + zcl NetworkCommissioning ConnectNetwork 1234 0 0 networkID=hex:dead00beef00cafe breadcrumb=0 + + close-ble + + resolve 1234 + + zcl OnOff Toggle 1234 1 0 + ``` + +### Notes + +- Depending on your network settings your router might not provide native ipv6 + addresses to your devices (Border router / PC). If this is the case, you + need to add a static ipv6 addresses on both device and then an ipv6 route to + the border router on your PC + +#On Border Router: \$ sudo ip addr add dev 2002::2/64 + +#On PC(Linux): \$ sudo ip addr add dev 2002::1/64 + +#Add Ipv6 route on PC(Linux) \$ sudo ip route add /64 +via 2002::2 + + + +## Running RPC console + +- As part of building the example with RPCs enabled the chip_rpc python + interactive console is installed into your venv. The python wheel files are + also created in the output folder: out/debug/chip_rpc_console_wheels. To + install the wheel files without rebuilding: + `pip3 install out/debug/chip_rpc_console_wheels/*.whl` + +- To use the chip-rpc console after it has been installed run: + `python3 -m chip_rpc.console --device /dev/tty. -b 115200 -o //pw_log.out` + +- Then you can simulate a button press or release using the following command + where : idx = 0 or 1 for Button PB0 or PB1 action = 0 for PRESSED, 1 for + RELEASE Test toggling the LED with + `rpcs.chip.rpc.Button.Event(idx=1, pushed=True)` + +- You can also Get and Set the light directly using the RPCs: + `rpcs.chip.rpc.Lighting.Get()` + + `rpcs.chip.rpc.Lighting.Set(on=True, level=128, color=protos.chip.rpc.LightingColor(hue=5, saturation=5))` + +## Memory settings + +While most of the RAM usage in CHIP is static, allowing easier debugging and +optimization with symbols analysis, we still need some HEAP for the crypto and +OpenThread. Size of the HEAP can be modified by changing the value of the +`configTOTAL_HEAP_SIZE` define inside of the FreeRTOSConfig.h file of this +example. Please take note that a HEAP size smaller than 13k can and will cause a +Mbedtls failure during the BLE rendez-vous or CASE session + +To track memory usage you can set `enable_heap_monitoring = true` either in the +BUILD.gn file or pass it as a build argument to gn. This will print on the RTT +console the RAM usage of each individual task and the number of Memory +allocation and Free. While this is not extensive monitoring you're welcome to +modify `examples/platform/mt793x/MemMonitoring.cpp` to add your own memory +tracking code inside the `trackAlloc` and `trackFree` function diff --git a/examples/lighting-app/mtk/args.gni b/examples/lighting-app/mtk/args.gni new file mode 100644 index 00000000000000..ddbfb9fa47f20d --- /dev/null +++ b/examples/lighting-app/mtk/args.gni @@ -0,0 +1,34 @@ +# Copyright (c) 2022 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/chip.gni") +import("//build_overrides/pigweed.gni") +import("${chip_root}/src/platform/mt793x/args.gni") + +mt793x_sdk_target = get_label_info(":sdk", "label_no_toolchain") + +pw_log_BACKEND = "${chip_root}/src/lib/support/pw_log_chip" +pw_assert_BACKEND = "$dir_pw_assert_log" + +chip_enable_ble = true + +declare_args() { + chip_enable_ota_requestor = false + + # Disable lock tracking, since our FreeRTOS configuration does not set + # INCLUDE_xSemaphoreGetMutexHolder + chip_stack_lock_tracking = "none" + + chip_config_network_layer_ble = true +} diff --git a/examples/lighting-app/mtk/build_for_wifi_args.gni b/examples/lighting-app/mtk/build_for_wifi_args.gni new file mode 100644 index 00000000000000..cb0ea7600a2dd5 --- /dev/null +++ b/examples/lighting-app/mtk/build_for_wifi_args.gni @@ -0,0 +1,22 @@ +# Copyright (c) 2020 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +import("//build_overrides/chip.gni") +import("//build_overrides/pigweed.gni") + +mt793x_sdk_target = get_label_info(":sdk", "label_no_toolchain") +chip_enable_openthread = false +import("${chip_root}/src/platform/MT793X/wifi_args.gni") + +pw_log_BACKEND = "${chip_root}/src/lib/support/pw_log_chip" +pw_assert_BACKEND = "$dir_pw_assert_log" diff --git a/examples/lighting-app/mtk/build_for_wifi_gnfile.gn b/examples/lighting-app/mtk/build_for_wifi_gnfile.gn new file mode 100644 index 00000000000000..9752ee73e7c91d --- /dev/null +++ b/examples/lighting-app/mtk/build_for_wifi_gnfile.gn @@ -0,0 +1,28 @@ +# Copyright (c) 2020 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/build.gni") + +# The location of the build configuration file. +buildconfig = "${build_root}/config/BUILDCONFIG.gn" + +# CHIP uses angle bracket includes. +check_system_includes = true + +default_args = { + target_cpu = "arm" + target_os = "freertos" + use_thread = false + import("//build_for_wifi_args.gni") +} diff --git a/examples/lighting-app/mtk/build_overrides b/examples/lighting-app/mtk/build_overrides new file mode 120000 index 00000000000000..e578e73312ebd1 --- /dev/null +++ b/examples/lighting-app/mtk/build_overrides @@ -0,0 +1 @@ +../../build_overrides \ No newline at end of file diff --git a/examples/lighting-app/mtk/include/AppConfig.h b/examples/lighting-app/mtk/include/AppConfig.h new file mode 100644 index 00000000000000..b56761e90a1242 --- /dev/null +++ b/examples/lighting-app/mtk/include/AppConfig.h @@ -0,0 +1,46 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2019 Google LLC. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +// ---- Lighting Example App Config ---- + +#define APP_TASK_NAME "Lit" + +// Time it takes in ms for the simulated actuator to move from one +// state to another. +#define ACTUATOR_MOVEMENT_PERIOS_MS 10 + +// EFR Logging +#ifdef __cplusplus +extern "C" { +#endif + +void mt793xLogInit(void); + +void mt793xLog(const char * aFormat, ...); +#define MT793X_LOG(aFormat...) mt793xLog(aFormat); +void appError(int err); + +#ifdef __cplusplus +} + +#include +void appError(CHIP_ERROR error); +#endif diff --git a/examples/lighting-app/mtk/include/AppEvent.h b/examples/lighting-app/mtk/include/AppEvent.h new file mode 100644 index 00000000000000..2483fe3cf9f831 --- /dev/null +++ b/examples/lighting-app/mtk/include/AppEvent.h @@ -0,0 +1,55 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2018 Nest Labs, Inc. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +struct AppEvent; +typedef void (*EventHandler)(AppEvent *); + +struct AppEvent +{ + enum AppEventTypes + { + kEventType_Button = 0, + kEventType_Timer, + kEventType_Light, + kEventType_Install, + }; + + uint16_t Type; + + union + { + struct + { + bool Pressed; + } ButtonEvent; + struct + { + void * Context; + } TimerEvent; + struct + { + uint8_t Action; + int32_t Actor; + } LightEvent; + }; + + EventHandler Handler; +}; diff --git a/examples/lighting-app/mtk/include/AppTask.h b/examples/lighting-app/mtk/include/AppTask.h new file mode 100644 index 00000000000000..5cc614daf45db4 --- /dev/null +++ b/examples/lighting-app/mtk/include/AppTask.h @@ -0,0 +1,92 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2019 Google LLC. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include + +#include "AppEvent.h" +#include "LightingManager.h" +#include "filogic_button.h" + +#include "FreeRTOS.h" +#include "timers.h" // provides FreeRTOS timer support +#include + +// Application-defined error codes in the CHIP_ERROR space. +#define APP_ERROR_EVENT_QUEUE_FAILED CHIP_APPLICATION_ERROR(0x01) +#define APP_ERROR_CREATE_TASK_FAILED CHIP_APPLICATION_ERROR(0x02) +#define APP_ERROR_UNHANDLED_EVENT CHIP_APPLICATION_ERROR(0x03) +#define APP_ERROR_CREATE_TIMER_FAILED CHIP_APPLICATION_ERROR(0x04) +#define APP_ERROR_START_TIMER_FAILED CHIP_APPLICATION_ERROR(0x05) +#define APP_ERROR_STOP_TIMER_FAILED CHIP_APPLICATION_ERROR(0x06) + +class AppTask +{ + +public: + CHIP_ERROR StartAppTask(); + static void AppTaskMain(void * pvParameter); + + void PostLightActionRequest(int32_t aActor, LightingManager::Action_t aAction); + void PostEvent(const AppEvent * event); + + void ButtonHandler(const filogic_button_t &button); + +private: + friend AppTask & GetAppTask(void); + + CHIP_ERROR Init(); + + static void ActionInitiated(LightingManager::Action_t aAction, int32_t aActor); + static void ActionCompleted(LightingManager::Action_t aAction); + + void DispatchEvent(AppEvent * event); + + static void SingleButtonEventHandler(AppEvent * aEvent); + static void ButtonTimerEventHandler(AppEvent * aEvent); + + static void LightActionEventHandler(AppEvent * aEvent); + + static void TimerEventHandler(TimerHandle_t xTimer); + void StartTimer(uint32_t aTimeoutMs); + void CancelTimer(void); + + enum Function_t + { + kFunction_NoneSelected = 0, + kFunction_StartBleAdv = 1, + kFunction_LightSwitch = 2, + kFunction_FactoryReset = 3, + kFunction_SoftwareUpdate = 0, + + kFunction_Invalid + } Function; + + Function_t mFunction; + bool mFunctionTimerActive; + + static AppTask sAppTask; +}; + +inline AppTask & GetAppTask(void) +{ + return AppTask::sAppTask; +} diff --git a/examples/lighting-app/mtk/include/CHIPProjectConfig.h b/examples/lighting-app/mtk/include/CHIPProjectConfig.h new file mode 100644 index 00000000000000..9dc6cad0065629 --- /dev/null +++ b/examples/lighting-app/mtk/include/CHIPProjectConfig.h @@ -0,0 +1,131 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2019 Google LLC. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Example project configuration file for CHIP. + * + * This is a place to put application or project-specific overrides + * to the default configuration values for general CHIP features. + * + */ + +#pragma once + +// Use a default pairing code if one hasn't been provisioned in flash. +#ifndef CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE +#define CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE 20202021 +#endif + +#ifndef CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR +#define CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR 0xF00 +#endif + +// For convenience, Chip Security Test Mode can be enabled and the +// requirement for authentication in various protocols can be disabled. +// +// WARNING: These options make it possible to circumvent basic Chip security functionality, +// including message encryption. Because of this they MUST NEVER BE ENABLED IN PRODUCTION BUILDS. +// +#define CHIP_CONFIG_SECURITY_TEST_MODE 0 +#define CHIP_CONFIG_REQUIRE_AUTH 1 + +/** + * CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID + * + * 0xFFF1: Test vendor + */ +#define CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID 0xFFF1 + +/** + * CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID + * + * 0x8005: example lighting app + */ +#define CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID 0x8005 + +/** + * CHIP_DEVICE_CONFIG_DEVICE_HARDWARE_VERSION + * + * The hardware version number assigned to device or product by the device vendor. This + * number is scoped to the device product id, and typically corresponds to a revision of the + * physical device, a change to its packaging, and/or a change to its marketing presentation. + * This value is generally *not* incremented for device software versions. + */ +#define CHIP_DEVICE_CONFIG_DEVICE_HARDWARE_VERSION 1 + +/** + * CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING + * + * A string identifying the software version running on the device. + * CHIP service currently expects the software version to be in the format + * {MAJOR_VERSION}.0d{MINOR_VERSION} + */ +#ifndef CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING +#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING "0.1ALPHA" +#endif +/** + * CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE + * + * Enable support for Chip-over-BLE (CHIPoBLE). + */ +#define CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE 1 + +/** + * CHIP_DEVICE_CONFIG_ENABLE_CHIP_TIME_SERVICE_TIME_SYNC + * + * Enables synchronizing the device's real time clock with a remote Chip Time service + * using the Chip Time Sync protocol. + */ +#define CHIP_DEVICE_CONFIG_ENABLE_CHIP_TIME_SERVICE_TIME_SYNC 0 + +/** + * CHIP_DEVICE_CONFIG_TEST_SERIAL_NUMBER + * + * Enables the use of a hard-coded default serial number if none + * is found in Chip NV storage. + */ +#define CHIP_DEVICE_CONFIG_TEST_SERIAL_NUMBER "TEST_SN" + +/** + * CHIP_CONFIG_EVENT_LOGGING_UTC_TIMESTAMPS + * + * Enable recording UTC timestamps. + */ +#define CHIP_CONFIG_EVENT_LOGGING_UTC_TIMESTAMPS 1 + +/** + * CHIP_DEVICE_CONFIG_EVENT_LOGGING_DEBUG_BUFFER_SIZE + * + * A size, in bytes, of the individual debug event logging buffer. + */ +#define CHIP_DEVICE_CONFIG_EVENT_LOGGING_DEBUG_BUFFER_SIZE (512) + +/** + * @def CHIP_CONFIG_MRP_DEFAULT_ACTIVE_RETRY_INTERVAL + * + * @brief + * Active retransmit interval, or time to wait before retransmission after + * subsequent failures in milliseconds. + * + * This is the default value, that might be adjusted by end device depending on its + * needs (e.g. sleeping period) using Service Discovery TXT record CRA key. + * + */ +#define CHIP_CONFIG_MRP_DEFAULT_ACTIVE_RETRY_INTERVAL (2000_ms32) diff --git a/examples/lighting-app/mtk/include/LEDWidget.h b/examples/lighting-app/mtk/include/LEDWidget.h new file mode 100644 index 00000000000000..6d611f4034ed9f --- /dev/null +++ b/examples/lighting-app/mtk/include/LEDWidget.h @@ -0,0 +1,70 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + + +#include +#include + +#include + + +enum led_id { + LED_LIGHT, + LED_STATUS +}; + + +enum led_color { + LED_RED, + LED_GREEN, + LED_BLUE +}; + + +class LEDWidget +{ +public: + // bind this LEDWidget with the specified LED + void Init (enum led_id led); + // retrieve the name of this LED + const char * Name (void); + // set to ON or OFF, no blink + void Set (bool state); + // change the color + void Color(enum led_color color); + // specify the ON, OFF duration + void Blink(int on, int off); + // specify evenly ON and OFF both to 'duration' + void Blink(int duration); + +private: + enum led_id mLed; + enum led_color mColor; + int mOn; + int mOff; + bool mState; + void Toggle(void); + void DoSet (bool state); + + TimerHandle_t mTimer; + static void TimerHandler(TimerHandle_t xTimer); + void DoBlink(void); + void StartTimer(uint32_t aTimeoutInMs); + void CancelTimer(void); +}; diff --git a/examples/lighting-app/mtk/include/LightingManager.h b/examples/lighting-app/mtk/include/LightingManager.h new file mode 100644 index 00000000000000..3aa9871e919074 --- /dev/null +++ b/examples/lighting-app/mtk/include/LightingManager.h @@ -0,0 +1,85 @@ +/* + * + * Copyright (c) 2019 Google LLC. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include + +#include "AppEvent.h" + +#include "FreeRTOS.h" +#include "timers.h" // provides FreeRTOS timer support + +#include + +class LightingManager +{ +public: + enum Action_t + { + ON_ACTION = 0, + OFF_ACTION, + + INVALID_ACTION + } Action; + + enum State_t + { + kState_OffInitiated = 0, + kState_OffCompleted, + kState_OnInitiated, + kState_OnCompleted, + } State; + + CHIP_ERROR Init(); + bool IsLightOn(); + void EnableAutoTurnOff(bool aOn); + void SetAutoTurnOffDuration(uint32_t aDurationInSecs); + bool IsActionInProgress(); + bool InitiateAction(int32_t aActor, Action_t aAction); + + typedef void (*Callback_fn_initiated)(Action_t, int32_t aActor); + typedef void (*Callback_fn_completed)(Action_t); + void SetCallbacks(Callback_fn_initiated aActionInitiated_CB, Callback_fn_completed aActionCompleted_CB); + +private: + friend LightingManager & LightMgr(void); + State_t mState; + + Callback_fn_initiated mActionInitiated_CB; + Callback_fn_completed mActionCompleted_CB; + + bool mAutoTurnOff; + uint32_t mAutoTurnOffDuration; + bool mAutoTurnOffTimerArmed; + + void CancelTimer(void); + void StartTimer(uint32_t aTimeoutMs); + + static void TimerEventHandler(TimerHandle_t xTimer); + static void AutoTurnOffTimerEventHandler(AppEvent * aEvent); + static void ActuatorMovementTimerEventHandler(AppEvent * aEvent); + + static LightingManager sLight; +}; + +inline LightingManager & LightMgr(void) +{ + return LightingManager::sLight; +} diff --git a/examples/lighting-app/mtk/mt793x_xip.ld b/examples/lighting-app/mtk/mt793x_xip.ld new file mode 100755 index 00000000000000..fd577c07ca60a0 --- /dev/null +++ b/examples/lighting-app/mtk/mt793x_xip.ld @@ -0,0 +1,394 @@ +/* + * MT7933 CM33 Memory Map + */ + +HIDDEN(__STACK_SIZE = 0x1000); +HIDDEN(__SYSRAM_OFFSET = 0x0); + +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Memory Spaces Definitions: 16MB flash */ +MEMORY +{ + ROM_BL(rx) : ORIGIN = 0x18000000, LENGTH = 64K + ROM_RBL(rx) : ORIGIN = 0x18010000, LENGTH = 8K + ROM_TFM(rx) : ORIGIN = 0x18012000, LENGTH = 200K + ROM_RTOS(rx) : ORIGIN = 0x18044000, LENGTH = 2092K + /* + Reserved : LENGTH = 228 K, 152 K For TFM + Free For Customer : LENGTH = 500 K + */ + ROM_FOTA(r) : ORIGIN = 0x18305000, LENGTH = 3968K + ROM_NVDM(rx) : ORIGIN = 0x186E5000, LENGTH = 64K + ROM_LOG(rx) : ORIGIN = 0x186F5000, LENGTH = 64K + ROM_BT(rx) : ORIGIN = 0x18705000, LENGTH = 304K + /* + Reserved For FW : LENGTH = 40 K + */ + ROM_WIFI_PWRTBL(rx): ORIGIN = 0x1875B000, LENGTH = 20K + ROM_WIFI_EXT(rx) : ORIGIN = 0x18760000, LENGTH = 636K + ROM_BUFFER_BIN(rx): ORIGIN = 0x187FF000, LENGTH = 4K + + TCM(rwx) : ORIGIN = 0x0010C000, LENGTH = 20K + RAM_WFFW(rwx) : ORIGIN = 0xA0000000, LENGTH = 312K + RAM(rwx) : ORIGIN = 0xA004E000, LENGTH = 3272K + RAM_TFM(rwx) : ORIGIN = 0xA0380000, LENGTH = 512K + RAM_BTFW(rwx) : ORIGIN = 0xA0400000, LENGTH = 352K + SYSRAM(rwx) : ORIGIN = 0x80000000, LENGTH = 992K + /* + Reserved : LENGTH = 32K + */ + + VROM(rx) : ORIGIN = 0x18000000, LENGTH = 4096K + VRAM_WFFW(rwx) : ORIGIN = 0x10000000, LENGTH = 312K + VRAM(rwx) : ORIGIN = 0x1004E000, LENGTH = 3272K + VRAM_TFM(rwx) : ORIGIN = 0x10380000, LENGTH = 512K + VRAM_BTFW(rwx) : ORIGIN = 0x10400000, LENGTH = 352K + VSYSRAM(rwx) : ORIGIN = 0x08000000, LENGTH = 992K + /* + Reserved : LENGTH = 32K + */ +} + +/**************************************************************************** + * + * FORWARD DECLARATIONS - SECTION SYMBOLS @ FLASH PHYSICAL ADDRESS + * + ****************************************************************************/ + + +_rom_bl_start = ORIGIN(ROM_BL) - ORIGIN(ROM_BL); +_rom_bl_length = LENGTH(ROM_BL); +_rom_rbl_start = ORIGIN(ROM_RBL) - ORIGIN(ROM_BL); +_rom_rbl_length = LENGTH(ROM_RBL); +_rom_tfm_start = ORIGIN(ROM_TFM) - ORIGIN(ROM_BL); +_rom_tfm_length = LENGTH(ROM_TFM); +_rom_rtos_start = ORIGIN(ROM_RTOS) - ORIGIN(ROM_BL); +_rom_rtos_length = LENGTH(ROM_RTOS); +_rom_fota_start = ORIGIN(ROM_FOTA) - ORIGIN(ROM_BL); +_rom_fota_length = LENGTH(ROM_FOTA); +_rom_wifi_patch_start = 0;/*ORIGIN(ROM_WIFI_PATCH) - ORIGIN(ROM_BL);*/ +_rom_wifi_patch_length = 0;/*LENGTH(ROM_WIFI_PATCH);*/ +_rom_wifi_start = 0;/*ORIGIN(ROM_WIFI) - ORIGIN(ROM_BL);*/ +_rom_wifi_length = 0;/*LENGTH(ROM_WIFI);*/ +_rom_wifi_ext_start = ORIGIN(ROM_WIFI_EXT) - ORIGIN(ROM_BL); +_rom_wifi_ext_length = LENGTH(ROM_WIFI_EXT); +_rom_wifi_pwrtbl_start = ORIGIN(ROM_WIFI_PWRTBL) - ORIGIN(ROM_BL); +_rom_wifi_pwrtbl_length = LENGTH(ROM_WIFI_PWRTBL); +_rom_buffer_bin_start = ORIGIN(ROM_BUFFER_BIN) - ORIGIN(ROM_BL); +_rom_buffer_bin_length = LENGTH(ROM_BUFFER_BIN); +_rom_bt_start = ORIGIN(ROM_BT) - ORIGIN(ROM_BL); +_rom_bt_length = LENGTH(ROM_BT); +_rom_nvdm_start = ORIGIN(ROM_NVDM) - ORIGIN(ROM_BL); +_rom_nvdm_length = LENGTH(ROM_NVDM); +_rom_log_start = ORIGIN(ROM_LOG) - ORIGIN(ROM_BL); +_rom_log_length = LENGTH(ROM_LOG); + + +/**************************************************************************** + * + * FORWARD DECLARATIONS - SECTION SYMBOLS @ MEMORY BUS ADDRESS + * + ****************************************************************************/ + +_xip_bl_addr = ORIGIN(ROM_BL); +_xip_rbl_addr = ORIGIN(ROM_RBL); +_xip_tfm_addr = ORIGIN(ROM_TFM); +_xip_rtos_addr = ORIGIN(ROM_RTOS); +_xip_nvdm_start = ORIGIN(ROM_NVDM); +_xip_log_start = ORIGIN(ROM_LOG); +_xip_bt_start = ORIGIN(ROM_BT); + +_sysram_start = ORIGIN(SYSRAM); +_sysram_length = LENGTH(SYSRAM); +_ram_start = ORIGIN(RAM); +_ram_length = LENGTH(RAM); +_ram_wifi_ext_start = ORIGIN(RAM_WFFW); +_ram_wifi_ext_length = LENGTH(RAM_WFFW); +_vram_start = ORIGIN(VRAM); +_vram_length = LENGTH(VRAM); +_vsysram_start = ORIGIN(VSYSRAM); +_vsysram_length = LENGTH(VSYSRAM); +_tcm_start = ORIGIN(TCM); +_tcm_length = LENGTH(TCM); + + /* Highest address of the stack */ +_stack_end = ORIGIN(TCM) + LENGTH(TCM); /* end of TCM */ + +/* stack start */ +_stack_start = _stack_end - __STACK_SIZE; + +/* SYSRAM Region0 Offset for BROM */ +_region0_offset = 0x13000 ; + +SECTIONS +{ + . = ORIGIN(ROM_RTOS); + .text ALIGN(4): + { + _text_start = .; + KEEP(*(.vectorsTop)) + KEEP(*(.vectors)) + /* *(.text*) */ + *(EXCLUDE_FILE(*/iperf_task.o *sockets*.o *netbuf*.o *pbuf*.o */mem.o *api_lib*.o */def.o *api_msg*.o *sys_arch*.o *ip4*.o *ip4_addr*.o *udp*.o *inet_chksum*.o *tcp_out*.o *tcp*.o */netif.o */ethernet.o *etharp*.o */lwip_cli.o *portasm*.o *event_groups*.o */heap_ext.o */queue.o */tasks.o *list*.o *os_port_callback*.o */port.o *timers*.o *hal_nvic*.o *libc_nano*.a:*memset*.o *libc_nano*.a:*memcpy*.o *libminisupp.a:*mem*.o) .text*) + KEEP(*(.init)) + KEEP(*(.fini)) + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + *(.rodata*) + *(.rom_rtos) + KEEP(*(.eh_frame*)) + . = ALIGN(4); + _text_end = .; + } > ROM_RTOS AT> ROM_RTOS + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > ROM_RTOS AT> ROM_RTOS + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > ROM_RTOS AT> ROM_RTOS + __exidx_end = .; + + . = ALIGN(32); + _sysram_code_load = LOADADDR(.sysram_text); + .sysram_text ORIGIN(VSYSRAM)+_region0_offset : + { + _sysram_code_start = .; + *(.sysram_code) + *(.text*) + *(.sysram_rodata) + . = ALIGN(4); + _sysram_code_end = .; + } > VSYSRAM AT> ROM_RTOS + + . = ALIGN(4); + _sysram_data_load = LOADADDR(.cached_sysram_data); + .cached_sysram_data : + { + _sysram_data_start = .; + *(vtable) + *(.data) + *(.data.*) + *(.sysram_rwdata) + . = ALIGN(4); + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + . = ALIGN(4); + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + KEEP(*(.jcr*)) + . = ALIGN(4); + _sysram_data_end = .; + } > VSYSRAM AT> ROM_RTOS + + . = ALIGN(4); + .bss (NOLOAD) : + { + _sysram_bss_start = .; + *(.bss) + *(.bss.*) + *(COMMON) + *(.sysram_zidata) + *(.sysram_swla_zidata) + . = ALIGN(4); + _sysram_bss_end = .; + } > VSYSRAM AT> ROM_RTOS + + + . = ALIGN(32); + _noncached_sysram_code_load = LOADADDR(.noncached_sysram_text); + . = . + ORIGIN(SYSRAM) - ORIGIN(VSYSRAM); + .noncached_sysram_text . : + { + _noncached_sysram_code_start = .; + *(.noncached_sysram_code) + *(.noncached_sysram_rodata) + . = ALIGN(4); + _noncached_sysram_code_end = .; + } > SYSRAM AT> ROM_RTOS + + . = ALIGN(4); + _noncached_sysram_data_load = LOADADDR(.noncached_sysram_data); + .noncached_sysram_data . : + { + _noncached_sysram_data_start = .; + *(.noncached_sysram_rwdata) + *(.secure_settings_section) + . = ALIGN(4); + _noncached_sysram_data_end = .; + } > SYSRAM AT> ROM_RTOS + + . = ALIGN(4); + .noncached_sysram_bss . (NOLOAD) : + { + _noncached_sysram_bss_start = .; + *(.noncached_sysram_zidata) + . = ALIGN(4); + _noncached_sysram_bss_end = .; + } > SYSRAM AT> ROM_RTOS + + . = ALIGN(32); + .btfw_code (NOLOAD) : + { + *(.bt_firmware_emi_code) + . = ALIGN(4); + } > RAM_BTFW AT> ROM_RTOS + + . = ALIGN(32); + .wffw_code (NOLOAD) : + { + *(.wf_firmware_emi_code) + . = ALIGN(4); + } > RAM_WFFW AT> ROM_RTOS + + . = ALIGN(32); + _ram_code_load = LOADADDR(.cached_ram_text); + .cached_ram_text : + { + _ram_code_start = .; + *(.ram_code) + *(.ram_rodata) + . = ALIGN(4); + _ram_code_end = .; + } > VRAM AT> ROM_RTOS + + . = ALIGN(4); + _ram_data_load = LOADADDR(.cached_ram_data); + .cached_ram_data : + { + _ram_data_start = .; + *(.ram_rwdata) + . = ALIGN(4); + _ram_data_end = .; + } > VRAM AT> ROM_RTOS + + . = ALIGN(4); + _ram_bss_load = LOADADDR(.cached_ram_bss); + .cached_ram_bss (NOLOAD) : + { + _ram_bss_start = .; + *(.ram_zidata) + . = ALIGN(4); + _ram_bss_end = .; + } > VRAM AT> ROM_RTOS + + . = ALIGN(32); + _noncached_ram_code_load = LOADADDR(.noncached_ram_text); + . = . + ORIGIN(RAM) - ORIGIN(VRAM); + .noncached_ram_text . : + { + _noncached_ram_code_start = .; + *(.noncached_ram_code) + *(.noncached_ram_rodata) + . = ALIGN(4); + _noncached_ram_code_end = .; + } > RAM AT> ROM_RTOS + + . = ALIGN(4); + _noncached_ram_data_load = LOADADDR(.noncached_ram_data); + .noncached_ram_data . : + { + _noncached_ram_data_start = .; + *(.noncached_ram_rwdata) + . = ALIGN(4); + _noncached_ram_data_end = .; + } > RAM AT> ROM_RTOS + + . = ALIGN(4); + _noncached_ram_bss_load = LOADADDR(.noncached_ram_bss); + .noncached_ram_bss . (NOLOAD) : + { + _noncached_ram_bss_start = .; + *(.noncached_ram_zidata) + . = ALIGN(4); + _noncached_ram_bss_end = .; + } > RAM AT> ROM_RTOS + + + . = ALIGN(4); + _tcm_code_load = LOADADDR(.tcm_text); + .tcm_text : + { + _tcm_code_start = .; + *(.tcm_code) + *(.tcm_rodata) + . = ALIGN(4); + _tcm_code_end = .; + }> TCM AT> ROM_RTOS + + . = ALIGN(4); + _tcm_data_load = LOADADDR(.tcm_data); + .tcm_data : + { + _tcm_data_start = .; + . = ALIGN(4); + *(.tcm_rwdata) + . = ALIGN(4); + _tcm_data_end = .; + }> TCM AT> ROM_RTOS + + . = ALIGN(4); + .tcm_bss (NOLOAD) : + { + _tcm_bss_start = .; + *(.tcm_zidata) + . = ALIGN(4); + *(.tcm_wakeup_info) + . = ALIGN(4); + _tcm_bss_end = .; + }> TCM AT> ROM_RTOS + + + __end__ = .; + + .mcuboot_tlv_rsvd (NOLOAD) : + { + /* reserve 512 bytes for imgtool.py TLVs */ + . = . + 512 ; + } > ROM_RTOS AT> ROM_RTOS + + .stack (ORIGIN(TCM) + LENGTH(TCM) - __STACK_SIZE) (COPY) : + { + . = ALIGN(4); + __StackLimit = .; + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + __STACK_SIZE; + . = ALIGN(4); + __StackTop = .; + } > TCM + + PROVIDE(__stack = __StackTop); + + ASSERT(__StackLimit >= __end__, "region TCM overflowed with stack") +} + + + diff --git a/examples/lighting-app/mtk/src/AppTask.cpp b/examples/lighting-app/mtk/src/AppTask.cpp new file mode 100644 index 00000000000000..5a5b67fb6a202c --- /dev/null +++ b/examples/lighting-app/mtk/src/AppTask.cpp @@ -0,0 +1,525 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2019 Google LLC. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "AppTask.h" +#include "AppConfig.h" +#include "AppEvent.h" +#include "LEDWidget.h" + +#include "qrcodegen.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include +#include + +#include + +#include +#include + + +#define FACTORY_RESET_TRIGGER_TIMEOUT 3000 +#define FACTORY_RESET_CANCEL_WINDOW_TIMEOUT 3000 +#define APP_TASK_STACK_SIZE (4096) +#define APP_TASK_PRIORITY 2 +#define APP_EVENT_QUEUE_SIZE 10 +#define EXAMPLE_VENDOR_ID 0xcafe + + +#ifdef portYIELD_FROM_ISR +#define OS_YIELD_FROM_ISR(yield) portYIELD_FROM_ISR(yield) +#elif portEND_SWITCHING_ISR +#define OS_YIELD_FROM_ISR(yield) portEND_SWITCHING_ISR(yield) +#else +#error "Must have portYIELD_FROM_ISR or portEND_SWITCHING_ISR" +#endif + + +#define UNUSED_PARAMETER(a) (a = a) + + +namespace { + +TimerHandle_t sFunctionTimer; // FreeRTOS app sw timer. +TaskHandle_t sAppTaskHandle; +QueueHandle_t sAppEventQueue; + +LEDWidget sStatusLED; +LEDWidget sLightLED; + +bool sIsWiFiProvisioned = false; +bool sIsWiFiEnabled = false; +bool sIsWiFiAttached = false; + +uint8_t sAppEventQueueBuffer[APP_EVENT_QUEUE_SIZE * sizeof(AppEvent)]; +StaticQueue_t sAppEventQueueStruct; + +StackType_t appStack[APP_TASK_STACK_SIZE * 2 / sizeof(StackType_t)]; +StaticTask_t appTaskStruct; + +#if CHIP_DEVICE_CONFIG_ENABLE_WIFI_STATION +using namespace chip::DeviceLayer::NetworkCommissioning; +chip::app::Clusters::NetworkCommissioning::Instance + sWiFiNetworkCommissioningInstance(0 /* Endpoint Id */, + &GenioWiFiDriver::GetInstance()); +#endif + +} + + +using namespace chip::TLV; +using namespace ::chip::Credentials; +using namespace ::chip::DeviceLayer; + + +AppTask AppTask::sAppTask; + + +CHIP_ERROR AppTask::StartAppTask() +{ + sAppEventQueue = xQueueCreateStatic(APP_EVENT_QUEUE_SIZE, + sizeof(AppEvent), + sAppEventQueueBuffer, + &sAppEventQueueStruct); + if (sAppEventQueue == NULL) + { + MT793X_LOG("Failed to allocate app event queue"); + appError(APP_ERROR_EVENT_QUEUE_FAILED); + } + + // Start App task. + sAppTaskHandle = xTaskCreateStatic(AppTaskMain, + APP_TASK_NAME, + ArraySize(appStack), + NULL, + 1, + appStack, + &appTaskStruct); + if (sAppTaskHandle == nullptr) + return APP_ERROR_CREATE_TASK_FAILED; + + return CHIP_NO_ERROR; +} + + +CHIP_ERROR AppTask::Init() +{ + CHIP_ERROR error = CHIP_NO_ERROR; + + // Wait for the WiFi to be initialized + MT793X_LOG("APP: Wait WiFi Init"); + vTaskDelay(1000); //TODO + MT793X_LOG("APP: Done WiFi Init"); + +#if CHIP_DEVICE_CONFIG_ENABLE_WIFI_STATION + sWiFiNetworkCommissioningInstance.Init(); +#endif + + // Init ZCL Data Model and start server + static chip::CommonCaseDeviceServerInitParams initParams; + (void) initParams.InitializeStaticResourcesBeforeServerInit(); + chip::Server::GetInstance().Init(initParams); + + // Initialize device attestation config + SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); + + // Create FreeRTOS sw timer for Function Selection. + sFunctionTimer = xTimerCreate("FnTmr", // Just a text name, not used by the RTOS kernel + 1, // == default timer period (mS) + false, // no timer reload (==one-shot) + (void *) this, // init timer id = app task obj context + TimerEventHandler // timer callback handler + ); + if (sFunctionTimer == NULL) + { + MT793X_LOG("funct timer create failed"); + appError(APP_ERROR_CREATE_TIMER_FAILED); + } + + MT793X_LOG("Current Software Version: %s", CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING); + error = LightMgr().Init(); + if (error != CHIP_NO_ERROR) + { + MT793X_LOG("LightMgr Init failed"); + appError(error); + } + + LightMgr().SetCallbacks(ActionInitiated, ActionCompleted); + + sStatusLED.Init(LED_STATUS); + sLightLED.Init(LED_LIGHT); + sLightLED.Set(LightMgr().IsLightOn()); + + ConfigurationMgr().LogDeviceConfig(); + + //PrintOnboardingCodes(chip::RendezvousInformationFlag(chip::RendezvousInformationFlag::kBLE)); + PrintOnboardingCodes(chip::RendezvousInformationFlag(chip::RendezvousInformationFlag::kSoftAP)); + + return error; +} + + +void AppTask::AppTaskMain(void * pvParameter) +{ + AppEvent event; + + CHIP_ERROR error = sAppTask.Init(); + if (error != CHIP_NO_ERROR) + { + MT793X_LOG("AppTask.Init() failed"); + appError(error); + } + + MT793X_LOG("AppTask started"); + + while (true) + { + BaseType_t eventReceived = xQueueReceive(sAppEventQueue, + &event, + pdMS_TO_TICKS(10)); + while (eventReceived == pdTRUE) + { + sAppTask.DispatchEvent(&event); + eventReceived = xQueueReceive(sAppEventQueue, &event, 0); + } + + // Collect connectivity and configuration state from the CHIP stack. Because + // the CHIP event loop is being run in a separate task, the stack must be + // locked while these values are queried. However we use a non-blocking + // lock request (TryLockCHIPStack()) to avoid blocking other UI activities + // when the CHIP task is busy (e.g. with a long crypto operation). + if (PlatformMgr().TryLockChipStack()) + { + sIsWiFiProvisioned = ConnectivityMgr().IsWiFiStationProvisioned(); + sIsWiFiEnabled = ConnectivityMgr().IsWiFiStationEnabled(); + sIsWiFiAttached = ConnectivityMgr().IsWiFiStationConnected(); + + PlatformMgr().UnlockChipStack(); + } + + // Update the status LED if factory reset has not been initiated. + // + // If system has "full connectivity", keep the LED On constantly. + // + // If thread and service provisioned, but not attached to the thread network + // yet OR no connectivity to the service OR subscriptions are not fully + // established THEN blink the LED Off for a short period of time. + // + // If the system has ble connection(s) uptill the stage above, THEN blink + // the LEDs at an even rate of 100ms. + // + // Otherwise, blink the LED ON for a very short time. + if (sAppTask.mFunction != kFunction_FactoryReset) + { + if (sIsWiFiProvisioned && sIsWiFiEnabled && !sIsWiFiAttached) + { + sStatusLED.Blink(950, 50); + } + else + { + sStatusLED.Blink(50, 950); + } + } + } +} + + +void AppTask::LightActionEventHandler(AppEvent * aEvent) +{ + bool initiated = false; + LightingManager::Action_t action; + int32_t actor; + CHIP_ERROR err = CHIP_NO_ERROR; + + if (aEvent->Type == AppEvent::kEventType_Light) + { + action = static_cast(aEvent->LightEvent.Action); + actor = aEvent->LightEvent.Actor; + } + else if (aEvent->Type == AppEvent::kEventType_Button) + { + if (LightMgr().IsLightOn()) + { + action = LightingManager::OFF_ACTION; + } + else + { + action = LightingManager::ON_ACTION; + } + actor = AppEvent::kEventType_Button; + } + else + { + err = APP_ERROR_UNHANDLED_EVENT; + } + + if (err == CHIP_NO_ERROR) + { + initiated = LightMgr().InitiateAction(actor, action); + + if (!initiated) + { + MT793X_LOG("Action is already in progress or active."); + } + } +} + + +void AppTask::ButtonTimerEventHandler(AppEvent * aEvent) +{ + if (aEvent->Type != AppEvent::kEventType_Timer || + sAppTask.mFunctionTimerActive == false) + { + return; + } + + switch (sAppTask.mFunction) + { + case kFunction_NoneSelected: + break; + + case kFunction_LightSwitch: + // Start timer for user to cancel the facotry reset, if needed + MT793X_LOG("Factory Reset Triggered."); + MT793X_LOG("Release button within %ums to cancel.", + FACTORY_RESET_CANCEL_WINDOW_TIMEOUT); + sAppTask.StartTimer(FACTORY_RESET_CANCEL_WINDOW_TIMEOUT); + sAppTask.mFunction = kFunction_FactoryReset; + + // Turn off all LEDs before starting blink to make sure blink is + // co-ordinated. + sStatusLED.Set(false); + sStatusLED.Blink(500); + break; + + case kFunction_FactoryReset: + MT793X_LOG("Factory Reset Start."); + // Actually trigger Factory Reset + sAppTask.mFunction = kFunction_NoneSelected; + ConfigurationMgr().InitiateFactoryReset(); + sStatusLED.Set(true); + break; + + default: + break; + } +} + + +void AppTask::SingleButtonEventHandler(AppEvent * aEvent) +{ + if (aEvent->Type != AppEvent::kEventType_Button) + { + MT793X_LOG("A Non ButtonEvent received %d", aEvent->Type); + return; + } + + if (aEvent->ButtonEvent.Pressed) + { + if (sAppTask.mFunctionTimerActive == false) + { + /* Start the timer to detect how long Button has been pressed */ + MT793X_LOG("AppTask status LED on"); + sStatusLED.Set(true); + sAppTask.mFunction = kFunction_LightSwitch; + sAppTask.StartTimer(FACTORY_RESET_TRIGGER_TIMEOUT); + } + else + { + MT793X_LOG("AppTask function timer already started"); + } + } + else + { + /* Cancel the timer to detect how long Button has been pressed */ + sAppTask.CancelTimer(); + + switch (sAppTask.mFunction) + { + case kFunction_LightSwitch: + MT793X_LOG("AppTask light switch"); + AppEvent event; + event.Type = AppEvent::kEventType_Button; + LightActionEventHandler(&event); + break; + case kFunction_FactoryReset: + // factory reset cancelled, restore LED + MT793X_LOG("AppTask factory reset cancelled"); + break; + default: + MT793X_LOG("not handled key release event, mFunction = %x", sAppTask.mFunction); + break; + } + + sStatusLED.Set(false); + + sAppTask.mFunction = kFunction_NoneSelected; + } +} + + +void AppTask::ButtonHandler(const filogic_button_t &button) +{ + AppEvent button_event = {}; + button_event.Type = AppEvent::kEventType_Button; + button_event.ButtonEvent.Pressed = button.press; + button_event.Handler = SingleButtonEventHandler; + sAppTask.PostEvent(&button_event); +} + + +void AppTask::TimerEventHandler(TimerHandle_t xTimer) +{ + AppEvent event; + event.Type = AppEvent::kEventType_Timer; + event.TimerEvent.Context = (void *) xTimer; + event.Handler = ButtonTimerEventHandler; + sAppTask.PostEvent(&event); +} + + +void AppTask::CancelTimer() +{ + if (xTimerStop(sFunctionTimer, 0) == pdFAIL) + { + MT793X_LOG("app timer stop() failed"); + appError(APP_ERROR_STOP_TIMER_FAILED); + } + + mFunctionTimerActive = false; +} + + +void AppTask::StartTimer(uint32_t aTimeoutInMs) +{ + if (xTimerIsTimerActive(sFunctionTimer)) + { + MT793X_LOG("app timer already started!"); + CancelTimer(); + } + + // timer is not active, change its period to required value (== restart). + // FreeRTOS- Block for a maximum of 100 ticks if the change period command + // cannot immediately be sent to the timer command queue. + if (xTimerChangePeriod(sFunctionTimer, aTimeoutInMs / portTICK_PERIOD_MS, 100) != pdPASS) + { + MT793X_LOG("app timer start() failed"); + appError(APP_ERROR_START_TIMER_FAILED); + } + + mFunctionTimerActive = true; +} + + +void AppTask::ActionInitiated(LightingManager::Action_t aAction, int32_t aActor) +{ + // Action initiated, update the light led + if (aAction == LightingManager::ON_ACTION) + { + MT793X_LOG("Turning light ON") + sLightLED.Set(true); + } + else if (aAction == LightingManager::OFF_ACTION) + { + MT793X_LOG("Turning light OFF") + sLightLED.Set(false); + } +} + + +void AppTask::ActionCompleted(LightingManager::Action_t aAction) +{ + // action has been completed bon the light + if (aAction == LightingManager::ON_ACTION) + { + MT793X_LOG("Light ON") + } + else if (aAction == LightingManager::OFF_ACTION) + { + MT793X_LOG("Light OFF") + } +} + + +void AppTask::PostLightActionRequest(int32_t aActor, LightingManager::Action_t aAction) +{ + AppEvent event; + event.Type = AppEvent::kEventType_Light; + event.LightEvent.Actor = aActor; + event.LightEvent.Action = aAction; + event.Handler = LightActionEventHandler; + PostEvent(&event); +} + + +void AppTask::PostEvent(const AppEvent * aEvent) +{ + if (sAppEventQueue != NULL) + { + BaseType_t status; + if (xPortIsInsideInterrupt()) + { + BaseType_t higherPrioTaskWoken; + + higherPrioTaskWoken = pdFALSE; + status = xQueueSendFromISR(sAppEventQueue, + aEvent, + &higherPrioTaskWoken); + OS_YIELD_FROM_ISR(higherPrioTaskWoken); + } + else + { + status = xQueueSend(sAppEventQueue, aEvent, 1); + } + + if (!status) + MT793X_LOG("Failed to post event to app task event queue"); + } + else + { + MT793X_LOG("Event Queue is NULL should never happen"); + } +} + + +void AppTask::DispatchEvent(AppEvent * aEvent) +{ + if (aEvent->Handler) + { + aEvent->Handler(aEvent); + } + else + { + MT793X_LOG("Event received with no handler. Dropping event."); + } +} diff --git a/examples/lighting-app/mtk/src/LEDWidget.cpp b/examples/lighting-app/mtk/src/LEDWidget.cpp new file mode 100644 index 00000000000000..7ee325ae8e94bd --- /dev/null +++ b/examples/lighting-app/mtk/src/LEDWidget.cpp @@ -0,0 +1,145 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + +#include +#include + + +#include + + +#include "LEDWidget.h" + + +void LEDWidget::TimerHandler(TimerHandle_t xTimer) +{ + LEDWidget *led_widget = (LEDWidget *)pvTimerGetTimerID(xTimer); + led_widget->Toggle(); +} + + +void LEDWidget::StartTimer(uint32_t aTimeoutInMs) +{ + if (xTimerIsTimerActive(mTimer)) + CancelTimer(); + + assert(xTimerChangePeriod(mTimer, aTimeoutInMs / portTICK_PERIOD_MS, 100) == pdPASS); +} + + +void LEDWidget::CancelTimer(void) +{ + assert(xTimerStop(mTimer, 0) == pdPASS); +} + + +void LEDWidget::Init(enum led_id led) +{ + filogic_led_init(); + + mLed = led; + + mTimer = xTimerCreate(Name(), + 1, // == default timer period (mS) + false, // no timer reload (==one-shot) + (void *) this, // init timer id = app task obj context + TimerHandler); // timer callback handler +} + + +const char *LEDWidget::Name(void) +{ + const char *name; + + switch (mLed) { + case LED_LIGHT: name = "LED_LIGHT"; break; + case LED_STATUS: name = "LED_STATUS"; break; + default: name ="LED UNKNOWN"; break; + } + + return name; +} + + +void LEDWidget::Toggle(void) +{ + Set(!mState); + StartTimer(mState ? mOn : mOff); +} + + +void LEDWidget::DoBlink(void) +{ + // turn off then turn on + Set(false); + Set(true); + StartTimer(mOn); +} + + +void LEDWidget::DoSet(bool state) +{ + switch (mLed) { + case LED_LIGHT: filogic_led_light_toggle(state); break; + case LED_STATUS: filogic_led_status_toggle(state); break; + } + mState = state; +} + + +void LEDWidget::Set(bool state) +{ + CancelTimer(); + DoSet(state); + //printf("%s %s\n", Name(), state ? "on" : "off"); +} + + +void LEDWidget::Blink(int on, int off) +{ + if (mOn != on || mOff != off) { + mOn = on; mOff = off; + printf("%s blink: on %d off %d\n", Name(), mOn, mOff); + DoBlink(); + } +} + + +void LEDWidget::Blink(int duration) +{ + Blink(duration, duration); +} + + +void LEDWidget::Color(enum led_color color) +{ + filogic_led_color_t _color = FILOGIC_LED_OFF; + + switch (color) { + case LED_RED: _color = FILOGIC_LED_R; + case LED_GREEN: _color = FILOGIC_LED_G; + case LED_BLUE: _color = FILOGIC_LED_B; + } + + switch (mLed) { + case LED_LIGHT: filogic_led_light_color(_color); break; + case LED_STATUS: filogic_led_status_color(_color); break; + } + + printf("%s color %d\n", Name(), color); +} diff --git a/examples/lighting-app/mtk/src/LightingManager.cpp b/examples/lighting-app/mtk/src/LightingManager.cpp new file mode 100644 index 00000000000000..a9fcd2a0fc9789 --- /dev/null +++ b/examples/lighting-app/mtk/src/LightingManager.cpp @@ -0,0 +1,225 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2019 Google LLC. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "LightingManager.h" + +#include "AppConfig.h" +#include "AppTask.h" +#include + +LightingManager LightingManager::sLight; + +TimerHandle_t sLightTimer; + +CHIP_ERROR LightingManager::Init() +{ + // Create FreeRTOS sw timer for light timer. + sLightTimer = xTimerCreate("lightTmr", // Just a text name, not used by the RTOS kernel + 1, // == default timer period (mS) + false, // no timer reload (==one-shot) + (void *) this, // init timer id = light obj context + TimerEventHandler // timer callback handler + ); + + if (sLightTimer == NULL) + { + MT793X_LOG("sLightTimer timer create failed"); + return APP_ERROR_CREATE_TIMER_FAILED; + } + + mState = kState_OffCompleted; + mAutoTurnOffTimerArmed = false; + mAutoTurnOff = false; + mAutoTurnOffDuration = 0; + + return CHIP_NO_ERROR; +} + +void LightingManager::SetCallbacks(Callback_fn_initiated aActionInitiated_CB, Callback_fn_completed aActionCompleted_CB) +{ + mActionInitiated_CB = aActionInitiated_CB; + mActionCompleted_CB = aActionCompleted_CB; +} + +bool LightingManager::IsActionInProgress() +{ + return (mState == kState_OffInitiated || mState == kState_OnInitiated); +} + +bool LightingManager::IsLightOn() +{ + return (mState == kState_OnCompleted); +} + +void LightingManager::EnableAutoTurnOff(bool aOn) +{ + mAutoTurnOff = aOn; +} + +void LightingManager::SetAutoTurnOffDuration(uint32_t aDurationInSecs) +{ + mAutoTurnOffDuration = aDurationInSecs; +} + +bool LightingManager::InitiateAction(int32_t aActor, Action_t aAction) +{ + bool action_initiated = false; + State_t new_state; + + // Initiate Turn On/Off Action only when the previous one is complete. + if (mState == kState_OffCompleted && aAction == ON_ACTION) + { + action_initiated = true; + + new_state = kState_OnInitiated; + } + else if (mState == kState_OnCompleted && aAction == OFF_ACTION) + { + action_initiated = true; + + new_state = kState_OffInitiated; + } + + if (action_initiated) + { + if (mAutoTurnOffTimerArmed && new_state == kState_OffInitiated) + { + // If auto turn off timer has been armed and someone initiates turning off, + // cancel the timer and continue as normal. + mAutoTurnOffTimerArmed = false; + + CancelTimer(); + } + + StartTimer(ACTUATOR_MOVEMENT_PERIOS_MS); + + // Since the timer started successfully, update the state and trigger callback + mState = new_state; + + if (mActionInitiated_CB) + { + mActionInitiated_CB(aAction, aActor); + } + } + + return action_initiated; +} + +void LightingManager::StartTimer(uint32_t aTimeoutMs) +{ + if (xTimerIsTimerActive(sLightTimer)) + { + MT793X_LOG("app timer already started!"); + CancelTimer(); + } + + // timer is not active, change its period to required value (== restart). + // FreeRTOS- Block for a maximum of 100 ticks if the change period command + // cannot immediately be sent to the timer command queue. + if (xTimerChangePeriod(sLightTimer, (aTimeoutMs / portTICK_PERIOD_MS), 100) != pdPASS) + { + MT793X_LOG("sLightTimer timer start() failed"); + appError(APP_ERROR_START_TIMER_FAILED); + } +} + +void LightingManager::CancelTimer(void) +{ + if (xTimerStop(sLightTimer, 0) == pdFAIL) + { + MT793X_LOG("sLightTimer stop() failed"); + appError(APP_ERROR_STOP_TIMER_FAILED); + } +} + +void LightingManager::TimerEventHandler(TimerHandle_t xTimer) +{ + // Get light obj context from timer id. + LightingManager * light = static_cast(pvTimerGetTimerID(xTimer)); + + // The timer event handler will be called in the context of the timer task + // once sLightTimer expires. Post an event to apptask queue with the actual handler + // so that the event can be handled in the context of the apptask. + AppEvent event; + event.Type = AppEvent::kEventType_Timer; + event.TimerEvent.Context = light; + if (light->mAutoTurnOffTimerArmed) + { + event.Handler = AutoTurnOffTimerEventHandler; + } + else + { + event.Handler = ActuatorMovementTimerEventHandler; + } + GetAppTask().PostEvent(&event); +} + +void LightingManager::AutoTurnOffTimerEventHandler(AppEvent * aEvent) +{ + LightingManager * light = static_cast(aEvent->TimerEvent.Context); + int32_t actor = 0; + + // Make sure auto turn off timer is still armed. + if (!light->mAutoTurnOffTimerArmed) + { + return; + } + + light->mAutoTurnOffTimerArmed = false; + + MT793X_LOG("Auto Turn Off has been triggered!"); + + light->InitiateAction(actor, OFF_ACTION); +} + +void LightingManager::ActuatorMovementTimerEventHandler(AppEvent * aEvent) +{ + Action_t actionCompleted = INVALID_ACTION; + + LightingManager * light = static_cast(aEvent->TimerEvent.Context); + + if (light->mState == kState_OffInitiated) + { + light->mState = kState_OffCompleted; + actionCompleted = OFF_ACTION; + } + else if (light->mState == kState_OnInitiated) + { + light->mState = kState_OnCompleted; + actionCompleted = ON_ACTION; + } + + if (actionCompleted != INVALID_ACTION) + { + if (light->mActionCompleted_CB) + { + light->mActionCompleted_CB(actionCompleted); + } + + if (light->mAutoTurnOff && actionCompleted == ON_ACTION) + { + // Start the timer for auto turn off + light->StartTimer(light->mAutoTurnOffDuration * 1000); + + light->mAutoTurnOffTimerArmed = true; + + MT793X_LOG("Auto Turn off enabled. Will be triggered in %u seconds", light->mAutoTurnOffDuration); + } + } +} diff --git a/examples/lighting-app/mtk/src/ZclCallbacks.cpp b/examples/lighting-app/mtk/src/ZclCallbacks.cpp new file mode 100644 index 00000000000000..30796a3d9fff23 --- /dev/null +++ b/examples/lighting-app/mtk/src/ZclCallbacks.cpp @@ -0,0 +1,92 @@ +/* + * + * Copyright (c) 2022 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * This file implements the handler for data model messages. + */ + +#include "AppConfig.h" +#include "LightingManager.h" + +#include +#include +#include +#include + +using namespace ::chip; +using namespace ::chip::app::Clusters; + +void MatterPostAttributeChangeCallback(const chip::app::ConcreteAttributePath & attributePath, uint8_t mask, uint8_t type, + uint16_t size, uint8_t * value) +{ + ClusterId clusterId = attributePath.mClusterId; + AttributeId attributeId = attributePath.mAttributeId; + ChipLogProgress(Zcl, "Cluster callback: " ChipLogFormatMEI, ChipLogValueMEI(clusterId)); + + if (clusterId == OnOff::Id && attributeId == OnOff::Attributes::OnOff::Id) + { + LightMgr().InitiateAction(AppEvent::kEventType_Light, *value ? LightingManager::ON_ACTION : LightingManager::OFF_ACTION); + } + else if (clusterId == LevelControl::Id) + { + ChipLogProgress(Zcl, "Level Control attribute ID: " ChipLogFormatMEI " Type: %u Value: %u, length %u", + ChipLogValueMEI(attributeId), type, *value, size); + + // WIP Apply attribute change to Light + } + else if (clusterId == ColorControl::Id) + { + ChipLogProgress(Zcl, "Color Control attribute ID: " ChipLogFormatMEI " Type: %u Value: %u, length %u", + ChipLogValueMEI(attributeId), type, *value, size); + + // WIP Apply attribute change to Light + } + else if (clusterId == OnOffSwitchConfiguration::Id) + { + ChipLogProgress( + Zcl, "OnOff Switch Configuration attribute ID: " ChipLogFormatMEI " Type: %u Value: %u, length %u", + ChipLogValueMEI(attributeId), type, *value, size); + + // WIP Apply attribute change to Light + } + else if (clusterId == Identify::Id) + { + ChipLogProgress(Zcl, "Identify attribute ID: " ChipLogFormatMEI " Type: %u Value: %u, length %u", + ChipLogValueMEI(attributeId), type, *value, size); + } +} + +/** @brief OnOff Cluster Init + * + * This function is called when a specific cluster is initialized. It gives the + * application an opportunity to take care of cluster initialization procedures. + * It is called exactly once for each endpoint where cluster is present. + * + * @param endpoint Ver.: always + * + * TODO Issue #3841 + * emberAfOnOffClusterInitCallback happens before the stack initialize the cluster + * attributes to the default value. + * The logic here expects something similar to the deprecated Plugins callback + * emberAfPluginOnOffClusterServerPostInitCallback. + * + */ +void emberAfOnOffClusterInitCallback(EndpointId endpoint) +{ + // TODO: implement any additional Cluster Server init actions +} diff --git a/examples/lighting-app/mtk/src/main.cpp b/examples/lighting-app/mtk/src/main.cpp new file mode 100644 index 00000000000000..28ae6dc05b9768 --- /dev/null +++ b/examples/lighting-app/mtk/src/main.cpp @@ -0,0 +1,311 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include + +#include "AppConfig.h" +#include + +#ifdef HEAP_MONITORING +#include "MemMonitoring.h" +#endif + +#include + +#ifdef ENABLE_CHIP_SHELL +#include "matter_shell.h" +#endif + +#define WIFI_DEV_NAME "MediaTek-Light" + +using namespace ::chip; +using namespace ::chip::Inet; +using namespace ::chip::DeviceLayer; + +#define UNUSED_PARAMETER(a) (a = a) + +volatile int apperror_cnt; + + +/*************************************************************************** + * Application Error hang + ****************************************************************************/ + + +void appError( int err ) +{ + printf("!!!!!!!!!!!! Application Critical Error: %d !!!!!!!!!!!", err); + portDISABLE_INTERRUPTS(); + while (1) + ; +} + + +void appError( CHIP_ERROR error ) +{ + appError( static_cast( error.AsInteger() ) ); +} + + +/*************************************************************************** + * FORWARD DECLARATIONS + ****************************************************************************/ + + +extern "C" void system_init ( void ); + + +void vStartTask( void * pvParameters ); + + +/*************************************************************************** + * FreeRTOS callback functions + ****************************************************************************/ + + +#if ( configUSE_DAEMON_TASK_STARTUP_HOOK == 1 ) + + extern "C" void vApplicationDaemonTaskStartupHook ( void ) + { + #define START_TASK_STACK_SIZE ( 1000 ) + BaseType_t xReturned; + + xReturned = xTaskCreate( + vStartTask, /* Function that implements the task. */ + "startTask", /* Text name for the task. */ + START_TASK_STACK_SIZE, /* Stack size in words, not bytes. */ + ( void * ) 0, /* Parameter passed into the task. */ + tskIDLE_PRIORITY, /* Priority at which the task is created. */ + NULL ); /* Used to pass out the created task's handle. */ + + configASSERT( xReturned == pdPASS ); + } + +#endif /* configUSE_DAEMON_TASK_STARTUP_HOOK */ + + +#if ( configUSE_IDLE_HOOK == 1 ) + + /* for idle task feed wdt (DO NOT enter sleep mode)*/ + extern "C" void vApplicationIdleHook ( void ) + { + #ifdef MTK_SYSTEM_HANG_CHECK_ENABLE + #ifdef HAL_WDT_MODULE_ENABLED + hal_wdt_feed(HAL_WDT_FEED_MAGIC); + #endif + #endif + } + +#endif /* configUSE_IDLE_HOOK */ + + +#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + + extern "C" void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, + StackType_t **ppxTimerTaskStackBuffer, + uint32_t *pulTimerTaskStackSize ) + { + *pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH; + *ppxTimerTaskTCBBuffer = ( StaticTask_t * ) pvPortMalloc( sizeof( StaticTask_t ) ); + if( *ppxTimerTaskTCBBuffer != NULL ) + { + *ppxTimerTaskStackBuffer = ( StackType_t * ) pvPortMalloc( + ( ( ( size_t ) *pulTimerTaskStackSize ) * sizeof( StackType_t ) ) + ); + } + } + + extern "C" void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, + StackType_t **ppxIdleTaskStackBuffer, + uint32_t *pulIdleTaskStackSize ) + { + *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE; + *ppxIdleTaskTCBBuffer = ( StaticTask_t * ) pvPortMalloc( sizeof( StaticTask_t ) ); + if( *ppxIdleTaskTCBBuffer != NULL ) + { + *ppxIdleTaskStackBuffer = ( StackType_t * ) pvPortMalloc( + ( ( ( size_t ) *pulIdleTaskStackSize ) * sizeof( StackType_t ) ) + ); + } + } + +#endif /* configSUPPORT_STATIC_ALLOCATION */ + + +/******************************************************************************* + * DECLARATIONS + ******************************************************************************/ + + +void mt793xLog(const char * aFormat, ...) +{ + va_list vargs; + + va_start(vargs, aFormat); + vprintf(aFormat, vargs); + va_end(vargs); + printf("\n"); +} + + +void mt793xLogRedirectCallback ( const char * module, + uint8_t category, + const char * msg, + va_list args ) +{ + int len; + char *buf; + + len = strlen(module) + 1 + vsnprintf(NULL, 0, msg, args) + 1; + buf = (char *)malloc(len); + if (buf) { + len = sprintf(buf, "%s ", module); + vsprintf(buf + len, msg, args); + printf("%s\n", buf); + free(buf); + } +} + + +void mt793xSwdPortConfig ( void ) +{ + *(volatile uint32_t *)0x30404358 = 0x00070700; + *(volatile uint32_t *)0x30404354 = 0x00020200; + *(volatile uint32_t *)0x304030e0 = 0x1e8210; + *(volatile uint32_t *)0x304030d4 = 0; +} + + +/*************************************************************************** + * Button Callback + ****************************************************************************/ + + +void vButtonCallback(const filogic_button_t *button_event) +{ + GetAppTask().ButtonHandler(*button_event); +} + + +/*************************************************************************** + * Supplicant Log Redirect + ****************************************************************************/ + + +extern "C" +{ + void mt793x_wpa_log_cb(void *ctx, int level, int type, + const char *txt, size_t len) + { + /* ignore ctx, type, len */ + (void)ctx; + (void)level; + (void)len; + + ChipLogProgress(DeviceLayer, "[%lu] FILOGIC supp %s", xTaskGetTickCount(), txt); + } + + void wpa_msg_register_cb(void *); +} + + +/*************************************************************************** + * Startup task + ****************************************************************************/ + + +void vStartRunning ( void ) +{ + CHIP_ERROR error; + + chip::Logging::SetLogRedirectCallback( mt793xLogRedirectCallback ); + + wpa_msg_register_cb( ( void * )mt793x_wpa_log_cb ); + + assert( chip::Platform::MemoryInit() == CHIP_NO_ERROR ); + + assert( chip::DeviceLayer::PlatformMgr().InitChipStack() == CHIP_NO_ERROR ); + + // Wi-Fi ? + //chip::DeviceLayer::ConnectivityMgr().SetBLEDeviceName(BLE_DEV_NAME); + + assert(chip::DeviceLayer::PlatformMgr().StartEventLoopTask() == CHIP_NO_ERROR); + + assert(GetAppTask().StartAppTask() == CHIP_NO_ERROR); + + assert(filogic_button_set_callback(vButtonCallback)); + + assert(filogic_button_init()); + +#ifdef ENABLE_CHIP_SHELL + chip::startShellTask(); +#endif +} + + +void vStartTask( void * pvParameters ) +{ + ( void )pvParameters; + + vStartRunning(); + + vTaskDelete( NULL ); +} + + +/*************************************************************************** + * Main Function + ****************************************************************************/ + + +extern "C" int main(void) +{ + mbedtls_platform_set_calloc_free( CHIPPlatformMemoryCalloc, + CHIPPlatformMemoryFree ); + +#ifdef HEAP_MONITORING + MemMonitoring::startHeapMonitoring(); +#endif + + system_init(); + + mt793xSwdPortConfig(); + + vTaskStartScheduler(); + + chip::Platform::MemoryShutdown(); + + // Should never get here. + while (1) ; + + return 0; +} diff --git a/examples/lighting-app/mtk/third_party/connectedhomeip b/examples/lighting-app/mtk/third_party/connectedhomeip new file mode 120000 index 00000000000000..c866b86874994d --- /dev/null +++ b/examples/lighting-app/mtk/third_party/connectedhomeip @@ -0,0 +1 @@ +../../../.. \ No newline at end of file diff --git a/examples/lighting-app/mtk/with_pw_rpc.gni b/examples/lighting-app/mtk/with_pw_rpc.gni new file mode 100644 index 00000000000000..581b4f415d5654 --- /dev/null +++ b/examples/lighting-app/mtk/with_pw_rpc.gni @@ -0,0 +1,27 @@ +# Copyright (c) 2021 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# add this gni as import in your build args to use pigweed in the example +# 'import("//with_pw_rpc.gni")' + +import("//build_overrides/chip.gni") +import("${chip_root}/config/mt793x/lib/pw_rpc/pw_rpc.gni") +import("${chip_root}/examples/platform/mt793x/args.gni") + +mt793x_sdk_target = get_label_info(":sdk", "label_no_toolchain") + +chip_enable_pw_rpc = true +chip_enable_openthread = true + +cpp_standard = "gnu++17" diff --git a/examples/platform/mt793x/BUILD.gn b/examples/platform/mt793x/BUILD.gn new file mode 100644 index 00000000000000..5f65a92effc563 --- /dev/null +++ b/examples/platform/mt793x/BUILD.gn @@ -0,0 +1,68 @@ +# Copyright (c) 2020 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/chip.gni") +import("//build_overrides/mt793x_sdk.gni") +import("${chip_root}/src/lib/lib.gni") +import("${mt793x_sdk_build_root}/mt793x_sdk.gni") + +config("chip_examples_project_config") { + include_dirs = [ "project_include" ] + + # Link options that provide a replacement for dynamic memory operations in standard + # library with the FreeRTOS malloc in platform code. + ldflags = [ + # memory allocation -- these must be re-entrant and do locking + "-Wl,--wrap=malloc", + "-Wl,--wrap=free", + "-Wl,--wrap=realloc", + "-Wl,--wrap=calloc", + "-Wl,--wrap=calloc", + "-Wl,--wrap=MemoryAlloc", + "-Wl,--wrap=__assert_function", + "-Wl,--wrap=wlan_printf", + + # Wrap these in case internal newlib call them (e.g. strdup will) + # directly call _malloc_r) + "-Wl,--wrap=_malloc_r", + "-Wl,--wrap=_realloc_r", + "-Wl,--wrap=_free_r", + "-Wl,--wrap=_calloc_r", + "-Wl,--wrap=_write", + ] +} + +source_set("mtk-matter-shell") { + if (chip_build_libshell) { + defines = [ "ENABLE_CHIP_SHELL" ] + + sources = [ + "matter_shell.cpp", + "malloc_wrap.c", + "assert_wrap.c", + "lwip_wrap.c", + "wifi_wrap.c", + "wrap_write.c", + ] + include_dirs = [ "." ] + + public_deps = [ + "${chip_root}/examples/shell/shell_common:shell_common", + "${chip_root}/src/lib/shell:shell", + "${chip_root}/src/lib/shell:shell_core", + ] + } + + public_configs = [ ":chip_examples_project_config" ] +} diff --git a/examples/platform/mt793x/LEDWidget.cpp b/examples/platform/mt793x/LEDWidget.cpp new file mode 100644 index 00000000000000..960995545e6efb --- /dev/null +++ b/examples/platform/mt793x/LEDWidget.cpp @@ -0,0 +1,86 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2019 Google LLC. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "LEDWidget.h" +#include "sl_simple_led_instances.h" + +#include + +using namespace ::chip::System; + +void LEDWidget::InitGpio(void) +{ + // Sets gpio pin mode for ALL board Leds. + sl_simple_led_init_instances(); +} + +void LEDWidget::Init(const sl_led_t * led) +{ + mLastChangeTimeMS = 0; + mBlinkOnTimeMS = 0; + mBlinkOffTimeMS = 0; + mLed = led; + + Set(false); +} + +void LEDWidget::Invert(void) +{ + if (mLed) + { + sl_led_toggle(mLed); + } +} + +void LEDWidget::Set(bool state) +{ + mLastChangeTimeMS = mBlinkOnTimeMS = mBlinkOffTimeMS = 0; + if (mLed) + { + state ? sl_led_turn_on(mLed) : sl_led_turn_off(mLed); + } +} + +void LEDWidget::Blink(uint32_t changeRateMS) +{ + Blink(changeRateMS, changeRateMS); +} + +void LEDWidget::Blink(uint32_t onTimeMS, uint32_t offTimeMS) +{ + mBlinkOnTimeMS = onTimeMS; + mBlinkOffTimeMS = offTimeMS; + Animate(); +} + +void LEDWidget::Animate() +{ + if (mBlinkOnTimeMS != 0 && mBlinkOffTimeMS != 0) + { + uint64_t nowMS = chip::System::SystemClock().GetMonotonicMilliseconds64().count(); + uint64_t stateDurMS = sl_led_get_state(mLed) ? mBlinkOnTimeMS : mBlinkOffTimeMS; + uint64_t nextChangeTimeMS = mLastChangeTimeMS + stateDurMS; + + if (nextChangeTimeMS < nowMS) + { + Invert(); + mLastChangeTimeMS = nowMS; + } + } +} diff --git a/examples/platform/mt793x/LEDWidget.h b/examples/platform/mt793x/LEDWidget.h new file mode 100644 index 00000000000000..d779cb9d3ef4b6 --- /dev/null +++ b/examples/platform/mt793x/LEDWidget.h @@ -0,0 +1,41 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2019 Google LLC. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include "sl_led.h" +#include + +class LEDWidget +{ +public: + static void InitGpio(void); + void Init(const sl_led_t * led); + void Set(bool state); + void Invert(void); + void Blink(uint32_t changeRateMS); + void Blink(uint32_t onTimeMS, uint32_t offTimeMS); + void Animate(); + +private: + uint64_t mLastChangeTimeMS; + uint32_t mBlinkOnTimeMS; + uint32_t mBlinkOffTimeMS; + const sl_led_t * mLed; +}; diff --git a/examples/platform/mt793x/args.gni b/examples/platform/mt793x/args.gni new file mode 100644 index 00000000000000..f10ca637dba00f --- /dev/null +++ b/examples/platform/mt793x/args.gni @@ -0,0 +1,21 @@ +# Copyright (c) 2020 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/chip.gni") + +chip_ble_project_config_include = "" +chip_device_project_config_include = "" +chip_project_config_include = "" +chip_inet_project_config_include = "" +chip_system_project_config_include = "" diff --git a/examples/platform/mt793x/assert_wrap.c b/examples/platform/mt793x/assert_wrap.c new file mode 100644 index 00000000000000..55082e9dce64eb --- /dev/null +++ b/examples/platform/mt793x/assert_wrap.c @@ -0,0 +1,20 @@ + + +#include +#include + + +extern void platform_assert(const char *expr, + const char *file, + int line); + + +void __assert_func (const char * file, + int line, + const char * func, + const char * expr) +{ + fflush(NULL); + platform_assert(expr, file, line); + while (1); +} diff --git a/examples/platform/mt793x/lwip_wrap.c b/examples/platform/mt793x/lwip_wrap.c new file mode 100644 index 00000000000000..071d997cfaf474 --- /dev/null +++ b/examples/platform/mt793x/lwip_wrap.c @@ -0,0 +1,91 @@ + + +#include + +#include + +/****************************************************************************/ + +#include + +#define portCACHELINE_ALIGNMENT HAL_CACHE_LINE_SIZE + +#if 0 +void * pvPortMallocExt(BaseType_t xRegion, size_t xWantedSize) +{ + (void) xRegion; + + return pvPortMalloc(xWantedSize); +} + +void vPortFreeExt(BaseType_t xRegion, void * pv) +{ + (void) xRegion; + + vPortFree(pv); +} + +#include + +static void vPortMallocCacheInvalidate(void * pvAddr, size_t xMemSize) +{ + hal_cache_status_t status; + + status = hal_cache_invalidate_multiple_cache_lines((uint32_t) pvAddr, xMemSize); + if (HAL_CACHE_STATUS_OK != status) + { + configASSERT(0); + } +} + +void * pvPortMallocNCExt(BaseType_t xRegion, size_t xWantedSize) +{ + /* +------+---+--------------+-----+ + * | | | | | + * +------+---+--------------+-----+ + * P0 P1 P2 P3 P4 + * + * P0 = pvRealAddr, returned by pvPortMallocExt() + * P1 = pv + * P2 = pvReturn, aligned to cache line, returned to caller. + * P3 = the end of caller's buffer, if xWantedSize is a multiple of + * the size of a cache line, P3 = P4. + * P4 = the end of real buffer. + * + * [P0, P1) - unused buffer for aligning P2~P3 with cache line. + * [P1, P2) - keeps the address of P0. + * [P2, P3) - caller wanted buffer + * [P3, P4) - unused buffer for cache line alignment + */ + +#define CACHE_ALIGN (16) +#define CACHE_ALIGN_PAD_MASK (CACHE_ALIGN - 1) +#define CACHE_ALIGN_MASK (~CACHE_ALIGN_PAD_MASK) + + const size_t xAddrSize = sizeof(void *); + const size_t xHeadSize = xAddrSize + CACHE_ALIGN - 1; + size_t xTailSize = CACHE_ALIGN - (xWantedSize & CACHE_ALIGN_PAD_MASK); + size_t xRealSize; + void * pvRealAddr; + void * pvReturn; + + xRealSize = xHeadSize + xWantedSize + xTailSize; + + pvRealAddr = pvPortMallocExt(xRegion, xRealSize); + + pvReturn = (void *) (((uint32_t) pvRealAddr + xHeadSize) & CACHE_ALIGN_MASK); + + // keep real addr for free() + *(uint32_t *) (pvReturn - xAddrSize) = (uint32_t) pvRealAddr; + + vPortMallocCacheInvalidate(pvReturn, xWantedSize); + + if (pvReturn != NULL) + { + pvReturn = (char *) HAL_CACHE_VIRTUAL_TO_PHYSICAL((uint32_t) pvReturn); + } + + return (void *) pvReturn; +} +#endif + diff --git a/examples/platform/mt793x/malloc_wrap.c b/examples/platform/mt793x/malloc_wrap.c new file mode 100644 index 00000000000000..1c1e9453895149 --- /dev/null +++ b/examples/platform/mt793x/malloc_wrap.c @@ -0,0 +1,28 @@ + + +#include + +#include +#include + +void *__wrap__malloc_r(void * REENT, size_t size) +{ + void *p = pvPortMalloc(size); + while (!p) ; + return p; +} + + +void __wrap__free_r(void * REENT, void *ptr) +{ + return vPortFree(ptr); +} + + +void *__wrap__realloc_r(void * REENT, void *ptr, size_t size) +{ + void *p = pvPortRealloc(ptr, size); + while (!p) ; + return p; +} + diff --git a/examples/platform/mt793x/matter_shell.cpp b/examples/platform/mt793x/matter_shell.cpp new file mode 100644 index 00000000000000..1b7b35b0c4fd91 --- /dev/null +++ b/examples/platform/mt793x/matter_shell.cpp @@ -0,0 +1,91 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "matter_shell.h" +#include +#include +#include +#include +#include + +using namespace ::chip; +using chip::Shell::Engine; + +namespace { + +#define SHELL_TASK_STACK_SIZE 2048 +#define SHELL_TASK_PRIORITY 5 +TaskHandle_t shellTaskHandle; +StackType_t shellStack[SHELL_TASK_STACK_SIZE / sizeof(StackType_t)]; +StaticTask_t shellTaskStruct; + +void MatterShellTask(void * args) +{ + chip::Shell::Engine::Root().RunMainLoop(); +} + +} // namespace + +extern "C" unsigned int sleep(unsigned int seconds) +{ + const TickType_t xDelay = 1000 * seconds / portTICK_PERIOD_MS; + vTaskDelay(xDelay); + return 0; +} + +namespace chip { + +void NotifyShellProcess() +{ + xTaskNotifyGive(shellTaskHandle); +} + +void NotifyShellProcessFromISR(void) +{ + BaseType_t yieldRequired = pdFALSE; + if (shellTaskHandle != NULL) + { + vTaskNotifyGiveFromISR(shellTaskHandle, &yieldRequired); + } + portYIELD_FROM_ISR(yieldRequired); +} + +void WaitForShellActivity(void) +{ + ulTaskNotifyTake(pdTRUE, portMAX_DELAY); +} + +void startShellTask(void) +{ + int status = chip::Shell::Engine::Root().Init(); + assert(status == 0); + + // For now also register commands from shell_common (shell app). + // TODO move at least OTCLI to default commands in lib/shell/commands + cmd_misc_init(); + cmd_otcli_init(); + + shellTaskHandle = xTaskCreateStatic(MatterShellTask, + "matter_cli", + ArraySize(shellStack), + NULL, + SHELL_TASK_PRIORITY, + shellStack, + &shellTaskStruct); +} + +} // namespace chip diff --git a/examples/platform/mt793x/matter_shell.h b/examples/platform/mt793x/matter_shell.h new file mode 100644 index 00000000000000..fe49bc7f27560d --- /dev/null +++ b/examples/platform/mt793x/matter_shell.h @@ -0,0 +1,27 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +namespace chip { + +void NotifyShellProcess(void); +void NotifyShellProcessFromISR(void); +void WaitForShellActivity(void); +void startShellTask(void); + +} // namespace chip diff --git a/examples/platform/mt793x/wifi_wrap.c b/examples/platform/mt793x/wifi_wrap.c new file mode 100644 index 00000000000000..db1f89710716bb --- /dev/null +++ b/examples/platform/mt793x/wifi_wrap.c @@ -0,0 +1,33 @@ + + +#include + +#include + + +/****************************************************************************/ + + +extern void mt793xLog(const char * aFormat, ...); + + +extern void mt793x_wpa_log_cb(void *ctx, int level, int type, + const char *txt, size_t len); + + +/****************************************************************************/ + + +void __wrap__wlan_printf(int skip, int level, const char *fmt, ...) +{ + va_list ap; + + if (skip) + return; + + va_start(ap, fmt); + + mt793xLog(fmt, ap); + + va_end(ap); +} diff --git a/examples/platform/mt793x/wrap_write.c b/examples/platform/mt793x/wrap_write.c new file mode 100644 index 00000000000000..9ab2736ab9376b --- /dev/null +++ b/examples/platform/mt793x/wrap_write.c @@ -0,0 +1,8 @@ +#include + +extern int log_write(char *buf, int len); + +int __wrap__write(int file, char *ptr, int len) +{ + return log_write(ptr, len); +} diff --git a/examples/shell/mtk/.gn b/examples/shell/mtk/.gn new file mode 100644 index 00000000000000..190e0cf8490f65 --- /dev/null +++ b/examples/shell/mtk/.gn @@ -0,0 +1,29 @@ +# Copyright (c) 2022 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/build.gni") + +# The location of the build configuration file. +buildconfig = "${build_root}/config/BUILDCONFIG.gn" + +# CHIP uses angle bracket includes. +check_system_includes = true + +default_args = { + target_cpu = "arm" + target_os = "freertos" + + import("//args.gni") +} + diff --git a/examples/shell/mtk/BUILD.gn b/examples/shell/mtk/BUILD.gn new file mode 100644 index 00000000000000..79a37a00040887 --- /dev/null +++ b/examples/shell/mtk/BUILD.gn @@ -0,0 +1,87 @@ +# Copyright (c) 2022 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/build.gni") +import("//build_overrides/chip.gni") +import("//build_overrides/mt793x_sdk.gni") + +#import("${chip_root}/build/chip/tools.gni") + +import("${build_root}/config/defaults.gni") +import("${chip_root}/src/platform/device.gni") +import("${mt793x_sdk_build_root}/mt793x_executable.gni") +import("${mt793x_sdk_build_root}/mt793x_sdk.gni") + +assert(current_os == "freertos") + +mt793x_project_dir = "${chip_root}/examples/shell/mtk" +mt793x_ex_plat_dir = "${chip_root}/examples/platform/mt793x" + +declare_args() { + # Dump memory usage at link time. + chip_print_memory_usage = true +} + +mt793x_sdk("sdk") { + sources = [ + "${mt793x_project_dir}/include/CHIPProjectConfig.h", + ] + + include_dirs = [ + "${chip_root}/src/platform/mt793x", + "${mt793x_project_dir}/include", + "${mt793x_ex_plat_dir}", + ] +} + +mt793x_executable("shell_app") { + output_name = "chip-mt793x-shell-example.out" + + sources = [ "src/main.cpp" ] + + deps = [ + ":sdk", + "${chip_root}/examples/shell/shell_common:shell_common", + "${chip_root}/src/lib", + "${chip_root}/src/platform", + "${mt793x_ex_plat_dir}:mtk-matter-shell", + ] + + include_dirs = [ "include" ] + + defines = [] + + ldscript = "mt793x_xip.ld" + + inputs = [ ldscript ] + + ldflags = [ "-T" + rebase_path(ldscript, root_build_dir) ] + + if (chip_print_memory_usage) { + ldflags += [ + "-Wl,--print-memory-usage", + "-fstack-usage", + ] + } + + output_dir = root_out_dir +} + +group("mt793x") { + deps = [ ":shell_app" ] +} + +group("default") { + deps = [ ":mt793x" ] +} diff --git a/examples/shell/mtk/args.gni b/examples/shell/mtk/args.gni new file mode 100644 index 00000000000000..4e835a8e7159d3 --- /dev/null +++ b/examples/shell/mtk/args.gni @@ -0,0 +1,31 @@ +# Copyright (c) 2022 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/chip.gni") +import("//build_overrides/pigweed.gni") +import("${chip_root}/src/platform/mt793x/args.gni") + +mt793x_sdk_target = get_label_info(":sdk", "label_no_toolchain") + +pw_log_BACKEND = "${chip_root}/src/lib/support/pw_log_chip" +pw_assert_BACKEND = "$dir_pw_assert_log" + +chip_enable_ble = false +chip_config_network_layer_ble = false + +chip_enable_openthread = false +chip_openthread_ftd = false +chip_build_libshell = true + + diff --git a/examples/shell/mtk/build_overrides b/examples/shell/mtk/build_overrides new file mode 120000 index 00000000000000..e578e73312ebd1 --- /dev/null +++ b/examples/shell/mtk/build_overrides @@ -0,0 +1 @@ +../../build_overrides \ No newline at end of file diff --git a/examples/shell/mtk/include/CHIPProjectConfig.h b/examples/shell/mtk/include/CHIPProjectConfig.h new file mode 100644 index 00000000000000..81cacab5517dad --- /dev/null +++ b/examples/shell/mtk/include/CHIPProjectConfig.h @@ -0,0 +1,117 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2019 Google LLC. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Example project configuration file for CHIP. + * + * This is a place to put application or project-specific overrides + * to the default configuration values for general CHIP features. + * + */ + +#pragma once + +// Use a default pairing code if one hasn't been provisioned in flash. +#ifndef CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE +#define CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE 20202021 +#endif +#define CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR 0xF00 + +// For convenience, Chip Security Test Mode can be enabled and the +// requirement for authentication in various protocols can be disabled. +// +// WARNING: These options make it possible to circumvent basic Chip security functionality, +// including message encryption. Because of this they MUST NEVER BE ENABLED IN PRODUCTION BUILDS. +// +#define CHIP_CONFIG_SECURITY_TEST_MODE 0 +#define CHIP_CONFIG_REQUIRE_AUTH 1 + +/** + * CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID + * + * 0x235A: Chip's Vendor Id. + */ +#define CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID 0x235A + +/** + * CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID + * + * 0x534C: EFR32 lighting-app + */ +#define CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID 0x534C + +/** + * CHIP_DEVICE_CONFIG_DEVICE_HARDWARE_VERSION + * + * The hardware version number assigned to device or product by the device vendor. This + * number is scoped to the device product id, and typically corresponds to a revision of the + * physical device, a change to its packaging, and/or a change to its marketing presentation. + * This value is generally *not* incremented for device software versions. + */ +#define CHIP_DEVICE_CONFIG_DEVICE_HARDWARE_VERSION 1 + +/** + * CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING + * + * A string identifying the software version running on the device. + * CHIP service currently expects the software version to be in the format + * {MAJOR_VERSION}.0d{MINOR_VERSION} + */ +#ifndef CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING +#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING "0.1ALPHA" +#endif +/** + * CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE + * + * Enable support for Chip-over-BLE (CHIPoBLE). + */ +#define CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE 0 + +/** + * CHIP_DEVICE_CONFIG_ENABLE_CHIP_TIME_SERVICE_TIME_SYNC + * + * Enables synchronizing the device's real time clock with a remote Chip Time service + * using the Chip Time Sync protocol. + */ +#define CHIP_DEVICE_CONFIG_ENABLE_CHIP_TIME_SERVICE_TIME_SYNC 0 + +/** + * CHIP_DEVICE_CONFIG_TEST_SERIAL_NUMBER + * + * Enables the use of a hard-coded default serial number if none + * is found in Chip NV storage. + */ +#define CHIP_DEVICE_CONFIG_TEST_SERIAL_NUMBER "TEST_SN" + +/** + * CHIP_CONFIG_EVENT_LOGGING_UTC_TIMESTAMPS + * + * Enable recording UTC timestamps. + */ +#define CHIP_CONFIG_EVENT_LOGGING_UTC_TIMESTAMPS 1 + +/** + * CHIP_DEVICE_CONFIG_EVENT_LOGGING_DEBUG_BUFFER_SIZE + * + * A size, in bytes, of the individual debug event logging buffer. + */ +#define CHIP_DEVICE_CONFIG_EVENT_LOGGING_DEBUG_BUFFER_SIZE (512) + +#define _NO_NETWORK_COMMISSIONING_DRIVER_ diff --git a/examples/shell/mtk/mt793x_xip.ld b/examples/shell/mtk/mt793x_xip.ld new file mode 100644 index 00000000000000..fc3304bbec627b --- /dev/null +++ b/examples/shell/mtk/mt793x_xip.ld @@ -0,0 +1,385 @@ +/* + * MT7933 CM33 Memory Map + */ + +HIDDEN(__STACK_SIZE = 0x1000); +HIDDEN(__SYSRAM_OFFSET = 0x0); + +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Memory Spaces Definitions: 16MB flash */ +MEMORY +{ + ROM_BL(rx) : ORIGIN = 0x18000000, LENGTH = 64K + ROM_RBL(rx) : ORIGIN = 0x18010000, LENGTH = 8K + ROM_TFM(rx) : ORIGIN = 0x18012000, LENGTH = 200K + ROM_RTOS(rx) : ORIGIN = 0x18044000, LENGTH = 2092K + /* + Reserved : LENGTH = 228 K, 152 K For TFM + Free For Customer : LENGTH = 500 K + */ + ROM_FOTA(r) : ORIGIN = 0x18305000, LENGTH = 3968K + ROM_NVDM(rx) : ORIGIN = 0x186E5000, LENGTH = 64K + ROM_LOG(rx) : ORIGIN = 0x186F5000, LENGTH = 64K + ROM_BT(rx) : ORIGIN = 0x18705000, LENGTH = 304K + /* + Reserved For FW : LENGTH = 40 K + */ + ROM_WIFI_PWRTBL(rx): ORIGIN = 0x1875B000, LENGTH = 20K + ROM_WIFI_EXT(rx) : ORIGIN = 0x18760000, LENGTH = 636K + ROM_BUFFER_BIN(rx): ORIGIN = 0x187FF000, LENGTH = 4K + + TCM(rwx) : ORIGIN = 0x0010C000, LENGTH = 20K + RAM_WFFW(rwx) : ORIGIN = 0xA0000000, LENGTH = 312K + RAM(rwx) : ORIGIN = 0xA004E000, LENGTH = 3272K + RAM_TFM(rwx) : ORIGIN = 0xA0380000, LENGTH = 512K + SYSRAM(rwx) : ORIGIN = 0x80000000, LENGTH = 992K + /* + Reserved : LENGTH = 32K + */ + + VROM(rx) : ORIGIN = 0x18000000, LENGTH = 4096K + VRAM_WFFW(rwx) : ORIGIN = 0x10000000, LENGTH = 312K + VRAM(rwx) : ORIGIN = 0x1004E000, LENGTH = 3272K + VRAM_TFM(rwx) : ORIGIN = 0x10380000, LENGTH = 512K + VSYSRAM(rwx) : ORIGIN = 0x08000000, LENGTH = 992K + /* + Reserved : LENGTH = 32K + */ +} + +/**************************************************************************** + * + * FORWARD DECLARATIONS - SECTION SYMBOLS @ FLASH PHYSICAL ADDRESS + * + ****************************************************************************/ + + +_rom_bl_start = ORIGIN(ROM_BL) - ORIGIN(ROM_BL); +_rom_bl_length = LENGTH(ROM_BL); +_rom_rbl_start = ORIGIN(ROM_RBL) - ORIGIN(ROM_BL); +_rom_rbl_length = LENGTH(ROM_RBL); +_rom_tfm_start = ORIGIN(ROM_TFM) - ORIGIN(ROM_BL); +_rom_tfm_length = LENGTH(ROM_TFM); +_rom_rtos_start = ORIGIN(ROM_RTOS) - ORIGIN(ROM_BL); +_rom_rtos_length = LENGTH(ROM_RTOS); +_rom_fota_start = ORIGIN(ROM_FOTA) - ORIGIN(ROM_BL); +_rom_fota_length = LENGTH(ROM_FOTA); +_rom_wifi_patch_start = 0;/*ORIGIN(ROM_WIFI_PATCH) - ORIGIN(ROM_BL);*/ +_rom_wifi_patch_length = 0;/*LENGTH(ROM_WIFI_PATCH);*/ +_rom_wifi_start = 0;/*ORIGIN(ROM_WIFI) - ORIGIN(ROM_BL);*/ +_rom_wifi_length = 0;/*LENGTH(ROM_WIFI);*/ +_rom_wifi_ext_start = ORIGIN(ROM_WIFI_EXT) - ORIGIN(ROM_BL); +_rom_wifi_ext_length = LENGTH(ROM_WIFI_EXT); +_rom_wifi_pwrtbl_start = ORIGIN(ROM_WIFI_PWRTBL) - ORIGIN(ROM_BL); +_rom_wifi_pwrtbl_length = LENGTH(ROM_WIFI_PWRTBL); +_rom_buffer_bin_start = ORIGIN(ROM_BUFFER_BIN) - ORIGIN(ROM_BL); +_rom_buffer_bin_length = LENGTH(ROM_BUFFER_BIN); +_rom_bt_start = ORIGIN(ROM_BT) - ORIGIN(ROM_BL); +_rom_bt_length = LENGTH(ROM_BT); +_rom_nvdm_start = ORIGIN(ROM_NVDM) - ORIGIN(ROM_BL); +_rom_nvdm_length = LENGTH(ROM_NVDM); +_rom_log_start = ORIGIN(ROM_LOG) - ORIGIN(ROM_BL); +_rom_log_length = LENGTH(ROM_LOG); + + +/**************************************************************************** + * + * FORWARD DECLARATIONS - SECTION SYMBOLS @ MEMORY BUS ADDRESS + * + ****************************************************************************/ + +_xip_bl_addr = ORIGIN(ROM_BL); +_xip_rbl_addr = ORIGIN(ROM_RBL); +_xip_tfm_addr = ORIGIN(ROM_TFM); +_xip_rtos_addr = ORIGIN(ROM_RTOS); +_xip_nvdm_start = ORIGIN(ROM_NVDM); +_xip_log_start = ORIGIN(ROM_LOG); +_xip_bt_start = ORIGIN(ROM_BT); + +_sysram_start = ORIGIN(SYSRAM); +_sysram_length = LENGTH(SYSRAM); +_ram_start = ORIGIN(RAM); +_ram_length = LENGTH(RAM); +_ram_wifi_ext_start = ORIGIN(RAM_WFFW); +_ram_wifi_ext_length = LENGTH(RAM_WFFW); +_vram_start = ORIGIN(VRAM); +_vram_length = LENGTH(VRAM); +_vsysram_start = ORIGIN(VSYSRAM); +_vsysram_length = LENGTH(VSYSRAM); +_tcm_start = ORIGIN(TCM); +_tcm_length = LENGTH(TCM); + + /* Highest address of the stack */ +_stack_end = ORIGIN(TCM) + LENGTH(TCM); /* end of TCM */ + +/* stack start */ +_stack_start = _stack_end - __STACK_SIZE; + +/* SYSRAM Region0 Offset for BROM */ +_region0_offset = 0x13000 ; + +SECTIONS +{ + . = ORIGIN(ROM_RTOS); + .text ALIGN(4): + { + _text_start = .; + KEEP(*(.vectorsTop)) + KEEP(*(.vectors)) + /* *(.text*) */ + *(EXCLUDE_FILE(*/iperf_task.o *sockets*.o *netbuf*.o *pbuf*.o */mem.o *api_lib*.o */def.o *api_msg*.o *sys_arch*.o *ip4*.o *ip4_addr*.o *udp*.o *inet_chksum*.o *tcp_out*.o *tcp*.o */netif.o */ethernet.o *etharp*.o */lwip_cli.o *portasm*.o *event_groups*.o */heap_ext.o */queue.o */tasks.o *list*.o *os_port_callback*.o */port.o *timers*.o *hal_nvic*.o *libc_nano*.a:*memset*.o *libc_nano*.a:*memcpy*.o *libminisupp.a:*mem*.o) .text*) + KEEP(*(.init)) + KEEP(*(.fini)) + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + *(.rodata*) + *(.rom_rtos) + KEEP(*(.eh_frame*)) + . = ALIGN(4); + _text_end = .; + } > ROM_RTOS AT> ROM_RTOS + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > ROM_RTOS AT> ROM_RTOS + + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > ROM_RTOS AT> ROM_RTOS + __exidx_end = .; + + . = ALIGN(32); + _sysram_code_load = LOADADDR(.sysram_text); + .sysram_text ORIGIN(VSYSRAM)+_region0_offset : + { + _sysram_code_start = .; + *(.sysram_code) + *(.text*) + *(.sysram_rodata) + . = ALIGN(4); + _sysram_code_end = .; + } > VSYSRAM AT> ROM_RTOS + + . = ALIGN(4); + _sysram_data_load = LOADADDR(.cached_sysram_data); + .cached_sysram_data : + { + _sysram_data_start = .; + *(vtable) + *(.data) + *(.data.*) + *(.sysram_rwdata) + . = ALIGN(4); + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + + . = ALIGN(4); + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + + . = ALIGN(4); + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + KEEP(*(.jcr*)) + . = ALIGN(4); + _sysram_data_end = .; + } > VSYSRAM AT> ROM_RTOS + + . = ALIGN(4); + .bss (NOLOAD) : + { + _sysram_bss_start = .; + *(.bss) + *(.bss.*) + *(COMMON) + *(.sysram_zidata) + *(.sysram_swla_zidata) + . = ALIGN(4); + _sysram_bss_end = .; + } > VSYSRAM AT> ROM_RTOS + + + . = ALIGN(32); + _noncached_sysram_code_load = LOADADDR(.noncached_sysram_text); + . = . + ORIGIN(SYSRAM) - ORIGIN(VSYSRAM); + .noncached_sysram_text . : + { + _noncached_sysram_code_start = .; + *(.noncached_sysram_code) + *(.noncached_sysram_rodata) + . = ALIGN(4); + _noncached_sysram_code_end = .; + } > SYSRAM AT> ROM_RTOS + + . = ALIGN(4); + _noncached_sysram_data_load = LOADADDR(.noncached_sysram_data); + .noncached_sysram_data . : + { + _noncached_sysram_data_start = .; + *(.noncached_sysram_rwdata) + *(.secure_settings_section) + . = ALIGN(4); + _noncached_sysram_data_end = .; + } > SYSRAM AT> ROM_RTOS + + . = ALIGN(4); + .noncached_sysram_bss . (NOLOAD) : + { + _noncached_sysram_bss_start = .; + *(.noncached_sysram_zidata) + . = ALIGN(4); + _noncached_sysram_bss_end = .; + } > SYSRAM AT> ROM_RTOS + + . = ALIGN(32); + .wffw_code (NOLOAD) : + { + *(.wf_firmware_emi_code) + . = ALIGN(4); + } > RAM_WFFW AT> ROM_RTOS + + . = ALIGN(32); + _ram_code_load = LOADADDR(.cached_ram_text); + .cached_ram_text : + { + _ram_code_start = .; + *(.ram_code) + *(.ram_rodata) + . = ALIGN(4); + _ram_code_end = .; + } > VRAM AT> ROM_RTOS + + . = ALIGN(4); + _ram_data_load = LOADADDR(.cached_ram_data); + .cached_ram_data : + { + _ram_data_start = .; + *(.ram_rwdata) + . = ALIGN(4); + _ram_data_end = .; + } > VRAM AT> ROM_RTOS + + . = ALIGN(4); + _ram_bss_load = LOADADDR(.cached_ram_bss); + .cached_ram_bss (NOLOAD) : + { + _ram_bss_start = .; + *(.ram_zidata) + . = ALIGN(4); + _ram_bss_end = .; + } > VRAM AT> ROM_RTOS + + . = ALIGN(32); + _noncached_ram_code_load = LOADADDR(.noncached_ram_text); + . = . + ORIGIN(RAM) - ORIGIN(VRAM); + .noncached_ram_text . : + { + _noncached_ram_code_start = .; + *(.noncached_ram_code) + *(.noncached_ram_rodata) + . = ALIGN(4); + _noncached_ram_code_end = .; + } > RAM AT> ROM_RTOS + + . = ALIGN(4); + _noncached_ram_data_load = LOADADDR(.noncached_ram_data); + .noncached_ram_data . : + { + _noncached_ram_data_start = .; + *(.noncached_ram_rwdata) + . = ALIGN(4); + _noncached_ram_data_end = .; + } > RAM AT> ROM_RTOS + + . = ALIGN(4); + _noncached_ram_bss_load = LOADADDR(.noncached_ram_bss); + .noncached_ram_bss . (NOLOAD) : + { + _noncached_ram_bss_start = .; + *(.noncached_ram_zidata) + . = ALIGN(4); + _noncached_ram_bss_end = .; + } > RAM AT> ROM_RTOS + + + . = ALIGN(4); + _tcm_code_load = LOADADDR(.tcm_text); + .tcm_text : + { + _tcm_code_start = .; + *(.tcm_code) + *(.tcm_rodata) + . = ALIGN(4); + _tcm_code_end = .; + }> TCM AT> ROM_RTOS + + . = ALIGN(4); + _tcm_data_load = LOADADDR(.tcm_data); + .tcm_data : + { + _tcm_data_start = .; + . = ALIGN(4); + *(.tcm_rwdata) + . = ALIGN(4); + _tcm_data_end = .; + }> TCM AT> ROM_RTOS + + . = ALIGN(4); + .tcm_bss (NOLOAD) : + { + _tcm_bss_start = .; + *(.tcm_zidata) + . = ALIGN(4); + *(.tcm_wakeup_info) + . = ALIGN(4); + _tcm_bss_end = .; + }> TCM AT> ROM_RTOS + + + __end__ = .; + + .mcuboot_tlv_rsvd (NOLOAD) : + { + /* reserve 512 bytes for imgtool.py TLVs */ + . = . + 512 ; + } > ROM_RTOS AT> ROM_RTOS + + .stack (ORIGIN(TCM) + LENGTH(TCM) - __STACK_SIZE) (COPY) : + { + . = ALIGN(4); + __StackLimit = .; + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + __STACK_SIZE; + . = ALIGN(4); + __StackTop = .; + } > TCM + + PROVIDE(__stack = __StackTop); + + ASSERT(__StackLimit >= __end__, "region TCM overflowed with stack") +} + + + diff --git a/examples/shell/mtk/src/main.cpp b/examples/shell/mtk/src/main.cpp new file mode 100644 index 00000000000000..fa9918875f5799 --- /dev/null +++ b/examples/shell/mtk/src/main.cpp @@ -0,0 +1,206 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include +//#include + +#include + +#include + +#include + +#include "matter_shell.h" + +using chip::Shell::Engine; + + +/*************************************************************************** + * FORWARD DECLARATIONS + ****************************************************************************/ + + +extern "C" void system_init ( void ); + + +void vStartTask ( void * pvParameters ); + + +/*************************************************************************** + * FreeRTOS callback functions + ****************************************************************************/ + + +#if ( configUSE_DAEMON_TASK_STARTUP_HOOK == 1 ) + + extern "C" void vApplicationDaemonTaskStartupHook ( void ) + { + #define START_TASK_STACK_SIZE ( 1000 ) + BaseType_t xReturned; + + xReturned = xTaskCreate( + vStartTask, /* Function that implements the task. */ + "startTask", /* Text name for the task. */ + START_TASK_STACK_SIZE, /* Stack size in words, not bytes. */ + ( void * ) 0, /* Parameter passed into the task. */ + tskIDLE_PRIORITY, /* Priority at which the task is created. */ + NULL ); /* Used to pass out the created task's handle. */ + + //configASSERT( xReturned == pdPASS ); + } + +#endif /* configUSE_DAEMON_TASK_STARTUP_HOOK */ + + +#if ( configUSE_IDLE_HOOK == 1 ) + + /* for idle task feed wdt (DO NOT enter sleep mode)*/ + extern "C" void vApplicationIdleHook ( void ) + { + #ifdef MTK_SYSTEM_HANG_CHECK_ENABLE + #ifdef HAL_WDT_MODULE_ENABLED + hal_wdt_feed(HAL_WDT_FEED_MAGIC); + #endif + #endif + } + +#endif /* configUSE_IDLE_HOOK */ + + +#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) + + extern "C" void vApplicationGetTimerTaskMemory( StaticTask_t **ppxTimerTaskTCBBuffer, + StackType_t **ppxTimerTaskStackBuffer, + uint32_t *pulTimerTaskStackSize ) + { + *pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH; + *ppxTimerTaskTCBBuffer = ( StaticTask_t * ) pvPortMalloc( sizeof( StaticTask_t ) ); + if( *ppxTimerTaskTCBBuffer != NULL ) + { + *ppxTimerTaskStackBuffer = ( StackType_t * ) pvPortMalloc( + ( ( ( size_t ) *pulTimerTaskStackSize ) * sizeof( StackType_t ) ) + ); + } + } + + extern "C" void vApplicationGetIdleTaskMemory( StaticTask_t **ppxIdleTaskTCBBuffer, + StackType_t **ppxIdleTaskStackBuffer, + uint32_t *pulIdleTaskStackSize ) + { + *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE; + *ppxIdleTaskTCBBuffer = ( StaticTask_t * ) pvPortMalloc( sizeof( StaticTask_t ) ); + if( *ppxIdleTaskTCBBuffer != NULL ) + { + *ppxIdleTaskStackBuffer = ( StackType_t * ) pvPortMalloc( + ( ( ( size_t ) *pulIdleTaskStackSize ) * sizeof( StackType_t ) ) + ); + } + } + +#endif /* configSUPPORT_STATIC_ALLOCATION */ + + +/******************************************************************************* + * DECLARATIONS + ******************************************************************************/ + + +void mt793xLogRedirectCallback ( const char * module, + uint8_t category, + const char * msg, + va_list args ) +{ + int len; + char *buf; + + len = strlen(module) + 1 + vsnprintf(NULL, 0, msg, args) + 1; + buf = (char *)malloc(len); + if (buf) { + len = sprintf(buf, "%s ", module); + vsprintf(buf + len, msg, args); + printf("%s\n", buf); + free(buf); + } +} + + +void mt793xSwdPortConfig ( void ) +{ + *(volatile uint32_t *)0x30404358 = 0x00070700; + *(volatile uint32_t *)0x30404354 = 0x00020200; + *(volatile uint32_t *)0x304030e0 = 0x1e8210; + *(volatile uint32_t *)0x304030d4 = 0; +} + + +/*************************************************************************** + * Startup task + ****************************************************************************/ + + +void vStartRunning ( void ) +{ + chip::Logging::SetLogRedirectCallback( mt793xLogRedirectCallback ); + + assert( chip::Platform::MemoryInit() == CHIP_NO_ERROR ); + + assert(chip::DeviceLayer::PlatformMgr().InitChipStack() == CHIP_NO_ERROR); + + assert(chip::DeviceLayer::PlatformMgr().StartEventLoopTask() == CHIP_NO_ERROR); + + chip::startShellTask(); +} + + +void vStartTask ( void * pvParameters ) +{ + ( void ) pvParameters; + + vStartRunning(); + + vTaskDelete( NULL ); +} + + +/*************************************************************************** + * Main Function + ****************************************************************************/ + + +extern "C" int main ( void ) +{ + mbedtls_platform_set_calloc_free( CHIPPlatformMemoryCalloc, + CHIPPlatformMemoryFree ); + +#ifdef HEAP_MONITORING + MemMonitoring::startHeapMonitoring(); +#endif + + system_init(); + + mt793xSwdPortConfig(); + + vTaskStartScheduler(); + + for (;;); + + return -1; +} diff --git a/examples/shell/mtk/third_party/connectedhomeip b/examples/shell/mtk/third_party/connectedhomeip new file mode 120000 index 00000000000000..c866b86874994d --- /dev/null +++ b/examples/shell/mtk/third_party/connectedhomeip @@ -0,0 +1 @@ +../../../.. \ No newline at end of file diff --git a/scripts/checkout_submodules.py b/scripts/checkout_submodules.py index c98f54c249e418..04f8d2e553b87d 100755 --- a/scripts/checkout_submodules.py +++ b/scripts/checkout_submodules.py @@ -43,6 +43,7 @@ 'tizen', 'webos', 'mw320', + 'genio', ]) Module = namedtuple('Module', 'name path platforms') diff --git a/src/lib/shell/BUILD.gn b/src/lib/shell/BUILD.gn index 9c003607b03116..fd1bd75d0cc046 100644 --- a/src/lib/shell/BUILD.gn +++ b/src/lib/shell/BUILD.gn @@ -63,6 +63,11 @@ static_library("shell") { "MainLoopCYW30739.cpp", "streamer_cyw30739.cpp", ] + } else if (chip_device_platform == "mt793x") { + sources += [ + "MainLoopDefault.cpp", + "streamer_mt793x.cpp", + ] } else if (current_os == "zephyr") { sources += [ "MainLoopZephyr.cpp", diff --git a/src/lib/shell/streamer_mt793x.cpp b/src/lib/shell/streamer_mt793x.cpp new file mode 100644 index 00000000000000..3f7f08dadef9c5 --- /dev/null +++ b/src/lib/shell/streamer_mt793x.cpp @@ -0,0 +1,74 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Source implementation of an input / output stream for zehpyr targets. + */ + +#include +#include + +#include + +#include +#include + +namespace chip { +namespace Shell { +namespace { + +int streamer_mt793x_init(streamer_t * streamer) +{ + (void) streamer; + //bsp_io_def_uart_init(); + return 0; +} + +ssize_t streamer_mt793x_read(streamer_t * streamer, char * buffer, size_t length) +{ + int i = 0; + (void) streamer; + + while (i < length) + buffer[i++] = (char)bsp_io_def_uart_getchar(); + return length; +} + +ssize_t streamer_mt793x_write(streamer_t * streamer, const char * buffer, size_t length) +{ + int i = 0; + (void) streamer; + while (i < length) + bsp_io_def_uart_putchar(buffer[i++]); + return length; +} + +static streamer_t streamer_mt793x = { + .init_cb = streamer_mt793x_init, + .read_cb = streamer_mt793x_read, + .write_cb = streamer_mt793x_write, +}; +} // namespace + +streamer_t * streamer_get(void) +{ + return &streamer_mt793x; +} + +} // namespace Shell +} // namespace chip diff --git a/src/lwip/BUILD.gn b/src/lwip/BUILD.gn index 830e82b3cb0e75..169b211a1bbae9 100644 --- a/src/lwip/BUILD.gn +++ b/src/lwip/BUILD.gn @@ -33,7 +33,8 @@ assert(lwip_platform == "external" || lwip_platform == "standalone" || lwip_platform == "efr32" || lwip_platform == "k32w0" || lwip_platform == "qpg" || lwip_platform == "mbed" || lwip_platform == "psoc6" || lwip_platform == "cyw30739" || - lwip_platform == "bl602" || lwip_platform == "mw320", + lwip_platform == "bl602" || lwip_platform == "mw320" || + lwip_platform == "mt793x", "Unsupported lwIP platform: ${lwip_platform}") if (lwip_platform != "external") { @@ -62,6 +63,8 @@ if (lwip_platform == "cc13x2_26x2") { import("//build_overrides/bl602_sdk.gni") } else if (lwip_platform == "mw320") { import("//build_overrides/mw320_sdk.gni") +} else if (lwip_platform == "mt793x") { + import("//build_overrides/mt793x_sdk.gni") } buildconfig_header("lwip_buildconfig") { @@ -158,6 +161,7 @@ if (current_os == "zephyr" || current_os == "mbed") { public += [ "standalone/arch/sys_arch.h" ] sources += [ "standalone/sys_arch.c" ] } else if (lwip_platform == "cyw30739") { + } else if (lwip_platform == "mt793x") { } else { public += [ "${lwip_platform}/lwippools.h", @@ -183,6 +187,8 @@ if (current_os == "zephyr" || current_os == "mbed") { public_deps += [ "${cyw30739_sdk_build_root}:cyw30739_sdk" ] } else if (lwip_platform == "bl602") { public_deps += [ "${bl602_sdk_build_root}:bl602_sdk" ] + } else if (lwip_platform == "mt793x") { + public_deps += [ "${mt793x_sdk_build_root}:mt793x_sdk" ] } public_configs = [ diff --git a/src/platform/BUILD.gn b/src/platform/BUILD.gn index e5758593538fde..d21295885e70fc 100644 --- a/src/platform/BUILD.gn +++ b/src/platform/BUILD.gn @@ -266,6 +266,11 @@ if (chip_device_platform != "none" && chip_device_platform != "external") { defines += [ "CHIP_DEVICE_LAYER_TARGET_BEKEN=1", "CHIP_DEVICE_LAYER_TARGET=Beken", + ] + } else if (chip_device_platform == "mt793x") { + defines += [ + "CHIP_DEVICE_LAYER_TARGET_MT793X=1", + "CHIP_DEVICE_LAYER_TARGET=mt793x", "CHIP_DEVICE_CONFIG_ENABLE_WIFI=${chip_enable_wifi}", ] } @@ -437,14 +442,18 @@ if (chip_device_platform != "none") { _platform_target = "nxp/mw320" } else if (chip_device_platform == "zephyr") { _platform_target = "Zephyr" +<<<<<<< HEAD } else if (chip_device_platform == "beken") { _platform_target = "Beken" +======= + } else if (chip_device_platform == "mt793x") { + _platform_target = "mt793x" +>>>>>>> 29e6c2b... [filogic] mt793x support } else { assert(false, "Unknown chip_device_platform: ${chip_device_platform}") } public_deps += [ _platform_target ] - # The platform target needs to include the headers, so allow that here. # It should be considered logically part of this target. allow_circular_includes_from = [ diff --git a/src/platform/device.gni b/src/platform/device.gni index 87330499cbca6e..84286e346bfc3c 100755 --- a/src/platform/device.gni +++ b/src/platform/device.gni @@ -65,6 +65,7 @@ declare_args() { chip_device_platform == "webos" || chip_device_platform == "cc32xx" || chip_device_platform == "bl602" || chip_device_platform == "bl602" || chip_device_platform == "mw320" || chip_device_platform == "beken" || + chip_device_platform == "mt793x" || (chip_device_platform == "darwin" && current_os == "mac") # Enable ble support. @@ -85,7 +86,8 @@ declare_args() { chip_device_platform == "mbed" || chip_device_platform == "psoc6" || chip_device_platform == "ameba" || chip_device_platform == "webos" || chip_device_platform == "cc32xx" || chip_device_platform == "bl602" || - chip_device_platform == "mw320" || chip_device_platform == "beken") { + chip_device_platform == "mw320" || chip_device_platform == "beken" || + chip_device_platform == "mt793x") { chip_mdns = "minimal" } else if (chip_device_platform == "darwin" || chip_device_platform == "cc13x2_26x2" || current_os == "android" || @@ -140,6 +142,8 @@ if (chip_device_platform == "cc13x2_26x2") { _chip_device_layer = "Zephyr" } else if (chip_device_platform == "beken") { _chip_device_layer = "Beken" +} else if (chip_device_platform == "mt793x") { + _chip_device_layer = "mt793x" } if (chip_device_platform != "external") { @@ -200,5 +204,5 @@ assert( chip_device_platform == "ameba" || chip_device_platform == "cyw30739" || chip_device_platform == "webos" || chip_device_platform == "bl602" || chip_device_platform == "mw320" || chip_device_platform == "zephyr" || - chip_device_platform == "beken", + chip_device_platform == "beken" || chip_device_platform == "mt793x", "Please select a valid value for chip_device_platform") diff --git a/src/platform/mt793x/BLEGattProfile.c b/src/platform/mt793x/BLEGattProfile.c new file mode 100755 index 00000000000000..7909b906e3ae2a --- /dev/null +++ b/src/platform/mt793x/BLEGattProfile.c @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2020-2021 Project CHIP Authors + * Copyright (c) 2019 Nest Labs, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Provides an implementation of the BLEManager singleton object + * for the MediaTek Genio platforms. + */ + +#include "bt_gap_le.h" +#include "bt_gatts.h" +#include "bt_uuid.h" +#include "BLEManagerImpl.h" + +#define CHIPOBLEPROFILE_SERVICE_UUID_16 (0xFFF6) +#define CHIPOBLEPROFILE_CHAR_UUID_RX { 0x11, 0x9D, 0x9F, 0x42, 0x9C, 0x4F, 0x9F, 0x95, 0x59, 0x45, 0x3D, 0x26, 0xF5, 0x2E, 0xEE, 0x18 } +#define CHIPOBLEPROFILE_CHAR_UUID_TX { 0x12, 0x9D, 0x9F, 0x42, 0x9C, 0x4F, 0x9F, 0x95, 0x59, 0x45, 0x3D, 0x26, 0xF5, 0x2E, 0xEE, 0x18 } + +const bt_uuid_t CHIPOBLEPROFILE_CHAR_SERVER_TX_UUID128 = { CHIPOBLEPROFILE_CHAR_UUID_TX }; +const bt_uuid_t CHIPOBLEPROFILE_CHAR_SERVER_RX_UUID128 = { CHIPOBLEPROFILE_CHAR_UUID_RX }; + +CHIPoBLECharCallback CHIPoBLEProfile_read_callback = NULL; +CHIPoBLECharCallback CHIPoBLEProfile_write_callback = NULL; +CHIPoBLECharCallback CHIPoBLEProfile_ccc_callback = NULL; + +uint32_t ble_tx_charc_value_callback(const uint8_t rw, uint16_t handle, void *data, uint16_t size, uint16_t offset) +{ + printf("ble_tx_charc_value_callback: %d %d %p %d %d\n", rw, handle, data, size, offset); + if (CHIPoBLEProfile_read_callback) { + CHIPoBLEProfile_read_callback(handle, data, size); + } + + return size; +} + + +uint32_t ble_rx_charc_callback(const uint8_t rw, uint16_t handle, void *data, uint16_t size, uint16_t offset) +{ + printf("ble_rx_charc_callback: %d %d %p %d %d\n", rw, handle, data, size, offset); + if (CHIPoBLEProfile_write_callback) { + CHIPoBLEProfile_write_callback(handle, data, size); + } + + return size; +} + +uint32_t ble_tx_ccc_callback(const uint8_t rw, uint16_t handle, void *data, uint16_t size, uint16_t offset) +{ + printf("ble_tx_ccc_callback: %d %d %p %d %d\n", rw, handle, data, size, offset); + if (CHIPoBLEProfile_ccc_callback) { + CHIPoBLEProfile_ccc_callback(handle, data, size); + } + + return size; +} + +BT_GATTS_NEW_PRIMARY_SERVICE_16(chipOBle_primary_service, CHIPOBLEPROFILE_SERVICE_UUID_16); + +BT_GATTS_NEW_CHARC_128(chipOBle_profile_rx_char, BT_GATT_CHARC_PROP_WRITE , 0x0016, CHIPOBLEPROFILE_CHAR_UUID_RX); +BT_GATTS_NEW_CHARC_VALUE_CALLBACK(chipOBle_profile_rx_value, CHIPOBLEPROFILE_CHAR_SERVER_RX_UUID128, + BT_GATTS_REC_PERM_READABLE | BT_GATTS_REC_PERM_WRITABLE, ble_rx_charc_callback); + +BT_GATTS_NEW_CHARC_128(chipOBle_profile_tx_char, + BT_GATT_CHARC_PROP_READ | BT_GATT_CHARC_PROP_INDICATE, 0x0018, CHIPOBLEPROFILE_CHAR_UUID_TX); + +BT_GATTS_NEW_CHARC_VALUE_CALLBACK(chipOBle_profile_tx_value, CHIPOBLEPROFILE_CHAR_SERVER_TX_UUID128, + BT_GATTS_REC_PERM_READABLE | BT_GATTS_REC_PERM_WRITABLE, ble_tx_charc_value_callback); + +BT_GATTS_NEW_CLIENT_CHARC_CONFIG(chipOBle_profile_tx_config, + BT_GATTS_REC_PERM_READABLE | BT_GATTS_REC_PERM_WRITABLE, + ble_tx_ccc_callback); + +static const bt_gatts_service_rec_t *chipOBle_service_rec[] = { + (const bt_gatts_service_rec_t *) &chipOBle_primary_service, + (const bt_gatts_service_rec_t *) &chipOBle_profile_rx_char, + (const bt_gatts_service_rec_t *) &chipOBle_profile_rx_value, + (const bt_gatts_service_rec_t *) &chipOBle_profile_tx_char, + (const bt_gatts_service_rec_t *) &chipOBle_profile_tx_value, + (const bt_gatts_service_rec_t *) &chipOBle_profile_tx_config, +}; + +const bt_gatts_service_t chipOBle_gatts_service = { + .starting_handle = 0x0014, + .ending_handle = 0x0019, + .required_encryption_key_size = 0, + .records = chipOBle_service_rec +}; + diff --git a/src/platform/mt793x/BLEManagerImpl.cpp b/src/platform/mt793x/BLEManagerImpl.cpp new file mode 100644 index 00000000000000..61c6ebf0e06edd --- /dev/null +++ b/src/platform/mt793x/BLEManagerImpl.cpp @@ -0,0 +1,807 @@ +/* + * + * Copyright (c) 2020-2021 Project CHIP Authors + * Copyright (c) 2019 Nest Labs, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Provides an implementation of the BLEManager singleton object + * for the MediaTek Genio platforms. + */ + +/* this file behaves like a config.h, comes first */ +#include +#if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE + +#undef BT_ENABLE_HCI_SNOOP_LOG + +#include + +#include "FreeRTOS.h" +#include "timers.h" +#include "event_groups.h" +#include +#include +#include + +#include "bt_init.h" +#include "bt_callback_manager.h" +#include "connection_info.h" +#include "bt_gap_le.h" +#include "bt_gatts.h" +#include "bt_uuid.h" +#include "bt_platform.h" +#ifdef BT_ENABLE_HCI_SNOOP_LOG +#include "bt_driver_btsnoop.h" +#endif +#include "gatt_service.h" + +using namespace ::chip; +using namespace ::chip::Ble; + +extern void (*CHIPoBLEProfile_read_callback)(uint16_t handle, void*data, uint16_t size); +extern void (*CHIPoBLEProfile_write_callback)(uint16_t handle, void*data, uint16_t size); +extern void (*CHIPoBLEProfile_ccc_callback)(uint16_t handle, void*data, uint16_t size); + +namespace chip { +namespace DeviceLayer { +namespace Internal { + +namespace { +#define CHIP_ADV_DATA_TYPE_FLAGS 0x01 +#define CHIP_ADV_DATA_FLAGS 0x06 +#define CHIP_ADV_DATA_TYPE_NAME 0x09 +#define CHIP_ADV_DATA_TYPE_SERVICE_DATA 0x16 +#define CHIP_ADV_SHORT_UUID_LEN 2 + +#define MAX_ADV_DATA_LEN (31) +#define BLE_ADV_OTHER_LEN (9) + +const uint8_t ShortUUID_CHIPoBLEService[] = { 0xF6, 0xFF }; + +#define EG_EVENT_BLE_POWER_ON_CNF (0x01) +#define EG_EVENT_BLE_ADV_CNF (0x02) + +TimerHandle_t sbleAdvTimeoutTimer; // FreeRTOS sw timer. +EventGroupHandle_t xBleEventGroup; + +const ChipBleUUID ChipUUID_CHIPoBLEChar_RX = { { 0x18, 0xEE, 0x2E, 0xF5, 0x26, 0x3D, 0x45, 0x59, 0x95, 0x9F, 0x4F, 0x9C, 0x42, 0x9F, + 0x9D, 0x11 } }; +const ChipBleUUID ChipUUID_CHIPoBLEChar_TX = { { 0x18, 0xEE, 0x2E, 0xF5, 0x26, 0x3D, 0x45, 0x59, 0x95, 0x9F, 0x4F, 0x9C, 0x42, 0x9F, + 0x9D, 0x12 } }; + +} // namespace + +BLEManagerImpl BLEManagerImpl::sInstance; + + +/***************************************************************************/ +/** + * Setup the bluetooth init function. + * + * @return none + * + * All bluetooth specific initialization + ******************************************************************************/ + +CHIP_ERROR BLEManagerImpl::_Init() +{ + CHIP_ERROR err = CHIP_NO_ERROR; + + // Initialize the CHIP BleLayer. + ChipLogError(DeviceLayer, "BLE init start"); + err = BleLayer::Init(this, this, &DeviceLayer::SystemLayer()); + ChipLogError(DeviceLayer, "BleLayer init complete"); + SuccessOrExit(err); + + mServiceMode = ConnectivityManager::kCHIPoBLEServiceMode_Enabled; + CHIPoBLEProfile_write_callback = BLEManagerImpl::HandleRXCharWrite; + CHIPoBLEProfile_ccc_callback = BLEManagerImpl::HandleTXCharCCCDWrite; + + xBleEventGroup = xEventGroupCreate(); + if (xBleEventGroup == NULL) { + ChipLogError(DeviceLayer, "Cannot create xBleEventGroup"); + err = CHIP_ERROR_NO_MEMORY; + } + SuccessOrExit(err); + + init_connection_info(); + bt_create_task(); + + bt_callback_manager_register_callback(bt_callback_type_app_event, + (uint32_t)(MODULE_MASK_GAP | MODULE_MASK_GATT | MODULE_MASK_SYSTEM), + (void *)BleMatterAppEventCallback); +#ifdef BT_ENABLE_HCI_SNOOP_LOG + bt_driver_btsnoop_ctrl(1); +#endif + // Create FreeRTOS sw timer for BLE timeouts and interval change. + sbleAdvTimeoutTimer = xTimerCreate("BleAdvTimer", // Just a text name, not used by the RTOS kernel + 1, // == default timer period (mS) + false, // no timer reload (==one-shot) + (void *) this, // init timer id = ble obj context + BleAdvTimeoutHandler // timer callback handler + ); + + mFlags.ClearAll().Set(Flags::kAdvertisingEnabled, CHIP_DEVICE_CONFIG_CHIPOBLE_ENABLE_ADVERTISING_AUTOSTART); + mFlags.Set(Flags::kFastAdvertisingEnabled, true); + PlatformMgr().ScheduleWork(DriveBLEState, 0); + + +exit: + return err; +} + +uint16_t BLEManagerImpl::_NumConnections(void) +{ + return num_connection_info(); +} + +#if 0 +CHIP_ERROR BLEManagerImpl::_SetCHIPoBLEServiceMode(CHIPoBLEServiceMode val) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + + VerifyOrExit(val != ConnectivityManager::kCHIPoBLEServiceMode_NotSupported, err = CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrExit(mServiceMode != ConnectivityManager::kCHIPoBLEServiceMode_NotSupported, err = CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE); + + if (val != mServiceMode) + { + mServiceMode = val; + PlatformMgr().ScheduleWork(DriveBLEState, 0); + } + +exit: + return err; +} +#endif + +CHIP_ERROR BLEManagerImpl::_SetAdvertisingEnabled(bool val) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + + VerifyOrExit(mServiceMode != ConnectivityManager::kCHIPoBLEServiceMode_NotSupported, err = CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE); + + if (mFlags.Has(Flags::kAdvertisingEnabled) != val) + { + mFlags.Set(Flags::kAdvertisingEnabled, val); + PlatformMgr().ScheduleWork(DriveBLEState, 0); + } + + exit: + return err; +} + +CHIP_ERROR BLEManagerImpl::_SetAdvertisingMode(BLEAdvertisingMode mode) +{ + switch (mode) + { + case BLEAdvertisingMode::kFastAdvertising: + mFlags.Set(Flags::kFastAdvertisingEnabled, true); + break; + case BLEAdvertisingMode::kSlowAdvertising: + mFlags.Set(Flags::kFastAdvertisingEnabled, false); + break; + default: + return CHIP_ERROR_INVALID_ARGUMENT; + } + + mFlags.Set(Flags::kRestartAdvertising); + PlatformMgr().ScheduleWork(DriveBLEState, 0); + + return CHIP_NO_ERROR; + +} + +CHIP_ERROR BLEManagerImpl::_GetDeviceName(char * buf, size_t bufSize) +{ + if (strlen(gatts_device_name) >= bufSize) + { + return CHIP_ERROR_BUFFER_TOO_SMALL; + } + + strcpy(buf, gatts_device_name); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR BLEManagerImpl::_SetDeviceName(const char * deviceName) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + + if (mServiceMode == ConnectivityManager::kCHIPoBLEServiceMode_NotSupported) + { + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; + } + + if (deviceName != NULL && deviceName[0] != 0) + { + if (strlen(deviceName) >= kMaxDeviceNameLength) + { + return CHIP_ERROR_INVALID_ARGUMENT; + } + strcpy(gatts_device_name, deviceName); + } + else + { + gatts_device_name[0] = 0; + } + + return CHIP_NO_ERROR; +} + +void BLEManagerImpl::_OnPlatformEvent(const ChipDeviceEvent * event) +{ + switch (event->Type) + { + case DeviceEventType::kCHIPoBLESubscribe: { + ChipDeviceEvent connEstEvent; + + ChipLogProgress(DeviceLayer, "_OnBlePlatformEvent kCHIPoBLESubscribe"); + HandleSubscribeReceived(event->CHIPoBLESubscribe.ConId, &CHIP_BLE_SVC_ID, &ChipUUID_CHIPoBLEChar_TX); + connEstEvent.Type = DeviceEventType::kCHIPoBLEConnectionEstablished; + PlatformMgr().PostEventOrDie(&connEstEvent); + } + break; + + case DeviceEventType::kCHIPoBLEUnsubscribe: { + ChipLogProgress(DeviceLayer, "_OnBlePlatformEvent kCHIPoBLEUnsubscribe"); + HandleUnsubscribeReceived(event->CHIPoBLEUnsubscribe.ConId, &CHIP_BLE_SVC_ID, &ChipUUID_CHIPoBLEChar_TX); + } + break; + + case DeviceEventType::kCHIPoBLEWriteReceived: { + ChipLogProgress(DeviceLayer, "_OnBlePlatformEvent kCHIPoBLEWriteReceived"); + HandleWriteReceived(event->CHIPoBLEWriteReceived.ConId, &CHIP_BLE_SVC_ID, &ChipUUID_CHIPoBLEChar_RX, + PacketBufferHandle::Adopt(event->CHIPoBLEWriteReceived.Data)); + } + break; + + case DeviceEventType::kCHIPoBLEConnectionError: { + ChipLogProgress(DeviceLayer, "_OnBlePlatformEvent kCHIPoBLEConnectionError"); + HandleConnectionError(event->CHIPoBLEConnectionError.ConId, event->CHIPoBLEConnectionError.Reason); + } + break; + + case DeviceEventType::kCHIPoBLEIndicateConfirm: { + ChipLogProgress(DeviceLayer, "_OnBlePlatformEvent kCHIPoBLEIndicateConfirm, ConId %04x", event->CHIPoBLEIndicateConfirm.ConId); + HandleIndicationConfirmation(event->CHIPoBLEIndicateConfirm.ConId, &CHIP_BLE_SVC_ID, &ChipUUID_CHIPoBLEChar_TX); + } + break; + + case DeviceEventType::kCHIPoBLENotifyConfirm: { + ChipLogProgress(DeviceLayer, "_OnBlePlatformEvent kCHIPoBLENotifyConfirm"); + HandleTxConfirmationEvent(event->CHIPoBLENotifyConfirm.ConId); + } + break; + + default: + ChipLogProgress(DeviceLayer, "_OnBlePlatformEvent default: event->Type = %d", event->Type); + break; + } +} + + +bool BLEManagerImpl::SubscribeCharacteristic(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId) +{ + ChipLogProgress(DeviceLayer, "BLEManagerImpl::SubscribeCharacteristic() not supported"); + return false; +} + +bool BLEManagerImpl::UnsubscribeCharacteristic(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId) +{ + ChipLogProgress(DeviceLayer, "BLEManagerImpl::UnsubscribeCharacteristic() not supported"); + return false; +} + +bool BLEManagerImpl::CloseConnection(BLE_CONNECTION_OBJECT conId) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + bt_hci_cmd_disconnect_t disconnect_para; + bt_status_t ret; + + ChipLogProgress(DeviceLayer, "Closing BLE GATT connection (con %u)", conId); + + disconnect_para.connection_handle = conId; + disconnect_para.reason = BT_HCI_STATUS_REMOTE_USER_TERMINATED_CONNECTION; + + ret = bt_gap_le_disconnect(&disconnect_para); + err = MapBLEError(ret); + + if (err != CHIP_NO_ERROR) + { + ChipLogError(DeviceLayer, "bt_gap_le_disconnect() failed: %s", ErrorStr(err)); + } + + return (err == CHIP_NO_ERROR); + +} + +uint16_t BLEManagerImpl::GetMTU(BLE_CONNECTION_OBJECT conId) const +{ + ChipLogProgress(DeviceLayer, "GetMTU (con %u), returning 247", conId); + return 247; +} + +#define INDICATION_BUFFER_LENGTH (300) +bool BLEManagerImpl::SendIndication(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId, + PacketBufferHandle data) +{ + uint8_t buf[INDICATION_BUFFER_LENGTH + 3] = {0}; + bt_gattc_charc_value_notification_indication_t *req; + CHIP_ERROR err = CHIP_NO_ERROR; + ChipDeviceEvent event; + bt_status_t ret; + + VerifyOrExit(UUIDsMatch(&ChipUUID_CHIPoBLEChar_TX, charId), err = CHIP_ERROR_INVALID_MESSAGE_TYPE); + VerifyOrExit(UUIDsMatch(&ChipUUID_CHIPoBLEChar_TX, charId), err = CHIP_ERROR_INVALID_MESSAGE_TYPE); + + ChipLogProgress(DeviceLayer, "SendIndication(): conId %d, len %d", conId, data->DataLength()); + + if (data->DataLength() > INDICATION_BUFFER_LENGTH) { + ChipLogError(DeviceLayer, "SendIndication(): Exceed buffer length! conId %d, len %d", conId, data->DataLength()); + err = CHIP_ERROR_NO_MEMORY; + goto exit; + } + + req = (bt_gattc_charc_value_notification_indication_t *) buf; + req->attribute_value_length = 3 + data->DataLength(); + req->att_req.opcode = BT_ATT_OPCODE_HANDLE_VALUE_INDICATION; + req->att_req.handle = 24; + memcpy(&req->att_req.attribute_value[0], data->Start(), data->DataLength()); + ret = bt_gatts_send_charc_value_notification_indication(conId, req); + err = MapBLEError(ret); + SuccessOrExit(err); + +exit: + if (err != CHIP_NO_ERROR) + { + ChipLogError(DeviceLayer, "BLEManagerImpl::SendIndication() failed: %s", ErrorStr(err)); + return false; + } + + return true; + +} + +void BLEManagerImpl::HandleRXCharWrite(uint16_t handle, void *data, uint16_t size) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + System::PacketBufferHandle buf; + uint16_t writeLen = size; + + // Copy the data to a packet buffer. + buf = System::PacketBufferHandle::NewWithData(data, writeLen, 0, 0); + VerifyOrExit(!buf.IsNull(), err = CHIP_ERROR_NO_MEMORY); + + ChipLogDetail(DeviceLayer, "Write request/command received for CHIPoBLE RX characteristic (con %" PRIu16 ", len %" PRIu16 ")", + handle, buf->DataLength()); + + // Post an event to the CHIP queue to deliver the data into the CHIP stack. + { + ChipDeviceEvent event; + event.Type = DeviceEventType::kCHIPoBLEWriteReceived; + event.CHIPoBLEWriteReceived.ConId = handle; + event.CHIPoBLEWriteReceived.Data = std::move(buf).UnsafeRelease(); + err = PlatformMgr().PostEvent(&event); + } + +exit: + if (err != CHIP_NO_ERROR) + { + ChipLogError(DeviceLayer, "HandleRXCharWrite() failed: %s", ErrorStr(err)); + } +} + +void BLEManagerImpl::HandleTXCharCCCDWrite(uint16_t handle, void *data, uint16_t size) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + app_bt_connection_cb_t * bleConnState; + bool isDisabled; + ChipDeviceEvent event; + bleConnState = find_conneciton_info_by_handle(handle); + VerifyOrExit(bleConnState != NULL, err = CHIP_ERROR_NO_MEMORY); + + VerifyOrExit(size == sizeof(uint16_t), err = CHIP_ERROR_INVALID_MESSAGE_LENGTH); + + // Determine if the client is enabling or disabling notification/indication. + isDisabled = (*(uint16_t *)data != 0x0002); + + ChipLogProgress(DeviceLayer, "HandleTXcharCCCDWrite - Config Flags value : %d", + *(uint16_t *)data); + ChipLogProgress(DeviceLayer, "CHIPoBLE %s received", isDisabled ? "unsubscribe" : "subscribe"); + + if (!isDisabled) + { + // If indications are not already enabled for the connection... + if (!bleConnState->subscribed) + { + bleConnState->subscribed = 1; + // Post an event to the CHIP queue to process either a CHIPoBLE Subscribe or Unsubscribe based on + // whether the client is enabling or disabling indications. + { + event.Type = DeviceEventType::kCHIPoBLESubscribe; + event.CHIPoBLESubscribe.ConId = handle; + err = PlatformMgr().PostEvent(&event); + } + } + } + else + { + bleConnState->subscribed = 0; + event.Type = DeviceEventType::kCHIPoBLEUnsubscribe; + event.CHIPoBLESubscribe.ConId = handle; + err = PlatformMgr().PostEvent(&event); + } + +exit: + if (err != CHIP_NO_ERROR) + { + ChipLogError(DeviceLayer, "HandleTXCharCCCDWrite() failed: %s", ErrorStr(err)); + } +} + +bool BLEManagerImpl::SendWriteRequest(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId, + PacketBufferHandle pBuf) +{ + ChipLogProgress(DeviceLayer, "BLEManagerImpl::SendWriteRequest() not supported"); + return false; +} + +bool BLEManagerImpl::SendReadRequest(BLE_CONNECTION_OBJECT conId, const ChipBleUUID * svcId, const ChipBleUUID * charId, + PacketBufferHandle pBuf) +{ + ChipLogProgress(DeviceLayer, "BLEManagerImpl::SendReadRequest() not supported"); + return false; +} + +bool BLEManagerImpl::SendReadResponse(BLE_CONNECTION_OBJECT conId, BLE_READ_REQUEST_CONTEXT requestContext, + const ChipBleUUID * svcId, const ChipBleUUID * charId) +{ + ChipLogProgress(DeviceLayer, "BLEManagerImpl::SendReadResponse() not supported"); + return false; +} + +void BLEManagerImpl::NotifyChipConnectionClosed(BLE_CONNECTION_OBJECT conId) +{ + // Nothing to do +} + +void BLEManagerImpl::HandleTxConfirmationEvent(BLE_CONNECTION_OBJECT conId) +{ + ChipDeviceEvent event; + ChipLogProgress(DeviceLayer, "Tx Confirmation received!!!"); + + event.Type = DeviceEventType::kCHIPoBLEIndicateConfirm; + event.CHIPoBLEIndicateConfirm.ConId = conId; + PlatformMgr().PostEventOrDie(&event); +} + +CHIP_ERROR BLEManagerImpl::MapBLEError(int bleErr) +{ + switch (bleErr) + { + case BT_STATUS_SUCCESS: + return CHIP_NO_ERROR; + default: + return CHIP_ERROR(ChipError::Range::kPlatform, bleErr + CHIP_DEVICE_CONFIG_BLE_ERROR_MIN); + } +} + +CHIP_ERROR BLEManagerImpl::StartAdvertising(void) +{ + bt_hci_cmd_le_set_advertising_enable_t enable; + uint32_t deviceNameLength = 0; + ChipBLEDeviceIdentificationInfo deviceIdInfo; + uint8_t deviceIdInfoLength = sizeof(deviceIdInfo); + CHIP_ERROR err = CHIP_NO_ERROR; + int adv_name_len; + uint32_t index = 0; + bt_status_t ret; + + bt_hci_cmd_le_set_advertising_parameters_t adv_param = { + .advertising_interval_min = CHIP_DEVICE_CONFIG_BLE_SLOW_ADVERTISING_INTERVAL_MIN, + .advertising_interval_max = CHIP_DEVICE_CONFIG_BLE_SLOW_ADVERTISING_INTERVAL_MAX, + .advertising_type = BT_HCI_ADV_TYPE_CONNECTABLE_UNDIRECTED, + .own_address_type = BT_ADDR_PUBLIC, + .advertising_channel_map = 7, + .advertising_filter_policy = 0 + }; + + bt_hci_cmd_le_set_advertising_data_t adv_data = { + .advertising_data_length = MAX_ADV_DATA_LEN, + }; + + if (mFlags.Has(Flags::kRestartAdvertising)) { + ChipLogProgress(DeviceLayer, "Stop advertising.."); + enable.advertising_enable = BT_HCI_DISABLE; + ret = bt_gap_le_set_advertising(&enable, NULL, NULL, NULL); + + if (BT_STATUS_SUCCESS == ret) { + xEventGroupWaitBits(xBleEventGroup, EG_EVENT_BLE_ADV_CNF, pdTRUE, pdFALSE, pdMS_TO_TICKS(10000)); + ChipLogProgress(DeviceLayer, "Advertising stopped."); + } + + mFlags.Clear(Flags::kRestartAdvertising); + } + + if (mFlags.Has(Flags::kFastAdvertisingEnabled)) + { + adv_param.advertising_interval_min = CHIP_DEVICE_CONFIG_BLE_FAST_ADVERTISING_INTERVAL_MIN; + adv_param.advertising_interval_max = CHIP_DEVICE_CONFIG_BLE_FAST_ADVERTISING_INTERVAL_MAX; + } + + if (!mFlags.Has(Flags::kDeviceNameSet)) + { + snprintf(gatts_device_name, sizeof(gatts_device_name), "%s%04" PRIX32, CHIP_DEVICE_CONFIG_BLE_DEVICE_NAME_PREFIX, (uint32_t) 0); + + gatts_device_name[kMaxDeviceNameLength] = 0; + } + + deviceNameLength = strlen(gatts_device_name); + + VerifyOrExit(deviceNameLength < kMaxDeviceNameLength, err = CHIP_ERROR_INVALID_ARGUMENT); + deviceNameLength = deviceNameLength > MAX_ADV_DATA_LEN - BLE_ADV_OTHER_LEN - 1 ? MAX_ADV_DATA_LEN - BLE_ADV_OTHER_LEN - 1 : deviceNameLength; + + ChipLogProgress(DeviceLayer, "Beginning advertising, interval(min,max)=(%d, %d), devName=%s, len=%lu", + adv_param.advertising_interval_min, adv_param.advertising_interval_max, gatts_device_name, deviceNameLength); + + err = ConfigurationMgr().GetBLEDeviceIdentificationInfo(deviceIdInfo); + SuccessOrExit(err); + + static_assert(sizeof(deviceIdInfo) + CHIP_ADV_SHORT_UUID_LEN + 1 <= UINT8_MAX, "Our length won't fit in a uint8_t"); + static_assert(2 + CHIP_ADV_SHORT_UUID_LEN + sizeof(deviceIdInfo) + 1 <= MAX_ADV_DATA_LEN, "Our buffer is not big enough"); + + adv_data.advertising_data[index++] = 0x02; // AD length + adv_data.advertising_data[index++] = CHIP_ADV_DATA_TYPE_FLAGS; // AD type : flags + adv_data.advertising_data[index++] = CHIP_ADV_DATA_FLAGS; // AD value + + adv_data.advertising_data[index++] = static_cast(deviceIdInfoLength + CHIP_ADV_SHORT_UUID_LEN + 1); // AD length + adv_data.advertising_data[index++] = CHIP_ADV_DATA_TYPE_SERVICE_DATA; // AD type : Service Data + adv_data.advertising_data[index++] = ShortUUID_CHIPoBLEService[0]; // AD value + adv_data.advertising_data[index++] = ShortUUID_CHIPoBLEService[1]; + + memcpy(&adv_data.advertising_data[index], (void *) &deviceIdInfo, deviceIdInfoLength); // AD value + index += deviceIdInfoLength; + + adv_data.advertising_data[index++] = static_cast(deviceNameLength + 1); // AD length + adv_data.advertising_data[index++] = CHIP_ADV_DATA_TYPE_NAME; // AD type : name + memcpy(&adv_data.advertising_data[index], gatts_device_name, deviceNameLength); // AD value + index += deviceNameLength; + + enable.advertising_enable = BT_HCI_ENABLE; + ret = bt_gap_le_set_advertising(&enable, &adv_param, &adv_data, NULL); + + err = MapBLEError(ret); + SuccessOrExit(err); + + if ((xEventGroupWaitBits(xBleEventGroup, EG_EVENT_BLE_ADV_CNF, pdTRUE, pdFALSE, pdMS_TO_TICKS(10000)) & EG_EVENT_BLE_ADV_CNF) == EG_EVENT_BLE_ADV_CNF) + { + ChipLogProgress(DeviceLayer, "Advertising started."); + if (mFlags.Has(Flags::kFastAdvertisingEnabled)) + { + StartBleAdvTimeoutTimer(CHIP_DEVICE_CONFIG_BLE_ADVERTISING_INTERVAL_CHANGE_TIME); + } + mFlags.Set(Flags::kAdvertising); + } else + { + err = CHIP_ERROR_TIMEOUT; + } + +exit: + return err; +} + +CHIP_ERROR BLEManagerImpl::StopAdvertising(void) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + bt_status_t ret; + + if (mFlags.Has(Flags::kAdvertising)) + { + mFlags.Clear(Flags::kAdvertising).Clear(Flags::kRestartAdvertising); + mFlags.Set(Flags::kFastAdvertisingEnabled, true); + + ChipLogProgress(DeviceLayer, "Stop advertising.."); + bt_hci_cmd_le_set_advertising_enable_t enable = {BT_HCI_DISABLE}; + ret = bt_gap_le_set_advertising(&enable, NULL, NULL, NULL); + + err = MapBLEError(ret); + SuccessOrExit(err); + + if((xEventGroupWaitBits(xBleEventGroup, EG_EVENT_BLE_ADV_CNF, pdTRUE, pdFALSE, pdMS_TO_TICKS(10000)) & EG_EVENT_BLE_ADV_CNF) != EG_EVENT_BLE_ADV_CNF) + { + err = CHIP_ERROR_TIMEOUT; + } + SuccessOrExit(err); + + ChipLogProgress(DeviceLayer, "Advertising stopped."); + + CancelBleAdvTimeoutTimer(); + } + +exit: + return err; + +} + +void BLEManagerImpl::BleAdvTimeoutHandler(TimerHandle_t xTimer) +{ + if (BLEMgrImpl().mFlags.Has(Flags::kFastAdvertisingEnabled)) + { + ChipLogDetail(DeviceLayer, "bleAdv Timeout : Start slow advertisement"); + BLEMgr().SetAdvertisingMode(BLEAdvertisingMode::kSlowAdvertising); + } + else if (BLEMgrImpl().mFlags.Has(Flags::kAdvertising)) + { + // Advertisement time expired. Stop advertising + ChipLogDetail(DeviceLayer, "bleAdv Timeout : Stop advertissement"); + BLEMgr().SetAdvertisingEnabled(false); + } +} + +void BLEManagerImpl::CancelBleAdvTimeoutTimer(void) +{ + if (xTimerStop(sbleAdvTimeoutTimer, 0) == pdFAIL) + { + ChipLogError(DeviceLayer, "Failed to stop BledAdv timeout timer"); + } +} + +void BLEManagerImpl::StartBleAdvTimeoutTimer(uint32_t aTimeoutInMs) +{ + if (xTimerIsTimerActive(sbleAdvTimeoutTimer)) + { + CancelBleAdvTimeoutTimer(); + } + + // timer is not active, change its period to required value (== restart). + // FreeRTOS- Block for a maximum of 100 ticks if the change period command + // cannot immediately be sent to the timer command queue. + if (xTimerChangePeriod(sbleAdvTimeoutTimer, aTimeoutInMs / portTICK_PERIOD_MS, 100) != pdPASS) + { + ChipLogError(DeviceLayer, "Failed to start BledAdv timeout timer"); + } +} + +bt_status_t BLEManagerImpl::BleMatterAppEventCallback(bt_msg_type_t msg, bt_status_t status, void *buff) +{ + ChipLogProgress(DeviceLayer, "BleMatterAppEventCallback: msg %08x, status %08x", (unsigned int)msg, (unsigned int)status); + + // PlatformMgr().LockChipStack(); + + switch (msg) + { + case BT_POWER_ON_CNF: + if (BT_STATUS_SUCCESS != bt_gatts_set_max_mtu(247)) { + ChipLogError(DeviceLayer, "Unable to set BT GATTS maximum mtu size!"); + } + + sInstance.mFlags.Set(Flags::kBLEStackInitialized); + PlatformMgr().ScheduleWork(DriveBLEState, 0); + break; + + case BT_GAP_LE_SET_ADVERTISING_CNF: + ChipLogProgress(DeviceLayer, "BT_GAP_LE_SET_ADVERTISING_CNF: Raise EG_EVENT_BLE_ADV_CNF"); + xEventGroupSetBits(xBleEventGroup, EG_EVENT_BLE_ADV_CNF); + break; + + case BT_GAP_LE_CONNECT_IND: + PlatformMgr().ScheduleWork(DriveBLEState, 0); + break; + + case BT_GAP_LE_DISCONNECT_IND: + { + bt_hci_evt_disconnect_complete_t *conn_evt = (bt_hci_evt_disconnect_complete_t*) buff; + ChipDeviceEvent event; + event.Type = DeviceEventType::kCHIPoBLEConnectionError; + event.CHIPoBLEConnectionError.ConId = conn_evt->connection_handle; + + switch (conn_evt->reason) + { + case BT_HCI_STATUS_REMOTE_USER_TERMINATED_CONNECTION: + case BT_HCI_STATUS_REMOTE_TERMINATED_CONNECTION_DUE_TO_LOW_RESOURCES: + case BT_HCI_STATUS_REMOTE_TERMINATED_CONNECTION_DUE_TO_POWER_OFF: + event.CHIPoBLEConnectionError.Reason = BLE_ERROR_REMOTE_DEVICE_DISCONNECTED; + break; + + case BT_HCI_STATUS_CONNECTION_TERMINATED_BY_LOCAL_HOST: + event.CHIPoBLEConnectionError.Reason = BLE_ERROR_APP_CLOSED_CONNECTION; + break; + + default: + event.CHIPoBLEConnectionError.Reason = BLE_ERROR_CHIPOBLE_PROTOCOL_ABORT; + break; + } + + ChipLogProgress(DeviceLayer, "BLE GATT connection closed (con %u, reason %u)", conn_evt->connection_handle, conn_evt->reason); + + PlatformMgr().PostEventOrDie(&event); + + // Arrange to re-enable connectable advertising in case it was disabled due to the + // maximum connection limit being reached. + + sInstance.mFlags.Set(Flags::kRestartAdvertising); + sInstance.mFlags.Set(Flags::kFastAdvertisingEnabled); + PlatformMgr().ScheduleWork(DriveBLEState, 0); + } + break; + case BT_GATTC_CHARC_VALUE_CONFIRMATION: + { + bt_handle_t *connection_handle_p = (bt_handle_t *) buff; + ChipDeviceEvent event; + + ChipLogProgress(DeviceLayer, "Tx Confirmation received"); + + event.Type = DeviceEventType::kCHIPoBLEIndicateConfirm; + event.CHIPoBLEIndicateConfirm.ConId = *connection_handle_p; + PlatformMgr().PostEventOrDie(&event); + } + break; + + default: + break; + } + + // PlatformMgr().UnlockChipStack(); + + return BT_STATUS_SUCCESS; +} + +void BLEManagerImpl::DriveBLEState(void) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + + // Check if BLE stack is initialized + VerifyOrExit(mFlags.Has(Flags::kBLEStackInitialized), /* */); + + // Start advertising if needed... + if (mServiceMode == ConnectivityManager::kCHIPoBLEServiceMode_Enabled && mFlags.Has(Flags::kAdvertisingEnabled) && + NumConnections() < kMaxConnections) + { + // Start/re-start advertising if not already started, or if there is a pending change + // to the advertising configuration. + if (!mFlags.Has(Flags::kAdvertising) || mFlags.Has(Flags::kRestartAdvertising)) + { + err = StartAdvertising(); + SuccessOrExit(err); + } + } + + // Otherwise, stop advertising if it is enabled. + else if (mFlags.Has(Flags::kAdvertising)) + { + err = StopAdvertising(); + SuccessOrExit(err); + } + +exit: + if (err != CHIP_NO_ERROR) + { + ChipLogError(DeviceLayer, "Disabling CHIPoBLE service due to error: %s", ErrorStr(err)); + mServiceMode = ConnectivityManager::kCHIPoBLEServiceMode_Disabled; + } +} + +void BLEManagerImpl::DriveBLEState(intptr_t arg) +{ + sInstance.DriveBLEState(); +} + +} +} +} + +#endif // CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE diff --git a/src/platform/mt793x/BLEManagerImpl.h b/src/platform/mt793x/BLEManagerImpl.h new file mode 100644 index 00000000000000..cb26e087464999 --- /dev/null +++ b/src/platform/mt793x/BLEManagerImpl.h @@ -0,0 +1,167 @@ +/* + * + * Copyright (c) 2020-2021 Project CHIP Authors + * Copyright (c) 2019 Nest Labs, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Provides an implementation of the BLEManager singleton object + * for the MediaTek MT793x platforms. + */ + +#pragma once + +typedef void (*CHIPoBLECharCallback)(uint16_t, void*, uint16_t); + +#if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE + +#include "FreeRTOS.h" +#include "timers.h" +#include "bt_type.h" + +namespace chip { +namespace DeviceLayer { +namespace Internal { + +using namespace chip::Ble; + +/** + * Concrete implementation of the BLEManager singleton object for the Genio platforms. + */ +class BLEManagerImpl final : public BLEManager, private BleLayer, private BlePlatformDelegate, private BleApplicationDelegate +{ + // Allow the BLEManager interface class to delegate method calls to + // the implementation methods provided by this class. + friend BLEManager; + + // ===== Members that implement the BLEManager internal interface. + CHIP_ERROR _Init(void); + CHIP_ERROR _Shutdown() { return CHIP_NO_ERROR; } + bool _IsAdvertisingEnabled(void); + CHIP_ERROR _SetAdvertisingEnabled(bool val); + bool _IsAdvertising(void); + CHIP_ERROR _SetAdvertisingMode(BLEAdvertisingMode mode); + CHIP_ERROR _GetDeviceName(char * buf, size_t bufSize); + CHIP_ERROR _SetDeviceName(const char * deviceName); + uint16_t _NumConnections(void); + void _OnPlatformEvent(const ChipDeviceEvent * event); + BleLayer * _GetBleLayer(void); + + // ===== Members that implement virtual methods on BlePlatformDelegate. + + bool SubscribeCharacteristic(BLE_CONNECTION_OBJECT conId, const Ble::ChipBleUUID * svcId, + const Ble::ChipBleUUID * charId) override; + bool UnsubscribeCharacteristic(BLE_CONNECTION_OBJECT conId, const Ble::ChipBleUUID * svcId, + const Ble::ChipBleUUID * charId) override; + bool CloseConnection(BLE_CONNECTION_OBJECT conId) override; + uint16_t GetMTU(BLE_CONNECTION_OBJECT conId) const override; + bool SendIndication(BLE_CONNECTION_OBJECT conId, const Ble::ChipBleUUID * svcId, const Ble::ChipBleUUID * charId, + System::PacketBufferHandle pBuf) override; + bool SendWriteRequest(BLE_CONNECTION_OBJECT conId, const Ble::ChipBleUUID * svcId, const Ble::ChipBleUUID * charId, + System::PacketBufferHandle pBuf) override; + bool SendReadRequest(BLE_CONNECTION_OBJECT conId, const Ble::ChipBleUUID * svcId, const Ble::ChipBleUUID * charId, + System::PacketBufferHandle pBuf) override; + bool SendReadResponse(BLE_CONNECTION_OBJECT conId, BLE_READ_REQUEST_CONTEXT requestContext, const Ble::ChipBleUUID * svcId, + const Ble::ChipBleUUID * charId) override; + + // ===== Members that implement virtual methods on BleApplicationDelegate. + + void NotifyChipConnectionClosed(BLE_CONNECTION_OBJECT conId) override; + + // ===== Members for internal use by the following friends. + + friend BLEManager & BLEMgr(void); + friend BLEManagerImpl & BLEMgrImpl(void); + + static BLEManagerImpl sInstance; + + // ===== Private members reserved for use by this class only. + enum class Flags : uint16_t + { + kAdvertisingEnabled = 0x0001, + kFastAdvertisingEnabled = 0x0002, + kAdvertising = 0x0004, + kRestartAdvertising = 0x0008, + kBLEStackInitialized = 0x0010, + kDeviceNameSet = 0x0020, + }; + + enum + { + kMaxConnections = BLE_LAYER_NUM_BLE_ENDPOINTS, + kMaxDeviceNameLength = 16, + kUnusedIndex = 0xFFFF, + }; + + CHIPoBLEServiceMode mServiceMode; + BitFlags mFlags; + + CHIP_ERROR MapBLEError(int bleErr); + void DriveBLEState(void); + CHIP_ERROR StartAdvertising(void); + CHIP_ERROR StopAdvertising(void); + void StartBleAdvTimeoutTimer(uint32_t aTimeoutInMs); + void CancelBleAdvTimeoutTimer(void); + void HandleTxConfirmationEvent(BLE_CONNECTION_OBJECT conId); + static void DriveBLEState(intptr_t arg); + static void BleAdvTimeoutHandler(TimerHandle_t xTimer); + static bt_status_t BleMatterAppEventCallback(bt_msg_type_t msg, bt_status_t status, void *buff); + static void HandleRXCharWrite(uint16_t handle, void *data, uint16_t size); + static void HandleTXCharCCCDWrite(uint16_t handle, void *data, uint16_t size); +}; + +/** + * Returns a reference to the public interface of the BLEManager singleton object. + * + * Internal components should use this to access features of the BLEManager object + * that are common to all platforms. + */ +inline BLEManager & BLEMgr(void) +{ + return BLEManagerImpl::sInstance; +} + +/** + * Returns the platform-specific implementation of the BLEManager singleton object. + * + * Internal components can use this to gain access to features of the BLEManager + * that are specific to the Genio platforms. + */ +inline BLEManagerImpl & BLEMgrImpl(void) +{ + return BLEManagerImpl::sInstance; +} + +inline BleLayer * BLEManagerImpl::_GetBleLayer() +{ + return this; +} + +//inline BLEManager::CHIPoBLEServiceMode BLEManagerImpl::_GetCHIPoBLEServiceMode(void) +//{ +// return mServiceMode; +//} + +inline bool BLEManagerImpl::_IsAdvertisingEnabled(void) +{ + return mFlags.Has(Flags::kAdvertisingEnabled); +} + +} // namespace Internal +} // namespace DeviceLayer +} // namespace chip + +#endif // CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE diff --git a/src/platform/mt793x/BUILD.gn b/src/platform/mt793x/BUILD.gn new file mode 100644 index 00000000000000..c25455e3e8f50c --- /dev/null +++ b/src/platform/mt793x/BUILD.gn @@ -0,0 +1,82 @@ +# Copyright (c) 2021 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/chip.gni") +import("//build_overrides/pigweed.gni") + +import("${chip_root}/src/platform/device.gni") + +assert(chip_device_platform == "mt793x") + +static_library("mt793x") { + sources = [ + "BLEManagerImpl.cpp", + "BLEManagerImpl.h", + "BlePlatformConfig.h", + "../SingletonConfigurationManager.cpp", + "CHIPDevicePlatformConfig.h", + "CHIPDevicePlatformEvent.h", + "CHIPMem-Platform.cpp", + "CHIPPlatformConfig.h", + "ConnectivityManagerImpl.cpp", + "ConnectivityManagerImpl.h", + "ConfigurationManagerImpl.cpp", + "ConfigurationManagerImpl.h", + "DeviceNetworkProvisioningDelegateImpl.cpp", + "DeviceNetworkProvisioningDelegateImpl.h", + "DiagnosticDataProviderImpl.cpp", + "DiagnosticDataProviderImpl.h", + "MT793XConfig.cpp", + "MT793XConfig.h", + "KeyValueStoreManagerImpl.cpp", + "KeyValueStoreManagerImpl.h", + "Logging.cpp", + "PlatformManagerImpl.cpp", + "PlatformManagerImpl.h", + "SystemTimeSupport.cpp", + "SystemPlatformConfig.h", + "DnssdImpl.cpp", + "MtkWiFiEvents.cpp", + "BLEGattProfile.c" + ] + + if (chip_enable_ota_requestor) { + sources += [ + "OTAImageProcessorImpl.cpp", + "OTAImageProcessorImpl.h", + ] + } + + # "${chip_root}/src/app:app_config", + public_deps = [ "${chip_root}/src/platform:platform_base" ] + + # Add pigweed KVS + deps = [ + "$dir_pw_kvs:crc16", + "$dir_pw_log", + ] + public_deps += [ + "$dir_pw_checksum", + "$dir_pw_kvs", + "${chip_root}/third_party/mt793x_sdk/mDNSResponder", + ] + + if (chip_enable_wifi) { + sources += [ + "ConnectivityManagerImpl_WIFI.cpp", + "NetworkCommissioningWiFiDriver.cpp", + "NetworkCommissioningWiFiDriver.h", + ] + } +} diff --git a/src/platform/mt793x/BlePlatformConfig.h b/src/platform/mt793x/BlePlatformConfig.h new file mode 100644 index 00000000000000..950b49dd56c68a --- /dev/null +++ b/src/platform/mt793x/BlePlatformConfig.h @@ -0,0 +1,39 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2019 Google LLC. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Platform-specific configuration overrides for the CHIP BLE + * Layer on Genio platforms using the MediaTek SDK. + * + */ + +#pragma once + +// ==================== Platform Adaptations ==================== + +#define BLE_CONNECTION_OBJECT uint16_t +#define BLE_CONNECTION_UNINITIALIZED ((uint16_t) -1) +#define BLE_MAX_RECEIVE_WINDOW_SIZE 5 + +#define BLE_CONFIG_ERROR_MIN 6000000 +#define BLE_CONFIG_ERROR_MAX 6000999 + +// ========== Platform-specific Configuration Overrides ========= + +/* none so far */ diff --git a/src/platform/mt793x/CHIPDevicePlatformConfig.h b/src/platform/mt793x/CHIPDevicePlatformConfig.h new file mode 100644 index 00000000000000..b2242941586392 --- /dev/null +++ b/src/platform/mt793x/CHIPDevicePlatformConfig.h @@ -0,0 +1,97 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2019 Nest Labs, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Platform-specific configuration overrides for the Chip Device Layer + * on Genio platforms using the MediaTek SDK. + */ + +#pragma once + +// ==================== Platform Adaptations ==================== + +#define CHIP_DEVICE_CONFIG_BLE_ERROR_MIN 0xC00000 + +#define CHIP_DEVICE_CONFIG_ENABLE_WIFI_STATION 1 +#define CHIP_DEVICE_CONFIG_ENABLE_WIFI_AP 1 + +#if defined(SL_WIFI) +#define CHIP_DEVICE_CONFIG_ENABLE_WIFI_STATION 1 +#elif CHIP_ENABLE_OPENTHREAD + +#define CHIP_DEVICE_CONFIG_ENABLE_THREAD 1 +#define CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT 1 +#define CHIP_DEVICE_CONFIG_ENABLE_THREAD_DNS_CLIENT 1 +#define CHIP_DEVICE_CONFIG_ENABLE_THREAD_COMMISSIONABLE_DISCOVERY 1 +#define CHIP_DEVICE_CONFIG_ENABLE_DNSSD 1 +#endif /* CHIP_ENABLE_OPENTHREAD */ + +#define CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY 1 +#define CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONABLE_DISCOVERY 1 + +#ifndef CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE +#define CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE 1 +#endif + +#define CHIP_DEVICE_CONFIG_ENABLE_CHIP_TIME_SERVICE_TIME_SYNC 0 +#define CHIP_DEVICE_CONFIG_PERSISTED_STORAGE_GLOBAL_EIDC_KEY 2 + +// ========== Platform-specific Configuration ========= + +// These are configuration options that are unique to the Genio platform. +// These can be overridden by the application as needed. + +// ========== Platform-specific Configuration Overrides ========= + +#ifndef CHIP_DEVICE_CONFIG_BLE_LL_TASK_PRIORITY +#define CHIP_DEVICE_CONFIG_BLE_LL_TASK_PRIORITY (configTIMER_TASK_PRIORITY - 1) +#endif // CHIP_DEVICE_CONFIG_BLE_LL_TASK_PRIORITY + +#ifndef CHIP_DEVICE_CONFIG_BLE_STACK_TASK_PRIORITY +#define CHIP_DEVICE_CONFIG_BLE_STACK_TASK_PRIORITY (CHIP_DEVICE_CONFIG_BLE_LL_TASK_PRIORITY - 1) +#endif // CHIP_DEVICE_CONFIG_BLE_STACK_TASK_PRIORITY + +#ifndef CHIP_DEVICE_CONFIG_BLE_APP_TASK_PRIORITY +#define CHIP_DEVICE_CONFIG_BLE_APP_TASK_PRIORITY (CHIP_DEVICE_CONFIG_BLE_STACK_TASK_PRIORITY - 1) +#endif // CHIP_DEVICE_CONFIG_BLE_STACK_TASK_PRIORITY + +#ifndef CHIP_DEVICE_CONFIG_BLE_APP_TASK_STACK_SIZE +#define CHIP_DEVICE_CONFIG_BLE_APP_TASK_STACK_SIZE 1536 +#endif // CHIP_DEVICE_CONFIG_BLE_APP_TASK_STACK_SIZE + +#ifndef CHIP_DEVICE_CONFIG_CHIP_TASK_STACK_SIZE +#define CHIP_DEVICE_CONFIG_CHIP_TASK_STACK_SIZE (6 * 1024) +#endif // CHIP_DEVICE_CONFIG_CHIP_TASK_STACK_SIZE + +#ifndef CHIP_DEVICE_CONFIG_THREAD_TASK_STACK_SIZE +#define CHIP_DEVICE_CONFIG_THREAD_TASK_STACK_SIZE (4 * 1024) +#endif // CHIP_DEVICE_CONFIG_THREAD_TASK_STACK_SIZE + +#define CHIP_DEVICE_CONFIG_ENABLE_WIFI_TELEMETRY 0 +#define CHIP_DEVICE_CONFIG_ENABLE_THREAD_TELEMETRY 0 +#define CHIP_DEVICE_CONFIG_ENABLE_THREAD_TELEMETRY_FULL 0 + +#ifndef CHIP_DEVICE_CONFIG_BLE_APP_TASK_NAME +#define CHIP_DEVICE_CONFIG_BLE_APP_TASK_NAME "BLE_EVENT" +#endif // CHIP_DEVICE_CONFIG_BLE_APP_TASK_NAME +#define CHIP_DEVICE_CONFIG_LOG_PROVISIONING_HASH 0 + +#define CHIP_DEVICE_CONFIG_MAX_EVENT_QUEUE_SIZE 25 + +#define CHIP_DEVICE_CONFIG_WIFI_AP_CHANNEL 44 diff --git a/src/platform/mt793x/CHIPDevicePlatformEvent.h b/src/platform/mt793x/CHIPDevicePlatformEvent.h new file mode 100644 index 00000000000000..22ba70360f41d5 --- /dev/null +++ b/src/platform/mt793x/CHIPDevicePlatformEvent.h @@ -0,0 +1,93 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2019 Nest Labs, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Defines platform-specific event types and data for the Chip + * Device Layer on MT793x platforms using MT793x SDK. + */ + +#pragma once + +#include +#include + +#if CHIP_DEVICE_CONFIG_ENABLE_WIFI +#include "wifi_api_ex.h" +#endif +#include "filogic.h" + +#define MTK_EVENT_BUF_LEN 40 + +namespace chip { +namespace DeviceLayer { + +namespace DeviceEventType { + +/** + * Enumerates MT793x platform-specific event types that are visible to the + * application. + */ +enum PublicPlatformSpecificEventTypes +{ + /* None currently defined */ +}; + +/** + * Enumerates MT793x platform-specific event types that are internal to the + * Chip Device Layer. + */ +enum InternalPlatformSpecificEventTypes +{ + kMtkFilogicEvent = kRange_InternalPlatformSpecific, + kMtkWiFiEvent = kRange_InternalPlatformSpecific + 1, + kMtkIPEvent = kRange_InternalPlatformSpecific + 2, +}; + +} // namespace DeviceEventType + +/** + * Represents platform-specific event information for MT793x platforms. + */ +struct ChipDevicePlatformEvent final +{ + union + { + struct + { + filogic_async_event_id_t event; + uint8_t payload[MTK_EVENT_BUF_LEN]; + uint32_t length; + } FilogicEvent; + +#if CHIP_DEVICE_CONFIG_ENABLE_WIFI_STATION || CHIP_DEVICE_CONFIG_ENABLE_WIFI_AP + struct + { + filogic_async_event_data event_data; + } MtkWiFiEvent; +#endif + struct + { + wifi_event_t event; + uint8_t *payload; + uint32_t length; + } MtkIPEvent; + }; +}; +}; // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/mt793x/CHIPMem-Platform.cpp b/src/platform/mt793x/CHIPMem-Platform.cpp new file mode 100644 index 00000000000000..9e5934419979ab --- /dev/null +++ b/src/platform/mt793x/CHIPMem-Platform.cpp @@ -0,0 +1,166 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2019 Nest Labs, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * + * Copyright (c) 2020-2021 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * This file implements heap memory allocation APIs for CHIP. These functions are platform + * specific and might be C Standard Library heap functions re-direction in most of cases. + * + */ + +//#include +#include + +#include +#include "task.h" + +// MT793X SDK +#include + +#include +#include +#include +#include + + +extern "C" log_create_module(connsys, PRINT_LEVEL_WARNING); + + +#if CHIP_CONFIG_MEMORY_MGMT_PLATFORM + +extern "C" void memMonitoringTrackAlloc(void * ptr, size_t size); +extern "C" void memMonitoringTrackFree(void * ptr, size_t size); + +#ifndef trackAlloc +#define trackAlloc(pvAddress, uiSize) memMonitoringTrackAlloc(pvAddress, uiSize) +#endif +#ifndef trackFree +#define trackFree(pvAddress, uiSize) memMonitoringTrackFree(pvAddress, uiSize) +#endif + +namespace chip { +namespace Platform { + +#define VERIFY_INITIALIZED() VerifyInitialized(__func__) + +static std::atomic_int memoryInitialized{ 0 }; + +static void VerifyInitialized(const char * func) +{ + if (!memoryInitialized) + { + fprintf(stderr, "ABORT: chip::Platform::%s() called before chip::Platform::MemoryInit()\n", func); + abort(); + } +} + +CHIP_ERROR MemoryAllocatorInit(void * buf, size_t bufSize) +{ +#ifndef NDEBUG + if (memoryInitialized++ > 0) + { + fprintf(stderr, "ABORT: chip::Platform::MemoryInit() called twice.\n"); + abort(); + } +#endif + return CHIP_NO_ERROR; +} + +void MemoryAllocatorShutdown() +{ +#ifndef NDEBUG + if (--memoryInitialized < 0) + { + fprintf(stderr, "ABORT: chip::Platform::MemoryShutdown() called twice.\n"); + abort(); + } +#endif +} + +void * MemoryAlloc(size_t size) +{ + void * ptr; + VERIFY_INITIALIZED(); + ptr = pvPortMalloc(size); + trackAlloc(ptr, size); + return ptr; +} + +void * MemoryAlloc(size_t size, bool isLongTermAlloc) +{ + void * ptr; + VERIFY_INITIALIZED(); + ptr = pvPortMalloc(size); + trackAlloc(ptr, size); + return ptr; +} + +void * MemoryCalloc(size_t num, size_t size) +{ + VERIFY_INITIALIZED(); + + void * ptr = pvPortCalloc(num, size); + trackAlloc(ptr, size * num); + return ptr; +} + +void * MemoryRealloc(void * p, size_t size) +{ + VERIFY_INITIALIZED(); + + p = pvPortRealloc(p, size); + return p; +} + +void MemoryFree(void * p) +{ + VERIFY_INITIALIZED(); + trackFree(p, 0); + vPortFree(p); +} + +bool MemoryInternalCheckPointer(const void * p, size_t min_size) +{ + return (p != nullptr); +} + +} // namespace Platform +} // namespace chip + +extern "C" __WEAK void memMonitoringTrackAlloc(void * ptr, size_t size) {} +extern "C" __WEAK void memMonitoringTrackFree(void * ptr, size_t size) {} + +#endif // CHIP_CONFIG_MEMORY_MGMT_PLATFORM diff --git a/src/platform/mt793x/CHIPPlatformConfig.h b/src/platform/mt793x/CHIPPlatformConfig.h new file mode 100644 index 00000000000000..0fb1488378afc5 --- /dev/null +++ b/src/platform/mt793x/CHIPPlatformConfig.h @@ -0,0 +1,98 @@ +/* + * + * Copyright (c) 2020-2022 Project CHIP Authors + * Copyright (c) 2019 Google LLC. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Platform-specific configuration overrides for CHIP on + * MediaTek Genio platforms. + */ + +#pragma once + +#include + +// ==================== General Platform Adaptations ==================== + +#define CHIP_CONFIG_ABORT() abort() + +#define CHIP_CONFIG_PERSISTED_STORAGE_KEY_TYPE uint8_t +#define CHIP_CONFIG_PERSISTED_STORAGE_ENC_MSG_CNTR_ID 1 +#define CHIP_CONFIG_PERSISTED_STORAGE_MAX_KEY_LENGTH 2 + +#define CHIP_CONFIG_LIFETIIME_PERSISTED_COUNTER_KEY 0x01 +#define CHIP_CONFIG_PERSISTED_STORAGE_KEY_GLOBAL_MESSAGE_COUNTER 0x2 + +#define CHIP_CONFIG_TIME_ENABLE_CLIENT 1 +#define CHIP_CONFIG_TIME_ENABLE_SERVER 0 + +// ==================== Security Adaptations ==================== + +// ==================== General Configuration Overrides ==================== + +#ifndef CHIP_CONFIG_MAX_PEER_NODES +#define CHIP_CONFIG_MAX_PEER_NODES 16 +#endif // CHIP_CONFIG_MAX_PEER_NODES + +#ifndef CHIP_CONFIG_MAX_UNSOLICITED_MESSAGE_HANDLERS +#define CHIP_CONFIG_MAX_UNSOLICITED_MESSAGE_HANDLERS 8 +#endif // CHIP_CONFIG_MAX_UNSOLICITED_MESSAGE_HANDLERS + +#ifndef CHIP_CONFIG_MAX_EXCHANGE_CONTEXTS +#define CHIP_CONFIG_MAX_EXCHANGE_CONTEXTS 8 +#endif // CHIP_CONFIG_MAX_EXCHANGE_CONTEXTS + +#ifndef CHIP_CONFIG_MAX_ACTIVE_CHANNELS +#define CHIP_CONFIG_MAX_ACTIVE_CHANNELS 8 +#endif // CHIP_CONFIG_MAX_ACTIVE_CHANNELS + +#ifndef CHIP_CONFIG_MAX_CHANNEL_HANDLES +#define CHIP_CONFIG_MAX_CHANNEL_HANDLES 16 +#endif // CHIP_CONFIG_MAX_CHANNEL_HANDLES + +#ifndef CHIP_LOG_FILTERING +#define CHIP_LOG_FILTERING 0 +#endif // CHIP_LOG_FILTERING + +#ifndef CHIP_CONFIG_MAX_INTERFACES +#define CHIP_CONFIG_MAX_INTERFACES 4 +#endif // CHIP_CONFIG_MAX_INTERFACES + +#ifndef CHIP_CONFIG_MAX_LOCAL_ADDR_UDP_ENDPOINTS +#define CHIP_CONFIG_MAX_LOCAL_ADDR_UDP_ENDPOINTS 4 +#endif // CHIP_CONFIG_MAX_LOCAL_ADDR_UDP_ENDPOINTS + +/** + * @def CHIP_CONFIG_MAX_FABRICS + * + * @brief + * Maximum number of fabrics the device can participate in. Each fabric can + * provision the device with its unique operational credentials and manage + * its own access control lists. + */ +#ifndef CHIP_CONFIG_MAX_FABRICS +#define CHIP_CONFIG_MAX_FABRICS 5 // 4 fabrics + 1 for rotation slack +#endif + +// ==================== FreeRTOS Configuration Overrides ==================== +#ifndef CHIP_CONFIG_FREERTOS_USE_STATIC_TASK +#define CHIP_CONFIG_FREERTOS_USE_STATIC_TASK 1 +#endif + +#ifndef CHIP_CONFIG_FREERTOS_USE_STATIC_QUEUE +#define CHIP_CONFIG_FREERTOS_USE_STATIC_QUEUE 1 +#endif diff --git a/src/platform/mt793x/ConfigurationManagerImpl.cpp b/src/platform/mt793x/ConfigurationManagerImpl.cpp new file mode 100644 index 00000000000000..2d2dfa6641c027 --- /dev/null +++ b/src/platform/mt793x/ConfigurationManagerImpl.cpp @@ -0,0 +1,270 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2019 Nest Labs, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Provides an implementation of the Device LayerConfigurationManager + * object for MT793X platforms using the MT793X SDK. + */ + +/* this file behaves like a config.h, comes first */ +#include + +#include + +#include +#include +#include + +#if CHIP_DEVICE_CONFIG_ENABLE_WIFI_STATION +#ifdef MT793X_PORTING +#include "wfx_host_events.h" +#endif /* MT793X_PORTING */ +#endif +#include "stdio.h" + +namespace chip { +namespace DeviceLayer { + +using namespace ::chip::DeviceLayer::Internal; + +ConfigurationManagerImpl & ConfigurationManagerImpl::GetDefaultInstance() +{ + static ConfigurationManagerImpl sInstance; + return sInstance; +} + +CHIP_ERROR ConfigurationManagerImpl::Init() +{ + CHIP_ERROR err; + bool failSafeArmed; + + // Initialize the generic implementation base class. + err = Internal::GenericConfigurationManagerImpl::Init(); + SuccessOrExit(err); + // TODO: Initialize the global GroupKeyStore object here (#1626) + IncreaseBootCount(); + + // It is possible to configure the possible reset sources with RMU_ResetControl + // In this case, we keep Reset control at default setting +// rebootCause = RMU_ResetCauseGet(); +// RMU_ResetCauseClear(); + // If the fail-safe was armed when the device last shutdown, initiate a factory reset. + if (GetFailSafeArmed(failSafeArmed) == CHIP_NO_ERROR && failSafeArmed) + { + ChipLogProgress(DeviceLayer, "Detected fail-safe armed on reboot; initiating factory reset"); + InitiateFactoryReset(); + } + err = CHIP_NO_ERROR; + +exit: + return err; +} + +bool ConfigurationManagerImpl::CanFactoryReset() +{ + // TODO: query the application to determine if factory reset is allowed. + return true; +} + +void ConfigurationManagerImpl::InitiateFactoryReset() +{ + PlatformMgr().ScheduleWork(DoFactoryReset); +} + +CHIP_ERROR ConfigurationManagerImpl::GetRebootCount(uint32_t & rebootCount) +{ + return MT793XConfig::ReadConfigValue(MT793XConfig::kConfigKey_BootCount, rebootCount); +} + +CHIP_ERROR ConfigurationManagerImpl::IncreaseBootCount(void) +{ + uint32_t bootCount = 0; + if (MT793XConfig::ConfigValueExists(MT793XConfig::kConfigKey_BootCount)) + { + GetRebootCount(bootCount); + } + return MT793XConfig::WriteConfigValue(MT793XConfig::kConfigKey_BootCount, bootCount + 1); +} + +uint32_t ConfigurationManagerImpl::GetBootReason(void) +{ + // rebootCause is obtained at bootup. + BootReasonType matterBootCause; + matterBootCause = BootReasonType::kUnspecified; + return to_underlying(matterBootCause); +} + +CHIP_ERROR ConfigurationManagerImpl::GetTotalOperationalHours(uint32_t & totalOperationalHours) +{ + if (!MT793XConfig::ConfigValueExists(MT793XConfig::kConfigKey_TotalOperationalHours)) + { + totalOperationalHours = 0; + return CHIP_NO_ERROR; + } + + return MT793XConfig::ReadConfigValue(MT793XConfig::kConfigKey_TotalOperationalHours, totalOperationalHours); +} + +CHIP_ERROR ConfigurationManagerImpl::StoreTotalOperationalHours(uint32_t totalOperationalHours) +{ + return MT793XConfig::WriteConfigValue(MT793XConfig::kConfigKey_TotalOperationalHours, totalOperationalHours); +} + +CHIP_ERROR ConfigurationManagerImpl::ReadPersistedStorageValue(::chip::Platform::PersistedStorage::Key persistedStorageKey, + uint32_t & value) +{ + CHIP_ERROR err; + MT793XConfig::Key configKey{ MT793XConfig::kConfigNamespace_ChipCounters, (char*)&persistedStorageKey }; + + err = ReadConfigValue(configKey, value); + if (err == CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND) + { + err = CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND; + } + SuccessOrExit(err); + +exit: + return err; +} + +CHIP_ERROR ConfigurationManagerImpl::WritePersistedStorageValue(::chip::Platform::PersistedStorage::Key persistedStorageKey, + uint32_t value) +{ + CHIP_ERROR err; + MT793XConfig::Key configKey{ MT793XConfig::kConfigNamespace_ChipCounters, (char*)&persistedStorageKey }; + + err = WriteConfigValue(configKey, value); + { + err = CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND; + } + SuccessOrExit(err); + +exit: + return err; +} + +CHIP_ERROR ConfigurationManagerImpl::ReadConfigValue(Key key, bool & val) +{ + return MT793XConfig::ReadConfigValue(key, val); +} + +CHIP_ERROR ConfigurationManagerImpl::ReadConfigValue(Key key, uint32_t & val) +{ + return MT793XConfig::ReadConfigValue(key, val); +} + +CHIP_ERROR ConfigurationManagerImpl::ReadConfigValue(Key key, uint64_t & val) +{ + return MT793XConfig::ReadConfigValue(key, val); +} + +CHIP_ERROR ConfigurationManagerImpl::ReadConfigValueStr(Key key, char * buf, size_t bufSize, size_t & outLen) +{ + return MT793XConfig::ReadConfigValueStr(key, buf, bufSize, outLen); +} + +CHIP_ERROR ConfigurationManagerImpl::ReadConfigValueBin(Key key, uint8_t * buf, size_t bufSize, size_t & outLen) +{ + return MT793XConfig::ReadConfigValueBin(key, buf, bufSize, outLen); +} + +CHIP_ERROR ConfigurationManagerImpl::WriteConfigValue(Key key, bool val) +{ + return MT793XConfig::WriteConfigValue(key, val); +} + +CHIP_ERROR ConfigurationManagerImpl::WriteConfigValue(Key key, uint32_t val) +{ + return MT793XConfig::WriteConfigValue(key, val); +} + +CHIP_ERROR ConfigurationManagerImpl::WriteConfigValue(Key key, uint64_t val) +{ + return MT793XConfig::WriteConfigValue(key, val); +} + +CHIP_ERROR ConfigurationManagerImpl::WriteConfigValueStr(Key key, const char * str) +{ + return MT793XConfig::WriteConfigValueStr(key, str); +} + +CHIP_ERROR ConfigurationManagerImpl::WriteConfigValueStr(Key key, const char * str, size_t strLen) +{ + return MT793XConfig::WriteConfigValueStr(key, str, strLen); +} + +CHIP_ERROR ConfigurationManagerImpl::WriteConfigValueBin(Key key, const uint8_t * data, size_t dataLen) +{ + return MT793XConfig::WriteConfigValueBin(key, data, dataLen); +} + +void ConfigurationManagerImpl::RunConfigUnitTest(void) +{ + MT793XConfig::RunConfigUnitTest(); +} + +void ConfigurationManagerImpl::DoFactoryReset(intptr_t arg) +{ + CHIP_ERROR err; + + ChipLogProgress(DeviceLayer, "Performing factory reset"); + + err = MT793XConfig::FactoryResetConfig(); + if (err != CHIP_NO_ERROR) + { + ChipLogError(DeviceLayer, "FactoryResetConfig() failed: %s", chip::ErrorStr(err)); + } + +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD + + ChipLogProgress(DeviceLayer, "Clearing Thread provision"); + ThreadStackMgr().ErasePersistentInfo(); + +#endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD + +#if CHIP_KVS_AVAILABLE + PersistedStorage::KeyValueStoreMgrImpl().ErasePartition(); +#endif // CHIP_KVS_AVAILABLE + +#if CHIP_DEVICE_CONFIG_ENABLE_WIFI_STATION + ChipLogProgress(DeviceLayer, "Clearing WiFi provision"); +#ifdef MT793X_PORTING + wfx_clear_wifi_provision(); +#endif /* MT793X_PORTING */ +#endif // CHIP_DEVICE_CONFIG_ENABLE_WIFI_STATION + + // Restart the system. + ChipLogProgress(DeviceLayer, "System restarting"); + NVIC_SystemReset(); +} + +CHIP_ERROR ConfigurationManagerImpl::GetPrimaryWiFiMACAddress(uint8_t * buf) +{ + if (wifi_get_mac_addr_from_efuse(1, buf) < 0) + return CHIP_ERROR_INTERNAL; + return CHIP_NO_ERROR; +} + +ConfigurationManager & ConfigurationMgrImpl() +{ + return ConfigurationManagerImpl::GetDefaultInstance(); +} + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/mt793x/ConfigurationManagerImpl.h b/src/platform/mt793x/ConfigurationManagerImpl.h new file mode 100644 index 00000000000000..f599ad29e37710 --- /dev/null +++ b/src/platform/mt793x/ConfigurationManagerImpl.h @@ -0,0 +1,90 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2019 Nest Labs, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Provides an implementation of the Device LayerConfigurationManager + * object for MT793X platforms using the MT793X SDK. + */ + +#pragma once + +#include + +#include "MT793XConfig.h" + +namespace chip { +namespace DeviceLayer { + +/** + * Concrete implementation of the ConfigurationManager singleton object for the Genio platform. + */ +class ConfigurationManagerImpl : public Internal::GenericConfigurationManagerImpl +{ +public: + // This returns an instance of this class. + static ConfigurationManagerImpl & GetDefaultInstance(); + + uint32_t GetBootReason(void); + CHIP_ERROR GetRebootCount(uint32_t & rebootCount); + CHIP_ERROR IncreaseBootCount(void); + CHIP_ERROR GetTotalOperationalHours(uint32_t & totalOperationalHours); + CHIP_ERROR StoreTotalOperationalHours(uint32_t totalOperationalHours); + +private: + // ===== Members that implement the ConfigurationManager public interface. + + CHIP_ERROR Init(void) override; + CHIP_ERROR GetPrimaryWiFiMACAddress(uint8_t * buf) override; + bool CanFactoryReset(void) override; + void InitiateFactoryReset(void) override; + CHIP_ERROR ReadPersistedStorageValue(::chip::Platform::PersistedStorage::Key key, uint32_t & value) override; + CHIP_ERROR WritePersistedStorageValue(::chip::Platform::PersistedStorage::Key key, uint32_t value) override; + + // NOTE: Other public interface methods are implemented by GenericConfigurationManagerImpl<>. + + // ===== Members that implement the GenericConfigurationManagerImpl protected interface. + CHIP_ERROR ReadConfigValue(Key key, bool & val) override; + CHIP_ERROR ReadConfigValue(Key key, uint32_t & val) override; + CHIP_ERROR ReadConfigValue(Key key, uint64_t & val) override; + CHIP_ERROR ReadConfigValueStr(Key key, char * buf, size_t bufSize, size_t & outLen) override; + CHIP_ERROR ReadConfigValueBin(Key key, uint8_t * buf, size_t bufSize, size_t & outLen) override; + CHIP_ERROR WriteConfigValue(Key key, bool val) override; + CHIP_ERROR WriteConfigValue(Key key, uint32_t val) override; + CHIP_ERROR WriteConfigValue(Key key, uint64_t val) override; + CHIP_ERROR WriteConfigValueStr(Key key, const char * str) override; + CHIP_ERROR WriteConfigValueStr(Key key, const char * str, size_t strLen) override; + CHIP_ERROR WriteConfigValueBin(Key key, const uint8_t * data, size_t dataLen) override; + void RunConfigUnitTest(void) override; + + // ===== Private members reserved for use by this class only. + uint32_t rebootCause; + static void DoFactoryReset(intptr_t arg); +}; + +/** + * Returns the platform-specific implementation of the ConfigurationManager object. + * + * Applications can use this to gain access to features of the ConfigurationManager + * that are specific to the selected platform. + */ +ConfigurationManager & ConfigurationMgrImpl(); + +} // namespace DeviceLayer +} // namespace chip + diff --git a/src/platform/mt793x/ConnectivityManagerImpl.cpp b/src/platform/mt793x/ConnectivityManagerImpl.cpp new file mode 100644 index 00000000000000..27d13160cda7c4 --- /dev/null +++ b/src/platform/mt793x/ConnectivityManagerImpl.cpp @@ -0,0 +1,92 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2019 Nest Labs, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* this file behaves like a config.h, comes first */ +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#if INET_CONFIG_ENABLE_TCP_ENDPOINT +#include +#endif + +#if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE +#include +#endif + +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD +#include +#endif + +#include "mt7933_pos.h" +#include "filogic.h" + +using namespace ::chip; +using namespace ::chip::Inet; +using namespace ::chip::System; +using namespace ::chip::TLV; +using namespace ::chip::DeviceLayer::Internal; + +namespace chip { +namespace DeviceLayer { + +#if CHIP_DEVICE_CONFIG_ENABLE_WIFI +ConnectivityManagerImpl ConnectivityManagerImpl::sInstance; +#endif + +CHIP_ERROR ConnectivityManagerImpl::_Init() +{ + CHIP_ERROR err = CHIP_NO_ERROR; + + // Initialize the generic base classes that require it. +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD + GenericConnectivityManagerImpl_Thread::_Init(); +#endif +#if CHIP_DEVICE_CONFIG_ENABLE_WIFI + err = WiFiInit(); + SuccessOrExit(err); +#endif + +exit: + return err; +} + +void ConnectivityManagerImpl::_OnPlatformEvent(const ChipDeviceEvent * event) +{ + ChipLogProgress(DeviceLayer, "%s", __func__); + + // Forward the event to the generic base classes as needed. +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD + GenericConnectivityManagerImpl_Thread::_OnPlatformEvent(event); +#endif +#if CHIP_DEVICE_CONFIG_ENABLE_WIFI + _OnWiFiPlatformEvent(event); +#endif +} + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/mt793x/ConnectivityManagerImpl.h b/src/platform/mt793x/ConnectivityManagerImpl.h new file mode 100644 index 00000000000000..e036ea498c56ca --- /dev/null +++ b/src/platform/mt793x/ConnectivityManagerImpl.h @@ -0,0 +1,266 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2019 Nest Labs, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include +#include + +#if INET_CONFIG_ENABLE_TCP_ENDPOINT +#include +#endif + +#if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE +#include +#else +#include +#endif +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD +#include +#else +#include +#endif +#if CHIP_DEVICE_CONFIG_ENABLE_WIFI_STATION +#include +#else +#include +#endif + +#include "filogic.h" + + +namespace Inet { +class IPAddress; +} // namespace Inet + +namespace chip { +namespace DeviceLayer { + +//class PlatformManagerImpl; + +/** + * Concrete implementation of the ConnectivityManager singleton object for MediaTek Genio platforms. + */ +class ConnectivityManagerImpl final : public ConnectivityManager, + public Internal::GenericConnectivityManagerImpl, + public Internal::GenericConnectivityManagerImpl_UDP, +#if INET_CONFIG_ENABLE_TCP_ENDPOINT + public Internal::GenericConnectivityManagerImpl_TCP, +#endif +#if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE + public Internal::GenericConnectivityManagerImpl_BLE, +#else + public Internal::GenericConnectivityManagerImpl_NoBLE, +#endif +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD + public Internal::GenericConnectivityManagerImpl_Thread, +#else + public Internal::GenericConnectivityManagerImpl_NoThread, +#endif +#if CHIP_DEVICE_CONFIG_ENABLE_WIFI_STATION + public Internal::GenericConnectivityManagerImpl_WiFi +#else + public Internal::GenericConnectivityManagerImpl_NoWiFi +#endif +{ + // Allow the ConnectivityManager interface class to delegate method calls to + // the implementation methods provided by this class. + friend class ConnectivityManager; + +private: + // ===== Members that implement the ConnectivityManager abstract interface. + + bool _HaveIPv4InternetConnectivity(void); + bool _HaveIPv6InternetConnectivity(void); +#if 0 // CHIP_DEVICE_CONFIG_ENABLE_THREAD + bool _HaveServiceConnectivity(void); +#endif + CHIP_ERROR _Init(void); + void _OnPlatformEvent(const ChipDeviceEvent * event); + +#if CHIP_DEVICE_CONFIG_ENABLE_WIFI + CHIP_ERROR WiFiInit(void); + WiFiStationMode GetFilogicStationMode(void); + WiFiAPMode GetFilogicAPMode(void); + filogic_wifi_opmode_t GetFilogicNextOpMode(WiFiStationMode wifiStationMode, + WiFiAPMode wifiAPMode); + void SetFlogicNextMode(filogic_wifi_opmode_t nextMode); + void _OnWiFiPlatformEvent(const ChipDeviceEvent * event); +#endif + +#if CHIP_DEVICE_CONFIG_ENABLE_WIFI_STATION + using Flags = GenericConnectivityManagerImpl_WiFi::ConnectivityFlags; + WiFiStationMode _GetWiFiStationMode(void); + CHIP_ERROR _SetWiFiStationMode(WiFiStationMode val); + CHIP_ERROR _SetWiFiStationReconnectInterval(System::Clock::Timeout val); + CHIP_ERROR _GetAndLogWifiStatsCounters(void); + bool _IsWiFiStationEnabled(void); + bool _IsWiFiStationApplicationControlled(void); + bool _IsWiFiStationConnected(void); + bool _IsWiFiStationProvisioned(void); + void _ClearWiFiStationProvision(void); + bool _CanStartWiFiScan(); + void _OnWiFiScanDone(); + void _OnWiFiStationProvisionChange(); + System::Clock::Timeout _GetWiFiStationReconnectInterval(void); +#endif +#if CHIP_DEVICE_CONFIG_ENABLE_WIFI_AP + void ChangeWiFiAPState(WiFiAPState newState); + void DriveAPState(void); + CHIP_ERROR ConfigureWiFiAP(void); + static void DriveAPState(::chip::System::Layer * aLayer, + void * aAppState); + WiFiAPMode _GetWiFiAPMode(void); + CHIP_ERROR _SetWiFiAPMode(WiFiAPMode val); + bool _IsWiFiAPApplicationControlled(void); + bool _IsWiFiAPActive(void); + void _DemandStartWiFiAP(void); + void _StopOnDemandWiFiAP(void); + void _MaintainOnDemandWiFiAP(void); + System::Clock::Timeout _GetWiFiAPIdleTimeout(void); + void _SetWiFiAPIdleTimeout(System::Clock::Timeout val); +#endif + // ===== Members for internal use by the following friends. + + friend ConnectivityManager & ConnectivityMgr(void); + friend ConnectivityManagerImpl & ConnectivityMgrImpl(void); + +#if CHIP_DEVICE_CONFIG_ENABLE_WIFI + static ConnectivityManagerImpl sInstance; +#endif + + // ===== Private members reserved for use by this class only. +#if CHIP_DEVICE_CONFIG_ENABLE_WIFI_STATION + System::Clock::Timestamp mLastStationConnectFailTime; + WiFiStationMode mWiFiStationMode; + WiFiStationState mWiFiStationState; + System::Clock::Timeout mWiFiStationReconnectInterval; + BitFlags mFlags; + + void DriveStationState(void); + void OnStationConnected(void); + void OnStationDisconnected(void); + void ChangeWiFiStationState(WiFiStationState newState); + static void DriveStationState(::chip::System::Layer * aLayer, void * aAppState); + + void UpdateInternetConnectivityState(bool haveIPv4Conn, bool haveIPv6Conn, const uint8_t *ipAddr); +#endif +#if CHIP_DEVICE_CONFIG_ENABLE_WIFI_AP + WiFiAPMode mWiFiAPMode; + WiFiAPState mWiFiAPState; + System::Clock::Timeout mWiFiAPIdleTimeout; + System::Clock::Timestamp mLastAPDemandTime; +#endif + void *mFilogicCtx; +}; + +inline bool ConnectivityManagerImpl::_HaveIPv4InternetConnectivity(void) +{ +#if CHIP_DEVICE_CONFIG_ENABLE_WIFI_STATION + return mFlags.Has(Flags::kHaveIPv4InternetConnectivity); +#else + return false; +#endif +} + +inline bool ConnectivityManagerImpl::_HaveIPv6InternetConnectivity(void) +{ +#if CHIP_DEVICE_CONFIG_ENABLE_WIFI_STATION + return mFlags.Has(Flags::kHaveIPv6InternetConnectivity); +#else + return false; +#endif +} + +#if CHIP_DEVICE_CONFIG_ENABLE_WIFI_STATION +inline bool ConnectivityManagerImpl::_IsWiFiStationApplicationControlled(void) +{ + return mWiFiStationMode == kWiFiStationMode_ApplicationControlled; +} + +inline bool ConnectivityManagerImpl::_IsWiFiStationConnected(void) +{ + return mWiFiStationState == kWiFiStationState_Connected; +} + +inline System::Clock::Timeout ConnectivityManagerImpl::_GetWiFiStationReconnectInterval(void) +{ + return mWiFiStationReconnectInterval; +} + +inline bool ConnectivityManagerImpl::_CanStartWiFiScan() +{ + return mWiFiStationState != kWiFiStationState_Connecting; +} +#endif + +#if CHIP_DEVICE_CONFIG_ENABLE_WIFI_AP +inline ConnectivityManager::WiFiAPMode ConnectivityManagerImpl::_GetWiFiAPMode(void) +{ + return mWiFiAPMode; +} + +inline bool ConnectivityManagerImpl::_IsWiFiAPApplicationControlled(void) +{ + return mWiFiAPMode == kWiFiAPMode_ApplicationControlled; +} + +inline bool ConnectivityManagerImpl::_IsWiFiAPActive(void) +{ + return mWiFiAPState == kWiFiAPState_Active; +} + +inline System::Clock::Timeout ConnectivityManagerImpl::_GetWiFiAPIdleTimeout(void) +{ + return mWiFiAPIdleTimeout; +} +#endif + +#if 0 // CHIP_DEVICE_CONFIG_ENABLE_THREAD +inline bool ConnectivityManagerImpl::_HaveServiceConnectivity(void) +{ + return _HaveServiceConnectivityViaThread(); +} +#endif + +/** + * + * Returns the public interface of the ConnectivityManager singleton object. + * + * Chip applications should use this to access features of the ConnectivityManager object + * that are common to all platforms. + */ +inline ConnectivityManager & ConnectivityMgr(void) +{ + return ConnectivityManagerImpl::sInstance; +} + +/** + * Returns the platform-specific implementation of the ConnectivityManager singleton object. + * + * Chip applications can use this to gain access to features of the ConnectivityManager + * that are specific to the ESP32 platform. + */ +inline ConnectivityManagerImpl & ConnectivityMgrImpl(void) +{ + return ConnectivityManagerImpl::sInstance; +} + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/mt793x/ConnectivityManagerImpl_WIFI.cpp b/src/platform/mt793x/ConnectivityManagerImpl_WIFI.cpp new file mode 100644 index 00000000000000..6adf8be423a45d --- /dev/null +++ b/src/platform/mt793x/ConnectivityManagerImpl_WIFI.cpp @@ -0,0 +1,704 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2019 Nest Labs, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/* this file behaves like a config.h, comes first */ +#include + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE +#include +#endif + +#include "wifi_api_ex.h" +#include "mt7933_pos.h" + +using namespace ::chip; +using namespace ::chip::Inet; +using namespace ::chip::System; +using namespace ::chip::TLV; +using namespace ::chip::DeviceLayer::Internal; + +namespace chip { +namespace DeviceLayer { + +CHIP_ERROR ConnectivityManagerImpl::WiFiInit(void) +{ + CHIP_ERROR err = CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; + + ChipLogProgress(DeviceLayer, "ConnectivityManager Wi-Fi init"); + +#if CHIP_DEVICE_CONFIG_ENABLE_WIFI_STATION + // Queue work items to bootstrap the AP and station state machines once + // the Chip event loop is running. + mWiFiStationMode = kWiFiStationMode_Disabled; + mWiFiStationState = kWiFiStationState_NotConnected; + mLastStationConnectFailTime = System::Clock::kZero; + mWiFiStationReconnectInterval = System::Clock::Milliseconds32( + CHIP_DEVICE_CONFIG_WIFI_STATION_RECONNECT_INTERVAL); +#endif +#if CHIP_DEVICE_CONFIG_ENABLE_WIFI_AP + mWiFiAPMode = kWiFiAPMode_Disabled; + mWiFiAPState = kWiFiAPState_NotActive; + mWiFiAPIdleTimeout = System::Clock::Milliseconds32( + CHIP_DEVICE_CONFIG_WIFI_AP_IDLE_TIMEOUT); + mLastAPDemandTime = System::Clock::kZero; +#endif + mFlags.ClearAll(); + + mFilogicCtx = PlatformMgrImpl().mFilogicCtx; + + if (!IsWiFiStationProvisioned()) + { +#if CHIP_DEVICE_CONFIG_ENABLE_WIFI_AP + mWiFiAPMode = kWiFiAPMode_Enabled; + mWiFiAPState = kWiFiAPState_NotActive; + filogic_wifi_init_async(mFilogicCtx, FILOGIC_WIFI_OPMODE_AP); + err = CHIP_NO_ERROR; + SuccessOrExit(err); +#endif + } + else + { +#if CHIP_DEVICE_CONFIG_ENABLE_WIFI_STATION + mWiFiStationMode = kWiFiStationMode_Enabled; + mWiFiStationState = kWiFiStationState_NotConnected; + filogic_wifi_init_async(mFilogicCtx, FILOGIC_WIFI_OPMODE_STA); + err = CHIP_NO_ERROR; + SuccessOrExit(err); +#endif + } + + ChipLogProgress(DeviceLayer, "ConnectivityManager Wi-Fi init done"); + +exit: + return err; +} + +void ConnectivityManagerImpl::ChangeWiFiAPState(WiFiAPState newState) +{ + if (mWiFiAPState != newState) + { + ChipLogProgress(DeviceLayer, "WiFi AP state change: %s -> %s", WiFiAPStateToStr(mWiFiAPState), WiFiAPStateToStr(newState)); + mWiFiAPState = newState; + } +} + +void ConnectivityManagerImpl::_OnWiFiPlatformEvent(const ChipDeviceEvent * event) +{ + ChipLogProgress(DeviceLayer, "%s", __func__); + + if (event->Type != DeviceEventType::kMtkWiFiEvent) + return; + + ChipLogProgress(DeviceLayer, "%s WiFi event %s", __func__, + filogic_event_to_name(event->Platform.FilogicEvent.event)); + + const filogic_async_event_data *event_data; + bool hadIPv4Conn = mFlags.Has(ConnectivityFlags::kHaveIPv4InternetConnectivity); + bool hadIPv6Conn = mFlags.Has(ConnectivityFlags::kHaveIPv6InternetConnectivity); + + event_data = &event->Platform.MtkWiFiEvent.event_data; + + if (event_data->event_id == FILOGIC_WIFI_INIT_OK) + { + if (FILOGIC_WIFI_PORT_STA == event_data->u.wifi_init.port) + { + mWiFiStationState = kWiFiStationState_NotConnected; + DriveStationState(); + } else + if (FILOGIC_WIFI_PORT_AP == event_data->u.wifi_init.port) + { + ConfigureWiFiAP(); + ChangeWiFiAPState(kWiFiAPState_Activating); + } else + assert(0); + } else + if (event_data->event_id == FILOGIC_AP_START_OK) + { + ChangeWiFiAPState(kWiFiAPState_Active); + } else + if (event_data->event_id == FILOGIC_SET_OPMODE_OK) + { + if (event_data->u.wifi_opmode.opmode == WIFI_MODE_STA_ONLY) + ChangeWiFiStationState(kWiFiStationState_NotConnected); + else + if (event_data->u.wifi_opmode.opmode == WIFI_MODE_AP_ONLY) + ChangeWiFiAPState(kWiFiAPState_Active); + else + assert(0); + } else + if (event_data->event_id == FILOGIC_AP_STATION_CONNECTED) + { + MaintainOnDemandWiFiAP(); + } else + if (event_data->event_id == FILOGIC_AP_STATION_DISCONNECTED) + { + } else + if (event_data->event_id == FILOGIC_STA_DISCONNECTED_FROM_AP) + { + if (mWiFiStationState == kWiFiStationState_Connecting) + { + ChangeWiFiStationState(kWiFiStationState_Connecting_Failed); + } + DriveStationState(); + } else + if (!hadIPv4Conn && event_data->event_id == FILOGIC_STA_IPV4_ADDR_READY) + { + if (mWiFiStationState == kWiFiStationState_Connecting) + { + ChangeWiFiStationState(kWiFiStationState_Connecting_Succeeded); + } + + ChipLogProgress(DeviceLayer, "ip addr: %s", event_data->u.ipv4_str.addr); + DriveStationState(); + UpdateInternetConnectivityState(TRUE, FALSE, event_data->u.ipv4_str.addr); + } + if (!hadIPv6Conn && event_data->event_id == FILOGIC_STA_IPV6_ADDR_READY) + { + if (mWiFiStationState == kWiFiStationState_Connecting) + { + ChangeWiFiStationState(kWiFiStationState_Connecting_Succeeded); + } + + ChipLogProgress(DeviceLayer, "ipv6 addr: %s", event_data->u.ipv6_str.addr); + DriveStationState(); + UpdateInternetConnectivityState(FALSE, TRUE, event_data->u.ipv6_str.addr); + } + else + if (event->Platform.FilogicEvent.event == FILOGIC_STA_CONNECTED_TO_AP) + { + ChipLogProgress(DeviceLayer, "WIFI_EVENT_STA_CONNECTED"); + if (mWiFiStationState == kWiFiStationState_Connecting) + { + ChangeWiFiStationState(kWiFiStationState_Connecting_Succeeded); + } + DriveStationState(); + } +} + +#if CHIP_DEVICE_CONFIG_ENABLE_WIFI +ConnectivityManager::WiFiStationMode ConnectivityManagerImpl::GetFilogicStationMode(void) +{ +#if CHIP_DEVICE_CONFIG_ENABLE_WIFI_STATION + filogic_wifi_opmode_t opmode; + int32_t ret; + + filogic_wifi_opmode_get_sync(mFilogicCtx, &opmode); + + if (opmode == FILOGIC_WIFI_OPMODE_STA || opmode == FILOGIC_WIFI_OPMODE_DUAL) + return kWiFiStationMode_Enabled; +#endif + return kWiFiStationMode_Disabled; +} + +ConnectivityManager::WiFiAPMode ConnectivityManagerImpl::GetFilogicAPMode(void) +{ +#if CHIP_DEVICE_CONFIG_ENABLE_WIFI_AP + filogic_wifi_opmode_t opmode; + int32_t ret; + + filogic_wifi_opmode_get_sync(mFilogicCtx, &opmode); + + if (opmode == FILOGIC_WIFI_OPMODE_AP || opmode == FILOGIC_WIFI_OPMODE_DUAL) + return kWiFiAPMode_Enabled; +#endif + return kWiFiAPMode_Disabled; +} + +filogic_wifi_opmode_t ConnectivityManagerImpl::GetFilogicNextOpMode( + WiFiStationMode staMode, + WiFiAPMode apMode) +{ + bool sta, ap; + filogic_wifi_opmode_t opmode; + + ChipLogProgress(DeviceLayer, "%s %d %d", __func__, staMode, apMode); + + sta = staMode == kWiFiStationMode_Enabled; + ap = apMode == kWiFiAPMode_Enabled; + + if (sta && ap) + opmode = FILOGIC_WIFI_OPMODE_DUAL; + else if (ap) + opmode = FILOGIC_WIFI_OPMODE_AP; + else if (sta) + opmode = FILOGIC_WIFI_OPMODE_STA; + else + opmode = FILOGIC_WIFI_OPMODE_NONE; + + return opmode; +} + +void ConnectivityManagerImpl::SetFlogicNextMode(filogic_wifi_opmode_t nextMode) +{ + ChipLogProgress(DeviceLayer, "WiFi driver mode set %s", filogic_opmode_to_name(nextMode)); + filogic_wifi_opmode_set_async(mFilogicCtx, nextMode); +} +#endif + +#if CHIP_DEVICE_CONFIG_ENABLE_WIFI_STATION +ConnectivityManager::WiFiStationMode ConnectivityManagerImpl::_GetWiFiStationMode(void) +{ + if (mWiFiStationMode != kWiFiStationMode_ApplicationControlled) + { + filogic_wifi_opmode_t opmode; + + filogic_wifi_opmode_get_sync(mFilogicCtx, &opmode); + + if (opmode == FILOGIC_WIFI_OPMODE_AP) + mWiFiStationMode = kWiFiStationMode_Disabled; + else + mWiFiStationMode = kWiFiStationMode_Enabled; + } + return mWiFiStationMode; +} + +CHIP_ERROR ConnectivityManagerImpl::_SetWiFiStationMode(ConnectivityManager::WiFiStationMode val) +{ + ChipLogProgress(DeviceLayer, "%s", __func__); + + if (mWiFiStationMode != val) + { + ChipLogProgress(DeviceLayer, + "WiFi station mode change: %s -> %s", + WiFiStationModeToStr(mWiFiStationMode), + WiFiStationModeToStr(val)); + DeviceLayer::SystemLayer().ScheduleWork(DriveStationState, NULL); + mWiFiStationMode = val; + } + + return CHIP_NO_ERROR; +} + +CHIP_ERROR ConnectivityManagerImpl::_SetWiFiStationReconnectInterval(System::Clock::Timeout val) +{ + ChipLogProgress(DeviceLayer, "%s", __func__); + + mWiFiStationReconnectInterval = val; + return CHIP_NO_ERROR; +} + +CHIP_ERROR ConnectivityManagerImpl::_GetAndLogWifiStatsCounters(void) +{ + ChipLogProgress(DeviceLayer, "%s", __func__); + + return CHIP_ERROR_NOT_IMPLEMENTED; +} + +bool ConnectivityManagerImpl::_IsWiFiStationEnabled(void) +{ + return GetWiFiStationMode() == kWiFiStationMode_Enabled; +} + +bool ConnectivityManagerImpl::_IsWiFiStationProvisioned(void) +{ + filogic_wifi_sta_prov_t prov = {}; + + /* See if we have SSID */ + if (filogic_wifi_sta_prov_get_sync(mFilogicCtx, &prov)) + { + return prov.ssid[0] != '\0'; + } + + return false; +} + +void ConnectivityManagerImpl::_ClearWiFiStationProvision(void) +{ + ChipLogProgress(DeviceLayer, "%s", __func__); + + if (mWiFiStationMode != kWiFiStationMode_ApplicationControlled) + { +#ifdef MT793X_PORTING + wfx_clear_wifi_provision(); +#endif /* MT793X_PORTING */ + + DeviceLayer::SystemLayer().ScheduleWork(DriveStationState, NULL); + } +} + +void ConnectivityManagerImpl::_OnWiFiScanDone() +{ + // CHIP_ERROR_NOT_IMPLEMENTED +} + +void ConnectivityManagerImpl::_OnWiFiStationProvisionChange() +{ + ChipLogProgress(DeviceLayer, "%s", __func__); + + // Schedule a call to the DriveStationState method to adjust the station state as needed. + ChipLogProgress(DeviceLayer, "_ON WIFI PROVISION CHANGE"); + DeviceLayer::SystemLayer().ScheduleWork(DriveStationState, NULL); +} +#endif + +#if CHIP_DEVICE_CONFIG_ENABLE_WIFI_AP +void ConnectivityManagerImpl::DriveAPState(void) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + WiFiAPMode driverAPMode = GetFilogicAPMode(); + filogic_wifi_opmode_t nextMode; + + ChipLogProgress(DeviceLayer, "%s", __func__); + + if (mWiFiAPMode != driverAPMode) + { + nextMode = GetFilogicNextOpMode(mWiFiStationMode, driverAPMode); + ChipLogProgress(DeviceLayer, "WiFi Driver AP mode set: %d", nextMode); + SetFlogicNextMode(nextMode); + if (driverAPMode == kWiFiAPMode_Enabled) + { + } + // TODO wait driver event + } +} + +CHIP_ERROR ConnectivityManagerImpl::ConfigureWiFiAP(void) +{ + char ssid[32]; + int ssid_len; + + ChipLogProgress(DeviceLayer, "%s", __func__); + + CHIP_ERROR err = CHIP_NO_ERROR; + + // TODO, generate + uint16_t discriminator = 0x8888; + + ssid_len = snprintf(ssid, sizeof(ssid), "%s%03X-%04X-%04X", + CHIP_DEVICE_CONFIG_WIFI_AP_SSID_PREFIX, + discriminator, + CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID, CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID); + int8_t channel = CHIP_DEVICE_CONFIG_WIFI_AP_CHANNEL; + + filogic_wifi_ap_config_async(mFilogicCtx, channel, ssid, ssid_len); + + return err; +} + +void ConnectivityManagerImpl::DriveAPState(::chip::System::Layer * aLayer, void * aAppState) +{ + sInstance.DriveAPState(); +} + +CHIP_ERROR ConnectivityManagerImpl::_SetWiFiAPMode(WiFiAPMode val) +{ + ChipLogProgress(DeviceLayer, "%s", __func__); + + CHIP_ERROR err = CHIP_NO_ERROR; + + VerifyOrExit(val != kWiFiAPMode_NotSupported, err = CHIP_ERROR_INVALID_ARGUMENT); + + if (mWiFiAPMode != val) + { + ChipLogProgress(DeviceLayer, "WiFi AP mode change: %s -> %s", + WiFiAPModeToStr(mWiFiAPMode), WiFiAPModeToStr(val)); + } + + mWiFiAPMode = val; + +exit: + return err; +} + +void ConnectivityManagerImpl::_DemandStartWiFiAP(void) +{ + ChipLogProgress(DeviceLayer, "%s", __func__); + + if (mWiFiAPMode == kWiFiAPMode_OnDemand || + mWiFiAPMode == kWiFiAPMode_OnDemand_NoStationProvision) + { + mLastAPDemandTime = System::SystemClock().GetMonotonicTimestamp(); + DeviceLayer::SystemLayer().ScheduleWork(DriveAPState, NULL); + } +} + +void ConnectivityManagerImpl::_StopOnDemandWiFiAP(void) +{ + ChipLogProgress(DeviceLayer, "%s", __func__); + + if (mWiFiAPMode == kWiFiAPMode_OnDemand || + mWiFiAPMode == kWiFiAPMode_OnDemand_NoStationProvision) + { + mLastAPDemandTime = System::Clock::kZero; + DeviceLayer::SystemLayer().ScheduleWork(DriveAPState, NULL); + } +} + +void ConnectivityManagerImpl::_MaintainOnDemandWiFiAP(void) +{ + ChipLogProgress(DeviceLayer, "%s", __func__); + + if (mWiFiAPMode == kWiFiAPMode_OnDemand || + mWiFiAPMode == kWiFiAPMode_OnDemand_NoStationProvision) + { + if (mWiFiAPState == kWiFiAPState_Activating || + mWiFiAPState == kWiFiAPState_Active) + { + mLastAPDemandTime = System::SystemClock().GetMonotonicTimestamp(); + } + } +} + +void ConnectivityManagerImpl::_SetWiFiAPIdleTimeout(System::Clock::Timeout val) +{ + ChipLogProgress(DeviceLayer, "%s", __func__); + + mWiFiAPIdleTimeout = val; + DeviceLayer::SystemLayer().ScheduleWork(DriveAPState, NULL); +} +#endif /* CHIP_DEVICE_CONFIG_ENABLE_WIFI_AP */ + + +/**************************************************************************** + * ConnectivityManager Private Methods + ****************************************************************************/ + + +#if CHIP_DEVICE_CONFIG_ENABLE_WIFI_STATION +void ConnectivityManagerImpl::DriveStationState() +{ + ChipLogProgress(DeviceLayer, "%s", __func__); + + CHIP_ERROR err = CHIP_NO_ERROR; + int32_t status; + bool stationConnected; + + // Refresh the current station mode. + GetWiFiStationMode(); + + // If the station interface is NOT under application control... + if (mWiFiStationMode != kWiFiStationMode_ApplicationControlled) + { + if (mWiFiStationMode != kWiFiStationMode_Enabled) + { + ChipLogProgress(DeviceLayer, "WiFi station mode set"); + mWiFiStationState = kWiFiStationState_NotConnected; + SetFlogicNextMode(FILOGIC_WIFI_OPMODE_STA); + return; + } + } + + stationConnected = filogic_wifi_sta_get_link_status_sync(mFilogicCtx); + + // If the station interface is currently connected ... + if (stationConnected) + { + // Advance the station state to Connected if it was previously NotConnected or + // a previously initiated connect attempt succeeded. + if (mWiFiStationState == kWiFiStationState_NotConnected || + mWiFiStationState == kWiFiStationState_Connecting_Succeeded) + { + ChangeWiFiStationState(kWiFiStationState_Connected); + ChipLogProgress(DeviceLayer, "WiFi station interface connected"); + mLastStationConnectFailTime = System::Clock::kZero; + OnStationConnected(); + } + + // If the WiFi station interface is no longer enabled, or no longer provisioned, + // disconnect the station from the AP, unless the WiFi station mode is currently + // under application control. + if (mWiFiStationMode != kWiFiStationMode_ApplicationControlled && + (mWiFiStationMode != kWiFiStationMode_Enabled || !IsWiFiStationProvisioned())) + { + ChipLogProgress(DeviceLayer, "Disconnecting WiFi station interface"); + + status = wifi_connection_disconnect_ap(); + if (status < 0) + { + ChipLogError(DeviceLayer, "WiFi disconnect : FAIL: %ld", status); + } + + ChangeWiFiStationState(kWiFiStationState_Disconnecting); + } + } + // Otherwise the station interface is NOT connected to an AP, so... + else + { + System::Clock::Timestamp now = System::SystemClock().GetMonotonicTimestamp(); + + // Advance the station state to NotConnected if it was previously Connected or Disconnecting, + // or if a previous initiated connect attempt failed. + if (mWiFiStationState == kWiFiStationState_Connected || + mWiFiStationState == kWiFiStationState_Disconnecting || + mWiFiStationState == kWiFiStationState_Connecting_Failed) + { + WiFiStationState prevState = mWiFiStationState; + ChangeWiFiStationState(kWiFiStationState_NotConnected); + if (prevState != kWiFiStationState_Connecting_Failed) + { + ChipLogProgress(DeviceLayer, "WiFi station interface disconnected"); + mLastStationConnectFailTime = System::Clock::kZero; + OnStationDisconnected(); + } + else + { + mLastStationConnectFailTime = now; + } + } + + // If the WiFi station interface is now enabled and provisioned (and by implication, + // not presently under application control), AND the system is not in the process of + // scanning, then... + if (mWiFiStationMode == kWiFiStationMode_Enabled && IsWiFiStationProvisioned()) + { + // Initiate a connection to the AP if we haven't done so before, or if enough + // time has passed since the last attempt. + if (mLastStationConnectFailTime == System::Clock::kZero || + now >= mLastStationConnectFailTime + mWiFiStationReconnectInterval) + { + if (mWiFiStationState != kWiFiStationState_Connecting) + { + ChipLogProgress(DeviceLayer, "Attempting to connect WiFi"); + + status = wifi_config_reload_setting(); + + if (status < 0) + { + ChipLogError(DeviceLayer, "WiFi start connect : FAIL %ld", status); + goto exit; + } + + ChangeWiFiStationState(kWiFiStationState_Connecting); + } + } + // Otherwise arrange another connection attempt at a suitable point in the future. + else + { + System::Clock::Timestamp timeToNextConnect = (mLastStationConnectFailTime + mWiFiStationReconnectInterval) - now; + + ChipLogProgress(DeviceLayer, "Next WiFi station reconnect in %" PRIu32 " ms", + System::Clock::Milliseconds32(timeToNextConnect).count()); + + ReturnOnFailure(DeviceLayer::SystemLayer().StartTimer(timeToNextConnect, DriveStationState, NULL)); + } + } + } + +exit: + + ChipLogProgress(DeviceLayer, "Done driving station state, nothing else to do..."); +} + +void ConnectivityManagerImpl::OnStationConnected() +{ + ChipLogProgress(DeviceLayer, "%s", __func__); + + ChipDeviceEvent event; + + NetworkCommissioning::GenioWiFiDriver::GetInstance().OnConnectWiFiNetwork(); + + // Alert other components of the new state. + event.Type = DeviceEventType::kWiFiConnectivityChange; + event.WiFiConnectivityChange.Result = kConnectivity_Established; + (void) PlatformMgr().PostEvent(&event); + + UpdateInternetConnectivityState(FALSE, FALSE, NULL); +} + +void ConnectivityManagerImpl::OnStationDisconnected() +{ + ChipLogProgress(DeviceLayer, "%s", __func__); + + // TODO Invoke WARM to perform actions that occur when the WiFi station interface goes down. + + // Alert other components of the new state. + ChipDeviceEvent event; + event.Type = DeviceEventType::kWiFiConnectivityChange; + event.WiFiConnectivityChange.Result = kConnectivity_Lost; + (void) PlatformMgr().PostEvent(&event); + + UpdateInternetConnectivityState(FALSE, FALSE, NULL); +} + +void ConnectivityManagerImpl::DriveStationState(::chip::System::Layer * aLayer, void * aAppState) +{ + ChipLogProgress(DeviceLayer, "%s", __func__); + + sInstance.DriveStationState(); +} + +void ConnectivityManagerImpl::ChangeWiFiStationState(WiFiStationState newState) +{ + ChipLogProgress(DeviceLayer, "%s", __func__); + + if (mWiFiStationState != newState) + { + ChipLogProgress(DeviceLayer, "WiFi station state change: %s -> %s", + WiFiStationStateToStr(mWiFiStationState), + WiFiStationStateToStr(newState)); + mWiFiStationState = newState; + } +} + +void ConnectivityManagerImpl::UpdateInternetConnectivityState(bool haveIPv4Conn, bool haveIPv6Conn, const uint8_t *ipAddr) +{ + ChipLogProgress(DeviceLayer, "%s", __func__); + + bool hadIPv4Conn = mFlags.Has(ConnectivityFlags::kHaveIPv4InternetConnectivity); + bool hadIPv6Conn = mFlags.Has(ConnectivityFlags::kHaveIPv6InternetConnectivity); + IPAddress addr; + + // If the WiFi station is currently in the connected state... + if (mWiFiStationState == kWiFiStationState_Connected) + { + IPAddress::FromString((char *)ipAddr, addr); + } + + // If the internet connectivity state has changed... + if (haveIPv4Conn != hadIPv4Conn || haveIPv6Conn != hadIPv6Conn) + { + // Update the current state. + mFlags.Set(ConnectivityFlags::kHaveIPv4InternetConnectivity, haveIPv4Conn) + .Set(ConnectivityFlags::kHaveIPv6InternetConnectivity, haveIPv6Conn); + + // Alert other components of the state change. + ChipDeviceEvent event; + event.Type = DeviceEventType::kInternetConnectivityChange; + event.InternetConnectivityChange.IPv4 = GetConnectivityChange(hadIPv4Conn, haveIPv4Conn); + event.InternetConnectivityChange.IPv6 = GetConnectivityChange(hadIPv6Conn, haveIPv6Conn); + event.InternetConnectivityChange.ipAddress = addr; + + (void) PlatformMgr().PostEvent(&event); + + if (haveIPv4Conn != hadIPv4Conn) + { + ChipLogProgress(DeviceLayer, "%s Internet connectivity %s", "IPv4", (haveIPv4Conn) ? "ESTABLISHED" : "LOST"); + } + + if (haveIPv6Conn != hadIPv6Conn) + { + ChipLogProgress(DeviceLayer, "%s Internet connectivity %s", "IPv6", (haveIPv6Conn) ? "ESTABLISHED" : "LOST"); + } + } +} +#endif + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/mt793x/DeviceNetworkProvisioningDelegateImpl.cpp b/src/platform/mt793x/DeviceNetworkProvisioningDelegateImpl.cpp new file mode 100644 index 00000000000000..fb3f9fb4317802 --- /dev/null +++ b/src/platform/mt793x/DeviceNetworkProvisioningDelegateImpl.cpp @@ -0,0 +1,65 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "DeviceNetworkProvisioningDelegateImpl.h" +#include "NetworkCommissioningWiFiDriver.h" +#include +#include + +#if CHIP_ENABLE_OPENTHREAD +#include +#endif + +namespace chip { +namespace DeviceLayer { + +CHIP_ERROR +DeviceNetworkProvisioningDelegateImpl::_ProvisionThreadNetwork(ByteSpan threadData) +{ +#if CHIP_ENABLE_OPENTHREAD + CHIP_ERROR error = CHIP_NO_ERROR; + + SuccessOrExit(error = ThreadStackMgr().SetThreadEnabled(false)); + SuccessOrExit(error = ThreadStackMgr().SetThreadProvision(threadData)); + SuccessOrExit(error = ThreadStackMgr().SetThreadEnabled(true)); +exit: + return error; +#else + return CHIP_ERROR_NOT_IMPLEMENTED; +#endif // CHIP_ENABLE_OPENTHREAD +} + +#if CHIP_DEVICE_CONFIG_ENABLE_WIFI_STATION +CHIP_ERROR DeviceNetworkProvisioningDelegateImpl::_ProvisionWiFiNetwork(const char * ssid, const char * key) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + + ChipLogProgress(NetworkProvisioning, "MT793x Wifi provision: SSID: %s", ssid); + err = NetworkCommissioning::GenioWiFiDriver::GetInstance().ConnectWiFiNetwork( + ssid, strlen(ssid), key, strlen(key)); + if (err != CHIP_NO_ERROR) + { + ChipLogError(NetworkProvisioning, "MT793x:WiFi:Provision network: %s", + chip::ErrorStr(err)); + } + + return err; +} +#endif + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/mt793x/DeviceNetworkProvisioningDelegateImpl.h b/src/platform/mt793x/DeviceNetworkProvisioningDelegateImpl.h new file mode 100644 index 00000000000000..6eb53530c0c8d1 --- /dev/null +++ b/src/platform/mt793x/DeviceNetworkProvisioningDelegateImpl.h @@ -0,0 +1,47 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +namespace chip { +namespace DeviceLayer { + +namespace Internal { + +template +class GenericDeviceNetworkProvisioningDelegateImpl; + +} // namespace Internal + +class DeviceNetworkProvisioningDelegateImpl final + : public Internal::GenericDeviceNetworkProvisioningDelegateImpl +{ + friend class GenericDeviceNetworkProvisioningDelegateImpl; + +private: +#if CHIP_DEVICE_CONFIG_ENABLE_WIFI_STATION + CHIP_ERROR _ProvisionWiFiNetwork(const char * ssid, const char * passwd); +#else + CHIP_ERROR _ProvisionWiFiNetwork(const char * ssid, const char * passwd) { return CHIP_ERROR_NOT_IMPLEMENTED; } +#endif + CHIP_ERROR _ProvisionThreadNetwork(ByteSpan threadData); +}; + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/mt793x/DiagnosticDataProviderImpl.cpp b/src/platform/mt793x/DiagnosticDataProviderImpl.cpp new file mode 100644 index 00000000000000..0fa3cfc9b49db8 --- /dev/null +++ b/src/platform/mt793x/DiagnosticDataProviderImpl.cpp @@ -0,0 +1,241 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Provides an implementation of the DiagnosticDataProvider object + * for Genio platform. + */ + +#include + +#include +#include +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD +#include +#endif +#include + +//#include "AppConfig.h" +#include "FreeRTOS.h" + +using namespace ::chip::app::Clusters::GeneralDiagnostics; + +namespace chip { +namespace DeviceLayer { + +DiagnosticDataProviderImpl & DiagnosticDataProviderImpl::GetDefaultInstance() +{ + static DiagnosticDataProviderImpl sInstance; + return sInstance; +} + +// Software Diagnostics Getters +/* + * The following Heap stats keeps track of the number of calls to allocate + * and free memory as well as the number of free bytes remaining, but says + * nothing about fragmentation. + */ +CHIP_ERROR DiagnosticDataProviderImpl::GetCurrentHeapFree(uint64_t & currentHeapFree) +{ + size_t freeHeapSize = xPortGetFreeHeapSize(); + currentHeapFree = static_cast(freeHeapSize); + return CHIP_NO_ERROR; +} + +CHIP_ERROR DiagnosticDataProviderImpl::GetCurrentHeapUsed(uint64_t & currentHeapUsed) +{ + // Calculate the Heap used based on Total heap - Free heap + int64_t heapUsed = (configTOTAL_HEAP_SIZE - xPortGetFreeHeapSize()); + + // Something went wrong, this should not happen + VerifyOrReturnError(heapUsed >= 0, CHIP_ERROR_INVALID_INTEGER_VALUE); + currentHeapUsed = static_cast(heapUsed); + return CHIP_NO_ERROR; +} + +CHIP_ERROR DiagnosticDataProviderImpl::GetCurrentHeapHighWatermark(uint64_t & currentHeapHighWatermark) +{ + // FreeRTOS records the lowest amount of available heap during runtime + // currentHeapHighWatermark wants the highest heap usage point so we calculate it here + int64_t HighestHeapUsageRecorded = (configTOTAL_HEAP_SIZE - xPortGetMinimumEverFreeHeapSize()); + + // Something went wrong, this should not happen + VerifyOrReturnError(HighestHeapUsageRecorded >= 0, CHIP_ERROR_INVALID_INTEGER_VALUE); + currentHeapHighWatermark = static_cast(HighestHeapUsageRecorded); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR DiagnosticDataProviderImpl::ResetWatermarks() +{ + // If implemented, the server SHALL set the value of the CurrentHeapHighWatermark attribute to the + // value of the CurrentHeapUsed. + + return CHIP_NO_ERROR; +} + +CHIP_ERROR DiagnosticDataProviderImpl::GetThreadMetrics(ThreadMetrics ** threadMetricsOut) +{ + *threadMetricsOut = NULL; + return CHIP_NO_ERROR; +} + +void DiagnosticDataProviderImpl::ReleaseThreadMetrics(ThreadMetrics * threadMetrics) +{ + while (threadMetrics) + { + ThreadMetrics * del = threadMetrics; + threadMetrics = threadMetrics->Next; + delete del; + } +} + +// General Diagnostics Getters + +CHIP_ERROR DiagnosticDataProviderImpl::GetRebootCount(uint16_t & rebootCount) +{ + uint32_t count = 0; + CHIP_ERROR err = ConfigurationMgr().GetRebootCount(count); + + if (err == CHIP_NO_ERROR) + { + VerifyOrReturnError(count <= UINT16_MAX, CHIP_ERROR_INVALID_INTEGER_VALUE); + rebootCount = static_cast(count); + } + + return err; +} + +CHIP_ERROR DiagnosticDataProviderImpl::GetBootReason(BootReasonType & bootReason) +{ + uint32_t reason = 0; + CHIP_ERROR err = ConfigurationMgr().GetBootReason(reason); + + if (err == CHIP_NO_ERROR) + { + VerifyOrReturnError(reason <= UINT8_MAX, CHIP_ERROR_INVALID_INTEGER_VALUE); + bootReason = static_cast(reason); + } + + return err; +} + +CHIP_ERROR DiagnosticDataProviderImpl::GetUpTime(uint64_t & upTime) +{ + System::Clock::Timestamp currentTime = System::SystemClock().GetMonotonicTimestamp(); + System::Clock::Timestamp startTime = PlatformMgrImpl().GetStartTime(); + + if (currentTime >= startTime) + { + upTime = std::chrono::duration_cast(currentTime - startTime).count(); + return CHIP_NO_ERROR; + } + + return CHIP_ERROR_INVALID_TIME; +} + +CHIP_ERROR DiagnosticDataProviderImpl::GetTotalOperationalHours(uint32_t & totalOperationalHours) +{ + uint64_t upTime = 0; + + if (GetUpTime(upTime) == CHIP_NO_ERROR) + { + uint32_t totalHours = 0; + if (ConfigurationMgr().GetTotalOperationalHours(totalHours) == CHIP_NO_ERROR) + { + VerifyOrReturnError(upTime / 3600 <= UINT32_MAX, CHIP_ERROR_INVALID_INTEGER_VALUE); + totalOperationalHours = totalHours + static_cast(upTime / 3600); + return CHIP_NO_ERROR; + } + } + + return CHIP_ERROR_INVALID_TIME; +} + +CHIP_ERROR DiagnosticDataProviderImpl::GetActiveHardwareFaults(GeneralFaults & hardwareFaults) +{ +#if CHIP_CONFIG_TEST + ReturnErrorOnFailure(hardwareFaults.add(EMBER_ZCL_HARDWARE_FAULT_TYPE_RADIO)); + ReturnErrorOnFailure(hardwareFaults.add(EMBER_ZCL_HARDWARE_FAULT_TYPE_SENSOR)); + ReturnErrorOnFailure(hardwareFaults.add(EMBER_ZCL_HARDWARE_FAULT_TYPE_POWER_SOURCE)); + ReturnErrorOnFailure(hardwareFaults.add(EMBER_ZCL_HARDWARE_FAULT_TYPE_USER_INTERFACE_FAULT)); +#endif + + return CHIP_NO_ERROR; +} + +CHIP_ERROR DiagnosticDataProviderImpl::GetActiveRadioFaults(GeneralFaults & radioFaults) +{ +#if CHIP_CONFIG_TEST + ReturnErrorOnFailure(radioFaults.add(EMBER_ZCL_RADIO_FAULT_TYPE_THREAD_FAULT)); + ReturnErrorOnFailure(radioFaults.add(EMBER_ZCL_RADIO_FAULT_TYPE_BLE_FAULT)); +#endif + + return CHIP_NO_ERROR; +} + +CHIP_ERROR DiagnosticDataProviderImpl::GetActiveNetworkFaults(GeneralFaults & networkFaults) +{ +#if CHIP_CONFIG_TEST + ReturnErrorOnFailure(networkFaults.add(EMBER_ZCL_NETWORK_FAULT_TYPE_HARDWARE_FAILURE)); + ReturnErrorOnFailure(networkFaults.add(EMBER_ZCL_NETWORK_FAULT_TYPE_NETWORK_JAMMED)); + ReturnErrorOnFailure(networkFaults.add(EMBER_ZCL_NETWORK_FAULT_TYPE_CONNECTION_FAILED)); +#endif + + return CHIP_NO_ERROR; +} + +CHIP_ERROR DiagnosticDataProviderImpl::GetNetworkInterfaces(NetworkInterface ** netifpp) +{ + NetworkInterface * ifp = new NetworkInterface(); + +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD + const char * threadNetworkName = otThreadGetNetworkName(ThreadStackMgrImpl().OTInstance()); + ifp->name = Span(threadNetworkName, strlen(threadNetworkName)); + ifp->fabricConnected = true; + ifp->offPremiseServicesReachableIPv4.SetNonNull(false); + ifp->offPremiseServicesReachableIPv6.SetNonNull(false); + ifp->type = InterfaceType::EMBER_ZCL_INTERFACE_TYPE_THREAD; +#else + /* TODO */ +#endif + uint8_t macBuffer[ConfigurationManager::kPrimaryMACAddressLength]; + ConfigurationMgr().GetPrimary802154MACAddress(macBuffer); + ifp->hardwareAddress = ByteSpan(macBuffer, ConfigurationManager::kPrimaryMACAddressLength); + + *netifpp = ifp; + return CHIP_NO_ERROR; +} + +void DiagnosticDataProviderImpl::ReleaseNetworkInterfaces(NetworkInterface * netifp) +{ + while (netifp) + { + NetworkInterface * del = netifp; + netifp = netifp->Next; + delete del; + } +} + +DiagnosticDataProvider & GetDiagnosticDataProviderImpl() +{ + return DiagnosticDataProviderImpl::GetDefaultInstance(); +} + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/mt793x/DiagnosticDataProviderImpl.h b/src/platform/mt793x/DiagnosticDataProviderImpl.h new file mode 100644 index 00000000000000..c28607cb304256 --- /dev/null +++ b/src/platform/mt793x/DiagnosticDataProviderImpl.h @@ -0,0 +1,69 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Provides an implementation of the DiagnosticDataProvider object. + */ + +#pragma once + +#include + +#include + +namespace chip { +namespace DeviceLayer { + +/** + * Concrete implementation of the PlatformManager singleton object for Linux platforms. + */ +class DiagnosticDataProviderImpl : public DiagnosticDataProvider +{ +public: + static DiagnosticDataProviderImpl & GetDefaultInstance(); + + // ===== Methods that implement the PlatformManager abstract interface. + + bool SupportsWatermarks() override { return false; } + CHIP_ERROR GetCurrentHeapFree(uint64_t & currentHeapFree) override; + CHIP_ERROR GetCurrentHeapUsed(uint64_t & currentHeapUsed) override; + CHIP_ERROR GetCurrentHeapHighWatermark(uint64_t & currentHeapHighWatermark) override; + CHIP_ERROR ResetWatermarks() override; + CHIP_ERROR GetThreadMetrics(ThreadMetrics ** threadMetricsOut) override; + void ReleaseThreadMetrics(ThreadMetrics * threadMetrics) override; + CHIP_ERROR GetRebootCount(uint16_t & rebootCount) override; + CHIP_ERROR GetBootReason(BootReasonType & bootReason) override; + CHIP_ERROR GetUpTime(uint64_t & upTime) override; + CHIP_ERROR GetTotalOperationalHours(uint32_t & totalOperationalHours) override; + CHIP_ERROR GetActiveHardwareFaults(GeneralFaults & hardwareFaults) override; + CHIP_ERROR GetActiveRadioFaults(GeneralFaults & radioFaults) override; + CHIP_ERROR GetActiveNetworkFaults(GeneralFaults & networkFaults) override; + CHIP_ERROR GetNetworkInterfaces(NetworkInterface ** netifpp) override; + void ReleaseNetworkInterfaces(NetworkInterface * netifp) override; +}; + +/** + * Returns the platform-specific implementation of the DiagnosticDataProvider singleton object. + * + * Applications can use this to gain access to features of the DiagnosticDataProvider + * that are specific to the selected platform. + */ +DiagnosticDataProvider & GetDiagnosticDataProviderImpl(); + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/mt793x/DnssdImpl.cpp b/src/platform/mt793x/DnssdImpl.cpp new file mode 100644 index 00000000000000..37e58f9b334bac --- /dev/null +++ b/src/platform/mt793x/DnssdImpl.cpp @@ -0,0 +1,293 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "lib/dnssd/platform/Dnssd.h" + +#include +#include +#include "lwip/mld6.h" +#include "mdns.h" +#include "dns_sd.h" + +#include "platform/CHIPDeviceLayer.h" +#include +#include +#include + +extern "C" { +extern void mDNSPlatformWriteLogRedirect( void ( * )( const char *, const char * ) ); +} + +namespace { + +static constexpr uint32_t kTimeoutMilli = 3000; +static constexpr size_t kMaxResults = 20; + +} // namespace + +namespace chip { +namespace Dnssd { + +#define SERVICE_DOMAIN ("local") + +static DNSServiceRef client = NULL; +static TXTRecordRef PublishTxtRecord; + +void ChipDnssdMdnsLog(const char *level, const char *msg) +{ + ChipLogProgress(ServiceProvisioning, "%s %s", level, msg); +} + +/** + * @brief mDNS Daemon Task entry + * @param[in] void *not_used:Not used + * @return None + */ +static void mdnsd_entry(void *not_used) +{ + ChipLogProgress(ServiceProvisioning, "mdnsd_entry start"); + mdnsd_start(); + ChipLogProgress(ServiceProvisioning, "mdnsd_entry return"); + client = NULL; + vTaskDelete(NULL); +} + +CHIP_ERROR ChipDnssdInit(DnssdAsyncReturnCallback initCallback, DnssdAsyncReturnCallback errorCallback, void * context) +{ + CHIP_ERROR error = CHIP_NO_ERROR; +#if LWIP_IPV6 + struct netif *sta_if = netif_default; + ip6_addr_t mld_address; +#endif + +#if LWIP_IPV6 + sta_if->ip6_autoconfig_enabled = 1; + ip6_addr_set_solicitednode(&mld_address, netif_ip6_addr(sta_if, 0)->addr[3]); + mld6_joingroup(netif_ip6_addr(sta_if, 0), &mld_address); +#endif + + ChipLogProgress(ServiceProvisioning, "create mdnsd_task"); + + mDNSPlatformWriteLogRedirect(ChipDnssdMdnsLog); + +#if 0 + #define MDNS_STACK_SIZE ( ( 64 * 1024 ) / sizeof( portSTACK_TYPE ) ) + static StackType_t xMDnsStack[ MDNS_STACK_SIZE ]; + static StaticTask_t xMDnsTask; + + // xTaskHandle create mDNS daemon task + if ( NULL != xTaskCreateStatic( mdnsd_entry, + "mdnsd", + MDNS_STACK_SIZE, + NULL, + TASK_PRIORITY_NORMAL, + &xMDnsStack[0], + &xMDnsTask ) ) +#else + // xTaskHandle create mDNS daemon task + if (pdPASS != xTaskCreate(mdnsd_entry, + "mdnsd", + (15 * 1024) / sizeof(portSTACK_TYPE), + NULL, + TASK_PRIORITY_NORMAL, + NULL)) +#endif + { + ChipLogProgress(ServiceProvisioning, "Cannot create mdnsd_task"); + error = CHIP_ERROR_INTERNAL; + } + + initCallback(context, error); + + return error; +} + +void ChipDnssdShutdown(void) +{ + ChipLogProgress(ServiceProvisioning, "shutdown mdnsd_task not implemented"); +} + +static const char * GetProtocolString(DnssdServiceProtocol protocol) +{ + return protocol == DnssdServiceProtocol::kDnssdProtocolTcp ? "_tcp" : "_udp"; +} + +CHIP_ERROR ChipDnssdPublishService(const DnssdService * service, DnssdPublishCallback callback, void * context) +{ + CHIP_ERROR error = CHIP_NO_ERROR; + DNSServiceErrorType err; + DNSServiceFlags flags = 0; + char ServiceType[kDnssdTypeMaxSize + 10] = {0}; + + (void)callback; + (void)context; + + ChipLogProgress(ServiceProvisioning, "ChipDnssdPublishService"); + + VerifyOrExit(service->mTextEntrySize <= UINT8_MAX, error = CHIP_ERROR_INVALID_ARGUMENT); + if (service->mTextEntries) + { + // Create TXT Record + TXTRecordCreate(&PublishTxtRecord, 0, NULL); + for (size_t i = 0; i < service->mTextEntrySize; i++) + { + err = TXTRecordSetValue(&PublishTxtRecord, service->mTextEntries[i].mKey, service->mTextEntries[i].mDataSize, service->mTextEntries[i].mData); + VerifyOrExit(err == 0, error = CHIP_ERROR_INTERNAL); + } + } + + strcpy(ServiceType, service->mType); + strcat(ServiceType, "."); + strcat(ServiceType, GetProtocolString(service->mProtocol)); + + ChipLogProgress(ServiceProvisioning, "ServiceName: %s", service->mName); + ChipLogProgress(ServiceProvisioning, "ServiceType: %s", ServiceType); + ChipLogProgress(ServiceProvisioning, "ServiceDomain: %s", SERVICE_DOMAIN); + ChipLogProgress(ServiceProvisioning, "Hostname: %s", service->mHostName); + ChipLogProgress(ServiceProvisioning, "ServicePort: %d", (int)service->mPort); + + ChipLogProgress(ServiceProvisioning, "ChipDnssdPublishService - DNSServiceRegister"); + + // Register Bonjour Service + err = DNSServiceRegister(&client, // DNSServiceRef + flags, // DNSServiceFlags + kDNSServiceInterfaceIndexAny, // interface index + service->mName, // service name + ServiceType, // service type + SERVICE_DOMAIN, // domain + NULL, // host + //service->mHostName, // host + htons(service->mPort), // port + TXTRecordGetLength(&PublishTxtRecord), // txt record length + TXTRecordGetBytesPtr(&PublishTxtRecord), // txt record pointer + NULL, // callback + NULL); // context + VerifyOrExit(err == 0, error = CHIP_ERROR_INTERNAL); + +exit: + // if (items != nullptr) + // { + // chip::Platform::MemoryFree(items); + // } + + return error; +} + +CHIP_ERROR ChipDnssdRemoveServices() +{ + // return mdns_service_remove_all() == ESP_OK ? CHIP_NO_ERROR : CHIP_ERROR_INTERNAL; + ChipLogProgress(ServiceProvisioning, "ChipDnssdRemoveServices"); + TXTRecordDeallocate(&PublishTxtRecord); + DNSServiceRefDeallocate(client); + return CHIP_NO_ERROR; +} + +CHIP_ERROR ChipDnssdFinalizeServiceUpdate() +{ + return CHIP_NO_ERROR; +} + +static DNSServiceRef BrowseClient = NULL; + +void ChipDNSServiceBrowseReply( + DNSServiceRef sdRef, + DNSServiceFlags flags, + uint32_t interfaceIndex, + DNSServiceErrorType errorCode, + const char *serviceName, + const char *regtype, + const char *replyDomain, + void *context +) +{ + DnssdBrowseCallback ChipBrowseHandler = (DnssdBrowseCallback)context; + DnssdService service; + + ChipLogProgress(ServiceProvisioning, "ChipDNSServiceBrowseReply %s", serviceName); + strcpy(service.mName, serviceName); + + ChipBrowseHandler(NULL, &service, 1, CHIP_NO_ERROR); + +} + +CHIP_ERROR ChipDnssdBrowse(const char * type, DnssdServiceProtocol protocol, chip::Inet::IPAddressType addressType, + chip::Inet::InterfaceId interface, DnssdBrowseCallback callback, void * context) +{ + CHIP_ERROR error = CHIP_NO_ERROR; + DNSServiceErrorType err; + char ServiceType[kDnssdTypeMaxSize + 10] = {0}; + + (void)addressType; + ChipLogProgress(ServiceProvisioning, "ChipDnssdBrowse %s", type); + strcpy(ServiceType, type); + strcat(ServiceType, "."); + strcat(ServiceType, GetProtocolString(protocol)); + err = DNSServiceBrowse(&BrowseClient, + 0, + 0, + ServiceType, + SERVICE_DOMAIN, + ChipDNSServiceBrowseReply, + (void*)callback); + ChipLogProgress(ServiceProvisioning, "DNSServiceBrowse %d", (int)err); + if (err) + { + error = CHIP_ERROR_INTERNAL; + } + return error; +} + +static DNSServiceRef ResolveClient = NULL; + +void ChipDNSServiceResolveReply(DNSServiceRef sdRef, DNSServiceFlags flags, uint32_t interfaceIndex, + DNSServiceErrorType errorCode, const char *fullname, const char *hosttarget, + uint16_t port, /* In network byte order */ uint16_t txtLen, + const unsigned char *txtRecord, void *context) +{ + ChipLogProgress(ServiceProvisioning, "ChipDNSServiceResolveReply"); +} + +CHIP_ERROR ChipDnssdResolve(DnssdService * service, chip::Inet::InterfaceId interface, DnssdResolveCallback callback, + void * context) +{ + CHIP_ERROR error = CHIP_NO_ERROR; + DNSServiceErrorType err; + char ServiceType[kDnssdTypeMaxSize + 10] = {0}; + + ChipLogProgress(ServiceProvisioning, "ChipDnssdResolve %s", service->mName); + strcpy(ServiceType, service->mType); + strcat(ServiceType, "."); + strcat(ServiceType, GetProtocolString(service->mProtocol)); + + err = DNSServiceResolve(&ResolveClient, + 0, + 0, + service->mName, + ServiceType, + SERVICE_DOMAIN, + ChipDNSServiceResolveReply, + (void*)callback); + ChipLogProgress(ServiceProvisioning, "DNSServiceResolve %d", (int)err); + if (err) + { + error = CHIP_ERROR_INTERNAL; + } + return error; +} + +} // namespace Dnssd +} // namespace chip diff --git a/src/platform/mt793x/InetPlatformConfig.h b/src/platform/mt793x/InetPlatformConfig.h new file mode 100644 index 00000000000000..e270a63641aa6a --- /dev/null +++ b/src/platform/mt793x/InetPlatformConfig.h @@ -0,0 +1,53 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2019 Google LLC. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Platform-specific configuration overrides for the CHIP Inet + * Layer on Genio platforms using the MediaTek SDK. + * + */ + +#pragma once + +#include + +// ==================== Platform Adaptations ==================== + +#define INET_CONFIG_ERROR_TYPE int32_t +#define INET_CONFIG_NO_ERROR 0 +#define INET_CONFIG_ERROR_MIN 1000000 +#define INET_CONFIG_ERROR_MAX 1000999 + +#ifndef INET_CONFIG_ENABLE_IPV4 +#ifdef SL_WIFI +#define INET_CONFIG_ENABLE_IPV4 1 +#else /* For Thread only devices */ +#define INET_CONFIG_ENABLE_IPV4 0 +#endif +#endif + +// ========== Platform-specific Configuration Overrides ========= + +#ifndef INET_CONFIG_NUM_TCP_ENDPOINTS +#define INET_CONFIG_NUM_TCP_ENDPOINTS 4 +#endif // INET_CONFIG_NUM_TCP_ENDPOINTS + +#ifndef INET_CONFIG_NUM_UDP_ENDPOINTS +#define INET_CONFIG_NUM_UDP_ENDPOINTS 6 +#endif // INET_CONFIG_NUM_UDP_ENDPOINTS diff --git a/src/platform/mt793x/KeyValueStoreManagerImpl.cpp b/src/platform/mt793x/KeyValueStoreManagerImpl.cpp new file mode 100644 index 00000000000000..9ab21a8315f1e4 --- /dev/null +++ b/src/platform/mt793x/KeyValueStoreManagerImpl.cpp @@ -0,0 +1,138 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Platform-specific key value storage implementation for Genio + */ + +#include + +/* ignore GCC Wconversion warnings for pigweed */ +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + +//#include + +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + +namespace chip { +namespace DeviceLayer { +namespace PersistedStorage { + +KeyValueStoreManagerImpl KeyValueStoreManagerImpl::sInstance; + +/** +* MT793x KVS Implemetation +*/ +CHIP_ERROR KeyValueStoreManagerImpl::_Get(const char * key, void * value, size_t value_size, size_t * read_bytes_size, + size_t offset_bytes) const +{ + CHIP_ERROR err; + nvdm_status_t nvdm_status; + + nvdm_status = nvdm_read_data_item(kNamespace, key, (uint8_t *)value, (uint32_t*)&value_size); + if (read_bytes_size) + { + *read_bytes_size = value_size; + } + err = MapNvdmStatus(nvdm_status); + + return err; +} + +CHIP_ERROR KeyValueStoreManagerImpl::_Put(const char * key, const void * value, size_t value_size) +{ + CHIP_ERROR err; + nvdm_status_t nvdm_status; + + nvdm_status = nvdm_write_data_item(kNamespace, key, NVDM_DATA_ITEM_TYPE_RAW_DATA, (uint8_t *)value, value_size); + err = MapNvdmStatus(nvdm_status); + + return err; +} + +CHIP_ERROR KeyValueStoreManagerImpl::_Delete(const char * key) +{ + CHIP_ERROR err; + nvdm_status_t nvdm_status; + + nvdm_status = nvdm_delete_data_item(kNamespace, key); + err = MapNvdmStatus(nvdm_status); + + return err; +} + +CHIP_ERROR KeyValueStoreManagerImpl::ErasePartition() +{ + CHIP_ERROR err; + nvdm_status_t nvdm_status; + + nvdm_status = nvdm_delete_group(kNamespace); + err = MapNvdmStatus(nvdm_status); + + return err; +} + +CHIP_ERROR KeyValueStoreManagerImpl::MapNvdmStatus(nvdm_status_t nvdm_status) +{ + CHIP_ERROR err; + +// NVDM_STATUS_INVALID_PARAMETER = -5, /**< The user parameter is invalid. */ +// NVDM_STATUS_ITEM_NOT_FOUND = -4, /**< The data item wasn't found by the NVDM. */ +// NVDM_STATUS_INSUFFICIENT_SPACE = -3, /**< No space is available in the flash. */ +// NVDM_STATUS_INCORRECT_CHECKSUM = -2, /**< The NVDM found a checksum error when reading the data item. */ +// NVDM_STATUS_ERROR = -1, /**< An unknown error occurred. */ +// NVDM_STATUS_OK = 0, /**< The operation was successful. */ + + switch (nvdm_status) + { + case NVDM_STATUS_OK: + err = CHIP_NO_ERROR; + break; + case NVDM_STATUS_ITEM_NOT_FOUND: + err = CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND; + break; + case NVDM_STATUS_INCORRECT_CHECKSUM: + err = CHIP_ERROR_INTEGRITY_CHECK_FAILED; + break; + case NVDM_STATUS_INSUFFICIENT_SPACE: + err = CHIP_ERROR_BUFFER_TOO_SMALL; + break; + case NVDM_STATUS_INVALID_PARAMETER: + err = CHIP_ERROR_INVALID_ARGUMENT; + break; + case NVDM_STATUS_ERROR: + err = CHIP_ERROR_INTERNAL; + break; + default: + err = CHIP_ERROR_INTERNAL; + break; + } + + return err; +} + + +} // namespace PersistedStorage +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/mt793x/KeyValueStoreManagerImpl.h b/src/platform/mt793x/KeyValueStoreManagerImpl.h new file mode 100644 index 00000000000000..db6f77f4ad348d --- /dev/null +++ b/src/platform/mt793x/KeyValueStoreManagerImpl.h @@ -0,0 +1,123 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Platform-specific key value storage implementation for Genio. + * + */ + +#pragma once + +#include "nvdm.h" + +/* ignore GCC Wconversion warnings for pigweed */ +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wconversion" +#endif + +//#include +//#include +//#include + +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif + +// KVS is only available for Genio when these macros are defined. +//#if defined(CHIP_KVS_SECTOR_COUNT) && defined(CHIP_KVS_BASE_SECTOR_INDEX) +//#define CHIP_KVS_AVAILABLE 1 +//#else // defined(CHIP_KVS_SECTOR_COUNT) && defined(CHIP_KVS_BASE_ADDRESS) +//#define CHIP_KVS_AVAILABLE 0 +//#endif // defined(CHIP_KVS_SECTOR_COUNT) && defined(CHIP_KVS_BASE_ADDRESS) + +namespace chip { +namespace DeviceLayer { +namespace PersistedStorage { + +/** +* +* MT793x KVS implementation +*/ + +class KeyValueStoreManagerImpl final : public KeyValueStoreManager +{ + // Allow the KeyValueStoreManager interface class to delegate method calls to + // the implementation methods provided by this class. + friend class KeyValueStoreManager; + +public: + void Init() { /*nvdm_init();*/ } + + CHIP_ERROR _Get(const char * key, void * value, size_t value_size, size_t * read_bytes_size = nullptr, size_t offset = 0) const; + + CHIP_ERROR _Delete(const char * key); + + /** + * @brief + * Erases all data in the KVS partition, KVS needs to be initialized after + * this operation. + * + * @return CHIP_NO_ERROR the partiton was erased. + * CHIP_ERROR_TIMEOUT timed out while doing erase. + * CHIP_ERROR_ACCESS_DENIED flash locked, erase failed. + */ + CHIP_ERROR ErasePartition(); + + CHIP_ERROR _Put(const char * key, const void * value, size_t value_size); + +private: + + const char * kNamespace = "CHIP_KVS"; + static CHIP_ERROR MapNvdmStatus(nvdm_status_t nvdm_status); + // ===== Members for internal use by the following friends. + + friend KeyValueStoreManager & KeyValueStoreMgr(); + friend KeyValueStoreManagerImpl & KeyValueStoreMgrImpl(); + + static KeyValueStoreManagerImpl sInstance; +}; + + + +/** + * Returns the public interface of the KeyValueStoreManager singleton object. + * + * Chip applications should use this to access features of the KeyValueStoreManager object + * that are common to all platforms. + */ +inline KeyValueStoreManager & KeyValueStoreMgr(void) +{ + return KeyValueStoreManagerImpl::sInstance; +} + +/** + * Returns the platform-specific implementation of the KeyValueStoreManager singleton object. + * + * Chip applications can use this to gain access to features of the KeyValueStoreManager + * that are specific to the ESP32 platform. + */ +inline KeyValueStoreManagerImpl & KeyValueStoreMgrImpl(void) +{ + return KeyValueStoreManagerImpl::sInstance; +} + +} // namespace PersistedStorage +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/mt793x/Logging.cpp b/src/platform/mt793x/Logging.cpp new file mode 100644 index 00000000000000..1bfa48aeff6d6a --- /dev/null +++ b/src/platform/mt793x/Logging.cpp @@ -0,0 +1,170 @@ +/* See Project CHIP LICENSE file for licensing information. */ +#include + +#include +#include + +#include +#include + +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD +#include +#endif + +#include +#include +#include +#include +#include + +#define MT793X_LOG_ENABLED (1) + +#ifdef PW_RPC_ENABLED +#include "PigweedLogger.h" +#endif + +#define LOG_ERROR " " +#define LOG_WARN " " +#define LOG_INFO " " +#define LOG_DETAIL " " +#define LOG_LWIP " " +#define LOG_MT793X " " +// If a new category string LOG_* is created, add it in the MaxStringLength arguments below +static constexpr size_t kMaxCategoryStrLen = chip::MaxStringLength(LOG_ERROR, LOG_WARN, LOG_INFO, LOG_DETAIL, LOG_LWIP, LOG_MT793X); + +#if MT793X_LOG_ENABLED +static bool sLogInitialized = false; +#endif + +#if MT793X_LOG_ENABLED +static void PrintLog(const char * msg) +{ + /*if (sLogInitialized) + { + size_t sz; + sz = strlen(msg); +#ifdef PW_RPC_ENABLED + PigweedLogger::putString(msg, sz); +#endif + + const char * newline = "\r\n"; + sz = strlen(newline); +#ifdef PW_RPC_ENABLED + PigweedLogger::putString(newline, sz); +#endif + }*/ + + printf("%s\n", msg); + +} +#endif // MT793X_LOG_ENABLED + +namespace chip { +namespace DeviceLayer { + +/** + * Called whenever a log message is emitted by Chip or LwIP. + * + * This function is intended be overridden by the application to, e.g., + * schedule output of queued log entries. + */ +void __attribute__((weak)) OnLogOutput(void) {} + +} // namespace DeviceLayer +} // namespace chip + +#include "stdio.h" + +namespace chip { +namespace Logging { +namespace Platform { + +/** + * CHIP log output functions. + */ +void LogV(const char * module, uint8_t category, const char * aFormat, va_list v) +{ +#if MT793X_LOG_ENABLED && _CHIP_USE_LOGGING + if (IsCategoryEnabled(category)) + { + char formattedMsg[CHIP_CONFIG_LOG_MESSAGE_MAX_SIZE]; + size_t formattedMsgLen; + + // len for Category string + "[" + Module name + "] " (Brackets and space =3) + constexpr size_t maxPrefixLen = kMaxCategoryStrLen + chip::Logging::kMaxModuleNameLen + 3; + static_assert(sizeof(formattedMsg) > maxPrefixLen); // Greater than to at least accommodate a ending Null Character + + switch (category) + { + case kLogCategory_Error: + strcpy(formattedMsg, LOG_ERROR); + break; + case kLogCategory_Progress: + default: + strcpy(formattedMsg, LOG_INFO); + break; + case kLogCategory_Detail: + strcpy(formattedMsg, LOG_DETAIL); + break; + } + + formattedMsgLen = strlen(formattedMsg); + + // Form the log prefix, e.g. "[DL] " + snprintf(formattedMsg + formattedMsgLen, sizeof(formattedMsg) - formattedMsgLen, "[%s] ", module); + formattedMsg[sizeof(formattedMsg) - 1] = 0; + formattedMsgLen = strlen(formattedMsg); + + size_t len = vsnprintf(formattedMsg + formattedMsgLen, sizeof formattedMsg - formattedMsgLen, aFormat, v); + + if (len >= sizeof formattedMsg - formattedMsgLen) + { + formattedMsg[sizeof formattedMsg - 1] = '\0'; + } + + PrintLog(formattedMsg); + } + + // Let the application know that a log message has been emitted. + chip::DeviceLayer::OnLogOutput(); +#endif // MT793X_LOG_ENABLED && _CHIP_USE_LOGGING +} + +} // namespace Platform +} // namespace Logging +} // namespace chip + +/** + * LwIP log output function. + */ +extern "C" void LwIPLog(const char * aFormat, ...) +{ + va_list v; + + va_start(v, aFormat); +#if MT793X_LOG_ENABLED + char formattedMsg[CHIP_CONFIG_LOG_MESSAGE_MAX_SIZE]; + + strcpy(formattedMsg, LOG_LWIP); + size_t prefixLen = strlen(formattedMsg); + size_t len = vsnprintf(formattedMsg + prefixLen, sizeof formattedMsg - prefixLen, aFormat, v); + + if (len >= sizeof formattedMsg - prefixLen) + { + formattedMsg[sizeof formattedMsg - 1] = '\0'; + } + + PrintLog(formattedMsg); + +#if configCHECK_FOR_STACK_OVERFLOW + // Force a stack overflow check. + if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) + taskYIELD(); +#endif + + // Let the application know that a log message has been emitted. + chip::DeviceLayer::OnLogOutput(); +#endif // MT793X_LOG_ENABLED + va_end(v); +} + diff --git a/src/platform/mt793x/MT793XConfig.cpp b/src/platform/mt793x/MT793XConfig.cpp new file mode 100644 index 00000000000000..5906d455cfd801 --- /dev/null +++ b/src/platform/mt793x/MT793XConfig.cpp @@ -0,0 +1,428 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2019 Nest Labs, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Utilities for accessing persisted device configuration on + * platforms based on the MediaTek SDK. + */ +/* this file behaves like a config.h, comes first */ +#include + +#include + +#include +#include + +#include "FreeRTOS.h" +#include "nvdm.h" + +namespace chip { +namespace DeviceLayer { +namespace Internal { + + // Factory config keys + const MT793XConfig::Key MT793XConfig::kConfigKey_SerialNum = { .Namespace = kConfigNamespace_ChipFactory, .Name = "serial-num" }; + const MT793XConfig::Key MT793XConfig::kConfigKey_UniqueId = { .Namespace = kConfigNamespace_ChipFactory, .Name = "unique-id" }; + const MT793XConfig::Key MT793XConfig::kConfigKey_MfrDeviceId = { .Namespace = kConfigNamespace_ChipFactory, .Name = "device-id" }; + const MT793XConfig::Key MT793XConfig::kConfigKey_MfrDeviceCert = { .Namespace = kConfigNamespace_ChipFactory, .Name = "device-cert" }; + const MT793XConfig::Key MT793XConfig::kConfigKey_MfrDevicePrivateKey = { .Namespace = kConfigNamespace_ChipFactory, .Name = "device-key" }; + const MT793XConfig::Key MT793XConfig::kConfigKey_ManufacturingDate = { .Namespace = kConfigNamespace_ChipFactory, .Name = "mfg-date" }; + const MT793XConfig::Key MT793XConfig::kConfigKey_SetupPinCode = { .Namespace = kConfigNamespace_ChipFactory, .Name = "pin-code" }; + const MT793XConfig::Key MT793XConfig::kConfigKey_MfrDeviceICACerts = { .Namespace = kConfigNamespace_ChipFactory, .Name = "device-ca-certs" }; + const MT793XConfig::Key MT793XConfig::kConfigKey_SetupDiscriminator = { .Namespace = kConfigNamespace_ChipFactory, .Name = "discriminator" }; + const MT793XConfig::Key MT793XConfig::kConfigKey_Spake2pIterationCount = { .Namespace = kConfigNamespace_ChipFactory, .Name = "iteration-count" }; + const MT793XConfig::Key MT793XConfig::kConfigKey_Spake2pSalt = { .Namespace = kConfigNamespace_ChipFactory, .Name = "salt" }; + const MT793XConfig::Key MT793XConfig::kConfigKey_Spake2pVerifier = { .Namespace = kConfigNamespace_ChipFactory, .Name = "verifier" }; + // CHIP Config Keys + const MT793XConfig::Key MT793XConfig::kConfigKey_FabricId = { .Namespace = kConfigNamespace_ChipConfig, .Name ="fabric-id" }; + const MT793XConfig::Key MT793XConfig::kConfigKey_ServiceConfig = { .Namespace = kConfigNamespace_ChipConfig, .Name ="service-config" }; + const MT793XConfig::Key MT793XConfig::kConfigKey_PairedAccountId = { .Namespace = kConfigNamespace_ChipConfig, .Name ="account-id" }; + const MT793XConfig::Key MT793XConfig::kConfigKey_ServiceId = { .Namespace = kConfigNamespace_ChipConfig, .Name ="service-id" }; + const MT793XConfig::Key MT793XConfig::kConfigKey_FabricSecret = { .Namespace = kConfigNamespace_ChipConfig, .Name ="fabric-secret" }; + const MT793XConfig::Key MT793XConfig::kConfigKey_LastUsedEpochKeyId = { .Namespace = kConfigNamespace_ChipConfig, .Name ="last-ek-id" }; + const MT793XConfig::Key MT793XConfig::kConfigKey_FailSafeArmed = { .Namespace = kConfigNamespace_ChipConfig, .Name ="fail-safe-armed" }; + const MT793XConfig::Key MT793XConfig::kConfigKey_GroupKey = { .Namespace = kConfigNamespace_ChipConfig, .Name ="group-key" }; + const MT793XConfig::Key MT793XConfig::kConfigKey_HardwareVersion = { .Namespace = kConfigNamespace_ChipConfig, .Name ="hardware-ver" }; + const MT793XConfig::Key MT793XConfig::kConfigKey_RegulatoryLocation = { .Namespace = kConfigNamespace_ChipConfig, .Name ="reg-location" }; + const MT793XConfig::Key MT793XConfig::kConfigKey_CountryCode = { .Namespace = kConfigNamespace_ChipConfig, .Name ="country-code" }; + const MT793XConfig::Key MT793XConfig::kConfigKey_Breadcrumb = { .Namespace = kConfigNamespace_ChipConfig, .Name ="breadcrumb" }; + const MT793XConfig::Key MT793XConfig::kConfigKey_WiFiSSID = { .Namespace = kConfigNamespace_ChipConfig, .Name ="wifi-ssid" }; + const MT793XConfig::Key MT793XConfig::kConfigKey_WiFiPSK = { .Namespace = kConfigNamespace_ChipConfig, .Name ="wifi-psk" }; + const MT793XConfig::Key MT793XConfig::kConfigKey_WiFiSEC = { .Namespace = kConfigNamespace_ChipConfig, .Name ="wifi-sec" }; + const MT793XConfig::Key MT793XConfig::kConfigKey_GroupKeyBase = { .Namespace = kConfigNamespace_ChipConfig, .Name ="group-key-base" }; + const MT793XConfig::Key MT793XConfig::kConfigKey_GroupKeyMax = { .Namespace = kConfigNamespace_ChipConfig, .Name ="group-key-max" }; + // CHIP Counter Keys + const MT793XConfig::Key MT793XConfig::kConfigKey_BootCount = { .Namespace = kConfigNamespace_ChipCounters, .Name ="boot-count" }; + const MT793XConfig::Key MT793XConfig::kConfigKey_TotalOperationalHours = { .Namespace = kConfigNamespace_ChipCounters, .Name ="total-hours" }; + +#define NVDM_SEM_TIMEOUT_MS 5 + +static SemaphoreHandle_t nvdm_sem; +static StaticSemaphore_t nvdm_sem_struct; + +CHIP_ERROR MT793XConfig::Init() +{ + CHIP_ERROR err; + nvdm_status_t nvdm_status; + + nvdm_sem = xSemaphoreCreateBinaryStatic(&nvdm_sem_struct); + + if (nvdm_sem == NULL) + { + return CHIP_ERROR_NO_MEMORY; + } + + nvdm_status = nvdm_init(); + err = MapNvdmStatus(nvdm_status); + SuccessOrExit(err); + +exit: + OnExit(); + return CHIP_NO_ERROR; +} + +CHIP_ERROR MT793XConfig::ReadConfigValue(Key key, bool & val) +{ + CHIP_ERROR err; + uint32_t intVal; + uint32_t len = sizeof(bool); + + if (pdFALSE == xSemaphoreTake(nvdm_sem, pdMS_TO_TICKS(NVDM_SEM_TIMEOUT_MS))) + { + err = CHIP_ERROR_TIMEOUT; + SuccessOrExit(err); + } + + // Get NVDM item + err = MapNvdmStatus(nvdm_read_data_item(key.Namespace, key.Name, (uint8_t*)&intVal, &len)); + SuccessOrExit(err); + + val = (intVal != 0); + +exit: + OnExit(); + return err; +} + +CHIP_ERROR MT793XConfig::ReadConfigValue(Key key, uint32_t & val) +{ + CHIP_ERROR err; + uint32_t len = sizeof(uint32_t); + + if (pdFALSE == xSemaphoreTake(nvdm_sem, pdMS_TO_TICKS(NVDM_SEM_TIMEOUT_MS))) + { + err = CHIP_ERROR_TIMEOUT; + SuccessOrExit(err); + } + // Get NVDM item + err = MapNvdmStatus(nvdm_read_data_item(key.Namespace, key.Name, (uint8_t*)&val, &len)); + SuccessOrExit(err); +exit: + OnExit(); + return err; +} + +CHIP_ERROR MT793XConfig::ReadConfigValue(Key key, uint64_t & val) +{ + CHIP_ERROR err; + uint32_t len = sizeof(uint64_t); + + if (pdFALSE == xSemaphoreTake(nvdm_sem, pdMS_TO_TICKS(NVDM_SEM_TIMEOUT_MS))) + { + err = CHIP_ERROR_TIMEOUT; + SuccessOrExit(err); + } + + // Get NVDM item + err = MapNvdmStatus(nvdm_read_data_item(key.Namespace, key.Name, (uint8_t*)&val, &len)); + SuccessOrExit(err); + +exit: + OnExit(); + return err; +} + +CHIP_ERROR MT793XConfig::ReadConfigValueStr(Key key, char * buf, size_t bufSize, size_t & outLen) +{ + CHIP_ERROR err; + outLen = bufSize; + if (pdFALSE == xSemaphoreTake(nvdm_sem, pdMS_TO_TICKS(NVDM_SEM_TIMEOUT_MS))) + { + err = CHIP_ERROR_TIMEOUT; + SuccessOrExit(err); + } + + // Get NVDM item + err = MapNvdmStatus(nvdm_read_data_item(key.Namespace, key.Name, (uint8_t*)buf, (uint32_t*)&outLen)); + SuccessOrExit(err); + +exit: + OnExit(); + return err; +} + +CHIP_ERROR MT793XConfig::ReadConfigValueBin(Key key, uint8_t * buf, size_t bufSize, size_t & outLen) +{ + CHIP_ERROR err; + outLen = bufSize; + if (pdFALSE == xSemaphoreTake(nvdm_sem, pdMS_TO_TICKS(NVDM_SEM_TIMEOUT_MS))) + { + err = CHIP_ERROR_TIMEOUT; + SuccessOrExit(err); + } + + // Get NVDM item + err = MapNvdmStatus(nvdm_read_data_item(key.Namespace, key.Name, (uint8_t*)buf, (uint32_t*)&outLen)); + SuccessOrExit(err); + +exit: + OnExit(); + return err; +} + +CHIP_ERROR MT793XConfig::ReadConfigValueCounter(uint8_t counterIdx, uint32_t & val) +{ + val = 0; + return CHIP_NO_ERROR; +} + +CHIP_ERROR MT793XConfig::WriteConfigValue(Key key, bool val) +{ + CHIP_ERROR err; + uint32_t intVal = val ? 1 : 0; + uint32_t len = sizeof(bool); + + if (pdFALSE == xSemaphoreTake(nvdm_sem, pdMS_TO_TICKS(NVDM_SEM_TIMEOUT_MS))) + { + err = CHIP_ERROR_TIMEOUT; + SuccessOrExit(err); + } + + // Set NVDM item + err = MapNvdmStatus(nvdm_write_data_item(key.Namespace, key.Name, NVDM_DATA_ITEM_TYPE_RAW_DATA, (uint8_t*)&intVal, len)); + SuccessOrExit(err); +exit: + OnExit(); + return err; +} + +CHIP_ERROR MT793XConfig::WriteConfigValue(Key key, uint32_t val) +{ + CHIP_ERROR err; + uint32_t len = sizeof(uint32_t); + + if (pdFALSE == xSemaphoreTake(nvdm_sem, pdMS_TO_TICKS(NVDM_SEM_TIMEOUT_MS))) + { + err = CHIP_ERROR_TIMEOUT; + SuccessOrExit(err); + } + + // Set NVDM item + err = MapNvdmStatus(nvdm_write_data_item(key.Namespace, key.Name, NVDM_DATA_ITEM_TYPE_RAW_DATA, (uint8_t*)&val, len)); + SuccessOrExit(err); +exit: + OnExit(); + return err; +} + +CHIP_ERROR MT793XConfig::WriteConfigValue(Key key, uint64_t val) +{ + CHIP_ERROR err; + uint32_t len = sizeof(uint64_t); + + if (pdFALSE == xSemaphoreTake(nvdm_sem, pdMS_TO_TICKS(NVDM_SEM_TIMEOUT_MS))) + { + err = CHIP_ERROR_TIMEOUT; + SuccessOrExit(err); + } + + // Set NVDM item + err = MapNvdmStatus(nvdm_write_data_item(key.Namespace, key.Name, NVDM_DATA_ITEM_TYPE_RAW_DATA, (uint8_t*)&val, len)); + SuccessOrExit(err); +exit: + OnExit(); + return err; +} + +CHIP_ERROR MT793XConfig::WriteConfigValueStr(Key key, const char * str) +{ + return WriteConfigValueStr(key, str, (str != NULL) ? strlen(str) : 0); +} + +CHIP_ERROR MT793XConfig::WriteConfigValueStr(Key key, const char * str, size_t strLen) +{ + CHIP_ERROR err; + + if (pdFALSE == xSemaphoreTake(nvdm_sem, pdMS_TO_TICKS(NVDM_SEM_TIMEOUT_MS))) + { + err = CHIP_ERROR_TIMEOUT; + SuccessOrExit(err); + } + + // Set NVDM item + err = MapNvdmStatus(nvdm_write_data_item(key.Namespace, key.Name, NVDM_DATA_ITEM_TYPE_STRING, (uint8_t*)str, strLen)); + SuccessOrExit(err); +exit: + OnExit(); + return err; +} + +CHIP_ERROR MT793XConfig::WriteConfigValueBin(Key key, const uint8_t * data, size_t dataLen) +{ + CHIP_ERROR err; + + if (pdFALSE == xSemaphoreTake(nvdm_sem, pdMS_TO_TICKS(NVDM_SEM_TIMEOUT_MS))) + { + err = CHIP_ERROR_TIMEOUT; + SuccessOrExit(err); + } + + // Set NVDM item + err = MapNvdmStatus(nvdm_write_data_item(key.Namespace, key.Name, NVDM_DATA_ITEM_TYPE_RAW_DATA, (uint8_t*)data, dataLen)); + SuccessOrExit(err); +exit: + OnExit(); + return err; +} + +CHIP_ERROR MT793XConfig::WriteConfigValueCounter(uint8_t counterIdx, uint32_t val) +{ + return CHIP_NO_ERROR; +} + +CHIP_ERROR MT793XConfig::ClearConfigValue(Key key) +{ + CHIP_ERROR err; + + if (pdFALSE == xSemaphoreTake(nvdm_sem, pdMS_TO_TICKS(NVDM_SEM_TIMEOUT_MS))) + { + err = CHIP_ERROR_TIMEOUT; + SuccessOrExit(err); + } + + // Delete NVDM item + err = MapNvdmStatus(nvdm_delete_data_item(key.Namespace, key.Name)); + SuccessOrExit(err); +exit: + OnExit(); + return err; +} + +bool MT793XConfig::ConfigValueExists(Key key) +{ + CHIP_ERROR err; + char group_name[32]; + char data_item_name[32]; + bool ret = false; + if (pdFALSE == xSemaphoreTake(nvdm_sem, pdMS_TO_TICKS(NVDM_SEM_TIMEOUT_MS))) + { + err = CHIP_ERROR_TIMEOUT; + SuccessOrExit(err); + } + + // Query NVDM item + nvdm_query_begin(); + while(nvdm_query_next_group_name(group_name) == NVDM_STATUS_OK) { + if(!strcmp(group_name, key.Namespace)) { + while(nvdm_query_next_data_item_name(data_item_name) == NVDM_STATUS_OK) { + if(!strcmp(data_item_name, key.Name)) { + ret = true; + } + } + } + } + nvdm_query_end(); + +exit: + OnExit(); + return ret; +} + +CHIP_ERROR MT793XConfig::FactoryResetConfig(void) +{ + CHIP_ERROR err; + + if (pdFALSE == xSemaphoreTake(nvdm_sem, pdMS_TO_TICKS(NVDM_SEM_TIMEOUT_MS))) + { + err = CHIP_ERROR_TIMEOUT; + SuccessOrExit(err); + } + + // Deletes all 'Config' type objects + // Note- 'Factory' and 'Counter' type are NOT deleted. + err = MapNvdmStatus(nvdm_delete_group(kConfigNamespace_ChipConfig)); + SuccessOrExit(err); +exit: + OnExit(); + return err; +} + +CHIP_ERROR MT793XConfig::MapNvdmStatus(nvdm_status_t nvdm_status) +{ + CHIP_ERROR err; + +// NVDM_STATUS_INVALID_PARAMETER = -5, /**< The user parameter is invalid. */ +// NVDM_STATUS_ITEM_NOT_FOUND = -4, /**< The data item wasn't found by the NVDM. */ +// NVDM_STATUS_INSUFFICIENT_SPACE = -3, /**< No space is available in the flash. */ +// NVDM_STATUS_INCORRECT_CHECKSUM = -2, /**< The NVDM found a checksum error when reading the data item. */ +// NVDM_STATUS_ERROR = -1, /**< An unknown error occurred. */ +// NVDM_STATUS_OK = 0, /**< The operation was successful. */ + + switch (nvdm_status) + { + case NVDM_STATUS_OK: + err = CHIP_NO_ERROR; + break; + case NVDM_STATUS_ITEM_NOT_FOUND: + err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND; + break; + case NVDM_STATUS_INCORRECT_CHECKSUM: + err = CHIP_ERROR_INTEGRITY_CHECK_FAILED; + break; + case NVDM_STATUS_INSUFFICIENT_SPACE: + err = CHIP_ERROR_BUFFER_TOO_SMALL; + break; + case NVDM_STATUS_INVALID_PARAMETER: + err = CHIP_ERROR_INVALID_ARGUMENT; + break; + case NVDM_STATUS_ERROR: + err = CHIP_ERROR_INTERNAL; + break; + default: + err = CHIP_ERROR_INTERNAL; + break; + } + + return err; +} + +void MT793XConfig::RunConfigUnitTest() +{ + // Run common unit test. + ::chip::DeviceLayer::Internal::RunConfigUnitTest(); +} + +void MT793XConfig::OnExit() +{ + xSemaphoreGive(nvdm_sem); +} + +} // namespace Internal +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/mt793x/MT793XConfig.h b/src/platform/mt793x/MT793XConfig.h new file mode 100644 index 00000000000000..d7d729d86b2e09 --- /dev/null +++ b/src/platform/mt793x/MT793XConfig.h @@ -0,0 +1,131 @@ +/* + * + * Copyright (c) 2020-2022 Project CHIP Authors + * Copyright (c) 2019 Nest Labs, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Utilities for accessing persisted device configuration on + * platforms based on the MediaTek SDK. + */ + +#pragma once + +#include + +#include + +#include "nvdm.h" + +namespace chip { +namespace DeviceLayer { +namespace Internal { + +/** + * + * This implementation uses the MT793X NVDM flash data storage library + * as the underlying storage layer. + * + * NOTE: This class is designed to be mixed-in to the concrete subclass of the + * GenericConfigurationManagerImpl<> template. When used this way, the class + * naturally provides implementations for the delegated members referenced by + * the template class (e.g. the ReadConfigValue() method). + */ + +class MT793XConfig +{ +public: +public: + + typedef struct + { + const char * Namespace; + const char * Name; + }Key; + + //NVM3 key base offsets used by the CHIP Device Layer. + static constexpr char* kConfigNamespace_ChipFactory = (char*)"chip-factory"; + static constexpr char* kConfigNamespace_ChipConfig = (char*)"chip-config"; + static constexpr char* kConfigNamespace_ChipCounters = (char*)"chip-counters"; + + // Factory config keys + static const Key kConfigKey_SerialNum; + static const Key kConfigKey_UniqueId; + static const Key kConfigKey_MfrDeviceId; + static const Key kConfigKey_MfrDeviceCert; + static const Key kConfigKey_MfrDevicePrivateKey; + static const Key kConfigKey_ManufacturingDate; + static const Key kConfigKey_SetupPinCode; + static const Key kConfigKey_MfrDeviceICACerts; + static const Key kConfigKey_SetupDiscriminator; + static const Key kConfigKey_Spake2pIterationCount; + static const Key kConfigKey_Spake2pSalt; + static const Key kConfigKey_Spake2pVerifier; + + // CHIP Config Keys + static const Key kConfigKey_FabricId; + static const Key kConfigKey_ServiceConfig; + static const Key kConfigKey_PairedAccountId; + static const Key kConfigKey_ServiceId; + static const Key kConfigKey_FabricSecret; + static const Key kConfigKey_LastUsedEpochKeyId; + static const Key kConfigKey_FailSafeArmed; + static const Key kConfigKey_GroupKey; + static const Key kConfigKey_HardwareVersion; + static const Key kConfigKey_RegulatoryLocation; + static const Key kConfigKey_CountryCode; + static const Key kConfigKey_Breadcrumb; + static const Key kConfigKey_WiFiSSID; + static const Key kConfigKey_WiFiPSK; + static const Key kConfigKey_WiFiSEC; + static const Key kConfigKey_GroupKeyBase; + static const Key kConfigKey_GroupKeyMax; + + // CHIP Counter Keys + static const Key kConfigKey_BootCount; + static const Key kConfigKey_TotalOperationalHours; + + static CHIP_ERROR Init(void); + + // Configuration methods used by the GenericConfigurationManagerImpl<> template. + static CHIP_ERROR ReadConfigValue(Key key, bool & val); + static CHIP_ERROR ReadConfigValue(Key key, uint32_t & val); + static CHIP_ERROR ReadConfigValue(Key key, uint64_t & val); + static CHIP_ERROR ReadConfigValueStr(Key key, char * buf, size_t bufSize, size_t & outLen); + static CHIP_ERROR ReadConfigValueBin(Key key, uint8_t * buf, size_t bufSize, size_t & outLen); + static CHIP_ERROR ReadConfigValueCounter(uint8_t counterIdx, uint32_t & val); + static CHIP_ERROR WriteConfigValue(Key key, bool val); + static CHIP_ERROR WriteConfigValue(Key key, uint32_t val); + static CHIP_ERROR WriteConfigValue(Key key, uint64_t val); + static CHIP_ERROR WriteConfigValueStr(Key key, const char * str); + static CHIP_ERROR WriteConfigValueStr(Key key, const char * str, size_t strLen); + static CHIP_ERROR WriteConfigValueBin(Key key, const uint8_t * data, size_t dataLen); + static CHIP_ERROR WriteConfigValueCounter(uint8_t counterIdx, uint32_t val); + static CHIP_ERROR ClearConfigValue(Key key); + static bool ConfigValueExists(Key key); + static CHIP_ERROR FactoryResetConfig(void); + + static void RunConfigUnitTest(void); + +private: + static CHIP_ERROR MapNvdmStatus(nvdm_status_t nvdm_status); + static void OnExit(void); +}; + +} // namespace Internal +} // namespace DeviceLayer +} // namespace chip + diff --git a/src/platform/mt793x/MtkWiFiEvents.cpp b/src/platform/mt793x/MtkWiFiEvents.cpp new file mode 100644 index 00000000000000..2f0cf7b97b7e0a --- /dev/null +++ b/src/platform/mt793x/MtkWiFiEvents.cpp @@ -0,0 +1,12 @@ + + +#include + +#include + +#include + + +using namespace ::chip::DeviceLayer; + + diff --git a/src/platform/mt793x/NetworkCommissioningWiFiDriver.cpp b/src/platform/mt793x/NetworkCommissioningWiFiDriver.cpp new file mode 100644 index 00000000000000..2b824297749260 --- /dev/null +++ b/src/platform/mt793x/NetworkCommissioningWiFiDriver.cpp @@ -0,0 +1,422 @@ +/* + * + * Copyright (c) 2022 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include +#include + +#include + +using namespace ::chip; +using namespace ::chip::DeviceLayer::Internal; + +namespace chip { +namespace DeviceLayer { +namespace NetworkCommissioning { + +namespace { +NetworkCommissioning::WiFiScanResponse * sScanResult; +GenioScanResponseIterator mScanResponseIter(sScanResult); +} // namespace + +CHIP_ERROR GenioWiFiDriver::Init(NetworkStatusChangeCallback * networkStatusChangeCallback) +{ + CHIP_ERROR err; + size_t ssidLen = 0; + size_t credentialsLen = 0; + size_t outLen = 0; + mpScanCallback = nullptr; + mpConnectCallback = nullptr; + + ChipLogProgress(NetworkProvisioning, "GenioWiFiDriver::Init"); + + // If reading fails, wifi is not provisioned, no need to go further. + err = MT793XConfig::ReadConfigValueStr(MT793XConfig::kConfigKey_WiFiSSID, + mSavedNetwork.ssid, + sizeof(mSavedNetwork.ssid), + ssidLen); + VerifyOrReturnError(err == CHIP_NO_ERROR, CHIP_NO_ERROR); + + err = MT793XConfig::ReadConfigValueStr(MT793XConfig::kConfigKey_WiFiPSK, + mSavedNetwork.credentials, + sizeof(mSavedNetwork.credentials), + credentialsLen); + VerifyOrReturnError(err == CHIP_NO_ERROR, CHIP_NO_ERROR); + + err = MT793XConfig::ReadConfigValueBin(MT793XConfig::kConfigKey_WiFiSEC, + &mSavedNetwork.auth_mode, + sizeof(mSavedNetwork.auth_mode), + outLen); + VerifyOrReturnError(err == CHIP_NO_ERROR, CHIP_NO_ERROR); + + mSavedNetwork.credentialsLen = credentialsLen; + mSavedNetwork.ssidLen = ssidLen; + mStagingNetwork = mSavedNetwork; + + ConnectWiFiNetwork(mSavedNetwork.ssid, ssidLen, + mSavedNetwork.credentials, credentialsLen); + return err; +} + +CHIP_ERROR GenioWiFiDriver::CommitConfiguration() +{ + CHIP_ERROR err; + + ChipLogProgress(NetworkProvisioning, "GenioWiFiDriver::CommitConfiguration"); + + ReturnErrorOnFailure( + MT793XConfig::WriteConfigValueStr(MT793XConfig::kConfigKey_WiFiSSID, + mStagingNetwork.ssid) + ); + + ReturnErrorOnFailure( + MT793XConfig::WriteConfigValueStr(MT793XConfig::kConfigKey_WiFiPSK, + mStagingNetwork.credentials) + ); + + ReturnErrorOnFailure( + MT793XConfig::WriteConfigValueBin(MT793XConfig::kConfigKey_WiFiSEC, + &mStagingNetwork.auth_mode, + sizeof(mStagingNetwork.auth_mode)) + ); + + mSavedNetwork = mStagingNetwork; + + return CHIP_NO_ERROR; +} + +CHIP_ERROR GenioWiFiDriver::RevertConfiguration() +{ + ChipLogProgress(NetworkProvisioning, "GenioWiFiDriver::RevertConfiguration"); + + mStagingNetwork = mSavedNetwork; + return CHIP_NO_ERROR; +} + +bool GenioWiFiDriver::NetworkMatch(const WiFiNetwork & network, ByteSpan networkId) +{ + return networkId.size() == network.ssidLen && + memcmp(networkId.data(), network.ssid, network.ssidLen) == 0; +} + +Status GenioWiFiDriver::AddOrUpdateNetwork(ByteSpan ssid, + ByteSpan credentials, + MutableCharSpan & outDebugText, + uint8_t & outNetworkIndex) +{ + outDebugText.reduce_size(0); + outNetworkIndex = 0; + + ChipLogProgress(NetworkProvisioning, "GenioWiFiDriver::AddOrUpdateNetwork"); + + VerifyOrReturnError(mStagingNetwork.ssidLen == 0 || + NetworkMatch(mStagingNetwork, ssid), + Status::kBoundsExceeded); + VerifyOrReturnError(credentials.size() <= sizeof(mStagingNetwork.credentials), + Status::kOutOfRange); + VerifyOrReturnError(ssid.size() <= sizeof(mStagingNetwork.ssid), Status::kOutOfRange); + + memset(mStagingNetwork.credentials, 0, sizeof(mStagingNetwork.credentials)); + memcpy(mStagingNetwork.credentials, credentials.data(), credentials.size()); + mStagingNetwork.credentialsLen = static_cast(credentials.size()); + + memset(mStagingNetwork.ssid, 0, sizeof(mStagingNetwork.ssid)); + memcpy(mStagingNetwork.ssid, ssid.data(), ssid.size()); + mStagingNetwork.ssidLen = static_cast(ssid.size()); + + mStagingNetwork.auth_mode = WIFI_AUTH_MODE_WPA2_PSK; + + return Status::kSuccess; +} + +Status GenioWiFiDriver::RemoveNetwork(ByteSpan networkId, + MutableCharSpan & outDebugText, + uint8_t & outNetworkIndex) +{ + outDebugText.reduce_size(0); + outNetworkIndex = 0; + + ChipLogProgress(NetworkProvisioning, "GenioWiFiDriver::RemoveNetwork"); + + VerifyOrReturnError(NetworkMatch(mStagingNetwork, networkId), Status::kNetworkIDNotFound); + + // Use empty ssid for representing invalid network + mStagingNetwork.ssidLen = 0; + return Status::kSuccess; +} + +Status GenioWiFiDriver::ReorderNetwork(ByteSpan networkId, + uint8_t index, + MutableCharSpan & outDebugText) +{ + ChipLogProgress(NetworkProvisioning, "GenioWiFiDriver::ReorderNetwork"); + + outDebugText.reduce_size(0); + // Only one network is supported for now + VerifyOrReturnError(index == 0, Status::kOutOfRange); + VerifyOrReturnError(NetworkMatch(mStagingNetwork, networkId), Status::kNetworkIDNotFound); + return Status::kSuccess; +} + +CHIP_ERROR GenioWiFiDriver::ConnectWiFiNetwork(const char * ssid, + uint8_t ssidLen, + const char * key, + uint8_t keyLen) +{ + ChipLogProgress(NetworkProvisioning, "GenioWiFiDriver::ConnectWiFiNetwork"); + + ReturnErrorOnFailure(ConnectivityMgr().SetWiFiStationMode( + ConnectivityManager::kWiFiStationMode_Enabled)); + + // Set the wifi configuration + filogic_wifi_sta_prov_t wifi_prov = {}; + memcpy(wifi_prov.ssid, ssid, ssidLen); + memcpy(wifi_prov.psk, key, keyLen); + wifi_prov.ssid_len = ssidLen; + wifi_prov.psk_len = keyLen; + wifi_prov.auth_mode = WIFI_AUTH_MODE_WPA2_PSK; + + ChipLogProgress(NetworkProvisioning, "Setting up connection for WiFi SSID: %.*s", + static_cast(ssidLen), ssid); + + void *filogicCtx = PlatformMgrImpl().mFilogicCtx; + + // Configure the FILOGIC WiFi interface. + filogic_wifi_sta_prov_set_sync(filogicCtx, &wifi_prov); + ReturnErrorOnFailure(ConnectivityMgr().SetWiFiStationMode(ConnectivityManager::kWiFiStationMode_Disabled)); + ReturnErrorOnFailure(ConnectivityMgr().SetWiFiStationMode(ConnectivityManager::kWiFiStationMode_Enabled)); + + return CHIP_NO_ERROR; +} + +void GenioWiFiDriver::OnConnectWiFiNetwork() +{ + ChipLogProgress(NetworkProvisioning, "GenioWiFiDriver::OnConnectWiFiNetwork"); + + if (mpConnectCallback) + { + CommitConfiguration(); + mpConnectCallback->OnResult(Status::kSuccess, CharSpan(), 0); + mpConnectCallback = nullptr; + } +} + +void GenioWiFiDriver::ConnectNetwork(ByteSpan networkId, + ConnectCallback * callback) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + Status networkingStatus = Status::kUnknownError; + + ChipLogProgress(NetworkProvisioning, "GenioWiFiDriver::ConnectNetwork"); + + VerifyOrExit(NetworkMatch(mStagingNetwork, networkId), + networkingStatus = Status::kNetworkIDNotFound); + VerifyOrExit(mpConnectCallback == nullptr, + networkingStatus = Status::kUnknownError); + + err = ConnectWiFiNetwork(mStagingNetwork.ssid, + mStagingNetwork.ssidLen, + mStagingNetwork.credentials, + mStagingNetwork.credentialsLen); + if (err == CHIP_NO_ERROR) + { + mpConnectCallback = callback; + networkingStatus = Status::kSuccess; + } + +exit: + if (networkingStatus != Status::kSuccess) + { + ChipLogError(NetworkProvisioning, "Failed to connect to WiFi network:%s", + chip::ErrorStr(err)); + mpConnectCallback = nullptr; + callback->OnResult(networkingStatus, CharSpan(), 0); + } +} + +chip::BitFlags GenioWiFiDriver::ConvertSecuritytype(wifi_auth_mode_t auth_mode) +{ + chip::BitFlags securityType; + if (auth_mode == WIFI_AUTH_MODE_OPEN) + { + securityType = WiFiSecurity::kUnencrypted; + } + else if (auth_mode == WIFI_AUTH_MODE_WPA_PSK) + { + securityType = WiFiSecurity::kWpaPersonal; + } + else if (auth_mode == WIFI_AUTH_MODE_WPA2_PSK) + { + securityType = WiFiSecurity::kWpa2Personal; + } + else if (auth_mode == WIFI_AUTH_MODE_WPA3_PSK) + { + securityType = WiFiSecurity::kWpa3Personal; + } + else + { + securityType = WiFiSecurity::kUnencrypted; + } + + return securityType; +} + +bool GenioWiFiDriver::StartScanWiFiNetworks(ByteSpan ssid) +{ + ChipLogProgress(NetworkProvisioning, "GenioWiFiDriver::StartScanWiFiNetworks"); + + ChipLogProgress(DeviceLayer, "Start Scan WiFi Networks"); + + void *filogicCtx = PlatformMgrImpl().mFilogicCtx; + + if (!ssid.empty()) // ssid is given, only scan this network + { + char cSsid[DeviceLayer::Internal::kMaxWiFiSSIDLength] = {}; + memcpy(cSsid, ssid.data(), ssid.size()); + filogic_wifi_scan(filogicCtx, (uint8_t *)cSsid, ssid.size(), + kMaxWiFiScanAPs, OnScanWiFiNetworkDone); + } + else // scan all networks + { + filogic_wifi_scan(filogicCtx, nullptr, 0, + kMaxWiFiScanAPs, OnScanWiFiNetworkDone); + } + return true; +} + +void GenioWiFiDriver::OnScanWiFiNetworkDone(wifi_scan_list_item_t * aScanResult) +{ + ChipLogProgress(NetworkProvisioning, "GenioWiFiDriver::OnScanWiFiNetworkDone"); + + ChipLogProgress(DeviceLayer, "OnScanWiFiNetworkDone"); + if (!aScanResult) + { + if (GetInstance().mpScanCallback != nullptr) + { + DeviceLayer::SystemLayer().ScheduleLambda( []() + { + GetInstance().mpScanCallback->OnFinished( + NetworkCommissioning::Status::kSuccess, CharSpan(), + &mScanResponseIter); + GetInstance().mpScanCallback = nullptr; + } ); + } + } + else + { + while ( aScanResult->is_valid ) { + NetworkCommissioning::WiFiScanResponse scanResponse = {}; + chip::BitFlags security; + + security = GetInstance().ConvertSecuritytype(aScanResult->auth_mode); + + scanResponse.security.Set(security); + scanResponse.channel = aScanResult->channel; + scanResponse.rssi = aScanResult->rssi; + scanResponse.ssidLen = strnlen((char *)aScanResult->ssid, + DeviceLayer::Internal::kMaxWiFiSSIDLength); + memcpy(scanResponse.ssid, aScanResult->ssid, scanResponse.ssidLen); + memcpy(scanResponse.bssid, aScanResult->bssid, sizeof(scanResponse.bssid)); + + mScanResponseIter.Add(&scanResponse); + + aScanResult++; // process next result + } + } +} + +void GenioWiFiDriver::ScanNetworks(ByteSpan ssid, WiFiDriver::ScanCallback * callback) +{ + ChipLogProgress(NetworkProvisioning, "GenioWiFiDriver::ScanNetworks"); + + if (callback != nullptr) + { + mpScanCallback = callback; + if (!StartScanWiFiNetworks(ssid)) + { + ChipLogError(DeviceLayer, "ScanWiFiNetworks failed to start"); + mpScanCallback = nullptr; + callback->OnFinished(Status::kUnknownError, CharSpan(), nullptr); + } + } +} + +CHIP_ERROR GetConnectedNetwork(Network & network) +{ + ChipLogProgress(NetworkProvisioning, "GetConnectedNetwork"); + + void *filogicCtx = PlatformMgrImpl().mFilogicCtx; + + filogic_wifi_sta_prov_t wifi_prov; + + if (!filogic_wifi_sta_get_link_status_sync(filogicCtx) || + !filogic_wifi_sta_prov_get_sync(filogicCtx, &wifi_prov)) + { + return CHIP_ERROR_INCORRECT_STATE; + } + + uint8_t length = strnlen(wifi_prov.ssid, DeviceLayer::Internal::kMaxWiFiSSIDLength); + if (length > sizeof(network.networkID)) + { + ChipLogError(DeviceLayer, "SSID too long"); + return CHIP_ERROR_INTERNAL; + } + + memcpy(network.networkID, wifi_prov.ssid, length); + network.networkIDLen = length; + + return CHIP_NO_ERROR; +} + +size_t GenioWiFiDriver::WiFiNetworkIterator::Count() +{ + ChipLogProgress(NetworkProvisioning, "GenioWiFiDriver::WiFiNetworkIterator::Count"); + + return mDriver->mStagingNetwork.ssidLen == 0 ? 0 : 1; +} + +bool GenioWiFiDriver::WiFiNetworkIterator::Next(Network & item) +{ + ChipLogProgress(NetworkProvisioning, "GenioWiFiDriver::WiFiNetworkIterator::Next"); + + if (mExhausted || mDriver->mStagingNetwork.ssidLen == 0) + { + return false; + } + memcpy(item.networkID, mDriver->mStagingNetwork.ssid, mDriver->mStagingNetwork.ssidLen); + item.networkIDLen = mDriver->mStagingNetwork.ssidLen; + item.connected = false; + mExhausted = true; + + Network connectedNetwork; + CHIP_ERROR err = GetConnectedNetwork(connectedNetwork); + if (err == CHIP_NO_ERROR) + { + if (connectedNetwork.networkIDLen == item.networkIDLen && + memcmp(connectedNetwork.networkID, item.networkID, item.networkIDLen) == 0) + { + item.connected = true; + } + } + return true; +} + +} // namespace NetworkCommissioning +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/mt793x/NetworkCommissioningWiFiDriver.h b/src/platform/mt793x/NetworkCommissioningWiFiDriver.h new file mode 100644 index 00000000000000..4bf46fa0c272bf --- /dev/null +++ b/src/platform/mt793x/NetworkCommissioningWiFiDriver.h @@ -0,0 +1,151 @@ +/* + * + * Copyright (c) 2022 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once +#if CHIP_DEVICE_CONFIG_ENABLE_WIFI_STATION +#include +#include + +namespace chip { +namespace DeviceLayer { +namespace NetworkCommissioning { + +namespace { +constexpr uint8_t kMaxWiFiNetworks = 1; +constexpr uint8_t kWiFiScanNetworksTimeOutSeconds = 10; +constexpr uint8_t kWiFiConnectNetworkTimeoutSeconds = 20; +constexpr uint8_t kMaxWiFiScanAPs = 30; +} // namespace + +template +class GenioScanResponseIterator : public Iterator +{ +public: + GenioScanResponseIterator(T * apScanResponse) : mpScanResponse(apScanResponse) {} + size_t Count() override { return itemCount; } + bool Next(T & item) override + { + if (mpScanResponse == nullptr || currentIterating >= itemCount) + { + return false; + } + item = mpScanResponse[currentIterating]; + currentIterating++; + return true; + } + void Release() override + { + itemCount = currentIterating = 0; + Platform::MemoryFree(mpScanResponse); + mpScanResponse = nullptr; + } + + void Add(T * pResponse) + { + size_t tempCount = itemCount + 1; + mpScanResponse = static_cast(Platform::MemoryRealloc(mpScanResponse, kItemSize * tempCount)); + if (mpScanResponse) + { + // first item at index. update after the copy. + memcpy(&(mpScanResponse[itemCount]), pResponse, kItemSize); + itemCount = tempCount; + } + } + +private: + size_t currentIterating = 0; + size_t itemCount = 0; + static constexpr size_t kItemSize = sizeof(T); + T * mpScanResponse; +}; + +class GenioWiFiDriver final : public WiFiDriver +{ +public: + class WiFiNetworkIterator final : public NetworkIterator + { + public: + WiFiNetworkIterator(GenioWiFiDriver * aDriver) : mDriver(aDriver) {} + size_t Count() override; + bool Next(Network & item) override; + void Release() override { delete this; } + ~WiFiNetworkIterator() = default; + + private: + GenioWiFiDriver * mDriver; + bool mExhausted = false; + }; + + struct WiFiNetwork + { + char ssid[DeviceLayer::Internal::kMaxWiFiSSIDLength]; + uint8_t ssidLen = 0; + char credentials[DeviceLayer::Internal::kMaxWiFiKeyLength]; + uint8_t credentialsLen = 0; + uint8_t auth_mode = 0; + }; + + // BaseDriver + NetworkIterator * GetNetworks() override { return new WiFiNetworkIterator(this); } + CHIP_ERROR Init(NetworkStatusChangeCallback * networkStatusChangeCallback) override; + + // WirelessDriver + uint8_t GetMaxNetworks() override { return kMaxWiFiNetworks; } + uint8_t GetScanNetworkTimeoutSeconds() override { return kWiFiScanNetworksTimeOutSeconds; } + uint8_t GetConnectNetworkTimeoutSeconds() override { return kWiFiConnectNetworkTimeoutSeconds; } + + CHIP_ERROR CommitConfiguration() override; + CHIP_ERROR RevertConfiguration() override; + + Status RemoveNetwork(ByteSpan networkId, MutableCharSpan & outDebugText, uint8_t & outNetworkIndex) override; + Status ReorderNetwork(ByteSpan networkId, uint8_t index, MutableCharSpan & outDebugText) override; + void ConnectNetwork(ByteSpan networkId, ConnectCallback * callback) override; + + // WiFiDriver + Status AddOrUpdateNetwork(ByteSpan ssid, ByteSpan credentials, MutableCharSpan & outDebugText, + uint8_t & outNetworkIndex) override; + void ScanNetworks(ByteSpan ssid, ScanCallback * callback) override; + + CHIP_ERROR ConnectWiFiNetwork(const char * ssid, + uint8_t ssidLen, + const char * key, + uint8_t keyLen); + + chip::BitFlags ConvertSecuritytype(wifi_auth_mode_t auth_mode); + + void OnConnectWiFiNetwork(); + static GenioWiFiDriver & GetInstance() + { + static GenioWiFiDriver instance; + return instance; + } + +private: + bool NetworkMatch(const WiFiNetwork & network, ByteSpan networkId); + bool StartScanWiFiNetworks(ByteSpan ssid); + static void OnScanWiFiNetworkDone(wifi_scan_list_item_t * aScanResult); + + WiFiNetwork mSavedNetwork = {}; + WiFiNetwork mStagingNetwork = {}; + ScanCallback * mpScanCallback; + ConnectCallback * mpConnectCallback; +}; + +} // namespace NetworkCommissioning +} // namespace DeviceLayer +} // namespace chip +#endif diff --git a/src/platform/mt793x/OTAImageProcessorImpl.cpp b/src/platform/mt793x/OTAImageProcessorImpl.cpp new file mode 100644 index 00000000000000..d3f2190b588e6d --- /dev/null +++ b/src/platform/mt793x/OTAImageProcessorImpl.cpp @@ -0,0 +1,236 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "OTAImageProcessorImpl.h" +#include + +extern "C" { +#include "platform/bootloader/api/btl_interface.h" +} + +/// No error, operation OK +#define SL_BOOTLOADER_OK 0L + +namespace chip { + +// Define static memebers +uint8_t OTAImageProcessorImpl::mSlotId; +uint32_t OTAImageProcessorImpl::mWriteOffset; + +CHIP_ERROR OTAImageProcessorImpl::PrepareDownload() +{ + if (mParams.imageFile.empty()) + { + ChipLogError(SoftwareUpdate, "Invalid output image file supplied"); + return CHIP_ERROR_INTERNAL; + } + + DeviceLayer::PlatformMgr().ScheduleWork(HandlePrepareDownload, reinterpret_cast(this)); + return CHIP_NO_ERROR; +} + +CHIP_ERROR OTAImageProcessorImpl::Finalize() +{ + DeviceLayer::PlatformMgr().ScheduleWork(HandleFinalize, reinterpret_cast(this)); + return CHIP_NO_ERROR; +} + +CHIP_ERROR OTAImageProcessorImpl::Apply() +{ + uint32_t err = SL_BOOTLOADER_OK; + + ChipLogError(SoftwareUpdate, "OTAImageProcessorImpl::Apply()"); + + // Assuming that bootloader_verifyImage() call is not too expensive and + // doesn't need to be offloaded to a different task. Revisit if necessary. + err = bootloader_verifyImage(mSlotId, NULL); + if (err != SL_BOOTLOADER_OK) + { + ChipLogError(SoftwareUpdate, "bootloader_verifyImage error %ld", err); + return CHIP_ERROR_INTERNAL; + } + + err = bootloader_setImageToBootload(mSlotId); + if (err != SL_BOOTLOADER_OK) + { + ChipLogError(SoftwareUpdate, "setImageToBootload error %ld", err); + return CHIP_ERROR_INTERNAL; + } + + // This reboots the device + bootloader_rebootAndInstall(); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR OTAImageProcessorImpl::Abort() +{ + if (mParams.imageFile.empty()) + { + ChipLogError(SoftwareUpdate, "Invalid output image file supplied"); + return CHIP_ERROR_INTERNAL; + } + + DeviceLayer::PlatformMgr().ScheduleWork(HandleAbort, reinterpret_cast(this)); + return CHIP_NO_ERROR; +} + +CHIP_ERROR OTAImageProcessorImpl::ProcessBlock(ByteSpan & block) +{ + if ((block.data() == nullptr) || block.empty()) + { + return CHIP_ERROR_INVALID_ARGUMENT; + } + + // Store block data for HandleProcessBlock to access + CHIP_ERROR err = SetBlock(block); + if (err != CHIP_NO_ERROR) + { + ChipLogError(SoftwareUpdate, "Cannot set block data: %" CHIP_ERROR_FORMAT, err.Format()); + } + + DeviceLayer::PlatformMgr().ScheduleWork(HandleProcessBlock, reinterpret_cast(this)); + return CHIP_NO_ERROR; +} + +void OTAImageProcessorImpl::HandlePrepareDownload(intptr_t context) +{ + int32_t err = SL_BOOTLOADER_OK; + auto * imageProcessor = reinterpret_cast(context); + + if (imageProcessor == nullptr) + { + ChipLogError(SoftwareUpdate, "ImageProcessor context is null"); + return; + } + else if (imageProcessor->mDownloader == nullptr) + { + ChipLogError(SoftwareUpdate, "mDownloader is null"); + return; + } + + bootloader_init(); + mSlotId = 0; // Single slot until we support multiple images + mWriteOffset = 0; + + // Not calling bootloader_eraseStorageSlot(mSlotId) here because we erase during each write + + imageProcessor->mDownloader->OnPreparedForDownload(err == SL_BOOTLOADER_OK ? CHIP_NO_ERROR : CHIP_ERROR_INTERNAL); +} + +void OTAImageProcessorImpl::HandleFinalize(intptr_t context) +{ + auto * imageProcessor = reinterpret_cast(context); + if (imageProcessor == nullptr) + { + return; + } + + imageProcessor->ReleaseBlock(); + + ChipLogProgress(SoftwareUpdate, "OTA image downloaded to %s", imageProcessor->mParams.imageFile.data()); +} + +void OTAImageProcessorImpl::HandleAbort(intptr_t context) +{ + auto * imageProcessor = reinterpret_cast(context); + if (imageProcessor == nullptr) + { + return; + } + + // Not clearing the image storage area as it is done during each write + imageProcessor->ReleaseBlock(); +} + +void OTAImageProcessorImpl::HandleProcessBlock(intptr_t context) +{ + uint32_t err = SL_BOOTLOADER_OK; + auto * imageProcessor = reinterpret_cast(context); + if (imageProcessor == nullptr) + { + ChipLogError(SoftwareUpdate, "ImageProcessor context is null"); + return; + } + else if (imageProcessor->mDownloader == nullptr) + { + ChipLogError(SoftwareUpdate, "mDownloader is null"); + return; + } + + // TODO: Process block header if any + + err = bootloader_eraseWriteStorage(mSlotId, mWriteOffset, reinterpret_cast(imageProcessor->mBlock.data()), + imageProcessor->mBlock.size()); + + if (err) + { + ChipLogError(SoftwareUpdate, "bootloader_eraseWriteStorage err %ld", err); + + imageProcessor->mDownloader->EndDownload(CHIP_ERROR_WRITE_FAILED); + return; + } + + mWriteOffset += imageProcessor->mBlock.size(); // Keep our own track of how far we've written + imageProcessor->mParams.downloadedBytes += imageProcessor->mBlock.size(); + imageProcessor->mDownloader->FetchNextData(); +} + +// Store block data for HandleProcessBlock to access +CHIP_ERROR OTAImageProcessorImpl::SetBlock(ByteSpan & block) +{ + if ((block.data() == nullptr) || block.empty()) + { + return CHIP_NO_ERROR; + } + + // Allocate memory for block data if we don't have enough already + if (mBlock.size() < block.size()) + { + ReleaseBlock(); + + mBlock = MutableByteSpan(static_cast(chip::Platform::MemoryAlloc(block.size())), block.size()); + if (mBlock.data() == nullptr) + { + return CHIP_ERROR_NO_MEMORY; + } + } + + // Store the actual block data + CHIP_ERROR err = CopySpanToMutableSpan(block, mBlock); + if (err != CHIP_NO_ERROR) + { + ChipLogError(SoftwareUpdate, "Cannot copy block data: %" CHIP_ERROR_FORMAT, err.Format()); + return err; + } + + return CHIP_NO_ERROR; +} + +CHIP_ERROR OTAImageProcessorImpl::ReleaseBlock() +{ + if (mBlock.data() != nullptr) + { + chip::Platform::MemoryFree(mBlock.data()); + } + + mBlock = MutableByteSpan(); + return CHIP_NO_ERROR; +} + +} // namespace chip diff --git a/src/platform/mt793x/OTAImageProcessorImpl.h b/src/platform/mt793x/OTAImageProcessorImpl.h new file mode 100644 index 00000000000000..662b8607d4f0ca --- /dev/null +++ b/src/platform/mt793x/OTAImageProcessorImpl.h @@ -0,0 +1,62 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include +#include + +namespace chip { + +class OTAImageProcessorImpl : public OTAImageProcessorInterface +{ +public: + //////////// OTAImageProcessorInterface Implementation /////////////// + CHIP_ERROR PrepareDownload() override; + CHIP_ERROR Finalize() override; + CHIP_ERROR Apply() override; + CHIP_ERROR Abort() override; + CHIP_ERROR ProcessBlock(ByteSpan & block) override; + + void SetOTADownloader(OTADownloader * downloader) { mDownloader = downloader; } + +private: + //////////// Actual handlers for the OTAImageProcessorInterface /////////////// + static void HandlePrepareDownload(intptr_t context); + static void HandleFinalize(intptr_t context); + static void HandleAbort(intptr_t context); + static void HandleProcessBlock(intptr_t context); + + /** + * Called to allocate memory for mBlock if necessary and set it to block + */ + CHIP_ERROR SetBlock(ByteSpan & block); + + /** + * Called to release allocated memory for mBlock + */ + CHIP_ERROR ReleaseBlock(); + + static uint32_t mWriteOffset; // End of last written block + static uint8_t mSlotId; // Bootloader storage slot + MutableByteSpan mBlock; + OTADownloader * mDownloader; +}; + +} // namespace chip diff --git a/src/platform/mt793x/PlatformManagerImpl.cpp b/src/platform/mt793x/PlatformManagerImpl.cpp new file mode 100644 index 00000000000000..f63aa8c0ba2a91 --- /dev/null +++ b/src/platform/mt793x/PlatformManagerImpl.cpp @@ -0,0 +1,135 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2019 Nest Labs, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Provides an implementation of the PlatformManager object + * for MT793x platforms using the MT793x SDK. + */ +/* this file behaves like a config.h, comes first */ +#include + +#include +#include +#include + +#include +#include + +#if CHIP_DEVICE_CONFIG_ENABLE_WIFI +#include "wifi_api_ex.h" +#endif + + +extern "C" void PlatformLogPrint(int module, int level, const char * msg, va_list args) +{ + char log[256]; + int i; + + i = vsnprintf(log, sizeof(log), msg, args); + while ((--i) >= 0) { + if (log[i] == '\n' || log[i] == '\r' || log[i] == ' ') { + log[i] = '\0'; + continue; + } + break; + } + ChipLogError(DeviceLayer, "[%lu] FILOGIC %s", xTaskGetTickCount(), log); +} + + +namespace chip { +namespace DeviceLayer { + +PlatformManagerImpl PlatformManagerImpl::sInstance; + +CHIP_ERROR PlatformManagerImpl::_InitChipStack(void) +{ + CHIP_ERROR err; + + // Initialize the configuration system. + err = Internal::MT793XConfig::Init(); + SuccessOrExit(err); + SetConfigurationMgr(&ConfigurationManagerImpl::GetDefaultInstance()); + SetDiagnosticDataProvider(&DiagnosticDataProviderImpl::GetDefaultInstance()); + + mFilogicCtx = filogic_start_sync(); + assert(mFilogicCtx != NULL); + + assert(filogic_set_logv_callback_sync(mFilogicCtx, PlatformLogPrint)); + + filogic_set_event_callback_sync(mFilogicCtx, FilogicEventHandler); + + // Initialize LwIP. + mtk_tcpip_init(NULL, NULL); + + // Call _InitChipStack() on the generic implementation base class + // to finish the initialization process. + err = Internal::GenericPlatformManagerImpl_FreeRTOS::_InitChipStack(); + SuccessOrExit(err); + +exit: + return err; +} + +void PlatformManagerImpl::_Shutdown() +{ + uint64_t upTime = 0; + + if (GetDiagnosticDataProvider().GetUpTime(upTime) == CHIP_NO_ERROR) + { + uint32_t totalOperationalHours = 0; + + if (ConfigurationMgr().GetTotalOperationalHours(totalOperationalHours) == CHIP_NO_ERROR) + { + ConfigurationMgr().StoreTotalOperationalHours(totalOperationalHours + static_cast(upTime / 3600)); + } + else + { + ChipLogError(DeviceLayer, "Failed to get total operational hours of the Node"); + } + } + else + { + ChipLogError(DeviceLayer, "Failed to get current uptime since the Node’s last reboot"); + } + + Internal::GenericPlatformManagerImpl_FreeRTOS::_Shutdown(); +} + +void PlatformManagerImpl::FilogicEventHandler(void *c, + filogic_async_event_id_t event, + filogic_async_event_data *data) +{ + ChipDeviceEvent e = {0}; + + ChipLogProgress(DeviceLayer, "%s %s", __func__, filogic_event_to_name(event)); + + if (event < FILOGIC_EVENT_ID_MAX) { + e.Type = DeviceEventType::kMtkWiFiEvent; + memcpy(&e.Platform.MtkWiFiEvent.event_data, data, sizeof(*data)); + ChipLogError(DeviceLayer, "event %s", filogic_event_to_name(event)); + (void) sInstance.PostEvent(&e); + } else { + ChipLogError(DeviceLayer, "Unhandled event %d", event); + } +} + + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/mt793x/PlatformManagerImpl.h b/src/platform/mt793x/PlatformManagerImpl.h new file mode 100644 index 00000000000000..6a6ad7dc9a094e --- /dev/null +++ b/src/platform/mt793x/PlatformManagerImpl.h @@ -0,0 +1,107 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2019 Nest Labs, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Provides an implementation of the PlatformManager object + * for Genio platforms using the MediaTek SDK. + */ + +#pragma once + +#include +#if CHIP_DEVICE_CONFIG_ENABLE_WIFI +#include "wifi_api_ex.h" +#endif + +#include "filogic.h" + +namespace chip { +namespace DeviceLayer { + +/** + * Concrete implementation of the PlatformManager singleton object for the Genio platform. + */ +class PlatformManagerImpl final : public PlatformManager, public Internal::GenericPlatformManagerImpl_FreeRTOS +{ + // Allow the PlatformManager interface class to delegate method calls to + // the implementation methods provided by this class. + friend PlatformManager; + + // Allow the generic implementation base class to call helper methods on + // this class. +#ifndef DOXYGEN_SHOULD_SKIP_THIS + friend Internal::GenericPlatformManagerImpl_FreeRTOS; +#endif + +public: + // ===== Platform-specific members that may be accessed directly by the application. + static void FilogicEventHandler(void *c, + filogic_async_event_id_t event, + filogic_async_event_data *data); + + System::Clock::Timestamp GetStartTime() { return mStartTime; } + + void *mFilogicCtx; + +private: + + // ===== Methods that implement the PlatformManager abstract interface. + + CHIP_ERROR _InitChipStack(void); + void _Shutdown(void); + + // ===== Members for internal use by the following friends. + + friend PlatformManager & PlatformMgr(void); + friend PlatformManagerImpl & PlatformMgrImpl(void); + friend class Internal::BLEManagerImpl; + friend class ConnectivityManagerImpl; + + System::Clock::Timestamp mStartTime = System::Clock::kZero; + + static PlatformManagerImpl sInstance; + + using Internal::GenericPlatformManagerImpl_FreeRTOS::PostEventFromISR; +}; + +/** + * Returns the public interface of the PlatformManager singleton object. + * + * Chip applications should use this to access features of the PlatformManager object + * that are common to all platforms. + */ +inline PlatformManager & PlatformMgr(void) +{ + return PlatformManagerImpl::sInstance; +} + +/** + * Returns the platform-specific implementation of the PlatformManager + * singleton object. + * + * Chip applications can use this to gain access to features of the + * PlatformManager that are specific to the MT793x platform. + */ +inline PlatformManagerImpl & PlatformMgrImpl(void) +{ + return PlatformManagerImpl::sInstance; +} + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/mt793x/SystemPlatformConfig.h b/src/platform/mt793x/SystemPlatformConfig.h new file mode 100644 index 00000000000000..2cca1502974671 --- /dev/null +++ b/src/platform/mt793x/SystemPlatformConfig.h @@ -0,0 +1,53 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2019 Google LLC. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Platform-specific configuration overrides for the CHIP System + * Layer on MediaTek Genio Platforms. + * + */ + +#pragma once + +#include + +namespace chip { +namespace DeviceLayer { +struct ChipDeviceEvent; +} // namespace DeviceLayer +} // namespace chip + +// ==================== Platform Adaptations ==================== +#define CHIP_SYSTEM_CONFIG_PLATFORM_PROVIDES_TIME 1 +#define CHIP_SYSTEM_CONFIG_EVENT_OBJECT_TYPE const struct ::chip::DeviceLayer::ChipDeviceEvent * + +// ========== Platform-specific Configuration Overrides ========= + +#ifndef CHIP_SYSTEM_CONFIG_NUM_TIMERS +#define CHIP_SYSTEM_CONFIG_NUM_TIMERS 16 +#endif // CHIP_SYSTEM_CONFIG_NUM_TIMERS + +#define CHIP_CONFIG_MDNS_CACHE_SIZE 4 + +/* + * Overrides CHIP_SYSTEM_HEADER_RESERVE_SIZE in SystemConfig.h + * + * Note: hard to include header files needed for NIC_TX_HEAD_ROOM (62) + */ +#define CHIP_SYSTEM_HEADER_RESERVE_SIZE (62 + CHIP_SYSTEM_CRYPTO_HEADER_RESERVE_SIZE) diff --git a/src/platform/mt793x/SystemTimeSupport.cpp b/src/platform/mt793x/SystemTimeSupport.cpp new file mode 100644 index 00000000000000..3f7d09ed734396 --- /dev/null +++ b/src/platform/mt793x/SystemTimeSupport.cpp @@ -0,0 +1,125 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2018 Nest Labs, Inc. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Provides implementations of the CHIP System Layer platform + * time/clock functions that are suitable for use on the ESP32 platform. + */ +/* this file behaves like a config.h, comes first */ +#include + +#include +#include + +namespace chip { +namespace System { +namespace Clock { + +namespace Internal { +ClockImpl gClockImpl; +} // namespace Internal + +Microseconds64 ClockImpl::GetMonotonicMicroseconds64(void) +{ + return static_cast(0); +} + +Milliseconds64 ClockImpl::GetMonotonicMilliseconds64(void) +{ + return std::chrono::duration_cast(GetMonotonicMicroseconds64()); +} + +CHIP_ERROR ClockImpl::GetClock_RealTime(Clock::Microseconds64 & aCurTime) +{ + struct timeval tv; + if (gettimeofday(&tv, nullptr) != 0) + { + return CHIP_ERROR_POSIX(errno); + } + if (tv.tv_sec < CHIP_SYSTEM_CONFIG_VALID_REAL_TIME_THRESHOLD) + { + return CHIP_ERROR_REAL_TIME_NOT_SYNCED; + } + if (tv.tv_usec < 0) + { + return CHIP_ERROR_REAL_TIME_NOT_SYNCED; + } + static_assert(CHIP_SYSTEM_CONFIG_VALID_REAL_TIME_THRESHOLD >= 0, "We might be letting through negative tv_sec values!"); + aCurTime = Clock::Microseconds64((static_cast(tv.tv_sec) * UINT64_C(1000000)) + static_cast(tv.tv_usec)); + return CHIP_NO_ERROR; +} + +CHIP_ERROR ClockImpl::GetClock_RealTimeMS(Clock::Milliseconds64 & aCurTime) +{ + struct timeval tv; + if (gettimeofday(&tv, nullptr) != 0) + { + return CHIP_ERROR_POSIX(errno); + } + if (tv.tv_sec < CHIP_SYSTEM_CONFIG_VALID_REAL_TIME_THRESHOLD) + { + return CHIP_ERROR_REAL_TIME_NOT_SYNCED; + } + if (tv.tv_usec < 0) + { + return CHIP_ERROR_REAL_TIME_NOT_SYNCED; + } + static_assert(CHIP_SYSTEM_CONFIG_VALID_REAL_TIME_THRESHOLD >= 0, "We might be letting through negative tv_sec values!"); + aCurTime = + Clock::Milliseconds64((static_cast(tv.tv_sec) * UINT64_C(1000)) + (static_cast(tv.tv_usec) / 1000)); + return CHIP_NO_ERROR; +} + +CHIP_ERROR ClockImpl::SetClock_RealTime(Clock::Microseconds64 aNewCurTime) +{ + struct timeval tv; + tv.tv_sec = static_cast(aNewCurTime.count() / UINT64_C(1000000)); + tv.tv_usec = static_cast(aNewCurTime.count() % UINT64_C(1000000)); +// if (settimeofday(&tv, nullptr) != 0) +// { +// return (errno == EPERM) ? CHIP_ERROR_ACCESS_DENIED : CHIP_ERROR_POSIX(errno); +// } +#if CHIP_PROGRESS_LOGGING + { + const time_t timep = tv.tv_sec; + struct tm calendar; + localtime_r(&timep, &calendar); + ChipLogProgress(DeviceLayer, + "Real time clock set to %ld (%04d/%02d/%02d %02d:%02d:%02d UTC)", + tv.tv_sec, calendar.tm_year, + calendar.tm_mon, calendar.tm_mday, + calendar.tm_hour, calendar.tm_min, calendar.tm_sec); + } +#endif // CHIP_PROGRESS_LOGGING + return CHIP_NO_ERROR; +} + +CHIP_ERROR InitClock_RealTime() +{ + Clock::Microseconds64 curTime = + Clock::Microseconds64((static_cast(CHIP_SYSTEM_CONFIG_VALID_REAL_TIME_THRESHOLD) * UINT64_C(1000000))); + // Use CHIP_SYSTEM_CONFIG_VALID_REAL_TIME_THRESHOLD as the initial value of RealTime. + // Then the RealTime obtained from GetClock_RealTime will be always valid. + return System::SystemClock().SetClock_RealTime(curTime); +} + +} // namespace Clock +} // namespace System +} // namespace chip diff --git a/src/platform/mt793x/WarmPlatformConfig.h b/src/platform/mt793x/WarmPlatformConfig.h new file mode 100644 index 00000000000000..c6542a21e778c5 --- /dev/null +++ b/src/platform/mt793x/WarmPlatformConfig.h @@ -0,0 +1,39 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2019 Google LLC. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Platform-specific configuration overrides for the Chip + * Addressing and Routing Module (WARM) on Genio platforms + * using the MediaTek SDK. + * + */ + +#pragma once + +// ==================== Platform Adaptations ==================== + +#define WARM_CONFIG_SUPPORT_THREAD 1 +#define WARM_CONFIG_SUPPORT_THREAD_ROUTING 0 +#define WARM_CONFIG_SUPPORT_LEGACY6LOWPAN_NETWORK 0 +#define WARM_CONFIG_SUPPORT_WIFI 0 +#define WARM_CONFIG_SUPPORT_CELLULAR 0 + +// ========== Platform-specific Configuration Overrides ========= + +/* none so far */ diff --git a/src/platform/mt793x/args.gni b/src/platform/mt793x/args.gni new file mode 100644 index 00000000000000..d59406736774ae --- /dev/null +++ b/src/platform/mt793x/args.gni @@ -0,0 +1,48 @@ +# Copyright (c) 2020 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/chip.gni") +import("//build_overrides/mt793x_sdk.gni") +import("//build_overrides/pigweed.gni") + +import("${chip_root}/examples/platform/mt793x/args.gni") + +# ARM architecture flags will be set based on mt793x_family. +arm_platform_config = "${mt793x_sdk_build_root}/mt793x_arm.gni" + +mbedtls_target = "${mt793x_sdk_build_root}:mt793x_sdk" + +chip_device_platform = "mt793x" + +# Network configuration + +lwip_platform = "mt793x" + +# Use our porting instad of //third_party/lwip + +lwip_root = "${chip_root}/third_party/mt793x_sdk/lwip" + +chip_mdns = "platform" +chip_inet_config_enable_ipv4 = false + +chip_build_libshell = true + +chip_build_tests = false + +chip_config_memory_management = "platform" + +pw_build_LINK_DEPS = [ + "$dir_pw_assert:impl", + "$dir_pw_log:impl", +] diff --git a/src/platform/mt793x/freertos_bluetooth.h b/src/platform/mt793x/freertos_bluetooth.h new file mode 100644 index 00000000000000..862b71550ec9f8 --- /dev/null +++ b/src/platform/mt793x/freertos_bluetooth.h @@ -0,0 +1,84 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2020 Google LLC. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#if __cplusplus +extern "C" { +#endif + +#include "FreeRTOS.h" +#include "event_groups.h" +#include "semphr.h" +#include "task.h" +#include "timers.h" + +#include "sl_bt_api.h" + +#define BLE_STACK_TASK_NAME "BLE_STACK" +#define BLE_LINK_TASK_NAME "BLE_LINK" + +// Bluetooth event flag group +extern EventGroupHandle_t bluetooth_event_flags; +// Bluetooth event flag definitions +#define BLUETOOTH_EVENT_FLAG_STACK (0x01u) // Bluetooth task needs an update +#define BLUETOOTH_EVENT_FLAG_LL (0x02u) // Linklayer task needs an update +#define BLUETOOTH_EVENT_FLAG_CMD_WAITING (0x04u) // BGAPI command is waiting to be processed +#define BLUETOOTH_EVENT_FLAG_RSP_WAITING (0x08u) // BGAPI response is waiting to be processed +#define BLUETOOTH_EVENT_FLAG_EVT_WAITING (0x10u) // BGAPI event is waiting to be processed +#define BLUETOOTH_EVENT_FLAG_EVT_HANDLED (0x20u) // BGAPI event is handled + +// Bluetooth event data pointer +extern volatile sl_bt_msg_t * bluetooth_evt; + +// Function prototype for initializing Bluetooth stack. +typedef sl_status_t (*bluetooth_stack_init_func)(); + +/** + * Start Bluetooth tasks. The given Bluetooth stack initialization function + * will be called at a proper time. Application should not initialize + * Bluetooth stack anywhere else. + * + * @param ll_priority link layer task priority + * @param stack_priority Bluetooth stack task priority + * @param initialize_bluetooth_stack The function for initializing Bluetooth stack + */ +sl_status_t bluetooth_start(UBaseType_t ll_priority, UBaseType_t stack_priority, + bluetooth_stack_init_func initialize_bluetooth_stack); + +// Set the callback for wakeup, Bluetooth task will call this when it has a new event +// It must only used to wake up application task, for example by posting task semaphore +typedef void (*wakeupCallback)(void); +void BluetoothSetWakeupCallback(wakeupCallback cb); +// Bluetooth stack needs an update +extern void BluetoothUpdate(void); +// Linklayer is updated +extern void BluetoothLLCallback(void); + +// Mutex functions for using Bluetooth from multiple tasks +void BluetoothPend(void); +void BluetoothPost(void); + +void vRaiseEventFlagBasedOnContext(EventGroupHandle_t xEventGroup, EventBits_t uxBitsToWaitFor); +BaseType_t vSendToQueueBasedOnContext(QueueHandle_t xQueue, void * xItemToQueue, TickType_t xTicksToWait, + BaseType_t * pxHigherPriorityTaskWoken); + +#if __cplusplus +} +#endif diff --git a/src/platform/mt793x/gatt.xml b/src/platform/mt793x/gatt.xml new file mode 100644 index 00000000000000..b346d14bdbeab9 --- /dev/null +++ b/src/platform/mt793x/gatt.xml @@ -0,0 +1,106 @@ + + + + + + + + + Abstract: The generic_access service contains generic information about the device. All available Characteristics are readonly. + + + + + Empty Example + + + + + + + + + Abstract: The external appearance of this device. The values are composed of a category (10-bits) and sub-categories (6-bits). + 0000 + + + + + + + + + Abstract: The Device Information Service exposes manufacturer and/or vendor information about a device. Summary: This service exposes manufacturer information about a device. The Device Information Service is instantiated as a Primary Service. Only one instance of the Device Information Service is exposed on a device. + + + + Abstract: The value of this characteristic is a UTF-8 string representing the name of the manufacturer of the device. + MediaTek + + + + + + + + Abstract: The value of this characteristic is a UTF-8 string representing the model number assigned by the device vendor. + Blue Gecko + + + + + + + + Abstract: The SYSTEM ID characteristic consists of a structure with two fields. The first field are the LSOs and the second field contains the MSOs. This is a 64-bit structure which consists of a 40-bit manufacturer-defined identifier concatenated with a 24 bit unique Organizationally Unique Identifier (OUI). The OUI is issued by the IEEE Registration Authority (http://standards.ieee.org/regauth/index.html) and is required to be used in accordance with IEEE Standard 802-2001.6 while the least significant 40 bits are manufacturer defined. If System ID generated based on a Bluetooth Device Address, it is required to be done as follows. System ID and the Bluetooth Device Address have a very similar structure: a Bluetooth Device Address is 48 bits in length and consists of a 24 bit Company Assigned Identifier (manufacturer defined identifier) concatenated with a 24 bit Company Identifier (OUI). In order to encapsulate a Bluetooth Device Address as System ID, the Company Identifier is concatenated with 0xFFFE followed by the Company Assigned Identifier of the Bluetooth Address. For more guidelines related to EUI-64, refer to http://standards.ieee.org/develop/regauth/tut/eui64.pdf. Examples: If the system ID is based of a Bluetooth Device Address with a Company Identifier (OUI) is 0x123456 and the Company Assigned Identifier is 0x9ABCDE, then the System Identifier is required to be 0x123456FFFE9ABCDE. + 000102030405 + + + + + + + + + Custom service + + + + Custom characteristic + 00 + + + + + + + + + Custom characteristic + 00 + + + + + + + + + + diff --git a/src/platform/mt793x/gatt_db.c b/src/platform/mt793x/gatt_db.c new file mode 100644 index 00000000000000..ea8c55764a6824 --- /dev/null +++ b/src/platform/mt793x/gatt_db.c @@ -0,0 +1,23 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2020 Google LLC. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/******************************************************************** + * Autogenerated file, do not edit. + *******************************************************************/ + +#include diff --git a/src/platform/mt793x/gatt_db.h b/src/platform/mt793x/gatt_db.h new file mode 100644 index 00000000000000..ca179934af5151 --- /dev/null +++ b/src/platform/mt793x/gatt_db.h @@ -0,0 +1,46 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2020 Google LLC. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/******************************************************************** + * Autogenerated file, do not edit. + *******************************************************************/ + +#ifndef __GATT_DB_H +#define __GATT_DB_H + +#if __cplusplus +extern "C" { +#endif + +//#include "sli_bt_gattdb_def.h" + +//extern const sli_bt_gattdb_t gattdb; + +#define gattdb_service_changed_char 3 +#define gattdb_database_hash 6 +#define gattdb_client_support_features 8 +#define gattdb_device_name 11 +#define gattdb_CHIPoBLEChar_Rx 23 +#define gattdb_CHIPoBLEChar_Tx 25 +#define gattdb_ota_control 29 + +#if __cplusplus +} +#endif + +#endif // __GATT_DB_H diff --git a/src/platform/mt793x/lwip/BUILD.gn b/src/platform/mt793x/lwip/BUILD.gn new file mode 100644 index 00000000000000..a6a5e3b428a264 --- /dev/null +++ b/src/platform/mt793x/lwip/BUILD.gn @@ -0,0 +1,64 @@ +# Copyright (c) 2020 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/build.gni") +import("//build_overrides/chip.gni") +import("${chip_root}/src/platform/mt793x/lwip/lwip.gni") + +import("${chip_root}/build/chip/buildconfig_header.gni") +import("${chip_root}/src/lwip/lwip.gni") +import("${lwip_root}/lwip.gni") + +assert(chip_with_lwip) + +assert(lwip_platform == "external", "Unsupported lwIP platform: ${lwip_platform}") + +declare_args() { + # Enable lwIP debugging. + lwip_debug = is_debug +} + +import("//build_overrides/mt793x_sdk.gni") +import("${mt793x_sdk_build_root}/mt793x_sdk.gni") + +#buildconfig_header("lwip_buildconfig") { +# header = "lwip_buildconfig.h" +# header_dir = "lwip" +# +# defines = [ "HAVE_LWIP_UDP_BIND_NETIF=1" ] +# if (lwip_platform != "external") { +# if (current_os == "android") { +# defines += [ "LWIP_NO_STDINT_H=1" ] +# } +# } +#} + +config("lwip_config") { + include_dirs = [ "${mt793x_sdk_root}/project/mt7933_hdk/apps/${mt793x_project_name}/inc" ] +} + +lwip_target("lwip") { + public = [ "${mt793x_sdk_root}/project/mt7933_hdk/apps/${mt793x_project_name}/inc/lwipopts.h" ] + + sources = [] + + public_deps = [ ":lwip_buildconfig" ] + + public_deps += [ "${mt793x_sdk_build_root}:mt793x_sdk" ] + + public_configs = [ + ":lwip_config", + "${chip_root}/src:includes", + ] +} diff --git a/src/platform/mt793x/lwip/lwip.gni b/src/platform/mt793x/lwip/lwip.gni new file mode 100644 index 00000000000000..a7ab9fefef1a4c --- /dev/null +++ b/src/platform/mt793x/lwip/lwip.gni @@ -0,0 +1,19 @@ +# Copyright (c) 2020 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/build.gni") +import("//build_overrides/chip.gni") + +lwip_remove_configs = [ "${build_root}/config/compiler:warnings_default" ] +lwip_add_configs = [ "${build_root}/config/compiler:warnings_third_party" ] diff --git a/src/platform/mt793x/mt793x-mbedtls-config.h b/src/platform/mt793x/mt793x-mbedtls-config.h new file mode 100644 index 00000000000000..b37edfcdfbb135 --- /dev/null +++ b/src/platform/mt793x/mt793x-mbedtls-config.h @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2020, The OpenThread Authors. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the copyright holder nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include +#include +#include + +#ifdef MT793X_PORTING +#include "em_device.h" +#include "em_se.h" +#endif + +/** + * Enable H Crypto and Entropy modules + */ +#define MBEDTLS_AES_C +#define MBEDTLS_ECP_C +#define MBEDTLS_ECDH_C +#define MBEDTLS_ENTROPY_C +#define MBEDTLS_SHA256_C +#define MBEDTLS_TRNG_C + +#define MBEDTLS_PLATFORM_SNPRINTF_MACRO snprintf + +#define MBEDTLS_AES_ROM_TABLES +#define MBEDTLS_ASN1_PARSE_C +#define MBEDTLS_ASN1_WRITE_C +#define MBEDTLS_BASE64_C +#define MBEDTLS_BIGNUM_C +#define MBEDTLS_CCM_C +#define MBEDTLS_CIPHER_C +#define MBEDTLS_CMAC_C +#define MBEDTLS_CTR_DRBG_C +#define MBEDTLS_ECDH_LEGACY_CONTEXT +#define MBEDTLS_ECDSA_C +#define MBEDTLS_ECDSA_DETERMINISTIC +#define MBEDTLS_ECJPAKE_C +#define MBEDTLS_ECP_DP_SECP256R1_ENABLED +#define MBEDTLS_ECP_NIST_OPTIM +#define MBEDTLS_ENTROPY_FORCE_SHA256 +#define MBEDTLS_ENTROPY_HARDWARE_ALT +#define MBEDTLS_ERROR_STRERROR_DUMMY +#define MBEDTLS_HAVE_ASM +#define MBEDTLS_HKDF_C +#define MBEDTLS_HMAC_DRBG_C +#define MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA_ENABLED +#define MBEDTLS_KEY_EXCHANGE_ECJPAKE_ENABLED +#define MBEDTLS_KEY_EXCHANGE_PSK_ENABLED +#define MBEDTLS_MD_C +#define MBEDTLS_NO_PLATFORM_ENTROPY +#define MBEDTLS_OID_C +#define MBEDTLS_PEM_PARSE_C +#define MBEDTLS_PEM_WRITE_C +#define MBEDTLS_PK_C +#define MBEDTLS_PK_PARSE_C +#define MBEDTLS_PK_WRITE_C +#define MBEDTLS_PKCS5_C +#define MBEDTLS_PLATFORM_C +#define MBEDTLS_PLATFORM_MEMORY +#define MBEDTLS_PLATFORM_NO_STD_FUNCTIONS +#define MBEDTLS_PSA_CRYPTO_C +#define MBEDTLS_PSA_CRYPTO_CONFIG +#define MBEDTLS_PSA_CRYPTO_DRIVERS +//#define MBEDTLS_PSA_CRYPTO_STORAGE_C +#define MBEDTLS_SHA256_SMALLER +#define MBEDTLS_SHA512_C +#define MBEDTLS_SSL_CLI_C +#define MBEDTLS_SSL_COOKIE_C +#define MBEDTLS_SSL_DTLS_ANTI_REPLAY +#define MBEDTLS_SSL_DTLS_HELLO_VERIFY +#define MBEDTLS_SSL_EXPORT_KEYS +#define MBEDTLS_SSL_KEEP_PEER_CERTIFICATE +#define MBEDTLS_SSL_MAX_FRAGMENT_LENGTH +#define MBEDTLS_SSL_PROTO_TLS1_2 +#define MBEDTLS_SSL_PROTO_DTLS +#define MBEDTLS_SSL_SRV_C +#define MBEDTLS_SSL_TLS_C +#define MBEDTLS_X509_CREATE_C +#define MBEDTLS_X509_CSR_WRITE_C +#define MBEDTLS_X509_CRL_PARSE_C +#define MBEDTLS_X509_CRT_PARSE_C +#define MBEDTLS_X509_CSR_PARSE_C +#define MBEDTLS_X509_USE_C + +#define MBEDTLS_MPI_WINDOW_SIZE 1 /**< Maximum windows size used. */ +#define MBEDTLS_MPI_MAX_SIZE 32 /**< Maximum number of bytes for usable MPIs. */ +#define MBEDTLS_ECP_MAX_BITS 256 /**< Maximum bit size of groups */ +#define MBEDTLS_ECP_WINDOW_SIZE 2 /**< Maximum window size used */ +#define MBEDTLS_ECP_FIXED_POINT_OPTIM 0 /**< Enable fixed-point speed-up */ +#define MBEDTLS_ENTROPY_MAX_SOURCES 2 /**< Maximum number of sources supported */ + +#if OPENTHREAD_CONFIG_COAP_SECURE_API_ENABLE +#define MBEDTLS_SSL_MAX_CONTENT_LEN 900 /**< Maxium fragment length in bytes */ +#else +#define MBEDTLS_SSL_MAX_CONTENT_LEN 768 /**< Maxium fragment length in bytes */ +#endif + +#define MBEDTLS_SSL_CIPHERSUITES MBEDTLS_TLS_ECJPAKE_WITH_AES_128_CCM_8 + +#define MBEDTLS_CIPHER_MODE_WITH_PADDING + +#ifdef MT793X_PORTING +#include "check_crypto_config.h" +#include "config-device-acceleration.h" +#include "mbedtls/check_config.h" +#include "mbedtls/config_psa.h" +#endif diff --git a/src/system/BUILD.gn b/src/system/BUILD.gn index a70b943e1d14d2..97a13e1afc94cc 100644 --- a/src/system/BUILD.gn +++ b/src/system/BUILD.gn @@ -53,6 +53,8 @@ if (chip_device_platform == "cc13x2_26x2") { import("//build_overrides/p6.gni") } else if (chip_device_platform == "cyw30739") { import("//build_overrides/cyw30739_sdk.gni") +} else if (chip_device_platform == "mt793x") { + import("//build_overrides/mt793x_sdk.gni") } buildconfig_header("system_buildconfig") { @@ -163,6 +165,10 @@ source_set("system_config_header") { # Add platform here as needed. } } + + if (chip_device_platform == "mt793x") { + public_deps += [ "${mt793x_sdk_build_root}:mt793x_sdk" ] + } } static_library("system") { diff --git a/third_party/mt793x_sdk/BUILD.gn b/third_party/mt793x_sdk/BUILD.gn new file mode 100644 index 00000000000000..a6e6f2db3ed65f --- /dev/null +++ b/third_party/mt793x_sdk/BUILD.gn @@ -0,0 +1,25 @@ +# Copyright (c) 2020 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/mt793x_sdk.gni") +import("${mt793x_sdk_build_root}/mt793x_sdk.gni") + +declare_args() { + # Build target to use for mt793x SDK. Use this to set global SDK defines. + mt793x_sdk_target = "" +} + +group("mt793x_sdk") { + public_deps = [ mt793x_sdk_target ] +} diff --git a/third_party/mt793x_sdk/filogic b/third_party/mt793x_sdk/filogic new file mode 160000 index 00000000000000..c84f611d399d23 --- /dev/null +++ b/third_party/mt793x_sdk/filogic @@ -0,0 +1 @@ +Subproject commit c84f611d399d2350b2c510bd005fa6703d75fc5a diff --git a/third_party/mt793x_sdk/mt793x_arm.gni b/third_party/mt793x_sdk/mt793x_arm.gni new file mode 100644 index 00000000000000..55396473e6ed62 --- /dev/null +++ b/third_party/mt793x_sdk/mt793x_arm.gni @@ -0,0 +1,19 @@ +# Copyright (c) 2022 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +arm_arch = "armv8-m.main+dsp" +arm_abi = "aapcs" +arm_cpu = "cortex-m33" +arm_float_abi = "hard" +arm_fpu = "fpv5-sp-d16" diff --git a/third_party/mt793x_sdk/mt793x_executable.gni b/third_party/mt793x_sdk/mt793x_executable.gni new file mode 100644 index 00000000000000..29f310c7448bf3 --- /dev/null +++ b/third_party/mt793x_sdk/mt793x_executable.gni @@ -0,0 +1,72 @@ +# Copyright (c) 2020 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/build.gni") +import("//build_overrides/chip.gni") +import("//build_overrides/mt793x_sdk.gni") +import("${build_root}/toolchain/flashable_executable.gni") + +template("mt793x_executable") { + output_base_name = get_path_info(invoker.output_name, "name") + + objcopy_image_name = output_base_name + ".bin" + objcopy_image_format = "binary" + objcopy = "arm-none-eabi-objcopy" + + flash_target_name = target_name + ".flash_executable" + flashbundle_name = "${target_name}.flashbundle.txt" + flashable_executable(flash_target_name) { + forward_variables_from(invoker, "*") + } + + action("scatter_file") { + script = "${mt793x_sdk_build_root}/filogic/project/mt7933_hdk/apps/matter_sdk/scripts/scatter_file_generator.py" + outputs = [ + "${target_gen_dir}/scatter.ini" + ] + + args = [ + "--output", "/" + rebase_path(root_out_dir, "/") + "/scatter.ini", + "--bl_path", "mt7931an_bootloader-xip.sgn", + "--img_path", "${objcopy_image_name}", + "--bt_path", "BT_RAM_CODE_MT7933_2_1_hdr.bin", + "--wifi_path", "WIFI_RAM_CODE_MT7933_ALL.bin", + ] + + gen_deps = [":$flash_target_name"] + } + + action("copy_file") { + script = "${mt793x_sdk_build_root}/filogic/project/mt7933_hdk/apps/matter_sdk/scripts/copy_file.py" + outputs = [ + "${target_out_dir}" + ] + + args = [ + "--outputdir", "/" + rebase_path(root_out_dir, "/"), + "--bl_path", rebase_path(mt793x_sdk_build_root, root_out_dir) + "/filogic/project/mt7933_hdk/apps/matter_sdk/bootloader/mt7931an_bootloader-xip.sgn", + "--bt_path", rebase_path(mt793x_sdk_build_root, root_out_dir) + "/filogic/prebuilt/driver/chip/mt7933/BT_RAM_CODE_MT7933_2_1_hdr.bin", + "--wifi_path", rebase_path(mt793x_sdk_build_root, root_out_dir) + "/filogic/prebuilt/driver/chip/mt7933/WIFI_RAM_CODE_MT7933_ALL.bin", + ] + + gen_deps = [":$flash_target_name"] + } + group(target_name) { + deps = [ + ":$flash_target_name", + ":scatter_file", + ":copy_file", + ] + } +} diff --git a/third_party/mt793x_sdk/mt793x_sdk.gni b/third_party/mt793x_sdk/mt793x_sdk.gni new file mode 100644 index 00000000000000..60d0d7615cfa6a --- /dev/null +++ b/third_party/mt793x_sdk/mt793x_sdk.gni @@ -0,0 +1,103 @@ +# Copyright (c) 2022 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +import("//build_overrides/chip.gni") +import("//build_overrides/mbedtls.gni") +import("//build_overrides/mt793x_sdk.gni") +import("${chip_root}/src/crypto/crypto.gni") +import("${chip_root}/src/platform/mt793x/args.gni") +import("${chip_root}/src/platform/mt793x/lwip/lwip.gni") + +# +# Defines an mt793x SDK build target. +# +# Parameters: +# sources - Extra source files to build. +# + +declare_args() { + mt793x_sdk_developer = getenv("MTK_DEV") +} + +if (mt793x_sdk_developer == "") { + import("${mt793x_sdk_build_root}/filogic/project/mt7933_hdk/apps/matter_sdk/matter_sdk.gni") +} else { + import("${mt793x_sdk_build_root}/filogic/project/mt7933_hdk/apps/matter_sdk/matter_sdk_internal.gni") +} + +template("mt793x_sdk") { + sdk_target_name = target_name + + matter_sdk("matter_sdk") { + include_dirs = [] + + if (defined(invoker.include_dirs)) { + include_dirs += invoker.include_dirs + } + + include_dirs += [ + "${lwip_root}/repo/lwip/ports/include", + "${lwip_root}/repo/lwip/src/include", + ] + + defines = [] + + if (chip_mdns == "platform") { + defines += [ + "OPENTHREAD_CONFIG_SRP_CLIENT_ENABLE=1", + "OPENTHREAD_CONFIG_ECDSA_ENABLE=1", + "OPENTHREAD_CONFIG_DNS_CLIENT_SERVICE_DISCOVERY_ENABLE=1", + "OPENTHREAD_CONFIG_DNS_CLIENT_ENABLE=1", + ] + } + } + + config("${sdk_target_name}_config") { + if (!defined(include_dirs)) { + include_dirs = [] + } + + if (defined(invoker.include_dirs)) { + include_dirs += invoker.include_dirs + } + + libs = [] + + defines = [] + + if (defined(invoker.defines)) { + defines += invoker.defines + } + + } + + # TODO - Break up this monolith and make it configurable. + source_set(sdk_target_name) { + forward_variables_from(invoker, "*") + + if (!defined(sources)) { + sources = [] + } + + if (!defined(public_configs)) { + public_configs = [] + } + + public_deps = [ + ":matter_sdk", + ] + + public_configs += [ ":${sdk_target_name}_config", ] + } +}