├── .github ├── PULL_REQUEST_TEMPLATE.md └── workflows │ ├── build_example.yml │ ├── build_test.yml │ ├── issue_comment.yml │ ├── new_issues.yml │ ├── new_prs.yml │ └── upload_component.yml ├── .gitignore ├── .gitlab-ci.yml ├── .pre-commit-config.yaml ├── README.md ├── README_CN.md ├── components ├── mesh_lite │ ├── CHANGELOG.md │ ├── CHANGELOG_CN.md │ ├── CMakeLists.txt │ ├── Kconfig │ ├── README.md │ ├── User_Guide.md │ ├── User_Guide_CN.md │ ├── docs │ │ └── _static │ │ │ ├── Network_Construction_Example.png │ │ │ ├── Schematic_diagram_of_bidirectional_data_flow.jpg │ │ │ ├── mesh-root-node-failure.png │ │ │ ├── root_node_election.png │ │ │ └── wireless_debug.drawio │ ├── idf_component.yml │ ├── include │ │ ├── esp_mesh_lite.h │ │ ├── esp_mesh_lite_core.h │ │ ├── esp_mesh_lite_espnow.h │ │ ├── esp_mesh_lite_log.h │ │ ├── esp_mesh_lite_port.h │ │ ├── esp_mesh_lite_wireless_debug.h │ │ ├── mesh_lite.pb-c.h │ │ ├── wifi_prov_mgr.h │ │ └── zero_provisioning.h │ ├── lib │ │ ├── VERSION │ │ ├── libesp_mesh_lite_esp32.a │ │ ├── libesp_mesh_lite_esp32c2.a │ │ ├── libesp_mesh_lite_esp32c3.a │ │ ├── libesp_mesh_lite_esp32c5.a │ │ ├── libesp_mesh_lite_esp32c6.a │ │ ├── libesp_mesh_lite_esp32c61.a │ │ ├── libesp_mesh_lite_esp32s2.a │ │ └── libesp_mesh_lite_esp32s3.a │ ├── license.txt │ └── src │ │ ├── esp_mesh_lite.c │ │ ├── esp_mesh_lite_espnow.c │ │ ├── esp_mesh_lite_log.c │ │ ├── esp_mesh_lite_port.c │ │ ├── esp_mesh_lite_wireless_debug.c │ │ ├── mesh_lite.pb-c.c │ │ ├── mesh_lite.proto │ │ ├── proto_generate_CN.md │ │ ├── proto_generate_EN.md │ │ └── wifi_prov │ │ ├── wifi_prov_mgr.c │ │ └── zero_provisioning.c └── wifi_provisioning │ ├── CMakeLists.txt │ ├── Kconfig │ ├── VERSION │ ├── include │ └── wifi_provisioning │ │ ├── manager.h │ │ ├── scheme_ble.h │ │ ├── scheme_console.h │ │ ├── scheme_softap.h │ │ ├── wifi_config.h │ │ └── wifi_scan.h │ ├── proto-c │ ├── constants.pb-c.h │ ├── wifi_config.pb-c.c │ ├── wifi_config.pb-c.h │ ├── wifi_constants.pb-c.c │ ├── wifi_constants.pb-c.h │ ├── wifi_ctrl.pb-c.c │ ├── wifi_ctrl.pb-c.h │ ├── wifi_scan.pb-c.c │ └── wifi_scan.pb-c.h │ ├── proto │ ├── CMakeLists.txt │ ├── README.md │ ├── makefile │ ├── wifi_config.proto │ ├── wifi_constants.proto │ ├── wifi_ctrl.proto │ └── wifi_scan.proto │ ├── python │ ├── wifi_config_pb2.py │ ├── wifi_constants_pb2.py │ ├── wifi_ctrl_pb2.py │ └── wifi_scan_pb2.py │ └── src │ ├── handlers.c │ ├── manager.c │ ├── scheme_ble.c │ ├── scheme_console.c │ ├── scheme_softap.c │ ├── wifi_config.c │ ├── wifi_ctrl.c │ ├── wifi_ctrl.h │ ├── wifi_provisioning_priv.h │ └── wifi_scan.c ├── examples ├── mesh_local_control │ ├── CMakeLists.txt │ ├── README.md │ ├── README_CN.md │ ├── device_config.png │ ├── main │ │ ├── CMakeLists.txt │ │ ├── Kconfig.projbuild │ │ ├── idf_component.yml │ │ └── local_control.c │ ├── sdkconfig.defaults │ ├── sdkconfig.defaults.esp32c2 │ └── sdkconfig.eth ├── mesh_wifi_provisioning │ ├── CMakeLists.txt │ ├── README.md │ ├── README_CN.md │ ├── main │ │ ├── CMakeLists.txt │ │ ├── Kconfig.projbuild │ │ ├── idf_component.yml │ │ └── mesh_wifi_provisioning.c │ ├── sdkconfig.defaults │ └── sdkconfig.defaults.esp32c2 ├── no_router │ ├── CMakeLists.txt │ ├── README.md │ ├── README_CN.md │ ├── example_config.png │ ├── main │ │ ├── CMakeLists.txt │ │ ├── Kconfig.projbuild │ │ ├── idf_component.yml │ │ └── no_router.c │ ├── mesh_config.png │ ├── sdkconfig.defaults │ └── sdkconfig.defaults.esp32c2 ├── rainmaker │ ├── led_light │ │ ├── CMakeLists.txt │ │ ├── README.md │ │ ├── README_CN.md │ │ ├── _static │ │ │ ├── child_done.png │ │ │ ├── click_group.png │ │ │ ├── find_devices.jpg │ │ │ ├── group_control.png │ │ │ ├── mesh_page.png │ │ │ ├── root_control.png │ │ │ ├── root_device_of_common.png │ │ │ ├── root_device_of_mesh.png │ │ │ ├── root_done.png │ │ │ ├── select_child_devices.jpg │ │ │ ├── select_device_for_group.png │ │ │ ├── select_network.jpg │ │ │ └── select_root_node.png │ │ ├── components │ │ │ ├── app_bridge │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── app_bridge.c │ │ │ │ ├── app_bridge.h │ │ │ │ └── app_mesh_lite_comm.c │ │ │ ├── app_insights │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Kconfig │ │ │ │ ├── app_insights.c │ │ │ │ ├── app_insights.h │ │ │ │ ├── component.mk │ │ │ │ └── idf_component.yml │ │ │ ├── app_light │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Kconfig.projbuild │ │ │ │ ├── app_light.c │ │ │ │ ├── app_light.h │ │ │ │ └── idf_component.yml │ │ │ ├── app_rainmaker │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── app_rainmaker.c │ │ │ │ ├── app_rainmaker.h │ │ │ │ ├── app_rainmaker_ota.c │ │ │ │ ├── app_rainmaker_ota.h │ │ │ │ ├── app_rainmaker_ota_topic.c │ │ │ │ └── server.crt │ │ │ ├── app_wifi │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── Kconfig.projbuild │ │ │ │ ├── app_wifi.c │ │ │ │ └── app_wifi.h │ │ │ └── group_control │ │ │ │ ├── CMakeLists.txt │ │ │ │ ├── app_espnow.c │ │ │ │ └── app_espnow.h │ │ ├── main │ │ │ ├── CMakeLists.txt │ │ │ ├── Kconfig.projbuild │ │ │ ├── app_main.c │ │ │ └── idf_component.yml │ │ ├── partition_table │ │ │ ├── partitions_2MB.csv │ │ │ └── partitions_4MB.csv │ │ ├── sdkconfig.defaults │ │ ├── sdkconfig.defaults.esp32 │ │ ├── sdkconfig.defaults.esp32c2 │ │ ├── sdkconfig.defaults.esp32c3 │ │ ├── sdkconfig.defaults.esp32c6 │ │ └── sdkconfig.defaults.esp32s3 │ └── provisioning_controller │ │ ├── CMakeLists.txt │ │ ├── README.md │ │ ├── README_CN.md │ │ ├── main │ │ ├── CMakeLists.txt │ │ ├── Kconfig.projbuild │ │ ├── app_espnow.c │ │ ├── app_espnow.h │ │ ├── app_main.c │ │ └── idf_component.yml │ │ └── sdkconfig.defaults └── wireless_debug │ ├── CMakeLists.txt │ ├── README.md │ ├── README_CN.md │ ├── main │ ├── CMakeLists.txt │ ├── Kconfig.projbuild │ ├── idf_component.yml │ └── wireless_debug.c │ ├── sdkconfig.defaults │ ├── sdkconfig.defaults.esp32c2 │ ├── sdkconfig.eth │ └── sdkconfig.leafnode └── tools └── ci ├── astyle-rules.yml ├── check_copyright_config.yaml ├── check_copyright_ignore.txt ├── check_executables.py ├── executable-list.txt └── idf_ci_utils.py /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | # Checklist for new Board Support package or Component 2 | 3 | - [ ] Component contains License 4 | - [ ] Component contains README.md 5 | - [ ] Project [README.md](../README.md) updated 6 | - [ ] Component contains idf_component.yml file with `url` field defined 7 | - [ ] Component was added to CI [upload job](https://github.com/espressif/esp-mesh-lite/blob/master/.github/workflows/upload_component.yml#L17) 8 | - [ ] New files were added to CI build job 9 | - [ ] _Optional:_ Component contains unit tests 10 | - [ ] CI passing 11 | 12 | # Change description 13 | _Please describe your change here_ 14 | -------------------------------------------------------------------------------- /.github/workflows/build_example.yml: -------------------------------------------------------------------------------- 1 | name: Build ESP-MESH-LITE examples 2 | 3 | on: 4 | pull_request: 5 | types: [opened, reopened, synchronize] 6 | 7 | jobs: 8 | build: 9 | strategy: 10 | matrix: 11 | idf_ver: ["latest"] 12 | runs-on: ubuntu-20.04 13 | container: espressif/idf:${{ matrix.idf_ver }} 14 | steps: 15 | - uses: actions/checkout@v3 16 | with: 17 | submodules: 'recursive' 18 | - name: Build ESP-MESH-LITE examples 19 | shell: bash 20 | run: | 21 | . ${IDF_PATH}/export.sh 22 | pip install idf-component-manager --upgrade 23 | cd examples 24 | exclude_examples=[""] 25 | for d in */; do 26 | if [[ ! "$exclude_examples" =~ "$d" ]]; then 27 | pushd $d 28 | idf.py build 29 | popd 30 | fi 31 | done 32 | -------------------------------------------------------------------------------- /.github/workflows/build_test.yml: -------------------------------------------------------------------------------- 1 | name: Build Test Application 2 | 3 | on: 4 | pull_request: 5 | types: [opened, reopened, synchronize] 6 | 7 | jobs: 8 | build: 9 | strategy: 10 | matrix: 11 | idf_ver: ["release-v4.4", "release-v5.0"] # "latest" 12 | idf_target: ["esp32", "esp32s2", "esp32s3", "esp32c2", "esp32c3"] 13 | exclude: 14 | - idf_ver: "release-v4.4" 15 | idf_target: esp32c2 # ESP32C2 support started with version 5.0 16 | runs-on: ubuntu-20.04 17 | container: espressif/idf:${{ matrix.idf_ver }} 18 | steps: 19 | - uses: actions/checkout@v3 20 | - name: Build ESP-MESH-LITE Test Application 21 | env: 22 | IDF_TARGET: ${{ matrix.idf_target }} 23 | shell: bash 24 | run: | 25 | cd test_app 26 | . ${IDF_PATH}/export.sh 27 | export PEDANTIC_FLAGS="-DIDF_CI_BUILD -Werror -Werror=deprecated-declarations -Werror=unused-variable -Werror=unused-but-set-variable -Werror=unused-function" 28 | export EXTRA_CFLAGS="${PEDANTIC_FLAGS} -Wstrict-prototypes" 29 | export EXTRA_CXXFLAGS="${PEDANTIC_FLAGS}" 30 | idf.py build 31 | -------------------------------------------------------------------------------- /.github/workflows/issue_comment.yml: -------------------------------------------------------------------------------- 1 | name: Sync issue comments to JIRA 2 | 3 | # This workflow will be triggered when new issue comment is created (including PR comments) 4 | on: issue_comment 5 | 6 | jobs: 7 | sync_issue_comments_to_jira: 8 | name: Sync Issue Comments to Jira 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@master 12 | - name: Sync issue comments to JIRA 13 | uses: espressif/github-actions/sync_issues_to_jira@master 14 | env: 15 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 16 | JIRA_PASS: ${{ secrets.JIRA_PASS }} 17 | JIRA_PROJECT: ${{ secrets.JIRA_PROJECT }} 18 | JIRA_COMPONENT: ${{ secrets.JIRA_COMPONENT }} 19 | JIRA_URL: ${{ secrets.JIRA_URL }} 20 | JIRA_USER: ${{ secrets.JIRA_USER }} 21 | -------------------------------------------------------------------------------- /.github/workflows/new_issues.yml: -------------------------------------------------------------------------------- 1 | name: Sync issues to Jira 2 | 3 | # This workflow will be triggered when a new issue is opened 4 | on: issues 5 | 6 | jobs: 7 | sync_issues_to_jira: 8 | name: Sync issues to Jira 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@master 12 | - name: Sync GitHub issues to Jira project 13 | uses: espressif/github-actions/sync_issues_to_jira@master 14 | env: 15 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 16 | JIRA_PASS: ${{ secrets.JIRA_PASS }} 17 | JIRA_PROJECT: ${{ secrets.JIRA_PROJECT }} 18 | JIRA_COMPONENT: ${{ secrets.JIRA_COMPONENT }} 19 | JIRA_URL: ${{ secrets.JIRA_URL }} 20 | JIRA_USER: ${{ secrets.JIRA_USER }} 21 | -------------------------------------------------------------------------------- /.github/workflows/new_prs.yml: -------------------------------------------------------------------------------- 1 | name: Sync remain PRs to Jira 2 | 3 | # This workflow will be triggered every 6 hours, to sync remaining PRs (i.e. PRs with zero comment) to Jira project 4 | # Note that, PRs can also get synced when new PR comment is created 5 | on: 6 | schedule: 7 | - cron: "0 */6 * * *" 8 | 9 | jobs: 10 | sync_prs_to_jira: 11 | name: Sync PRs to Jira 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: actions/checkout@master 15 | - name: Sync PRs to Jira project 16 | uses: espressif/github-actions/sync_issues_to_jira@master 17 | with: 18 | cron_job: true 19 | env: 20 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 21 | JIRA_PASS: ${{ secrets.JIRA_PASS }} 22 | JIRA_PROJECT: ${{ secrets.JIRA_PROJECT }} 23 | JIRA_COMPONENT: ${{ secrets.JIRA_COMPONENT }} 24 | JIRA_URL: ${{ secrets.JIRA_URL }} 25 | JIRA_USER: ${{ secrets.JIRA_USER }} 26 | -------------------------------------------------------------------------------- /.github/workflows/upload_component.yml: -------------------------------------------------------------------------------- 1 | name: Push components to Espressif Component Service 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | 8 | jobs: 9 | upload_components: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - uses: actions/checkout@master 13 | 14 | - name: Upload components to component service 15 | uses: espressif/upload-components-ci-action@v1 16 | with: 17 | directories: > 18 | components/mesh_lite; 19 | namespace: "espressif" 20 | api_token: ${{ secrets.IDF_COMPONENT_API_TOKEN }} 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .config 2 | *.o 3 | *.pyc 4 | 5 | # gtags 6 | GTAGS 7 | GRTAGS 8 | GPATH 9 | 10 | # emacs 11 | .dir-locals.el 12 | 13 | # emacs temp file suffixes 14 | *~ 15 | .#* 16 | \#*# 17 | 18 | # eclipse setting 19 | .settings 20 | 21 | # sublime 22 | .tags 23 | .tags_sorted_by_file 24 | *.sublime-project 25 | *.sublime-workspace 26 | 27 | # vscode 28 | .vscode/ 29 | 30 | build 31 | sdkconfig 32 | sdkconfig.old 33 | dependencies.lock 34 | 35 | *.DS_Store 36 | */*.DS_Store 37 | */*/*.DS_Store 38 | */*/*/*.DS_Store 39 | 40 | # vscode settings 41 | .vscode 42 | 43 | # clangd cache 44 | .clangd 45 | .cache 46 | 47 | # IDF Components manage 48 | **/managed_components 49 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | # See https://pre-commit.com for more information 2 | # See https://pre-commit.com/hooks.html for more hooks 3 | 4 | default_stages: [commit] 5 | 6 | repos: 7 | - repo: https://github.com/pre-commit/pre-commit-hooks 8 | rev: v4.0.1 9 | hooks: 10 | - id: trailing-whitespace 11 | # note: whitespace exclusions use multiline regex, see https://pre-commit.com/#regular-expressions 12 | # items are: 13 | # 1 - some file extensions 14 | # 2 - any file matching *test*/*expected* (for host tests, if possible use this naming pattern always) 15 | # 3 - any directory named 'testdata' 16 | # 4 - protobuf auto-generated files 17 | exclude: &whitespace_excludes | 18 | (?x)^( 19 | .+\.(md|rst|map|bin)| 20 | .+test.*\/.*expected.*| 21 | .+\/testdata\/.+| 22 | .*_pb2.py| 23 | .*.pb-c.h| 24 | .*.pb-c.c| 25 | .*.patch| 26 | .*.yuv 27 | )$ 28 | - id: end-of-file-fixer 29 | exclude: *whitespace_excludes 30 | - id: check-executables-have-shebangs 31 | - id: check-shebang-scripts-are-executable 32 | - id: mixed-line-ending 33 | args: ['-f=lf'] 34 | - id: double-quote-string-fixer 35 | - id: no-commit-to-branch 36 | name: Do not use more than one slash in the branch name 37 | args: ['--pattern', '^[^/]*/[^/]*/'] 38 | - id: no-commit-to-branch 39 | name: Do not use uppercase letters in the branch name 40 | args: ['--pattern', '^[^A-Z]*[A-Z]'] 41 | - repo: local 42 | hooks: 43 | - id: check-executables 44 | name: Check File Permissions 45 | entry: tools/ci/check_executables.py --action executables 46 | language: python 47 | types: [executable] 48 | exclude: '\.pre-commit/.+' 49 | - id: check-executable-list 50 | name: Validate executable-list.txt 51 | entry: tools/ci/check_executables.py --action list 52 | language: python 53 | pass_filenames: false 54 | always_run: true 55 | - repo: https://github.com/pre-commit/pre-commit-hooks 56 | rev: v4.0.1 57 | hooks: 58 | - id: file-contents-sorter 59 | files: 'tools\/ci\/(executable-list\.txt|check_copyright_ignore\.txt)' 60 | - repo: https://github.com/espressif/check-copyright/ 61 | rev: v1.0.3 62 | hooks: 63 | - id: check-copyright 64 | args: ['--ignore', 'tools/ci/check_copyright_ignore.txt', '--config', 'tools/ci/check_copyright_config.yaml'] 65 | - repo: https://github.com/espressif/astyle_py.git 66 | rev: v1.0.5 67 | hooks: 68 | - id: astyle_py 69 | # If you are modifying astyle version, update tools/format.sh as well 70 | args: ['--astyle-version=3.4.7', '--rules=tools/ci/astyle-rules.yml'] 71 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | - [中文版本](./README_CN.md) 2 | 3 | # ESP-Mesh-Lite 4 | 5 | 6 | ESP-MESH-LITE is a Wi-Fi networking application of [IoT-Bridge](https://github.com/espressif/esp-iot-bridge), based on the **SoftAP + Station** mode, a set of Mesh solutions built on top of the Wi-Fi protocol. ESP-MESH-LITE allows numerous devices (henceforth referred to as nodes) spread over a large physical area (both indoors and outdoors) to be interconnected under a single WLAN (Wireless Local-Area Network). The biggest difference between ESP-MESH-LITE and [ESP-MESH](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/esp-wifi-mesh.html) (also known as ESP-WIFI-MESH) is that ESP-MESH-LITE allows sub-devices in the network to independently access the external network, and the transmission information is insensitive to the parent node, which greatly reduces the difficulty to develop the application layer. ESP-MESH-LITE is self-organizing and self-healing, which means the network can be built and maintained autonomously. 7 | 8 | For more information about ESP-MESH-LITE, please refer to [ESP-MESH-LITE Guide](https://github.com/espressif/esp-mesh-lite/blob/master/components/mesh_lite/User_Guide.md). 9 | 10 | In the [examples](https://github.com/espressif/esp-mesh-lite/blob/master/examples) directory, demos of some common application scenarios are implemented for users to quickly integrate into their own application projects. 11 | 12 | - [examples/mesh_local_control](examples/mesh_local_control): This example only simply demonstrates device networking and TCP communication, and does not include complex network applications. Users can carry out secondary development based on this example. 13 | - [examples/rainmaker/led_light](examples/rainmaker/led_light): This example integrates the Mesh functionality into the Rainmaker application. Users can configure the device through the `Nova Home` APP and successfully connect to the Rainmaker cloud. The device is connected to the cloud based on Rainmaker. It can also provide other devices with the ability to surf the Internet wirelessly, and form a network with the Mesh-Lite function, which greatly reduces the load on the router and expands the wireless communication range. 14 | -------------------------------------------------------------------------------- /README_CN.md: -------------------------------------------------------------------------------- 1 | - [English Version](./README.md) 2 | 3 | # ESP-Mesh-Lite 4 | 5 | ESP-MESH-LITE 是以 [IoT-Bridge](https://github.com/espressif/esp-iot-bridge) 为模型,基于 **SoftAP + Station** 模式,建立在 Wi-Fi 协议之上的一套 Mesh 方案。ESP-MESH-LITE 允许分布在大范围区域内(室内和室外)的大量设备(下文称节点)在同一个 WLAN(无线局域网)中相互连接。ESP-MESH-LITE 与 [ESP-MESH](https://docs.espressif.com/projects/esp-idf/zh_CN/latest/esp32/api-guides/esp-wifi-mesh.html)(又称 ESP-WIFI-MESH)最大的不同是 ESP-MESH-LITE 允许组网内的子设备独立访问外部网络,传输信息对于父节点无感,大大降低了应用层开发难度,ESP-MESH-LITE 具有自组网和自修复的特性,也就是说 Mesh 网络可以自主地构建和维护。 6 | 7 | 更多有关 ESP-MESH-LITE 的信息请参考 [ESP-MESH-LITE Guide](https://github.com/espressif/esp-mesh-lite/blob/master/components/mesh_lite/User_Guide_CN.md)。 8 | 9 | 在 [examples](https://github.com/espressif/esp-mesh-lite/blob/master/examples) 目录下,实现了一些常见应用场景的 demo,可供用户快速集成到自己的应用项目中。 10 | 11 | - [examples/mesh_local_control](examples/mesh_local_control):本示例仅简单演示设备组网,以及 TCP 通信,不包含复杂的网络应用,用户可基于此示例进行二次开发。 12 | - [examples/rainmaker/led_light](examples/rainmaker/led_light):本示例将 Mesh 功能集成到 Rainmaker 应用中,用户可通过 `Nova Home` APP 来为设备配网并使设备成功连接至 Rainmaker 云端,设备本身基于 Rainmaker 实现自身连接云端的同时,还可以为其他无线设备提供无线上网的能力,搭配 Mesh-Lite 功能形成组网,极大程度上减轻路由器承载压力,同时扩大了无线通信范围。 13 | -------------------------------------------------------------------------------- /components/mesh_lite/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(srcs "src/esp_mesh_lite_espnow.c") 2 | set(require_components "json" "esp_wifi" "app_update" "wifi_provisioning" "qrcode" "nvs_flash" "protobuf-c" "console") 3 | 4 | if (CONFIG_MESH_LITE_ENABLE) 5 | list(APPEND srcs "src/esp_mesh_lite.c" "src/esp_mesh_lite_port.c" "src/esp_mesh_lite_log.c" "src/mesh_lite.pb-c.c") 6 | endif() 7 | 8 | if (CONFIG_MESH_LITE_PROV_ENABLE) 9 | list(APPEND srcs "src/wifi_prov/wifi_prov_mgr.c" "src/wifi_prov/zero_provisioning.c") 10 | endif() 11 | 12 | if (CONFIG_MESH_LITE_WIRELESS_DEBUG) 13 | list(APPEND srcs "src/esp_mesh_lite_wireless_debug.c") 14 | endif() 15 | 16 | idf_component_register(SRCS "${srcs}" 17 | INCLUDE_DIRS include 18 | REQUIRES ${require_components}) 19 | 20 | string(CONCAT LIBS "esp_mesh_lite_" "${IDF_TARGET}") 21 | 22 | add_library(${LIBS} STATIC IMPORTED) 23 | set_property(TARGET ${LIBS} PROPERTY IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/lib/lib${LIBS}.a) 24 | target_link_libraries(${COMPONENT_LIB} INTERFACE ${LIBS}) 25 | set_property(TARGET ${LIBS} APPEND PROPERTY INTERFACE_LINK_LIBRARIES ${COMPONENT_LIB}) 26 | 27 | include(package_manager) 28 | if (CONFIG_MESH_LITE_ENABLE) 29 | cu_pkg_define_version(${CMAKE_CURRENT_LIST_DIR}) 30 | endif() 31 | -------------------------------------------------------------------------------- /components/mesh_lite/README.md: -------------------------------------------------------------------------------- 1 | # ESP-Mesh-Lite Component 2 | 3 | [![Component Registry](https://components.espressif.com/components/espressif/mesh_lite/badge.svg)](https://components.espressif.com/components/espressif/mesh_lite) 4 | 5 | - [User Guide](https://github.com/espressif/esp-mesh-lite/tree/master/components/mesh_lite/User_Guide.md) 6 | 7 | ESP-MESH-LITE is a Wi-Fi networking application of [IoT-Bridge](https://github.com/espressif/esp-iot-bridge), based on the **SoftAP + Station** mode, a set of Mesh solutions built on top of the Wi-Fi protocol. ESP-MESH-LITE allows numerous devices (henceforth referred to as nodes) spread over a large physical area (both indoors and outdoors) to be interconnected under a single WLAN (Wireless Local-Area Network). The biggest difference between ESP-MESH-LITE and [ESP-MESH](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/esp-wifi-mesh.html) (also known as ESP-WIFI-MESH) is that ESP-MESH-LITE allows sub-devices in the network to independently access the external network, and the transmission information is insensitive to the parent node, which greatly reduces the difficulty to develop the application layer. ESP-MESH-LITE is self-organizing and self-healing, which means the network can be built and maintained autonomously. 8 | 9 | If you are located in China or have difficulties to access GitHub, you can also use `git clone https://jihulab.com/esp-mirror/espressif/esp-mesh-lite.git` or `git clone https://gitee.com/EspressifSystems/esp-mesh-lite.git` to get ESP-Mesh-Lite, which may be faster. 10 | 11 | ## Feature 12 | 13 | - Support self-healing of the mesh network 14 | - Support establishing mesh network by root node even if no router is connected 15 | - Support automatically joining the mesh network without configuring router information 16 | - Support setting node only as root node 17 | - Support setting node only as non-root node 18 | - Support setting whether the mesh network is allowed to join 19 | - Support checking whether the joined devices are legal 20 | - Support root node to communicate with child nodes 21 | - Child node sends broadcast message to parent node 22 | - Child node sends message to root node 23 | - Child node sends message to parent node 24 | - Parent node sends broadcast message to child nodes 25 | - Support encryption of data communication between mesh network 26 | 27 | ## API 28 | 29 | - The application layer only needs to call this API at the code level to enable Mesh-Lite. 30 | 31 | ``` 32 | esp_bridge_create_all_netif(); 33 | 34 | esp_mesh_lite_config_t mesh_lite_config = ESP_MESH_LITE_DEFAULT_INIT(); 35 | esp_mesh_lite_init(&mesh_lite_config); 36 | 37 | esp_mesh_lite_start(); 38 | ``` 39 | 40 | ## Add component to your project 41 | Please use the component manager command `add-dependency` to add the `mesh_lite` to your project's dependency, during the CMake step the component will be downloaded automatically. 42 | 43 | ``` 44 | idf.py add-dependency "espressif/mesh_lite=*" 45 | ``` 46 | 47 | ## Examples 48 | 49 | Please use the component manager command `create-project-from-example` to create the project from example template. 50 | 51 | ``` 52 | idf.py create-project-from-example "espressif/mesh_lite=*:mesh_local_control" 53 | ``` 54 | 55 | Then the example will be downloaded in current folder, you can check into it for build and flash. 56 | 57 | > Or you can download examples from `esp-mesh-lite` repository: [mesh_local_control](https://github.com/espressif/esp-mesh-lite/tree/master/examples/mesh_local_control) 58 | 59 | ## Q&A 60 | 61 | Q1. I encountered the following problems when using the package manager 62 | 63 | ``` 64 | Executing action: create-project-from-example 65 | CMakeLists.txt not found in project directory /home/username 66 | ``` 67 | 68 | A1. This is because an older version packege manager was used, please run `pip install -U idf-component-manager` in ESP-IDF environment to update. 69 | 70 | Q2. When Mesh-Lite is working, I call the `esp_wifi_scan_start` interface but it does not work. 71 | 72 | A2. Because Mesh-Lite also has scan operations inside, it is recommended to use the `esp_mesh_lite_wifi_scan_start()` interface to scan. To call the scan interface externally, there needs to be a flag in the scan_done cb to control whether it is an externally called scan. If it is not an externally called scan, do not enter the external scan_done cb for processing. 73 | 74 | ``` 75 | if (esp_mesh_lite_wifi_scan_start(NULL, 3000 / TICK_MS) == ESP_OK) { 76 | scan_flag = true; 77 | } 78 | ``` 79 | -------------------------------------------------------------------------------- /components/mesh_lite/docs/_static/Network_Construction_Example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esp-mesh-lite/d991f8d9787eecd36239491a6d45a8e041a42907/components/mesh_lite/docs/_static/Network_Construction_Example.png -------------------------------------------------------------------------------- /components/mesh_lite/docs/_static/Schematic_diagram_of_bidirectional_data_flow.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esp-mesh-lite/d991f8d9787eecd36239491a6d45a8e041a42907/components/mesh_lite/docs/_static/Schematic_diagram_of_bidirectional_data_flow.jpg -------------------------------------------------------------------------------- /components/mesh_lite/docs/_static/mesh-root-node-failure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esp-mesh-lite/d991f8d9787eecd36239491a6d45a8e041a42907/components/mesh_lite/docs/_static/mesh-root-node-failure.png -------------------------------------------------------------------------------- /components/mesh_lite/docs/_static/root_node_election.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esp-mesh-lite/d991f8d9787eecd36239491a6d45a8e041a42907/components/mesh_lite/docs/_static/root_node_election.png -------------------------------------------------------------------------------- /components/mesh_lite/idf_component.yml: -------------------------------------------------------------------------------- 1 | version: "1.0.1" 2 | description: A lite version Wi-Fi Mesh, each node can access the network over the IP layer. 3 | url: https://github.com/espressif/esp-mesh-lite/tree/master/components/mesh_lite 4 | repository: https://github.com/espressif/esp-mesh-lite.git 5 | documentation: https://github.com/espressif/esp-mesh-lite/blob/master/components/mesh_lite/User_Guide.md 6 | issues: https://github.com/espressif/esp-mesh-lite/issues 7 | dependencies: 8 | idf: ">=5.0" 9 | espressif/qrcode: "^0.1.0" 10 | espressif/iot_bridge: "1.0.1" 11 | espressif/cmake_utilities: 0.* 12 | examples: 13 | - path: ../../examples/mesh_local_control 14 | - path: ../../examples/no_router 15 | - path: ../../examples/wireless_debug 16 | - path: ../../examples/mesh_wifi_provisioning 17 | - path: ../../examples/rainmaker/led_light 18 | -------------------------------------------------------------------------------- /components/mesh_lite/include/esp_mesh_lite_log.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | #include "esp_err.h" 11 | #include "esp_log.h" 12 | #include "esp_mesh_lite_wireless_debug.h" 13 | 14 | #define ESP_MESH_LITE_LOG_LEVEL ESP_LOG_DEBUG 15 | 16 | void esp_mesh_lite_log_write(esp_log_level_t level, const char *tag, const char *format, ...); 17 | 18 | #define ESP_MESH_LITE_LOGE(format, ... ) do { \ 19 | if (ESP_MESH_LITE_LOG_LEVEL >= ESP_LOG_ERROR) { \ 20 | esp_mesh_lite_log_write(ESP_LOG_ERROR, TAG, format, ##__VA_ARGS__); \ 21 | } \ 22 | } while(0) 23 | 24 | #define ESP_MESH_LITE_LOGW(format, ... ) do { \ 25 | if (ESP_MESH_LITE_LOG_LEVEL >= ESP_LOG_WARN) { \ 26 | esp_mesh_lite_log_write(ESP_LOG_WARN, TAG, format, ##__VA_ARGS__); \ 27 | } \ 28 | } while(0) 29 | 30 | #define ESP_MESH_LITE_LOGI(format, ... ) do { \ 31 | if (ESP_MESH_LITE_LOG_LEVEL >= ESP_LOG_INFO) { \ 32 | esp_mesh_lite_log_write(ESP_LOG_INFO, TAG, format, ##__VA_ARGS__); \ 33 | } \ 34 | } while(0) 35 | 36 | #define ESP_MESH_LITE_LOGD(format, ... ) do { \ 37 | if (ESP_MESH_LITE_LOG_LEVEL >= ESP_LOG_DEBUG) { \ 38 | esp_mesh_lite_log_write(ESP_LOG_DEBUG, TAG, format, ##__VA_ARGS__); \ 39 | } \ 40 | } while(0) 41 | 42 | #define ESP_MESH_LITE_LOGV(format, ... ) do { \ 43 | if (ESP_MESH_LITE_LOG_LEVEL >= ESP_LOG_VERBOSE) { \ 44 | esp_mesh_lite_log_write(ESP_LOG_VERBOSE, TAG, format, ##__VA_ARGS__); \ 45 | } \ 46 | } while(0) 47 | -------------------------------------------------------------------------------- /components/mesh_lite/include/esp_mesh_lite_port.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #pragma once 8 | 9 | #include "esp_ota_ops.h" 10 | 11 | typedef struct { 12 | uint8_t ssid[32]; /**< SSID of target AP. */ 13 | uint8_t password[64]; /**< Password of target AP. */ 14 | bool bssid_set; /**< whether set MAC address of target AP or not. Generally, station_config.bssid_set needs to be 0; and it needs to be 1 only when users need to check the MAC address of the AP.*/ 15 | uint8_t bssid[6]; /**< MAC address of target AP*/ 16 | wifi_scan_threshold_t threshold; /**< When scan_threshold is set, only APs which have an auth mode that is more secure than the selected auth mode and a signal stronger than the minimum RSSI will be used. */ 17 | uint8_t failure_retry_cnt; /**< Number of connection retries station will do before moving to next AP. scan_method should be set as WIFI_ALL_CHANNEL_SCAN to use this config. 18 | Note: Enabling this may cause connection time to increase incase best AP doesn't behave properly. */ 19 | } mesh_lite_sta_config_t; 20 | 21 | typedef struct { 22 | uint8_t ssid[32]; /**< SSID of ESP32 soft-AP. If ssid_len field is 0, this must be a Null terminated string. Otherwise, length is set according to ssid_len. */ 23 | uint8_t password[64]; /**< Password of ESP32 soft-AP. */ 24 | uint8_t ssid_len; /**< Optional length of SSID field. */ 25 | uint8_t channel; /**< Channel of soft-AP */ 26 | wifi_auth_mode_t authmode; /**< Auth mode of soft-AP. Do not support AUTH_WEP, AUTH_WAPI_PSK and AUTH_OWE in soft-AP mode. When the auth mode is set to WPA2_PSK, WPA2_WPA3_PSK or WPA3_PSK, the pairwise cipher will be overwritten with WIFI_CIPHER_TYPE_CCMP. */ 27 | uint8_t ssid_hidden; /**< Broadcast SSID or not, default 0, broadcast the SSID */ 28 | uint8_t max_connection; /**< Max number of stations allowed to connect in */ 29 | uint16_t beacon_interval; /**< Beacon interval which should be multiples of 100. Unit: TU(time unit, 1 TU = 1024 us). Range: 100 ~ 60000. Default value: 100 */ 30 | } mesh_lite_ap_config_t; 31 | 32 | typedef struct { 33 | uint8_t bssid[6]; /**< MAC address of AP */ 34 | uint8_t ssid[33]; /**< SSID of AP */ 35 | uint8_t primary; /**< channel of AP */ 36 | wifi_second_chan_t second; /**< secondary channel of AP */ 37 | int8_t rssi; /**< signal strength of AP */ 38 | } mesh_lite_ap_record_t; 39 | 40 | /** 41 | * @brief Get access point records when scan is done. 42 | * 43 | * This function retrieves the list of access point records after a Wi-Fi scan 44 | * has been completed. 45 | * 46 | * @param count Number of access point records to retrieve. 47 | * @return Pointer to the list of access point records (wifi_ap_record_t). 48 | */ 49 | wifi_ap_record_t *esp_mesh_lite_scan_get_ap_records_list(uint16_t count); 50 | 51 | /** 52 | * @brief Get the next access point record. 53 | * 54 | * This function retrieves the next access point record from the given list. 55 | * 56 | * @param ap_record Pointer to the current access point record. 57 | * @return Pointer to the next access point record. 58 | */ 59 | void *esp_mesh_lite_scan_get_next_ap_record(void *ap_record); 60 | 61 | /** 62 | * @brief Get access point information. 63 | * 64 | * This function retrieves information about a specific access point. 65 | * 66 | * @param ap_record Pointer to the structure to hold the access point information (mesh_lite_ap_record_t). 67 | * @return ESP_OK on success, or an appropriate error code on failure. 68 | */ 69 | esp_err_t esp_mesh_lite_get_ap_record(mesh_lite_ap_record_t *ap_record); 70 | 71 | /** 72 | * @brief Set Wi-Fi station configuration. 73 | * 74 | * This function sets the configuration for the Wi-Fi station, including SSID, 75 | * password, and other connection parameters. 76 | * 77 | * @param cfg Pointer to the Wi-Fi station configuration structure (mesh_lite_sta_config_t). 78 | * @return ESP_OK on success, or an appropriate error code on failure. 79 | */ 80 | esp_err_t esp_mesh_lite_set_wifi_config(mesh_lite_sta_config_t *cfg); 81 | 82 | /** 83 | * @brief Get Wi-Fi station configuration. 84 | * 85 | * This function retrieves the current configuration of the Wi-Fi station. 86 | * 87 | * @param cfg Pointer to the structure to hold the Wi-Fi station configuration (mesh_lite_sta_config_t). 88 | * @return ESP_OK on success, or an appropriate error code on failure. 89 | */ 90 | esp_err_t esp_mesh_lite_get_wifi_config(mesh_lite_sta_config_t *cfg); 91 | 92 | /** 93 | * @brief Get access point configuration. 94 | * 95 | * This function retrieves the configuration of the access point, including SSID, 96 | * password, channel, and other parameters. 97 | * 98 | * @param cfg Pointer to the structure to hold the access point configuration (mesh_lite_ap_config_t). 99 | * @return ESP_OK on success, or an appropriate error code on failure. 100 | */ 101 | esp_err_t esp_mesh_lite_get_ap_config(mesh_lite_ap_config_t *cfg); 102 | -------------------------------------------------------------------------------- /components/mesh_lite/include/mesh_lite.pb-c.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | /* Generated by the protocol buffer compiler. DO NOT EDIT! */ 7 | /* Generated from: mesh_lite.proto */ 8 | 9 | #ifndef PROTOBUF_C_mesh_5flite_2eproto__INCLUDED 10 | #define PROTOBUF_C_mesh_5flite_2eproto__INCLUDED 11 | 12 | #include 13 | 14 | PROTOBUF_C__BEGIN_DECLS 15 | 16 | #if PROTOBUF_C_VERSION_NUMBER < 1003000 17 | # error This file was generated by a newer version of protoc-c which is incompatible with your libprotobuf-c headers. Please update your headers. 18 | #elif 1005000 < PROTOBUF_C_MIN_COMPILER_VERSION 19 | # error This file was generated by an older version of protoc-c which is incompatible with your libprotobuf-c headers. Please regenerate this file with a newer version of protoc-c. 20 | #endif 21 | 22 | typedef struct MeshLite__NodeData MeshLite__NodeData; 23 | typedef struct MeshLite__Data MeshLite__Data; 24 | 25 | /* --- enums --- */ 26 | 27 | /* --- messages --- */ 28 | 29 | struct MeshLite__NodeData { 30 | ProtobufCMessage base; 31 | uint32_t node_level; 32 | uint32_t node_ip; 33 | ProtobufCBinaryData node_mac; 34 | }; 35 | #define MESH_LITE__NODE_DATA__INIT \ 36 | { PROTOBUF_C_MESSAGE_INIT (&mesh_lite__node_data__descriptor) \ 37 | , 0, 0, {0,NULL} } 38 | 39 | struct MeshLite__Data { 40 | ProtobufCMessage base; 41 | size_t n_nodes; 42 | MeshLite__NodeData **nodes; 43 | }; 44 | #define MESH_LITE__DATA__INIT \ 45 | { PROTOBUF_C_MESSAGE_INIT (&mesh_lite__data__descriptor) \ 46 | , 0,NULL } 47 | 48 | /* MeshLite__NodeData methods */ 49 | void mesh_lite__node_data__init 50 | (MeshLite__NodeData *message); 51 | size_t mesh_lite__node_data__get_packed_size 52 | (const MeshLite__NodeData *message); 53 | size_t mesh_lite__node_data__pack 54 | (const MeshLite__NodeData *message, 55 | uint8_t *out); 56 | size_t mesh_lite__node_data__pack_to_buffer 57 | (const MeshLite__NodeData *message, 58 | ProtobufCBuffer *buffer); 59 | MeshLite__NodeData * 60 | mesh_lite__node_data__unpack 61 | (ProtobufCAllocator *allocator, 62 | size_t len, 63 | const uint8_t *data); 64 | void mesh_lite__node_data__free_unpacked 65 | (MeshLite__NodeData *message, 66 | ProtobufCAllocator *allocator); 67 | /* MeshLite__Data methods */ 68 | void mesh_lite__data__init 69 | (MeshLite__Data *message); 70 | size_t mesh_lite__data__get_packed_size 71 | (const MeshLite__Data *message); 72 | size_t mesh_lite__data__pack 73 | (const MeshLite__Data *message, 74 | uint8_t *out); 75 | size_t mesh_lite__data__pack_to_buffer 76 | (const MeshLite__Data *message, 77 | ProtobufCBuffer *buffer); 78 | MeshLite__Data * 79 | mesh_lite__data__unpack 80 | (ProtobufCAllocator *allocator, 81 | size_t len, 82 | const uint8_t *data); 83 | void mesh_lite__data__free_unpacked 84 | (MeshLite__Data *message, 85 | ProtobufCAllocator *allocator); 86 | /* --- per-message closures --- */ 87 | 88 | typedef void (*MeshLite__NodeData_Closure) 89 | (const MeshLite__NodeData *message, 90 | void *closure_data); 91 | typedef void (*MeshLite__Data_Closure) 92 | (const MeshLite__Data *message, 93 | void *closure_data); 94 | 95 | /* --- services --- */ 96 | 97 | /* --- descriptors --- */ 98 | 99 | extern const ProtobufCMessageDescriptor mesh_lite__node_data__descriptor; 100 | extern const ProtobufCMessageDescriptor mesh_lite__data__descriptor; 101 | 102 | PROTOBUF_C__END_DECLS 103 | 104 | #endif /* PROTOBUF_C_mesh_5flite_2eproto__INCLUDED */ 105 | -------------------------------------------------------------------------------- /components/mesh_lite/include/wifi_prov_mgr.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #pragma once 8 | 9 | /** 10 | * @brief Enable Wi-Fi Provisioning 11 | * 12 | */ 13 | esp_err_t esp_mesh_lite_wifi_prov_mgr_init(void); 14 | 15 | /** 16 | * @brief Disable Wi-Fi Provisioning 17 | * 18 | */ 19 | esp_err_t esp_mesh_lite_wifi_prov_mgr_deinit(void); 20 | 21 | /** 22 | * @brief Get Wi-Fi Provisioning Status 23 | * 24 | * @return 25 | * - true: Wi-Fi Provisioning still in progress 26 | * - false:End of Wi-Fi Provisioning 27 | */ 28 | bool wifi_provision_in_progress(void); 29 | 30 | /** 31 | * @brief Stop Wi-Fi Provisioning 32 | * 33 | * This function stops the Wi-Fi provisioning process if it is in progress. 34 | */ 35 | void wifi_provision_stop(void); 36 | -------------------------------------------------------------------------------- /components/mesh_lite/include/zero_provisioning.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #include "esp_now.h" 8 | #include "sdkconfig.h" 9 | 10 | #ifndef zero_prov_H 11 | #define zero_prov_H 12 | 13 | #define ZERO_PROV_DEBUG (0) 14 | #define ZERO_PROV_QUEUE_SIZE (100) 15 | #define ZERO_PROV_LISTENING_TIMEOUT CONFIG_ZERO_PROV_LISTENING_TIMEOUT 16 | #define ZERO_PROV_ERR_CHECK(a, str, ret) if(!(a)) { \ 17 | ESP_LOGE(TAG,"%s:%d (%s):%s", __FILE__, __LINE__, __FUNCTION__, str); \ 18 | return (ret); \ 19 | } 20 | #define ZERO_PROV_CHECK_RETURN_VAIL(func_call) \ 21 | do { \ 22 | esp_err_t err = (func_call); \ 23 | if (err == ESP_FAIL) { \ 24 | ESP_LOGW(TAG, "%s %d %s failed with error: %d", __func__, __LINE__, #func_call, err); \ 25 | } \ 26 | } while (0) 27 | 28 | typedef enum { 29 | ZERO_PROV_SEND_BROADCAST, 30 | ZERO_PROV_RECIVE_DATA, 31 | ZERO_PROV_SEND_UNICAST_DATA, 32 | } zero_prov_event_id_t; 33 | 34 | enum { 35 | ESPNOW_DATA_BROADCAST, 36 | ESPNOW_DATA_UNICAST_INFO, 37 | ESPNOW_DATA_UNICAST_CONFIRM, 38 | ESPNOW_DATA_UNICAST_ACK, 39 | ESPNOW_DATA_MAX, 40 | }; 41 | 42 | typedef struct { 43 | uint8_t mac_addr[ESP_NOW_ETH_ALEN]; 44 | esp_now_send_status_t status; 45 | } zero_prov_send_cb_t; 46 | 47 | typedef struct { 48 | uint8_t mac_addr[ESP_NOW_ETH_ALEN]; 49 | uint8_t *data; 50 | int data_len; 51 | } zero_prov_recv_cb_t; 52 | 53 | typedef union { 54 | zero_prov_send_cb_t send_cb; 55 | zero_prov_recv_cb_t recv_cb; 56 | } zero_prov_event_info_t; 57 | 58 | typedef struct { 59 | zero_prov_event_id_t id; 60 | zero_prov_event_info_t info; 61 | } zero_prov_event_t; 62 | 63 | typedef struct { 64 | uint8_t router_ssid[32]; 65 | uint8_t router_password[32]; 66 | uint8_t channel; 67 | uint8_t mesh_id; 68 | uint32_t random; 69 | uint8_t softap_ssid[32]; 70 | uint8_t softap_password[32]; 71 | uint8_t mac_addr[ESP_NOW_ETH_ALEN]; 72 | } zero_prov_unicast_data_t; 73 | 74 | typedef struct { 75 | char cust_data[CONFIG_CUSTOMER_DATA_LENGTH]; 76 | char device_info[CONFIG_DEVICE_INFO_LENGTH]; 77 | } zero_prov_idle_node_data_t; 78 | 79 | typedef struct { 80 | uint8_t type; 81 | uint8_t len; 82 | uint16_t crc; 83 | uint8_t payload[0]; 84 | } zero_prov_esp_now_data_t; 85 | 86 | /** 87 | * @brief Initialize the Zero Provisioning module with customer-specific data and device information. 88 | * 89 | * This function initializes the Zero Provisioning module with the provided customer-specific data 90 | * and device information. 91 | * 92 | * @param[in] cust_data Pointer to the customer-specific data buffer. 93 | * @param[in] device_info Pointer to the device information data buffer. 94 | * @return 95 | * - ESP_OK if initialization was successful. 96 | * - ESP_FAIL if initialization failed, for example due to invalid parameters. 97 | */ 98 | esp_err_t zero_prov_init(char *cust_data, char *device_info); 99 | 100 | /** 101 | * @brief Stop the Zero Provisioning listening service. 102 | * 103 | * This function stops the Zero Provisioning module from listening for incoming provisioning requests. 104 | * It can be called to terminate the provisioning process once it is no longer needed or after a successful 105 | * provisioning has been completed. 106 | */ 107 | void zero_prov_listening_stop(void); 108 | 109 | #endif 110 | -------------------------------------------------------------------------------- /components/mesh_lite/lib/VERSION: -------------------------------------------------------------------------------- 1 | version 2 | libesp_mesh_lite_esp32.a :9235116 3 | libesp_mesh_lite_esp32c2.a :9235116 4 | libesp_mesh_lite_esp32c3.a :9235116 5 | libesp_mesh_lite_esp32c5.a :9235116 6 | libesp_mesh_lite_esp32c6.a :9235116 7 | libesp_mesh_lite_esp32c61.a :9235116 8 | libesp_mesh_lite_esp32s2.a :9235116 9 | libesp_mesh_lite_esp32s3.a :9235116 10 | -------------------------------------------------------------------------------- /components/mesh_lite/lib/libesp_mesh_lite_esp32.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esp-mesh-lite/d991f8d9787eecd36239491a6d45a8e041a42907/components/mesh_lite/lib/libesp_mesh_lite_esp32.a -------------------------------------------------------------------------------- /components/mesh_lite/lib/libesp_mesh_lite_esp32c2.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esp-mesh-lite/d991f8d9787eecd36239491a6d45a8e041a42907/components/mesh_lite/lib/libesp_mesh_lite_esp32c2.a -------------------------------------------------------------------------------- /components/mesh_lite/lib/libesp_mesh_lite_esp32c3.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esp-mesh-lite/d991f8d9787eecd36239491a6d45a8e041a42907/components/mesh_lite/lib/libesp_mesh_lite_esp32c3.a -------------------------------------------------------------------------------- /components/mesh_lite/lib/libesp_mesh_lite_esp32c5.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esp-mesh-lite/d991f8d9787eecd36239491a6d45a8e041a42907/components/mesh_lite/lib/libesp_mesh_lite_esp32c5.a -------------------------------------------------------------------------------- /components/mesh_lite/lib/libesp_mesh_lite_esp32c6.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esp-mesh-lite/d991f8d9787eecd36239491a6d45a8e041a42907/components/mesh_lite/lib/libesp_mesh_lite_esp32c6.a -------------------------------------------------------------------------------- /components/mesh_lite/lib/libesp_mesh_lite_esp32c61.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esp-mesh-lite/d991f8d9787eecd36239491a6d45a8e041a42907/components/mesh_lite/lib/libesp_mesh_lite_esp32c61.a -------------------------------------------------------------------------------- /components/mesh_lite/lib/libesp_mesh_lite_esp32s2.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esp-mesh-lite/d991f8d9787eecd36239491a6d45a8e041a42907/components/mesh_lite/lib/libesp_mesh_lite_esp32s2.a -------------------------------------------------------------------------------- /components/mesh_lite/lib/libesp_mesh_lite_esp32s3.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esp-mesh-lite/d991f8d9787eecd36239491a6d45a8e041a42907/components/mesh_lite/lib/libesp_mesh_lite_esp32s3.a -------------------------------------------------------------------------------- /components/mesh_lite/src/esp_mesh_lite_espnow.c: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #include 8 | #include 9 | #include "freertos/FreeRTOS.h" 10 | #include "esp_log.h" 11 | #include "esp_mac.h" 12 | #include "esp_mesh_lite.h" 13 | 14 | static uint8_t espnow_data[ESPNOW_PAYLOAD_MAX_LEN]; 15 | static esp_mesh_lite_espnow_handler_failed_hook_t espnow_recv_failed_hook = NULL; 16 | static espnow_cb_register_t *esp_mesh_lite_espnow_cb_list = NULL; 17 | static bool espnow_init = false; 18 | 19 | esp_err_t esp_mesh_lite_espnow_register_handler_failed_callback(esp_mesh_lite_espnow_handler_failed_hook_t cb) 20 | { 21 | espnow_recv_failed_hook = cb; 22 | return ESP_OK; 23 | } 24 | 25 | static inline esp_err_t esp_mesh_lite_espnow_recv_callback(uint8_t type, const esp_now_recv_info_t *recv_info, const uint8_t *data, int len) 26 | { 27 | esp_err_t ret = ESP_FAIL; 28 | espnow_cb_register_t *current = esp_mesh_lite_espnow_cb_list; 29 | while (current != NULL) { 30 | if (current->type == type) { 31 | current->esp_mesh_lite_espnow_recv_cb(recv_info, data, len); 32 | ret = ESP_OK; 33 | break; 34 | } 35 | current = current->next; 36 | } 37 | return ret; 38 | } 39 | 40 | static void espnow_recv_cb(const esp_now_recv_info_t *recv_info, const uint8_t *data, int len) 41 | { 42 | esp_err_t ret = esp_mesh_lite_espnow_recv_callback(data[0], recv_info, data + 1, len - 1); 43 | 44 | if (ret != ESP_OK) { 45 | if (espnow_recv_failed_hook) { 46 | espnow_recv_failed_hook(recv_info, data, len); 47 | } 48 | } 49 | } 50 | 51 | esp_err_t esp_mesh_lite_espnow_recv_cb_register(esp_mesh_lite_espnow_data_type_t type, 52 | void (*recv_cb)(const esp_now_recv_info_t *recv_info, const uint8_t *data, int len)) 53 | { 54 | if (espnow_init == false) { 55 | return ESP_ERR_INVALID_STATE; 56 | } 57 | 58 | espnow_cb_register_t *new_espnow_cb = (espnow_cb_register_t *)malloc(sizeof(espnow_cb_register_t)); 59 | if (!new_espnow_cb) { 60 | return ESP_ERR_NO_MEM; 61 | } 62 | 63 | new_espnow_cb->type = type; 64 | new_espnow_cb->esp_mesh_lite_espnow_recv_cb = recv_cb; 65 | new_espnow_cb->next = NULL; 66 | 67 | if (esp_mesh_lite_espnow_cb_list == NULL) { 68 | esp_mesh_lite_espnow_cb_list = new_espnow_cb; 69 | } else { 70 | new_espnow_cb->next = esp_mesh_lite_espnow_cb_list; 71 | esp_mesh_lite_espnow_cb_list = new_espnow_cb; 72 | } 73 | 74 | return ESP_OK; 75 | } 76 | 77 | esp_err_t esp_mesh_lite_espnow_recv_cb_unregister(esp_mesh_lite_espnow_data_type_t type) 78 | { 79 | if (espnow_init == false) { 80 | return ESP_ERR_INVALID_STATE; 81 | } 82 | 83 | espnow_cb_register_t *current = esp_mesh_lite_espnow_cb_list; 84 | espnow_cb_register_t *previous = NULL; 85 | 86 | while (current != NULL) { 87 | if (current->type == type) { 88 | if (previous == NULL) { 89 | esp_mesh_lite_espnow_cb_list = current->next; 90 | } else { 91 | previous->next = current->next; 92 | } 93 | free(current); 94 | return ESP_OK; 95 | } 96 | previous = current; 97 | current = current->next; 98 | } 99 | 100 | return ESP_ERR_NOT_FOUND; 101 | } 102 | 103 | esp_err_t esp_mesh_lite_espnow_send(uint8_t type, uint8_t *peer_addr, const uint8_t *data, size_t len) 104 | { 105 | if (espnow_init == false) { 106 | return ESP_ERR_INVALID_STATE; 107 | } 108 | 109 | if (len >= ESPNOW_PAYLOAD_MAX_LEN) { 110 | len = ESPNOW_PAYLOAD_MAX_LEN - 1; 111 | } 112 | espnow_data[0] = type; 113 | memcpy(&espnow_data[1], data, len); 114 | 115 | esp_err_t ret = esp_now_send(peer_addr, espnow_data, len + 1); 116 | 117 | return ret; 118 | } 119 | 120 | esp_err_t esp_mesh_lite_espnow_send_and_del_peer(uint8_t type, uint8_t *peer_addr, const uint8_t *data, size_t len) 121 | { 122 | esp_err_t ret = esp_mesh_lite_espnow_send(type, peer_addr, data, len); 123 | 124 | // Check if peer_addr is a broadcast address 125 | if (!IS_BROADCAST_ADDR(peer_addr)) { 126 | esp_now_del_peer(peer_addr); 127 | } 128 | 129 | return ret; 130 | } 131 | 132 | esp_err_t esp_mesh_lite_espnow_init(void) 133 | { 134 | if (espnow_init == true) { 135 | return ESP_FAIL; 136 | } 137 | 138 | /* Initialize ESPNOW and register sending and receiving callback function. */ 139 | ESP_ERROR_CHECK(esp_now_init()); 140 | ESP_ERROR_CHECK(esp_now_register_recv_cb(espnow_recv_cb)); 141 | 142 | /* Set primary master key. */ 143 | // ESP_ERROR_CHECK( esp_now_set_pmk((uint8_t *)CONFIG_ESPNOW_PMK) ); 144 | 145 | espnow_init = true; 146 | 147 | return ESP_OK; 148 | } 149 | -------------------------------------------------------------------------------- /components/mesh_lite/src/esp_mesh_lite_log.c: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #include "string.h" 8 | #include "inttypes.h" 9 | #include "esp_mesh_lite_log.h" 10 | 11 | #define LOG_COLOR_LEN 8 12 | 13 | __attribute__((weak)) void esp_mesh_lite_log_write(esp_log_level_t level, const char *tag, const char *format, ...) 14 | { 15 | char letter = 'I'; 16 | char log_color[LOG_COLOR_LEN] = {0}; 17 | memset(log_color, 0, sizeof(log_color)); 18 | switch (level) { 19 | case ESP_LOG_ERROR: 20 | letter = 'E'; 21 | #ifdef CONFIG_LOG_COLORS 22 | memcpy(log_color, "\033[0;" "31" "m", LOG_COLOR_LEN); 23 | #endif 24 | break; 25 | case ESP_LOG_WARN: 26 | letter = 'W'; 27 | #ifdef CONFIG_LOG_COLORS 28 | memcpy(log_color, "\033[0;" "33" "m", LOG_COLOR_LEN); 29 | #endif 30 | break; 31 | case ESP_LOG_INFO: 32 | letter = 'I'; 33 | #ifdef CONFIG_LOG_COLORS 34 | memcpy(log_color, "\033[0;" "32" "m", LOG_COLOR_LEN); 35 | #endif 36 | break; 37 | case ESP_LOG_DEBUG: 38 | letter = 'D'; 39 | #ifdef CONFIG_LOG_COLORS 40 | memcpy(log_color, "\033[0;" "36" "m", LOG_COLOR_LEN); 41 | #endif 42 | break; 43 | case ESP_LOG_VERBOSE: 44 | letter = 'V'; 45 | break; 46 | default: 47 | break; 48 | } 49 | va_list list; 50 | va_start(list, format); 51 | 52 | size_t new_format_length = strlen(tag) + strlen(format) + 30; 53 | char new_format[new_format_length]; 54 | snprintf(new_format, new_format_length, "%s%c (%"PRIu32") [%s]: %s " LOG_RESET_COLOR "\n", log_color, letter, esp_log_timestamp(), tag, format); 55 | 56 | esp_log_writev(level, tag, new_format, list); 57 | va_end(list); 58 | } 59 | -------------------------------------------------------------------------------- /components/mesh_lite/src/esp_mesh_lite_port.c: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #include 8 | #include "esp_mac.h" 9 | #include "esp_log.h" 10 | #include "esp_wifi.h" 11 | #include "esp_mesh_lite_port.h" 12 | 13 | wifi_ap_record_t *esp_mesh_lite_scan_get_ap_records_list(uint16_t count) 14 | { 15 | wifi_ap_record_t *ap_list = (wifi_ap_record_t *)malloc(sizeof(wifi_ap_record_t) * count); 16 | if (ap_list) { 17 | esp_wifi_scan_get_ap_records(&count, ap_list); 18 | } 19 | return ap_list; 20 | } 21 | 22 | void *esp_mesh_lite_scan_get_next_ap_record(void *ap_record) 23 | { 24 | if (!ap_record) { 25 | return NULL; 26 | } else { 27 | return ((wifi_ap_record_t *)ap_record) + 1; 28 | } 29 | } 30 | 31 | esp_err_t esp_mesh_lite_get_ap_record(mesh_lite_ap_record_t *ap_record) 32 | { 33 | if (!ap_record) { 34 | return ESP_FAIL; 35 | } 36 | 37 | wifi_ap_record_t ap_info; 38 | if (esp_wifi_sta_get_ap_info(&ap_info) != ESP_OK) { 39 | return ESP_FAIL; 40 | } 41 | memcpy((char*)ap_record->bssid, (char*)ap_info.bssid, sizeof(ap_record->bssid)); 42 | memcpy((char*)ap_record->ssid, (char*)ap_info.ssid, sizeof(ap_record->ssid)); 43 | ap_record->primary = ap_info.primary; 44 | ap_record->second = ap_info.second; 45 | ap_record->rssi = ap_info.rssi; 46 | 47 | return ESP_OK; 48 | } 49 | 50 | esp_err_t esp_mesh_lite_set_wifi_config(mesh_lite_sta_config_t *cfg) 51 | { 52 | if (!cfg) { 53 | return ESP_FAIL; 54 | } 55 | 56 | wifi_config_t wifi_cfg; 57 | memset(&wifi_cfg, 0x0, sizeof(wifi_config_t)); 58 | 59 | memcpy((char *)wifi_cfg.sta.ssid, (char *)cfg->ssid, sizeof(wifi_cfg.sta.ssid)); 60 | strlcpy((char *)wifi_cfg.sta.password, (char *)cfg->password, sizeof(wifi_cfg.sta.password)); 61 | 62 | if (cfg->bssid_set) { 63 | wifi_cfg.sta.bssid_set = 1; 64 | memcpy((char *)wifi_cfg.sta.bssid, (char *)cfg->bssid, sizeof(wifi_cfg.sta.bssid)); 65 | } 66 | 67 | wifi_cfg.sta.threshold.rssi = cfg->threshold.rssi; 68 | wifi_cfg.sta.threshold.authmode = cfg->threshold.authmode; 69 | 70 | if (esp_wifi_set_config(WIFI_IF_STA, &wifi_cfg) != ESP_OK) { 71 | return ESP_FAIL; 72 | } 73 | return ESP_OK; 74 | } 75 | 76 | esp_err_t esp_mesh_lite_get_wifi_config(mesh_lite_sta_config_t *cfg) 77 | { 78 | if (!cfg) { 79 | return ESP_FAIL; 80 | } 81 | 82 | wifi_config_t wifi_cfg; 83 | if (esp_wifi_get_config(WIFI_IF_STA, &wifi_cfg) != ESP_OK) { 84 | return ESP_FAIL; 85 | } 86 | 87 | memcpy((char *)cfg->ssid, (char *)wifi_cfg.sta.ssid, sizeof(cfg->ssid)); 88 | strlcpy((char *)cfg->password, (char *)wifi_cfg.sta.password, sizeof(cfg->password)); 89 | 90 | cfg->bssid_set = wifi_cfg.sta.bssid_set; 91 | if (cfg->bssid_set) { 92 | memcpy((char *)cfg->bssid, (char *)wifi_cfg.sta.bssid, sizeof(cfg->bssid)); 93 | } else { 94 | memset((char *)cfg->bssid, 0x0, sizeof(cfg->bssid)); 95 | } 96 | 97 | cfg->threshold.rssi = wifi_cfg.sta.threshold.rssi; 98 | cfg->threshold.authmode = wifi_cfg.sta.threshold.authmode; 99 | 100 | return ESP_OK; 101 | } 102 | 103 | esp_err_t esp_mesh_lite_get_ap_config(mesh_lite_ap_config_t *cfg) 104 | { 105 | if (!cfg) { 106 | return ESP_FAIL; 107 | } 108 | 109 | wifi_config_t wifi_cfg; 110 | if (esp_wifi_get_config(WIFI_IF_AP, &wifi_cfg) != ESP_OK) { 111 | return ESP_FAIL; 112 | } 113 | 114 | memcpy((char *)cfg->ssid, (char *)wifi_cfg.ap.ssid, sizeof(cfg->ssid)); 115 | strlcpy((char *)cfg->password, (char *)wifi_cfg.ap.password, sizeof(cfg->password)); 116 | 117 | return ESP_OK; 118 | } 119 | -------------------------------------------------------------------------------- /components/mesh_lite/src/mesh_lite.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package mesh_lite; 4 | 5 | message node_data { 6 | uint32 node_level = 1; 7 | uint32 node_ip = 2; 8 | bytes node_mac = 3; 9 | } 10 | 11 | message data { 12 | repeated node_data nodes = 1; 13 | } 14 | -------------------------------------------------------------------------------- /components/mesh_lite/src/proto_generate_CN.md: -------------------------------------------------------------------------------- 1 | # 自定义修改 `mesh_lite.proto` 文件并生成 C 和 H 文件 2 | 3 | ### 修改 `mesh_lite.proto` 文件 4 | 5 | **编辑 `mesh_lite.proto` 文件**: 6 | - 打开 `mesh_lite.proto` 文件,可以使用任何文本编辑器进行修改。 7 | - 添加新的消息类型或者修改现有消息的字段定义。 8 | 9 | ### 生成 C 和 H 文件 10 | 11 | **使用 `protoc` 工具生成文件**: 12 | - 打开终端或命令提示符。 13 | - cd 至 esp-mesh-lite/components/mesh_lite/src 目录 14 | - 使用以下命令生成 C 和 H 文件: 15 | ```bash 16 | protoc --c_out=. mesh_lite.proto 17 | ``` 18 | - 这将在当前目录下生成相应的 C 和 H 文件。 19 | 20 | ### 注意事项 21 | 22 | 1. **插件依赖**: 23 | - 确保系统安装了 `protobuf-c-compiler`,它包含了 `protoc-gen-c` 和 `protoc-gen-h` 这两个插件,用于生成 C 和 H 文件。 24 | 25 | 2. **目标目录和路径**: 26 | - 确保生成文件的输出目录正确指定,可以使用 `--c_out` 参数指定生成的 C 和 H 文件的目录。 27 | 28 | 3. **检查编译器插件**: 29 | - 如果遇到 `protoc-gen-h: program not found or is not executable` 错误,可能是由于缺少或未正确配置 `protoc-gen-h` 插件。需要确保该插件在系统的可执行路径中。 30 | -------------------------------------------------------------------------------- /components/mesh_lite/src/proto_generate_EN.md: -------------------------------------------------------------------------------- 1 | # Customizing `mesh_lite.proto` and Generating C and H Files 2 | 3 | ### Modifying `mesh_lite.proto` File 4 | 5 | **Edit `mesh_lite.proto` File**: 6 | - Open the `mesh_lite.proto` file using any text editor. 7 | - Add new message types or modify the field definitions of existing messages. 8 | 9 | ### Generating C and H Files 10 | 11 | **Using `protoc` Tool to Generate Files**: 12 | - Open a terminal or command prompt. 13 | - cd to the esp-mesh-lite/components/mesh_lite/src directory 14 | - Use the following command to generate C and H files: 15 | ```bash 16 | protoc --c_out=. mesh_lite.proto 17 | ``` 18 | - This command will generate corresponding C and H files in the current directory. 19 | 20 | ### Notes 21 | 22 | 1. **Plugin Dependencies**: 23 | - Ensure that `protobuf-c-compiler` is installed on your system, which includes `protoc-gen-c` and `protoc-gen-h` plugins required for generating C and H files. 24 | 25 | 2. **Target Directory and Paths**: 26 | - Ensure that the output directory for generated files is correctly specified. Use the `--c_out` parameter to specify the directory for generated C and H files. 27 | 28 | 3. **Checking Compiler Plugins**: 29 | - If you encounter `protoc-gen-h: program not found or is not executable` error, it may be due to missing or incorrectly configured `protoc-gen-h` plugin. Ensure that this plugin is located in the system's executable path. 30 | -------------------------------------------------------------------------------- /components/wifi_provisioning/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | idf_build_get_property(target IDF_TARGET) 2 | 3 | if(${target} STREQUAL "linux") 4 | return() # This component is not supported by the POSIX/Linux simulator 5 | endif() 6 | 7 | set(srcs "src/wifi_config.c" 8 | "src/wifi_scan.c" 9 | "src/wifi_ctrl.c" 10 | "src/manager.c" 11 | "src/handlers.c" 12 | "src/scheme_console.c" 13 | "proto-c/wifi_config.pb-c.c" 14 | "proto-c/wifi_scan.pb-c.c" 15 | "proto-c/wifi_ctrl.pb-c.c" 16 | "proto-c/wifi_constants.pb-c.c") 17 | 18 | if(CONFIG_ESP_WIFI_SOFTAP_SUPPORT) 19 | list(APPEND srcs "src/scheme_softap.c") 20 | endif() 21 | 22 | if(CONFIG_BT_ENABLED) 23 | if(CONFIG_BT_BLUEDROID_ENABLED OR CONFIG_BT_NIMBLE_ENABLED) 24 | list(APPEND srcs 25 | "src/scheme_ble.c") 26 | endif() 27 | endif() 28 | 29 | idf_component_register(SRCS "${srcs}" 30 | INCLUDE_DIRS include 31 | PRIV_INCLUDE_DIRS src proto-c 32 | REQUIRES lwip protocomm 33 | PRIV_REQUIRES protobuf-c bt json esp_timer esp_wifi) 34 | -------------------------------------------------------------------------------- /components/wifi_provisioning/Kconfig: -------------------------------------------------------------------------------- 1 | menu "Mesh Lite Wi-Fi Provisioning Manager" 2 | 3 | config MESH_LITE_WIFI_PROV_SCAN_MAX_ENTRIES 4 | int "Max Wi-Fi Scan Result Entries" 5 | default 16 6 | range 1 255 7 | help 8 | This sets the maximum number of entries of Wi-Fi scan results that will be kept by the provisioning manager 9 | 10 | config MESH_LITE_WIFI_PROV_AUTOSTOP_TIMEOUT 11 | int "Provisioning auto-stop timeout" 12 | default 30 13 | range 5 600 14 | help 15 | Time (in seconds) after which the Wi-Fi provisioning manager will auto-stop after connecting to 16 | a Wi-Fi network successfully. 17 | 18 | config MESH_LITE_WIFI_PROV_BLE_BONDING 19 | bool 20 | prompt "Enable BLE bonding" 21 | depends on BT_ENABLED 22 | help 23 | This option is applicable only when provisioning transport is BLE. 24 | 25 | config MESH_LITE_WIFI_PROV_BLE_SEC_CONN 26 | bool 27 | prompt "Enable BLE Secure connection flag" 28 | depends on BT_NIMBLE_ENABLED 29 | default y 30 | help 31 | Used to enable Secure connection support when provisioning transport is BLE. 32 | 33 | config MESH_LITE_WIFI_PROV_BLE_FORCE_ENCRYPTION 34 | bool 35 | prompt "Force Link Encryption during characteristic Read / Write" 36 | depends on BT_ENABLED 37 | help 38 | Used to enforce link encryption when attempting to read / write characteristic 39 | 40 | config MESH_LITE_WIFI_PROV_BLE_NOTIFY 41 | bool 42 | prompt "Add support for Notification for provisioning BLE descriptors" 43 | depends on BT_ENABLED 44 | help 45 | Used to enable support Notification in BLE descriptors of prov* characteristics 46 | 47 | config MESH_LITE_WIFI_PROV_KEEP_BLE_ON_AFTER_PROV 48 | bool "Keep BT on after provisioning is done" 49 | depends on BT_ENABLED 50 | select ESP_PROTOCOMM_KEEP_BLE_ON_AFTER_BLE_STOP 51 | 52 | config MESH_LITE_WIFI_PROV_DISCONNECT_AFTER_PROV 53 | bool "Terminate connection after provisioning is done" 54 | depends on MESH_LITE_WIFI_PROV_KEEP_BLE_ON_AFTER_PROV 55 | default y 56 | select ESP_PROTOCOMM_DISCONNECT_AFTER_BLE_STOP 57 | 58 | choice MESH_LITE_WIFI_PROV_STA_SCAN_METHOD 59 | bool "Wifi Provisioning Scan Method" 60 | default MESH_LITE_WIFI_PROV_STA_ALL_CHANNEL_SCAN 61 | config MESH_LITE_WIFI_PROV_STA_ALL_CHANNEL_SCAN 62 | bool "All Channel Scan" 63 | help 64 | Scan will end after scanning the entire channel. This option is useful in Mesh WiFi Systems. 65 | config MESH_LITE_WIFI_PROV_STA_FAST_SCAN 66 | bool "Fast Scan" 67 | help 68 | Scan will end after an AP matching with the SSID has been detected. 69 | endchoice 70 | endmenu 71 | -------------------------------------------------------------------------------- /components/wifi_provisioning/VERSION: -------------------------------------------------------------------------------- 1 | ESP-IDF 2 | release/v5.3 4d0db7045d5bf398e3187512b086f97f13d8c68e 3 | -------------------------------------------------------------------------------- /components/wifi_provisioning/include/wifi_provisioning/scheme_ble.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | #include 11 | 12 | #include "wifi_provisioning/manager.h" 13 | 14 | #ifdef __cplusplus 15 | extern "C" { 16 | #endif 17 | 18 | /** 19 | * @brief Scheme that can be used by manager for provisioning 20 | * over BLE transport with GATT server 21 | */ 22 | extern const wifi_prov_scheme_t wifi_prov_scheme_ble; 23 | 24 | /* This scheme specific event handler is to be used when application 25 | * doesn't require BT and BLE after provisioning has finished */ 26 | #define WIFI_PROV_SCHEME_BLE_EVENT_HANDLER_FREE_BTDM { \ 27 | .event_cb = wifi_prov_scheme_ble_event_cb_free_btdm, \ 28 | .user_data = NULL \ 29 | } 30 | 31 | /* This scheme specific event handler is to be used when application 32 | * doesn't require BLE to be active after provisioning has finished */ 33 | #define WIFI_PROV_SCHEME_BLE_EVENT_HANDLER_FREE_BLE { \ 34 | .event_cb = wifi_prov_scheme_ble_event_cb_free_ble, \ 35 | .user_data = NULL \ 36 | } 37 | 38 | /* This scheme specific event handler is to be used when application 39 | * doesn't require BT to be active after provisioning has finished */ 40 | #define WIFI_PROV_SCHEME_BLE_EVENT_HANDLER_FREE_BT { \ 41 | .event_cb = wifi_prov_scheme_ble_event_cb_free_bt, \ 42 | .user_data = NULL \ 43 | } 44 | 45 | void wifi_prov_scheme_ble_event_cb_free_btdm(void *user_data, wifi_prov_cb_event_t event, void *event_data); 46 | void wifi_prov_scheme_ble_event_cb_free_ble(void *user_data, wifi_prov_cb_event_t event, void *event_data); 47 | void wifi_prov_scheme_ble_event_cb_free_bt(void *user_data, wifi_prov_cb_event_t event, void *event_data); 48 | 49 | /** 50 | * @brief Set the 128 bit GATT service UUID used for provisioning 51 | * 52 | * This API is used to override the default 128 bit provisioning 53 | * service UUID, which is 0000ffff-0000-1000-8000-00805f9b34fb. 54 | * 55 | * This must be called before starting provisioning, i.e. before 56 | * making a call to wifi_prov_mgr_start_provisioning(), otherwise 57 | * the default UUID will be used. 58 | * 59 | * @note The data being pointed to by the argument must be valid 60 | * at least till provisioning is started. Upon start, the 61 | * manager will store an internal copy of this UUID, and 62 | * this data can be freed or invalidated afterwards. 63 | * 64 | * @param[in] uuid128 A custom 128 bit UUID 65 | * 66 | * @return 67 | * - ESP_OK : Success 68 | * - ESP_ERR_INVALID_ARG : Null argument 69 | */ 70 | esp_err_t wifi_prov_scheme_ble_set_service_uuid(uint8_t *uuid128); 71 | 72 | /** 73 | * @brief Set manufacturer specific data in scan response 74 | * 75 | * This must be called before starting provisioning, i.e. before 76 | * making a call to wifi_prov_mgr_start_provisioning(). 77 | * 78 | * @note It is important to understand that length of custom manufacturer 79 | * data should be within limits. The manufacturer data goes into scan 80 | * response along with BLE device name. By default, BLE device name 81 | * length is of 11 Bytes, however it can vary as per application use 82 | * case. So, one has to honour the scan response data size limits i.e. 83 | * (mfg_data_len + 2) < 31 - (device_name_length + 2 ). If the 84 | * mfg_data length exceeds this limit, the length will be truncated. 85 | * 86 | * @param[in] mfg_data Custom manufacturer data 87 | * @param[in] mfg_data_len Manufacturer data length 88 | * 89 | * @return 90 | * - ESP_OK : Success 91 | * - ESP_ERR_INVALID_ARG : Null argument 92 | */ 93 | esp_err_t wifi_prov_scheme_ble_set_mfg_data(uint8_t *mfg_data, ssize_t mfg_data_len); 94 | 95 | /** 96 | * @brief Set Bluetooth Random address 97 | * 98 | * This must be called before starting provisioning, i.e. before 99 | * making a call to wifi_prov_mgr_start_provisioning(). 100 | * 101 | * This API can be used in cases where a new identity address is to be used during 102 | * provisioning. This will result in this device being treated as a new device by remote 103 | * devices. 104 | * 105 | * @note This API will change the existing BD address for the device. The address once 106 | * set will remain unchanged until BLE stack tear down happens when 107 | * wifi_prov_mgr_deinit is invoked. 108 | * 109 | * This API is only to be called to set random address. Re-invoking this API 110 | * after provisioning is started will have no effect. 111 | * 112 | * @param[in] rand_addr The static random address to be set of length 6 bytes. 113 | * 114 | * @return 115 | * - ESP_OK : Success 116 | * - ESP_ERR_INVALID_ARG : Null argument 117 | */ 118 | esp_err_t wifi_prov_scheme_ble_set_random_addr(const uint8_t *rand_addr); 119 | 120 | #ifdef __cplusplus 121 | } 122 | #endif 123 | -------------------------------------------------------------------------------- /components/wifi_provisioning/include/wifi_provisioning/scheme_console.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | #include 11 | 12 | #include "wifi_provisioning/manager.h" 13 | 14 | #ifdef __cplusplus 15 | extern "C" { 16 | #endif 17 | 18 | /** 19 | * @brief Scheme that can be used by manager for provisioning 20 | * over console (Serial UART) 21 | */ 22 | extern const wifi_prov_scheme_t wifi_prov_scheme_console; 23 | 24 | #ifdef __cplusplus 25 | } 26 | #endif 27 | -------------------------------------------------------------------------------- /components/wifi_provisioning/include/wifi_provisioning/scheme_softap.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | #include 11 | 12 | #include "wifi_provisioning/manager.h" 13 | 14 | #ifdef __cplusplus 15 | extern "C" { 16 | #endif 17 | 18 | /** 19 | * @brief Scheme that can be used by manager for provisioning 20 | * over SoftAP transport with HTTP server 21 | */ 22 | extern const wifi_prov_scheme_t wifi_prov_scheme_softap; 23 | 24 | /** 25 | * 26 | * @brief Provide HTTPD Server handle externally. 27 | * 28 | * Useful in cases wherein applications need the webserver for some 29 | * different operations, and do not want the wifi provisioning component 30 | * to start/stop a new instance. 31 | * 32 | * @note This API should be called before wifi_prov_mgr_start_provisioning() 33 | * 34 | * @param[in] handle Handle to HTTPD server instance 35 | */ 36 | void wifi_prov_scheme_softap_set_httpd_handle(void *handle); 37 | #ifdef __cplusplus 38 | } 39 | #endif 40 | -------------------------------------------------------------------------------- /components/wifi_provisioning/include/wifi_provisioning/wifi_config.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2018-2022 Espressif Systems (Shanghai) CO LTD 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #ifndef _WIFI_PROV_CONFIG_H_ 8 | #define _WIFI_PROV_CONFIG_H_ 9 | 10 | #include 11 | #include "esp_netif_ip_addr.h" 12 | #include "esp_err.h" 13 | 14 | #ifdef __cplusplus 15 | extern "C" { 16 | #endif 17 | 18 | /** 19 | * @brief WiFi STA status for conveying back to the provisioning master 20 | */ 21 | typedef enum { 22 | WIFI_PROV_STA_CONNECTING, 23 | WIFI_PROV_STA_CONNECTED, 24 | WIFI_PROV_STA_DISCONNECTED 25 | } wifi_prov_sta_state_t; 26 | 27 | /** 28 | * @brief WiFi STA connection fail reason 29 | */ 30 | typedef enum { 31 | WIFI_PROV_STA_AUTH_ERROR, 32 | WIFI_PROV_STA_AP_NOT_FOUND 33 | } wifi_prov_sta_fail_reason_t; 34 | 35 | /** 36 | * @brief WiFi STA connected status information 37 | */ 38 | typedef struct { 39 | /** 40 | * IP Address received by station 41 | */ 42 | char ip_addr[IP4ADDR_STRLEN_MAX]; 43 | 44 | char bssid[6]; /*!< BSSID of the AP to which connection was estalished */ 45 | char ssid[33]; /*!< SSID of the to which connection was estalished */ 46 | uint8_t channel; /*!< Channel of the AP */ 47 | uint8_t auth_mode; /*!< Authorization mode of the AP */ 48 | } wifi_prov_sta_conn_info_t; 49 | 50 | /** 51 | * @brief WiFi status data to be sent in response to `get_status` request from master 52 | */ 53 | typedef struct { 54 | wifi_prov_sta_state_t wifi_state; /*!< WiFi state of the station */ 55 | union { 56 | /** 57 | * Reason for disconnection (valid only when `wifi_state` is `WIFI_STATION_DISCONNECTED`) 58 | */ 59 | wifi_prov_sta_fail_reason_t fail_reason; 60 | 61 | /** 62 | * Connection information (valid only when `wifi_state` is `WIFI_STATION_CONNECTED`) 63 | */ 64 | wifi_prov_sta_conn_info_t conn_info; 65 | }; 66 | } wifi_prov_config_get_data_t; 67 | 68 | /** 69 | * @brief WiFi config data received by slave during `set_config` request from master 70 | */ 71 | typedef struct { 72 | char ssid[33]; /*!< SSID of the AP to which the slave is to be connected */ 73 | char password[64]; /*!< Password of the AP */ 74 | char bssid[6]; /*!< BSSID of the AP */ 75 | uint8_t channel; /*!< Channel of the AP */ 76 | uint32_t mesh_id; 77 | char softap_ssid[33]; /*!< SSID of the AP to which the slave is to be connected */ 78 | char softap_passphrase[64]; /*!< Password of the AP */ 79 | } wifi_prov_config_set_data_t; 80 | 81 | /** 82 | * @brief Type of context data passed to each get/set/apply handler 83 | * function set in `wifi_prov_config_handlers` structure. 84 | * 85 | * This is passed as an opaque pointer, thereby allowing it be defined 86 | * later in application code as per requirements. 87 | */ 88 | typedef struct wifi_prov_ctx wifi_prov_ctx_t; 89 | 90 | /** 91 | * @brief Internal handlers for receiving and responding to protocomm 92 | * requests from master 93 | * 94 | * This is to be passed as priv_data for protocomm request handler 95 | * (refer to `wifi_prov_config_data_handler()`) when calling `protocomm_add_endpoint()`. 96 | */ 97 | typedef struct wifi_prov_config_handlers { 98 | /** 99 | * Handler function called when connection status 100 | * of the slave (in WiFi station mode) is requested 101 | */ 102 | esp_err_t (*get_status_handler)(wifi_prov_config_get_data_t *resp_data, 103 | wifi_prov_ctx_t **ctx); 104 | 105 | /** 106 | * Handler function called when WiFi connection configuration 107 | * (eg. AP SSID, password, etc.) of the slave (in WiFi station mode) 108 | * is to be set to user provided values 109 | */ 110 | esp_err_t (*set_config_handler)(const wifi_prov_config_set_data_t *req_data, 111 | wifi_prov_ctx_t **ctx); 112 | 113 | /** 114 | * Handler function for applying the configuration that was set in 115 | * `set_config_handler`. After applying the station may get connected to 116 | * the AP or may fail to connect. The slave must be ready to convey the 117 | * updated connection status information when `get_status_handler` is 118 | * invoked again by the master. 119 | */ 120 | esp_err_t (*apply_config_handler)(wifi_prov_ctx_t **ctx); 121 | 122 | /** 123 | * Context pointer to be passed to above handler functions upon invocation 124 | */ 125 | wifi_prov_ctx_t *ctx; 126 | } wifi_prov_config_handlers_t; 127 | 128 | /** 129 | * @brief Handler for receiving and responding to requests from master 130 | * 131 | * This is to be registered as the `wifi_config` endpoint handler 132 | * (protocomm `protocomm_req_handler_t`) using `protocomm_add_endpoint()` 133 | */ 134 | esp_err_t wifi_prov_config_data_handler(uint32_t session_id, const uint8_t *inbuf, ssize_t inlen, 135 | uint8_t **outbuf, ssize_t *outlen, void *priv_data); 136 | 137 | esp_err_t wifi_prov_meshlite_data_handler(uint32_t session_id, const uint8_t *inbuf, ssize_t inlen, 138 | uint8_t **outbuf, ssize_t *outlen, void *priv_data); 139 | #ifdef __cplusplus 140 | } 141 | #endif 142 | 143 | #endif 144 | -------------------------------------------------------------------------------- /components/wifi_provisioning/include/wifi_provisioning/wifi_scan.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #ifndef _PROV_WIFI_SCAN_H_ 8 | #define _PROV_WIFI_SCAN_H_ 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | #include 15 | 16 | #define WIFI_SSID_LEN sizeof(((wifi_ap_record_t *)0)->ssid) 17 | #define WIFI_BSSID_LEN sizeof(((wifi_ap_record_t *)0)->bssid) 18 | 19 | /** 20 | * @brief Type of context data passed to each get/set/apply handler 21 | * function set in `wifi_prov_scan_handlers` structure. 22 | * 23 | * This is passed as an opaque pointer, thereby allowing it be defined 24 | * later in application code as per requirements. 25 | */ 26 | typedef struct wifi_prov_scan_ctx wifi_prov_scan_ctx_t; 27 | 28 | /** 29 | * @brief Structure of entries in the scan results list 30 | */ 31 | typedef struct { 32 | /** 33 | * SSID of Wi-Fi AP 34 | */ 35 | char ssid[WIFI_SSID_LEN]; 36 | 37 | /** 38 | * BSSID of Wi-Fi AP 39 | */ 40 | char bssid[WIFI_BSSID_LEN]; 41 | 42 | /** 43 | * Wi-Fi channel number 44 | */ 45 | uint8_t channel; 46 | 47 | /** 48 | * Signal strength 49 | */ 50 | int rssi; 51 | 52 | /** 53 | * Wi-Fi security mode 54 | */ 55 | uint8_t auth; 56 | } wifi_prov_scan_result_t; 57 | 58 | /** 59 | * @brief Internal handlers for receiving and responding to protocomm 60 | * requests from client 61 | * 62 | * This is to be passed as priv_data for protocomm request handler 63 | * (refer to `wifi_prov_scan_handler()`) when calling `protocomm_add_endpoint()`. 64 | */ 65 | typedef struct wifi_prov_scan_handlers { 66 | /** 67 | * Handler function called when scan start command is received 68 | * with various scan parameters : 69 | * 70 | * blocking (input) - If true, the function should return only 71 | * when the scanning is finished 72 | * 73 | * passive (input) - If true, scan is to be started in passive 74 | * mode (this may be slower) instead of active mode 75 | * 76 | * group_channels (input) - This specifies whether to scan 77 | * all channels in one go (when zero) or perform scanning of 78 | * channels in groups, with 120ms delay between scanning of 79 | * consecutive groups, and the value of this parameter sets the 80 | * number of channels in each group. This is useful when transport 81 | * mode is SoftAP, where scanning all channels in one go may not 82 | * give the Wi-Fi driver enough time to send out beacons, and 83 | * hence may cause disconnection with any connected stations. 84 | * When scanning in groups, the manager will wait for atleast 85 | * 120ms after completing scan on a group of channels, and thus 86 | * allow the driver to send out the beacons. For example, given 87 | * that the total number of Wi-Fi channels is 14, then setting 88 | * group_channels to 4, will create 5 groups, with each group 89 | * having 3 channels, except the last one which will have 90 | * 14 % 3 = 2 channels. So, when scan is started, the first 3 91 | * channels will be scanned, followed by a 120ms delay, and then 92 | * the next 3 channels, and so on, until all the 14 channels have 93 | * been scanned. One may need to adjust this parameter as having 94 | * only few channels in a group may slow down the overall scan 95 | * time, while having too many may again cause disconnection. 96 | * Usually a value of 4 should work for most cases. Note that 97 | * for any other mode of transport, e.g. BLE, this can be safely 98 | * set to 0, and hence achieve the fastest overall scanning time. 99 | * 100 | * period_ms (input) - Scan parameter specifying how long to 101 | * wait on each channel (in milli-seconds) 102 | */ 103 | esp_err_t (*scan_start)(bool blocking, bool passive, 104 | uint8_t group_channels, uint32_t period_ms, 105 | wifi_prov_scan_ctx_t **ctx); 106 | 107 | /** 108 | * Handler function called when scan status is requested. Status 109 | * is given the parameters : 110 | * 111 | * scan_finished (output) - When scan has finished this returns true 112 | * 113 | * result_count (output) - This gives the total number of results 114 | * obtained till now. If scan is yet happening this number will 115 | * keep on updating 116 | */ 117 | esp_err_t (*scan_status)(bool *scan_finished, 118 | uint16_t *result_count, 119 | wifi_prov_scan_ctx_t **ctx); 120 | 121 | /** 122 | * Handler function called when scan result is requested. Parameters : 123 | * 124 | * scan_result - For fetching scan results. This can be called even 125 | * if scan is still on going 126 | * 127 | * start_index (input) - Starting index from where to fetch the 128 | * entries from the results list 129 | * 130 | * count (input) - Number of entries to fetch from the starting index 131 | * 132 | * entries (output) - List of entries returned. Each entry consists 133 | * of ssid, channel and rssi information 134 | */ 135 | esp_err_t (*scan_result)(uint16_t result_index, 136 | wifi_prov_scan_result_t *result, 137 | wifi_prov_scan_ctx_t **ctx); 138 | 139 | /** 140 | * Context pointer to be passed to above handler functions upon invocation 141 | */ 142 | wifi_prov_scan_ctx_t *ctx; 143 | } wifi_prov_scan_handlers_t; 144 | 145 | /** 146 | * @brief Handler for sending on demand Wi-Fi scan results 147 | * 148 | * This is to be registered as the `prov-scan` endpoint handler 149 | * (protocomm `protocomm_req_handler_t`) using `protocomm_add_endpoint()` 150 | */ 151 | esp_err_t wifi_prov_scan_handler(uint32_t session_id, const uint8_t *inbuf, ssize_t inlen, 152 | uint8_t **outbuf, ssize_t *outlen, void *priv_data); 153 | 154 | #ifdef __cplusplus 155 | } 156 | #endif 157 | 158 | #endif 159 | -------------------------------------------------------------------------------- /components/wifi_provisioning/proto-c/constants.pb-c.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | /* Generated by the protocol buffer compiler. DO NOT EDIT! */ 7 | /* Generated from: constants.proto */ 8 | 9 | #ifndef PROTOBUF_C_constants_2eproto__INCLUDED 10 | #define PROTOBUF_C_constants_2eproto__INCLUDED 11 | 12 | #include 13 | 14 | PROTOBUF_C__BEGIN_DECLS 15 | 16 | #if PROTOBUF_C_VERSION_NUMBER < 1003000 17 | # error This file was generated by a newer version of protoc-c which is incompatible with your libprotobuf-c headers. Please update your headers. 18 | #elif 1004000 < PROTOBUF_C_MIN_COMPILER_VERSION 19 | # error This file was generated by an older version of protoc-c which is incompatible with your libprotobuf-c headers. Please regenerate this file with a newer version of protoc-c. 20 | #endif 21 | 22 | /* --- enums --- */ 23 | 24 | /* 25 | * Allowed values for the status 26 | * of a protocomm instance 27 | */ 28 | typedef enum _Status { 29 | STATUS__Success = 0, 30 | STATUS__InvalidSecScheme = 1, 31 | STATUS__InvalidProto = 2, 32 | STATUS__TooManySessions = 3, 33 | STATUS__InvalidArgument = 4, 34 | STATUS__InternalError = 5, 35 | STATUS__CryptoError = 6, 36 | STATUS__InvalidSession = 7 37 | PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE(STATUS) 38 | } Status; 39 | 40 | /* --- messages --- */ 41 | 42 | /* --- per-message closures --- */ 43 | 44 | /* --- services --- */ 45 | 46 | /* --- descriptors --- */ 47 | 48 | extern const ProtobufCEnumDescriptor status__descriptor; 49 | 50 | PROTOBUF_C__END_DECLS 51 | 52 | #endif /* PROTOBUF_C_constants_2eproto__INCLUDED */ 53 | -------------------------------------------------------------------------------- /components/wifi_provisioning/proto-c/wifi_constants.pb-c.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | /* Generated by the protocol buffer compiler. DO NOT EDIT! */ 7 | /* Generated from: wifi_constants.proto */ 8 | 9 | #ifndef PROTOBUF_C_wifi_5fconstants_2eproto__INCLUDED 10 | #define PROTOBUF_C_wifi_5fconstants_2eproto__INCLUDED 11 | 12 | #include 13 | 14 | PROTOBUF_C__BEGIN_DECLS 15 | 16 | #if PROTOBUF_C_VERSION_NUMBER < 1003000 17 | # error This file was generated by a newer version of protoc-c which is incompatible with your libprotobuf-c headers. Please update your headers. 18 | #elif 1003003 < PROTOBUF_C_MIN_COMPILER_VERSION 19 | # error This file was generated by an older version of protoc-c which is incompatible with your libprotobuf-c headers. Please regenerate this file with a newer version of protoc-c. 20 | #endif 21 | 22 | typedef struct _WifiConnectedState WifiConnectedState; 23 | 24 | /* --- enums --- */ 25 | 26 | typedef enum _WifiStationState { 27 | WIFI_STATION_STATE__Connected = 0, 28 | WIFI_STATION_STATE__Connecting = 1, 29 | WIFI_STATION_STATE__Disconnected = 2, 30 | WIFI_STATION_STATE__ConnectionFailed = 3 31 | PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE(WIFI_STATION_STATE) 32 | } WifiStationState; 33 | typedef enum _WifiConnectFailedReason { 34 | WIFI_CONNECT_FAILED_REASON__AuthError = 0, 35 | WIFI_CONNECT_FAILED_REASON__NetworkNotFound = 1 36 | PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE(WIFI_CONNECT_FAILED_REASON) 37 | } WifiConnectFailedReason; 38 | typedef enum _WifiAuthMode { 39 | WIFI_AUTH_MODE__Open = 0, 40 | WIFI_AUTH_MODE__WEP = 1, 41 | WIFI_AUTH_MODE__WPA_PSK = 2, 42 | WIFI_AUTH_MODE__WPA2_PSK = 3, 43 | WIFI_AUTH_MODE__WPA_WPA2_PSK = 4, 44 | WIFI_AUTH_MODE__WPA2_ENTERPRISE = 5, 45 | WIFI_AUTH_MODE__WPA3_PSK = 6, 46 | WIFI_AUTH_MODE__WPA2_WPA3_PSK = 7 47 | PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE(WIFI_AUTH_MODE) 48 | } WifiAuthMode; 49 | 50 | /* --- messages --- */ 51 | 52 | struct _WifiConnectedState { 53 | ProtobufCMessage base; 54 | char *ip4_addr; 55 | WifiAuthMode auth_mode; 56 | ProtobufCBinaryData ssid; 57 | ProtobufCBinaryData bssid; 58 | int32_t channel; 59 | }; 60 | #define WIFI_CONNECTED_STATE__INIT \ 61 | { PROTOBUF_C_MESSAGE_INIT (&wifi_connected_state__descriptor) \ 62 | , (char *)protobuf_c_empty_string, WIFI_AUTH_MODE__Open, {0,NULL}, {0,NULL}, 0 } 63 | 64 | /* WifiConnectedState methods */ 65 | void wifi_connected_state__init 66 | (WifiConnectedState *message); 67 | size_t wifi_connected_state__get_packed_size 68 | (const WifiConnectedState *message); 69 | size_t wifi_connected_state__pack 70 | (const WifiConnectedState *message, 71 | uint8_t *out); 72 | size_t wifi_connected_state__pack_to_buffer 73 | (const WifiConnectedState *message, 74 | ProtobufCBuffer *buffer); 75 | WifiConnectedState * 76 | wifi_connected_state__unpack 77 | (ProtobufCAllocator *allocator, 78 | size_t len, 79 | const uint8_t *data); 80 | void wifi_connected_state__free_unpacked 81 | (WifiConnectedState *message, 82 | ProtobufCAllocator *allocator); 83 | /* --- per-message closures --- */ 84 | 85 | typedef void (*WifiConnectedState_Closure) 86 | (const WifiConnectedState *message, 87 | void *closure_data); 88 | 89 | /* --- services --- */ 90 | 91 | /* --- descriptors --- */ 92 | 93 | extern const ProtobufCEnumDescriptor wifi_station_state__descriptor; 94 | extern const ProtobufCEnumDescriptor wifi_connect_failed_reason__descriptor; 95 | extern const ProtobufCEnumDescriptor wifi_auth_mode__descriptor; 96 | extern const ProtobufCMessageDescriptor wifi_connected_state__descriptor; 97 | 98 | PROTOBUF_C__END_DECLS 99 | 100 | #endif /* PROTOBUF_C_wifi_5fconstants_2eproto__INCLUDED */ 101 | -------------------------------------------------------------------------------- /components/wifi_provisioning/proto/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.16) 2 | 3 | set(PROTO_COMPILER "protoc") 4 | set(PROTO_C_COMPILER "protoc-c") 5 | set(C_OUT_PATH "${CMAKE_CURRENT_LIST_DIR}/../proto-c") 6 | set(PY_OUT_PATH "${CMAKE_CURRENT_LIST_DIR}/../python") 7 | set(PROTOCOMM_INCL_PATH "${CMAKE_CURRENT_LIST_DIR}/../../protocomm/proto") 8 | 9 | set(PROTO_SRCS "wifi_constants.proto" 10 | "wifi_config.proto" 11 | "wifi_scan.proto") 12 | 13 | add_custom_target(c_proto 14 | COMMAND ${PROTO_C_COMPILER} --c_out=${C_OUT_PATH} -I . -I ${PROTOCOMM_INCL_PATH} ${PROTO_SRCS} 15 | VERBATIM 16 | WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} 17 | ) 18 | 19 | add_custom_target(python_proto 20 | COMMAND ${PROTO_COMPILER} --python_out=${PY_OUT_PATH} -I . -I ${PROTOCOMM_INCL_PATH} ${PROTO_SRCS} 21 | VERBATIM 22 | WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} 23 | ) 24 | 25 | add_custom_target(proto ALL 26 | DEPENDS c_proto python_proto 27 | VERBATIM 28 | WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} 29 | ) 30 | -------------------------------------------------------------------------------- /components/wifi_provisioning/proto/README.md: -------------------------------------------------------------------------------- 1 | # Protobuf files for defining Wi-Fi provisioning packet structures 2 | 3 | `wifi_provisioning` uses Google Protobuf for language, transport and architecture agnostic protocol communication. These proto files define the protocomm packet structure, separated across multiple files: 4 | * wifi_contants.proto - Defines the various enums for indicating state of Wi-Fi (connected / disconnect / connecting), diconnect reasons, auth modes, etc. 5 | * wifi_config.proto - Defines Wi-Fi configuration structures and commands for setting credentials (SSID, passphrase, BSSID), applying credentials and getting connection state. 6 | * wifi_scan.proto - Defines Wi-Fi scan commands and result structures 7 | 8 | Note : These proto files are not automatically compiled during the build process. 9 | 10 | # Compilation 11 | 12 | Compilation requires protoc (Protobuf Compiler) and protoc-c (Protobuf C Compiler) installed. Since the generated files are to remain the same, as long as the proto files are not modified, therefore the generated files are already available under `components/wifi_provisioning/proto-c` and `components/wifi_provisioning/python` directories, and thus running cmake / make (and installing the Protobuf compilers) is optional. 13 | 14 | If using `cmake` follow the below steps. If using `make`, jump to Step 2 directly. 15 | 16 | ## Step 1 (Only for cmake) 17 | 18 | When using cmake, first create a build directory and call cmake from inside: 19 | 20 | ``` 21 | mkdir build 22 | cd build 23 | cmake .. 24 | ``` 25 | 26 | ## Step 2 27 | 28 | Simply run `make` to generate the respective C and Python files. The newly created files will overwrite those under `components/wifi_provisioning/proto-c` and `components/wifi_provisioning/python` 29 | -------------------------------------------------------------------------------- /components/wifi_provisioning/proto/makefile: -------------------------------------------------------------------------------- 1 | all: c_proto python_proto 2 | 3 | c_proto: *.proto 4 | @protoc-c --c_out=../proto-c/ -I . -I ../../protocomm/proto/ *.proto 5 | 6 | python_proto: *.proto 7 | @protoc --python_out=../python/ -I . -I ../../protocomm/proto/ *.proto 8 | -------------------------------------------------------------------------------- /components/wifi_provisioning/proto/wifi_config.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | import "constants.proto"; 4 | import "wifi_constants.proto"; 5 | 6 | message CmdGetStatus { 7 | 8 | } 9 | 10 | message RespGetStatus { 11 | Status status = 1; 12 | WifiStationState sta_state = 2; 13 | oneof state { 14 | WifiConnectFailedReason fail_reason = 10; 15 | WifiConnectedState connected = 11; 16 | } 17 | } 18 | 19 | message CmdSetConfig { 20 | bytes ssid = 1; 21 | bytes passphrase = 2; 22 | bytes bssid = 3; 23 | int32 channel = 4; 24 | int32 mesh_id = 100; 25 | bytes softap_ssid = 101; 26 | bytes softap_passphrase = 102; 27 | } 28 | 29 | message RespSetConfig { 30 | Status status = 1; 31 | } 32 | 33 | message CmdApplyConfig { 34 | 35 | } 36 | 37 | message RespApplyConfig { 38 | Status status = 1; 39 | } 40 | 41 | enum WiFiConfigMsgType { 42 | TypeCmdGetStatus = 0; 43 | TypeRespGetStatus = 1; 44 | TypeCmdSetConfig = 2; 45 | TypeRespSetConfig = 3; 46 | TypeCmdApplyConfig = 4; 47 | TypeRespApplyConfig = 5; 48 | } 49 | 50 | message WiFiConfigPayload { 51 | WiFiConfigMsgType msg = 1; 52 | oneof payload { 53 | CmdGetStatus cmd_get_status = 10; 54 | RespGetStatus resp_get_status = 11; 55 | CmdSetConfig cmd_set_config = 12; 56 | RespSetConfig resp_set_config = 13; 57 | CmdApplyConfig cmd_apply_config = 14; 58 | RespApplyConfig resp_apply_config = 15; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /components/wifi_provisioning/proto/wifi_constants.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | enum WifiStationState { 4 | Connected = 0; 5 | Connecting = 1; 6 | Disconnected = 2; 7 | ConnectionFailed = 3; 8 | } 9 | 10 | enum WifiConnectFailedReason { 11 | AuthError = 0; 12 | NetworkNotFound = 1; 13 | } 14 | 15 | enum WifiAuthMode { 16 | Open = 0; 17 | WEP = 1; 18 | WPA_PSK = 2; 19 | WPA2_PSK = 3; 20 | WPA_WPA2_PSK = 4; 21 | WPA2_ENTERPRISE = 5; 22 | WPA3_PSK = 6; 23 | WPA2_WPA3_PSK = 7; 24 | } 25 | 26 | message WifiConnectedState { 27 | string ip4_addr = 1; 28 | WifiAuthMode auth_mode = 2; 29 | bytes ssid = 3; 30 | bytes bssid = 4; 31 | int32 channel = 5; 32 | } 33 | -------------------------------------------------------------------------------- /components/wifi_provisioning/proto/wifi_ctrl.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | import "constants.proto"; 4 | 5 | message CmdCtrlReset { 6 | 7 | } 8 | 9 | message RespCtrlReset { 10 | 11 | } 12 | 13 | message CmdCtrlReprov { 14 | 15 | } 16 | 17 | message RespCtrlReprov{ 18 | 19 | } 20 | 21 | enum WiFiCtrlMsgType { 22 | TypeCtrlReserved = 0; 23 | TypeCmdCtrlReset = 1; 24 | TypeRespCtrlReset = 2; 25 | TypeCmdCtrlReprov = 3; 26 | TypeRespCtrlReprov = 4; 27 | } 28 | 29 | message WiFiCtrlPayload { 30 | WiFiCtrlMsgType msg = 1; 31 | Status status = 2; 32 | oneof payload { 33 | CmdCtrlReset cmd_ctrl_reset = 11; 34 | RespCtrlReset resp_ctrl_reset = 12; 35 | CmdCtrlReprov cmd_ctrl_reprov = 13; 36 | RespCtrlReprov resp_ctrl_reprov = 14; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /components/wifi_provisioning/proto/wifi_scan.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | import "constants.proto"; 4 | import "wifi_constants.proto"; 5 | 6 | message CmdScanStart { 7 | bool blocking = 1; 8 | bool passive = 2; 9 | uint32 group_channels = 3; 10 | uint32 period_ms = 4; 11 | } 12 | 13 | message RespScanStart { 14 | 15 | } 16 | 17 | message CmdScanStatus { 18 | 19 | } 20 | 21 | message RespScanStatus { 22 | bool scan_finished = 1; 23 | uint32 result_count = 2; 24 | } 25 | 26 | message CmdScanResult { 27 | uint32 start_index = 1; 28 | uint32 count = 2; 29 | } 30 | 31 | message WiFiScanResult { 32 | bytes ssid = 1; 33 | uint32 channel = 2; 34 | int32 rssi = 3; 35 | bytes bssid = 4; 36 | WifiAuthMode auth = 5; 37 | } 38 | 39 | message RespScanResult { 40 | repeated WiFiScanResult entries = 1; 41 | } 42 | 43 | enum WiFiScanMsgType { 44 | TypeCmdScanStart = 0; 45 | TypeRespScanStart = 1; 46 | TypeCmdScanStatus = 2; 47 | TypeRespScanStatus = 3; 48 | TypeCmdScanResult = 4; 49 | TypeRespScanResult = 5; 50 | } 51 | 52 | message WiFiScanPayload { 53 | WiFiScanMsgType msg = 1; 54 | Status status = 2; 55 | oneof payload { 56 | CmdScanStart cmd_scan_start = 10; 57 | RespScanStart resp_scan_start = 11; 58 | CmdScanStatus cmd_scan_status = 12; 59 | RespScanStatus resp_scan_status = 13; 60 | CmdScanResult cmd_scan_result = 14; 61 | RespScanResult resp_scan_result = 15; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /components/wifi_provisioning/python/wifi_config_pb2.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD 2 | # SPDX-License-Identifier: Apache-2.0 3 | # -*- coding: utf-8 -*- 4 | # Generated by the protocol buffer compiler. DO NOT EDIT! 5 | # source: wifi_config.proto 6 | """Generated protocol buffer code.""" 7 | from google.protobuf.internal import builder as _builder 8 | from google.protobuf import descriptor as _descriptor 9 | from google.protobuf import descriptor_pool as _descriptor_pool 10 | from google.protobuf import symbol_database as _symbol_database 11 | # @@protoc_insertion_point(imports) 12 | 13 | _sym_db = _symbol_database.Default() 14 | 15 | 16 | import constants_pb2 as constants__pb2 17 | import wifi_constants_pb2 as wifi__constants__pb2 18 | 19 | 20 | DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x11wifi_config.proto\x1a\x0f\x63onstants.proto\x1a\x14wifi_constants.proto\"\x0e\n\x0c\x43mdGetStatus\"\xb2\x01\n\rRespGetStatus\x12\x17\n\x06status\x18\x01 \x01(\x0e\x32\x07.Status\x12$\n\tsta_state\x18\x02 \x01(\x0e\x32\x11.WifiStationState\x12/\n\x0b\x66\x61il_reason\x18\n \x01(\x0e\x32\x18.WifiConnectFailedReasonH\x00\x12(\n\tconnected\x18\x0b \x01(\x0b\x32\x13.WifiConnectedStateH\x00\x42\x07\n\x05state\"P\n\x0c\x43mdSetConfig\x12\x0c\n\x04ssid\x18\x01 \x01(\x0c\x12\x12\n\npassphrase\x18\x02 \x01(\x0c\x12\r\n\x05\x62ssid\x18\x03 \x01(\x0c\x12\x0f\n\x07\x63hannel\x18\x04 \x01(\x05\"(\n\rRespSetConfig\x12\x17\n\x06status\x18\x01 \x01(\x0e\x32\x07.Status\"\x10\n\x0e\x43mdApplyConfig\"*\n\x0fRespApplyConfig\x12\x17\n\x06status\x18\x01 \x01(\x0e\x32\x07.Status\"\xc3\x02\n\x11WiFiConfigPayload\x12\x1f\n\x03msg\x18\x01 \x01(\x0e\x32\x12.WiFiConfigMsgType\x12\'\n\x0e\x63md_get_status\x18\n \x01(\x0b\x32\r.CmdGetStatusH\x00\x12)\n\x0fresp_get_status\x18\x0b \x01(\x0b\x32\x0e.RespGetStatusH\x00\x12\'\n\x0e\x63md_set_config\x18\x0c \x01(\x0b\x32\r.CmdSetConfigH\x00\x12)\n\x0fresp_set_config\x18\r \x01(\x0b\x32\x0e.RespSetConfigH\x00\x12+\n\x10\x63md_apply_config\x18\x0e \x01(\x0b\x32\x0f.CmdApplyConfigH\x00\x12-\n\x11resp_apply_config\x18\x0f \x01(\x0b\x32\x10.RespApplyConfigH\x00\x42\t\n\x07payload*\x9e\x01\n\x11WiFiConfigMsgType\x12\x14\n\x10TypeCmdGetStatus\x10\x00\x12\x15\n\x11TypeRespGetStatus\x10\x01\x12\x14\n\x10TypeCmdSetConfig\x10\x02\x12\x15\n\x11TypeRespSetConfig\x10\x03\x12\x16\n\x12TypeCmdApplyConfig\x10\x04\x12\x17\n\x13TypeRespApplyConfig\x10\x05\x62\x06proto3') 21 | 22 | _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) 23 | _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'wifi_config_pb2', globals()) 24 | if _descriptor._USE_C_DESCRIPTORS == False: 25 | 26 | DESCRIPTOR._options = None 27 | _WIFICONFIGMSGTYPE._serialized_start=770 28 | _WIFICONFIGMSGTYPE._serialized_end=928 29 | _CMDGETSTATUS._serialized_start=60 30 | _CMDGETSTATUS._serialized_end=74 31 | _RESPGETSTATUS._serialized_start=77 32 | _RESPGETSTATUS._serialized_end=255 33 | _CMDSETCONFIG._serialized_start=257 34 | _CMDSETCONFIG._serialized_end=337 35 | _RESPSETCONFIG._serialized_start=339 36 | _RESPSETCONFIG._serialized_end=379 37 | _CMDAPPLYCONFIG._serialized_start=381 38 | _CMDAPPLYCONFIG._serialized_end=397 39 | _RESPAPPLYCONFIG._serialized_start=399 40 | _RESPAPPLYCONFIG._serialized_end=441 41 | _WIFICONFIGPAYLOAD._serialized_start=444 42 | _WIFICONFIGPAYLOAD._serialized_end=767 43 | # @@protoc_insertion_point(module_scope) 44 | -------------------------------------------------------------------------------- /components/wifi_provisioning/python/wifi_constants_pb2.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD 2 | # SPDX-License-Identifier: Apache-2.0 3 | # -*- coding: utf-8 -*- 4 | # Generated by the protocol buffer compiler. DO NOT EDIT! 5 | # source: wifi_constants.proto 6 | """Generated protocol buffer code.""" 7 | from google.protobuf.internal import builder as _builder 8 | from google.protobuf import descriptor as _descriptor 9 | from google.protobuf import descriptor_pool as _descriptor_pool 10 | from google.protobuf import symbol_database as _symbol_database 11 | # @@protoc_insertion_point(imports) 12 | 13 | _sym_db = _symbol_database.Default() 14 | 15 | 16 | 17 | 18 | DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x14wifi_constants.proto\"v\n\x12WifiConnectedState\x12\x10\n\x08ip4_addr\x18\x01 \x01(\t\x12 \n\tauth_mode\x18\x02 \x01(\x0e\x32\r.WifiAuthMode\x12\x0c\n\x04ssid\x18\x03 \x01(\x0c\x12\r\n\x05\x62ssid\x18\x04 \x01(\x0c\x12\x0f\n\x07\x63hannel\x18\x05 \x01(\x05*Y\n\x10WifiStationState\x12\r\n\tConnected\x10\x00\x12\x0e\n\nConnecting\x10\x01\x12\x10\n\x0c\x44isconnected\x10\x02\x12\x14\n\x10\x43onnectionFailed\x10\x03*=\n\x17WifiConnectFailedReason\x12\r\n\tAuthError\x10\x00\x12\x13\n\x0fNetworkNotFound\x10\x01*\x84\x01\n\x0cWifiAuthMode\x12\x08\n\x04Open\x10\x00\x12\x07\n\x03WEP\x10\x01\x12\x0b\n\x07WPA_PSK\x10\x02\x12\x0c\n\x08WPA2_PSK\x10\x03\x12\x10\n\x0cWPA_WPA2_PSK\x10\x04\x12\x13\n\x0fWPA2_ENTERPRISE\x10\x05\x12\x0c\n\x08WPA3_PSK\x10\x06\x12\x11\n\rWPA2_WPA3_PSK\x10\x07\x62\x06proto3') 19 | 20 | _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) 21 | _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'wifi_constants_pb2', globals()) 22 | if _descriptor._USE_C_DESCRIPTORS == False: 23 | 24 | DESCRIPTOR._options = None 25 | _WIFISTATIONSTATE._serialized_start=144 26 | _WIFISTATIONSTATE._serialized_end=233 27 | _WIFICONNECTFAILEDREASON._serialized_start=235 28 | _WIFICONNECTFAILEDREASON._serialized_end=296 29 | _WIFIAUTHMODE._serialized_start=299 30 | _WIFIAUTHMODE._serialized_end=431 31 | _WIFICONNECTEDSTATE._serialized_start=24 32 | _WIFICONNECTEDSTATE._serialized_end=142 33 | # @@protoc_insertion_point(module_scope) 34 | -------------------------------------------------------------------------------- /components/wifi_provisioning/python/wifi_ctrl_pb2.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD 2 | # SPDX-License-Identifier: Apache-2.0 3 | # -*- coding: utf-8 -*- 4 | # Generated by the protocol buffer compiler. DO NOT EDIT! 5 | # source: wifi_ctrl.proto 6 | """Generated protocol buffer code.""" 7 | from google.protobuf.internal import builder as _builder 8 | from google.protobuf import descriptor as _descriptor 9 | from google.protobuf import descriptor_pool as _descriptor_pool 10 | from google.protobuf import symbol_database as _symbol_database 11 | # @@protoc_insertion_point(imports) 12 | 13 | _sym_db = _symbol_database.Default() 14 | 15 | 16 | import constants_pb2 as constants__pb2 17 | 18 | 19 | DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0fwifi_ctrl.proto\x1a\x0f\x63onstants.proto\"\x0e\n\x0c\x43mdCtrlReset\"\x0f\n\rRespCtrlReset\"\x0f\n\rCmdCtrlReprov\"\x10\n\x0eRespCtrlReprov\"\x80\x02\n\x0fWiFiCtrlPayload\x12\x1d\n\x03msg\x18\x01 \x01(\x0e\x32\x10.WiFiCtrlMsgType\x12\x17\n\x06status\x18\x02 \x01(\x0e\x32\x07.Status\x12\'\n\x0e\x63md_ctrl_reset\x18\x0b \x01(\x0b\x32\r.CmdCtrlResetH\x00\x12)\n\x0fresp_ctrl_reset\x18\x0c \x01(\x0b\x32\x0e.RespCtrlResetH\x00\x12)\n\x0f\x63md_ctrl_reprov\x18\r \x01(\x0b\x32\x0e.CmdCtrlReprovH\x00\x12+\n\x10resp_ctrl_reprov\x18\x0e \x01(\x0b\x32\x0f.RespCtrlReprovH\x00\x42\t\n\x07payload*\x83\x01\n\x0fWiFiCtrlMsgType\x12\x14\n\x10TypeCtrlReserved\x10\x00\x12\x14\n\x10TypeCmdCtrlReset\x10\x01\x12\x15\n\x11TypeRespCtrlReset\x10\x02\x12\x15\n\x11TypeCmdCtrlReprov\x10\x03\x12\x16\n\x12TypeRespCtrlReprov\x10\x04\x62\x06proto3') 20 | 21 | _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) 22 | _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'wifi_ctrl_pb2', globals()) 23 | if _descriptor._USE_C_DESCRIPTORS == False: 24 | 25 | DESCRIPTOR._options = None 26 | _WIFICTRLMSGTYPE._serialized_start=364 27 | _WIFICTRLMSGTYPE._serialized_end=495 28 | _CMDCTRLRESET._serialized_start=36 29 | _CMDCTRLRESET._serialized_end=50 30 | _RESPCTRLRESET._serialized_start=52 31 | _RESPCTRLRESET._serialized_end=67 32 | _CMDCTRLREPROV._serialized_start=69 33 | _CMDCTRLREPROV._serialized_end=84 34 | _RESPCTRLREPROV._serialized_start=86 35 | _RESPCTRLREPROV._serialized_end=102 36 | _WIFICTRLPAYLOAD._serialized_start=105 37 | _WIFICTRLPAYLOAD._serialized_end=361 38 | # @@protoc_insertion_point(module_scope) 39 | -------------------------------------------------------------------------------- /components/wifi_provisioning/python/wifi_scan_pb2.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD 2 | # SPDX-License-Identifier: Apache-2.0 3 | # -*- coding: utf-8 -*- 4 | # Generated by the protocol buffer compiler. DO NOT EDIT! 5 | # source: wifi_scan.proto 6 | """Generated protocol buffer code.""" 7 | from google.protobuf.internal import builder as _builder 8 | from google.protobuf import descriptor as _descriptor 9 | from google.protobuf import descriptor_pool as _descriptor_pool 10 | from google.protobuf import symbol_database as _symbol_database 11 | # @@protoc_insertion_point(imports) 12 | 13 | _sym_db = _symbol_database.Default() 14 | 15 | 16 | import constants_pb2 as constants__pb2 17 | import wifi_constants_pb2 as wifi__constants__pb2 18 | 19 | 20 | DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0fwifi_scan.proto\x1a\x0f\x63onstants.proto\x1a\x14wifi_constants.proto\"\\\n\x0c\x43mdScanStart\x12\x10\n\x08\x62locking\x18\x01 \x01(\x08\x12\x0f\n\x07passive\x18\x02 \x01(\x08\x12\x16\n\x0egroup_channels\x18\x03 \x01(\r\x12\x11\n\tperiod_ms\x18\x04 \x01(\r\"\x0f\n\rRespScanStart\"\x0f\n\rCmdScanStatus\"=\n\x0eRespScanStatus\x12\x15\n\rscan_finished\x18\x01 \x01(\x08\x12\x14\n\x0cresult_count\x18\x02 \x01(\r\"3\n\rCmdScanResult\x12\x13\n\x0bstart_index\x18\x01 \x01(\r\x12\r\n\x05\x63ount\x18\x02 \x01(\r\"i\n\x0eWiFiScanResult\x12\x0c\n\x04ssid\x18\x01 \x01(\x0c\x12\x0f\n\x07\x63hannel\x18\x02 \x01(\r\x12\x0c\n\x04rssi\x18\x03 \x01(\x05\x12\r\n\x05\x62ssid\x18\x04 \x01(\x0c\x12\x1b\n\x04\x61uth\x18\x05 \x01(\x0e\x32\r.WifiAuthMode\"2\n\x0eRespScanResult\x12 \n\x07\x65ntries\x18\x01 \x03(\x0b\x32\x0f.WiFiScanResult\"\xd8\x02\n\x0fWiFiScanPayload\x12\x1d\n\x03msg\x18\x01 \x01(\x0e\x32\x10.WiFiScanMsgType\x12\x17\n\x06status\x18\x02 \x01(\x0e\x32\x07.Status\x12\'\n\x0e\x63md_scan_start\x18\n \x01(\x0b\x32\r.CmdScanStartH\x00\x12)\n\x0fresp_scan_start\x18\x0b \x01(\x0b\x32\x0e.RespScanStartH\x00\x12)\n\x0f\x63md_scan_status\x18\x0c \x01(\x0b\x32\x0e.CmdScanStatusH\x00\x12+\n\x10resp_scan_status\x18\r \x01(\x0b\x32\x0f.RespScanStatusH\x00\x12)\n\x0f\x63md_scan_result\x18\x0e \x01(\x0b\x32\x0e.CmdScanResultH\x00\x12+\n\x10resp_scan_result\x18\x0f \x01(\x0b\x32\x0f.RespScanResultH\x00\x42\t\n\x07payload*\x9c\x01\n\x0fWiFiScanMsgType\x12\x14\n\x10TypeCmdScanStart\x10\x00\x12\x15\n\x11TypeRespScanStart\x10\x01\x12\x15\n\x11TypeCmdScanStatus\x10\x02\x12\x16\n\x12TypeRespScanStatus\x10\x03\x12\x15\n\x11TypeCmdScanResult\x10\x04\x12\x16\n\x12TypeRespScanResult\x10\x05\x62\x06proto3') 21 | 22 | _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) 23 | _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'wifi_scan_pb2', globals()) 24 | if _descriptor._USE_C_DESCRIPTORS == False: 25 | 26 | DESCRIPTOR._options = None 27 | _WIFISCANMSGTYPE._serialized_start=809 28 | _WIFISCANMSGTYPE._serialized_end=965 29 | _CMDSCANSTART._serialized_start=58 30 | _CMDSCANSTART._serialized_end=150 31 | _RESPSCANSTART._serialized_start=152 32 | _RESPSCANSTART._serialized_end=167 33 | _CMDSCANSTATUS._serialized_start=169 34 | _CMDSCANSTATUS._serialized_end=184 35 | _RESPSCANSTATUS._serialized_start=186 36 | _RESPSCANSTATUS._serialized_end=247 37 | _CMDSCANRESULT._serialized_start=249 38 | _CMDSCANRESULT._serialized_end=300 39 | _WIFISCANRESULT._serialized_start=302 40 | _WIFISCANRESULT._serialized_end=407 41 | _RESPSCANRESULT._serialized_start=409 42 | _RESPSCANRESULT._serialized_end=459 43 | _WIFISCANPAYLOAD._serialized_start=462 44 | _WIFISCANPAYLOAD._serialized_end=806 45 | # @@protoc_insertion_point(module_scope) 46 | -------------------------------------------------------------------------------- /components/wifi_provisioning/src/scheme_console.c: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2019-2024 Espressif Systems (Shanghai) CO LTD 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include 13 | #include 14 | 15 | #include "wifi_provisioning/scheme_console.h" 16 | #include "wifi_provisioning_priv.h" 17 | 18 | static const char *TAG = "wifi_prov_scheme_console"; 19 | 20 | extern const wifi_prov_scheme_t wifi_prov_scheme_console; 21 | 22 | static esp_err_t prov_start(protocomm_t *pc, void *config) 23 | { 24 | if (!pc) { 25 | ESP_LOGE(TAG, "Protocomm handle cannot be null"); 26 | return ESP_ERR_INVALID_ARG; 27 | } 28 | 29 | if (!config) { 30 | ESP_LOGE(TAG, "Cannot start with null configuration"); 31 | return ESP_ERR_INVALID_ARG; 32 | } 33 | 34 | protocomm_console_config_t *console_config = (protocomm_console_config_t *) config; 35 | 36 | /* Start protocomm console */ 37 | esp_err_t err = protocomm_console_start(pc, console_config); 38 | if (err != ESP_OK) { 39 | ESP_LOGE(TAG, "Failed to start protocomm HTTP server"); 40 | return ESP_FAIL; 41 | } 42 | return ESP_OK; 43 | } 44 | 45 | static void *new_config(void) 46 | { 47 | protocomm_console_config_t *console_config = malloc(sizeof(protocomm_console_config_t)); 48 | if (!console_config) { 49 | ESP_LOGE(TAG, "Error allocating memory for new configuration"); 50 | return NULL; 51 | } 52 | protocomm_console_config_t default_config = PROTOCOMM_CONSOLE_DEFAULT_CONFIG(); 53 | memcpy(console_config, &default_config, sizeof(default_config)); 54 | return console_config; 55 | } 56 | 57 | static void delete_config(void *config) 58 | { 59 | if (!config) { 60 | ESP_LOGE(TAG, "Cannot delete null configuration"); 61 | return; 62 | } 63 | free(config); 64 | } 65 | 66 | static esp_err_t set_config_service(void *config, const char *service_name, const char *service_key) 67 | { 68 | return ESP_OK; 69 | } 70 | 71 | static esp_err_t set_config_endpoint(void *config, const char *endpoint_name, uint16_t uuid) 72 | { 73 | return ESP_OK; 74 | } 75 | 76 | const wifi_prov_scheme_t wifi_prov_scheme_console = { 77 | .prov_start = prov_start, 78 | .prov_stop = protocomm_console_stop, 79 | .new_config = new_config, 80 | .delete_config = delete_config, 81 | .set_config_service = set_config_service, 82 | .set_config_endpoint = set_config_endpoint, 83 | .wifi_mode = WIFI_MODE_STA 84 | }; 85 | -------------------------------------------------------------------------------- /components/wifi_provisioning/src/wifi_ctrl.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #ifndef _PROV_WIFI_CTRL_H_ 8 | #define _PROV_WIFI_CTRL_H_ 9 | 10 | #ifdef __cplusplus 11 | extern "C" { 12 | #endif 13 | 14 | /** 15 | * @brief Internal handlers for receiving and responding to protocomm 16 | * requests from client 17 | * 18 | * This is to be passed as priv_data for protocomm request handler 19 | * (refer to `wifi_ctrl_handler()`) when calling `protocomm_add_endpoint()`. 20 | */ 21 | typedef struct wifi_ctrl_handlers { 22 | /** 23 | * Handler function called when ctrl reset command is received 24 | */ 25 | esp_err_t (*ctrl_reset)(void); 26 | 27 | /** 28 | * Handler function called when ctrl reprov command is received 29 | */ 30 | esp_err_t (*ctrl_reprov)(void); 31 | 32 | } wifi_ctrl_handlers_t; 33 | 34 | /** 35 | * @brief Handler for sending on demand Wi-Fi ctrl results 36 | * 37 | * This is to be registered as the `prov-ctrl` endpoint handler 38 | * (protocomm `protocomm_req_handler_t`) using `protocomm_add_endpoint()` 39 | */ 40 | esp_err_t wifi_ctrl_handler(uint32_t session_id, const uint8_t *inbuf, ssize_t inlen, 41 | uint8_t **outbuf, ssize_t *outlen, void *priv_data); 42 | 43 | #ifdef __cplusplus 44 | } 45 | #endif 46 | 47 | #endif 48 | -------------------------------------------------------------------------------- /components/wifi_provisioning/src/wifi_provisioning_priv.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2019-2022 Espressif Systems (Shanghai) CO LTD 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #pragma once 8 | 9 | #include 10 | #include 11 | 12 | #include "wifi_provisioning/manager.h" 13 | #include "wifi_provisioning/wifi_config.h" 14 | #include "wifi_provisioning/wifi_scan.h" 15 | #include "wifi_ctrl.h" 16 | 17 | /** 18 | * @brief Notify manager that provisioning is done 19 | * 20 | * Stops the provisioning. This is called by the get_status_handler() 21 | * when the status is connected. This has no effect if main application 22 | * has disabled auto stop on completion by calling 23 | * wifi_prov_mgr_disable_auto_stop() 24 | * 25 | * @return 26 | * - ESP_OK : Provisioning will be stopped 27 | * - ESP_FAIL : Failed to stop provisioning 28 | */ 29 | esp_err_t wifi_prov_mgr_done(void); 30 | 31 | /** 32 | * @brief Start Wi-Fi AP Scan 33 | * 34 | * @param[in] blocking Set true to return only after scanning is complete 35 | * @param[in] passive Set true to perform passive scan instead of default active scan 36 | * @param[in] group_channels Number of channels to scan in one go 37 | * (set to 0 for scanning all channels in one go) 38 | * @param[in] period_ms Scan time (in milli-seconds) on each channel 39 | * 40 | * @return 41 | * - ESP_OK : Successfully started Wi-Fi scanning 42 | * - ESP_FAIL : Provisioning app not running 43 | */ 44 | esp_err_t wifi_prov_mgr_wifi_scan_start(bool blocking, bool passive, 45 | uint8_t group_channels, 46 | uint32_t period_ms); 47 | 48 | /** 49 | * @brief Use to query the state of Wi-Fi scan 50 | * 51 | * @return 52 | * - true : Scan finished 53 | * - false : Scan running 54 | */ 55 | bool wifi_prov_mgr_wifi_scan_finished(void); 56 | 57 | /** 58 | * @brief Get the count of results in the scan list 59 | * 60 | * @return 61 | * - count : Number of Wi-Fi Access Points detected while scanning 62 | */ 63 | uint16_t wifi_prov_mgr_wifi_scan_result_count(void); 64 | 65 | /** 66 | * @brief Get AP record for a particular index in the scan list result 67 | * 68 | * @param[out] index Index of the result to fetch 69 | * 70 | * @return 71 | * - result : Pointer to Access Point record 72 | */ 73 | const wifi_ap_record_t *wifi_prov_mgr_wifi_scan_result(uint16_t index); 74 | 75 | /** 76 | * @brief Get protocomm handlers for wifi_config provisioning endpoint 77 | * 78 | * @param[out] ptr pointer to structure to be set 79 | * 80 | * @return 81 | * - ESP_OK : success 82 | * - ESP_ERR_INVALID_ARG : null argument 83 | */ 84 | esp_err_t get_wifi_prov_handlers(wifi_prov_config_handlers_t *ptr); 85 | 86 | /** 87 | * @brief Get protocomm handlers for wifi_scan provisioning endpoint 88 | * 89 | * @param[out] ptr pointer to structure to be set 90 | * 91 | * @return 92 | * - ESP_OK : success 93 | * - ESP_ERR_INVALID_ARG : null argument 94 | */ 95 | esp_err_t get_wifi_scan_handlers(wifi_prov_scan_handlers_t *ptr); 96 | 97 | /** 98 | * @brief Get protocomm handlers for wifi_ctrl provisioning endpoint 99 | * 100 | * @param[in] ptr pointer to structure to be set 101 | * 102 | * @return 103 | * - ESP_OK : success 104 | * - ESP_ERR_INVALID_ARG : null argument 105 | */ 106 | esp_err_t get_wifi_ctrl_handlers(wifi_ctrl_handlers_t *ptr); 107 | -------------------------------------------------------------------------------- /examples/mesh_local_control/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # The following lines of boilerplate have to be in your project's 2 | # CMakeLists in this exact order for cmake to work correctly 3 | cmake_minimum_required(VERSION 3.5) 4 | 5 | include($ENV{IDF_PATH}/tools/cmake/project.cmake) 6 | 7 | project(mesh_local_control) 8 | -------------------------------------------------------------------------------- /examples/mesh_local_control/README.md: -------------------------------------------------------------------------------- 1 | - [中文版本](https://github.com/espressif/esp-mesh-lite/blob/master/examples/mesh_local_control/README_CN.md) 2 | 3 | | Supported Targets | ESP32 | ESP32-C3 | ESP32-S2 | ESP32-S3 | ESP32-C2 | ESP32-C6 | 4 | | ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | 5 | 6 | # Mesh Local Control Example 7 | 8 | ## Introduction 9 | 10 | This example will introduce how to implement a device connection to a remote external server based on Mesh-Lite. Different from ESP-WIFI-MESH, each device in the Mesh-Lite network can independently access the external network. 11 | 12 | This example implements the function of device data transmission in the mesh network to the TCP server. 13 | 14 | ## Hardware 15 | 16 | * At least 2 x ESP32 development boards 17 | * 1 x router that supports 2.4G 18 | 19 | ## Process 20 | 21 | ESP-Mesh-Lite is developed based on ESP-IDF functions and tools. Therefore, the ESP-IDF development environment must be set up first. You can refer to [Setting up Development Environment](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/get-started/index.html) for detailed steps. Afterward, you can build the example directly in ESP-Mesh-Lite, similar to building the example in ESP-IDF. 22 | 23 | ### Run TCP server 24 | 25 | 1. Connect PC or the mobile phone to the router. 26 | 2. Use a TCP testing tool (any third-party TCP testing software) to create a TCP server. 27 | 28 | ### Configure the devices 29 | 30 | Enter `idf.py menuconfig`, and configure the followings under the submenu "Example Configuration". 31 | 32 | * The router information. 33 | * ESP-WIFI-MESH network: The network password length should be between 8 and 64 bits (both exclusive), and the network will not be encrypted if you leave the password blank. 34 | * TCP server: the information of the TCP server run on the PC. 35 | 36 | device_config 37 | 38 | ### Build and Flash 39 | 40 | CMake: 41 | ```shell 42 | idf.py erase_flash flash monitor -p /dev/ttyUSBx 43 | ``` 44 | 45 | ### Run 46 | 47 | ESP-WIFI-MESH devices send the real-time device status to the TCP server at an interval of three seconds. -------------------------------------------------------------------------------- /examples/mesh_local_control/README_CN.md: -------------------------------------------------------------------------------- 1 | - [English Version](https://github.com/espressif/esp-mesh-lite/blob/master/examples/mesh_local_control/README.md) 2 | 3 | | Supported Targets | ESP32 | ESP32-C3 | ESP32-S2 | ESP32-S3 | ESP32-C2 | ESP32-C6 | 4 | | ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | 5 | 6 | # Mesh-Lite 局域网控制示例 7 | 8 | ## 介绍 9 | 10 | 本示例将介绍如何基于 Mesh-Lite 实现设备连接远程外部服务器。与 ESP-WIFI-MESH 不同,Mesh-Lite 组网内每个设备均可独立访问外部网络。 11 | 12 | 本示例实现了 mesh 网络中设备数据传输到 TCP 服务器功能。 13 | 14 | ## 硬件准备 15 | 16 | 1. 至少两块 ESP32 开发板 17 | 2. 一台支持 2.4G 路由器 18 | 19 | ## 工作流程 20 | 21 | ESP-Mesh-Lite 是基于 ESP-IDF 的功能和工具开发的。因此,首先必须设置 ESP-IDF 开发环境。您可以参考[设置开发环境](https://docs.espressif.com/projects/esp-idf/zh_CN/latest/esp32/get-started/index.html)获取详细的步骤。之后,您可以直接在 ESP-Mesh-Lite 中构建示例,类似于在 ESP-IDF 中构建示例。 22 | 23 | ### 运行 TCP 服务器 24 | 25 | 1. 将主机(PC 或手机)连接到路由器。 26 | 2. 使用 TCP 测试工具(此工具为任意一个第三方的 TCP 测试软件)来创建 TCP 服务器。 27 | 28 | ### 配置设备 29 | 30 | 输入 `idf.py menuconfig`,在 “Example Configuration” 子菜单下,进行配置: 31 | 32 | * 路由器信息 33 | * ESP-WIFI-MESH 网络:密码长度要大于 8 位并小于 64 位,设置为空则不加密 34 | * TCP 服务器:主机上运行的 TCP 服务器信息, 包含:IP 地址、端口 35 | 36 | device_config 37 | 38 | ### 编译和烧录 39 | 40 | CMake: 41 | ```shell 42 | idf.py erase_flash flash monitor -p /dev/ttyUSBx 43 | ``` 44 | 45 | ### 运行 46 | 47 | Mesh-Lite 设备每隔三秒会给 TCP 服务发送当前设备的信息 48 | -------------------------------------------------------------------------------- /examples/mesh_local_control/device_config.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esp-mesh-lite/d991f8d9787eecd36239491a6d45a8e041a42907/examples/mesh_local_control/device_config.png -------------------------------------------------------------------------------- /examples/mesh_local_control/main/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | idf_component_register(SRCS "local_control.c" 2 | INCLUDE_DIRS ".") 3 | -------------------------------------------------------------------------------- /examples/mesh_local_control/main/Kconfig.projbuild: -------------------------------------------------------------------------------- 1 | menu "Example Configuration" 2 | 3 | config ROUTER_SSID 4 | string "Router SSID" 5 | default "ROUTER_SSID" 6 | help 7 | Router SSID. 8 | 9 | config ROUTER_PASSWORD 10 | string "Router password" 11 | default "ROUTER_PASSWORD" 12 | help 13 | Router password. 14 | 15 | config SERVER_IP 16 | string "Server IP address" 17 | default "192.168.0.1" 18 | help 19 | Server IP address. 20 | 21 | config SERVER_PORT 22 | int "Server port" 23 | default "8070" 24 | help 25 | Server port. 26 | 27 | endmenu 28 | -------------------------------------------------------------------------------- /examples/mesh_local_control/main/idf_component.yml: -------------------------------------------------------------------------------- 1 | dependencies: 2 | idf: ">=5.0" 3 | mesh_lite: 4 | version: "*" 5 | # Please comment the following line, if this example is installed by idf.py create-project-from-example. 6 | override_path: "../../../components/mesh_lite" 7 | wifi_provisioning: 8 | path: components/wifi_provisioning 9 | git: https://github.com/espressif/esp-mesh-lite.git 10 | -------------------------------------------------------------------------------- /examples/mesh_local_control/sdkconfig.defaults: -------------------------------------------------------------------------------- 1 | # Override some defaults in mesh application project. 2 | 3 | # 4 | # FreeRTOS 5 | # 6 | CONFIG_FREERTOS_HZ=1000 7 | CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=3072 8 | CONFIG_FREERTOS_USE_TRACE_FACILITY=y 9 | CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y 10 | CONFIG_FREERTOS_VTASKLIST_INCLUDE_COREID=y 11 | CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y 12 | 13 | # 14 | # ESP32-specific 15 | # 16 | CONFIG_ESP_TASK_WDT_PANIC=y 17 | CONFIG_ESP_TASK_WDT_TIMEOUT_S=10 18 | CONFIG_ESP_TIMER_TASK_STACK_SIZE=4096 19 | 20 | # LWIP 21 | CONFIG_LWIP_IP_FORWARD=y 22 | CONFIG_LWIP_IPV4_NAPT=y 23 | 24 | CONFIG_MESH_LITE_ENABLE=y 25 | 26 | CONFIG_BRIDGE_SOFTAP_SSID_END_WITH_THE_MAC=y 27 | -------------------------------------------------------------------------------- /examples/mesh_local_control/sdkconfig.defaults.esp32c2: -------------------------------------------------------------------------------- 1 | CONFIG_XTAL_FREQ_26=y 2 | CONFIG_ESP_WIFI_ESPNOW_MAX_ENCRYPT_NUM=0 3 | -------------------------------------------------------------------------------- /examples/mesh_local_control/sdkconfig.eth: -------------------------------------------------------------------------------- 1 | CONFIG_ETH_DMA_BUFFER_SIZE=1600 2 | 3 | CONFIG_ETH_SPI_ETHERNET_DM9051=y 4 | CONFIG_ETH_SPI_ETHERNET_KSZ8851SNL=y 5 | CONFIG_ETH_SPI_ETHERNET_W5500=y 6 | -------------------------------------------------------------------------------- /examples/mesh_wifi_provisioning/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # The following lines of boilerplate have to be in your project's 2 | # CMakeLists in this exact order for cmake to work correctly 3 | cmake_minimum_required(VERSION 3.5) 4 | 5 | include($ENV{IDF_PATH}/tools/cmake/project.cmake) 6 | 7 | project(mesh_wifi_provisioning) 8 | -------------------------------------------------------------------------------- /examples/mesh_wifi_provisioning/README.md: -------------------------------------------------------------------------------- 1 | - [中文版本](https://github.com/espressif/esp-mesh-lite/blob/master/examples/mesh_wifi_provisioning/README_CN.md) 2 | 3 | | Supported Targets | ESP32 | ESP32-C3 | ESP32-S2 | ESP32-S3 | ESP32-C2 | ESP32-C6 | 4 | | ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | 5 | 6 | # Mesh-Lite provisioning example 7 | 8 | ## Introduction 9 | 10 | This example will demonstrate how to provision devices using the ESP Mesh-Lite Provisioning APP. 11 | 12 | ## Hardware 13 | 14 | * At least 2 x ESP32 development boards 15 | * 1 x router that supports 2.4G 16 | 17 | ## APP Preparation 18 | 19 | The ESP Mesh-Lite Provisioning APP requires the customer to compile it themselves from the branch https://github.com/espressif/esp-mesh-lite/tree/feature/zero_provisioning_android. 20 | 21 | ## Process 22 | 23 | ESP-Mesh-Lite is developed based on ESP-IDF functions and tools. Therefore, the ESP-IDF development environment must be set up first. You can refer to [Setting up Development Environment](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/get-started/index.html) for detailed steps. Afterward, you can build the example directly in ESP-Mesh-Lite, similar to building the example in ESP-IDF. 24 | 25 | ### IDF configuration device 26 | 27 | It is recommended to use v5.0.7, v5.1.5, v5.2.3, v5.3.1 and previous tag versions 28 | 29 | ### Build and Flash and Monitor 30 | 31 | CMake: 32 | ```shell 33 | idf.py erase_flash flash monitor -p /dev/ttyUSBx 34 | ``` 35 | 36 | ### Provisioning 37 | 38 | - Open the ESP Mesh-Lite Provisioning APP and click on "Provision New Device" 39 | - Click "I don't have a QR code" and select the BLE type 40 | - The list will show devices waiting for provisioning; select one as the root node and click on the device to provision it 41 | - Once the root node connects to the router successfully, it will automatically provision other sub-nodes through the zero-touch provisioning process 42 | -------------------------------------------------------------------------------- /examples/mesh_wifi_provisioning/README_CN.md: -------------------------------------------------------------------------------- 1 | - [English Version](https://github.com/espressif/esp-mesh-lite/blob/master/examples/mesh_wifi_provisioning/README.md) 2 | 3 | | Supported Targets | ESP32 | ESP32-C3 | ESP32-S2 | ESP32-S3 | ESP32-C2 | ESP32-C6 | 4 | | ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | 5 | 6 | # Mesh-Lite 配网示例 7 | 8 | ## 介绍 9 | 10 | 本示例将介绍如何基于 ESP Mesh-Lite Provisioning APP 为设备配网。 11 | 12 | ## 硬件准备 13 | 14 | 1. 至少两块 ESP32 开发板 15 | 2. 一台支持 2.4G 路由器 16 | 17 | ## APP 准备 18 | 19 | ESP Mesh-Lite Provisioning APP 需要客户根据 https://github.com/espressif/esp-mesh-lite/tree/feature/zero_provisioning_android 分支自己编译。 20 | 21 | ## 工作流程 22 | 23 | ESP-Mesh-Lite 是基于 ESP-IDF 的功能和工具开发的。因此,首先必须设置 ESP-IDF 开发环境。您可以参考[设置开发环境](https://docs.espressif.com/projects/esp-idf/zh_CN/latest/esp32/get-started/index.html)获取详细的步骤。之后,您可以直接在 ESP-Mesh-Lite 中构建示例,类似于在 ESP-IDF 中构建示例。 24 | 25 | ### IDF 配置设备 26 | 27 | 建议使用 v5.0.7、v5.1.5、v5.2.3、v5.3.1 及其之前的 tag 版本 28 | 29 | ### 编译&烧录&运行 30 | 31 | CMake: 32 | ```shell 33 | idf.py erase_flash flash monitor -p /dev/ttyUSBx 34 | ``` 35 | 36 | ### 配网 37 | 38 | - 打开 ESP Mesh-Lite Provisioning APP,点击 `Provision New Device`` 39 | - 点击 `I don't have a QR code`,选择 BLE 类型 40 | - 列表中将会列出待配网设备,选择其中一个作为根节点,点击设备进行配网 41 | - 根节点连接路由器成功后,会自动通过零配流程给其他子节点配网 42 | -------------------------------------------------------------------------------- /examples/mesh_wifi_provisioning/main/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | idf_component_register(SRCS "mesh_wifi_provisioning.c" 2 | INCLUDE_DIRS ".") 3 | -------------------------------------------------------------------------------- /examples/mesh_wifi_provisioning/main/Kconfig.projbuild: -------------------------------------------------------------------------------- 1 | menu "Example Configuration" 2 | 3 | config SERVER_IP 4 | string "Server IP address" 5 | default "192.168.0.1" 6 | help 7 | Server IP address. 8 | 9 | config SERVER_PORT 10 | int "Server port" 11 | default "8070" 12 | help 13 | Server port. 14 | 15 | endmenu 16 | -------------------------------------------------------------------------------- /examples/mesh_wifi_provisioning/main/idf_component.yml: -------------------------------------------------------------------------------- 1 | dependencies: 2 | idf: ">=5.0" 3 | mesh_lite: 4 | version: "*" 5 | # Please comment the following line, if this example is installed by idf.py create-project-from-example. 6 | override_path: "../../../components/mesh_lite" 7 | wifi_provisioning: 8 | path: components/wifi_provisioning 9 | git: https://github.com/espressif/esp-mesh-lite.git 10 | -------------------------------------------------------------------------------- /examples/mesh_wifi_provisioning/sdkconfig.defaults: -------------------------------------------------------------------------------- 1 | # Override some defaults in mesh application project. 2 | 3 | # 4 | # Partition Table 5 | # 6 | CONFIG_PARTITION_TABLE_SINGLE_APP_LARGE=y 7 | 8 | # 9 | # FreeRTOS 10 | # 11 | CONFIG_FREERTOS_HZ=1000 12 | CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=3072 13 | CONFIG_FREERTOS_USE_TRACE_FACILITY=y 14 | CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y 15 | CONFIG_FREERTOS_VTASKLIST_INCLUDE_COREID=y 16 | CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y 17 | 18 | # 19 | # ESP32-specific 20 | # 21 | CONFIG_ESP_TASK_WDT_PANIC=y 22 | CONFIG_ESP_TASK_WDT_TIMEOUT_S=10 23 | CONFIG_ESP_TIMER_TASK_STACK_SIZE=4096 24 | 25 | # LWIP 26 | CONFIG_LWIP_IP_FORWARD=y 27 | CONFIG_LWIP_IPV4_NAPT=y 28 | 29 | CONFIG_MESH_LITE_ENABLE=y 30 | CONFIG_MESH_LITE_PROV_ENABLE=y 31 | CONFIG_BT_NIMBLE_ENABLED=y 32 | CONFIG_JOIN_MESH_WITHOUT_CONFIGURED_WIFI_INFO=n 33 | 34 | CONFIG_BRIDGE_SOFTAP_SSID_END_WITH_THE_MAC=y 35 | -------------------------------------------------------------------------------- /examples/mesh_wifi_provisioning/sdkconfig.defaults.esp32c2: -------------------------------------------------------------------------------- 1 | CONFIG_XTAL_FREQ_26=y 2 | CONFIG_ESP_WIFI_ESPNOW_MAX_ENCRYPT_NUM=0 3 | -------------------------------------------------------------------------------- /examples/no_router/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # The following lines of boilerplate have to be in your project's 2 | # CMakeLists in this exact order for cmake to work correctly 3 | cmake_minimum_required(VERSION 3.5) 4 | 5 | include($ENV{IDF_PATH}/tools/cmake/project.cmake) 6 | 7 | project(no_router) 8 | -------------------------------------------------------------------------------- /examples/no_router/README.md: -------------------------------------------------------------------------------- 1 | - [中文版本](https://github.com/espressif/esp-mesh-lite/blob/master/examples/no_router/README_CN.md) 2 | 3 | # No Router Example 4 | 5 | ## Introduction 6 | 7 | It introduces a quick way to build an ESP-Mesh-Lite network without a router. For details on other network configuration methods, please refer to [README](https://github.com/espressif/esp-mesh-lite/blob/master/examples/mesh_local_control/README.md). Before running this example, please firstly go through [User Guide](https://github.com/espressif/esp-mesh-lite/blob/master/components/mesh_lite/User_Guide.md). 8 | 9 | ## Configure 10 | 11 | To run this example, you need at least two development boards, one configured as a root node, and the other a non-root node. In this example, all the devices are non-root nodes by default. 12 | 13 | - Root node: There is only one root node in an ESP-Mesh-Lite network. `MESH-LITE` networks can be differentiated by their `MESH_LITE_ID` and channels. 14 | - Non-root node: Includes leaf nodes and intermediate nodes, which automatically select their parent nodes according to the network conditions. 15 | - Leaf node: A leaf node cannot also be an intermediate node, which means leaf node cannot has any child nodes. 16 | 17 | You need to go to the submenu `Example Configuration` and configure one device as a root node, and the others as non-root nodes with `idf.py menuconfig`(CMake). 18 | 19 | You can also go to the submenu `Component config -> ESP Wi-Fi Mesh Lite`, and configure the ESP-Mesh-Lite related parameters such as the max number of layers allowed and the `MESH_LITE_ID`. 20 | 21 | example_config 22 | 23 | mesh_config 24 | 25 | ## Run 26 | 27 | 1. Initialize Wi-Fi, and start ESP-Mesh-Lite according to configuration; 28 | 2. Create a timer: print at the specified time the ESP-Mesh-Lite network information about layers, and the parent node's signal strength and the remaining memory. 29 | 30 | ```c 31 | I (1386) vendor_ie: Mesh ID: 77 32 | W (1390) vendor_ie: Error Get[4354] 33 | W (1394) vendor_ie: Error Get[4354] 34 | I (1399) ESP_Mesh_Lite_Comm: msg action add success 35 | I (1405) ESP_Mesh_Lite_Comm: Bind Socket 54, port 6364 36 | I (1410) ESP_Mesh_Lite_Comm: Bind Socket 55, port 6363 37 | I (1416) ESP_Mesh_Lite_Comm: Bind Socket 56, port 6366 38 | I (1421) ESP_Mesh_Lite_Comm: Bind Socket 57, port 6365 39 | I (1428) ESP_Mesh_Lite_Comm: msg action add success 40 | I (1433) no_router: Child node 41 | I (1436) Mesh-Lite: Mesh-Lite connecting 42 | I (1442) main_task: Returned from app_main() 43 | I (4274) vendor_ie: Mesh-Lite Scan done 44 | I (4276) vendor_ie: Find ESP_Bridge_1eb259 45 | I (4276) vendor_ie: RTC store: ssid:ESP_Bridge_1eb259; bssid:58:cf:79:1e:b2:59 crc:3027520052 46 | I (6340) wifi:ap channel adjust o:1,1 n:13,2 47 | I (6340) wifi:new:<13,2>, old:<1,1>, ap:<13,2>, sta:<13,2>, prof:1 48 | I (7031) wifi:state: init -> auth (b0) 49 | I (7033) ESP_Mesh_Lite_Comm: Retry to connect to the AP 50 | I (7044) wifi:state: auth -> assoc (0) 51 | I (7057) wifi:state: assoc -> run (10) 52 | I (7071) wifi:connected with ESP_Bridge_1eb259, aid = 1, channel 13, 40D, bssid = 58:cf:79:1e:b2:59 53 | I (7072) wifi:security: WPA2-PSK, phy: bgn, rssi: -12 54 | I (7074) wifi:pm start, type: 1 55 | 56 | I (7077) wifi:set rx beacon pti, rx_bcn_pti: 0, bcn_timeout: 0, mt_pti: 25000, mt_time: 10000 57 | I (7154) wifi:AP's beacon interval = 102400 us, DTIM period = 2 58 | I (7155) Mesh-Lite: netif network segment conflict check 59 | I (7156) ip select: IP Address:192.168.5.1 60 | I (7160) ip select: GW Address:192.168.5.1 61 | I (7164) ip select: NM Address:255.255.255.0 62 | I (7170) bridge_common: ip reallocate new:192.168.5.1 63 | W (7175) bridge_wifi: SoftAP IP network segment has changed, deauth all station 64 | I (8087) esp_netif_handlers: sta ip: 192.168.5.2, mask: 255.255.255.0, gw: 192.168.5.1 65 | I (8088) bridge_wifi: Connected with IP Address:192.168.5.2 66 | I (8091) ip select: IP Address:192.168.6.1 67 | I (8096) ip select: GW Address:192.168.6.1 68 | I (8101) ip select: NM Address:255.255.255.0 69 | I (8106) bridge_common: ip reallocate new:192.168.6.1 70 | W (8112) bridge_wifi: SoftAP IP network segment has changed, deauth all station 71 | I (8120) vendor_ie: RTC store: ssid:ESP_Bridge_1eb259; bssid:58:cf:79:1e:b2:59 crc:3027520052 72 | I (11442) no_router: System information, channel: 13, layer: 2, self mac: 58:cf:79:e9:9e:c0, parent bssid: 58:cf:79:1e:b2:59, parent rssi: -14, free heap: 209280 73 | I (21442) no_router: System information, channel: 13, layer: 2, self mac: 58:cf:79:e9:9e:c0, parent bssid: 58:cf:79:1e:b2:59, parent rssi: -13, free heap: 209280 74 | I (31442) no_router: System information, channel: 13, layer: 2, self mac: 58:cf:79:e9:9e:c0, parent bssid: 58:cf:79:1e:b2:59, parent rssi: -13, free heap: 209280 75 | ``` 76 | -------------------------------------------------------------------------------- /examples/no_router/README_CN.md: -------------------------------------------------------------------------------- 1 | - [English Version](https://github.com/espressif/esp-mesh-lite/blob/master/examples/no_router/README.md) 2 | 3 | # 无路由器示例 4 | 5 | ## 介绍 6 | 7 | 本示例将介绍如何快速组建一个无路由器 ESP-Mesh-Lite 网络,其余的组网方案及详细使用方式参见 [README](https://github.com/espressif/esp-mesh-lite/blob/master/examples/mesh_local_control/README_CN.md),在运行本示例之前请详细阅读 [User Guide](https://github.com/espressif/esp-mesh-lite/blob/master/components/mesh_lite/User_Guide_CN.md)。 8 | 9 | ## 配置 10 | 11 | 运行本示例,您至少需要准备两块开发板,一块配置为根节点,其余为非根节点,本示例默认为非根节点类型。 12 | 13 | - 根节点:一个 ESP-Mesh-Lite 网络中有且仅有一个根节点,通过 `MESH_LITE_ID` 和信道来区分不同的 `MESH-LITE` 网络 14 | - 非根节点:包含叶子节点和中间节点,其根据网络情况自动选择父节点 15 | - 叶子节点:叶子节点不会做为中间节点,即不允许有下游链接 16 | 17 | 你需要通过 `idf.py menuconfig`(CMake),在 `Example Configuration` 子菜单下,配置一个设备为根节点,其余设备为非根节点。 18 | 您也可以在 `Component config -> ESP Wi-Fi Mesh Lite` 子菜单下,配置 ESP-Mesh-Lite 的最大层级、`MESH_LITE_ID` 等参数。 19 | 20 | example_config 21 | 22 | mesh_config 23 | 24 | ## 运行 25 | 26 | 1. 初始化 Wi-Fi,根据配置启动 ESP-Mesh-Lite; 27 | 2. 创建定时器:定时打印 ESP-Mesh-Lite 网络的层级,父节点的信号强度及剩余内存。 28 | 29 | ```c 30 | I (1386) vendor_ie: Mesh ID: 77 31 | W (1390) vendor_ie: Error Get[4354] 32 | W (1394) vendor_ie: Error Get[4354] 33 | I (1399) ESP_Mesh_Lite_Comm: msg action add success 34 | I (1405) ESP_Mesh_Lite_Comm: Bind Socket 54, port 6364 35 | I (1410) ESP_Mesh_Lite_Comm: Bind Socket 55, port 6363 36 | I (1416) ESP_Mesh_Lite_Comm: Bind Socket 56, port 6366 37 | I (1421) ESP_Mesh_Lite_Comm: Bind Socket 57, port 6365 38 | I (1428) ESP_Mesh_Lite_Comm: msg action add success 39 | I (1433) no_router: Child node 40 | I (1436) Mesh-Lite: Mesh-Lite connecting 41 | I (1442) main_task: Returned from app_main() 42 | I (4274) vendor_ie: Mesh-Lite Scan done 43 | I (4276) vendor_ie: Find ESP_Bridge_1eb259 44 | I (4276) vendor_ie: RTC store: ssid:ESP_Bridge_1eb259; bssid:58:cf:79:1e:b2:59 crc:3027520052 45 | I (6340) wifi:ap channel adjust o:1,1 n:13,2 46 | I (6340) wifi:new:<13,2>, old:<1,1>, ap:<13,2>, sta:<13,2>, prof:1 47 | I (7031) wifi:state: init -> auth (b0) 48 | I (7033) ESP_Mesh_Lite_Comm: Retry to connect to the AP 49 | I (7044) wifi:state: auth -> assoc (0) 50 | I (7057) wifi:state: assoc -> run (10) 51 | I (7071) wifi:connected with ESP_Bridge_1eb259, aid = 1, channel 13, 40D, bssid = 58:cf:79:1e:b2:59 52 | I (7072) wifi:security: WPA2-PSK, phy: bgn, rssi: -12 53 | I (7074) wifi:pm start, type: 1 54 | 55 | I (7077) wifi:set rx beacon pti, rx_bcn_pti: 0, bcn_timeout: 0, mt_pti: 25000, mt_time: 10000 56 | I (7154) wifi:AP's beacon interval = 102400 us, DTIM period = 2 57 | I (7155) Mesh-Lite: netif network segment conflict check 58 | I (7156) ip select: IP Address:192.168.5.1 59 | I (7160) ip select: GW Address:192.168.5.1 60 | I (7164) ip select: NM Address:255.255.255.0 61 | I (7170) bridge_common: ip reallocate new:192.168.5.1 62 | W (7175) bridge_wifi: SoftAP IP network segment has changed, deauth all station 63 | I (8087) esp_netif_handlers: sta ip: 192.168.5.2, mask: 255.255.255.0, gw: 192.168.5.1 64 | I (8088) bridge_wifi: Connected with IP Address:192.168.5.2 65 | I (8091) ip select: IP Address:192.168.6.1 66 | I (8096) ip select: GW Address:192.168.6.1 67 | I (8101) ip select: NM Address:255.255.255.0 68 | I (8106) bridge_common: ip reallocate new:192.168.6.1 69 | W (8112) bridge_wifi: SoftAP IP network segment has changed, deauth all station 70 | I (8120) vendor_ie: RTC store: ssid:ESP_Bridge_1eb259; bssid:58:cf:79:1e:b2:59 crc:3027520052 71 | I (11442) no_router: System information, channel: 13, layer: 2, self mac: 58:cf:79:e9:9e:c0, parent bssid: 58:cf:79:1e:b2:59, parent rssi: -14, free heap: 209280 72 | I (21442) no_router: System information, channel: 13, layer: 2, self mac: 58:cf:79:e9:9e:c0, parent bssid: 58:cf:79:1e:b2:59, parent rssi: -13, free heap: 209280 73 | I (31442) no_router: System information, channel: 13, layer: 2, self mac: 58:cf:79:e9:9e:c0, parent bssid: 58:cf:79:1e:b2:59, parent rssi: -13, free heap: 209280 74 | ``` 75 | -------------------------------------------------------------------------------- /examples/no_router/example_config.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esp-mesh-lite/d991f8d9787eecd36239491a6d45a8e041a42907/examples/no_router/example_config.png -------------------------------------------------------------------------------- /examples/no_router/main/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | idf_component_register(SRCS "no_router.c" 2 | INCLUDE_DIRS ".") 3 | -------------------------------------------------------------------------------- /examples/no_router/main/Kconfig.projbuild: -------------------------------------------------------------------------------- 1 | menu "Example Configuration" 2 | 3 | config MESH_ROOT 4 | select JOIN_MESH_IGNORE_ROUTER_STATUS 5 | bool "Root device" 6 | default n 7 | help 8 | Configure the root device type. 9 | 10 | config MESH_CHANNEL 11 | int "Mesh network channel" 12 | range 1 14 13 | default 11 14 | help 15 | Mesh network channel. 16 | 17 | endmenu 18 | -------------------------------------------------------------------------------- /examples/no_router/main/idf_component.yml: -------------------------------------------------------------------------------- 1 | dependencies: 2 | idf: ">=5.0" 3 | mesh_lite: 4 | version: "*" 5 | # Please comment the following line, if this example is installed by idf.py create-project-from-example. 6 | override_path: "../../../components/mesh_lite" 7 | wifi_provisioning: 8 | path: components/wifi_provisioning 9 | git: https://github.com/espressif/esp-mesh-lite.git 10 | -------------------------------------------------------------------------------- /examples/no_router/main/no_router.c: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #include 8 | #include "esp_log.h" 9 | #include "freertos/FreeRTOS.h" 10 | #include "freertos/task.h" 11 | #include "freertos/timers.h" 12 | 13 | #include "esp_wifi.h" 14 | #include "nvs_flash.h" 15 | #include 16 | 17 | #include "esp_mac.h" 18 | #include "esp_bridge.h" 19 | #include "esp_mesh_lite.h" 20 | 21 | static const char *TAG = "no_router"; 22 | 23 | /** 24 | * @brief Timed printing system information 25 | */ 26 | static void print_system_info_timercb(TimerHandle_t timer) 27 | { 28 | uint8_t primary = 0; 29 | uint8_t sta_mac[6] = {0}; 30 | wifi_ap_record_t ap_info = {0}; 31 | wifi_second_chan_t second = 0; 32 | wifi_sta_list_t wifi_sta_list = {0x0}; 33 | 34 | if (esp_mesh_lite_get_level() > 1) { 35 | esp_wifi_sta_get_ap_info(&ap_info); 36 | } 37 | esp_wifi_get_mac(ESP_IF_WIFI_STA, sta_mac); 38 | esp_wifi_ap_get_sta_list(&wifi_sta_list); 39 | esp_wifi_get_channel(&primary, &second); 40 | 41 | ESP_LOGI(TAG, "System information, channel: %d, layer: %d, self mac: " MACSTR ", parent bssid: " MACSTR 42 | ", parent rssi: %d, free heap: %"PRIu32"", primary, 43 | esp_mesh_lite_get_level(), MAC2STR(sta_mac), MAC2STR(ap_info.bssid), 44 | (ap_info.rssi != 0 ? ap_info.rssi : -120), esp_get_free_heap_size()); 45 | 46 | for (int i = 0; i < wifi_sta_list.num; i++) { 47 | ESP_LOGI(TAG, "Child mac: " MACSTR, MAC2STR(wifi_sta_list.sta[i].mac)); 48 | } 49 | 50 | uint32_t size = 0; 51 | const node_info_list_t *node = esp_mesh_lite_get_nodes_list(&size); 52 | printf("MeshLite nodes %ld:\r\n", size); 53 | for (uint32_t loop = 0; (loop < size) && (node != NULL); loop++) { 54 | struct in_addr ip_struct; 55 | ip_struct.s_addr = node->node->ip_addr; 56 | printf("%ld: %d, "MACSTR", %s\r\n" , loop + 1, node->node->level, MAC2STR(node->node->mac_addr), inet_ntoa(ip_struct)); 57 | node = node->next; 58 | } 59 | } 60 | 61 | static esp_err_t esp_storage_init(void) 62 | { 63 | esp_err_t ret = nvs_flash_init(); 64 | 65 | if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { 66 | // NVS partition was truncated and needs to be erased 67 | // Retry nvs_flash_init 68 | ESP_ERROR_CHECK(nvs_flash_erase()); 69 | ret = nvs_flash_init(); 70 | } 71 | 72 | return ret; 73 | } 74 | 75 | static void wifi_init(void) 76 | { 77 | // Station 78 | wifi_config_t wifi_config; 79 | memset(&wifi_config, 0x0, sizeof(wifi_config_t)); 80 | esp_bridge_wifi_set_config(WIFI_IF_STA, &wifi_config); 81 | 82 | // Softap 83 | wifi_config_t wifi_softap_config = { 84 | .ap = { 85 | .ssid = CONFIG_BRIDGE_SOFTAP_SSID, 86 | .password = CONFIG_BRIDGE_SOFTAP_PASSWORD, 87 | .channel = CONFIG_MESH_CHANNEL, 88 | }, 89 | }; 90 | esp_bridge_wifi_set_config(WIFI_IF_AP, &wifi_softap_config); 91 | } 92 | 93 | void app_wifi_set_softap_info(void) 94 | { 95 | char softap_ssid[33]; 96 | char softap_psw[64]; 97 | uint8_t softap_mac[6]; 98 | size_t ssid_size = sizeof(softap_ssid); 99 | size_t psw_size = sizeof(softap_psw); 100 | esp_wifi_get_mac(WIFI_IF_AP, softap_mac); 101 | memset(softap_ssid, 0x0, sizeof(softap_ssid)); 102 | memset(softap_psw, 0x0, sizeof(softap_psw)); 103 | 104 | if (esp_mesh_lite_get_softap_ssid_from_nvs(softap_ssid, &ssid_size) == ESP_OK) { 105 | ESP_LOGI(TAG, "Get ssid from nvs: %s", softap_ssid); 106 | } else { 107 | #ifdef CONFIG_BRIDGE_SOFTAP_SSID_END_WITH_THE_MAC 108 | snprintf(softap_ssid, sizeof(softap_ssid), "%.25s_%02x%02x%02x", CONFIG_BRIDGE_SOFTAP_SSID, softap_mac[3], softap_mac[4], softap_mac[5]); 109 | #else 110 | snprintf(softap_ssid, sizeof(softap_ssid), "%.32s", CONFIG_BRIDGE_SOFTAP_SSID); 111 | #endif 112 | ESP_LOGI(TAG, "Get ssid from nvs failed, set ssid: %s", softap_ssid); 113 | } 114 | 115 | if (esp_mesh_lite_get_softap_psw_from_nvs(softap_psw, &psw_size) == ESP_OK) { 116 | ESP_LOGI(TAG, "Get psw from nvs: [HIDDEN]"); 117 | } else { 118 | strlcpy(softap_psw, CONFIG_BRIDGE_SOFTAP_PASSWORD, sizeof(softap_psw)); 119 | ESP_LOGI(TAG, "Get psw from nvs failed, set psw: [HIDDEN]"); 120 | } 121 | 122 | esp_mesh_lite_set_softap_info(softap_ssid, softap_psw); 123 | } 124 | 125 | void app_main() 126 | { 127 | // Set the log level for serial port printing. 128 | esp_log_level_set("*", ESP_LOG_INFO); 129 | 130 | esp_storage_init(); 131 | 132 | ESP_ERROR_CHECK(esp_netif_init()); 133 | ESP_ERROR_CHECK(esp_event_loop_create_default()); 134 | 135 | esp_bridge_create_all_netif(); 136 | 137 | wifi_init(); 138 | 139 | esp_mesh_lite_config_t mesh_lite_config = ESP_MESH_LITE_DEFAULT_INIT(); 140 | mesh_lite_config.join_mesh_ignore_router_status = true; 141 | #if CONFIG_MESH_ROOT 142 | mesh_lite_config.join_mesh_without_configured_wifi = false; 143 | #else 144 | mesh_lite_config.join_mesh_without_configured_wifi = true; 145 | #endif 146 | esp_mesh_lite_init(&mesh_lite_config); 147 | 148 | app_wifi_set_softap_info(); 149 | 150 | #if CONFIG_MESH_ROOT 151 | ESP_LOGI(TAG, "Root node"); 152 | esp_mesh_lite_set_allowed_level(1); 153 | #else 154 | ESP_LOGI(TAG, "Child node"); 155 | esp_mesh_lite_set_disallowed_level(1); 156 | #endif 157 | 158 | esp_mesh_lite_start(); 159 | 160 | TimerHandle_t timer = xTimerCreate("print_system_info", 10000 / portTICK_PERIOD_MS, 161 | true, NULL, print_system_info_timercb); 162 | xTimerStart(timer, 0); 163 | } 164 | -------------------------------------------------------------------------------- /examples/no_router/mesh_config.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esp-mesh-lite/d991f8d9787eecd36239491a6d45a8e041a42907/examples/no_router/mesh_config.png -------------------------------------------------------------------------------- /examples/no_router/sdkconfig.defaults: -------------------------------------------------------------------------------- 1 | # Override some defaults in mesh application project. 2 | 3 | # 4 | # FreeRTOS 5 | # 6 | CONFIG_FREERTOS_HZ=1000 7 | CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=3072 8 | CONFIG_FREERTOS_USE_TRACE_FACILITY=y 9 | CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y 10 | CONFIG_FREERTOS_VTASKLIST_INCLUDE_COREID=y 11 | CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y 12 | 13 | # 14 | # ESP32-specific 15 | # 16 | CONFIG_ESP_TASK_WDT_PANIC=y 17 | CONFIG_ESP_TASK_WDT_TIMEOUT_S=10 18 | CONFIG_ESP_TIMER_TASK_STACK_SIZE=4096 19 | 20 | # LWIP 21 | CONFIG_LWIP_IP_FORWARD=y 22 | CONFIG_LWIP_IPV4_NAPT=y 23 | 24 | CONFIG_MESH_LITE_ENABLE=y 25 | CONFIG_MESH_LITE_NODE_INFO_REPORT=y 26 | 27 | CONFIG_BRIDGE_SOFTAP_SSID_END_WITH_THE_MAC=y 28 | -------------------------------------------------------------------------------- /examples/no_router/sdkconfig.defaults.esp32c2: -------------------------------------------------------------------------------- 1 | CONFIG_XTAL_FREQ_26=y 2 | CONFIG_ESP_WIFI_ESPNOW_MAX_ENCRYPT_NUM=0 3 | -------------------------------------------------------------------------------- /examples/rainmaker/led_light/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # The following five lines of boilerplate have to be in your project's 2 | # CMakeLists in this exact order for cmake to work correctly 3 | cmake_minimum_required(VERSION 3.5) 4 | 5 | add_definitions(-w) 6 | add_compile_options(-fdiagnostics-color=always) 7 | 8 | # Add git describe to version 9 | EXECUTE_PROCESS( 10 | COMMAND git describe --always --dirty 11 | OUTPUT_VARIABLE IMAGE_VERSION_GIT_HEAD_VERSION 12 | OUTPUT_STRIP_TRAILING_WHITESPACE 13 | ERROR_VARIABLE GET_GIT_VERSION_FAILED 14 | ) 15 | string(CONCAT PROJECT_V "v1.0.0" "-beta_" ${IMAGE_VERSION_GIT_HEAD_VERSION}) 16 | set(PROJECT_VER ${PROJECT_V}) 17 | 18 | include($ENV{IDF_PATH}/tools/cmake/project.cmake) 19 | project(led_light) 20 | -------------------------------------------------------------------------------- /examples/rainmaker/led_light/README_CN.md: -------------------------------------------------------------------------------- 1 | - [English Version](https://github.com/espressif/esp-mesh-lite/blob/master/examples/rainmaker/led_light/README.md) 2 | 3 | | Supported Targets | ESP32 | ESP32-C3 | ESP32-S3 | 4 | | ----------------- | ----- | -------- | -------- | 5 | 6 | # LED Light 示例(Nova Home) 7 | 8 | 本示例通过使用 [Rainmaker 云平台](https://rainmaker.espressif.com) 来展示 ESP-Mesh-Lite 功能,用户可通过 `Nova Home` APP 来为设备配网并使设备成功连接至 Rainmaker 云端,设备本身基于 Rainmaker 实现自身连接云端的同时,还可以为其他无线设备提供无线上网的能力,多个设备形成 Mesh 组网,极大程度上减轻路由器承载压力,同时扩大了无线通信范围。 9 | 10 | ## Get Start 11 | 12 | ### 1. Apps 13 | 14 | - [Google PlayStore](https://play.google.com/store/apps/details?id=com.espressif.novahome) 15 | 16 | - [Apple App Store](https://apps.apple.com/us/app/nova-home/id1563728960) 17 | 18 | ### 2. 获取 Key 19 | 20 | 目前设备获取证书的方式有两种: 21 | 22 | - Self Claiming:配网后设备直接发 http 请求从服务器拉证书,只能在 ESP32-S3 和 ESP32-C3 上应用,由于与 MAC 绑定,每一台设备每次拉取的证书是一样的 23 | - Assisted Claiming:配网时,手机 APP 跟服务器请求证书,随后通过蓝牙发送给设备,不和 MAC 绑定,默认一个账户只有 5 次申请的限制 24 | 25 | 目前 ESP32-S3 和 ESP32-C3 默认采用 Self-Claiming 的方式获取证书,ESP32 仅能使用 Assisted Claiming 方式获取证书。 26 | 27 | >Nova Home 目前 Assisted Claiming 方式不稳定,若使用 ESP32 获取证书建议使用 [ESP Rainmaker](https://github.com/espressif/esp-rainmaker#phone-apps) APP 进行 Claiming 28 | 29 | ### 3. 编译环境搭建 & SDK 准备 30 | 31 | 参考 [README](https://github.com/espressif/esp-iot-bridge/blob/master/components/iot_bridge/User_Guide.md#3-set-up-development-environment) 32 | 33 | ### 4. Mesh-Lite 功能 34 | 35 | - 可以在 menuconfig 配置 `Component config → ESP Wi-Fi Mesh Lite` 中选择是否使能 Mesh-Lite 功能,本示例默认使能该功能。 36 | 37 | - 若开启 Mesh-Lite 功能,第一个配网的设备会连接至目标路由器并作为 Root 根结点,之后的设备均会连接至根结点设备并作为子节点组成一个 Mesh-Lite 网络,详情请参考 [Mesh-Lite](https://github.com/espressif/esp-mesh-lite/blob/master/components/mesh_lite/User_Guide_CN.md)。 38 | 39 | ### 5. 固件编译 & 烧录 40 | 41 | ESP-IDF 环境搭建成功后,即可执行以下命令进行固件编译和烧录。 42 | 43 | ``` 44 | $ cd esp-mesh-lite/examples/rainmaker/led_light 45 | $ idf.py set-target esp32c3 46 | $ idf.py build 47 | $ idf.py flash 48 | ``` 49 | 50 | ### 6. 操作步骤 51 | 52 | #### 6.1 添加根节点 53 | 54 | - 打开 Nova Home,APP 自动搜索到待配网设备 55 | 56 | find_devices 57 | 58 | - 选择其中某个设备 59 | 60 | select_root_node 61 | 62 | - 输入配网信息进入配网 63 | 64 | select_network 65 | 66 | - 配网成功 67 | 68 | root_done 69 | 70 | - 配网成功后的设备 71 | 72 | root_device_of_common 73 | 74 | - 配网成功后的设备所属 Mesh 页面(Mesh ID 为 117) 75 | 76 | root_device_of_mesh 77 | 78 | #### 6.2 添加子节点 79 | 80 | - 进入对应 Mesh 页面,点击右上角加号 81 | 82 | mesh_page 83 | 84 | - 选择要配网的子节电设备 85 | 86 | select_child_devices 87 | 88 | - 输入配网信息(同为路由器信息)进入配网 89 | 90 | select_network 91 | 92 | - 配网成功 93 | 94 | child_done 95 | 96 | #### 6.3 群控 97 | 98 | - 进入 Mesh 页面,点击对应根节点,进入控制页面进行控制 Mesh 组网内部所有设备的灯效 99 | 100 | root_control 101 | 102 | #### 6.4 组控 103 | 104 | - 进入 Mesh 页面,点击左下角 Group 105 | 106 | click_group 107 | 108 | - 创建 Mesh Group 109 | 110 | select_device_for_group 111 | 112 | - 通过创建的 Group 页面进行控制 113 | 114 | group_control 115 | 116 | ### 7. 注意事项 117 | 118 | - 目前 Nova Home 仅支持 Wi-Fi Provisioning 配网(BLE),故该示例目前不支持 ESP32-S2 芯片 119 | -------------------------------------------------------------------------------- /examples/rainmaker/led_light/_static/child_done.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esp-mesh-lite/d991f8d9787eecd36239491a6d45a8e041a42907/examples/rainmaker/led_light/_static/child_done.png -------------------------------------------------------------------------------- /examples/rainmaker/led_light/_static/click_group.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esp-mesh-lite/d991f8d9787eecd36239491a6d45a8e041a42907/examples/rainmaker/led_light/_static/click_group.png -------------------------------------------------------------------------------- /examples/rainmaker/led_light/_static/find_devices.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esp-mesh-lite/d991f8d9787eecd36239491a6d45a8e041a42907/examples/rainmaker/led_light/_static/find_devices.jpg -------------------------------------------------------------------------------- /examples/rainmaker/led_light/_static/group_control.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esp-mesh-lite/d991f8d9787eecd36239491a6d45a8e041a42907/examples/rainmaker/led_light/_static/group_control.png -------------------------------------------------------------------------------- /examples/rainmaker/led_light/_static/mesh_page.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esp-mesh-lite/d991f8d9787eecd36239491a6d45a8e041a42907/examples/rainmaker/led_light/_static/mesh_page.png -------------------------------------------------------------------------------- /examples/rainmaker/led_light/_static/root_control.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esp-mesh-lite/d991f8d9787eecd36239491a6d45a8e041a42907/examples/rainmaker/led_light/_static/root_control.png -------------------------------------------------------------------------------- /examples/rainmaker/led_light/_static/root_device_of_common.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esp-mesh-lite/d991f8d9787eecd36239491a6d45a8e041a42907/examples/rainmaker/led_light/_static/root_device_of_common.png -------------------------------------------------------------------------------- /examples/rainmaker/led_light/_static/root_device_of_mesh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esp-mesh-lite/d991f8d9787eecd36239491a6d45a8e041a42907/examples/rainmaker/led_light/_static/root_device_of_mesh.png -------------------------------------------------------------------------------- /examples/rainmaker/led_light/_static/root_done.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esp-mesh-lite/d991f8d9787eecd36239491a6d45a8e041a42907/examples/rainmaker/led_light/_static/root_done.png -------------------------------------------------------------------------------- /examples/rainmaker/led_light/_static/select_child_devices.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esp-mesh-lite/d991f8d9787eecd36239491a6d45a8e041a42907/examples/rainmaker/led_light/_static/select_child_devices.jpg -------------------------------------------------------------------------------- /examples/rainmaker/led_light/_static/select_device_for_group.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esp-mesh-lite/d991f8d9787eecd36239491a6d45a8e041a42907/examples/rainmaker/led_light/_static/select_device_for_group.png -------------------------------------------------------------------------------- /examples/rainmaker/led_light/_static/select_network.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esp-mesh-lite/d991f8d9787eecd36239491a6d45a8e041a42907/examples/rainmaker/led_light/_static/select_network.jpg -------------------------------------------------------------------------------- /examples/rainmaker/led_light/_static/select_root_node.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esp-mesh-lite/d991f8d9787eecd36239491a6d45a8e041a42907/examples/rainmaker/led_light/_static/select_root_node.png -------------------------------------------------------------------------------- /examples/rainmaker/led_light/components/app_bridge/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | idf_component_register(SRCS "app_bridge.c" "app_mesh_lite_comm.c" 2 | INCLUDE_DIRS "." 3 | PRIV_REQUIRES iot_bridge mesh_lite app_rainmaker) 4 | -------------------------------------------------------------------------------- /examples/rainmaker/led_light/components/app_bridge/app_bridge.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #pragma once 8 | #include 9 | #include 10 | 11 | #include "esp_netif.h" 12 | #include "esp_mesh_lite.h" 13 | 14 | typedef enum { 15 | ESP_MESH_LITE_EVENT_CHILD_NODE_JOIN = ESP_MESH_LITE_EVENT_MAX, 16 | ESP_MESH_LITE_EVENT_CHILD_NODE_LEAVE, 17 | } mesh_lite_event_child_node_info_t; 18 | 19 | typedef struct app_node_info { 20 | uint8_t level; 21 | char ip[IP_MAX_LEN]; 22 | char mac[MAC_MAX_LEN]; 23 | } app_node_info_t; 24 | 25 | /* Enable ESP IoT Bridge in the application 26 | * 27 | * @return ESP_OK on success. 28 | * @return error in case of failure. 29 | */ 30 | esp_err_t app_rmaker_enable_bridge(void); 31 | 32 | esp_err_t app_rmaker_mesh_lite_service_create(void); 33 | 34 | esp_err_t app_rmaker_mesh_lite_report_child_info(void); 35 | 36 | void app_rmaker_mesh_lite_report_info_to_parent(void); 37 | 38 | void app_rmaker_mesh_lite_level_update_and_report(uint8_t level); 39 | 40 | void app_rmaker_mesh_lite_self_ip_update_and_report(esp_netif_ip_info_t* ap_ip_info, esp_netif_ip_info_t* sta_ip_info); 41 | 42 | bool esp_rmaker_is_my_group_id(uint8_t group_id); 43 | -------------------------------------------------------------------------------- /examples/rainmaker/led_light/components/app_insights/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | idf_component_register(SRCS "app_insights.c" 2 | INCLUDE_DIRS "." 3 | PRIV_REQUIRES esp_insights esp_diagnostics esp_rainmaker) 4 | -------------------------------------------------------------------------------- /examples/rainmaker/led_light/components/app_insights/Kconfig: -------------------------------------------------------------------------------- 1 | menu "App Insights" 2 | visible if ESP_INSIGHTS_ENABLED 3 | 4 | config APP_INSIGHTS_ENABLE_LOG_TYPE_ALL 5 | bool "Enable all diagnostics log type" 6 | default n 7 | help 8 | By default only error logs are enabled. 9 | This config option enables the capture of all log types (errors/warnings/events). 10 | 11 | endmenu 12 | -------------------------------------------------------------------------------- /examples/rainmaker/led_light/components/app_insights/app_insights.c: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #include 8 | #include 9 | #ifdef CONFIG_ESP_INSIGHTS_ENABLED 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #if CONFIG_APP_INSIGHTS_ENABLE_LOG_TYPE_ALL 17 | #define APP_INSIGHTS_LOG_TYPE ESP_DIAG_LOG_TYPE_ERROR \ 18 | | ESP_DIAG_LOG_TYPE_WARNING \ 19 | | ESP_DIAG_LOG_TYPE_EVENT 20 | #else 21 | #define APP_INSIGHTS_LOG_TYPE ESP_DIAG_LOG_TYPE_ERROR 22 | #endif /* CONFIG_APP_INSIGHTS_ENABLE_LOG_TYPE_ALL */ 23 | 24 | esp_err_t esp_insights_enable(esp_insights_config_t *config); 25 | 26 | #define INSIGHTS_TOPIC_SUFFIX "diagnostics/from-node" 27 | #define INSIGHTS_TOPIC_RULE "insights_message_delivery" 28 | 29 | static int app_insights_data_send(void *data, size_t len) 30 | { 31 | char topic[128]; 32 | int msg_id = -1; 33 | if (data == NULL) { 34 | return 0; 35 | } 36 | char *node_id = esp_rmaker_get_node_id(); 37 | if (!node_id) { 38 | return -1; 39 | } 40 | if (esp_rmaker_mqtt_is_budget_available() == false) { 41 | /* the API `esp_rmaker_mqtt_publish` already checks if the budget is available. 42 | This also raises an error message, which we do not want for esp-insights. 43 | silently return with error */ 44 | return ESP_FAIL; 45 | } 46 | esp_rmaker_create_mqtt_topic(topic, sizeof(topic), INSIGHTS_TOPIC_SUFFIX, INSIGHTS_TOPIC_RULE); 47 | esp_rmaker_mqtt_publish(topic, data, len, RMAKER_MQTT_QOS1, &msg_id); 48 | return msg_id; 49 | } 50 | 51 | static void rmaker_common_event_handler(void* arg, esp_event_base_t event_base, 52 | int32_t event_id, void* event_data) 53 | { 54 | if (event_base != RMAKER_COMMON_EVENT) { 55 | return; 56 | } 57 | esp_insights_transport_event_data_t data; 58 | switch (event_id) { 59 | case RMAKER_MQTT_EVENT_PUBLISHED: 60 | memset(&data, 0, sizeof(data)); 61 | data.msg_id = *(int *)event_data; 62 | esp_event_post(INSIGHTS_EVENT, INSIGHTS_EVENT_TRANSPORT_SEND_SUCCESS, &data, sizeof(data), portMAX_DELAY); 63 | break; 64 | #ifdef CONFIG_MQTT_REPORT_DELETED_MESSAGES 65 | case RMAKER_MQTT_EVENT_MSG_DELETED: 66 | memset(&data, 0, sizeof(data)); 67 | data.msg_id = *(int *)event_data; 68 | esp_event_post(INSIGHTS_EVENT, INSIGHTS_EVENT_TRANSPORT_SEND_FAILED, &data, sizeof(data), portMAX_DELAY); 69 | break; 70 | #endif /* CONFIG_MQTT_REPORT_DELETED_MESSAGES */ 71 | default: 72 | break; 73 | } 74 | } 75 | #endif /* CONFIG_ESP_INSIGHTS_ENABLED */ 76 | 77 | #define TAG "app_insights" 78 | 79 | esp_err_t app_insights_enable(void) 80 | { 81 | #ifdef CONFIG_ESP_INSIGHTS_ENABLED 82 | /* Initialize the event loop, if not done already. */ 83 | esp_err_t err = esp_event_loop_create_default(); 84 | /* If the default event loop is already initialized, we get ESP_ERR_INVALID_STATE */ 85 | if (err != ESP_OK) { 86 | if (err == ESP_ERR_INVALID_STATE) { 87 | ESP_LOGW(TAG, "Event loop creation failed with ESP_ERR_INVALID_STATE. Proceeding since it must have been created elsewhere."); 88 | } else { 89 | ESP_LOGE(TAG, "Failed to create default event loop, err = %x", err); 90 | return err; 91 | } 92 | } 93 | #ifdef CONFIG_ESP_RMAKER_SELF_CLAIM 94 | ESP_LOGW(TAG, "Nodes with Self Claiming may not be accessible for Insights."); 95 | #endif 96 | char *node_id = esp_rmaker_get_node_id(); 97 | 98 | esp_insights_transport_config_t transport = { 99 | .callbacks.data_send = app_insights_data_send, 100 | }; 101 | esp_insights_transport_register(&transport); 102 | 103 | esp_event_handler_register(RMAKER_COMMON_EVENT, ESP_EVENT_ANY_ID, rmaker_common_event_handler, NULL); 104 | 105 | esp_insights_config_t config = { 106 | .log_type = APP_INSIGHTS_LOG_TYPE, 107 | .node_id = node_id, 108 | .alloc_ext_ram = true, 109 | }; 110 | esp_insights_enable(&config); 111 | #else 112 | ESP_LOGI(TAG, "Enable CONFIG_ESP_INSIGHTS_ENABLED to get Insights."); 113 | #endif /* ! CONFIG_ESP_INSIGHTS_ENABLED */ 114 | return ESP_OK; 115 | } 116 | -------------------------------------------------------------------------------- /examples/rainmaker/led_light/components/app_insights/app_insights.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #pragma once 8 | #include 9 | #include 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | 15 | /* Enable ESP Insights in the application 16 | * 17 | * @return ESP_OK on success. 18 | * @return error in case of failure. 19 | */ 20 | esp_err_t app_insights_enable(void); 21 | 22 | #ifdef __cplusplus 23 | } 24 | #endif 25 | -------------------------------------------------------------------------------- /examples/rainmaker/led_light/components/app_insights/component.mk: -------------------------------------------------------------------------------- 1 | COMPONENT_ADD_INCLUDEDIRS := . 2 | COMPONENT_SRCDIRS := . 3 | -------------------------------------------------------------------------------- /examples/rainmaker/led_light/components/app_insights/idf_component.yml: -------------------------------------------------------------------------------- 1 | ## IDF Component Manager Manifest File 2 | dependencies: 3 | espressif/esp_rainmaker: 4 | version: "~=1.0" 5 | # override_path: '../../../components/esp_rainmaker/' 6 | espressif/esp_insights: 7 | version: "~1.2.1" 8 | # override_path: '../../../components/esp-insights/components/esp_insights/' 9 | -------------------------------------------------------------------------------- /examples/rainmaker/led_light/components/app_light/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | idf_component_register(SRCS "app_light.c" 2 | INCLUDE_DIRS "." 3 | REQUIRES app_reset rmaker_common esp_rainmaker) 4 | -------------------------------------------------------------------------------- /examples/rainmaker/led_light/components/app_light/Kconfig.projbuild: -------------------------------------------------------------------------------- 1 | menu "Lightbulb Demo Configuration" 2 | 3 | choice LIGHTBULB_DEMO_DRIVER_SELECT 4 | bool "Demo select" 5 | default LIGHTBULB_DEMO_DRIVER_SELECT_WS2812 if IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3 || IDF_TARGET_ESP32H2 || IDF_TARGET_ESP32C6 6 | default LIGHTBULB_DEMO_DRIVER_SELECT_PWM 7 | help 8 | Select the driver type you want to demonstrate 9 | 10 | config LIGHTBULB_DEMO_DRIVER_SELECT_SM2135E 11 | bool "Demo SM2135E" 12 | config LIGHTBULB_DEMO_DRIVER_SELECT_WS2812 13 | bool "Demo WS2812" 14 | config LIGHTBULB_DEMO_DRIVER_SELECT_PWM 15 | bool "Demo PWM" 16 | endchoice 17 | 18 | config WS2812_LED_GPIO 19 | int "WS2812 LED GPIO" 20 | default 8 if IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32H2 || IDF_TARGET_ESP32C6 21 | default 18 if IDF_TARGET_ESP32S2 22 | default 48 if IDF_TARGET_ESP32S3 23 | default 4 if IDF_TARGET_ESP32C2 24 | default 18 25 | depends on LIGHTBULB_DEMO_DRIVER_SELECT_WS2812 26 | help 27 | Set the WS2812 RGB LED GPIO. 28 | 29 | config WS2812_LED_NUM 30 | int "WS2812 LED NUM" 31 | default 1 32 | depends on LIGHTBULB_DEMO_DRIVER_SELECT_WS2812 33 | help 34 | Set the WS2812 LED NUM. 35 | 36 | config PWM_FREQ_HZ 37 | int "PWM Frequency (hz)" 38 | default 4000 39 | range 2000 5000 40 | depends on LIGHTBULB_DEMO_DRIVER_SELECT_PWM 41 | help 42 | Set the PWM Frequency (hz). 43 | 44 | config PWM_RED_GPIO 45 | int "PWM Red GPIO" 46 | default 10 if IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32C6 47 | default 15 if IDF_TARGET_ESP32S3 48 | default 0 if IDF_TARGET_ESP32C2 49 | default 23 if IDF_TARGET_ESP32H2 50 | default 25 51 | depends on LIGHTBULB_DEMO_DRIVER_SELECT_PWM 52 | help 53 | Set the PWM Red LED GPIO. 54 | 55 | config PWM_GREEN_GPIO 56 | int "PWM Green GPIO" 57 | default 6 if IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32C6 58 | default 16 if IDF_TARGET_ESP32S3 59 | default 1 if IDF_TARGET_ESP32C2 60 | default 24 if IDF_TARGET_ESP32H2 61 | default 26 62 | depends on LIGHTBULB_DEMO_DRIVER_SELECT_PWM 63 | help 64 | Set the PWM Green LED GPIO. 65 | 66 | config PWM_BLUE_GPIO 67 | int "PWM Blue GPIO" 68 | default 7 if IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32C6 69 | default 17 if IDF_TARGET_ESP32S3 70 | default 8 if IDF_TARGET_ESP32C2 71 | default 25 if IDF_TARGET_ESP32H2 72 | default 27 73 | depends on LIGHTBULB_DEMO_DRIVER_SELECT_PWM 74 | help 75 | Set the PWM Blue LED GPIO. 76 | 77 | config SM2135E_IIC_CLK_GPIO 78 | int "SM2135E IIC CLK GPIO" 79 | default 4 80 | depends on LIGHTBULB_DEMO_DRIVER_SELECT_SM2135E 81 | help 82 | Set the SM2135E CLK GPIO. 83 | 84 | config SM2135E_IIC_SDA_GPIO 85 | int "SM2135E IIC SDA GPIO" 86 | default 5 87 | depends on LIGHTBULB_DEMO_DRIVER_SELECT_SM2135E 88 | help 89 | Set the SM2135E SDA GPIO. 90 | 91 | endmenu 92 | -------------------------------------------------------------------------------- /examples/rainmaker/led_light/components/app_light/app_light.c: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #include 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include 16 | #include 17 | #include 18 | 19 | static const char *TAG = "app_light"; 20 | 21 | /* This is the button that is used for toggling the power */ 22 | #define BUTTON_GPIO CONFIG_EXAMPLE_BOARD_BUTTON_GPIO 23 | #define BUTTON_ACTIVE_LEVEL 0 24 | 25 | #define WIFI_RESET_BUTTON_TIMEOUT 3 26 | #define FACTORY_RESET_BUTTON_TIMEOUT 5 27 | 28 | static uint16_t g_hue = DEFAULT_HUE; 29 | static uint16_t g_saturation = DEFAULT_SATURATION; 30 | static uint16_t g_value = DEFAULT_BRIGHTNESS; 31 | static bool g_power = DEFAULT_POWER; 32 | 33 | extern esp_rmaker_device_t *light_device; 34 | 35 | esp_err_t app_light_set_led(uint32_t hue, uint32_t saturation, uint32_t brightness) 36 | { 37 | /* Whenever this function is called, light power will be ON */ 38 | if (!g_power) { 39 | g_power = true; 40 | esp_rmaker_param_update_and_report( 41 | esp_rmaker_device_get_param_by_type(light_device, ESP_RMAKER_PARAM_POWER), 42 | esp_rmaker_bool(g_power)); 43 | } 44 | return lightbulb_set_hsv(hue, saturation, brightness); 45 | } 46 | 47 | esp_err_t app_light_set_power(bool power) 48 | { 49 | g_power = power; 50 | if (power) { 51 | lightbulb_set_hsv(g_hue, g_saturation, g_value); 52 | } else { 53 | lightbulb_set_hsv(0, 0, 0); 54 | } 55 | return ESP_OK; 56 | } 57 | 58 | esp_err_t app_light_set_brightness(uint16_t brightness) 59 | { 60 | g_value = brightness; 61 | return app_light_set_led(g_hue, g_saturation, g_value); 62 | } 63 | 64 | esp_err_t app_light_set_hue(uint16_t hue) 65 | { 66 | g_hue = hue; 67 | return app_light_set_led(g_hue, g_saturation, g_value); 68 | } 69 | 70 | esp_err_t app_light_set_saturation(uint16_t saturation) 71 | { 72 | g_saturation = saturation; 73 | return app_light_set_led(g_hue, g_saturation, g_value); 74 | } 75 | 76 | esp_err_t app_light_init(void) 77 | { 78 | lightbulb_config_t config = { 79 | //1. Select and configure the chip 80 | #ifdef CONFIG_LIGHTBULB_DEMO_DRIVER_SELECT_WS2812 81 | .type = DRIVER_WS2812, 82 | .driver_conf.ws2812.led_num = CONFIG_WS2812_LED_NUM, 83 | .driver_conf.ws2812.ctrl_io = CONFIG_WS2812_LED_GPIO, 84 | #endif 85 | #ifdef CONFIG_LIGHTBULB_DEMO_DRIVER_SELECT_PWM 86 | .type = DRIVER_ESP_PWM, 87 | .driver_conf.pwm.freq_hz = CONFIG_PWM_FREQ_HZ, 88 | #ifdef CONFIG_IDF_TARGET_ESP32C2 89 | /* Adapt to ESP8684-DevKitM-1 90 | * For details, please refer to: 91 | * https://docs.espressif.com/projects/espressif-esp-dev-kits/zh_CN/latest/esp8684/esp8684-devkitm-1/user_guide.html 92 | */ 93 | .driver_conf.pwm.invert_level = true, 94 | #endif 95 | #endif 96 | #ifdef CONFIG_LIGHTBULB_DEMO_DRIVER_SELECT_SM2135E 97 | .type = DRIVER_SM2135E, 98 | .driver_conf.sm2135e.freq_khz = 400, 99 | .driver_conf.sm2135e.enable_iic_queue = true, 100 | .driver_conf.sm2135e.iic_clk = CONFIG_SM2135E_IIC_CLK_GPIO, 101 | .driver_conf.sm2135e.iic_sda = CONFIG_SM2135E_IIC_SDA_GPIO, 102 | .driver_conf.sm2135e.rgb_current = SM2135E_RGB_CURRENT_20MA, 103 | .driver_conf.sm2135e.wy_current = SM2135E_WY_CURRENT_40MA, 104 | #endif 105 | // 2. Configure the drive capability 106 | .capability.enable_fades = false, 107 | .capability.fades_ms = 800, 108 | .capability.enable_status_storage = false, 109 | .capability.mode_mask = COLOR_MODE, 110 | .capability.storage_cb = NULL, 111 | 112 | //3. Configure driver io 113 | #ifdef CONFIG_LIGHTBULB_DEMO_DRIVER_SELECT_PWM 114 | .io_conf.pwm_io.red = CONFIG_PWM_RED_GPIO, 115 | .io_conf.pwm_io.green = CONFIG_PWM_GREEN_GPIO, 116 | .io_conf.pwm_io.blue = CONFIG_PWM_BLUE_GPIO, 117 | #endif 118 | #ifdef CONFIG_LIGHTBULB_DEMO_DRIVER_SELECT_SM2135E 119 | .io_conf.iic_io.red = OUT3, 120 | .io_conf.iic_io.green = OUT2, 121 | .io_conf.iic_io.blue = OUT1, 122 | .io_conf.iic_io.cold_white = OUT5, 123 | .io_conf.iic_io.warm_yellow = OUT4, 124 | #endif 125 | //4. Limit param 126 | .external_limit = NULL, 127 | 128 | //5. Gamma param 129 | .gamma_conf = NULL, 130 | 131 | //6. Init param 132 | .init_status.mode = WORK_COLOR, 133 | .init_status.on = true, 134 | .init_status.hue = 0, 135 | .init_status.saturation = 100, 136 | .init_status.value = 100, 137 | }; 138 | esp_err_t err = lightbulb_init(&config); 139 | if (err != ESP_OK) { 140 | ESP_LOGE(TAG, "There may be some errors in the configuration, please check the log."); 141 | return err; 142 | } 143 | 144 | if (g_power) { 145 | lightbulb_set_hsv(g_hue, g_saturation, g_value); 146 | } else { 147 | lightbulb_set_hsv(0, 0, 0); 148 | } 149 | return ESP_OK; 150 | } 151 | 152 | static void push_btn_cb(void *arg) 153 | { 154 | app_espnow_reset_group_control(); 155 | } 156 | 157 | void app_driver_init() 158 | { 159 | app_light_init(); 160 | button_handle_t btn_handle = iot_button_create(BUTTON_GPIO, BUTTON_ACTIVE_LEVEL); 161 | if (btn_handle) { 162 | /* Register a callback for a button tap (short press) event */ 163 | iot_button_set_evt_cb(btn_handle, BUTTON_CB_TAP, push_btn_cb, NULL); 164 | /* Register Wi-Fi reset and factory reset functionality on same button */ 165 | app_reset_button_register(btn_handle, WIFI_RESET_BUTTON_TIMEOUT, FACTORY_RESET_BUTTON_TIMEOUT); 166 | } 167 | } 168 | -------------------------------------------------------------------------------- /examples/rainmaker/led_light/components/app_light/app_light.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #pragma once 8 | #include 9 | #include 10 | 11 | #define DEFAULT_POWER true 12 | #define DEFAULT_HUE 180 13 | #define DEFAULT_SATURATION 100 14 | #define DEFAULT_BRIGHTNESS 25 15 | 16 | void app_driver_init(void); 17 | esp_err_t app_light_set(uint32_t hue, uint32_t saturation, uint32_t brightness); 18 | esp_err_t app_light_set_power(bool power); 19 | esp_err_t app_light_set_brightness(uint16_t brightness); 20 | esp_err_t app_light_set_hue(uint16_t hue); 21 | esp_err_t app_light_set_saturation(uint16_t saturation); 22 | -------------------------------------------------------------------------------- /examples/rainmaker/led_light/components/app_light/idf_component.yml: -------------------------------------------------------------------------------- 1 | dependencies: 2 | espressif/lightbulb_driver: 3 | version: "0.2.2" 4 | -------------------------------------------------------------------------------- /examples/rainmaker/led_light/components/app_rainmaker/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | idf_component_register(SRCS "app_rainmaker.c" "app_rainmaker_ota.c" "app_rainmaker_ota_topic.c" 2 | INCLUDE_DIRS "." 3 | REQUIRES json 4 | nvs_flash 5 | app_update 6 | json_parser 7 | esp_https_ota 8 | esp_rainmaker 9 | app_light 10 | app_insights 11 | mesh_lite 12 | group_control) 13 | 14 | target_add_binary_data(${COMPONENT_TARGET} "server.crt" TEXT) 15 | target_link_libraries(${COMPONENT_LIB} INTERFACE "-Wl,--wrap=esp_rmaker_handle_set_params") 16 | -------------------------------------------------------------------------------- /examples/rainmaker/led_light/components/app_rainmaker/app_rainmaker.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #pragma once 8 | 9 | void app_rainmaker_start(void); 10 | 11 | void esp_rmaker_control_light_by_user(char* data); 12 | -------------------------------------------------------------------------------- /examples/rainmaker/led_light/components/app_rainmaker/app_rainmaker_ota.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #pragma once 8 | 9 | #include "esp_rmaker_work_queue.h" 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #if CONFIG_BT_ENABLED 16 | #include 17 | #endif /* CONFIG_BT_ENABLED */ 18 | #include "esp_ota_ops.h" 19 | 20 | #define OTA_REBOOT_TIMER_SEC 10 21 | #define DEF_HTTP_TX_BUFFER_SIZE 1024 22 | #define DEF_HTTP_RX_BUFFER_SIZE CONFIG_ESP_RMAKER_OTA_HTTP_RX_BUFFER_SIZE 23 | 24 | #define ESP_RMAKER_NVS_PART_NAME "nvs" 25 | #define RMAKER_OTA_NVS_NAMESPACE "rmaker_ota" 26 | #define RMAKER_OTA_UPDATE_FLAG_NVS_NAME "ota_update" 27 | #define RMAKER_OTA_JOB_ID_NVS_NAME "rmaker_ota_id" 28 | 29 | #define ESP_ERR_OTA_BASE 0x1500 30 | #define ESP_ERR_OTA_VALIDATE_FAILED (ESP_ERR_OTA_BASE + 0x03) /*!< Error if OTA app image is invalid */ 31 | 32 | // Topic 33 | #define NODE_PARAMS_REMOTE_TOPIC_SUFFIX "params/remote" 34 | #define OTAURL_TOPIC_SUFFIX "otaurl" 35 | #define MQTT_TOPIC_BUFFER_SIZE 150 36 | #define RMAKER_MQTT_QOS0 0 37 | #define RMAKER_MQTT_QOS1 1 38 | 39 | esp_err_t esp_rmaker_mesh_lite_ota_subscribe_topic(void); 40 | esp_err_t esp_rmaker_mesh_lite_ota_init(esp_rmaker_ota_config_t *ota_config); 41 | esp_err_t esp_rmaker_mesh_lite_ota_cb(esp_rmaker_ota_handle_t ota_handle, esp_rmaker_ota_data_t *ota_data); 42 | -------------------------------------------------------------------------------- /examples/rainmaker/led_light/components/app_rainmaker/server.crt: -------------------------------------------------------------------------------- 1 | ESP RainMaker OTA Upgrade Server Certificate. 2 | Replace this if you choose to use any other Server. 3 | -----BEGIN CERTIFICATE----- 4 | MIIEYzCCA0ugAwIBAgIQAYL4CY6i5ia5GjsnhB+5rzANBgkqhkiG9w0BAQsFADBa 5 | MQswCQYDVQQGEwJJRTESMBAGA1UEChMJQmFsdGltb3JlMRMwEQYDVQQLEwpDeWJl 6 | clRydXN0MSIwIAYDVQQDExlCYWx0aW1vcmUgQ3liZXJUcnVzdCBSb290MB4XDTE1 7 | MTIwODEyMDUwN1oXDTI1MDUxMDEyMDAwMFowZDELMAkGA1UEBhMCVVMxFTATBgNV 8 | BAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEjMCEG 9 | A1UEAxMaRGlnaUNlcnQgQmFsdGltb3JlIENBLTIgRzIwggEiMA0GCSqGSIb3DQEB 10 | AQUAA4IBDwAwggEKAoIBAQC75wD+AAFz75uI8FwIdfBccHMf/7V6H40II/3HwRM/ 11 | sSEGvU3M2y24hxkx3tprDcFd0lHVsF5y1PBm1ITykRhBtQkmsgOWBGmVU/oHTz6+ 12 | hjpDK7JZtavRuvRZQHJaZ7bN5lX8CSukmLK/zKkf1L+Hj4Il/UWAqeydjPl0kM8c 13 | +GVQr834RavIL42ONh3e6onNslLZ5QnNNnEr2sbQm8b2pFtbObYfAB8ZpPvTvgzm 14 | +4/dDoDmpOdaxMAvcu6R84Nnyc3KzkqwIIH95HKvCRjnT0LsTSdCTQeg3dUNdfc2 15 | YMwmVJihiDfwg/etKVkgz7sl4dWe5vOuwQHrtQaJ4gqPAgMBAAGjggEZMIIBFTAd 16 | BgNVHQ4EFgQUwBKyKHRoRmfpcCV0GgBFWwZ9XEQwHwYDVR0jBBgwFoAU5Z1ZMIJH 17 | WMys+ghUNoZ7OrUETfAwEgYDVR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMC 18 | AYYwNAYIKwYBBQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdp 19 | Y2VydC5jb20wOgYDVR0fBDMwMTAvoC2gK4YpaHR0cDovL2NybDMuZGlnaWNlcnQu 20 | Y29tL09tbmlyb290MjAyNS5jcmwwPQYDVR0gBDYwNDAyBgRVHSAAMCowKAYIKwYB 21 | BQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNvbS9DUFMwDQYJKoZIhvcNAQEL 22 | BQADggEBAC/iN2bDGs+RVe4pFPpQEL6ZjeIo8XQWB2k7RDA99blJ9Wg2/rcwjang 23 | B0lCY0ZStWnGm0nyGg9Xxva3vqt1jQ2iqzPkYoVDVKtjlAyjU6DqHeSmpqyVDmV4 24 | 7DOMvpQ+2HCr6sfheM4zlbv7LFjgikCmbUHY2Nmz+S8CxRtwa+I6hXsdGLDRS5rB 25 | bxcQKegOw+FUllSlkZUIII1pLJ4vP1C0LuVXH6+kc9KhJLsNkP5FEx2noSnYZgvD 26 | 0WyzT7QrhExHkOyL4kGJE7YHRndC/bseF/r/JUuOUFfrjsxOFT+xJd1BDKCcYm1v 27 | upcHi9nzBhDFKdT3uhaQqNBU4UtJx5g= 28 | -----END CERTIFICATE----- 29 | -----BEGIN CERTIFICATE----- 30 | MIIEdTCCA12gAwIBAgIJAKcOSkw0grd/MA0GCSqGSIb3DQEBCwUAMGgxCzAJBgNV 31 | BAYTAlVTMSUwIwYDVQQKExxTdGFyZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTIw 32 | MAYDVQQLEylTdGFyZmllbGQgQ2xhc3MgMiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0 33 | eTAeFw0wOTA5MDIwMDAwMDBaFw0zNDA2MjgxNzM5MTZaMIGYMQswCQYDVQQGEwJV 34 | UzEQMA4GA1UECBMHQXJpem9uYTETMBEGA1UEBxMKU2NvdHRzZGFsZTElMCMGA1UE 35 | ChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjE7MDkGA1UEAxMyU3RhcmZp 36 | ZWxkIFNlcnZpY2VzIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IC0gRzIwggEi 37 | MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDVDDrEKvlO4vW+GZdfjohTsR8/ 38 | y8+fIBNtKTrID30892t2OGPZNmCom15cAICyL1l/9of5JUOG52kbUpqQ4XHj2C0N 39 | Tm/2yEnZtvMaVq4rtnQU68/7JuMauh2WLmo7WJSJR1b/JaCTcFOD2oR0FMNnngRo 40 | Ot+OQFodSk7PQ5E751bWAHDLUu57fa4657wx+UX2wmDPE1kCK4DMNEffud6QZW0C 41 | zyyRpqbn3oUYSXxmTqM6bam17jQuug0DuDPfR+uxa40l2ZvOgdFFRjKWcIfeAg5J 42 | Q4W2bHO7ZOphQazJ1FTfhy/HIrImzJ9ZVGif/L4qL8RVHHVAYBeFAlU5i38FAgMB 43 | AAGjgfAwge0wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0O 44 | BBYEFJxfAN+qAdcwKziIorhtSpzyEZGDMB8GA1UdIwQYMBaAFL9ft9HO3R+G9FtV 45 | rNzXEMIOqYjnME8GCCsGAQUFBwEBBEMwQTAcBggrBgEFBQcwAYYQaHR0cDovL28u 46 | c3MyLnVzLzAhBggrBgEFBQcwAoYVaHR0cDovL3guc3MyLnVzL3guY2VyMCYGA1Ud 47 | HwQfMB0wG6AZoBeGFWh0dHA6Ly9zLnNzMi51cy9yLmNybDARBgNVHSAECjAIMAYG 48 | BFUdIAAwDQYJKoZIhvcNAQELBQADggEBACMd44pXyn3pF3lM8R5V/cxTbj5HD9/G 49 | VfKyBDbtgB9TxF00KGu+x1X8Z+rLP3+QsjPNG1gQggL4+C/1E2DUBc7xgQjB3ad1 50 | l08YuW3e95ORCLp+QCztweq7dp4zBncdDQh/U90bZKuCJ/Fp1U1ervShw3WnWEQt 51 | 8jxwmKy6abaVd38PMV4s/KCHOkdp8Hlf9BRUpJVeEXgSYCfOn8J3/yNTd126/+pZ 52 | 59vPr5KW7ySaNRB6nJHGDn2Z9j8Z3/VyVOEVqQdZe4O/Ui5GjLIAZHYcSNPYeehu 53 | VsyuLAOQ1xk4meTKCRlb/weWsKh/NEnfVqn3sF/tM+2MR7cwA130A4w= 54 | -----END CERTIFICATE----- 55 | -------------------------------------------------------------------------------- /examples/rainmaker/led_light/components/app_wifi/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(priv_req wifi_provisioning qrcode nvs_flash esp_event json mesh_lite) 2 | 3 | idf_component_register(SRCS "app_wifi.c" 4 | INCLUDE_DIRS "." 5 | REQUIRES 6 | PRIV_REQUIRES ${priv_req}) 7 | 8 | if(CONFIG_APP_WIFI_SHOW_DEMO_INTRO_TEXT) 9 | target_compile_definitions(${COMPONENT_TARGET} PRIVATE "-D RMAKER_DEMO_PROJECT_NAME=\"${CMAKE_PROJECT_NAME}\"") 10 | endif() 11 | -------------------------------------------------------------------------------- /examples/rainmaker/led_light/components/app_wifi/Kconfig.projbuild: -------------------------------------------------------------------------------- 1 | menu "ESP RainMaker App Wi-Fi Provisioning" 2 | 3 | config APP_WIFI_PROV_SHOW_QR 4 | bool "Show provisioning QR code" 5 | default y 6 | help 7 | Show the QR code for provisioning. 8 | 9 | choice APP_WIFI_PROV_TRANSPORT 10 | bool "Provisioning Transport method" 11 | default APP_WIFI_PROV_TRANSPORT_BLE 12 | help 13 | Wi-Fi provisioning component offers both, SoftAP and BLE transports. Choose any one. 14 | 15 | config APP_WIFI_PROV_TRANSPORT_SOFTAP 16 | bool "Soft AP" 17 | config APP_WIFI_PROV_TRANSPORT_BLE 18 | bool "BLE" 19 | select BT_ENABLED 20 | depends on !IDF_TARGET_ESP32S2 21 | endchoice 22 | 23 | config APP_WIFI_PROV_TRANSPORT 24 | int 25 | default 1 if APP_WIFI_PROV_TRANSPORT_SOFTAP 26 | default 2 if APP_WIFI_PROV_TRANSPORT_BLE 27 | 28 | config APP_WIFI_RESET_PROV_ON_FAILURE 29 | bool 30 | default y 31 | prompt "Reset provisioned credentials and state machine after session failure" 32 | help 33 | Enable reseting provisioned credentials and state machine after session failure. 34 | This will restart the provisioning service after retries are exhausted. 35 | 36 | config APP_WIFI_PROV_MAX_RETRY_CNT 37 | int 38 | default 5 39 | prompt "Max retries before reseting provisioning state machine" 40 | depends on APP_WIFI_RESET_PROV_ON_FAILURE 41 | help 42 | Set the Maximum retry to avoid reconnecting to an inexistent AP or if credentials 43 | are misconfigured. Provisioned credentials are erased and internal state machine 44 | is reset after this threshold is reached. 45 | 46 | config APP_WIFI_SHOW_DEMO_INTRO_TEXT 47 | bool "Show intro text for demos" 48 | default n 49 | help 50 | Show some intro text for demos in order to help users understand more about ESP RainMaker. 51 | 52 | config APP_WIFI_PROV_TIMEOUT_PERIOD 53 | int "Provisioning Timeout" 54 | default 30 55 | help 56 | Timeout (in minutes) after which the provisioning will auto stop. A reboot will be required 57 | to restart provisioning. It is always recommended to set this to some non zero value, especially 58 | if you are not using PoP. Set to 0 if you do not want provisioning to auto stop. 59 | 60 | config APP_WIFI_PROV_NAME_PREFIX 61 | string "Provisioning Name Prefix" 62 | default "PROV" 63 | help 64 | Provisioning Name Prefix. 65 | 66 | endmenu 67 | -------------------------------------------------------------------------------- /examples/rainmaker/led_light/components/app_wifi/app_wifi.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #pragma once 8 | #include 9 | #include 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | 15 | /** ESP RainMaker Event Base */ 16 | ESP_EVENT_DECLARE_BASE(APP_WIFI_EVENT); 17 | 18 | /** App Wi-Fir Events */ 19 | typedef enum { 20 | /** QR code available for display. Associated data is the NULL terminated QR payload. */ 21 | APP_WIFI_EVENT_QR_DISPLAY = 1, 22 | /** Provisioning timed out */ 23 | APP_WIFI_EVENT_PROV_TIMEOUT, 24 | /** Provisioning has restarted due to failures (Invalid SSID/Passphrase) */ 25 | APP_WIFI_EVENT_PROV_RESTART, 26 | } app_wifi_event_t; 27 | 28 | /** Types of Proof of Possession */ 29 | typedef enum { 30 | /** Use MAC address to generate PoP */ 31 | POP_TYPE_MAC, 32 | /** Use random stream generated and stored in fctry partition during claiming process as PoP */ 33 | POP_TYPE_RANDOM, 34 | /** Do not use any PoP. 35 | * Use this option with caution. Consider using `CONFIG_APP_WIFI_PROV_TIMEOUT_PERIOD` with this. 36 | */ 37 | POP_TYPE_NONE 38 | } app_wifi_pop_type_t; 39 | 40 | bool app_wifi_prov_is_timeout(void); 41 | 42 | esp_err_t app_wifi_start(app_wifi_pop_type_t pop_type); 43 | 44 | #ifdef __cplusplus 45 | } 46 | #endif 47 | -------------------------------------------------------------------------------- /examples/rainmaker/led_light/components/group_control/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | idf_component_register(SRCS "app_espnow.c" 2 | INCLUDE_DIRS "." 3 | REQUIRES esp_wifi wifi_provisioning json mesh_lite app_bridge app_wifi) 4 | -------------------------------------------------------------------------------- /examples/rainmaker/led_light/components/group_control/app_espnow.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #pragma once 8 | 9 | #include "esp_now.h" 10 | 11 | #define ESPNOW_DEBUG (0) 12 | #define ESPNOW_PAYLOAD_HEAD_LEN (5) 13 | #define ESPNOW_QUEUE_SIZE (50) 14 | #define ESPNOW_DEVICE_NAME "Light" 15 | #define ESPNOW_GROUP_ID "group_id" 16 | #define ESPNOW_DISTRIBUTION_NETWORK "distribution_network" 17 | 18 | typedef enum espnow_msg_mode { 19 | ESPNOW_MSG_MODE_INVALID = 0, 20 | ESPNOW_MSG_MODE_CONTROL = 1, 21 | ESPNOW_MSG_MODE_RESET = 2 22 | } ESPNOW_MSG_MODE; 23 | 24 | enum { 25 | APP_ESPNOW_DATA_BROADCAST, 26 | APP_ESPNOW_DATA_UNICAST, 27 | APP_ESPNOW_DATA_MAX, 28 | }; 29 | 30 | /* User defined field of ESPNOW data in this example. */ 31 | typedef struct { 32 | uint32_t seq; //Magic number which is used to determine which device to send unicast ESPNOW data. 33 | uint8_t mesh_id; //Mesh ID of ESPNOW data 34 | uint8_t payload[0]; //Real payload of ESPNOW data. 35 | } __attribute__((packed)) app_espnow_data_t; 36 | 37 | esp_err_t group_control_init(void); 38 | esp_err_t group_control_deinit(void); 39 | esp_err_t app_espnow_reset_group_control(void); 40 | void esp_now_send_group_control(uint8_t *payload, bool seq_init); 41 | -------------------------------------------------------------------------------- /examples/rainmaker/led_light/main/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | idf_component_register(SRCS "app_main.c" 2 | INCLUDE_DIRS ".") 3 | -------------------------------------------------------------------------------- /examples/rainmaker/led_light/main/Kconfig.projbuild: -------------------------------------------------------------------------------- 1 | menu "RainMaker Led_Light Example" 2 | 3 | config EXAMPLE_BOARD_BUTTON_GPIO 4 | int "Boot Button GPIO" 5 | default 9 if IDF_TARGET_ESP32C3 || IDF_TARGET_ESP32C2 6 | default 0 7 | help 8 | GPIO number on which the "Boot" button is connected. This is generally used 9 | by the application for custom operations like toggling states, resetting to defaults, etc. 10 | 11 | menu "ESPNOW Configuration" 12 | 13 | config ESPNOW_PMK 14 | string "ESPNOW primary master key" 15 | default "pmk1234567890123" 16 | help 17 | ESPNOW primary master for the example to use. The length of ESPNOW primary master must be 16 bytes. 18 | 19 | endmenu 20 | 21 | endmenu 22 | -------------------------------------------------------------------------------- /examples/rainmaker/led_light/main/app_main.c: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #include "inttypes.h" 8 | #include "nvs.h" 9 | #include "nvs_flash.h" 10 | #include "esp_log.h" 11 | #include "app_wifi.h" 12 | #include "app_bridge.h" 13 | #include "app_espnow.h" 14 | #include "app_rainmaker.h" 15 | 16 | static const char *TAG = "app_main"; 17 | 18 | static esp_err_t esp_storage_init(void) 19 | { 20 | esp_err_t ret = nvs_flash_init(); 21 | 22 | if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { 23 | // NVS partition was truncated and needs to be erased 24 | // Retry nvs_flash_init 25 | ESP_ERROR_CHECK(nvs_flash_erase()); 26 | ret = nvs_flash_init(); 27 | } 28 | 29 | return ret; 30 | } 31 | 32 | void session_cost_information(const char *tag, const char *func, int line, const char *desc) 33 | { 34 | static uint32_t free_heap = 0; 35 | 36 | ESP_LOGW(tag, "%s %d %s const heap %"PRIu32"", func, line, desc ? desc : "NULL", esp_get_free_heap_size() - free_heap); 37 | free_heap = esp_get_free_heap_size(); 38 | ESP_LOGW(tag, "free heap %"PRIu32", minimum %"PRIu32"", free_heap, esp_get_minimum_free_heap_size()); 39 | } 40 | 41 | void app_main(void) 42 | { 43 | session_cost_information(TAG, __func__, __LINE__, "app_main"); 44 | 45 | esp_storage_init(); 46 | 47 | app_rmaker_enable_bridge(); 48 | 49 | app_rainmaker_start(); 50 | 51 | group_control_init(); 52 | 53 | /* Start wifi provisioning */ 54 | app_wifi_start(POP_TYPE_MAC); 55 | 56 | app_rmaker_mesh_lite_service_create(); 57 | } 58 | -------------------------------------------------------------------------------- /examples/rainmaker/led_light/main/idf_component.yml: -------------------------------------------------------------------------------- 1 | dependencies: 2 | idf: ">=5.0" 3 | espressif/cbor: "^0.6.0~1" 4 | espressif/esp_insights: "^1.2.1" 5 | espressif/esp_rainmaker: "1.3.0" 6 | 7 | mesh_lite: 8 | version: "*" 9 | # Please comment the following line, if this example is installed by idf.py create-project-from-example. 10 | override_path: "../../../../components/mesh_lite" 11 | 12 | wifi_provisioning: 13 | path: components/wifi_provisioning 14 | git: https://github.com/espressif/esp-mesh-lite.git 15 | 16 | gpio_button: 17 | path: examples/common/gpio_button 18 | git: https://github.com/espressif/esp-rainmaker.git 19 | version: 43444ff 20 | 21 | app_reset: 22 | path: examples/common/app_reset 23 | git: https://github.com/espressif/esp-rainmaker.git 24 | version: 43444ff 25 | -------------------------------------------------------------------------------- /examples/rainmaker/led_light/partition_table/partitions_2MB.csv: -------------------------------------------------------------------------------- 1 | # Name, Type, SubType, Offset, Size, Flags 2 | # Note: Firmware partition offset needs to be 64K aligned, initial 36K (9 sectors) are reserved for bootloader and partition table 3 | otadata, data, ota, 0x9000, 0x2000, , 4 | phy_init, data, phy, , 0x1000, , 5 | sec_cert, 0x3F, , , 0x3000, , # Never mark this as an encrypted partition 6 | ota_0, app, ota_0, 0x10000, 960K, , 7 | ota_1, app, ota_1, , 960K, , 8 | nvs, data, nvs, 0x1f0000, 0x6000, , 9 | fctry, data, nvs, 0x1f6000, 0x6000, , 10 | -------------------------------------------------------------------------------- /examples/rainmaker/led_light/partition_table/partitions_4MB.csv: -------------------------------------------------------------------------------- 1 | # Name, Type, SubType, Offset, Size, Flags 2 | # Note: Firmware partition offset needs to be 64K aligned, initial 36K (9 sectors) are reserved for bootloader and partition table 3 | sec_cert, 0x3F, ,0xd000, 0x3000, , # Never mark this as an encrypted partition 4 | nvs, data, nvs, 0x10000, 0x6000, 5 | otadata, data, ota, , 0x2000 6 | phy_init, data, phy, , 0x1000, 7 | ota_0, app, ota_0, 0x20000, 1792K, 8 | ota_1, app, ota_1, , 1792K, 9 | fctry, data, nvs, 0x3A0000, 0x6000 10 | -------------------------------------------------------------------------------- /examples/rainmaker/led_light/sdkconfig.defaults: -------------------------------------------------------------------------------- 1 | CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y 2 | CONFIG_LWIP_ESP_LWIP_ASSERT=n 3 | CONFIG_LWIP_L2_TO_L3_COPY=y 4 | CONFIG_LWIP_IP_FORWARD=y 5 | CONFIG_LWIP_IPV4_NAPT=y 6 | CONFIG_LWIP_TCP_MSS=624 7 | CONFIG_LWIP_TCP_OVERSIZE_MSS=y 8 | 9 | CONFIG_PARTITION_TABLE_CUSTOM=y 10 | CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partition_table/partitions_4MB.csv" 11 | CONFIG_PARTITION_TABLE_FILENAME="partition_table/partitions_4MB.csv" 12 | CONFIG_PARTITION_TABLE_OFFSET=0x8000 13 | CONFIG_PARTITION_TABLE_MD5=y 14 | 15 | # ESP RainMaker Config 16 | CONFIG_ESP_RMAKER_USER_ID_CHECK=y 17 | CONFIG_ESP_RMAKER_OTA_AUTOFETCH=y 18 | CONFIG_ESP_RMAKER_OTA_AUTOFETCH_PERIOD=6 19 | CONFIG_ESP_RMAKER_USE_CERT_BUNDLE=n 20 | CONFIG_ESP_RMAKER_MQTT_USE_CERT_BUNDLE=n 21 | 22 | # Enable Local Control by default 23 | CONFIG_ESP_RMAKER_LOCAL_CTRL_ENABLE=y 24 | CONFIG_ESP_RMAKER_LOCAL_CTRL_SECURITY_0=y 25 | 26 | # mbedtls 27 | CONFIG_MBEDTLS_DYNAMIC_BUFFER=y 28 | CONFIG_MBEDTLS_DYNAMIC_FREE_PEER_CERT=y 29 | CONFIG_MBEDTLS_DYNAMIC_FREE_CONFIG_DATA=y 30 | CONFIG_MBEDTLS_CERTIFICATE_BUNDLE_DEFAULT_CMN=y 31 | 32 | # For BLE Provisioning using NimBLE stack (Not applicable for ESP32-S2) 33 | CONFIG_BT_ENABLED=y 34 | CONFIG_BTDM_CTRL_MODE_BLE_ONLY=y 35 | CONFIG_BT_NIMBLE_ENABLED=y 36 | CONFIG_BT_NIMBLE_MAX_CONNECTIONS=5 37 | CONFIG_BT_NIMBLE_ROLE_CENTRAL=n 38 | CONFIG_BT_NIMBLE_ROLE_OBSERVER=n 39 | 40 | # Temporary Fix for Timer Overflows 41 | CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=4096 42 | 43 | # ESP Wi-Fi Mesh Lite 44 | CONFIG_MESH_LITE_ENABLE=y 45 | CONFIG_BRIDGE_USE_WEB_SERVER=n 46 | CONFIG_BRIDGE_SOFTAP_SSID_END_WITH_THE_MAC=y 47 | CONFIG_JOIN_MESH_WITHOUT_CONFIGURED_WIFI_INFO=n 48 | 49 | CONFIG_APP_WIFI_PROV_NAME_PREFIX="MESH" 50 | -------------------------------------------------------------------------------- /examples/rainmaker/led_light/sdkconfig.defaults.esp32: -------------------------------------------------------------------------------- 1 | # ESP RainMaker Config 2 | CONFIG_ESP_RMAKER_ASSISTED_CLAIM=y 3 | 4 | CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH=y 5 | CONFIG_FREERTOS_PLACE_SNAPSHOT_FUNS_INTO_FLASH=y 6 | CONFIG_RINGBUF_PLACE_FUNCTIONS_INTO_FLASH=y 7 | 8 | CONFIG_COMPILER_OPTIMIZATION_SIZE=y 9 | -------------------------------------------------------------------------------- /examples/rainmaker/led_light/sdkconfig.defaults.esp32c2: -------------------------------------------------------------------------------- 1 | # ESP RainMaker Config 2 | CONFIG_ESP_RMAKER_NO_CLAIM=y 3 | 4 | # ESP RainMaker App Wi-Fi Provisioning 5 | CONFIG_APP_WIFI_PROV_SHOW_QR=n 6 | 7 | # Hardware Settings 8 | CONFIG_XTAL_FREQ_26=y 9 | 10 | # Log output 11 | CONFIG_LOG_DEFAULT_LEVEL_INFO=y 12 | CONFIG_LOG_COLORS=y 13 | 14 | # Compiler options 15 | CONFIG_COMPILER_OPTIMIZATION_SIZE=y 16 | CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y 17 | 18 | # Wi-Fi 19 | CONFIG_ESP32_WIFI_ENABLED=y 20 | CONFIG_ESP32_WIFI_SW_COEXIST_ENABLE=y 21 | CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM=2 22 | CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM=4 23 | CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER=y 24 | CONFIG_ESP32_WIFI_TX_BUFFER_TYPE=1 25 | CONFIG_ESP32_WIFI_DYNAMIC_TX_BUFFER_NUM=4 26 | CONFIG_ESP32_WIFI_AMPDU_TX_ENABLED=y 27 | CONFIG_ESP32_WIFI_TX_BA_WIN=4 28 | CONFIG_ESP32_WIFI_AMPDU_RX_ENABLED=y 29 | CONFIG_ESP32_WIFI_RX_BA_WIN=4 30 | CONFIG_ESP32_WIFI_NVS_ENABLED=y 31 | CONFIG_ESP32_WIFI_SOFTAP_BEACON_MAX_LEN=752 32 | CONFIG_ESP32_WIFI_MGMT_SBUF_NUM=12 33 | CONFIG_ESP32_WIFI_ENABLE_WPA3_SAE=y 34 | CONFIG_ESP32_WIFI_ENABLE_WPA3_OWE_STA=y 35 | CONFIG_ESP_WIFI_STA_DISCONNECTED_PM_ENABLE=y 36 | CONFIG_ESP_WIFI_SOFTAP_SUPPORT=y 37 | CONFIG_ESP_WIFI_ESPNOW_MAX_ENCRYPT_NUM=2 38 | 39 | # TCP 40 | CONFIG_LWIP_MAX_ACTIVE_TCP=10 41 | CONFIG_LWIP_MAX_LISTENING_TCP=10 42 | CONFIG_LWIP_TCP_HIGH_SPEED_RETRANSMISSION=y 43 | CONFIG_LWIP_TCP_MAXRTX=12 44 | CONFIG_LWIP_TCP_SYNMAXRTX=12 45 | CONFIG_LWIP_TCP_MSS=624 46 | CONFIG_LWIP_TCP_TMR_INTERVAL=250 47 | CONFIG_LWIP_TCP_MSL=60000 48 | CONFIG_LWIP_TCP_FIN_WAIT_TIMEOUT=20000 49 | CONFIG_LWIP_TCP_SND_BUF_DEFAULT=2440 50 | CONFIG_LWIP_TCP_WND_DEFAULT=2440 51 | CONFIG_LWIP_TCP_RECVMBOX_SIZE=6 52 | CONFIG_LWIP_TCP_QUEUE_OOSEQ=y 53 | CONFIG_LWIP_TCP_OVERSIZE_MSS=y 54 | CONFIG_LWIP_TCP_RTO_TIME=1500 55 | -------------------------------------------------------------------------------- /examples/rainmaker/led_light/sdkconfig.defaults.esp32c3: -------------------------------------------------------------------------------- 1 | # Bootloader config 2 | CONFIG_BOOTLOADER_APP_ROLLBACK_ENABLE=y 3 | CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP=y 4 | CONFIG_BOOTLOADER_SKIP_VALIDATE_ON_POWER_ON=y 5 | CONFIG_BOOTLOADER_SKIP_VALIDATE_ALWAYS=y 6 | CONFIG_BOOTLOADER_LOG_LEVEL_WARN=y 7 | 8 | # ESP RainMaker Config 9 | CONFIG_ESP_RMAKER_SELF_CLAIM=y 10 | 11 | # ESP RainMaker App Wi-Fi Provisioning 12 | CONFIG_APP_WIFI_PROV_SHOW_QR=n 13 | 14 | # Log output 15 | CONFIG_LOG_DEFAULT_LEVEL_INFO=y 16 | CONFIG_LOG_COLORS=y 17 | 18 | # Compiler options 19 | CONFIG_COMPILER_OPTIMIZATION_SIZE=y 20 | CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y 21 | 22 | # Newlib 23 | CONFIG_NEWLIB_NANO_FORMAT=y 24 | 25 | # Virtual file system 26 | CONFIG_VFS_SUPPORT_DIR=n 27 | CONFIG_VFS_SUPPORT_SELECT=n 28 | CONFIG_VFS_SUPPORT_TERMIOS=n 29 | 30 | # ESP NETIF Adapter 31 | CONFIG_ESP_NETIF_TCPIP_ADAPTER_COMPATIBLE_LAYER=n 32 | 33 | # Common ESP-related 34 | CONFIG_ESP_ERR_TO_NAME_LOOKUP=n 35 | 36 | # ESP-MQTT Configurations 37 | CONFIG_MQTT_TRANSPORT_WEBSOCKET=n 38 | 39 | # Wi-Fi 40 | CONFIG_ESP_WIFI_FTM_INITIATOR_SUPPORT=n 41 | CONFIG_ESP_WIFI_FTM_RESPONDER_SUPPORT=n 42 | 43 | # PHY 44 | CONFIG_ESP_PHY_MAX_WIFI_TX_POWER=20 45 | -------------------------------------------------------------------------------- /examples/rainmaker/led_light/sdkconfig.defaults.esp32c6: -------------------------------------------------------------------------------- 1 | # ESP RainMaker Config 2 | CONFIG_ESP_RMAKER_NO_CLAIM=y 3 | 4 | # ESP RainMaker App Wi-Fi Provisioning 5 | CONFIG_APP_WIFI_PROV_SHOW_QR=n 6 | 7 | # Log output 8 | CONFIG_LOG_DEFAULT_LEVEL_INFO=y 9 | CONFIG_LOG_COLORS=y 10 | 11 | # Compiler options 12 | CONFIG_COMPILER_OPTIMIZATION_SIZE=y 13 | CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y 14 | -------------------------------------------------------------------------------- /examples/rainmaker/led_light/sdkconfig.defaults.esp32s3: -------------------------------------------------------------------------------- 1 | # ESP RainMaker Config 2 | CONFIG_ESP_RMAKER_SELF_CLAIM=y 3 | -------------------------------------------------------------------------------- /examples/rainmaker/provisioning_controller/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # The following five lines of boilerplate have to be in your project's 2 | # CMakeLists in this exact order for cmake to work correctly 3 | cmake_minimum_required(VERSION 3.5) 4 | 5 | include($ENV{IDF_PATH}/tools/cmake/project.cmake) 6 | project(provisioning_controller) 7 | -------------------------------------------------------------------------------- /examples/rainmaker/provisioning_controller/README.md: -------------------------------------------------------------------------------- 1 | - [中文版本](https://github.com/espressif/esp-mesh-lite/blob/master/examples/rainmaker/provisioning_controller/README_CN.md) 2 | 3 | | Supported Targets | ESP32 | ESP32-C3 | ESP32-C2 | ESP32-S2 | ESP32-S3 | 4 | | ----------------- | ----- | -------- | -------- | -------- | -------- | 5 | 6 | # Provisioning Controller 7 | 8 | This example triggers the ESPNOW broadcast by pressing a button to put the remaining devices that have timed out during provisioning back into provisioning mode. 9 | -------------------------------------------------------------------------------- /examples/rainmaker/provisioning_controller/README_CN.md: -------------------------------------------------------------------------------- 1 | - [English Version](https://github.com/espressif/esp-mesh-lite/blob/master/examples/rainmaker/provisioning_controller/README.md) 2 | 3 | | Supported Targets | ESP32 | ESP32-C3 | ESP32-C2 | ESP32-S2 | ESP32-S3 | 4 | | ----------------- | ----- | -------- | -------- | -------- | -------- | 5 | 6 | # 配网控制器示例 7 | 8 | 本示例通过触发按键的方式发送 ESPNOW 广播使配网超时的设备重新进入配网模式。 9 | -------------------------------------------------------------------------------- /examples/rainmaker/provisioning_controller/main/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | idf_component_register(SRCS "app_main.c" "app_espnow.c" 2 | INCLUDE_DIRS ".") 3 | -------------------------------------------------------------------------------- /examples/rainmaker/provisioning_controller/main/Kconfig.projbuild: -------------------------------------------------------------------------------- 1 | menu "Distribution Network Controller Example" 2 | 3 | menu "Button Configuration" 4 | config APP_GPIO_BUTTON_SW1 5 | default 16 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32H2 6 | default 38 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3 7 | default 9 8 | int "GPIO button of switch" 9 | help 10 | Set the GPIO button of switch. 11 | endmenu 12 | 13 | menu "ESPNOW Configuration" 14 | 15 | config ESPNOW_PMK 16 | string "ESPNOW primary master key" 17 | default "pmk1234567890123" 18 | help 19 | ESPNOW primary master for the example to use. The length of ESPNOW primary master must be 16 bytes. 20 | 21 | config ESPNOW_CHANNEL 22 | int "Channel" 23 | default 1 24 | range 0 14 25 | help 26 | The channel on which sending and receiving ESPNOW data. 27 | 28 | endmenu 29 | 30 | endmenu 31 | -------------------------------------------------------------------------------- /examples/rainmaker/provisioning_controller/main/app_espnow.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #pragma once 8 | 9 | #include "esp_now.h" 10 | 11 | #define ESPNOW_DEBUG (0) 12 | #define ESPNOW_PAYLOAD_HEAD_LEN (5) 13 | #define ESPNOW_QUEUE_SIZE (50) 14 | #define ESPNOW_MESH_ID (77) 15 | #define ESPNOW_DEVICE_NAME "Light" 16 | #define ESPNOW_GROUP_ID "group_id" 17 | #define ESPNOW_DISTRIBUTION_NETWORK "distribution_network" 18 | 19 | typedef enum espnow_msg_mode { 20 | ESPNOW_MSG_MODE_INVALID = 0, 21 | ESPNOW_MSG_MODE_CONTROL = 1, 22 | ESPNOW_MSG_MODE_RESET = 2 23 | } ESPNOW_MSG_MODE; 24 | 25 | enum { 26 | APP_ESPNOW_DATA_BROADCAST, 27 | APP_ESPNOW_DATA_UNICAST, 28 | APP_ESPNOW_DATA_MAX, 29 | }; 30 | 31 | /* User defined field of ESPNOW data in this example. */ 32 | typedef struct { 33 | uint32_t seq; //Magic number which is used to determine which device to send unicast ESPNOW data. 34 | uint8_t mesh_id; //Mesh ID of ESPNOW data 35 | uint8_t payload[0]; //Real payload of ESPNOW data. 36 | } __attribute__((packed)) app_espnow_data_t; 37 | 38 | esp_err_t app_espnow_init(void); 39 | esp_err_t app_espnow_reset_group_control(void); 40 | esp_err_t app_espnow_trigger_distribution_network(void); 41 | -------------------------------------------------------------------------------- /examples/rainmaker/provisioning_controller/main/app_main.c: -------------------------------------------------------------------------------- 1 | /* 2 | * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #include "nvs.h" 8 | #include "nvs_flash.h" 9 | #include "freertos/FreeRTOS.h" 10 | #include "freertos/event_groups.h" 11 | #include "esp_log.h" 12 | #include "esp_wifi.h" 13 | #include "esp_netif.h" 14 | #include "app_espnow.h" 15 | #include "iot_button.h" 16 | 17 | #define BUTTON_NUM 1 18 | #define BUTTON_SW1 CONFIG_APP_GPIO_BUTTON_SW1 19 | 20 | static TimerHandle_t trigger_timer; 21 | static button_handle_t g_btns[BUTTON_NUM] = { 0 }; 22 | 23 | static esp_err_t esp_storage_init(void) 24 | { 25 | esp_err_t ret = nvs_flash_init(); 26 | 27 | if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { 28 | // NVS partition was truncated and needs to be erased 29 | // Retry nvs_flash_init 30 | ESP_ERROR_CHECK(nvs_flash_erase()); 31 | ret = nvs_flash_init(); 32 | } 33 | 34 | return ret; 35 | } 36 | 37 | static void button_press_up_cb(void *hardware_data, void *usr_data) 38 | { 39 | if (xTimerIsTimerActive(trigger_timer) == pdFALSE) { 40 | // xTimer is not active 41 | app_espnow_reset_group_control(); 42 | xTimerStart(trigger_timer, 0); 43 | } 44 | } 45 | 46 | static void trigger_timer_callback(TimerHandle_t timer) 47 | { 48 | app_espnow_trigger_distribution_network(); 49 | xTimerStop(trigger_timer, 0); 50 | } 51 | 52 | void app_button_init(void) 53 | { 54 | trigger_timer = xTimerCreate("trigger_timer", pdMS_TO_TICKS(1000), pdTRUE, NULL, trigger_timer_callback); 55 | 56 | button_config_t button_cfg = { 57 | .type = BUTTON_TYPE_GPIO, 58 | .gpio_button_config = { 59 | .gpio_num = BUTTON_SW1, 60 | .active_level = 0, 61 | }, 62 | }; 63 | g_btns[0] = iot_button_create(&button_cfg); 64 | iot_button_register_cb(g_btns[0], BUTTON_PRESS_UP, button_press_up_cb, 0); 65 | } 66 | 67 | void app_wifi_init(void) 68 | { 69 | ESP_ERROR_CHECK(esp_netif_init()); 70 | ESP_ERROR_CHECK(esp_event_loop_create_default()); 71 | wifi_init_config_t wifi_cfg = WIFI_INIT_CONFIG_DEFAULT(); 72 | ESP_ERROR_CHECK(esp_wifi_init(&wifi_cfg)); 73 | ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM)); 74 | ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); 75 | ESP_ERROR_CHECK(esp_wifi_start()); 76 | ESP_ERROR_CHECK(esp_wifi_set_channel(CONFIG_ESPNOW_CHANNEL, WIFI_SECOND_CHAN_NONE)); 77 | } 78 | 79 | void app_main(void) 80 | { 81 | esp_storage_init(); 82 | 83 | app_wifi_init(); 84 | 85 | app_espnow_init(); 86 | 87 | app_button_init(); 88 | } 89 | -------------------------------------------------------------------------------- /examples/rainmaker/provisioning_controller/main/idf_component.yml: -------------------------------------------------------------------------------- 1 | dependencies: 2 | idf: ">=5.0" 3 | espressif/button: 2.* 4 | mesh_lite: 5 | version: "*" 6 | # Please comment the following line, if this example is installed by idf.py create-project-from-example. 7 | override_path: "../../../../components/mesh_lite" 8 | wifi_provisioning: 9 | path: components/wifi_provisioning 10 | git: https://github.com/espressif/esp-mesh-lite.git 11 | -------------------------------------------------------------------------------- /examples/rainmaker/provisioning_controller/sdkconfig.defaults: -------------------------------------------------------------------------------- 1 | CONFIG_LWIP_IP_FORWARD=y 2 | CONFIG_LWIP_IPV4_NAPT=y 3 | -------------------------------------------------------------------------------- /examples/wireless_debug/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # The following lines of boilerplate have to be in your project's 2 | # CMakeLists in this exact order for cmake to work correctly 3 | cmake_minimum_required(VERSION 3.5) 4 | 5 | include($ENV{IDF_PATH}/tools/cmake/project.cmake) 6 | 7 | project(wireless_debug) 8 | -------------------------------------------------------------------------------- /examples/wireless_debug/README.md: -------------------------------------------------------------------------------- 1 | - [中文版本](https://github.com/espressif/esp-mesh-lite/blob/master/examples/wireless_debug/README_CN.md) 2 | 3 | | Supported Targets | ESP32 | ESP32-C3 | ESP32-S2 | ESP32-S3 | ESP32-C2 | ESP32-C6 | 4 | | ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | 5 | 6 | # **ESP-Mesh-Lite Wireless Debug Example** 7 | 8 | ## **1. Feature Overview** 9 | **Wireless Debug** is an innovative wireless debugging solution that enables developers to control target devices without physical UART or JTAG connections. It provides real-time status information of devices in the Mesh-Lite network, including Wi-Fi connection status, application layer connection status, and debug logs. Furthermore, developers can retrieve runtime logs and connection status of offline devices through cloud services or online device forwarding, significantly improving the debugging efficiency of distributed devices. 10 | 11 | --- 12 | 13 | ## **2. Typical Use Cases** 14 | ### **(1) Multi-Device Collaborative Debugging** 15 | Enables centralized monitoring of all devices in a Mesh-Lite network without requiring individual UART connections for debugging. 16 | 17 | ### **(2) Field Troubleshooting** 18 | Facilitates quick access to fault logs from devices installed in hard-to-reach locations (such as embedded sensors and industrial controllers) through wireless communication. 19 | 20 | --- 21 | 22 | ## **3. Hardware Requirements** 23 | | Device | Quantity | Notes | 24 | |--------|----------|-------| 25 | | ESP32/ESP32-C3/ESP32-S3 etc. | ≥2 | Minimum requirement: 1 **Debug Host** and 1 **Target Device** | 26 | | 2.4GHz Router | 1 | All devices must connect to the same router to ensure channel synchronization | 27 | 28 | --- 29 | 30 | ## **4. Configuration** 31 | Navigate to **Example Configuration** in `idf.py menuconfig` and configure the following parameters: 32 | 33 | | Option | Description | 34 | |--------|-------------| 35 | | `Router SSID` | Wi-Fi network name | 36 | | `Router Password` | Wi-Fi network password | 37 | | `APP_GPIO_BUTTON_SW1` | GPIO pin number for button input | 38 | 39 | --- 40 | 41 | ## **5. Build and Flash** 42 | ```bash 43 | # Erase and flash firmware 44 | idf.py erase_flash flash monitor -p /dev/ttyUSB0 45 | ``` 46 | > Replace `/dev/ttyUSB0` with your actual port. 47 | 48 | --- 49 | 50 | ## **6. Sample Output** 51 | When operational, the debug host can send wireless commands via button presses. Serial output shows: 52 | ``` 53 | Command Type: discover 54 | MAC Address: 58:cf:79:1e:b1:14 55 | Channel: 11 56 | I (329519) wireless_debug: BTN: BUTTON_PRESS_UP 57 | I (329519) Mesh-Lite-Wireless-Debug: send command: discover --delay 1000 --channel 11 --mac 58:cf:79:1e:b1:14 58 | I (330094) wireless_debug: BTN: BUTTON_PRESS_UP 59 | I (330094) Mesh-Lite-Wireless-Debug: send command: wifi_error 60 | Command Type: discover 61 | MAC Address: 58:cf:79:1e:b1:14 62 | Channel: 11 63 | I (330694) wireless_debug: BTN: BUTTON_PRESS_UP 64 | I (330694) Mesh-Lite-Wireless-Debug: send command: wifi_error --mac 58:cf:79:1e:b1:14 65 | Command Type: wifi_error 66 | Command Value: This message from app_wifi_error_cb 67 | ``` 68 | 69 | --- 70 | -------------------------------------------------------------------------------- /examples/wireless_debug/README_CN.md: -------------------------------------------------------------------------------- 1 | - [English Version](https://github.com/espressif/esp-mesh-lite/blob/master/examples/wireless_debug/README.md) 2 | 3 | | Supported Targets | ESP32 | ESP32-C3 | ESP32-S2 | ESP32-S3 | ESP32-C2 | ESP32-C6 | 4 | | ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | 5 | 6 | # **ESP-Mesh-Lite 无线调试示例** 7 | 8 | ## **1. 功能概述** 9 | **Wireless Debug** 是一种创新的无线调试解决方案。该方案使开发者无需通过物理连接 UART 或 JTAG 接口,即可通过无线方式控制目标设备,并实时获取 Mesh-Lite 网络中其他设备的运行状态信息(包括 Wi-Fi 连接状态、应用层连接状态、调试日志等)。此外,开发者还可以通过云端或在线设备转发的方式获取离线设备的运行日志和连接状态,大大提升了分布式设备的调试效率。 10 | 11 | --- 12 | 13 | ## **2. 应用场景** 14 | ### **(1) 多设备协同调试** 15 | 当多个 ESP32 设备组成 Mesh-Lite 网络时,可通过 **Wireless Debug** 实现对所有设备运行状态的集中监控,无需逐一连接串口进行调试。 16 | 17 | ### **(2) 现场故障诊断** 18 | 对于部署在难以直接接触的位置的设备(如嵌入式传感器、工业控制器等),可通过无线方式快速获取故障日志,提高问题诊断效率。 19 | 20 | --- 21 | 22 | ## **3. 硬件要求** 23 | | 设备 | 数量 | 说明 | 24 | |------|------|------| 25 | | ESP32/ESP32-C3/ESP32-S3 等 | ≥2 | 至少需要 1 个作为 **调试主机**,1 个作为 **被调试设备** | 26 | | 2.4GHz 路由器 | 1 | 所有设备需连接至同一路由器,确保工作在相同信道 | 27 | 28 | --- 29 | 30 | ## **4. 配置说明** 31 | 运行 `idf.py menuconfig`,在 **Example Configuration** 中配置以下参数: 32 | 33 | | 配置项 | 说明 | 34 | |--------|------| 35 | | `Router SSID` | 路由器 SSID | 36 | | `Router Password` | 路由器密码 | 37 | | `APP_GPIO_BUTTON_SW1` | 按键引脚编号 | 38 | 39 | --- 40 | 41 | ## **5. 编译与烧录** 42 | ```bash 43 | # 清除旧固件并烧录新固件 44 | idf.py erase_flash flash monitor -p /dev/ttyUSB0 45 | ``` 46 | > 将 `/dev/ttyUSB0` 替换为实际串口设备。 47 | 48 | --- 49 | 50 | ## **6. 示例输出** 51 | 成功运行后,调试主机可通过按键模拟发送对应无线调试指令,串口会显示: 52 | ``` 53 | Command Type: discover 54 | MAC Address: 58:cf:79:1e:b1:14 55 | Channel: 11 56 | I (329519) wireless_debug: BTN: BUTTON_PRESS_UP 57 | I (329519) Mesh-Lite-Wireless-Debug: send command: discover --delay 1000 --channel 11 --mac 58:cf:79:1e:b1:14 58 | I (330094) wireless_debug: BTN: BUTTON_PRESS_UP 59 | I (330094) Mesh-Lite-Wireless-Debug: send command: wifi_error 60 | Command Type: discover 61 | MAC Address: 58:cf:79:1e:b1:14 62 | Channel: 11 63 | I (330694) wireless_debug: BTN: BUTTON_PRESS_UP 64 | I (330694) Mesh-Lite-Wireless-Debug: send command: wifi_error --mac 58:cf:79:1e:b1:14 65 | Command Type: wifi_error 66 | Command Value: This message from app_wifi_error_cb 67 | ``` 68 | 69 | --- 70 | -------------------------------------------------------------------------------- /examples/wireless_debug/main/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | idf_component_register(SRCS "wireless_debug.c" 2 | INCLUDE_DIRS ".") 3 | -------------------------------------------------------------------------------- /examples/wireless_debug/main/Kconfig.projbuild: -------------------------------------------------------------------------------- 1 | menu "Example Configuration" 2 | 3 | config ROUTER_SSID 4 | string "Router SSID" 5 | default "ROUTER_SSID" 6 | help 7 | Router SSID. 8 | 9 | config ROUTER_PASSWORD 10 | string "Router password" 11 | default "ROUTER_PASSWORD" 12 | help 13 | Router password. 14 | 15 | config APP_GPIO_BUTTON_SW1 16 | default 16 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32H2 17 | default 38 if IDF_TARGET_ESP32S2 || IDF_TARGET_ESP32S3 18 | default 9 19 | int "GPIO button of switch" 20 | help 21 | Set the GPIO button of switch. 22 | 23 | endmenu 24 | -------------------------------------------------------------------------------- /examples/wireless_debug/main/idf_component.yml: -------------------------------------------------------------------------------- 1 | dependencies: 2 | idf: ">=5.0" 3 | espressif/button: 3.* 4 | mesh_lite: 5 | version: "*" 6 | # Please comment the following line, if this example is installed by idf.py create-project-from-example. 7 | override_path: "../../../components/mesh_lite" 8 | -------------------------------------------------------------------------------- /examples/wireless_debug/sdkconfig.defaults: -------------------------------------------------------------------------------- 1 | # Override some defaults in mesh application project. 2 | 3 | # 4 | # FreeRTOS 5 | # 6 | CONFIG_FREERTOS_HZ=1000 7 | CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=3072 8 | CONFIG_FREERTOS_USE_TRACE_FACILITY=y 9 | CONFIG_FREERTOS_USE_STATS_FORMATTING_FUNCTIONS=y 10 | CONFIG_FREERTOS_VTASKLIST_INCLUDE_COREID=y 11 | CONFIG_FREERTOS_GENERATE_RUN_TIME_STATS=y 12 | 13 | # 14 | # ESP32-specific 15 | # 16 | CONFIG_ESP_TASK_WDT_PANIC=y 17 | CONFIG_ESP_TASK_WDT_TIMEOUT_S=10 18 | CONFIG_ESP_TIMER_TASK_STACK_SIZE=4096 19 | 20 | # LWIP 21 | CONFIG_LWIP_IP_FORWARD=y 22 | CONFIG_LWIP_IPV4_NAPT=y 23 | 24 | CONFIG_MESH_LITE_ENABLE=y 25 | CONFIG_MESH_LITE_WIRELESS_DEBUG=y 26 | CONFIG_BRIDGE_SOFTAP_SSID_END_WITH_THE_MAC=y 27 | -------------------------------------------------------------------------------- /examples/wireless_debug/sdkconfig.defaults.esp32c2: -------------------------------------------------------------------------------- 1 | CONFIG_XTAL_FREQ_26=y 2 | CONFIG_ESP_WIFI_ESPNOW_MAX_ENCRYPT_NUM=0 3 | -------------------------------------------------------------------------------- /examples/wireless_debug/sdkconfig.eth: -------------------------------------------------------------------------------- 1 | CONFIG_ETH_DMA_BUFFER_SIZE=1600 2 | 3 | CONFIG_ETH_SPI_ETHERNET_DM9051=y 4 | CONFIG_ETH_SPI_ETHERNET_KSZ8851SNL=y 5 | CONFIG_ETH_SPI_ETHERNET_W5500=y 6 | -------------------------------------------------------------------------------- /examples/wireless_debug/sdkconfig.leafnode: -------------------------------------------------------------------------------- 1 | CONFIG_LEAF_NODE=y 2 | -------------------------------------------------------------------------------- /tools/ci/astyle-rules.yml: -------------------------------------------------------------------------------- 1 | DEFAULT: 2 | # These formatting options will be used by default. 3 | # If you are modifying this, update tools/format.sh as well! 4 | options: "--style=otbs --attach-namespaces --attach-classes --indent=spaces=4 --convert-tabs --align-reference=name --keep-one-line-statements --pad-header --pad-oper --unpad-paren --max-continuation-indent=120" 5 | 6 | # files matching this section do not perform the check 7 | # docs: 8 | # # Docs directory contains some .inc files, which are not C include files 9 | # # and should not be formatted 10 | # check: false 11 | # include: 12 | # - "/docs/**/*.inc" 13 | -------------------------------------------------------------------------------- /tools/ci/check_copyright_config.yaml: -------------------------------------------------------------------------------- 1 | # This file configures the check_copyright pre-commit hook 2 | # 3 | # Values from the DEFAULT section are used, when the particular option is not set in a section. 4 | # The DEFAULT section also contains all options with description 5 | # 6 | # Section name is just an identifier, keep it unique. 7 | # Section must contain the option 'include' and at least one other option 8 | # 9 | # The sections are matched in the order they are in this config file, the last section which matches is used. 10 | # This means that the order of the sections should be from broad to specific. 11 | # For example: 12 | # sections: 13 | # tools/ 14 | # tools/ci/file.c 15 | # tools/ci/ 16 | # files: 17 | # tools/file.c -> section tools/ 18 | # tools/ci/file.c -> section tools/ci/ 19 | # 20 | 21 | # don't modify this section! 22 | DEFAULT: 23 | perform_check: yes # should the check be performed? 24 | # Sections setting this to 'no' don't need to include any other options as they are ignored 25 | # When a file is using a section with the option set to 'no', no checks are performed. 26 | 27 | # what licenses (or license expressions) are allowed for files in this section 28 | # when setting this option in a section, you need to list all the allowed licenses 29 | allowed_licenses: 30 | - Apache-2.0 31 | license_for_new_files: Apache-2.0 # license to be used when inserting a new copyright notice 32 | new_notice_c: | # notice for new C, CPP, H, HPP and LD files 33 | /* 34 | * SPDX-FileCopyrightText: {years} Espressif Systems (Shanghai) CO LTD 35 | * 36 | * SPDX-License-Identifier: {license} 37 | */ 38 | new_notice_python: | # notice for new python files 39 | # SPDX-FileCopyrightText: {years} Espressif Systems (Shanghai) CO LTD 40 | # SPDX-License-Identifier: {license} 41 | 42 | # comment lines matching: 43 | # SPDX-FileCopyrightText: year[-year] Espressif Systems 44 | # or 45 | # SPDX-FileContributor: year[-year] Espressif Systems 46 | # are replaced with this template prefixed with the correct comment notation (# or // or *) and SPDX- notation 47 | espressif_copyright: '{years} Espressif Systems (Shanghai) CO LTD' 48 | 49 | # files matching this section do not perform the check 50 | # file patterns starting with ! are negated, meaning files matching them won't match the section. 51 | # ignore: 52 | # perform_check: no 53 | # include: 54 | -------------------------------------------------------------------------------- /tools/ci/check_copyright_ignore.txt: -------------------------------------------------------------------------------- 1 | Place your file path here if you want to ignore the copyright check. 2 | -------------------------------------------------------------------------------- /tools/ci/check_executables.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | import argparse 7 | import os 8 | import sys 9 | from typing import Iterable, List 10 | 11 | try: 12 | from idf_ci_utils import is_executable 13 | except ImportError: 14 | sys.path.append(os.path.join(os.path.dirname(__file__))) 15 | 16 | from idf_ci_utils import is_executable 17 | 18 | 19 | def _strip_each_item(iterable: Iterable) -> List: 20 | res = [] 21 | for item in iterable: 22 | if item: 23 | res.append(item.strip()) 24 | return res 25 | 26 | 27 | IDF_PATH = os.getenv('IDF_PATH', os.getcwd()) 28 | EXECUTABLE_LIST_FN = os.path.join(IDF_PATH, 'tools/ci/executable-list.txt') 29 | known_executables = _strip_each_item(open(EXECUTABLE_LIST_FN).readlines()) 30 | 31 | 32 | def check_executable_list() -> int: 33 | ret = 0 34 | for index, fn in enumerate(known_executables): 35 | if not os.path.exists(os.path.join(IDF_PATH, fn)): 36 | print('{}:{} {} not exists. Please remove it manually'.format(EXECUTABLE_LIST_FN, index + 1, fn)) 37 | ret = 1 38 | return ret 39 | 40 | 41 | def check_executables(files: List) -> int: 42 | ret = 0 43 | for fn in files: 44 | fn_executable = is_executable(fn) 45 | fn_in_list = fn in known_executables 46 | if fn_executable and not fn_in_list: 47 | print('"{}" is not in {}'.format(fn, EXECUTABLE_LIST_FN)) 48 | ret = 1 49 | if not fn_executable and fn_in_list: 50 | print('"{}" is not executable but is in {}'.format(fn, EXECUTABLE_LIST_FN)) 51 | ret = 1 52 | return ret 53 | 54 | 55 | def check() -> int: 56 | parser = argparse.ArgumentParser() 57 | parser.add_argument('--action', choices=['executables', 'list'], required=True, 58 | help='if "executables", pass all your executables to see if it\'s in the list.' 59 | 'if "list", check if all items on your list exist') 60 | parser.add_argument('filenames', nargs='*', help='Filenames to check.') 61 | args = parser.parse_args() 62 | 63 | if args.action == 'executables': 64 | ret = check_executables(args.filenames) 65 | elif args.action == 'list': 66 | ret = check_executable_list() 67 | else: 68 | raise ValueError 69 | 70 | return ret 71 | 72 | if __name__ == '__main__': 73 | sys.exit(check()) 74 | -------------------------------------------------------------------------------- /tools/ci/executable-list.txt: -------------------------------------------------------------------------------- 1 | tools/ci/check_executables.py 2 | tools/ci/idf_ci_utils.py 3 | -------------------------------------------------------------------------------- /tools/ci/idf_ci_utils.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2020-2023 Espressif Systems (Shanghai) CO LTD 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | # internal use only for CI 5 | # some CI related util functions 6 | 7 | import logging 8 | import os 9 | import subprocess 10 | import sys 11 | from typing import Any, List 12 | 13 | IDF_PATH = os.path.abspath(os.getenv('IDF_PATH', os.path.join(os.path.dirname(__file__), '..', '..'))) 14 | 15 | 16 | def get_submodule_dirs(full_path: bool = False) -> List[str]: 17 | """ 18 | To avoid issue could be introduced by multi-os or additional dependency, 19 | we use python and git to get this output 20 | :return: List of submodule dirs 21 | """ 22 | dirs = [] 23 | try: 24 | lines = ( 25 | subprocess.check_output( 26 | [ 27 | 'git', 28 | 'config', 29 | '--file', 30 | os.path.realpath(os.path.join(IDF_PATH, '.gitmodules')), 31 | '--get-regexp', 32 | 'path', 33 | ] 34 | ) 35 | .decode('utf8') 36 | .strip() 37 | .split('\n') 38 | ) 39 | for line in lines: 40 | _, path = line.split(' ') 41 | if full_path: 42 | dirs.append(os.path.join(IDF_PATH, path)) 43 | else: 44 | dirs.append(path) 45 | except Exception as e: # pylint: disable=W0703 46 | logging.warning(str(e)) 47 | 48 | return dirs 49 | 50 | 51 | def _check_git_filemode(full_path: str) -> bool: 52 | try: 53 | stdout = subprocess.check_output(['git', 'ls-files', '--stage', full_path]).strip().decode('utf-8') 54 | except subprocess.CalledProcessError: 55 | return True 56 | 57 | mode = stdout.split(' ', 1)[0] # e.g. 100644 for a rw-r--r-- 58 | if any([int(i, 8) & 1 for i in mode[-3:]]): 59 | return True 60 | return False 61 | 62 | 63 | def is_executable(full_path: str) -> bool: 64 | """ 65 | os.X_OK will always return true on windows. Use git to check file mode. 66 | :param full_path: file full path 67 | :return: True is it's an executable file 68 | """ 69 | if sys.platform == 'win32': 70 | return _check_git_filemode(full_path) 71 | return os.access(full_path, os.X_OK) 72 | 73 | 74 | def get_git_files(path: str = IDF_PATH, full_path: bool = False) -> List[str]: 75 | """ 76 | Get the result of git ls-files 77 | :param path: path to run git ls-files 78 | :param full_path: return full path if set to True 79 | :return: list of file paths 80 | """ 81 | try: 82 | # this is a workaround when using under worktree 83 | # if you're using worktree, when running git commit a new environment variable GIT_DIR would be declared, 84 | # the value should be /.git/worktrees/ 85 | # This would affect the return value of `git ls-files`, unset this would use the `cwd`value or its parent 86 | # folder if no `.git` folder found in `cwd`. 87 | workaround_env = os.environ.copy() 88 | workaround_env.pop('GIT_DIR', None) 89 | files = ( 90 | subprocess.check_output(['git', 'ls-files'], cwd=path, env=workaround_env) 91 | .decode('utf8') 92 | .strip() 93 | .split('\n') 94 | ) 95 | except Exception as e: # pylint: disable=W0703 96 | logging.warning(str(e)) 97 | files = [] 98 | return [os.path.join(path, f) for f in files] if full_path else files 99 | 100 | 101 | def is_in_directory(file_path: str, folder: str) -> bool: 102 | return os.path.realpath(file_path).startswith(os.path.realpath(folder) + os.sep) 103 | 104 | 105 | def to_list(s: Any) -> List[Any]: 106 | if isinstance(s, (set, tuple)): 107 | return list(s) 108 | 109 | if isinstance(s, list): 110 | return s 111 | 112 | return [s] 113 | --------------------------------------------------------------------------------