From 2e4cbcf63916b2b60558aa71508029746fa178b1 Mon Sep 17 00:00:00 2001 From: Piyush Shah Date: Thu, 24 Sep 2020 14:56:14 +0530 Subject: [PATCH] esp_homekit_sdk: Add all the required code, dependencies, tools, docs, examples --- .gitignore | 41 + .gitlab-ci.yml | 92 + .gitmodules | 6 + MFI_README.md | 3 + README.md | 128 +- components/button/CMakeLists.txt | 9 + components/button/Kconfig | 6 + components/button/button/button.c | 363 + components/button/button/button_obj.cpp | 64 + components/button/button/component.mk | 4 + components/button/button/include/iot_button.h | 280 + components/button/component.mk | 2 + .../esp_hap_apple_profiles/CMakeLists.txt | 10 + .../esp_hap_apple_profiles/component.mk | 6 + .../include/hap_apple_chars.h | 1422 ++++ .../include/hap_apple_servs.h | 560 ++ .../src/hap_apple_chars.c | 1482 ++++ .../src/hap_apple_servs.c | 706 ++ .../homekit/esp_hap_core/CMakeLists.txt | 53 + components/homekit/esp_hap_core/Kconfig | 10 + components/homekit/esp_hap_core/component.mk | 18 + components/homekit/esp_hap_core/include/hap.h | 1572 ++++ .../homekit/esp_hap_core/include/hap_bct.h | 54 + .../homekit/esp_hap_core/include/hap_wac.h | 121 + .../homekit/esp_hap_core/src/byte_convert.c | 173 + .../homekit/esp_hap_core/src/esp_hap_acc.c | 491 ++ .../homekit/esp_hap_core/src/esp_hap_bct.c | 71 + .../homekit/esp_hap_core/src/esp_hap_char.c | 601 ++ .../esp_hap_core/src/esp_hap_controllers.c | 149 + .../esp_hap_core/src/esp_hap_database.c | 334 + .../esp_hap_core/src/esp_hap_ip_services.c | 1582 ++++ .../esp_hap_core/src/esp_hap_keystore.c | 128 + .../homekit/esp_hap_core/src/esp_hap_main.c | 372 + .../homekit/esp_hap_core/src/esp_hap_mdns.c | 85 + .../esp_hap_core/src/esp_hap_network_io.c | 199 + .../esp_hap_core/src/esp_hap_pair_common.c | 127 + .../esp_hap_core/src/esp_hap_pair_setup.c | 563 ++ .../esp_hap_core/src/esp_hap_pair_verify.c | 457 ++ .../esp_hap_core/src/esp_hap_pairings.c | 255 + .../homekit/esp_hap_core/src/esp_hap_serv.c | 329 + .../esp_hap_core/src/esp_hap_setup_payload.c | 81 + .../homekit/esp_hap_core/src/esp_hap_wifi.c | 121 + .../homekit/esp_hap_core/src/esp_mfi_debug.c | 80 + .../homekit/esp_hap_core/src/esp_mfi_dummy.c | 84 + components/homekit/esp_hap_core/src/hexbin.c | 51 + components/homekit/esp_hap_core/src/hexdump.c | 34 + .../esp_hap_core/src/priv_includes/base36.h | 60 + .../src/priv_includes/byte_convert.h | 139 + .../src/priv_includes/esp_hap_acc.h | 51 + .../src/priv_includes/esp_hap_bct_priv.h | 28 + .../src/priv_includes/esp_hap_char.h | 98 + .../src/priv_includes/esp_hap_controllers.h | 61 + .../src/priv_includes/esp_hap_database.h | 92 + .../src/priv_includes/esp_hap_ip_services.h | 35 + .../src/priv_includes/esp_hap_keystore.h | 34 + .../src/priv_includes/esp_hap_main.h | 72 + .../src/priv_includes/esp_hap_mdns.h | 43 + .../src/priv_includes/esp_hap_network_io.h | 31 + .../src/priv_includes/esp_hap_pair_common.h | 114 + .../src/priv_includes/esp_hap_pair_setup.h | 60 + .../src/priv_includes/esp_hap_pair_verify.h | 35 + .../src/priv_includes/esp_hap_pairings.h | 29 + .../priv_includes/esp_hap_secure_message.h | 42 + .../src/priv_includes/esp_hap_serv.h | 80 + .../src/priv_includes/esp_hap_wac.h | 32 + .../src/priv_includes/esp_hap_wifi.h | 30 + .../src/priv_includes/esp_mfi_debug.h | 158 + .../esp_hap_core/src/priv_includes/hexbin.h | 19 + .../esp_hap_core/src/priv_includes/hexdump.h | 18 + .../homekit/esp_hap_extras/CMakeLists.txt | 10 + .../homekit/esp_hap_extras/component.mk | 6 + .../include/hap_bct_http_handlers.h | 61 + .../esp_hap_extras/include/hap_fw_upgrade.h | 87 + .../src/hap_bct_http_handlers.c | 90 + .../esp_hap_extras/src/hap_fw_upgrade.c | 168 + .../homekit/esp_hap_platform/CMakeLists.txt | 10 + components/homekit/esp_hap_platform/Kconfig | 85 + .../homekit/esp_hap_platform/component.mk | 6 + .../esp_hap_platform/include/esp_mfi_aes.h | 82 + .../esp_hap_platform/include/esp_mfi_base64.h | 67 + .../esp_hap_platform/include/esp_mfi_i2c.h | 84 + .../esp_hap_platform/include/esp_mfi_rand.h | 50 + .../esp_hap_platform/include/esp_mfi_sha.h | 172 + .../include/hap_platform_httpd.h | 136 + .../include/hap_platform_keystore.h | 115 + .../include/hap_platform_memory.h | 67 + .../include/hap_platform_os.h | 41 + .../esp_hap_platform/src/esp32/esp_mfi_aes.c | 145 + .../src/esp32/esp_mfi_base64.c | 54 + .../esp_hap_platform/src/esp32/esp_mfi_i2c.c | 689 ++ .../esp_hap_platform/src/esp32/esp_mfi_rand.c | 56 + .../esp_hap_platform/src/esp32/esp_mfi_sha.c | 273 + .../src/esp32/hap_platform_httpd.c | 123 + .../src/esp32/hap_platform_keystore.c | 187 + .../src/esp32/hap_platform_memory.c | 39 + .../src/esp32/hap_platform_os.c | 31 + components/homekit/hkdf-sha/CMakeLists.txt | 9 + components/homekit/hkdf-sha/component.mk | 3 + .../homekit/hkdf-sha/include/hkdf-sha.h | 358 + .../homekit/hkdf-sha/upstream/.gitignore | 22 + components/homekit/hkdf-sha/upstream/Makefile | 36 + .../homekit/hkdf-sha/upstream/README.md | 6 + components/homekit/hkdf-sha/upstream/hkdf.c | 335 + components/homekit/hkdf-sha/upstream/hmac.c | 249 + .../homekit/hkdf-sha/upstream/rfc6234.txt | 7115 +++++++++++++++++ .../homekit/hkdf-sha/upstream/sha-private.h | 29 + components/homekit/hkdf-sha/upstream/sha.h | 358 + components/homekit/hkdf-sha/upstream/sha1.c | 414 + .../homekit/hkdf-sha/upstream/sha224-256.c | 581 ++ .../homekit/hkdf-sha/upstream/sha384-512.c | 1032 +++ .../homekit/hkdf-sha/upstream/shatest.c | 1530 ++++ components/homekit/hkdf-sha/upstream/usha.c | 281 + .../homekit/json_generator/CMakeLists.txt | 3 + .../homekit/json_generator/component.mk | 3 + components/homekit/json_generator/upstream | 1 + components/homekit/json_parser/CMakeLists.txt | 3 + components/homekit/json_parser/component.mk | 2 + components/homekit/json_parser/upstream | 1 + components/homekit/mu_srp/CMakeLists.txt | 9 + components/homekit/mu_srp/LICENSE | 176 + components/homekit/mu_srp/component.mk | 3 + components/homekit/mu_srp/mu_bignum.h | 192 + components/homekit/mu_srp/mu_srp.c | 489 ++ components/homekit/mu_srp/mu_srp.h | 91 + components/led/CMakeLists.txt | 9 + components/led/Kconfig | 212 + components/led/component.mk | 2 + components/led/led/component.mk | 4 + components/led/led/include/iot_led.h | 157 + components/led/led/led.c | 224 + examples/aws-iot/CMakeLists.txt | 21 + examples/aws-iot/Makefile | 19 + examples/aws-iot/README_EN.md | 48 + examples/aws-iot/aws-iot_factory.bin | Bin 0 -> 4096 bytes examples/aws-iot/main/CMakeLists.txt | 6 + examples/aws-iot/main/Kconfig.projbuild | 67 + examples/aws-iot/main/app_main.c | 228 + examples/aws-iot/main/certs/server.crt | 20 + examples/aws-iot/main/component.mk | 8 + examples/aws-iot/main/hap_aws_iot.h | 19 + examples/aws-iot/main/hap_aws_iot_pub_sub.c | 242 + .../aws-iot/main/hap_aws_iot_thing_shadow.c | 338 + examples/aws-iot/partitions_hap.csv | 10 + examples/aws-iot/sdkconfig.defaults | 20 + examples/bridge/CMakeLists.txt | 14 + examples/bridge/Makefile | 15 + examples/bridge/main/CMakeLists.txt | 1 + examples/bridge/main/Kconfig.projbuild | 26 + examples/bridge/main/app_main.c | 261 + examples/bridge/main/component.mk | 4 + examples/bridge/partitions_hap.csv | 10 + examples/bridge/sdkconfig.defaults | 19 + .../app_hap_setup_payload/CMakeLists.txt | 3 + .../app_hap_setup_payload.c | 29 + .../app_hap_setup_payload.h | 24 + .../common/app_hap_setup_payload/component.mk | 2 + examples/common/app_wifi/CMakeLists.txt | 3 + examples/common/app_wifi/Kconfig.projbuild | 85 + examples/common/app_wifi/app_wifi.c | 433 + examples/common/app_wifi/app_wifi.h | 12 + examples/common/app_wifi/component.mk | 2 + examples/common/qrcode/CMakeLists.txt | 5 + examples/common/qrcode/component.mk | 3 + examples/common/qrcode/include/qrcode.h | 40 + examples/common/qrcode/src/qrcode.c | 101 + examples/common/qrcode/src/qrcodegen.c | 1022 +++ examples/common/qrcode/src/qrcodegen.h | 311 + examples/data_tlv8/CMakeLists.txt | 17 + examples/data_tlv8/Makefile | 15 + examples/data_tlv8/main/CMakeLists.txt | 1 + examples/data_tlv8/main/Kconfig.projbuild | 26 + examples/data_tlv8/main/app_main.c | 336 + examples/data_tlv8/main/component.mk | 4 + examples/data_tlv8/partitions_hap.csv | 10 + examples/data_tlv8/sdkconfig.defaults | 19 + examples/emulator/CMakeLists.txt | 17 + examples/emulator/Makefile | 15 + examples/emulator/README.md | 19 + examples/emulator/emulator_factory.bin | Bin 0 -> 4096 bytes examples/emulator/main/CMakeLists.txt | 2 + examples/emulator/main/Kconfig.projbuild | 26 + examples/emulator/main/app_main.c | 323 + examples/emulator/main/cmd_register.c | 260 + examples/emulator/main/component.mk | 4 + examples/emulator/main/console_init.c | 125 + examples/emulator/main/emulator.c | 631 ++ examples/emulator/main/emulator.h | 28 + examples/emulator/partitions_hap.csv | 10 + examples/emulator/sdkconfig.defaults | 21 + examples/ethernet_bridge/CMakeLists.txt | 17 + examples/ethernet_bridge/Makefile | 15 + examples/ethernet_bridge/main/CMakeLists.txt | 2 + .../ethernet_bridge/main/Kconfig.projbuild | 126 + examples/ethernet_bridge/main/app_eth.c | 145 + examples/ethernet_bridge/main/app_eth.h | 12 + examples/ethernet_bridge/main/app_main.c | 222 + examples/ethernet_bridge/main/component.mk | 4 + examples/ethernet_bridge/partitions_hap.csv | 10 + examples/ethernet_bridge/sdkconfig.defaults | 21 + examples/fan/CMakeLists.txt | 17 + examples/fan/Makefile | 15 + examples/fan/fan_factory.bin | Bin 0 -> 4096 bytes examples/fan/main/CMakeLists.txt | 1 + examples/fan/main/Kconfig.projbuild | 26 + examples/fan/main/app_main.c | 325 + examples/fan/main/component.mk | 4 + examples/fan/partitions_hap.csv | 10 + examples/fan/sdkconfig.defaults | 19 + examples/lightbulb/CMakeLists.txt | 17 + examples/lightbulb/Makefile | 15 + examples/lightbulb/main/CMakeLists.txt | 2 + examples/lightbulb/main/Kconfig.projbuild | 26 + examples/lightbulb/main/app_main.c | 281 + examples/lightbulb/main/component.mk | 4 + examples/lightbulb/main/lightbulb.c | 279 + examples/lightbulb/main/lightbulb.h | 91 + examples/lightbulb/partitions_hap.csv | 10 + examples/lightbulb/sdkconfig.defaults | 19 + examples/smart_outlet/CMakeLists.txt | 17 + examples/smart_outlet/Makefile | 15 + examples/smart_outlet/main/CMakeLists.txt | 1 + examples/smart_outlet/main/Kconfig.projbuild | 26 + examples/smart_outlet/main/app_main.c | 241 + examples/smart_outlet/main/component.mk | 4 + examples/smart_outlet/partitions_hap.csv | 10 + examples/smart_outlet/sdkconfig.defaults | 19 + tools/factory_nvs_gen/README.md | 107 + tools/factory_nvs_gen/factory_nvs_gen.py | 165 + tools/idf_tools/mass_mfg/mfg_gen.py | 549 ++ .../nvs_partition_generator/README.rst | 187 + .../nvs_partition_gen.py | 887 ++ tools/mfg_homekit/README.md | 233 + tools/mfg_homekit/hk_mfg_gen.py | 755 ++ tools/mfg_homekit/setup_info_gen.py | 191 + tools/setup_payload_gen/README.md | 30 + tools/setup_payload_gen/setup_payload_gen.py | 62 + tools/srp/srp_tool.py | 424 + 237 files changed, 42650 insertions(+), 1 deletion(-) create mode 100644 .gitignore create mode 100644 .gitlab-ci.yml create mode 100644 .gitmodules create mode 100644 MFI_README.md create mode 100644 components/button/CMakeLists.txt create mode 100644 components/button/Kconfig create mode 100644 components/button/button/button.c create mode 100644 components/button/button/button_obj.cpp create mode 100644 components/button/button/component.mk create mode 100644 components/button/button/include/iot_button.h create mode 100644 components/button/component.mk create mode 100644 components/homekit/esp_hap_apple_profiles/CMakeLists.txt create mode 100644 components/homekit/esp_hap_apple_profiles/component.mk create mode 100644 components/homekit/esp_hap_apple_profiles/include/hap_apple_chars.h create mode 100644 components/homekit/esp_hap_apple_profiles/include/hap_apple_servs.h create mode 100644 components/homekit/esp_hap_apple_profiles/src/hap_apple_chars.c create mode 100644 components/homekit/esp_hap_apple_profiles/src/hap_apple_servs.c create mode 100644 components/homekit/esp_hap_core/CMakeLists.txt create mode 100644 components/homekit/esp_hap_core/Kconfig create mode 100644 components/homekit/esp_hap_core/component.mk create mode 100644 components/homekit/esp_hap_core/include/hap.h create mode 100644 components/homekit/esp_hap_core/include/hap_bct.h create mode 100644 components/homekit/esp_hap_core/include/hap_wac.h create mode 100644 components/homekit/esp_hap_core/src/byte_convert.c create mode 100644 components/homekit/esp_hap_core/src/esp_hap_acc.c create mode 100644 components/homekit/esp_hap_core/src/esp_hap_bct.c create mode 100644 components/homekit/esp_hap_core/src/esp_hap_char.c create mode 100644 components/homekit/esp_hap_core/src/esp_hap_controllers.c create mode 100644 components/homekit/esp_hap_core/src/esp_hap_database.c create mode 100644 components/homekit/esp_hap_core/src/esp_hap_ip_services.c create mode 100644 components/homekit/esp_hap_core/src/esp_hap_keystore.c create mode 100644 components/homekit/esp_hap_core/src/esp_hap_main.c create mode 100644 components/homekit/esp_hap_core/src/esp_hap_mdns.c create mode 100644 components/homekit/esp_hap_core/src/esp_hap_network_io.c create mode 100644 components/homekit/esp_hap_core/src/esp_hap_pair_common.c create mode 100644 components/homekit/esp_hap_core/src/esp_hap_pair_setup.c create mode 100644 components/homekit/esp_hap_core/src/esp_hap_pair_verify.c create mode 100644 components/homekit/esp_hap_core/src/esp_hap_pairings.c create mode 100644 components/homekit/esp_hap_core/src/esp_hap_serv.c create mode 100644 components/homekit/esp_hap_core/src/esp_hap_setup_payload.c create mode 100644 components/homekit/esp_hap_core/src/esp_hap_wifi.c create mode 100644 components/homekit/esp_hap_core/src/esp_mfi_debug.c create mode 100644 components/homekit/esp_hap_core/src/esp_mfi_dummy.c create mode 100644 components/homekit/esp_hap_core/src/hexbin.c create mode 100644 components/homekit/esp_hap_core/src/hexdump.c create mode 100644 components/homekit/esp_hap_core/src/priv_includes/base36.h create mode 100644 components/homekit/esp_hap_core/src/priv_includes/byte_convert.h create mode 100644 components/homekit/esp_hap_core/src/priv_includes/esp_hap_acc.h create mode 100644 components/homekit/esp_hap_core/src/priv_includes/esp_hap_bct_priv.h create mode 100644 components/homekit/esp_hap_core/src/priv_includes/esp_hap_char.h create mode 100644 components/homekit/esp_hap_core/src/priv_includes/esp_hap_controllers.h create mode 100644 components/homekit/esp_hap_core/src/priv_includes/esp_hap_database.h create mode 100644 components/homekit/esp_hap_core/src/priv_includes/esp_hap_ip_services.h create mode 100644 components/homekit/esp_hap_core/src/priv_includes/esp_hap_keystore.h create mode 100644 components/homekit/esp_hap_core/src/priv_includes/esp_hap_main.h create mode 100644 components/homekit/esp_hap_core/src/priv_includes/esp_hap_mdns.h create mode 100644 components/homekit/esp_hap_core/src/priv_includes/esp_hap_network_io.h create mode 100644 components/homekit/esp_hap_core/src/priv_includes/esp_hap_pair_common.h create mode 100644 components/homekit/esp_hap_core/src/priv_includes/esp_hap_pair_setup.h create mode 100644 components/homekit/esp_hap_core/src/priv_includes/esp_hap_pair_verify.h create mode 100644 components/homekit/esp_hap_core/src/priv_includes/esp_hap_pairings.h create mode 100644 components/homekit/esp_hap_core/src/priv_includes/esp_hap_secure_message.h create mode 100644 components/homekit/esp_hap_core/src/priv_includes/esp_hap_serv.h create mode 100644 components/homekit/esp_hap_core/src/priv_includes/esp_hap_wac.h create mode 100644 components/homekit/esp_hap_core/src/priv_includes/esp_hap_wifi.h create mode 100644 components/homekit/esp_hap_core/src/priv_includes/esp_mfi_debug.h create mode 100644 components/homekit/esp_hap_core/src/priv_includes/hexbin.h create mode 100644 components/homekit/esp_hap_core/src/priv_includes/hexdump.h create mode 100644 components/homekit/esp_hap_extras/CMakeLists.txt create mode 100644 components/homekit/esp_hap_extras/component.mk create mode 100644 components/homekit/esp_hap_extras/include/hap_bct_http_handlers.h create mode 100644 components/homekit/esp_hap_extras/include/hap_fw_upgrade.h create mode 100644 components/homekit/esp_hap_extras/src/hap_bct_http_handlers.c create mode 100644 components/homekit/esp_hap_extras/src/hap_fw_upgrade.c create mode 100644 components/homekit/esp_hap_platform/CMakeLists.txt create mode 100644 components/homekit/esp_hap_platform/Kconfig create mode 100644 components/homekit/esp_hap_platform/component.mk create mode 100644 components/homekit/esp_hap_platform/include/esp_mfi_aes.h create mode 100644 components/homekit/esp_hap_platform/include/esp_mfi_base64.h create mode 100644 components/homekit/esp_hap_platform/include/esp_mfi_i2c.h create mode 100644 components/homekit/esp_hap_platform/include/esp_mfi_rand.h create mode 100644 components/homekit/esp_hap_platform/include/esp_mfi_sha.h create mode 100644 components/homekit/esp_hap_platform/include/hap_platform_httpd.h create mode 100644 components/homekit/esp_hap_platform/include/hap_platform_keystore.h create mode 100644 components/homekit/esp_hap_platform/include/hap_platform_memory.h create mode 100644 components/homekit/esp_hap_platform/include/hap_platform_os.h create mode 100644 components/homekit/esp_hap_platform/src/esp32/esp_mfi_aes.c create mode 100644 components/homekit/esp_hap_platform/src/esp32/esp_mfi_base64.c create mode 100644 components/homekit/esp_hap_platform/src/esp32/esp_mfi_i2c.c create mode 100644 components/homekit/esp_hap_platform/src/esp32/esp_mfi_rand.c create mode 100644 components/homekit/esp_hap_platform/src/esp32/esp_mfi_sha.c create mode 100644 components/homekit/esp_hap_platform/src/esp32/hap_platform_httpd.c create mode 100644 components/homekit/esp_hap_platform/src/esp32/hap_platform_keystore.c create mode 100644 components/homekit/esp_hap_platform/src/esp32/hap_platform_memory.c create mode 100644 components/homekit/esp_hap_platform/src/esp32/hap_platform_os.c create mode 100644 components/homekit/hkdf-sha/CMakeLists.txt create mode 100644 components/homekit/hkdf-sha/component.mk create mode 100644 components/homekit/hkdf-sha/include/hkdf-sha.h create mode 100644 components/homekit/hkdf-sha/upstream/.gitignore create mode 100644 components/homekit/hkdf-sha/upstream/Makefile create mode 100644 components/homekit/hkdf-sha/upstream/README.md create mode 100644 components/homekit/hkdf-sha/upstream/hkdf.c create mode 100644 components/homekit/hkdf-sha/upstream/hmac.c create mode 100644 components/homekit/hkdf-sha/upstream/rfc6234.txt create mode 100644 components/homekit/hkdf-sha/upstream/sha-private.h create mode 100644 components/homekit/hkdf-sha/upstream/sha.h create mode 100644 components/homekit/hkdf-sha/upstream/sha1.c create mode 100644 components/homekit/hkdf-sha/upstream/sha224-256.c create mode 100644 components/homekit/hkdf-sha/upstream/sha384-512.c create mode 100644 components/homekit/hkdf-sha/upstream/shatest.c create mode 100644 components/homekit/hkdf-sha/upstream/usha.c create mode 100644 components/homekit/json_generator/CMakeLists.txt create mode 100644 components/homekit/json_generator/component.mk create mode 160000 components/homekit/json_generator/upstream create mode 100644 components/homekit/json_parser/CMakeLists.txt create mode 100644 components/homekit/json_parser/component.mk create mode 160000 components/homekit/json_parser/upstream create mode 100644 components/homekit/mu_srp/CMakeLists.txt create mode 100644 components/homekit/mu_srp/LICENSE create mode 100644 components/homekit/mu_srp/component.mk create mode 100644 components/homekit/mu_srp/mu_bignum.h create mode 100644 components/homekit/mu_srp/mu_srp.c create mode 100644 components/homekit/mu_srp/mu_srp.h create mode 100644 components/led/CMakeLists.txt create mode 100644 components/led/Kconfig create mode 100644 components/led/component.mk create mode 100644 components/led/led/component.mk create mode 100644 components/led/led/include/iot_led.h create mode 100644 components/led/led/led.c create mode 100644 examples/aws-iot/CMakeLists.txt create mode 100755 examples/aws-iot/Makefile create mode 100755 examples/aws-iot/README_EN.md create mode 100644 examples/aws-iot/aws-iot_factory.bin create mode 100644 examples/aws-iot/main/CMakeLists.txt create mode 100644 examples/aws-iot/main/Kconfig.projbuild create mode 100755 examples/aws-iot/main/app_main.c create mode 100644 examples/aws-iot/main/certs/server.crt create mode 100644 examples/aws-iot/main/component.mk create mode 100644 examples/aws-iot/main/hap_aws_iot.h create mode 100644 examples/aws-iot/main/hap_aws_iot_pub_sub.c create mode 100644 examples/aws-iot/main/hap_aws_iot_thing_shadow.c create mode 100644 examples/aws-iot/partitions_hap.csv create mode 100644 examples/aws-iot/sdkconfig.defaults create mode 100644 examples/bridge/CMakeLists.txt create mode 100755 examples/bridge/Makefile create mode 100644 examples/bridge/main/CMakeLists.txt create mode 100644 examples/bridge/main/Kconfig.projbuild create mode 100644 examples/bridge/main/app_main.c create mode 100644 examples/bridge/main/component.mk create mode 100644 examples/bridge/partitions_hap.csv create mode 100644 examples/bridge/sdkconfig.defaults create mode 100644 examples/common/app_hap_setup_payload/CMakeLists.txt create mode 100644 examples/common/app_hap_setup_payload/app_hap_setup_payload.c create mode 100644 examples/common/app_hap_setup_payload/app_hap_setup_payload.h create mode 100644 examples/common/app_hap_setup_payload/component.mk create mode 100644 examples/common/app_wifi/CMakeLists.txt create mode 100644 examples/common/app_wifi/Kconfig.projbuild create mode 100644 examples/common/app_wifi/app_wifi.c create mode 100644 examples/common/app_wifi/app_wifi.h create mode 100644 examples/common/app_wifi/component.mk create mode 100644 examples/common/qrcode/CMakeLists.txt create mode 100644 examples/common/qrcode/component.mk create mode 100644 examples/common/qrcode/include/qrcode.h create mode 100644 examples/common/qrcode/src/qrcode.c create mode 100644 examples/common/qrcode/src/qrcodegen.c create mode 100644 examples/common/qrcode/src/qrcodegen.h create mode 100644 examples/data_tlv8/CMakeLists.txt create mode 100755 examples/data_tlv8/Makefile create mode 100644 examples/data_tlv8/main/CMakeLists.txt create mode 100644 examples/data_tlv8/main/Kconfig.projbuild create mode 100644 examples/data_tlv8/main/app_main.c create mode 100644 examples/data_tlv8/main/component.mk create mode 100644 examples/data_tlv8/partitions_hap.csv create mode 100644 examples/data_tlv8/sdkconfig.defaults create mode 100644 examples/emulator/CMakeLists.txt create mode 100755 examples/emulator/Makefile create mode 100644 examples/emulator/README.md create mode 100644 examples/emulator/emulator_factory.bin create mode 100644 examples/emulator/main/CMakeLists.txt create mode 100644 examples/emulator/main/Kconfig.projbuild create mode 100644 examples/emulator/main/app_main.c create mode 100644 examples/emulator/main/cmd_register.c create mode 100644 examples/emulator/main/component.mk create mode 100644 examples/emulator/main/console_init.c create mode 100644 examples/emulator/main/emulator.c create mode 100644 examples/emulator/main/emulator.h create mode 100644 examples/emulator/partitions_hap.csv create mode 100644 examples/emulator/sdkconfig.defaults create mode 100644 examples/ethernet_bridge/CMakeLists.txt create mode 100644 examples/ethernet_bridge/Makefile create mode 100644 examples/ethernet_bridge/main/CMakeLists.txt create mode 100644 examples/ethernet_bridge/main/Kconfig.projbuild create mode 100644 examples/ethernet_bridge/main/app_eth.c create mode 100644 examples/ethernet_bridge/main/app_eth.h create mode 100644 examples/ethernet_bridge/main/app_main.c create mode 100644 examples/ethernet_bridge/main/component.mk create mode 100644 examples/ethernet_bridge/partitions_hap.csv create mode 100644 examples/ethernet_bridge/sdkconfig.defaults create mode 100644 examples/fan/CMakeLists.txt create mode 100755 examples/fan/Makefile create mode 100644 examples/fan/fan_factory.bin create mode 100644 examples/fan/main/CMakeLists.txt create mode 100644 examples/fan/main/Kconfig.projbuild create mode 100644 examples/fan/main/app_main.c create mode 100644 examples/fan/main/component.mk create mode 100644 examples/fan/partitions_hap.csv create mode 100644 examples/fan/sdkconfig.defaults create mode 100644 examples/lightbulb/CMakeLists.txt create mode 100755 examples/lightbulb/Makefile create mode 100644 examples/lightbulb/main/CMakeLists.txt create mode 100644 examples/lightbulb/main/Kconfig.projbuild create mode 100644 examples/lightbulb/main/app_main.c create mode 100644 examples/lightbulb/main/component.mk create mode 100644 examples/lightbulb/main/lightbulb.c create mode 100644 examples/lightbulb/main/lightbulb.h create mode 100644 examples/lightbulb/partitions_hap.csv create mode 100644 examples/lightbulb/sdkconfig.defaults create mode 100644 examples/smart_outlet/CMakeLists.txt create mode 100755 examples/smart_outlet/Makefile create mode 100644 examples/smart_outlet/main/CMakeLists.txt create mode 100644 examples/smart_outlet/main/Kconfig.projbuild create mode 100644 examples/smart_outlet/main/app_main.c create mode 100644 examples/smart_outlet/main/component.mk create mode 100644 examples/smart_outlet/partitions_hap.csv create mode 100644 examples/smart_outlet/sdkconfig.defaults create mode 100644 tools/factory_nvs_gen/README.md create mode 100755 tools/factory_nvs_gen/factory_nvs_gen.py create mode 100755 tools/idf_tools/mass_mfg/mfg_gen.py create mode 100644 tools/idf_tools/nvs_partition_generator/README.rst create mode 100755 tools/idf_tools/nvs_partition_generator/nvs_partition_gen.py create mode 100644 tools/mfg_homekit/README.md create mode 100755 tools/mfg_homekit/hk_mfg_gen.py create mode 100755 tools/mfg_homekit/setup_info_gen.py create mode 100644 tools/setup_payload_gen/README.md create mode 100755 tools/setup_payload_gen/setup_payload_gen.py create mode 100644 tools/srp/srp_tool.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3d7f062 --- /dev/null +++ b/.gitignore @@ -0,0 +1,41 @@ +.config +*.o +*.pyc + + +# Example project files +examples/**/sdkconfig +examples/**/sdkconfig.old +examples/**/build + +# emacs +.dir-locals.el + +# eclipse setting +.settings + +# vscode +.vscode + +# Doc build artifacts +docs/*/_build/ +docs/*/doxygen-warning-log.txt +docs/*/sphinx-warning-log.txt +docs/*/sphinx-warning-log-sanitized.txt +docs/*/xml/ +docs/*/xml_in/ +docs/*/man/ +docs/doxygen_sqlite3.db + +# MacOS directory files +.DS_Store + +# Tools +tools/factory_nvs_gen/*.bin +tools/factory_nvs_gen/*.csv + +# Patch files +*.patch + +#CTags +tags diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000..9ea704f --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,92 @@ +stages: + - build + +build_homekit_examples: + stage: build + image: $CI_DOCKER_REGISTRY/esp32-ci-env + tags: + - build + + variables: + IDF_PATH: "$CI_PROJECT_DIR/esp-idf" + GIT_STRATEGY: clone + + artifacts: + paths: + - examples/fan/build/*.bin + - examples/fan/build/*.elf + - examples/fan/build/*.map + - examples/fan/build/bootloader/*.bin + expire_in: 6 mos + + before_script: + - mkdir -p ~/.ssh + - chmod 700 ~/.ssh + - echo -n $GITLAB_KEY >> ~/.ssh/id_rsa_base64 + - base64 --decode --ignore-garbage ~/.ssh/id_rsa_base64 > ~/.ssh/id_rsa + - chmod 600 ~/.ssh/id_rsa + - echo -e "Host gitlab.espressif.cn\n\tStrictHostKeyChecking no\n" >> ~/.ssh/config + + script: + - git submodule update --init --recursive + # Cloning esp-idf + - git clone -b release/v4.2 --recursive --depth 1 https://github.com/espressif/esp-idf.git + - cd esp-idf + - ./install.sh + - . export.sh + + - cd ../examples/fan + - idf.py build + - cd ../bridge + - idf.py build + - cd ../lightbulb + - idf.py build + - cd ../smart_outlet + - idf.py build + - cd ../data_tlv8 + - idf.py build + - cd ../aws-iot + - mkdir components + - cd components + - git clone --depth 1 --single-branch --recursive https://github.com/espressif/esp-aws-iot.git + - export AWS_IOT_PATH=$PWD/esp-aws-iot + - cd .. + - touch main/certs/device.crt main/certs/device.key + - idf.py build + - cd ../emulator + - idf.py build + - cd ../ethernet_bridge + - idf.py build + - cd ../fan + - rm -rf build sdkconfig sdkconfig.old + - make defconfig + - make -j4 + - cd ../bridge + - rm -rf build sdkconfig sdkconfig.old + - make defconfig + - make -j4 + - cd ../lightbulb + - rm -rf build sdkconfig sdkconfig.old + - make defconfig + - make -j4 + - cd ../smart_outlet + - rm -rf build sdkconfig sdkconfig.old + - make defconfig + - make -j4 + - cd ../data_tlv8 + - rm -rf build sdkconfig sdkconfig.old + - make defconfig + - make -j4 + - cd ../aws-iot + - rm -rf build sdkconfig sdkconfig.old + - touch main/certs/device.crt main/certs/device.key + - make defconfig + - make -j4 + - cd ../emulator + - rm -rf build sdkconfig sdkconfig.old + - make defconfig + - make -j4 + - cd ../ethernet_bridge + - rm -rf build sdkconfig sdkconfig.old + - make defconfig + - make -j4 diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..c3b42fc --- /dev/null +++ b/.gitmodules @@ -0,0 +1,6 @@ +[submodule "components/homekit/json_parser/upstream"] + path = components/homekit/json_parser/upstream + url = https://github.com/shahpiyushv/json_parser.git +[submodule "components/homekit/json_generator/upstream"] + path = components/homekit/json_generator/upstream + url = https://github.com/shahpiyushv/json_generator.git diff --git a/MFI_README.md b/MFI_README.md new file mode 100644 index 0000000..6b3e156 --- /dev/null +++ b/MFI_README.md @@ -0,0 +1,3 @@ +# ESP HomeKit SDK (MFi) + +The Open source variant of esp-homekit-sdk cannot be used for commercial products. If you want to build commercial products and have an MFi License already, please get in touch with us by visiting [here](https://www.espressif.com/en/products/sdks/esp-homekit-sdk). diff --git a/README.md b/README.md index d0df919..133b944 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,129 @@ # ESP HomeKit SDK +## Introduction -Espressif HomeKit SDK developed in-house \ No newline at end of file +[HomeKit](https://developer.apple.com/homekit/) is a framework developed by Apple for communicating with and controlling connected accessories in a user’s home using iOS devices. +ESP HomeKit SDK has been developed in-house by Espressif to build Apple HomeKit compatible accessories using ESP32/ESP32-S2 SoCs. + +> Note: If you want to use HomeKit for commercial products, please check [here](https://www.espressif.com/en/products/sdks/esp-homekit-sdk) for access to the MFi variant of this SDK. It has the exact same APIs as this and so, moving to it should be easy. + +> If you want to use a port of Apple's ADK instead, please check [here](https://github.com/espressif/esp-apple-homekit-adk) + +Features of this SDK: + +* Easy APIs to implement all standard HomeKit profiles defined by Apple. +* Facility to add customised accessory specific Services and Characteristics. +* Samples (Fan, Lightbulb, Outlet, Bridge, Data-TLV8, Ethernet) to enable quick accessory development. +* Support for ESP Unified Provisioning. + +## Get Started + +### Set up Host environment + +Set up the host environment and ESP IDF (**master** branch) as per the steps given [here](https://docs.espressif.com/projects/esp-idf/en/latest/get-started/index.html). + +### Get esp-homekit-sdk + +Please clone this repository using the below command: + +```text +git clone --recursive https://github.com/espressif/esp-homekit-sdk.git +``` + +> Note the --recursive option. This is required to pull in the JSON dependencies into esp-homekit-sdk. In case you have already cloned the repository without this option, execute this to pull in the submodules: +> `git submodule update --init --recursive` + + +### Compile and Flash + +You can use esp-homekit-sdk with any ESP32 or ESP32-S2 board. We have provided multiple examples for reference. Compile and flash as below (fan used as example): + +```text +$ cd /path/to/esp-homekit-sdk/examples/fan +$ export ESPPORT=/dev/tty.SLAB_USBtoUART #Set your board's serial port here +$ idf.py set-target +$ idf.py flash monitor +``` + +As the device boots up, you will see two QR codes, a small one for HomeKit and a larger one for Wi-Fi provisioning. Please use any of the [Espressif Provisioning Apps](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/provisioning/provisioning.html#provisioning-tools) for Wi-Fi provisioning. + +> Note: For the Open source HomeKit SDK, the HomeKit QR code cannot be used for provisioning from the Home app. It can be used only for pairing, after the Wi-Fi provisioning is done. For provisioning from Home app, you will need the MFi variant of the SDK. + +> Note: If you want to use hard-coded credentials instead of Provisioning, please set the ssid and passphrase by navigating to `idf.py menuconfig -> App Wi-Fi -> Source of Wi-Fi Credentials -> Use Hardcoded` + +After the device connects to your Home Wi-Fi network it can be added in the Home app + +### Add acccessory in the Home app + +Open the Home app on your iPhone/iPad and follow these steps + +- Tap on "Add Accessory" and scan the small QR code mentioned above. +- If QR code is not visible correctly, you may use the link printed on the serial terminal or follow these steps: + - Choose the "I Don't Have a Code or Cannot Scan" option. + - Tap on "Esp-Fan-xxxxxx" in the list of Nearby Accessories. + - Select the "Add Anyway" option for the "Uncertified Accessory" prompt. + - Enter 11122333 as the Setup code. +- You should eventually see the "Esp-Fan-xxxxxx added" message. +- Give a custom name, assign to a room, create scenes as required and you are done. + +### Changing the Setup Code + +The HomeKit setup code can be changed by using the `CONFIG_EXAMPLE_SETUP_CODE` config option (`idf.py menuconfig -> Example Configuration -> HomeKit Setup Code`). Please also refer the [HomeKit Setup Configuration](#homeKit-setup-configuration) below. + + +## Using Standard Apple HomeKit Profiles +The examples provided in the SDK are for fan, outlet, lightbulb. For using any other standard profiles, please refer the files under `components/homekit/hap_apple_profiles/`. + +## Adding Custom Profiles +Please refer the Firmware Upgrades Custom Profile (`components/homekit/extras/`) to see how to add your own profile. You can use some UUID generator like [this](https://www.uuidgenerator.net/) to generate your own UUIDs for the services and characteristics. + +## HomeKit Setup Configuration + +As per the HomeKit requirements, the raw setup code should not be stored on the accessory. Instead, the SRP Salt and Verifier generated from the code should be stored. This salt-verifier combination, called as setup info in the ESP HomeKit SDK, needs to be unique for every accessory. This can be provided to the HAP Core using the `hap_set_setup_info()` API. Another parameter required for setup is the setup id, which also needs to be unique. It is provided to the HAP Core using `hap_set_setup_id()` API. + +In order to ease the task of providing unique setup info and setup id for each accessory, instead of using the above APIs, the same information can be stored in a separate flash partition called factory\_nvs (Please see the `partitions_hap.csv` file in any example). This allows to keep the same firmware image and just flash different factory\_nvs images for different accessories. The factory\_nvs image fan\_factory.bin has been provided for Fan, which can be flashed using esptool. Custom images can be created using the `factory_nvs_gen` utility in tools/ as below + +Usage: + +``` +./factory_nvs_gen.py 11122333 ES32 factory +``` + +> Replace ES32 and 11122333 with the setup code and setup id of your choice. This has been tested with **Python 3.7.3**. + +Flash this using the esptool as below. + +```text +$ esptool.py -p $ESPPORT write_flash 0x340000 factory.bin +``` + +To use the setup info from this image, you will have to disable the hardcoded setup code by setting `CONFIG_EXAMPLE_SETUP_CODE=n` (`idf.py menuconfig -> Example Configuration -> Use hard-coded setup code -> disable`). + +The factory\_nvs partition can also hold other information like serial numbers, cloud credentials, firmware verification keys, etc. For that, just create a CSV file as per the requirements of [NVS Partition Generator Utility](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/storage/nvs_partition_gen.html#) and provide it to the `factory_nvs_gen` using the `--infile` option. These variables (if stored as binary data) can then be read in the accessory code using `hap_factory_keystore_get()` API. + +Sample CSV (say sample.csv) + +``` +key,type,encoding,value +app,namespace,, +serial_num,data,binary,12345 +``` + +Usage: + +``` +./factory_nvs_gen.py --infile sample.csv 11122333 ES32 factory +``` + +Flash this using the same command given above. + +```text +$ esptool.py -p $ESPPORT write_flash 0x340000 factory.bin +``` + +## Additional MFi requirements + +If you have access to the MFi variant of esp-homekit-sdk, please check additional information [here](MFI_README.md). + +## Reporting issues + +You can report issues directly on [Github issues](https://github.com/espressif/esp-homekit-sdk/issues). diff --git a/components/button/CMakeLists.txt b/components/button/CMakeLists.txt new file mode 100644 index 0000000..1135b6d --- /dev/null +++ b/components/button/CMakeLists.txt @@ -0,0 +1,9 @@ +set(COMPONENT_ADD_INCLUDEDIRS ./button/include) + +# Edit following two lines to set component requirements (see docs) +set(COMPONENT_REQUIRES ) +set(COMPONENT_PRIV_REQUIRES ) + +set(COMPONENT_SRCS ./button/button.c ./button/button_obj.cpp) + +register_component() diff --git a/components/button/Kconfig b/components/button/Kconfig new file mode 100644 index 0000000..8125118 --- /dev/null +++ b/components/button/Kconfig @@ -0,0 +1,6 @@ +menu "Button" + config IO_GLITCH_FILTER_TIME_MS + int "IO glitch filter timer ms (10~100)" + range 10 100 + default 50 +endmenu \ No newline at end of file diff --git a/components/button/button/button.c b/components/button/button/button.c new file mode 100644 index 0000000..a8a4144 --- /dev/null +++ b/components/button/button/button.c @@ -0,0 +1,363 @@ +/* + * ESPRSSIF MIT License + * + * Copyright (c) 2015 + * + * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case, + * it is free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define IOT_CHECK(tag, a, ret) if(!(a)) { \ + ESP_LOGE(tag,"%s:%d (%s)", __FILE__, __LINE__, __FUNCTION__); \ + return (ret); \ + } +#define ERR_ASSERT(tag, param) IOT_CHECK(tag, (param) == ESP_OK, ESP_FAIL) +#define POINT_ASSERT(tag, param, ret) IOT_CHECK(tag, (param) != NULL, (ret)) + +typedef enum { + BUTTON_STATE_IDLE = 0, + BUTTON_STATE_PUSH, + BUTTON_STATE_PRESSED, +} button_status_t; + +typedef struct button_dev button_dev_t; +typedef struct btn_cb button_cb_t; + +struct btn_cb{ + TickType_t interval; + button_cb cb; + void* arg; + uint8_t on_press; + TimerHandle_t tmr; + button_dev_t *pbtn; + button_cb_t *next_cb; +}; + +struct button_dev{ + uint8_t io_num; + uint8_t active_level; + uint32_t serial_thres_sec; + uint8_t taskq_on; + QueueHandle_t taskq; + QueueHandle_t argq; + button_status_t state; + button_cb_t tap_short_cb; + button_cb_t tap_psh_cb; + button_cb_t tap_rls_cb; + button_cb_t press_serial_cb; + button_cb_t* cb_head; +}; + +#define BUTTON_GLITCH_FILTER_TIME_MS CONFIG_IO_GLITCH_FILTER_TIME_MS +static const char* TAG = "button"; + +static void button_press_cb(xTimerHandle tmr) +{ + button_cb_t* btn_cb = (button_cb_t*) pvTimerGetTimerID(tmr); + button_dev_t* btn = btn_cb->pbtn; + // low, then restart + if (btn->active_level == gpio_get_level(btn->io_num)) { + btn->state = BUTTON_STATE_PRESSED; + if (btn->taskq != NULL && btn->argq != NULL && btn->taskq_on && !btn_cb->on_press) { + void *tmp = btn_cb->cb; + xQueueOverwrite(btn->taskq, &tmp); + xQueueOverwrite(btn->argq, &btn_cb->arg); + } else if (btn_cb->cb) { + btn_cb->cb(btn_cb->arg); + } + } +} + +static void button_tap_psh_cb(xTimerHandle tmr) +{ + button_cb_t* btn_cb = (button_cb_t*) pvTimerGetTimerID(tmr); + button_dev_t* btn = btn_cb->pbtn; + xTimerStop(btn->tap_rls_cb.tmr, portMAX_DELAY); + int lv = gpio_get_level(btn->io_num); + + if (btn->active_level == lv) { + // True implies key is pressed + btn->state = BUTTON_STATE_PUSH; + if (btn->press_serial_cb.tmr) { + xTimerChangePeriod(btn->press_serial_cb.tmr, btn->serial_thres_sec*1000 / portTICK_PERIOD_MS, portMAX_DELAY); + xTimerReset(btn->press_serial_cb.tmr, portMAX_DELAY); + } + if (btn->tap_psh_cb.cb) { + btn->tap_psh_cb.cb(btn->tap_psh_cb.arg); + } + } else { + // 50ms, check if this is a real key up + if (btn->tap_rls_cb.tmr) { + xTimerStop(btn->tap_rls_cb.tmr, portMAX_DELAY); + xTimerReset(btn->tap_rls_cb.tmr, portMAX_DELAY); + } + } +} + +static void button_tap_rls_cb(xTimerHandle tmr) +{ + button_cb_t* btn_cb = (button_cb_t*) pvTimerGetTimerID(tmr); + button_dev_t* btn = btn_cb->pbtn; + xTimerStop(btn->tap_rls_cb.tmr, portMAX_DELAY); + if (btn->active_level == gpio_get_level(btn->io_num)) { + + } else { + // high, then key is up + button_cb_t *pcb = btn->cb_head; + while (pcb != NULL) { + if (pcb->tmr != NULL) { + xTimerStop(pcb->tmr, portMAX_DELAY); + } + pcb = pcb->next_cb; + } + if (btn->taskq != NULL && btn->argq != NULL && btn->taskq_on && uxQueueMessagesWaiting(btn->taskq) != 0 && btn->state != BUTTON_STATE_IDLE) { + void (*task)(void*); + void *arg; + xQueueReceive(btn->taskq, &task, 0); + xQueueReceive(btn->argq, &arg, 0); + task(arg); + } + if (btn->press_serial_cb.tmr && btn->press_serial_cb.tmr != NULL) { + xTimerStop(btn->press_serial_cb.tmr, portMAX_DELAY); + } + if (btn->tap_short_cb.cb && btn->state == BUTTON_STATE_PUSH) { + btn->tap_short_cb.cb(btn->tap_short_cb.arg); + } + if(btn->tap_rls_cb.cb && btn->state != BUTTON_STATE_IDLE) { + btn->tap_rls_cb.cb(btn->tap_rls_cb.arg); + } + btn->state = BUTTON_STATE_IDLE; + } +} + +static void button_press_serial_cb(xTimerHandle tmr) +{ + button_dev_t* btn = (button_dev_t*) pvTimerGetTimerID(tmr); + if (btn->press_serial_cb.cb) { + btn->press_serial_cb.cb(btn->press_serial_cb.arg); + } + xTimerChangePeriod(btn->press_serial_cb.tmr, btn->press_serial_cb.interval, portMAX_DELAY); + xTimerReset(btn->press_serial_cb.tmr, portMAX_DELAY); +} + +static void button_gpio_isr_handler(void* arg) +{ + button_dev_t* btn = (button_dev_t*) arg; + portBASE_TYPE HPTaskAwoken = pdFALSE; + int level = gpio_get_level(btn->io_num); + if (level == btn->active_level) { + if (btn->tap_psh_cb.tmr) { + xTimerStopFromISR(btn->tap_psh_cb.tmr, &HPTaskAwoken); + xTimerResetFromISR(btn->tap_psh_cb.tmr, &HPTaskAwoken); + } + + button_cb_t *pcb = btn->cb_head; + while (pcb != NULL) { + if (pcb->tmr != NULL) { + xTimerStopFromISR(pcb->tmr, &HPTaskAwoken); + xTimerResetFromISR(pcb->tmr, &HPTaskAwoken); + } + pcb = pcb->next_cb; + } + } else { + // 50ms, check if this is a real key up + if (btn->tap_rls_cb.tmr) { + xTimerStopFromISR(btn->tap_rls_cb.tmr, &HPTaskAwoken); + xTimerResetFromISR(btn->tap_rls_cb.tmr, &HPTaskAwoken); + } + } + if(HPTaskAwoken == pdTRUE) { + portYIELD_FROM_ISR(); + } +} + +static void button_free_tmr(xTimerHandle* tmr) +{ + if (tmr && *tmr) { + xTimerStop(*tmr, portMAX_DELAY); + xTimerDelete(*tmr, portMAX_DELAY); + *tmr = NULL; + } +} + +esp_err_t iot_button_delete(button_handle_t btn_handle) +{ + POINT_ASSERT(TAG, btn_handle, ESP_ERR_INVALID_ARG); + button_dev_t* btn = (button_dev_t*) btn_handle; + gpio_set_intr_type(btn->io_num, GPIO_INTR_DISABLE); + gpio_isr_handler_remove(btn->io_num); + + button_free_tmr(&btn->tap_rls_cb.tmr); + button_free_tmr(&btn->tap_psh_cb.tmr); + button_free_tmr(&btn->tap_short_cb.tmr); + button_free_tmr(&btn->press_serial_cb.tmr); + + button_cb_t *pcb = btn->cb_head; + while (pcb != NULL) { + button_cb_t *cb_next = pcb->next_cb; + button_free_tmr(&pcb->tmr); + free(pcb); + pcb = cb_next; + } + free(btn); + return ESP_OK; +} + +button_handle_t iot_button_create(gpio_num_t gpio_num, button_active_t active_level) +{ + IOT_CHECK(TAG, gpio_num < GPIO_NUM_MAX, NULL); + button_dev_t* btn = (button_dev_t*) calloc(1, sizeof(button_dev_t)); + POINT_ASSERT(TAG, btn, NULL); + btn->active_level = active_level; + btn->io_num = gpio_num; + btn->state = BUTTON_STATE_IDLE; + btn->taskq_on = 0; + btn->taskq = xQueueCreate(1, sizeof(void*)); + btn->argq = xQueueCreate(1, sizeof(void *)); + btn->tap_rls_cb.arg = NULL; + btn->tap_rls_cb.cb = NULL; + btn->tap_rls_cb.interval = BUTTON_GLITCH_FILTER_TIME_MS / portTICK_PERIOD_MS; + btn->tap_rls_cb.pbtn = btn; + btn->tap_rls_cb.tmr = xTimerCreate("btn_rls_tmr", btn->tap_rls_cb.interval, pdFALSE, + &btn->tap_rls_cb, button_tap_rls_cb); + btn->tap_psh_cb.arg = NULL; + btn->tap_psh_cb.cb = NULL; + btn->tap_psh_cb.interval = BUTTON_GLITCH_FILTER_TIME_MS / portTICK_PERIOD_MS; + btn->tap_psh_cb.pbtn = btn; + btn->tap_psh_cb.tmr = xTimerCreate("btn_psh_tmr", btn->tap_psh_cb.interval, pdFALSE, + &btn->tap_psh_cb, button_tap_psh_cb); + gpio_install_isr_service(0); + gpio_config_t gpio_conf; + gpio_conf.intr_type = GPIO_INTR_ANYEDGE; + gpio_conf.mode = GPIO_MODE_INPUT; + gpio_conf.pin_bit_mask = (1 << gpio_num); + gpio_conf.pull_down_en = GPIO_PULLDOWN_DISABLE; + gpio_conf.pull_up_en = GPIO_PULLUP_ENABLE; + gpio_config(&gpio_conf); + gpio_isr_handler_add(gpio_num, button_gpio_isr_handler, btn); + return (button_handle_t) btn; +} + +esp_err_t iot_button_rm_cb(button_handle_t btn_handle, button_cb_type_t type) +{ + button_dev_t* btn = (button_dev_t*) btn_handle; + button_cb_t* btn_cb = NULL; + if (type == BUTTON_CB_PUSH) { + btn_cb = &btn->tap_psh_cb; + } else if (type == BUTTON_CB_RELEASE) { + btn_cb = &btn->tap_rls_cb; + } else if (type == BUTTON_CB_TAP) { + btn_cb = &btn->tap_short_cb; + } else if (type == BUTTON_CB_SERIAL) { + btn_cb = &btn->press_serial_cb; + } + btn_cb->cb = NULL; + btn_cb->arg = NULL; + btn_cb->pbtn = btn; + button_free_tmr(&btn_cb->tmr); + return ESP_OK; +} + +esp_err_t iot_button_set_serial_cb(button_handle_t btn_handle, uint32_t start_after_sec, TickType_t interval_tick, button_cb cb, void* arg) +{ + button_dev_t* btn = (button_dev_t*) btn_handle; + btn->serial_thres_sec = start_after_sec; + if (btn->press_serial_cb.tmr == NULL) { + btn->press_serial_cb.tmr = xTimerCreate("btn_serial_tmr", btn->serial_thres_sec*1000 / portTICK_PERIOD_MS, + pdFALSE, btn, button_press_serial_cb); + } + btn->press_serial_cb.arg = arg; + btn->press_serial_cb.cb = cb; + btn->press_serial_cb.interval = interval_tick; + btn->press_serial_cb.pbtn = btn; + xTimerChangePeriod(btn->press_serial_cb.tmr, btn->serial_thres_sec*1000 / portTICK_PERIOD_MS, portMAX_DELAY); + return ESP_OK; +} + +esp_err_t iot_button_set_evt_cb(button_handle_t btn_handle, button_cb_type_t type, button_cb cb, void* arg) +{ + POINT_ASSERT(TAG, btn_handle, ESP_ERR_INVALID_ARG); + button_dev_t* btn = (button_dev_t*) btn_handle; + if (type == BUTTON_CB_PUSH) { + btn->tap_psh_cb.arg = arg; + btn->tap_psh_cb.cb = cb; + btn->tap_psh_cb.interval = BUTTON_GLITCH_FILTER_TIME_MS / portTICK_RATE_MS; + btn->tap_psh_cb.pbtn = btn; + xTimerChangePeriod(btn->tap_psh_cb.tmr, btn->tap_psh_cb.interval, portMAX_DELAY); + } else if (type == BUTTON_CB_RELEASE) { + btn->tap_rls_cb.arg = arg; + btn->tap_rls_cb.cb = cb; + btn->tap_rls_cb.interval = BUTTON_GLITCH_FILTER_TIME_MS / portTICK_RATE_MS; + btn->tap_rls_cb.pbtn = btn; + xTimerChangePeriod(btn->tap_rls_cb.tmr, btn->tap_psh_cb.interval, portMAX_DELAY); + } else if (type == BUTTON_CB_TAP) { + btn->tap_short_cb.arg = arg; + btn->tap_short_cb.cb = cb; + btn->tap_short_cb.interval = BUTTON_GLITCH_FILTER_TIME_MS / portTICK_RATE_MS; + btn->tap_short_cb.pbtn = btn; + } else if (type == BUTTON_CB_SERIAL) { + iot_button_set_serial_cb(btn_handle, 1, 1000 / portTICK_RATE_MS, cb, arg); + } + return ESP_OK; +} + +esp_err_t iot_button_add_on_press_cb(button_handle_t btn_handle, uint32_t press_sec, button_cb cb, void* arg) +{ + POINT_ASSERT(TAG, btn_handle, ESP_ERR_INVALID_ARG); + IOT_CHECK(TAG, press_sec != 0, ESP_ERR_INVALID_ARG); + button_dev_t* btn = (button_dev_t*) btn_handle; + button_cb_t* cb_new = (button_cb_t*) calloc(1, sizeof(button_cb_t)); + POINT_ASSERT(TAG, cb_new, ESP_FAIL); + cb_new->on_press = 1; + cb_new->arg = arg; + cb_new->cb = cb; + cb_new->interval = press_sec * 1000 / portTICK_PERIOD_MS; + cb_new->pbtn = btn; + cb_new->tmr = xTimerCreate("btn_press_tmr", cb_new->interval, pdFALSE, cb_new, button_press_cb); + cb_new->next_cb = btn->cb_head; + btn->cb_head = cb_new; + return ESP_OK; +} + +esp_err_t iot_button_add_on_release_cb(button_handle_t btn_handle, uint32_t press_sec, button_cb cb, void* arg) +{ + POINT_ASSERT(TAG, btn_handle, ESP_ERR_INVALID_ARG); + IOT_CHECK(TAG, press_sec != 0, ESP_ERR_INVALID_ARG); + button_dev_t* btn = (button_dev_t*) btn_handle; + button_cb_t* cb_new = (button_cb_t*) calloc(1, sizeof(button_cb_t)); + POINT_ASSERT(TAG, cb_new, ESP_FAIL); + btn->taskq_on = 1; + cb_new->arg = arg; + cb_new->cb = cb; + cb_new->interval = press_sec * 1000 / portTICK_PERIOD_MS; + cb_new->pbtn = btn; + cb_new->tmr = xTimerCreate("btn_press_tmr", cb_new->interval, pdFALSE, cb_new, button_press_cb); + cb_new->next_cb = btn->cb_head; + btn->cb_head = cb_new; + return ESP_OK; +} + diff --git a/components/button/button/button_obj.cpp b/components/button/button/button_obj.cpp new file mode 100644 index 0000000..8a1f287 --- /dev/null +++ b/components/button/button/button_obj.cpp @@ -0,0 +1,64 @@ +/* + * ESPRESSIF MIT License + * + * Copyright (c) 2017 + * + * Permission is hereby granted for use on ESPRESSIF SYSTEMS products only, in which case, + * it is free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include +#include +#include +#include + +CButton::CButton(gpio_num_t gpio_num, button_active_t active_level) +{ + m_btn_handle = iot_button_create(gpio_num, active_level); +} + +CButton::~CButton() +{ + iot_button_delete(m_btn_handle); + m_btn_handle = NULL; +} + +esp_err_t CButton::set_evt_cb(button_cb_type_t type, button_cb cb, void* arg) +{ + return iot_button_set_evt_cb(m_btn_handle, type, cb, arg); +} + +esp_err_t CButton::set_serial_cb(button_cb cb, void* arg, TickType_t interval_tick, uint32_t start_after_sec) +{ + return iot_button_set_serial_cb(m_btn_handle, start_after_sec, interval_tick, cb, arg); +} + +esp_err_t CButton::add_on_press_cb(uint32_t press_sec, button_cb cb, void* arg) +{ + return iot_button_add_on_press_cb(m_btn_handle, press_sec, cb, arg); +} + +esp_err_t CButton::add_on_release_cb(uint32_t press_sec, button_cb cb, void* arg) +{ + return iot_button_add_on_release_cb(m_btn_handle, press_sec, cb, arg); +} + +esp_err_t CButton::rm_cb(button_cb_type_t type) +{ + return iot_button_rm_cb(m_btn_handle, type); +} diff --git a/components/button/button/component.mk b/components/button/button/component.mk new file mode 100644 index 0000000..a98f634 --- /dev/null +++ b/components/button/button/component.mk @@ -0,0 +1,4 @@ +# +# "main" pseudo-component makefile. +# +# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.) diff --git a/components/button/button/include/iot_button.h b/components/button/button/include/iot_button.h new file mode 100644 index 0000000..3f5de51 --- /dev/null +++ b/components/button/button/include/iot_button.h @@ -0,0 +1,280 @@ +/* + * ESPRSSIF MIT License + * + * Copyright (c) 2015 + * + * Permission is hereby granted for use on ESPRESSIF SYSTEMS ESP8266 only, in which case, + * it is free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef _IOT_BUTTON_H_ +#define _IOT_BUTTON_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +typedef void (* button_cb)(void*); +typedef void* button_handle_t; + +typedef enum { + BUTTON_ACTIVE_HIGH = 1, /*!