Skip to content

Commit

Permalink
Squash commit of peer address and connection status (#1112)
Browse files Browse the repository at this point in the history
Co-authored-by: Andrei Litvin <[email protected]>
  • Loading branch information
andy31415 and andreilitvin authored Jun 16, 2020
1 parent b8be85f commit 4746858
Show file tree
Hide file tree
Showing 17 changed files with 429 additions and 179 deletions.
24 changes: 20 additions & 4 deletions examples/chip-tool/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,12 @@ extern "C" {
using namespace ::chip;
using namespace ::chip::Inet;

// NOTE: Remote device ID is in sync with the echo server device id
// At some point, we may want to add an option to connect to a device without
// knowing its id, because the ID can be learned on the first response that is received.
constexpr NodeId kLocalDeviceId = 112233;
constexpr NodeId kRemoteDeviceId = 12344321;

static const char * PAYLOAD = "Message from Standalone CHIP echo client!";

// Device Manager Callbacks
Expand Down Expand Up @@ -297,6 +303,7 @@ int main(int argc, char * argv[])
IPAddress host_addr;
uint16_t port;
Command command;
CHIP_ERROR err;
CommandArgs commandArgs;
if (!DetermineAddress(argc, argv, &host_addr, &port) || !DetermineCommand(argc, argv, &command) ||
!DetermineCommandArgs(argc, argv, command, &commandArgs))
Expand All @@ -306,10 +313,14 @@ int main(int argc, char * argv[])
}

auto * controller = new DeviceController::ChipDeviceController();
controller->Init();
err = controller->Init(kLocalDeviceId);
VerifyOrExit(err == CHIP_NO_ERROR, fprintf(stderr, "Failed to initialize the device controller"));

err = controller->ConnectDevice(kRemoteDeviceId, host_addr, NULL, EchoResponse, ReceiveError, port);
VerifyOrExit(err == CHIP_NO_ERROR, fprintf(stderr, "Failed to connect to the device"));

controller->ConnectDevice(1, host_addr, NULL, EchoResponse, ReceiveError, port);
controller->ManualKeyExchange(remote_public_key, sizeof(remote_public_key), local_private_key, sizeof(local_private_key));
err = controller->ManualKeyExchange(remote_public_key, sizeof(remote_public_key), local_private_key, sizeof(local_private_key));
VerifyOrExit(err == CHIP_NO_ERROR, fprintf(stderr, "Failed to exchange keys"));

if (command == Command::Echo)
{
Expand All @@ -320,10 +331,15 @@ int main(int argc, char * argv[])
DoOnOff(controller, command, commandArgs.endpointId);
}

exit:
if (err != CHIP_NO_ERROR)
{
fprintf(stderr, "ERROR: %s\n", ErrorStr(err));
}
controller->Shutdown();
delete controller;

return 0;
return (err == CHIP_NO_ERROR) ? EXIT_SUCCESS : EXIT_FAILURE;
}

