Skip to content

Commit

Permalink
Use CHIPDeviceController instead of CHIPDeviceController_deprecated (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
vivien-apple authored Dec 1, 2020
1 parent 2f16904 commit f382625
Show file tree
Hide file tree
Showing 24 changed files with 740 additions and 431 deletions.
11 changes: 8 additions & 3 deletions examples/chip-tool/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,14 @@ assert(chip_build_tools)

executable("chip-tool") {
sources = [
"commands/clusters/ModelCommand.cpp",
"commands/common/Command.cpp",
"commands/common/Commands.cpp",
"commands/common/EchoCommand.cpp",
"commands/common/Logging.cpp",
"commands/common/ModelCommand.cpp",
"commands/common/NetworkCommand.cpp",
"commands/echo/EchoCommand.cpp",
"commands/pairing/PairingCommand.cpp",
"config/PersistentStorage.cpp",
"main.cpp",
]

Expand All @@ -37,7 +39,10 @@ executable("chip-tool") {

cflags = [ "-Wconversion" ]

public_deps = [ "${chip_root}/src/lib" ]
public_deps = [
"${chip_root}/src/lib",
"${chip_root}/third_party/inipp",
]

output_dir = root_out_dir
}
53 changes: 33 additions & 20 deletions examples/chip-tool/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,40 +27,53 @@ ninja -C out/debug
- After the application is built, it can be found in the build directory as
`out/debug/chip-tool`

## Using the Client to Request an Echo
## Using the Client to Pair a device

In order to send commands to a device, it must be paired with the client.

#### Pair a device

To initiate a client pairing request to a device, run the built executable and
choose the pairing mode.

##### Pair a device configured to bypass Rendezvous

### Ping a device over BLE
The command below pair a device with the provided IP address and port of the
server to talk to.

To initiate a client echo request to a BLE device, run the built executable and
pass it the discriminator and pairing code of the remote device. The command
below uses the default values hard-coded into the debug versions of the ESP32
all-clusters-app:
$ chip-tool pairing bypass 192.168.0.30 11097

$ chip-tool echo ble 12345678 3840
#### Pair a device over BLE

### Ping a device over IP
Run the built executable and pass it the discriminator and pairing code of the
remote device.

To start the Client in echo mode, run the built executable and pass it the IP
address and port of the server to talk to, as well as the command "echo".
The command below uses the default values hard-coded into the debug versions of
the ESP32 all-clusters-app:

$ chip-tool echo ip 192.168.0.30 11097
$ chip-tool pairing ble 12345678 3840

If valid values are supplied, it will begin to periodically send messages to the
server address provided.
### Unpair a device

It also verifies that the incoming echo from the server matches what was sent
out.
$ chip-tool pairing unpair

Stop the Client at any time with `Ctrl + C`.
## Using the Client to Request an Echo

### Ping a device

$ chip-tool echo ip

If valid values are supplied, it will send a message to the paired device and
verify that the incoming echo from the server matches what was sent out.

## Using the Client to Send CHIP Commands

To use the Client to send a CHIP commands, run the built executable and pass it
the target cluster name, the target command name, the ip address and port of the
server to talk to as well as an endpoint id. The endpoint id must be between 1
and 240.
the target cluster name, the target command name as well as an endpoint id.

The endpoint id must be between 1 and 240.

$ chip-tool onoff on 192.168.0.30 11097 1
$ chip-tool onoff on 1

The client will send a single command packet and then exit.

Expand Down
4 changes: 2 additions & 2 deletions examples/chip-tool/commands/clusters/Commands.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@

#pragma once

#include "../common/ModelCommand.h"
#include "../common/ModelCommandResponse.h"
#include "ModelCommand.h"
#include "ModelCommandResponse.h"

#include <limits>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,7 @@

#include "ModelCommand.h"

#include <atomic>
#include <chrono>
#include <sstream>
#include <string>

using namespace ::chip;
using namespace ::chip::DeviceController;

constexpr std::chrono::seconds kWaitingForResponseTimeout(10);

namespace {
constexpr uint8_t kZCLGlobalCmdFrameControlHeader = 8;
Expand All @@ -44,76 +36,15 @@ bool isGlobalCommand(uint8_t frameControl)
}
} // namespace

void ModelCommand::OnConnect(ChipDeviceController * dc)
{
if (SendCommand(dc))
{
UpdateWaitForResponse(true);
WaitForResponse();
}
}

void ModelCommand::OnError(ChipDeviceController * dc, CHIP_ERROR err)
{
UpdateWaitForResponse(false);
}

void ModelCommand::OnMessage(ChipDeviceController * dc, PacketBufferHandle buffer)
uint16_t ModelCommand::Encode(PacketBufferHandle & buffer, uint16_t bufferSize)
{
SetCommandExitStatus(ReceiveCommandResponse(dc, std::move(buffer)));
UpdateWaitForResponse(false);
}

CHIP_ERROR ModelCommand::Run(ChipDeviceController * dc, NodeId remoteId)
{
CHIP_ERROR err = CHIP_NO_ERROR;

err = NetworkCommand::Run(dc, remoteId);
SuccessOrExit(err);

err = dc->ServiceEventSignal();
SuccessOrExit(err);

VerifyOrExit(GetCommandExitStatus(), err = CHIP_ERROR_INTERNAL);

exit:
return err;
}

bool ModelCommand::SendCommand(ChipDeviceController * dc)
{
// Make sure our buffer is big enough, but this will need a better setup!
static const uint16_t bufferSize = 1024;
PacketBufferHandle buffer = PacketBuffer::NewWithAvailableSize(bufferSize);

if (buffer.IsNull())
{
ChipLogError(chipTool, "Failed to allocate memory for packet data.");
return false;
}

ChipLogProgress(chipTool, "Endpoint id: '0x%02x', Cluster id: '0x%04x', Command id: '0x%02x'", mEndPointId, mClusterId,
mCommandId);

uint16_t dataLength = EncodeCommand(buffer, bufferSize, mEndPointId);
if (dataLength == 0)
{
ChipLogError(chipTool, "Error while encoding data for command: %s", GetName());
return false;
}

buffer->SetDataLength(dataLength);
ChipLogDetail(chipTool, "Encoded data of length %d", dataLength);

#ifdef DEBUG
PrintBuffer(buffer);
#endif

dc->SendMessage(NULL, buffer.Release_ForNow());
return true;
return EncodeCommand(buffer, bufferSize, mEndPointId);
}

bool ModelCommand::ReceiveCommandResponse(ChipDeviceController * dc, PacketBufferHandle buffer) const
bool ModelCommand::Decode(PacketBufferHandle & buffer) const
{
EmberApsFrame frame;
uint8_t * message;
Expand Down Expand Up @@ -150,34 +81,3 @@ bool ModelCommand::ReceiveCommandResponse(ChipDeviceController * dc, PacketBuffe
exit:
return success;
}

void ModelCommand::UpdateWaitForResponse(bool value)
{
{
std::lock_guard<std::mutex> lk(cvWaitingForResponseMutex);
mWaitingForResponse = value;
}
cvWaitingForResponse.notify_all();
}

void ModelCommand::WaitForResponse()
{
std::unique_lock<std::mutex> lk(cvWaitingForResponseMutex);
auto waitingUntil = std::chrono::system_clock::now() + kWaitingForResponseTimeout;
if (!cvWaitingForResponse.wait_until(lk, waitingUntil, [this]() { return !this->mWaitingForResponse; }))
{
ChipLogError(chipTool, "No response from device");
}
}

void ModelCommand::PrintBuffer(const PacketBufferHandle & buffer) const
{
const size_t data_len = buffer->DataLength();

fprintf(stderr, "SENDING: %zu ", data_len);
for (size_t i = 0; i < data_len; ++i)
{
fprintf(stderr, "%d ", buffer->Start()[i]);
}
fprintf(stderr, "\n");
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,7 @@

#pragma once

#include "NetworkCommand.h"

#include <condition_variable>
#include <mutex>
#include "../common/NetworkCommand.h"

#include <app/chip-zcl-zpro-codec.h>
#include <core/CHIPEncoding.h>
Expand All @@ -35,38 +32,20 @@ class ModelCommand : public NetworkCommand
{
public:
ModelCommand(const char * commandName, uint16_t clusterId, uint8_t commandId) :
NetworkCommand(commandName, NetworkType::UDP), mClusterId(clusterId), mCommandId(commandId)
NetworkCommand(commandName), mClusterId(clusterId), mCommandId(commandId)
{}

void AddArguments()
{
NetworkCommand::AddArguments();
AddArgument("endpoint-id", CHIP_ZCL_ENDPOINT_MIN, CHIP_ZCL_ENDPOINT_MAX, &mEndPointId);
}

/////////// Command Interface /////////
CHIP_ERROR Run(ChipDeviceController * dc, NodeId remoteId) override;
void AddArguments() { AddArgument("endpoint-id", CHIP_ZCL_ENDPOINT_MIN, CHIP_ZCL_ENDPOINT_MAX, &mEndPointId); }

/////////// IPCommand Interface /////////
void OnConnect(ChipDeviceController * dc) override;
void OnError(ChipDeviceController * dc, CHIP_ERROR err) override;
void OnMessage(ChipDeviceController * dc, chip::System::PacketBufferHandle buffer) override;
/////////// NetworkCommand Interface /////////
uint16_t Encode(PacketBufferHandle & buffer, uint16_t bufferSize) override;
bool Decode(PacketBufferHandle & buffer) const override;

virtual uint16_t EncodeCommand(const chip::System::PacketBufferHandle & buffer, uint16_t bufferSize, uint8_t endPointId) = 0;
virtual uint16_t EncodeCommand(const PacketBufferHandle & buffer, uint16_t bufferSize, uint8_t endPointId) = 0;
virtual bool HandleGlobalResponse(uint8_t commandId, uint8_t * message, uint16_t messageLen) const { return false; }
virtual bool HandleSpecificResponse(uint8_t commandId, uint8_t * message, uint16_t messageLen) const { return false; }

private:
bool SendCommand(ChipDeviceController * dc);
bool ReceiveCommandResponse(ChipDeviceController * dc, chip::System::PacketBufferHandle buffer) const;

void UpdateWaitForResponse(bool value);
void WaitForResponse(void);
void PrintBuffer(const chip::System::PacketBufferHandle & buffer) const;

std::condition_variable cvWaitingForResponse;
std::mutex cvWaitingForResponseMutex;
bool mWaitingForResponse{ false };
const uint16_t mClusterId;
const uint8_t mCommandId;
uint8_t mEndPointId;
Expand Down
20 changes: 20 additions & 0 deletions examples/chip-tool/commands/common/Command.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -295,3 +295,23 @@ const char * Command::GetAttribute(void) const

return nullptr;
}

void Command::UpdateWaitForResponse(bool value)
{
{
std::lock_guard<std::mutex> lk(cvWaitingForResponseMutex);
mWaitingForResponse = value;
}
cvWaitingForResponse.notify_all();
}

void Command::WaitForResponse(uint16_t duration)
{
std::chrono::seconds waitingForResponseTimeout(duration);
std::unique_lock<std::mutex> lk(cvWaitingForResponseMutex);
auto waitingUntil = std::chrono::system_clock::now() + waitingForResponseTimeout;
if (!cvWaitingForResponse.wait_until(lk, waitingUntil, [this]() { return !this->mWaitingForResponse; }))
{
ChipLogError(chipTool, "No response from device");
}
}
28 changes: 21 additions & 7 deletions examples/chip-tool/commands/common/Command.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,18 @@

#pragma once

#include <controller/CHIPDeviceController_deprecated.h>
#include <controller/CHIPDeviceController.h>
#include <inet/InetInterface.h>
#include <support/logging/CHIPLogging.h>

#include <atomic>
#include <condition_variable>
#include <memory>
#include <mutex>
#include <vector>

class Command;
class PersistentStorage;

template <typename T, typename... Args>
std::unique_ptr<Command> make_unique(Args &&... args)
Expand Down Expand Up @@ -69,11 +73,14 @@ struct Argument
class Command
{
public:
using ChipDeviceController = ::chip::DeviceController::ChipDeviceController;
using IPAddress = ::chip::Inet::IPAddress;
using PacketBuffer = ::chip::System::PacketBuffer;
using PacketBufferHandle = ::chip::System::PacketBufferHandle;
using NodeId = ::chip::NodeId;
using ChipDeviceCommissioner = ::chip::Controller::DeviceCommissioner;
using ChipSerializedDevice = ::chip::Controller::SerializedDevice;
using ChipDevice = ::chip::Controller::Device;
using PeerAddress = ::chip::Transport::PeerAddress;
using IPAddress = ::chip::Inet::IPAddress;
using PacketBuffer = ::chip::System::PacketBuffer;
using PacketBufferHandle = ::chip::System::PacketBufferHandle;
using NodeId = ::chip::NodeId;

struct AddressWithInterface
{
Expand Down Expand Up @@ -134,11 +141,14 @@ class Command
return AddArgument(name, min, max, reinterpret_cast<void *>(out), Number_uint64);
}

virtual CHIP_ERROR Run(ChipDeviceController * dc, NodeId remoteId) = 0;
virtual CHIP_ERROR Run(PersistentStorage & storage, NodeId localId, NodeId remoteId) = 0;

bool GetCommandExitStatus() const { return mCommandExitStatus; }
void SetCommandExitStatus(bool status) { mCommandExitStatus = status; }

void UpdateWaitForResponse(bool value);
void WaitForResponse(uint16_t duration);

private:
bool InitArgument(size_t argIndex, const char * argValue);
size_t AddArgument(const char * name, int64_t min, uint64_t max, void * out, ArgumentType type);
Expand All @@ -147,4 +157,8 @@ class Command
bool mCommandExitStatus = false;
const char * mName = nullptr;
std::vector<Argument> mArgs;

std::condition_variable cvWaitingForResponse;
std::mutex cvWaitingForResponseMutex;
bool mWaitingForResponse{ false };
};
Loading

0 comments on commit f382625

Please sign in to comment.