diff --git a/examples/all-clusters-app/esp32/main/CMakeLists.txt b/examples/all-clusters-app/esp32/main/CMakeLists.txt index 0b4520dca3d90d..29430a67c079a6 100644 --- a/examples/all-clusters-app/esp32/main/CMakeLists.txt +++ b/examples/all-clusters-app/esp32/main/CMakeLists.txt @@ -220,4 +220,11 @@ target_link_options(${COMPONENT_LIB} "-T${PIGWEED_ROOT}/pw_tokenizer/pw_tokenizer_linker_sections.ld" ) +target_compile_options(${COMPONENT_LIB} PRIVATE + "-DPW_RPC_ATTRIBUTE_SERVICE=1" + "-DPW_RPC_BUTTON_SERVICE=1" + "-DPW_RPC_DEVICE_SERVICE=1" + "-DPW_RPC_LIGHTING_SERVICE=1" + "-DPW_RPC_LOCKING_SERVICE=1") + endif (CONFIG_ENABLE_PW_RPC) diff --git a/examples/all-clusters-app/esp32/main/Rpc.cpp b/examples/all-clusters-app/esp32/main/Rpc.cpp deleted file mode 100644 index 0de247455fcd61..00000000000000 --- a/examples/all-clusters-app/esp32/main/Rpc.cpp +++ /dev/null @@ -1,352 +0,0 @@ -/* - * - * Copyright (c) 2021 Project CHIP Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "sdkconfig.h" -#if CONFIG_ENABLE_PW_RPC -#include "PigweedLoggerMutex.h" -#include "RpcService.h" -#include "esp_log.h" -#include "freertos/FreeRTOS.h" -#include "freertos/event_groups.h" -#include "freertos/semphr.h" -#include "freertos/task.h" -#include "pw_log/log.h" -#include "pw_rpc/server.h" -#include "pw_sys_io/sys_io.h" -#include "rpc_services/Attributes.h" -#include "rpc_services/Button.h" -#include "rpc_services/Device.h" -#include "rpc_services/Lighting.h" -#include "rpc_services/Locking.h" - -#include - -#include "ScreenManager.h" -#include "esp_event.h" -#include "esp_log.h" -#include "esp_netif.h" -#include "esp_system.h" -#include "esp_wifi.h" -#include "freertos/FreeRTOS.h" -#include "freertos/semphr.h" -#include "freertos/timers.h" -#include "pw_containers/flat_map.h" -#include "pw_status/status.h" -#include "pw_status/try.h" -#include "pw_trace_tokenized/trace_rpc_service_nanopb.h" -#include "wifi_service/wifi_service.rpc.pb.h" -#include - -#include "WiFiProvisioning.h" - -#include "ESP32Utils.h" - -static const char * TAG = "RPC"; - -// Define trace time for pw_trace -PW_TRACE_TIME_TYPE pw_trace_GetTraceTime() -{ - return (PW_TRACE_TIME_TYPE) chip::System::SystemClock().GetMonotonicMicroseconds64().count(); -} -// Microsecond time source -size_t pw_trace_GetTraceTimeTicksPerSecond() -{ - return 1000000; -} - -namespace chip { -namespace rpc { -namespace { - -constexpr pw::containers::FlatMap kChannelToFreqMap({ { - { 1, 2412 }, { 2, 2417 }, { 3, 2422 }, { 4, 2427 }, { 5, 2432 }, { 6, 2437 }, { 7, 2442 }, { 8, 2447 }, - { 9, 2452 }, { 10, 2457 }, { 11, 2462 }, { 12, 2467 }, { 13, 2472 }, { 14, 2484 }, { 32, 5160 }, { 34, 5170 }, - { 36, 5180 }, { 38, 5190 }, { 40, 5200 }, { 42, 5210 }, { 44, 5220 }, { 46, 5230 }, { 48, 5240 }, { 50, 5250 }, - { 52, 5260 }, { 54, 5270 }, { 56, 5280 }, { 58, 5290 }, { 60, 5300 }, { 62, 5310 }, { 64, 5320 }, { 68, 5340 }, - { 96, 5480 }, { 100, 5500 }, { 102, 5510 }, { 104, 5520 }, { 106, 5530 }, { 108, 5540 }, { 110, 5550 }, { 112, 5560 }, - { 114, 5570 }, { 116, 5580 }, { 118, 5590 }, { 120, 5600 }, { 122, 5610 }, { 124, 5620 }, { 126, 5630 }, { 128, 5640 }, - { 132, 5660 }, { 134, 5670 }, { 136, 5680 }, { 138, 5690 }, { 140, 5700 }, { 142, 5710 }, { 144, 5720 }, { 149, 5745 }, - { 151, 5755 }, { 153, 5765 }, { 155, 5775 }, { 157, 5785 }, { 159, 5795 }, { 161, 5805 }, { 165, 5825 }, { 169, 5845 }, - { 173, 5865 }, { 183, 4915 }, { 184, 4920 }, { 185, 4925 }, { 187, 4935 }, { 188, 4940 }, { 189, 4945 }, { 192, 4960 }, - { 196, 4980 }, -} }); - -// These are potentially large objects for the scan results. -constexpr size_t kScanRecordsMax = sizeof(chip_rpc_ScanResults().aps) / sizeof(chip_rpc_ScanResult); -chip_rpc_ScanResults out_scan_records; -wifi_ap_record_t scan_records[kScanRecordsMax]; - -class Esp32Button final : public Button -{ -public: - pw::Status Event(ServerContext &, const chip_rpc_ButtonEvent & request, pw_protobuf_Empty & response) override - { -#if CONFIG_DEVICE_TYPE_M5STACK - if (request.pushed) - { - ScreenManager::ButtonPressed(1 + request.idx); - } - return pw::OkStatus(); -#else // CONFIG_DEVICE_TYPE_M5STACK - return pw::Status::Unimplemented(); -#endif // CONFIG_DEVICE_TYPE_M5STACK - } -}; - -class Esp32Device final : public Device -{ -public: - pw::Status Reboot(ServerContext & ctx, const pw_protobuf_Empty & request, pw_protobuf_Empty & response) override - { - mRebootTimer = xTimerCreateStatic("Reboot", kRebootTimerPeriodTicks, false, nullptr, RebootHandler, &mRebootTimerBuffer); - xTimerStart(mRebootTimer, 0); - return pw::OkStatus(); - } - -private: - static constexpr TickType_t kRebootTimerPeriodTicks = 1000; - TimerHandle_t mRebootTimer; - StaticTimer_t mRebootTimerBuffer; - - static void RebootHandler(TimerHandle_t) { esp_restart(); } -}; - -class Wifi final : public generated::Wifi -{ -public: - pw::Status GetChannel(ServerContext &, const pw_protobuf_Empty & request, chip_rpc_Channel & response) - { - uint8_t channel = 0; - wifi_second_chan_t second; - PW_TRY(EspToPwStatus(esp_wifi_get_channel(&channel, &second))); - response.channel = channel; - return pw::OkStatus(); - } - - pw::Status GetSsid(ServerContext &, const pw_protobuf_Empty & request, chip_rpc_Ssid & response) - { - wifi_config_t config; - PW_TRY(EspToPwStatus(esp_wifi_get_config(WIFI_IF_STA, &config))); - size_t size = std::min(sizeof(response.ssid.bytes), sizeof(config.sta.ssid)); - memcpy(response.ssid.bytes, config.sta.ssid, size); - response.ssid.size = size; - return pw::OkStatus(); - } - - pw::Status GetState(ServerContext &, const pw_protobuf_Empty & request, chip_rpc_State & response) - { - wifi_ap_record_t ap_info; - esp_err_t err = esp_wifi_sta_get_ap_info(&ap_info); - PW_TRY(EspToPwStatus(err)); - response.connected = (err != ESP_ERR_WIFI_NOT_CONNECT); - return pw::OkStatus(); - } - - pw::Status GetMacAddress(ServerContext &, const pw_protobuf_Empty & request, chip_rpc_MacAddress & response) - { - uint8_t mac[6]; - PW_TRY(EspToPwStatus(esp_wifi_get_mac(WIFI_IF_STA, mac))); - snprintf(response.mac_address, sizeof(response.mac_address), "%02x:%02x:%02x:%02x:%02x:%02x", mac[0], mac[1], mac[2], - mac[3], mac[4], mac[5]); - return pw::OkStatus(); - } - - pw::Status GetWiFiInterface(ServerContext &, const pw_protobuf_Empty & request, chip_rpc_WiFiInterface & response) - { - wifi_ap_record_t ap_info; - PW_TRY(EspToPwStatus(esp_wifi_sta_get_ap_info(&ap_info))); - snprintf(response.interface, sizeof(response.interface), "STA"); - return pw::OkStatus(); - } - - pw::Status GetIP4Address(ServerContext &, const pw_protobuf_Empty & request, chip_rpc_IP4Address & response) - { - esp_netif_ip_info_t ip_info; - PW_TRY(EspToPwStatus(esp_netif_get_ip_info(esp_netif_get_handle_from_ifkey("WIFI_STA_DEF"), &ip_info))); - snprintf(response.address, sizeof(response.address), IPSTR, IP2STR(&ip_info.ip)); - return pw::OkStatus(); - } - - pw::Status GetIP6Address(ServerContext &, const pw_protobuf_Empty & request, chip_rpc_IP6Address & response) - { - esp_ip6_addr_t ip6; - PW_TRY(EspToPwStatus(esp_netif_get_ip6_linklocal(esp_netif_get_handle_from_ifkey("WIFI_STA_DEF"), &ip6))); - snprintf(response.address, sizeof(response.address), IPV6STR, IPV62STR(ip6)); - return pw::OkStatus(); - } - - // NOTE: Currently this is blocking, it can be made non-blocking if needed - // but would require another worker thread to handle the scanning. - void StartScan(ServerContext &, const chip_rpc_ScanConfig & request, ServerWriter & writer) - { - wifi_scan_config_t scan_config; - if (request.ssid_count != 0) - { - scan_config.ssid = const_cast(reinterpret_cast(request.ssid[0].bytes)); - } - if (request.bssid_count != 0) - { - scan_config.bssid = const_cast(reinterpret_cast(request.bssid[0].bytes)); - } - scan_config.channel = request.channel; - scan_config.show_hidden = request.show_hidden; - scan_config.scan_type = static_cast(request.active_scan); - if (request.active_scan) - { - scan_config.scan_time.active.min = request.scan_time_min_ms; - scan_config.scan_time.active.max = request.scan_time_max_ms; - } - else - { - scan_config.scan_time.passive = request.scan_time_min_ms; - } - - auto err = esp_wifi_scan_start(&scan_config, true /* block */); - if (ESP_OK != err) - { - ESP_LOGI(TAG, "Error starting scan: %d", err); - return; - } - - // Output scan results - uint16_t num_scan_records = kScanRecordsMax; - err = esp_wifi_scan_get_ap_records(&num_scan_records, scan_records); - if (ESP_OK != err) - { - ESP_LOGI(TAG, "Error getting scanned APs: %d", err); - num_scan_records = 0; - } - ESP_LOGI(TAG, "%d", num_scan_records); - out_scan_records.aps_count = num_scan_records; - - for (size_t i = 0; i < num_scan_records; ++i) - { - out_scan_records.aps[i].ssid.size = std::min(sizeof(scan_records[i].ssid), sizeof(out_scan_records.aps[i].ssid.bytes)); - memcpy(out_scan_records.aps[i].ssid.bytes, scan_records[i].ssid, out_scan_records.aps[i].ssid.size); - out_scan_records.aps[i].bssid.size = - std::min(sizeof(scan_records[i].bssid), sizeof(out_scan_records.aps[i].bssid.bytes)); - memcpy(out_scan_records.aps[i].bssid.bytes, scan_records[i].bssid, out_scan_records.aps[i].bssid.size); - out_scan_records.aps[i].security_type = static_cast(scan_records[i].authmode); - out_scan_records.aps[i].channel = scan_records[i].primary; - auto found_channel = kChannelToFreqMap.find(scan_records[i].primary); - out_scan_records.aps[i].frequency = (found_channel ? found_channel->second : 0); - out_scan_records.aps[i].signal = scan_records[i].rssi; - } - writer.Write(out_scan_records); - writer.Finish(); - } - - pw::Status StopScan(ServerContext &, const pw_protobuf_Empty & request, pw_protobuf_Empty & response) - { - esp_wifi_scan_stop(); - return pw::OkStatus(); - } - - pw::Status Connect(ServerContext &, const chip_rpc_ConnectionData & request, chip_rpc_ConnectionResult & response) - { - char ssid[sizeof(wifi_config_t().sta.ssid)]; - char password[sizeof(wifi_config_t().sta.password)]; - size_t ssid_size = std::min(sizeof(ssid) - 1, static_cast(request.ssid.size)); - memcpy(ssid, request.ssid.bytes, ssid_size); - ssid[ssid_size] = '\0'; - size_t password_size = std::min(sizeof(password) - 1, static_cast(request.secret.size)); - memcpy(password, request.secret.bytes, password_size); - password[password_size] = '\0'; - return SetWiFiStationProvisioning(ssid, password) == CHIP_NO_ERROR ? pw::OkStatus() : pw::Status::Unknown(); - } - - pw::Status Disconnect(ServerContext &, const pw_protobuf_Empty & request, pw_protobuf_Empty & response) - { - chip::DeviceLayer::ConnectivityMgr().ClearWiFiStationProvision(); - chip::DeviceLayer::ConnectivityMgr().SetWiFiStationMode(chip::DeviceLayer::ConnectivityManager::kWiFiStationMode_Disabled); - return pw::OkStatus(); - } - -private: - static constexpr pw::Status EspToPwStatus(esp_err_t err) - { - switch (err) - { - case ESP_OK: - return pw::OkStatus(); - case ESP_ERR_WIFI_NOT_INIT: - return pw::Status::FailedPrecondition(); - case ESP_ERR_INVALID_ARG: - return pw::Status::InvalidArgument(); - case ESP_ERR_ESP_NETIF_INVALID_PARAMS: - return pw::Status::InvalidArgument(); - case ESP_ERR_WIFI_IF: - return pw::Status::NotFound(); - case ESP_ERR_WIFI_NOT_CONNECT: - return pw::Status::FailedPrecondition(); - case ESP_ERR_WIFI_NOT_STARTED: - return pw::Status::FailedPrecondition(); - case ESP_ERR_WIFI_CONN: - return pw::Status::Internal(); - case ESP_FAIL: - return pw::Status::Internal(); - default: - return pw::Status::Unknown(); - } - } -}; - -constexpr size_t kRpcStackSizeBytes = (8 * 1024); -constexpr uint8_t kRpcTaskPriority = 5; - -TaskHandle_t rpcTaskHandle; - -Attributes attributes_service; -Esp32Button button_service; -Esp32Device device_service; -Lighting lighting_service; -Locking locking_service; -Wifi wifi_service; -pw::trace::TraceService trace_service; - -void RegisterServices(pw::rpc::Server & server) -{ - server.RegisterService(attributes_service); - server.RegisterService(button_service); - server.RegisterService(device_service); - server.RegisterService(lighting_service); - server.RegisterService(locking_service); - server.RegisterService(wifi_service); - server.RegisterService(trace_service); - PW_TRACE_SET_ENABLED(true); -} - -void RunRpcService(void *) -{ - Start(RegisterServices, &logger_mutex); -} - -} // namespace - -void Init() -{ - PigweedLogger::init(); - - ESP_LOGI(TAG, "----------- esp32-rpc-service starting -----------"); - - xTaskCreate(RunRpcService, "RPC", kRpcStackSizeBytes / sizeof(StackType_t), nullptr, kRpcTaskPriority, &rpcTaskHandle); -} - -} // namespace rpc -} // namespace chip - -#endif // CONFIG_ENABLE_PW_RPC diff --git a/examples/common/pigweed/protos/device_service.proto b/examples/common/pigweed/protos/device_service.proto index fdca9667a1daf9..1e9f3281ffb99d 100644 --- a/examples/common/pigweed/protos/device_service.proto +++ b/examples/common/pigweed/protos/device_service.proto @@ -20,7 +20,7 @@ message DeviceInfo { message FabricInfo { uint32 fabric_id = 1; - uint32 node_id = 2; + uint64 node_id = 2; } message DeviceState { diff --git a/examples/lighting-app/efr32/BUILD.gn b/examples/lighting-app/efr32/BUILD.gn index dd93106fd3636b..b7d2e00c3b5ae1 100644 --- a/examples/lighting-app/efr32/BUILD.gn +++ b/examples/lighting-app/efr32/BUILD.gn @@ -22,7 +22,6 @@ import("${efr32_sdk_build_root}/efr32_executable.gni") import("${efr32_sdk_build_root}/efr32_sdk.gni") import("${chip_root}/examples/common/pigweed/pigweed_rpcs.gni") - if (chip_enable_pw_rpc) { import("//build_overrides/pigweed.gni") import("$dir_pw_build/target_types.gni") @@ -71,10 +70,7 @@ efr32_sdk("sdk") { ] if (chip_enable_pw_rpc) { - defines += [ - "HAL_VCOM_ENABLE=1", - "PW_RPC_ENABLED", - ] + defines += [ "HAL_VCOM_ENABLE=1" ] } } @@ -114,21 +110,24 @@ efr32_executable("lighting_app") { } if (chip_enable_pw_rpc) { - defines += [ "PW_RPC_ENABLED" ] + defines += [ + "PW_RPC_ENABLED", + "PW_RPC_ATTRIBUTE_SERVICE=1", + "PW_RPC_BUTTON_SERVICE=1", + "PW_RPC_DEVICE_SERVICE=1", + "PW_RPC_LIGHTING_SERVICE=1", + ] + sources += [ "${chip_root}/examples/common/pigweed/RpcService.cpp", "${chip_root}/examples/common/pigweed/efr32/PigweedLoggerMutex.cpp", "${examples_plat_dir}/PigweedLogger.cpp", - "src/Rpc.cpp", + "${examples_plat_dir}/Rpc.cpp", ] deps += [ - "$dir_pw_assert", - "$dir_pw_checksum", "$dir_pw_hdlc:rpc_channel_output", - "$dir_pw_stream", "$dir_pw_stream:sys_io_stream", - "$dir_pw_sys_io", "${chip_root}/config/efr32/lib/pw_rpc:pw_rpc", "${chip_root}/examples/common/pigweed:attributes_service.nanopb_rpc", "${chip_root}/examples/common/pigweed:button_service.nanopb_rpc", diff --git a/examples/lighting-app/efr32/src/Rpc.cpp b/examples/lighting-app/efr32/src/Rpc.cpp deleted file mode 100644 index d7969972530dc1..00000000000000 --- a/examples/lighting-app/efr32/src/Rpc.cpp +++ /dev/null @@ -1,92 +0,0 @@ -/* - * - * Copyright (c) 2021 Project CHIP Authors - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "AppTask.h" -#include "FreeRTOS.h" -#include "PigweedLoggerMutex.h" -#include "pigweed/RpcService.h" -#include "pigweed/rpc_services/Attributes.h" -#include "pigweed/rpc_services/Button.h" -#include "pigweed/rpc_services/Device.h" -#include "pigweed/rpc_services/Lighting.h" -#include "pw_sys_io_efr32/init.h" -#include "task.h" - -namespace chip { -namespace rpc { - -class Efr32Button final : public Button -{ -public: - pw::Status Event(ServerContext &, const chip_rpc_ButtonEvent & request, pw_protobuf_Empty & response) override - { - GetAppTask().ButtonEventHandler(SL_SIMPLE_BUTTON_INSTANCE(request.idx) /* PB 0 or PB 1 */, request.pushed); - return pw::OkStatus(); - } -}; - -class Efr32Device final : public Device -{ -public: - pw::Status Reboot(ServerContext & ctx, const pw_protobuf_Empty & request, pw_protobuf_Empty & response) override - { - NVIC_SystemReset(); - // WILL NOT RETURN - return pw::OkStatus(); - } -}; - -namespace { - -#define RPC_TASK_STACK_SIZE 4096 -#define RPC_TASK_PRIORITY 1 -static TaskHandle_t sRpcTaskHandle; -StaticTask_t sRpcTaskBuffer; -StackType_t sRpcTaskStack[RPC_TASK_STACK_SIZE]; - -Attributes attributes_service; -Efr32Button button_service; -Efr32Device device_service; -Lighting lighting_service; - -void RegisterServices(pw::rpc::Server & server) -{ - server.RegisterService(attributes_service); - server.RegisterService(button_service); - server.RegisterService(device_service); - server.RegisterService(lighting_service); -} - -} // namespace - -void RunRpcService(void *) -{ - Start(RegisterServices, &logger_mutex); -} - -void Init() -{ - pw_sys_io_Init(); - - // Start App task. - sRpcTaskHandle = xTaskCreateStatic(RunRpcService, "RPC_TASK", ArraySize(sRpcTaskStack), nullptr, RPC_TASK_PRIORITY, - sRpcTaskStack, &sRpcTaskBuffer); -} - -} // namespace rpc -} // namespace chip diff --git a/examples/lighting-app/nrfconnect/CMakeLists.txt b/examples/lighting-app/nrfconnect/CMakeLists.txt index 698c0bd65621de..6663936334d4a1 100644 --- a/examples/lighting-app/nrfconnect/CMakeLists.txt +++ b/examples/lighting-app/nrfconnect/CMakeLists.txt @@ -160,9 +160,9 @@ pw_proto_library(lighting_service ) target_sources(app PRIVATE - main/Rpc.cpp ../../common/pigweed/RpcService.cpp ../../common/pigweed/nrfconnect/PigweedLoggerMutex.cpp + ${NRFCONNECT_COMMON}/Rpc.cpp ${NRFCONNECT_COMMON}/util/PigweedLogger.cpp ) @@ -170,10 +170,17 @@ target_include_directories(app PRIVATE ${PIGWEED_ROOT}/pw_sys_io/public ${CHIP_ROOT}/src/lib/support ${CHIP_ROOT}/src/system + ${NRFCONNECT_COMMON} ../../common ../../common/pigweed ../../common/pigweed/nrfconnect) +target_compile_options(app PRIVATE + "-DPW_RPC_ATTRIBUTE_SERVICE=1" + "-DPW_RPC_BUTTON_SERVICE=1" + "-DPW_RPC_DEVICE_SERVICE=1" + "-DPW_RPC_LIGHTING_SERVICE=1") + target_link_libraries(app PRIVATE attributes_service.nanopb_rpc button_service.nanopb_rpc diff --git a/examples/lighting-app/nrfconnect/main/Rpc.cpp b/examples/lighting-app/nrfconnect/main/Rpc.cpp deleted file mode 100644 index 66100e38593f87..00000000000000 --- a/examples/lighting-app/nrfconnect/main/Rpc.cpp +++ /dev/null @@ -1,102 +0,0 @@ -/* - * - * Copyright (c) 2020 Project CHIP Authors - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "AppTask.h" -#include "PigweedLoggerMutex.h" -#include "pigweed/RpcService.h" -#include "pw_sys_io_nrfconnect/init.h" -#include "rpc_services/Attributes.h" -#include "rpc_services/Button.h" -#include "rpc_services/Device.h" -#include "rpc_services/Lighting.h" - -#include - -LOG_MODULE_DECLARE(app); - -namespace chip { -namespace rpc { - -namespace { - -void reboot_timer_handler(struct k_timer * dummy) -{ - NVIC_SystemReset(); -} -K_TIMER_DEFINE(reboot_timer, reboot_timer_handler, NULL); - -} // namespace - -class NrfButton final : public Button -{ -public: - pw::Status Event(ServerContext &, const chip_rpc_ButtonEvent & request, pw_protobuf_Empty & response) override - { - GetAppTask().ButtonEventHandler(request.pushed << request.idx /* button_state */, 1 << request.idx /* has_changed */); - return pw::OkStatus(); - } -}; - -class NrfDevice final : public Device -{ -public: - pw::Status Reboot(ServerContext & ctx, const pw_protobuf_Empty & request, pw_protobuf_Empty & response) override - { - k_timer_start(&reboot_timer, K_SECONDS(1), K_FOREVER); - return pw::OkStatus(); - } -}; - -namespace { - -constexpr size_t kRpcTaskSize = 4096; -constexpr int kRpcPriority = 5; - -K_THREAD_STACK_DEFINE(rpc_stack_area, kRpcTaskSize); -struct k_thread rpc_thread_data; - -Attributes attributes_service; -NrfButton button_service; -NrfDevice device_service; -Lighting lighting_service; - -void RegisterServices(pw::rpc::Server & server) -{ - server.RegisterService(attributes_service); - server.RegisterService(button_service); - server.RegisterService(device_service); - server.RegisterService(lighting_service); -} - -} // namespace - -k_tid_t Init() -{ - pw_sys_io_Init(); - k_tid_t tid = k_thread_create(&rpc_thread_data, rpc_stack_area, K_THREAD_STACK_SIZEOF(rpc_stack_area), RunRpcService, NULL, - NULL, NULL, kRpcPriority, 0, K_NO_WAIT); - return tid; -} - -void RunRpcService(void *, void *, void *) -{ - Start(RegisterServices, &logger_mutex); -} - -} // namespace rpc -} // namespace chip diff --git a/examples/lighting-app/nrfconnect/main/include/AppTask.h b/examples/lighting-app/nrfconnect/main/include/AppTask.h index 83f54267a555b2..12ff22ba963ca3 100644 --- a/examples/lighting-app/nrfconnect/main/include/AppTask.h +++ b/examples/lighting-app/nrfconnect/main/include/AppTask.h @@ -21,10 +21,13 @@ #include "AppEvent.h" #include "LEDWidget.h" #include "LightingManager.h" -#include "Rpc.h" #include +#ifdef CONFIG_CHIP_PW_RPC +#include "Rpc.h" +#endif + #ifdef CONFIG_MCUMGR_SMP_BT #include "DFUOverSMP.h" #endif @@ -43,9 +46,11 @@ class AppTask void UpdateClusterState(); private: +#ifdef CONFIG_CHIP_PW_RPC friend class chip::rpc::NrfButton; - friend AppTask & GetAppTask(void); +#endif + friend AppTask & GetAppTask(void); int Init(); static void ActionInitiated(LightingManager::Action_t aAction, int32_t aActor); diff --git a/examples/lighting-app/nrfconnect/main/main.cpp b/examples/lighting-app/nrfconnect/main/main.cpp index a3e5944651b9cf..1d2ae1530b813d 100644 --- a/examples/lighting-app/nrfconnect/main/main.cpp +++ b/examples/lighting-app/nrfconnect/main/main.cpp @@ -17,7 +17,6 @@ */ #include "AppTask.h" -#include "Rpc.h" #include #include @@ -25,6 +24,10 @@ #include +#ifdef CONFIG_CHIP_PW_RPC +#include "Rpc.h" +#endif + #ifdef CONFIG_USB #include #endif diff --git a/examples/lock-app/esp32/main/CMakeLists.txt b/examples/lock-app/esp32/main/CMakeLists.txt index 75b0d406fa412b..ce2c2116ca6e59 100644 --- a/examples/lock-app/esp32/main/CMakeLists.txt +++ b/examples/lock-app/esp32/main/CMakeLists.txt @@ -98,6 +98,7 @@ pw_proto_library(locking_service ) target_link_libraries(${COMPONENT_LIB} PUBLIC + attributes_service.nanopb_rpc device_service.nanopb_rpc button_service.nanopb_rpc locking_service.nanopb_rpc @@ -107,6 +108,12 @@ target_link_libraries(${COMPONENT_LIB} PUBLIC pw_rpc.server ) +target_compile_options(${COMPONENT_LIB} PRIVATE + "-DPW_RPC_ATTRIBUTE_SERVICE=2" + "-DPW_RPC_BUTTON_SERVICE=1" + "-DPW_RPC_DEVICE_SERVICE=1" + "-DPW_RPC_LOCKING_SERVICE=1") + else (CONFIG_ENABLE_PW_RPC) idf_component_register(PRIV_INCLUDE_DIRS "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/zzz_generated/lock-app/" diff --git a/examples/lock-app/esp32/main/Rpc.cpp b/examples/lock-app/esp32/main/Rpc.cpp deleted file mode 100644 index 0aea9244960482..00000000000000 --- a/examples/lock-app/esp32/main/Rpc.cpp +++ /dev/null @@ -1,99 +0,0 @@ -/* - * - * Copyright (c) 2020 Project CHIP Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "sdkconfig.h" -#if CONFIG_ENABLE_PW_RPC -#include "AppTask.h" -#include "PigweedLoggerMutex.h" -#include "RpcService.h" -#include "esp_log.h" -#include "esp_system.h" -#include "freertos/FreeRTOS.h" -#include "freertos/task.h" -#include "pw_rpc/server.h" -#include "pw_sys_io/sys_io.h" -#include "rpc_services/Button.h" -#include "rpc_services/Device.h" -#include "rpc_services/Locking.h" - -#include - -const char * TAG = "RPC"; - -using chip::DeviceLayer::ConfigurationMgr; - -static bool uartInitialised; - -namespace chip { -namespace rpc { - -class Esp32Button final : public Button -{ -public: - pw::Status Event(ServerContext &, const chip_rpc_ButtonEvent & request, pw_protobuf_Empty & response) override - { - GetAppTask().ButtonEventHandler(request.idx, request.pushed); - return pw::OkStatus(); - } -}; - -class Esp32Device final : public Device -{ -public: - pw::Status Reboot(ServerContext & ctx, const pw_protobuf_Empty & request, pw_protobuf_Empty & response) override - { - esp_restart(); - // WILL NOT RETURN - return pw::OkStatus(); - } -}; - -constexpr size_t kRpcStackSizeBytes = (4 * 1024); -constexpr uint8_t kRpcTaskPriority = 5; - -TaskHandle_t rpcTaskHandle; - -Esp32Button button_service; -Locking locking_service; -Device device_service; - -void RegisterServices(pw::rpc::Server & server) -{ - server.RegisterService(locking_service); - server.RegisterService(button_service); - server.RegisterService(device_service); -} - -void RunRpcService(void *) -{ - Start(RegisterServices, &logger_mutex); -} - -void Init() -{ - PigweedLogger::init(); - uartInitialised = true; - - ESP_LOGI(TAG, "----------- esp32-rpc-service starting -----------"); - - xTaskCreate(RunRpcService, "RPC", kRpcStackSizeBytes / sizeof(StackType_t), nullptr, kRpcTaskPriority, &rpcTaskHandle); -} - -} // namespace rpc -} // namespace chip - -#endif diff --git a/examples/platform/efr32/Rpc.cpp b/examples/platform/efr32/Rpc.cpp new file mode 100644 index 00000000000000..89afffe420b0b1 --- /dev/null +++ b/examples/platform/efr32/Rpc.cpp @@ -0,0 +1,149 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "AppTask.h" +#include "FreeRTOS.h" +#include "PigweedLoggerMutex.h" +#include "pigweed/RpcService.h" +#include "pw_sys_io_efr32/init.h" +#include "task.h" + +#if defined(PW_RPC_ATTRIBUTE_SERVICE) && PW_RPC_ATTRIBUTE_SERVICE +#include "pigweed/rpc_services/Attributes.h" +#endif // defined(PW_RPC_ATTRIBUTE_SERVICE) && PW_RPC_ATTRIBUTE_SERVICE + +#if defined(PW_RPC_BUTTON_SERVICE) && PW_RPC_BUTTON_SERVICE +#include "pigweed/rpc_services/Button.h" +#endif // defined(PW_RPC_BUTTON_SERVICE) && PW_RPC_BUTTON_SERVICE + +#if defined(PW_RPC_DEVICE_SERVICE) && PW_RPC_DEVICE_SERVICE +#include "pigweed/rpc_services/Device.h" +#endif // defined(PW_RPC_DEVICE_SERVICE) && PW_RPC_DEVICE_SERVICE + +#if defined(PW_RPC_LIGHTING_SERVICE) && PW_RPC_LIGHTING_SERVICE +#include "pigweed/rpc_services/Lighting.h" +#endif // defined(PW_RPC_LIGHTING_SERVICE) && PW_RPC_LIGHTING_SERVICE + +#if defined(PW_RPC_LOCKING_SERVICE) && PW_RPC_LOCKING_SERVICE +#include "pigweed/rpc_services/Locking.h" +#endif // defined(PW_RPC_LOCKING_SERVICE) && PW_RPC_LOCKING_SERVICE + +namespace chip { +namespace rpc { + +#if defined(PW_RPC_BUTTON_SERVICE) && PW_RPC_BUTTON_SERVICE +class Efr32Button final : public Button +{ +public: + pw::Status Event(ServerContext &, const chip_rpc_ButtonEvent & request, pw_protobuf_Empty & response) override + { + GetAppTask().ButtonEventHandler(SL_SIMPLE_BUTTON_INSTANCE(request.idx) /* PB 0 or PB 1 */, request.pushed); + return pw::OkStatus(); + } +}; +#endif // defined(PW_RPC_BUTTON_SERVICE) && PW_RPC_BUTTON_SERVICE + +#if defined(PW_RPC_DEVICE_SERVICE) && PW_RPC_DEVICE_SERVICE +class Efr32Device final : public Device +{ +public: + pw::Status Reboot(ServerContext & ctx, const pw_protobuf_Empty & request, pw_protobuf_Empty & response) override + { + mRebootTimer = xTimerCreateStatic("Reboot", kRebootTimerPeriodTicks, false, nullptr, RebootHandler, &mRebootTimerBuffer); + xTimerStart(mRebootTimer, 0); + return pw::OkStatus(); + } + +private: + static constexpr TickType_t kRebootTimerPeriodTicks = 1000; + TimerHandle_t mRebootTimer; + StaticTimer_t mRebootTimerBuffer; + + static void RebootHandler(TimerHandle_t) { NVIC_SystemReset(); } +}; +#endif // defined(PW_RPC_DEVICE_SERVICE) && PW_RPC_DEVICE_SERVICE + +namespace { + +#define RPC_TASK_STACK_SIZE 4096 +#define RPC_TASK_PRIORITY 1 +static TaskHandle_t sRpcTaskHandle; +StaticTask_t sRpcTaskBuffer; +StackType_t sRpcTaskStack[RPC_TASK_STACK_SIZE]; + +#if defined(PW_RPC_ATTRIBUTE_SERVICE) && PW_RPC_ATTRIBUTE_SERVICE +Attributes attributes_service; +#endif // defined(PW_RPC_ATTRIBUTE_SERVICE) && PW_RPC_ATTRIBUTE_SERVICE + +#if defined(PW_RPC_BUTTON_SERVICE) && PW_RPC_BUTTON_SERVICE +Efr32Button button_service; +#endif // defined(PW_RPC_BUTTON_SERVICE) && PW_RPC_BUTTON_SERVICE + +#if defined(PW_RPC_DEVICE_SERVICE) && PW_RPC_DEVICE_SERVICE +Efr32Device device_service; +#endif // defined(PW_RPC_DEVICE_SERVICE) && PW_RPC_DEVICE_SERVICE + +#if defined(PW_RPC_LIGHTING_SERVICE) && PW_RPC_LIGHTING_SERVICE +Lighting lighting_service; +#endif // defined(PW_RPC_LIGHTING_SERVICE) && PW_RPC_LIGHTING_SERVICE + +#if defined(PW_RPC_LOCKING_SERVICE) && PW_RPC_LOCKING_SERVICE +Locking locking; +#endif // defined(PW_RPC_LOCKING_SERVICE) && PW_RPC_LOCKING_SERVICE + +void RegisterServices(pw::rpc::Server & server) +{ +#if defined(PW_RPC_ATTRIBUTE_SERVICE) && PW_RPC_ATTRIBUTE_SERVICE + server.RegisterService(attributes_service); +#endif // defined(PW_RPC_ATTRIBUTE_SERVICE) && PW_RPC_ATTRIBUTE_SERVICE + +#if defined(PW_RPC_BUTTON_SERVICE) && PW_RPC_BUTTON_SERVICE + server.RegisterService(button_service); +#endif // defined(PW_RPC_BUTTON_SERVICE) && PW_RPC_BUTTON_SERVICE + +#if defined(PW_RPC_DEVICE_SERVICE) && PW_RPC_DEVICE_SERVICE + server.RegisterService(device_service); +#endif // defined(PW_RPC_DEVICE_SERVICE) && PW_RPC_DEVICE_SERVICE + +#if defined(PW_RPC_LIGHTING_SERVICE) && PW_RPC_LIGHTING_SERVICE + server.RegisterService(lighting_service); +#endif // defined(PW_RPC_LIGHTING_SERVICE) && PW_RPC_LIGHTING_SERVICE + +#if defined(PW_RPC_LOCKING_SERVICE) && PW_RPC_LOCKING_SERVICE + server.RegisterService(locking); +#endif // defined(PW_RPC_LOCKING_SERVICE) && PW_RPC_LOCKING_SERVICE +} + +} // namespace + +void RunRpcService(void *) +{ + Start(RegisterServices, &logger_mutex); +} + +void Init() +{ + pw_sys_io_Init(); + + // Start App task. + sRpcTaskHandle = xTaskCreateStatic(RunRpcService, "RPC_TASK", ArraySize(sRpcTaskStack), nullptr, RPC_TASK_PRIORITY, + sRpcTaskStack, &sRpcTaskBuffer); +} + +} // namespace rpc +} // namespace chip diff --git a/examples/lighting-app/efr32/include/Rpc.h b/examples/platform/efr32/Rpc.h similarity index 100% rename from examples/lighting-app/efr32/include/Rpc.h rename to examples/platform/efr32/Rpc.h diff --git a/examples/platform/esp32/Rpc.cpp b/examples/platform/esp32/Rpc.cpp new file mode 100644 index 00000000000000..ccc877ecb46fdf --- /dev/null +++ b/examples/platform/esp32/Rpc.cpp @@ -0,0 +1,167 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "sdkconfig.h" + +#if CONFIG_ENABLE_PW_RPC +#include "PigweedLoggerMutex.h" +#include "RpcService.h" +#include "esp_log.h" +#include "freertos/FreeRTOS.h" +#include "freertos/event_groups.h" +#include "freertos/semphr.h" +#include "freertos/task.h" +#include "pw_log/log.h" +#include "pw_rpc/server.h" +#include "pw_sys_io/sys_io.h" +#include "support/CodeUtils.h" + +#if defined(PW_RPC_ATTRIBUTE_SERVICE) && PW_RPC_ATTRIBUTE_SERVICE +#include "pigweed/rpc_services/Attributes.h" +#endif // defined(PW_RPC_ATTRIBUTE_SERVICE) && PW_RPC_ATTRIBUTE_SERVICE + +#if defined(PW_RPC_BUTTON_SERVICE) && PW_RPC_BUTTON_SERVICE +#include "ScreenManager.h" +#include "pigweed/rpc_services/Button.h" +#endif // defined(PW_RPC_BUTTON_SERVICE) && PW_RPC_BUTTON_SERVICE + +#if defined(PW_RPC_DEVICE_SERVICE) && PW_RPC_DEVICE_SERVICE +#include "pigweed/rpc_services/Device.h" +#endif // defined(PW_RPC_DEVICE_SERVICE) && PW_RPC_DEVICE_SERVICE + +#if defined(PW_RPC_LIGHTING_SERVICE) && PW_RPC_LIGHTING_SERVICE +#include "pigweed/rpc_services/Lighting.h" +#endif // defined(PW_RPC_LIGHTING_SERVICE) && PW_RPC_LIGHTING_SERVICE + +#if defined(PW_RPC_LOCKING_SERVICE) && PW_RPC_LOCKING_SERVICE +#include "pigweed/rpc_services/Locking.h" +#endif // defined(PW_RPC_LOCKING_SERVICE) && PW_RPC_LOCKING_SERVICE + +namespace chip { +namespace rpc { + +#if defined(PW_RPC_BUTTON_SERVICE) && PW_RPC_BUTTON_SERVICE +class Esp32Button final : public Button +{ +public: + pw::Status Event(ServerContext &, const chip_rpc_ButtonEvent & request, pw_protobuf_Empty & response) override + { +#if CONFIG_DEVICE_TYPE_M5STACK + if (request.pushed) + { + ScreenManager::ButtonPressed(1 + request.idx); + } + return pw::OkStatus(); +#else // CONFIG_DEVICE_TYPE_M5STACK + return pw::Status::Unimplemented(); +#endif // CONFIG_DEVICE_TYPE_M5STACK + } +}; +#endif // defined(PW_RPC_BUTTON_SERVICE) && PW_RPC_BUTTON_SERVICE + +#if defined(PW_RPC_DEVICE_SERVICE) && PW_RPC_DEVICE_SERVICE +class Esp32Device final : public Device +{ +public: + pw::Status Reboot(ServerContext & ctx, const pw_protobuf_Empty & request, pw_protobuf_Empty & response) override + { + mRebootTimer = xTimerCreateStatic("Reboot", kRebootTimerPeriodTicks, false, nullptr, RebootHandler, &mRebootTimerBuffer); + xTimerStart(mRebootTimer, 0); + return pw::OkStatus(); + } + +private: + static constexpr TickType_t kRebootTimerPeriodTicks = 1000; + TimerHandle_t mRebootTimer; + StaticTimer_t mRebootTimerBuffer; + + static void RebootHandler(TimerHandle_t) { esp_restart(); } +}; +#endif // defined(PW_RPC_DEVICE_SERVICE) && PW_RPC_DEVICE_SERVICE + +namespace { + +#define RPC_TASK_STACK_SIZE (8 * 1024) +#define RPC_TASK_PRIORITY 5 +static TaskHandle_t sRpcTaskHandle; +StaticTask_t sRpcTaskBuffer; +StackType_t sRpcTaskStack[RPC_TASK_STACK_SIZE]; + +#if defined(PW_RPC_ATTRIBUTE_SERVICE) && PW_RPC_ATTRIBUTE_SERVICE +Attributes attributes_service; +#endif // defined(PW_RPC_ATTRIBUTE_SERVICE) && PW_RPC_ATTRIBUTE_SERVICE + +#if defined(PW_RPC_BUTTON_SERVICE) && PW_RPC_BUTTON_SERVICE +Esp32Button button_service; +#endif // defined(PW_RPC_BUTTON_SERVICE) && PW_RPC_BUTTON_SERVICE + +#if defined(PW_RPC_DEVICE_SERVICE) && PW_RPC_DEVICE_SERVICE +Esp32Device device_service; +#endif // defined(PW_RPC_DEVICE_SERVICE) && PW_RPC_DEVICE_SERVICE + +#if defined(PW_RPC_LIGHTING_SERVICE) && PW_RPC_LIGHTING_SERVICE +Lighting lighting_service; +#endif // defined(PW_RPC_LIGHTING_SERVICE) && PW_RPC_LIGHTING_SERVICE + +#if defined(PW_RPC_LOCKING_SERVICE) && PW_RPC_LOCKING_SERVICE +Locking locking; +#endif // defined(PW_RPC_LOCKING_SERVICE) && PW_RPC_LOCKING_SERVICE + +void RegisterServices(pw::rpc::Server & server) +{ +#if defined(PW_RPC_ATTRIBUTE_SERVICE) && PW_RPC_ATTRIBUTE_SERVICE + server.RegisterService(attributes_service); +#endif // defined(PW_RPC_ATTRIBUTE_SERVICE) && PW_RPC_ATTRIBUTE_SERVICE + +#if defined(PW_RPC_BUTTON_SERVICE) && PW_RPC_BUTTON_SERVICE + server.RegisterService(button_service); +#endif // defined(PW_RPC_BUTTON_SERVICE) && PW_RPC_BUTTON_SERVICE + +#if defined(PW_RPC_DEVICE_SERVICE) && PW_RPC_DEVICE_SERVICE + server.RegisterService(device_service); +#endif // defined(PW_RPC_DEVICE_SERVICE) && PW_RPC_DEVICE_SERVICE + +#if defined(PW_RPC_LIGHTING_SERVICE) && PW_RPC_LIGHTING_SERVICE + server.RegisterService(lighting_service); +#endif // defined(PW_RPC_LIGHTING_SERVICE) && PW_RPC_LIGHTING_SERVICE + +#if defined(PW_RPC_LOCKING_SERVICE) && PW_RPC_LOCKING_SERVICE + server.RegisterService(locking); +#endif // defined(PW_RPC_LOCKING_SERVICE) && PW_RPC_LOCKING_SERVICE +} + +} // namespace + +void RunRpcService(void *) +{ + Start(RegisterServices, &logger_mutex); +} + +void Init() +{ + PigweedLogger::init(); + + // Start App task. + sRpcTaskHandle = xTaskCreateStatic(RunRpcService, "RPC_TASK", ArraySize(sRpcTaskStack), nullptr, RPC_TASK_PRIORITY, + sRpcTaskStack, &sRpcTaskBuffer); +} + +} // namespace rpc +} // namespace chip + +#endif // CONFIG_ENABLE_PW_RPC diff --git a/examples/all-clusters-app/esp32/main/include/Rpc.h b/examples/platform/esp32/Rpc.h similarity index 100% rename from examples/all-clusters-app/esp32/main/include/Rpc.h rename to examples/platform/esp32/Rpc.h diff --git a/examples/platform/nrfconnect/Rpc.cpp b/examples/platform/nrfconnect/Rpc.cpp new file mode 100644 index 00000000000000..44cfb0e82eb01e --- /dev/null +++ b/examples/platform/nrfconnect/Rpc.cpp @@ -0,0 +1,152 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "AppTask.h" +#include "PigweedLoggerMutex.h" +#include "pigweed/RpcService.h" +#include "pw_sys_io_nrfconnect/init.h" + +#include + +LOG_MODULE_DECLARE(app); + +#if defined(PW_RPC_ATTRIBUTE_SERVICE) && PW_RPC_ATTRIBUTE_SERVICE +#include "pigweed/rpc_services/Attributes.h" +#endif // defined(PW_RPC_ATTRIBUTE_SERVICE) && PW_RPC_ATTRIBUTE_SERVICE + +#if defined(PW_RPC_BUTTON_SERVICE) && PW_RPC_BUTTON_SERVICE +#include "pigweed/rpc_services/Button.h" +#endif // defined(PW_RPC_BUTTON_SERVICE) && PW_RPC_BUTTON_SERVICE + +#if defined(PW_RPC_DEVICE_SERVICE) && PW_RPC_DEVICE_SERVICE +#include "pigweed/rpc_services/Device.h" +#endif // defined(PW_RPC_DEVICE_SERVICE) && PW_RPC_DEVICE_SERVICE + +#if defined(PW_RPC_LIGHTING_SERVICE) && PW_RPC_LIGHTING_SERVICE +#include "pigweed/rpc_services/Lighting.h" +#endif // defined(PW_RPC_LIGHTING_SERVICE) && PW_RPC_LIGHTING_SERVICE + +#if defined(PW_RPC_LOCKING_SERVICE) && PW_RPC_LOCKING_SERVICE +#include "pigweed/rpc_services/Locking.h" +#endif // defined(PW_RPC_LOCKING_SERVICE) && PW_RPC_LOCKING_SERVICE + +namespace chip { +namespace rpc { + +#if defined(PW_RPC_DEVICE_SERVICE) && PW_RPC_DEVICE_SERVICE +namespace { + +void reboot_timer_handler(struct k_timer * dummy) +{ + NVIC_SystemReset(); +} +K_TIMER_DEFINE(reboot_timer, reboot_timer_handler, NULL); + +} // namespace + +class NrfDevice final : public Device +{ +public: + pw::Status Reboot(ServerContext & ctx, const pw_protobuf_Empty & request, pw_protobuf_Empty & response) override + { + k_timer_start(&reboot_timer, K_SECONDS(1), K_FOREVER); + return pw::OkStatus(); + } +}; +#endif // defined(PW_RPC_DEVICE_SERVICE) && PW_RPC_DEVICE_SERVICE + +#if defined(PW_RPC_BUTTON_SERVICE) && PW_RPC_BUTTON_SERVICE +class NrfButton final : public Button +{ +public: + pw::Status Event(ServerContext &, const chip_rpc_ButtonEvent & request, pw_protobuf_Empty & response) override + { + GetAppTask().ButtonEventHandler(request.pushed << request.idx /* button_state */, 1 << request.idx /* has_changed */); + return pw::OkStatus(); + } +}; +#endif // defined(PW_RPC_BUTTON_SERVICE) && PW_RPC_BUTTON_SERVICE + +namespace { + +constexpr size_t kRpcTaskSize = 4096; +constexpr int kRpcPriority = 5; + +K_THREAD_STACK_DEFINE(rpc_stack_area, kRpcTaskSize); +struct k_thread rpc_thread_data; + +#if defined(PW_RPC_ATTRIBUTE_SERVICE) && PW_RPC_ATTRIBUTE_SERVICE +Attributes attributes_service; +#endif // defined(PW_RPC_ATTRIBUTE_SERVICE) && PW_RPC_ATTRIBUTE_SERVICE + +#if defined(PW_RPC_BUTTON_SERVICE) && PW_RPC_BUTTON_SERVICE +NrfButton button_service; +#endif // defined(PW_RPC_BUTTON_SERVICE) && PW_RPC_BUTTON_SERVICE + +#if defined(PW_RPC_DEVICE_SERVICE) && PW_RPC_DEVICE_SERVICE +NrfDevice device_service; +#endif // defined(PW_RPC_DEVICE_SERVICE) && PW_RPC_DEVICE_SERVICE + +#if defined(PW_RPC_LIGHTING_SERVICE) && PW_RPC_LIGHTING_SERVICE +Lighting lighting_service; +#endif // defined(PW_RPC_LIGHTING_SERVICE) && PW_RPC_LIGHTING_SERVICE + +#if defined(PW_RPC_LOCKING_SERVICE) && PW_RPC_LOCKING_SERVICE +Locking locking; +#endif // defined(PW_RPC_LOCKING_SERVICE) && PW_RPC_LOCKING_SERVICE + +void RegisterServices(pw::rpc::Server & server) +{ +#if defined(PW_RPC_ATTRIBUTE_SERVICE) && PW_RPC_ATTRIBUTE_SERVICE + server.RegisterService(attributes_service); +#endif // defined(PW_RPC_ATTRIBUTE_SERVICE) && PW_RPC_ATTRIBUTE_SERVICE + +#if defined(PW_RPC_BUTTON_SERVICE) && PW_RPC_BUTTON_SERVICE + server.RegisterService(button_service); +#endif // defined(PW_RPC_BUTTON_SERVICE) && PW_RPC_BUTTON_SERVICE + +#if defined(PW_RPC_DEVICE_SERVICE) && PW_RPC_DEVICE_SERVICE + server.RegisterService(device_service); +#endif // defined(PW_RPC_DEVICE_SERVICE) && PW_RPC_DEVICE_SERVICE + +#if defined(PW_RPC_LIGHTING_SERVICE) && PW_RPC_LIGHTING_SERVICE + server.RegisterService(lighting_service); +#endif // defined(PW_RPC_LIGHTING_SERVICE) && PW_RPC_LIGHTING_SERVICE + +#if defined(PW_RPC_LOCKING_SERVICE) && PW_RPC_LOCKING_SERVICE + server.RegisterService(locking); +#endif // defined(PW_RPC_LOCKING_SERVICE) && PW_RPC_LOCKING_SERVICE +} + +} // namespace + +void RunRpcService(void *, void *, void *) +{ + Start(RegisterServices, &logger_mutex); +} + +k_tid_t Init() +{ + pw_sys_io_Init(); + k_tid_t tid = k_thread_create(&rpc_thread_data, rpc_stack_area, K_THREAD_STACK_SIZEOF(rpc_stack_area), RunRpcService, NULL, + NULL, NULL, kRpcPriority, 0, K_NO_WAIT); + return tid; +} + +} // namespace rpc +} // namespace chip diff --git a/examples/lighting-app/nrfconnect/main/include/Rpc.h b/examples/platform/nrfconnect/Rpc.h similarity index 100% rename from examples/lighting-app/nrfconnect/main/include/Rpc.h rename to examples/platform/nrfconnect/Rpc.h