Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add echo example apps to conduct end-to-end connectivity sanity check… #3836

Merged
merged 10 commits into from
Dec 8, 2020
2 changes: 2 additions & 0 deletions BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ if (current_toolchain != "${dir_pw_toolchain}/dummy:dummy") {
if (chip_build_tools) {
deps += [
"${chip_root}/examples/shell/standalone:chip-shell",
"${chip_root}/src/messaging/tests/echo:chip-echo-requester",
"${chip_root}/src/messaging/tests/echo:chip-echo-responder",
"${chip_root}/src/qrcodetool",
"${chip_root}/src/setup_payload",
]
Expand Down
60 changes: 60 additions & 0 deletions src/messaging/tests/echo/BUILD.gn
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# 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.

import("//build_overrides/chip.gni")

import("${chip_root}/build/chip/tools.gni")

assert(chip_build_tools)

executable("chip-echo-requester") {
sources = [
"common.cpp",
"echo_requester.cpp",
]

public_deps = [
"${chip_root}/src/lib/core",
"${chip_root}/src/lib/support",
"${chip_root}/src/platform",
"${chip_root}/src/protocols",
"${chip_root}/src/system",
]

output_dir = root_out_dir
}

executable("chip-echo-responder") {
sources = [
"common.cpp",
"echo_responder.cpp",
]

public_deps = [
"${chip_root}/src/lib/core",
"${chip_root}/src/lib/support",
"${chip_root}/src/platform",
"${chip_root}/src/protocols",
"${chip_root}/src/system",
]

output_dir = root_out_dir
}

group("echo") {
deps = [
":chip-echo-requester",
":chip-echo-responder",
]
}
51 changes: 51 additions & 0 deletions src/messaging/tests/echo/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# CHIP Example Application Tutorial

## Introduction

The CHIP Echo example application shows you how to implement a CHIP application
program using one of the supported CHIP protocols, namely the very simple CHIP
Echo protocol. This protocol allows you to send a CHIP message to a peer and
expect a CHIP response (similar to the ICMP Echo Request/Echo Response
messages).

CHIP Protocols are, essentially, implementations of specific protocols over the
CHIP transport. Furthermore, when two CHIP nodes are exchanging messages of a
particular CHIP protocol, they do so over a construct called a CHIP Exchange
which is a description of a CHIP-based conversation over a CHIP protocol. A CHIP
Exchange is characterised by the ExchangeContext object, and every CHIP node
must create an ExchangeContext object before initiating a CHIP conversation.

After constructing a CHIP ExchangeContext, CHIP messages are sent and received
using the ChipMessageLayer class which sends the CHIP message over a chosen
transport (TCP, UDP, or CRMP).

## Building

```
source scripts/activate.sh
gn gen out/debug
ninja -C out/debug
```

- After the applications are built, it can be found in the build directory as
`out/debug/chip-echo-requester and out/debug/chip-echo-responder`

## Example Applications Walk Through

As part of this example, we have a ChipEchoRequester program that acts as the
client and sends echo requests to a ChipEchoResponder program that receives
EchoRequests and sends back EchoResponse messages.

### Ping a device over IP

To start the Server in echo mode, run the built executable.

$ ./chip-echo-responder

To start the Client in echo mode, run the built executable and pass it the IP
address of the server to talk to.

$ ./chip-echo-requester <Server's IPv4 address>

If valid values are supplied, it will begin to periodically send messages to the
server address provided for three times.
99 changes: 99 additions & 0 deletions src/messaging/tests/echo/common.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
/*
*
* 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.
*/

/**
* @file
* This file implements constants, globals and interfaces common
* to and used by CHIP example applications.
*
*/

#include <errno.h>

#include "common.h"
#include <core/CHIPCore.h>
#include <platform/CHIPDeviceLayer.h>
#include <support/ErrorStr.h>

// The ExchangeManager global object.
chip::Messaging::ExchangeManager gExchangeManager;

void InitializeChip(void)
{
CHIP_ERROR err = CHIP_NO_ERROR;

printf("Init CHIP Stack\r\n");

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: the carriage return + line feed is in this function but not other places.


// Initialize System memory and resources
err = chip::Platform::MemoryInit();
SuccessOrExit(err);

// Initialize the CHIP stack.
err = chip::DeviceLayer::PlatformMgr().InitChipStack();
SuccessOrExit(err);

exit:
if (err != CHIP_NO_ERROR)
{
printf("Failed to init CHIP Stack with err: %s\r\n", chip::ErrorStr(err));
exit(EXIT_FAILURE);
}
}

void ShutdownChip(void)
{
gExchangeManager.Shutdown();
chip::DeviceLayer::SystemLayer.Shutdown();
}

void DriveIO(void)
{
struct timeval sleepTime;
fd_set readFDs, writeFDs, exceptFDs;
int numFDs = 0;
int selectRes;

sleepTime.tv_sec = 0;
sleepTime.tv_usec = NETWORK_SLEEP_TIME_MSECS;

FD_ZERO(&readFDs);
FD_ZERO(&writeFDs);
FD_ZERO(&exceptFDs);

if (chip::DeviceLayer::SystemLayer.State() == chip::System::kLayerState_Initialized)
chip::DeviceLayer::SystemLayer.PrepareSelect(numFDs, &readFDs, &writeFDs, &exceptFDs, sleepTime);

if (chip::DeviceLayer::InetLayer.State == chip::Inet::InetLayer::kState_Initialized)
chip::DeviceLayer::InetLayer.PrepareSelect(numFDs, &readFDs, &writeFDs, &exceptFDs, sleepTime);

selectRes = select(numFDs, &readFDs, &writeFDs, &exceptFDs, &sleepTime);
if (selectRes < 0)
{
printf("select failed: %s\n", chip::ErrorStr(chip::System::MapErrorPOSIX(errno)));
return;
}

if (chip::DeviceLayer::SystemLayer.State() == chip::System::kLayerState_Initialized)
{
chip::DeviceLayer::SystemLayer.HandleSelectResult(selectRes, &readFDs, &writeFDs, &exceptFDs);
}

if (chip::DeviceLayer::InetLayer.State == chip::Inet::InetLayer::kState_Initialized)
{
chip::DeviceLayer::InetLayer.HandleSelectResult(selectRes, &readFDs, &writeFDs, &exceptFDs);
}
}
36 changes: 36 additions & 0 deletions src/messaging/tests/echo/common.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
*
* 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.
*/

/**
* @file
* This file defines some of the common constants, globals and interfaces
* that are common to and used by CHIP example applications.
*
*/

#pragma once

#include <messaging/ExchangeMgr.h>

#define MAX_MESSAGE_SOURCE_STR_LENGTH (100)
#define NETWORK_SLEEP_TIME_MSECS (100 * 1000)

extern chip::Messaging::ExchangeManager gExchangeManager;

void InitializeChip(void);
void ShutdownChip(void);
void DriveIO(void);
Loading