Skip to content

Commit

Permalink
RPC: Refactor to share common code between examples
Browse files Browse the repository at this point in the history
Move the common RPC services into a common location and have
default virtual implementations which use the ember API.

Applications can customize the behaviour when neccessary by
overriding the methods.

Also cleanup the lighting proto to better match the spec.
  • Loading branch information
Rob Oliver committed Sep 13, 2021
1 parent 92d3a28 commit 8bdddd7
Show file tree
Hide file tree
Showing 28 changed files with 449 additions and 302 deletions.
3 changes: 3 additions & 0 deletions examples/all-clusters-app/esp32/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -285,3 +285,6 @@ From within the console you can then invoke rpcs:

rpcs.chip.rpc.Wifi.Connect(ssid=b"MySSID", secret=b"MyPASSWORD")
rpcs.chip.rpc.Wifi.GetIP6Address()

rpcs.chip.rpc.Lighting.Get()
rpcs.chip.rpc.Lighting.Set(on=True, level=128, color=protos.chip.rpc.LightingColor(hue=5, saturation=5))
13 changes: 13 additions & 0 deletions examples/all-clusters-app/esp32/main/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ if (CONFIG_ENABLE_PW_RPC)
# Append additional directories for RPC build
set(PRIV_INCLUDE_DIRS_LIST "${PRIV_INCLUDE_DIRS_LIST}"
"${CMAKE_SOURCE_DIR}/../../platform/esp32/pw_sys_io/public"
"${CMAKE_SOURCE_DIR}/../../common"
"${CMAKE_SOURCE_DIR}/../../common/pigweed"
"${CMAKE_SOURCE_DIR}/../../common/pigweed/esp32"
"${CMAKE_SOURCE_DIR}/../../../src/lib/support"
Expand Down Expand Up @@ -149,6 +150,17 @@ pw_proto_library(device_service
pw_protobuf.common_protos
)

pw_proto_library(lighting_service
SOURCES
${CHIP_ROOT}/examples/common/pigweed/protos/lighting_service.proto
PREFIX
lighting_service
STRIP_PREFIX
${CHIP_ROOT}/examples/common/pigweed/protos
DEPS
pw_protobuf.common_protos
)

pw_proto_library(wifi_service
SOURCES
${CHIP_ROOT}/examples/ipv6only-app/common/wifi_service/wifi_service.proto
Expand All @@ -165,6 +177,7 @@ pw_proto_library(wifi_service
target_link_libraries(${COMPONENT_LIB} PUBLIC
button_service.nanopb_rpc
device_service.nanopb_rpc
lighting_service.nanopb_rpc
wifi_service.nanopb_rpc
pw_checksum
pw_hdlc
Expand Down
52 changes: 21 additions & 31 deletions examples/all-clusters-app/esp32/main/Rpc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@
#if CONFIG_ENABLE_PW_RPC
#include "PigweedLoggerMutex.h"
#include "RpcService.h"
#include "button_service/button_service.rpc.pb.h"
#include "device_service/device_service.rpc.pb.h"
#include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "freertos/event_groups.h"
Expand All @@ -29,6 +27,10 @@
#include "pw_log/log.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/Lighting.h"

#include <lib/support/logging/CHIPLogging.h>

#include "ScreenManager.h"
Expand Down Expand Up @@ -72,35 +74,10 @@ constexpr size_t kScanRecordsMax = sizeof(chip_rpc_ScanResults().aps) / sizeof(c
chip_rpc_ScanResults out_scan_records;
wifi_ap_record_t scan_records[kScanRecordsMax];

class Device final : public generated::Device<Device>
{
public:
pw::Status FactoryReset(ServerContext & ctx, const pw_protobuf_Empty & request, pw_protobuf_Empty & response)
{
chip::DeviceLayer::ConfigurationMgr().InitiateFactoryReset();
return pw::OkStatus();
}
pw::Status Reboot(ServerContext & ctx, const pw_protobuf_Empty & request, pw_protobuf_Empty & response)
{
return pw::Status::Unimplemented();
}
pw::Status TriggerOta(ServerContext & ctx, const pw_protobuf_Empty & request, pw_protobuf_Empty & response)
{
return pw::Status::Unimplemented();
}
pw::Status GetDeviceInfo(ServerContext &, const pw_protobuf_Empty & request, chip_rpc_DeviceInfo & response)
{
response.vendor_id = 1234;
response.product_id = 5678;
response.software_version = 0;
return pw::OkStatus();
}
};

class Button final : public generated::Button<Button>
class Esp32Button final : public Button
{
public:
pw::Status Event(ServerContext &, const chip_rpc_ButtonEvent & request, pw_protobuf_Empty & response)
pw::Status Event(ServerContext &, const chip_rpc_ButtonEvent & request, pw_protobuf_Empty & response) override
{
#if CONFIG_DEVICE_TYPE_M5STACK
if (request.pushed)
Expand All @@ -114,6 +91,17 @@ class Button final : public generated::Button<Button>
}
};

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

class Wifi final : public generated::Wifi<Wifi>
{
public:
Expand Down Expand Up @@ -299,14 +287,16 @@ constexpr uint8_t kRpcTaskPriority = 5;

TaskHandle_t rpcTaskHandle;

Button button_service;
Device device_service;
Esp32Button button_service;
Esp32Device device_service;
Lighting lighting_service;
Wifi wifi_service;

void RegisterServices(pw::rpc::Server & server)
{
server.RegisterService(button_service);
server.RegisterService(device_service);
server.RegisterService(lighting_service);
server.RegisterService(wifi_service);
}

Expand Down
23 changes: 22 additions & 1 deletion examples/common/pigweed/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ import("$dir_pw_build/target_types.gni")
import("pigweed_rpcs.gni")

config("default_config") {
include_dirs = [ ".." ]
include_dirs = [
".",
"..",
]
}

if (chip_enable_pw_rpc) {
Expand All @@ -39,6 +42,24 @@ if (chip_enable_pw_rpc) {
strip_prefix = "protos"
prefix = "button_service"
}

pw_proto_library("lighting_service") {
sources = [ "protos/lighting_service.proto" ]
deps = [ "$dir_pw_protobuf:common_protos" ]
strip_prefix = "protos"
prefix = "lighting_service"
}

pw_proto_library("locking_service") {
sources = [ "protos/locking_service.proto" ]
deps = [ "$dir_pw_protobuf:common_protos" ]
strip_prefix = "protos"
prefix = "locking_service"
}
}

pw_source_set("rpc_services") {
public_configs = [ ":default_config" ]
}

pw_source_set("system_rpc_server") {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,20 @@ import 'pw_protobuf_protos/common.proto';

package chip.rpc;

message LightingBrightness {
// level is between 0 and max_level inclusively.
// The device should support rescaling if provided a max_value which doesn't
// match the platforms value.
uint32 level = 1;
uint32 max_level = 2;

message LightingColor {
// Values are between 0x00 and 0xFE inclusive
uint32 hue = 1;
uint32 saturation = 2;
}

message LightingState {
bool on = 1;
optional LightingBrightness brightness = 2;

// level is between 0 and 255 inclusively.
optional uint32 level = 2;

optional LightingColor color = 3;
}

service Lighting {
Expand Down
4 changes: 2 additions & 2 deletions examples/common/pigweed/rpc_console/py/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@ pw_python_package("chip_rpc") {
"$dir_pw_rpc/py",
"${chip_root}/examples/common/pigweed:button_service.python",
"${chip_root}/examples/common/pigweed:device_service.python",
"${chip_root}/examples/common/pigweed:lighting_service.python",
"${chip_root}/examples/common/pigweed:locking_service.python",
"${chip_root}/examples/ipv6only-app/common:wifi_service.python",
"${chip_root}/examples/lighting-app/lighting-common:lighting_service.python",
"${chip_root}/examples/lock-app/lock-common:locking_service.python",
]
}

Expand Down
38 changes: 38 additions & 0 deletions examples/common/pigweed/rpc_services/Button.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
*
* Copyright (c) 2021 Project CHIP Authors
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#pragma once

#include "button_service/button_service.rpc.pb.h"

namespace chip {
namespace rpc {

class Button : public generated::Button<Button>
{
public:
virtual ~Button() = default;

virtual pw::Status Event(ServerContext &, const chip_rpc_ButtonEvent & request, pw_protobuf_Empty & response)
{
return pw::Status::Unimplemented();
}
};

} // namespace rpc
} // namespace chip
62 changes: 62 additions & 0 deletions examples/common/pigweed/rpc_services/Device.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
*
* Copyright (c) 2021 Project CHIP Authors
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#pragma once

#include <platform/CHIPDeviceConfig.h>

#include "device_service/device_service.rpc.pb.h"
#include "platform/ConfigurationManager.h"

namespace chip {
namespace rpc {

class Device : public generated::Device<Device>
{
public:
virtual ~Device() = default;

virtual pw::Status FactoryReset(ServerContext & ctx, const pw_protobuf_Empty & request, pw_protobuf_Empty & response)
{
DeviceLayer::ConfigurationMgr().InitiateFactoryReset();
return pw::OkStatus();
}

virtual pw::Status Reboot(ServerContext & ctx, const pw_protobuf_Empty & request, pw_protobuf_Empty & response)
{
return pw::Status::Unimplemented();
}

virtual pw::Status TriggerOta(ServerContext & ctx, const pw_protobuf_Empty & request, pw_protobuf_Empty & response)
{
// TODO: auto err = DeviceLayer::SoftwareUpdateMgr().CheckNow();
return pw::Status::Unimplemented();
}

virtual pw::Status GetDeviceInfo(ServerContext &, const pw_protobuf_Empty & request, chip_rpc_DeviceInfo & response)
{
response.vendor_id = CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID;
response.product_id = CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID;
response.software_version = CHIP_DEVICE_CONFIG_DEVICE_FIRMWARE_REVISION;
snprintf(response.serial_number, sizeof(response.serial_number), CHIP_DEVICE_CONFIG_TEST_SERIAL_NUMBER);
return pw::OkStatus();
}
};

} // namespace rpc
} // namespace chip
Loading

0 comments on commit 8bdddd7

Please sign in to comment.