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

[examples] Extract common Linux platform app start up code #6222

Merged
merged 7 commits into from
Apr 23, 2021
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions examples/all-clusters-app/linux/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ executable("chip-all-clusters-app") {

deps = [
"${chip_root}/examples/all-clusters-app/all-clusters-common",
"${chip_root}/examples/platform/linux:chip_examples_project_linux_platform_main",
"${chip_root}/src/lib",
]

Expand Down
27 changes: 3 additions & 24 deletions examples/all-clusters-app/linux/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
#include <support/CHIPMem.h>
#include <support/RandUtils.h>

#include "Server.h"
#include "AppMain.h"

#include <cassert>
#include <iostream>
Expand All @@ -54,28 +54,7 @@ bool emberAfBasicClusterMfgSpecificPingCallback(chip::app::Command * commandObj)

int main(int argc, char * argv[])
{
CHIP_ERROR err = CHIP_NO_ERROR;

err = chip::Platform::MemoryInit();
SuccessOrExit(err);

err = chip::DeviceLayer::PlatformMgr().InitChipStack();
SuccessOrExit(err);

// Init ZCL Data Model and CHIP App Server
InitServer();

// Init Mdns Server
app::Mdns::StartServer();

chip::DeviceLayer::PlatformMgr().RunEventLoop();

exit:
if (err != CHIP_NO_ERROR)
{
std::cerr << "Failed to run All Clusters App: " << ErrorStr(err) << std::endl;
// End the program with non zero error code to indicate a error.
return 1;
}
VerifyOrDie(ChipLinuxAppInit(argc, argv) == 0);
ChipLinuxAppMainLoop();
return 0;
}
2 changes: 1 addition & 1 deletion examples/lighting-app/linux/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,13 @@ config("includes") {
executable("chip-lighting-app") {
sources = [
"LightingManager.cpp",
"Options.cpp",
"include/LightingManager.h",
"main.cpp",
]

deps = [
"${chip_root}/examples/lighting-app/lighting-common",
"${chip_root}/examples/platform/linux:chip_examples_project_linux_platform_main",
"${chip_root}/src/lib",
]

Expand Down
132 changes: 4 additions & 128 deletions examples/lighting-app/linux/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,25 +16,17 @@
* limitations under the License.
*/

#include <platform/CHIPDeviceLayer.h>
#include <platform/PlatformManager.h>

#include "af.h"
#include "gen/attribute-id.h"
#include "gen/cluster-id.h"
#include <app/chip-zcl-zpro-codec.h>
#include <app/util/af-types.h>
#include <app/util/attribute-storage.h>
#include <app/util/util.h>
#include <core/CHIPError.h>
#include <setup_payload/QRCodeSetupPayloadGenerator.h>
#include <setup_payload/SetupPayload.h>
#include <support/CHIPMem.h>
#include <support/RandUtils.h>

#include "LightingManager.h"
#include "Options.h"
#include "Server.h"

#include <AppMain.h>

#if defined(PW_RPC_ENABLED)
#include "Rpc.h"
Expand All @@ -44,8 +36,6 @@
#include <iostream>

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

void emberAfPostAttributeChangeCallback(EndpointId endpoint, ClusterId clusterId, AttributeId attributeId, uint8_t mask,
Expand Down Expand Up @@ -93,124 +83,10 @@ void emberAfOnOffClusterInitCallback(EndpointId endpoint)
// TODO: implement any additional Cluster Server init actions
}

namespace {
void EventHandler(const chip::DeviceLayer::ChipDeviceEvent * event, intptr_t arg)
{
(void) arg;
if (event->Type == chip::DeviceLayer::DeviceEventType::kCHIPoBLEConnectionEstablished)
{
ChipLogProgress(DeviceLayer, "Receive kCHIPoBLEConnectionEstablished");
}
}

CHIP_ERROR PrintQRCodeContent()
{
CHIP_ERROR err = CHIP_NO_ERROR;
// If we do not have a discriminator, generate one
chip::SetupPayload payload;
uint32_t setUpPINCode;
uint16_t setUpDiscriminator;
uint16_t vendorId;
uint16_t productId;
std::string result;

err = ConfigurationMgr().GetSetupPinCode(setUpPINCode);
SuccessOrExit(err);

err = ConfigurationMgr().GetSetupDiscriminator(setUpDiscriminator);
SuccessOrExit(err);

err = ConfigurationMgr().GetVendorId(vendorId);
SuccessOrExit(err);

err = ConfigurationMgr().GetProductId(productId);
SuccessOrExit(err);

payload.version = 0;
payload.vendorID = vendorId;
payload.productID = productId;
payload.setUpPINCode = setUpPINCode;
payload.discriminator = setUpDiscriminator;

// Wrap it so SuccessOrExit can work
{
chip::QRCodeSetupPayloadGenerator generator(payload);
err = generator.payloadBase41Representation(result);
SuccessOrExit(err);
}

std::cout << "SetupPINCode: [" << setUpPINCode << "]" << std::endl;
// There might be whitespace in setup QRCode, add brackets to make it clearer.
std::cout << "SetupQRCode: [" << result << "]" << std::endl;

exit:
if (err != CHIP_NO_ERROR)
{
std::cerr << "Failed to generate QR Code: " << ErrorStr(err) << std::endl;
}
return err;
}
} // namespace

int main(int argc, char * argv[])
{
CHIP_ERROR err = CHIP_NO_ERROR;

err = chip::Platform::MemoryInit();
SuccessOrExit(err);

err = ParseArguments(argc, argv);
SuccessOrExit(err);

err = chip::DeviceLayer::PlatformMgr().InitChipStack();
SuccessOrExit(err);

err = PrintQRCodeContent();
SuccessOrExit(err);

#if defined(PW_RPC_ENABLED)
chip::rpc::Init();
std::cerr << "PW_RPC initialized." << std::endl;
#endif // defined(PW_RPC_ENABLED)

chip::DeviceLayer::PlatformMgrImpl().AddEventHandler(EventHandler, 0);

chip::DeviceLayer::ConnectivityMgr().SetBLEDeviceName(nullptr); // Use default device name (CHIP-XXXX)

#if CONFIG_NETWORK_LAYER_BLE
chip::DeviceLayer::Internal::BLEMgrImpl().ConfigureBle(LinuxDeviceOptions::GetInstance().mBleDevice, false);
#endif

chip::DeviceLayer::ConnectivityMgr().SetBLEAdvertisingEnabled(true);

VerifyOrDie(ChipLinuxAppInit(argc, argv) == 0);
LightingMgr().Init();

// Init ZCL Data Model and CHIP App Server
InitServer();

#if CHIP_DEVICE_CONFIG_ENABLE_WPA
if (LinuxDeviceOptions::GetInstance().mWiFi)
{
chip::DeviceLayer::ConnectivityMgrImpl().StartWiFiManagement();
}
#endif // CHIP_DEVICE_CONFIG_ENABLE_WPA

#if CHIP_ENABLE_OPENTHREAD
if (LinuxDeviceOptions::GetInstance().mThread)
{
SuccessOrExit(err = chip::DeviceLayer::ThreadStackMgrImpl().InitThreadStack());
std::cerr << "Thread initialized." << std::endl;
}
#endif // CHIP_ENABLE_OPENTHREAD

chip::DeviceLayer::PlatformMgr().RunEventLoop();

exit:
if (err != CHIP_NO_ERROR)
{
std::cerr << "Failed to run Linux Lighting App: " << ErrorStr(err) << std::endl;
// End the program with non zero error code to indicate a error.
return 1;
}
ChipLinuxAppMainLoop();
return 0;
}
144 changes: 144 additions & 0 deletions examples/platform/linux/AppMain.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@


#include <iostream>
#include <thread>

#include <platform/CHIPDeviceLayer.h>
#include <platform/PlatformManager.h>

#include <app/server/Server.h>
#include <core/CHIPError.h>
#include <setup_payload/QRCodeSetupPayloadGenerator.h>
#include <setup_payload/SetupPayload.h>
#include <support/CHIPMem.h>
#include <support/RandUtils.h>

#include "Options.h"

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

namespace {
void EventHandler(const chip::DeviceLayer::ChipDeviceEvent * event, intptr_t arg)
{
(void) arg;
if (event->Type == chip::DeviceLayer::DeviceEventType::kCHIPoBLEConnectionEstablished)
{
ChipLogProgress(DeviceLayer, "Receive kCHIPoBLEConnectionEstablished");
}
}

CHIP_ERROR PrintQRCodeContent()
erjiaqing marked this conversation as resolved.
Show resolved Hide resolved
{
CHIP_ERROR err = CHIP_NO_ERROR;
// If we do not have a discriminator, generate one
chip::SetupPayload payload;
uint32_t setUpPINCode;
uint16_t setUpDiscriminator;
uint16_t vendorId;
uint16_t productId;
std::string result;

err = ConfigurationMgr().GetSetupPinCode(setUpPINCode);
SuccessOrExit(err);

err = ConfigurationMgr().GetSetupDiscriminator(setUpDiscriminator);
SuccessOrExit(err);

err = ConfigurationMgr().GetVendorId(vendorId);
SuccessOrExit(err);

err = ConfigurationMgr().GetProductId(productId);
SuccessOrExit(err);

payload.version = 0;
payload.vendorID = vendorId;
payload.productID = productId;
payload.setUpPINCode = setUpPINCode;
payload.discriminator = setUpDiscriminator;

// Wrap it so SuccessOrExit can work
{
chip::QRCodeSetupPayloadGenerator generator(payload);
err = generator.payloadBase41Representation(result);
SuccessOrExit(err);
}

std::cout << "SetupPINCode: [" << setUpPINCode << "]" << std::endl;
// There might be whitespace in setup QRCode, add brackets to make it clearer.
std::cout << "SetupQRCode: [" << result << "]" << std::endl;

exit:
if (err != CHIP_NO_ERROR)
{
std::cerr << "Failed to generate QR Code: " << ErrorStr(err) << std::endl;
}
return err;
}
} // namespace

int ChipLinuxAppInit(int argc, char ** argv)
{
CHIP_ERROR err = CHIP_NO_ERROR;

err = chip::Platform::MemoryInit();
SuccessOrExit(err);

err = ParseArguments(argc, argv);
SuccessOrExit(err);

err = chip::DeviceLayer::PlatformMgr().InitChipStack();
SuccessOrExit(err);

err = PrintQRCodeContent();
SuccessOrExit(err);

#if defined(PW_RPC_ENABLED)
Copy link
Contributor

Choose a reason for hiding this comment

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

This won't work without relocating the defines.

chip::rpc::Init();
std::cerr << "PW_RPC initialized." << std::endl;
#endif // defined(PW_RPC_ENABLED)

chip::DeviceLayer::PlatformMgrImpl().AddEventHandler(EventHandler, 0);

chip::DeviceLayer::ConnectivityMgr().SetBLEDeviceName(nullptr); // Use default device name (CHIP-XXXX)

#if CONFIG_NETWORK_LAYER_BLE
chip::DeviceLayer::Internal::BLEMgrImpl().ConfigureBle(LinuxDeviceOptions::GetInstance().mBleDevice, false);
#endif

chip::DeviceLayer::ConnectivityMgr().SetBLEAdvertisingEnabled(true);

#if CHIP_DEVICE_CONFIG_ENABLE_WPA
if (LinuxDeviceOptions::GetInstance().mWiFi)
{
chip::DeviceLayer::ConnectivityMgrImpl().StartWiFiManagement();
}
#endif // CHIP_DEVICE_CONFIG_ENABLE_WPA

#if CHIP_ENABLE_OPENTHREAD
if (LinuxDeviceOptions::GetInstance().mThread)
{
SuccessOrExit(err = chip::DeviceLayer::ThreadStackMgrImpl().InitThreadStack());
std::cerr << "Thread initialized." << std::endl;
Copy link
Contributor

Choose a reason for hiding this comment

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

Shouldn't we use the CHIP logging subsystem here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, however, when taking look at other apps, we use the log api provided by platform directly. And when building real apps, the library other than CHIP may also print their log. Maybe we can provide a log module called "CHIPApp" for apps that want to print the logs of calling CHIP apis, or introduce some logging framework to Linux/Posix so we can avoid the use of writting logs to stderr directly?

Copy link
Contributor

Choose a reason for hiding this comment

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

I guess you're right. There are cases to be made on either side. Yes, you can consider libCHIP one of many libraries, all of which have their own logging. And I don't think we need a separate App logging interface. In this context, I suppose calling to the CHIP logger simply gives some useful context and log line prefixes.

As an aside, the Linux platform is logging to stdout, not stderr, which itself seems like a poor practice.

}
#endif // CHIP_ENABLE_OPENTHREAD

exit:
if (err != CHIP_NO_ERROR)
{
std::cerr << "Failed to run Linux Lighting App: " << ErrorStr(err) << std::endl;
// End the program with non zero error code to indicate a error.
return 1;
}
return 0;
}

void ChipLinuxAppMainLoop()
{
// Init ZCL Data Model and CHIP App Server
InitServer();

chip::DeviceLayer::PlatformMgr().RunEventLoop();
}
4 changes: 4 additions & 0 deletions examples/platform/linux/AppMain.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#pragma once
erjiaqing marked this conversation as resolved.
Show resolved Hide resolved

int ChipLinuxAppInit(int argc, char ** argv);
void ChipLinuxAppMainLoop();
Loading