Skip to content

Commit

Permalink
RPC: Cleanup and add thread service (#14843)
Browse files Browse the repository at this point in the history
* RPC: Refactor wifi RPC as common service

- Move WiFi into a common rpc service like others.
- Add WiFi RPC service to the all-clusters app

* RPC: Add thread rpc service to efr and nrf

- Add a Thread RPC service similar to others.
- Add to NRF and EFR32 platforms
- Add to efr/lighting RPC example app
- Add to efr/lock RPC example app
- Add to nfr/lighting RPC example app

* RPC: Add get/set pairing state

* RPC: Add OTCLI to EFR32 and NRF32

- Add the openthread cli as a new RPC service.
- Add service to EFR32 and NRF32 platforms
- Add to lighting/efr32 example
- Add to lighting/nrf example

* RPC: Refactor linux RPC into platform.

Move common linux Rpc.* files into common platform to match refactoring
done for other platforms.

* RPC: Wake m5 display on RPC button press
  • Loading branch information
rgoliver authored and pull[bot] committed Feb 23, 2022
1 parent 577463b commit 75ed145
Show file tree
Hide file tree
Showing 28 changed files with 691 additions and 114 deletions.
9 changes: 5 additions & 4 deletions examples/all-clusters-app/esp32/main/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -198,15 +198,15 @@ pw_proto_library(locking_service

pw_proto_library(wifi_service
SOURCES
${CHIP_ROOT}/examples/ipv6only-app/common/wifi_service/wifi_service.proto
${CHIP_ROOT}/examples/common/pigweed/protos/wifi_service.proto
INPUTS
${CHIP_ROOT}/examples/ipv6only-app/common/wifi_service/wifi_service.options
${CHIP_ROOT}/examples/common/pigweed/protos/wifi_service.options
PREFIX
wifi_service
DEPS
pw_protobuf.common_protos
STRIP_PREFIX
${CHIP_ROOT}/examples/ipv6only-app/common/wifi_service
${CHIP_ROOT}/examples/common/pigweed/protos
)

target_link_libraries(${COMPONENT_LIB} PUBLIC
Expand Down Expand Up @@ -237,6 +237,7 @@ target_compile_options(${COMPONENT_LIB} PRIVATE
"-DPW_RPC_DEVICE_SERVICE=1"
"-DPW_RPC_LIGHTING_SERVICE=1"
"-DPW_RPC_LOCKING_SERVICE=1"
"-DPW_RPC_TRACING_SERVICE=1")
"-DPW_RPC_TRACING_SERVICE=1"
"-DPW_RPC_WIFI_SERVICE=1")

endif (CONFIG_ENABLE_PW_RPC)
23 changes: 23 additions & 0 deletions examples/common/pigweed/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,29 @@ if (chip_enable_pw_rpc) {
strip_prefix = "protos"
prefix = "locking_service"
}

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

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

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

pw_source_set("rpc_services") {
Expand Down
7 changes: 6 additions & 1 deletion examples/common/pigweed/protos/device_service.proto
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,16 @@ message DeviceState {
repeated FabricInfo fabric_info = 2;
}

message PairingState {
bool pairing_enabled = 1;
}

service Device {
rpc FactoryReset(pw.protobuf.Empty) returns (pw.protobuf.Empty){}
rpc Reboot(pw.protobuf.Empty) returns (pw.protobuf.Empty){}
rpc TriggerOta(pw.protobuf.Empty) returns (pw.protobuf.Empty){}
rpc GetDeviceInfo(pw.protobuf.Empty) returns (DeviceInfo){}
rpc GetDeviceState(pw.protobuf.Empty) returns (DeviceState){}
rpc SetPairingInfo(PairingInfo) returns (pw.protobuf.Empty){}
rpc SetPairingState(PairingState) returns (pw.protobuf.Empty){}
rpc GetPairingState(pw.protobuf.Empty) returns (PairingState){}
}
2 changes: 2 additions & 0 deletions examples/common/pigweed/protos/ot_cli_service.options
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
chip.rpc.OtCliResponse.response max_size:128
chip.rpc.OtCliCommand.command max_size:128
18 changes: 18 additions & 0 deletions examples/common/pigweed/protos/ot_cli_service.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
syntax = "proto3";

package chip.rpc;

import 'pw_protobuf_protos/common.proto';

message OtCliResponse {
string response = 1;
}

message OtCliCommand {
string command = 1;
}

service OtCli {
// Handle the command using the Open Thread CLI, and stream the reponses back.
rpc Command(OtCliCommand) returns (stream OtCliResponse){}
}
2 changes: 2 additions & 0 deletions examples/common/pigweed/protos/thread_service.options
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
chip.rpc.ThreadNetworkInfo.network_name max_size:17 // Maximum size of the Thread Network Name field + 1 for null
chip.rpc.ThreadNetworkInfo.extended_pan_id max_size:8 // Size of extended pan id in bytes
32 changes: 32 additions & 0 deletions examples/common/pigweed/protos/thread_service.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
syntax = "proto3";

package chip.rpc;

import 'pw_protobuf_protos/common.proto';

enum ThreadDeviceType {
DEVICE_TYPE_NOT_SUPPORTED = 0;
DEVICE_TYPE_ROUTER = 1;
DEVICE_TYPE_FULL_END_DEVICE = 2;
DEVICE_TYPE_MINIMAL_END_DEVICE = 3;
DEVICE_TYPE_SLEEPY_END_DEVICE = 4;
}

message ThreadState {
bool is_provisioned = 1;
bool is_enabled = 2;
bool is_attached = 3;
ThreadDeviceType device_type = 4;
}

message ThreadNetworkInfo {
uint32 pan_id = 1;
string network_name = 2;
uint32 channel = 3;
bytes extended_pan_id = 4;
}

service Thread {
rpc GetState(pw.protobuf.Empty) returns (ThreadState){}
rpc GetNetworkInfo(pw.protobuf.Empty) returns (ThreadNetworkInfo){}
}
4 changes: 3 additions & 1 deletion examples/common/pigweed/rpc_console/py/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,9 @@ pw_python_package("chip_rpc") {
"${chip_root}/examples/common/pigweed:echo_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/common/pigweed:ot_cli_service.python",
"${chip_root}/examples/common/pigweed:thread_service.python",
"${chip_root}/examples/common/pigweed:wifi_service.python",
]
}

Expand Down
16 changes: 10 additions & 6 deletions examples/common/pigweed/rpc_console/py/chip_rpc/console.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,12 @@
from attributes_service import attributes_service_pb2
from button_service import button_service_pb2
from device_service import device_service_pb2
from echo_service import echo_pb2
from lighting_service import lighting_service_pb2
from locking_service import locking_service_pb2
from ot_cli_service import ot_cli_service_pb2
from thread_service import thread_service_pb2
from wifi_service import wifi_service_pb2
from echo_service import echo_pb2

_LOG = logging.getLogger(__name__)
_DEVICE_LOG = logging.getLogger('rpc_device')
Expand All @@ -69,13 +71,15 @@
SOCKET_SERVER = 'localhost'
SOCKET_PORT = 33000

PROTOS = [button_service_pb2,
attributes_service_pb2,
PROTOS = [attributes_service_pb2,
button_service_pb2,
device_service_pb2,
echo_pb2,
lighting_service_pb2,
locking_service_pb2,
wifi_service_pb2,
device_service_pb2,
echo_pb2]
ot_cli_service_pb2,
thread_service_pb2,
wifi_service_pb2]


def _parse_args():
Expand Down
20 changes: 20 additions & 0 deletions examples/common/pigweed/rpc_services/Device.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,26 @@ class Device : public pw_rpc::nanopb::Device::Service<Device>
return pw::Status::Unimplemented();
}

virtual pw::Status SetPairingState(const chip_rpc_PairingState & request, pw_protobuf_Empty & response)
{
if (request.pairing_enabled)
{
DeviceLayer::ConnectivityMgr().SetBLEAdvertisingEnabled(true);
DeviceLayer::ConnectivityMgr().SetBLEAdvertisingMode(DeviceLayer::ConnectivityMgr().kFastAdvertising);
}
else
{
DeviceLayer::ConnectivityMgr().SetBLEAdvertisingEnabled(false);
}
return pw::OkStatus();
}

virtual pw::Status GetPairingState(const pw_protobuf_Empty & request, chip_rpc_PairingState & response)
{
response.pairing_enabled = DeviceLayer::ConnectivityMgr().IsBLEAdvertisingEnabled();
return pw::OkStatus();
}

virtual pw::Status GetDeviceState(const pw_protobuf_Empty & request, chip_rpc_DeviceState & response)
{
uint64_t time_since_boot_sec;
Expand Down
83 changes: 83 additions & 0 deletions examples/common/pigweed/rpc_services/OtCli.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*
*
* Copyright (c) 2022 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

#if CHIP_ENABLE_OPENTHREAD
#include <openthread/cli.h>
#include <openthread/instance.h>

static_assert(OPENTHREAD_API_VERSION >= 85, "Invalid Open Thread version");
#endif // CHIP_ENABLE_OPENTHREAD

#include "ot_cli_service/ot_cli_service.rpc.pb.h"
#include "platform/ConfigurationManager.h"
#include "pw_log/log.h"

namespace chip {
namespace rpc {

class OtCli : public pw_rpc::nanopb::OtCli::Service<OtCli>
{
public:
virtual ~OtCli() = default;

virtual void Command(const ::chip_rpc_OtCliCommand & request, ServerWriter<::chip_rpc_OtCliResponse> & writer)
{
#if CHIP_ENABLE_OPENTHREAD
LazyInit();
rpc_writer = &writer;
otCliInputLine(const_cast<char *>(request.command));
rpc_writer->Finish();
rpc_writer = nullptr;
#endif // CHIP_ENABLE_OPENTHREAD
}

private:
ServerWriter<::chip_rpc_OtCliResponse> * rpc_writer = nullptr;

#if CHIP_ENABLE_OPENTHREAD
bool mInitComplete = false;

void LazyInit()
{
if (mInitComplete)
{
return;
}
otCliInit(otInstanceInitSingle(), &OnOtCliOutput, this);
mInitComplete = true;
}

static int OnOtCliOutput(void * context, const char * format, va_list arguments)
{
OtCli * ot_cli = reinterpret_cast<OtCli *>(context);
if (ot_cli->rpc_writer)
{
chip_rpc_OtCliResponse out;
int rval = vsnprintf(out.response, sizeof(out.response), format, arguments);
ot_cli->rpc_writer->Write(out);
return rval;
}
return 0;
}
#endif // CHIP_ENABLE_OPENTHREAD
};

} // namespace rpc
} // namespace chip
83 changes: 83 additions & 0 deletions examples/common/pigweed/rpc_services/Thread.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*
*
* Copyright (c) 2022 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 "platform/ConnectivityManager.h"
#include "thread_service/thread_service.rpc.pb.h"

#if CHIP_ENABLE_OPENTHREAD
#include <openthread/dataset.h>
#include <platform/ThreadStackManager.h>
#endif

namespace chip {
namespace rpc {

// Implementation class for chip.rpc.Thread.
class Thread : public pw_rpc::nanopb::Thread::Service<Thread>
{
public:
::pw::Status GetState(const pw_protobuf_Empty & request, chip_rpc_ThreadState & response)
{
response.is_provisioned = DeviceLayer::ConnectivityMgr().IsThreadProvisioned();
response.is_enabled = DeviceLayer::ConnectivityMgr().IsThreadEnabled();
response.is_attached = DeviceLayer::ConnectivityMgr().IsThreadAttached();
response.device_type = static_cast<chip_rpc_ThreadDeviceType>(DeviceLayer::ConnectivityMgr().GetThreadDeviceType());
return pw::OkStatus();
}

::pw::Status GetNetworkInfo(const pw_protobuf_Empty & request, chip_rpc_ThreadNetworkInfo & response)
{
#if CHIP_ENABLE_OPENTHREAD
otInstance * otInst = DeviceLayer::ThreadStackMgrImpl().OTInstance();
otOperationalDataset data;
if (OT_ERROR_NONE != otDatasetGetActive(otInst, &data))
{
return pw::Status::NotFound();
}

if (data.mComponents.mIsPanIdPresent)
{
response.pan_id = data.mPanId;
}
if (data.mComponents.mIsNetworkNamePresent)
{
snprintf(response.network_name, sizeof(response.network_name), "%s", data.mNetworkName.m8);
}
if (data.mComponents.mIsChannelPresent)
{
response.channel = data.mChannel;
}
if (data.mComponents.mIsExtendedPanIdPresent)
{
size_t size = std::min(sizeof(response.extended_pan_id.bytes), sizeof(data.mExtendedPanId));
memcpy(response.extended_pan_id.bytes, data.mExtendedPanId.m8, size);
response.extended_pan_id.size = size;
}
return pw::OkStatus();
#else // CHIP_ENABLE_OPENTHREAD
return ::pw::Status::Unimplemented();
#endif // CHIP_ENABLE_OPENTHREAD
}
};

} // namespace rpc
} // namespace chip
Loading

0 comments on commit 75ed145

Please sign in to comment.