extern "C" {
Expand Down
4 changes: 4 additions & 0 deletions examples/wifi-echo/server/esp32/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,8 @@ EXTRA_COMPONENT_DIRS += $(PROJECT_PATH)/third_party/connectedhomeip/config/esp32
$(PROJECT_PATH)/../../../common/m5stack-tft/repo/components \
$(PROJECT_PATH)/../../../common/QRCode \

CXXFLAGS += -std=c++11 -Os
CPPFLAGS += -Os
CLAGS += -Os

include $(IDF_PATH)/make/project.mk
122 changes: 81 additions & 41 deletions examples/wifi-echo/server/esp32/main/EchoServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,12 @@
#include "freertos/task.h"
#include "nvs_flash.h"
#include "tcpip_adapter.h"

#include <string.h>
#include <sys/param.h>

#include <algorithm>

#include "lwip/err.h"
#include "lwip/sockets.h"
#include "lwip/sys.h"
Expand All @@ -47,46 +50,96 @@ static const char * TAG = "echo_server";

using namespace ::chip;
using namespace ::chip::Inet;
using namespace ::chip::Transport;

constexpr NodeId kLocalNodeId = 12344321;
extern LEDWidget statusLED; // In wifi-echo.cpp

namespace {

const unsigned char local_private_key[] = { 0xc6, 0x1a, 0x2f, 0x89, 0x36, 0x67, 0x2b, 0x26, 0x12, 0x47, 0x4f,
0x11, 0x0e, 0x34, 0x15, 0x81, 0x81, 0x12, 0xfc, 0x36, 0xeb, 0x65,
0x61, 0x07, 0xaa, 0x63, 0xe8, 0xc5, 0x22, 0xac, 0x52, 0xa1 };

const unsigned char remote_public_key[] = { 0x04, 0x30, 0x77, 0x2c, 0xe7, 0xd4, 0x0a, 0xf2, 0xf3, 0x19, 0xbd, 0xfb, 0x1f,
0xcc, 0x88, 0xd9, 0x83, 0x25, 0x89, 0xf2, 0x09, 0xf3, 0xab, 0xe4, 0x33, 0xb6,
0x7a, 0xff, 0x73, 0x3b, 0x01, 0x35, 0x34, 0x92, 0x73, 0x14, 0x59, 0x0b, 0xbd,
0x44, 0x72, 0x1b, 0xcd, 0xb9, 0x02, 0x53, 0xd9, 0xaf, 0xcc, 0x1a, 0xcd, 0xae,
0xe8, 0x87, 0x2e, 0x52, 0x3b, 0x98, 0xf0, 0xa1, 0x88, 0x4a, 0xe3, 0x03, 0x75 };

/// A printable string has all characters printable and ends with a '\0'
bool ContentIsAPrintableString(System::PacketBuffer * buffer)
{
const size_t data_len = buffer->DataLength();
const uint8_t * data = buffer->Start();
bool isPrintable = true;

// Has to end with a 0 terminator
VerifyOrExit(data_len > 0, isPrintable = false);
VerifyOrExit(data[data_len - 1] == 0, isPrintable = false);

// all other characters are printable
isPrintable = std::all_of(data, data + data_len - 1, isprint);

exit:
return isPrintable;
}

void newConnectionHandler(const MessageHeader & header, const IPPacketInfo & packet_info, SecureTransport * transport)
{
CHIP_ERROR err;

ESP_LOGI(TAG, "Received a new connection.");

VerifyOrExit(header.GetSourceNodeId().HasValue(), ESP_LOGE(TAG, "Unknown source for received message"));
VerifyOrExit(transport->GetPeerNodeId() != header.GetSourceNodeId().Value(), ESP_LOGI(TAG, "Node already known."));

err = transport->Connect(header.GetSourceNodeId().Value(), PeerAddress::UDP(packet_info.SrcAddress, packet_info.SrcPort));
VerifyOrExit(err == CHIP_NO_ERROR, ESP_LOGE(TAG, "Failed to connect transport"));

err = transport->ManualKeyExchange(remote_public_key, sizeof(remote_public_key), local_private_key, sizeof(local_private_key));
VerifyOrExit(err == CHIP_NO_ERROR, ESP_LOGE(TAG, "Failed to setup encryption"));

exit:
return;
}

// Transport Callbacks
static void echo(const MessageHeader & header, const IPPacketInfo & packet_info, System::PacketBuffer * buffer,
SecureTransport * transport)
void echo(const MessageHeader & header, const IPPacketInfo & packet_info, System::PacketBuffer * buffer,
SecureTransport * transport)
{
bool status = transport != NULL && buffer != NULL;
CHIP_ERROR err;
const size_t data_len = buffer->DataLength();

// as soon as a client connects, assume it is connected
VerifyOrExit(transport != NULL && buffer != NULL, ESP_LOGE(TAG, "Received data but couldn't process it..."));

VerifyOrExit(header.GetSourceNodeId().HasValue(), ESP_LOGE(TAG, "Unknown source for received message"));

if (status)
{
char src_addr[INET_ADDRSTRLEN];
char dest_addr[INET_ADDRSTRLEN];
const size_t data_len = buffer->DataLength();

packet_info.SrcAddress.ToString(src_addr, sizeof(src_addr));
packet_info.DestAddress.ToString(dest_addr, sizeof(dest_addr));

ESP_LOGI(TAG, "UDP packet received from %s:%u to %s:%u (%zu bytes)", src_addr, packet_info.SrcPort, dest_addr,
packet_info.DestPort, static_cast<size_t>(data_len));
}

if (data_len > 0 && buffer->Start()[0] < 0x20)
{
// Non-ACII; assume it's a data model message.
HandleDataModelMessage(buffer);
return;
}
if (!ContentIsAPrintableString(buffer))
{
// Non-ACII; assume it's a data model message.
HandleDataModelMessage(buffer);
buffer = NULL;
}
else
{

ESP_LOGI(TAG, "Client sent: \"%.*s\"", data_len, buffer->Start());

MessageHeader sendHeader;

sendHeader
.SetSourceNodeId(kLocalNodeId) //
.SetDestinationNodeId(header.GetSourceNodeId()) //
.SetMessageId(header.GetMessageId());

// Attempt to echo back
CHIP_ERROR err = transport->SendMessage(sendHeader, packet_info.SrcAddress, buffer);
err = transport->SendMessage(header.GetSourceNodeId().Value(), buffer);
buffer = NULL;
if (err != CHIP_NO_ERROR)
{
ESP_LOGE(TAG, "Unable to echo back to client: %s", ErrorStr(err));
Expand All @@ -97,27 +150,16 @@ static void echo(const MessageHeader & header, const IPPacketInfo & packet_info,
}
}

if (!status)
{
ESP_LOGE(TAG, "Received data but couldn't process it...");
exit:

// SendTo calls Free on the buffer without an AddRef, if SendTo was not called, free the buffer.
if (buffer != NULL)
{
System::PacketBuffer::Free(buffer);
}
// SendTo calls Free on the buffer without an AddRef, if SendTo was not called, free the buffer.
if (buffer != NULL)
{
System::PacketBuffer::Free(buffer);
}
}

static const unsigned char local_private_key[] = { 0xc6, 0x1a, 0x2f, 0x89, 0x36, 0x67, 0x2b, 0x26, 0x12, 0x47, 0x4f,
0x11, 0x0e, 0x34, 0x15, 0x81, 0x81, 0x12, 0xfc, 0x36, 0xeb, 0x65,
0x61, 0x07, 0xaa, 0x63, 0xe8, 0xc5, 0x22, 0xac, 0x52, 0xa1 };

static const unsigned char remote_public_key[] = { 0x04, 0x30, 0x77, 0x2c, 0xe7, 0xd4, 0x0a, 0xf2, 0xf3, 0x19, 0xbd, 0xfb, 0x1f,
0xcc, 0x88, 0xd9, 0x83, 0x25, 0x89, 0xf2, 0x09, 0xf3, 0xab, 0xe4, 0x33, 0xb6,
0x7a, 0xff, 0x73, 0x3b, 0x01, 0x35, 0x34, 0x92, 0x73, 0x14, 0x59, 0x0b, 0xbd,
0x44, 0x72, 0x1b, 0xcd, 0xb9, 0x02, 0x53, 0xd9, 0xaf, 0xcc, 0x1a, 0xcd, 0xae,
0xe8, 0x87, 0x2e, 0x52, 0x3b, 0x98, 0xf0, 0xa1, 0x88, 0x4a, 0xe3, 0x03, 0x75 };
} // namespace

// The echo server assumes the platform's networking has been setup already
void setupTransport(IPAddressType type, SecureTransport * transport)
Expand All @@ -130,13 +172,11 @@ void setupTransport(IPAddressType type, SecureTransport * transport)
tcpip_adapter_get_netif(TCPIP_ADAPTER_IF_AP, (void **) &netif);
}

err = transport->Init(&DeviceLayer::InetLayer, Transport::UdpListenParameters().SetAddressType(type).SetInterfaceId(netif));
err = transport->Init(kLocalNodeId, &DeviceLayer::InetLayer, UdpListenParameters().SetAddressType(type).SetInterfaceId(netif));
SuccessOrExit(err);

transport->SetMessageReceiveHandler(echo, transport);

err = transport->ManualKeyExchange(remote_public_key, sizeof(remote_public_key), local_private_key, sizeof(local_private_key));
SuccessOrExit(err);
transport->SetNewConnectionHandler(newConnectionHandler, transport);

exit:
if (err != CHIP_NO_ERROR)
Expand Down
78 changes: 28 additions & 50 deletions src/controller/CHIPDeviceController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,19 +51,19 @@ using namespace chip::Encoding;

ChipDeviceController::ChipDeviceController()
{
mState = kState_NotInitialized;
AppState = NULL;
mConState = kConnectionState_NotConnected;
mDeviceCon = NULL;
mCurReqMsg = NULL;
mOnError = NULL;
mDeviceAddr = IPAddress::Any;
mDevicePort = CHIP_PORT;
mDeviceId = 0;
mState = kState_NotInitialized;
AppState = NULL;
mConState = kConnectionState_NotConnected;
mDeviceCon = NULL;
mCurReqMsg = NULL;
mOnError = NULL;
mDeviceAddr = IPAddress::Any;
mDevicePort = CHIP_PORT;
mLocalDeviceId = 0;
memset(&mOnComplete, 0, sizeof(mOnComplete));
}

CHIP_ERROR ChipDeviceController::Init()
CHIP_ERROR ChipDeviceController::Init(NodeId localNodeId)
{
CHIP_ERROR err = CHIP_NO_ERROR;

Expand All @@ -88,7 +88,8 @@ CHIP_ERROR ChipDeviceController::Init()
}
SuccessOrExit(err);

mState = kState_Initialized;
mState = kState_Initialized;
mLocalDeviceId = localNodeId;

exit:
return err;
Expand Down Expand Up @@ -125,7 +126,7 @@ CHIP_ERROR ChipDeviceController::Shutdown()
return err;
}

CHIP_ERROR ChipDeviceController::ConnectDevice(uint64_t deviceId, IPAddress deviceAddr, void * appReqState,
CHIP_ERROR ChipDeviceController::ConnectDevice(NodeId remoteDeviceId, IPAddress deviceAddr, void * appReqState,
MessageReceiveHandler onMessageReceived, ErrorHandler onError, uint16_t devicePort)
{
CHIP_ERROR err = CHIP_NO_ERROR;
Expand All @@ -135,13 +136,16 @@ CHIP_ERROR ChipDeviceController::ConnectDevice(uint64_t deviceId, IPAddress devi
return CHIP_ERROR_INCORRECT_STATE;
}

mDeviceId = deviceId;
mDeviceAddr = deviceAddr;
mDevicePort = devicePort;
mAppReqState = appReqState;
mDeviceCon = new SecureTransport();
mRemoteDeviceId = Optional<NodeId>::Value(remoteDeviceId);
mDeviceAddr = deviceAddr;
mDevicePort = devicePort;
mAppReqState = appReqState;
mDeviceCon = new SecureTransport();

err = mDeviceCon->Init(mInetLayer, Transport::UdpListenParameters().SetAddressType(deviceAddr.Type()));
err = mDeviceCon->Init(mLocalDeviceId, mInetLayer, Transport::UdpListenParameters().SetAddressType(deviceAddr.Type()));
SuccessOrExit(err);

err = mDeviceCon->Connect(remoteDeviceId, Transport::PeerAddress::UDP(deviceAddr, devicePort));
SuccessOrExit(err);

mDeviceCon->SetMessageReceiveHandler(OnReceiveMessage, this);
Expand Down Expand Up @@ -183,27 +187,6 @@ CHIP_ERROR ChipDeviceController::ManualKeyExchange(const unsigned char * remote_
return err;
}

CHIP_ERROR ChipDeviceController::GetDeviceAddress(IPAddress * deviceAddr, uint16_t * devicePort)
{
CHIP_ERROR err = CHIP_NO_ERROR;

if (!IsSecurelyConnected())
{
return CHIP_ERROR_INCORRECT_STATE;
}

if (deviceAddr)
{
*deviceAddr = mDeviceAddr;
}
if (devicePort)
{
*devicePort = mDevicePort;
}

return err;
}

bool ChipDeviceController::IsConnected()
{
return kState_Initialized && (mConState == kConnectionState_Connected || mConState == kConnectionState_SecureConnected);
Expand Down Expand Up @@ -231,20 +214,15 @@ CHIP_ERROR ChipDeviceController::DisconnectDevice()

CHIP_ERROR ChipDeviceController::SendMessage(void * appReqState, PacketBuffer * buffer)
{
CHIP_ERROR err = CHIP_ERROR_INCORRECT_STATE;
CHIP_ERROR err = CHIP_NO_ERROR;

mAppReqState = appReqState;
if (IsSecurelyConnected())
{
MessageHeader header;
VerifyOrExit(mRemoteDeviceId.HasValue(), err = CHIP_ERROR_INCORRECT_STATE);

header
.SetSourceNodeId(mDeviceId) //
.SetDestinationNodeId(mRemoteDeviceId) //
.SetMessageId(mMessageNumber++);
mAppReqState = appReqState;
VerifyOrExit(IsSecurelyConnected(), err = CHIP_ERROR_INCORRECT_STATE);

err = mDeviceCon->SendMessage(header, mDeviceAddr, buffer);
}
err = mDeviceCon->SendMessage(mRemoteDeviceId.Value(), buffer);
exit:

return err;
}
Expand Down
Loading

0 comments on commit 4746858

Please sign in to comment.