From c52c2d468af78d8e926e0a752818258ceda3712f Mon Sep 17 00:00:00 2001 From: Yufeng Wang Date: Tue, 20 Jul 2021 22:32:54 -0700 Subject: [PATCH 1/5] [TE4] Enable setup code options in linux example apps --- examples/bridge-app/linux/include/Options.h | 2 + examples/platform/linux/AppMain.cpp | 17 ++-- examples/platform/linux/Options.cpp | 89 ++++++++++++++++++--- examples/platform/linux/Options.h | 2 + src/app/server/OnboardingCodesUtil.cpp | 57 +++++++++++++ src/app/server/OnboardingCodesUtil.h | 3 + 6 files changed, 152 insertions(+), 18 deletions(-) diff --git a/examples/bridge-app/linux/include/Options.h b/examples/bridge-app/linux/include/Options.h index 4e0ee2084cdc33..83d90c9d9f097e 100644 --- a/examples/bridge-app/linux/include/Options.h +++ b/examples/bridge-app/linux/include/Options.h @@ -27,9 +27,11 @@ #include #include +#include struct LinuxDeviceOptions { + chip::SetupPayload payload; uint32_t mBleDevice = 0; static LinuxDeviceOptions & GetInstance(); diff --git a/examples/platform/linux/AppMain.cpp b/examples/platform/linux/AppMain.cpp index 614a3618775866..89bcd3b6273778 100644 --- a/examples/platform/linux/AppMain.cpp +++ b/examples/platform/linux/AppMain.cpp @@ -72,11 +72,19 @@ void EventHandler(const chip::DeviceLayer::ChipDeviceEvent * event, intptr_t arg int ChipLinuxAppInit(int argc, char ** argv) { - CHIP_ERROR err = CHIP_NO_ERROR; + CHIP_ERROR err = CHIP_NO_ERROR; + chip::RendezvousInformationFlags rendezvousFlags = chip::RendezvousInformationFlag::kBLE; + +#ifdef CONFIG_RENDEZVOUS_MODE + rendezvousFlags = static_cast(CONFIG_RENDEZVOUS_MODE); +#endif err = chip::Platform::MemoryInit(); SuccessOrExit(err); + err = GetSetupPayload(LinuxDeviceOptions::GetInstance().payload, rendezvousFlags); + SuccessOrExit(err); + err = ParseArguments(argc, argv); SuccessOrExit(err); @@ -84,11 +92,8 @@ int ChipLinuxAppInit(int argc, char ** argv) SuccessOrExit(err); ConfigurationMgr().LogDeviceConfig(); -#ifdef CONFIG_RENDEZVOUS_MODE - PrintOnboardingCodes(static_cast(CONFIG_RENDEZVOUS_MODE)); -#else - PrintOnboardingCodes(chip::RendezvousInformationFlag::kBLE); -#endif + + PrintOnboardingCodes(LinuxDeviceOptions::GetInstance().payload); #if defined(PW_RPC_ENABLED) chip::rpc::Init(); diff --git a/examples/platform/linux/Options.cpp b/examples/platform/linux/Options.cpp index 20a0b6e9c6e90f..7b3cfc6ee9ee96 100644 --- a/examples/platform/linux/Options.cpp +++ b/examples/platform/linux/Options.cpp @@ -18,6 +18,7 @@ #include "Options.h" +#include #include #include @@ -32,9 +33,16 @@ LinuxDeviceOptions gDeviceOptions; // Follow the code style of command line arguments in case we need to add more options in the future. enum { - kDeviceOption_BleDevice = 0x1000, - kDeviceOption_WiFi = 0x1001, - kDeviceOption_Thread = 0x1002, + kDeviceOption_BleDevice = 0x1000, + kDeviceOption_WiFi = 0x1001, + kDeviceOption_Thread = 0x1002, + kDeviceOption_Version = 0x1003, + kDeviceOption_VendorID = 0x1004, + kDeviceOption_ProductID = 0x1005, + kDeviceOption_CustomFlow = 0x1006, + kDeviceOption_Capabilities = 0x1007, + kDeviceOption_Discriminator = 0x1008, + kDeviceOption_Passcode = 0x1009 }; constexpr unsigned kAppUsageLength = 64; @@ -46,21 +54,50 @@ OptionDef sDeviceOptionDefs[] = { { "ble-device", kArgumentRequired, kDeviceOpti #if CHIP_ENABLE_OPENTHREAD { "thread", kNoArgument, kDeviceOption_Thread }, #endif // CHIP_ENABLE_OPENTHREAD + { "version", kArgumentRequired, kDeviceOption_Version }, + { "vendor-id", kArgumentRequired, kDeviceOption_VendorID }, + { "product-id", kArgumentRequired, kDeviceOption_ProductID }, + { "custom-flow", kArgumentRequired, kDeviceOption_CustomFlow }, + { "capabilities", kArgumentRequired, kDeviceOption_Capabilities }, + { "discriminator", kArgumentRequired, kDeviceOption_Discriminator }, + { "passcode", kArgumentRequired, kDeviceOption_Passcode }, {} }; -const char * sDeviceOptionHelp = " --ble-device \n" - " The device number for CHIPoBLE, without 'hci' prefix, can be found by hciconfig.\n" +const char * sDeviceOptionHelp = + " --ble-device \n" + " The device number for CHIPoBLE, without 'hci' prefix, can be found by hciconfig.\n" #if CHIP_DEVICE_CONFIG_ENABLE_WPA - "\n" - " --wifi\n" - " Enable WiFi management via wpa_supplicant.\n" + "\n" + " --wifi\n" + " Enable WiFi management via wpa_supplicant.\n" #endif // CHIP_DEVICE_CONFIG_ENABLE_WPA #if CHIP_ENABLE_OPENTHREAD - "\n" - " --thread\n" - " Enable Thread management via ot-agent.\n" + "\n" + " --thread\n" + " Enable Thread management via ot-agent.\n" #endif // CHIP_ENABLE_OPENTHREAD - "\n"; + "\n" + " --version \n" + " The version indication provides versioning of the setup payload.\n" + "\n" + " --vendor-id \n" + " The Vendor ID is assigned by the Connectivity Standards Alliance.\n" + "\n" + " --product-id \n" + " The Product ID is specified by vendor.\n" + "\n" + " --custom-flow \n" + " A 2-bit unsigned enumeration specifying manufacturer-specific custom flow options.\n" + "\n" + " --capabilities \n" + " Discovery Capabilities Bitmask which contains information about Device’s available technologies for device discovery.\n" + "\n" + " --discriminator \n" + " A 12-bit unsigned integer match the value which a device advertises during commissioning.\n" + "\n" + " --passcode \n" + " A 27-bit unsigned integer, which serves as proof of possession during commissioning.\n" + "\n"; bool HandleOption(const char * aProgram, OptionSet * aOptions, int aIdentifier, const char * aName, const char * aValue) { @@ -85,6 +122,34 @@ bool HandleOption(const char * aProgram, OptionSet * aOptions, int aIdentifier, LinuxDeviceOptions::GetInstance().mThread = true; break; + case kDeviceOption_Version: + LinuxDeviceOptions::GetInstance().payload.version = static_cast(atoi(aValue)); + break; + + case kDeviceOption_VendorID: + LinuxDeviceOptions::GetInstance().payload.vendorID = static_cast(atoi(aValue)); + break; + + case kDeviceOption_ProductID: + LinuxDeviceOptions::GetInstance().payload.productID = static_cast(atoi(aValue)); + break; + + case kDeviceOption_CustomFlow: + LinuxDeviceOptions::GetInstance().payload.commissioningFlow = static_cast(atoi(aValue)); + break; + + case kDeviceOption_Capabilities: + LinuxDeviceOptions::GetInstance().payload.rendezvousInformation.SetRaw(static_cast(atoi(aValue))); + break; + + case kDeviceOption_Discriminator: + LinuxDeviceOptions::GetInstance().payload.discriminator = static_cast(atoi(aValue)); + break; + + case kDeviceOption_Passcode: + LinuxDeviceOptions::GetInstance().payload.setUpPINCode = static_cast(atoi(aValue)); + break; + default: PrintArgError("%s: INTERNAL ERROR: Unhandled option: %s\n", aProgram, aName); retval = false; diff --git a/examples/platform/linux/Options.h b/examples/platform/linux/Options.h index 1ecc372ff6bdf2..da4493bf1d530e 100644 --- a/examples/platform/linux/Options.h +++ b/examples/platform/linux/Options.h @@ -27,9 +27,11 @@ #include #include +#include struct LinuxDeviceOptions { + chip::SetupPayload payload; uint32_t mBleDevice = 0; bool mWiFi = false; bool mThread = false; diff --git a/src/app/server/OnboardingCodesUtil.cpp b/src/app/server/OnboardingCodesUtil.cpp index 99f6a3dc3f8888..6eabea53fd4222 100644 --- a/src/app/server/OnboardingCodesUtil.cpp +++ b/src/app/server/OnboardingCodesUtil.cpp @@ -67,6 +67,39 @@ void PrintOnboardingCodes(chip::RendezvousInformationFlags aRendezvousFlags) } } +void PrintOnboardingCodes(const chip::SetupPayload & payload) +{ + std::string QRCode; + std::string manualPairingCode; + + if (GetQRCode(QRCode, payload) == CHIP_NO_ERROR) + { + chip::Platform::ScopedMemoryBuffer qrCodeBuffer; + const size_t qrCodeBufferMaxSize = strlen(kQrCodeBaseUrl) + strlen(kUrlDataAssignmentPhrase) + 3 * QRCode.size() + 1; + qrCodeBuffer.Alloc(qrCodeBufferMaxSize); + + ChipLogProgress(AppServer, "SetupQRCode: [%s]", QRCode.c_str()); + if (GetQRCodeUrl(&qrCodeBuffer[0], qrCodeBufferMaxSize, QRCode) == CHIP_NO_ERROR) + { + ChipLogProgress(AppServer, "Copy/paste the below URL in a browser to see the QR Code:"); + ChipLogProgress(AppServer, "%s", &qrCodeBuffer[0]); + } + } + else + { + ChipLogError(AppServer, "Getting QR code failed!"); + } + + if (GetManualPairingCode(manualPairingCode, payload) == CHIP_NO_ERROR) + { + ChipLogProgress(AppServer, "Manual pairing code: [%s]", manualPairingCode.c_str()); + } + else + { + ChipLogError(AppServer, "Getting manual pairing code failed!"); + } +} + #if CHIP_DEVICE_CONFIG_ENABLE_NFC void ShareQRCodeOverNFC(chip::RendezvousInformationFlags aRendezvousFlags) { @@ -138,6 +171,18 @@ CHIP_ERROR GetQRCode(std::string & aQRCode, chip::RendezvousInformationFlags aRe return CHIP_NO_ERROR; } +CHIP_ERROR GetQRCode(std::string & aQRCode, const chip::SetupPayload & payload) +{ + CHIP_ERROR err = chip::QRCodeSetupPayloadGenerator(payload).payloadBase38Representation(aQRCode); + if (err != CHIP_NO_ERROR) + { + ChipLogProgress(AppServer, "Generating QR Code failed: %s", chip::ErrorStr(err)); + return err; + } + + return CHIP_NO_ERROR; +} + CHIP_ERROR GetQRCodeUrl(char * aQRCodeUrl, size_t aUrlMaxSize, const std::string & aQRCode) { VerifyOrReturnError(aQRCodeUrl, CHIP_ERROR_INVALID_ARGUMENT); @@ -173,6 +218,18 @@ CHIP_ERROR GetManualPairingCode(std::string & aManualPairingCode, chip::Rendezvo return CHIP_NO_ERROR; } +CHIP_ERROR GetManualPairingCode(std::string & aManualPairingCode, const chip::SetupPayload & payload) +{ + CHIP_ERROR err = chip::ManualSetupPayloadGenerator(payload).payloadDecimalStringRepresentation(aManualPairingCode); + if (err != CHIP_NO_ERROR) + { + ChipLogProgress(AppServer, "Generating Manual Pairing Code failed: %s", chip::ErrorStr(err)); + return err; + } + + return CHIP_NO_ERROR; +} + static inline bool isCharUnreservedInRfc3986(const char c) { return isalpha(c) || isdigit(c) || (strchr(kSpecialCharsUnreservedInRfc3986, c) != nullptr); diff --git a/src/app/server/OnboardingCodesUtil.h b/src/app/server/OnboardingCodesUtil.h index 9aec2e05e1ccbf..1d2cb73022365e 100644 --- a/src/app/server/OnboardingCodesUtil.h +++ b/src/app/server/OnboardingCodesUtil.h @@ -20,10 +20,13 @@ #include void PrintOnboardingCodes(chip::RendezvousInformationFlags aRendezvousFlags); +void PrintOnboardingCodes(const chip::SetupPayload & payload); void ShareQRCodeOverNFC(chip::RendezvousInformationFlags aRendezvousFlags); CHIP_ERROR GetQRCode(std::string & QRCode, chip::RendezvousInformationFlags aRendezvousFlags); +CHIP_ERROR GetQRCode(std::string & QRCode, const chip::SetupPayload & payload); CHIP_ERROR GetQRCodeUrl(char * aQRCodeUrl, size_t aUrlMaxSize, const std::string & aQRCode); CHIP_ERROR GetManualPairingCode(std::string & aManualPairingCode, chip::RendezvousInformationFlags aRendezvousFlags); +CHIP_ERROR GetManualPairingCode(std::string & aManualPairingCode, const chip::SetupPayload & payload); CHIP_ERROR GetSetupPayload(chip::SetupPayload & aSetupPayload, chip::RendezvousInformationFlags aRendezvousFlags); /** From c30ad34f446e89561d72f81e3b754dfe9b0efd07 Mon Sep 17 00:00:00 2001 From: Justin Wood Date: Thu, 22 Jul 2021 02:20:19 +0000 Subject: [PATCH 2/5] Update src/app/server/OnboardingCodesUtil.cpp Co-authored-by: Boris Zbarsky --- src/app/server/OnboardingCodesUtil.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/server/OnboardingCodesUtil.cpp b/src/app/server/OnboardingCodesUtil.cpp index 6eabea53fd4222..b068264fb0c106 100644 --- a/src/app/server/OnboardingCodesUtil.cpp +++ b/src/app/server/OnboardingCodesUtil.cpp @@ -82,7 +82,7 @@ void PrintOnboardingCodes(const chip::SetupPayload & payload) if (GetQRCodeUrl(&qrCodeBuffer[0], qrCodeBufferMaxSize, QRCode) == CHIP_NO_ERROR) { ChipLogProgress(AppServer, "Copy/paste the below URL in a browser to see the QR Code:"); - ChipLogProgress(AppServer, "%s", &qrCodeBuffer[0]); + ChipLogProgress(AppServer, "%s", qrCodeBuffer.Get()); } } else From 75da0084e24b2e123a4131ae1f170e109a412935 Mon Sep 17 00:00:00 2001 From: Justin Wood Date: Thu, 22 Jul 2021 02:20:23 +0000 Subject: [PATCH 3/5] Update src/app/server/OnboardingCodesUtil.cpp Co-authored-by: Boris Zbarsky --- src/app/server/OnboardingCodesUtil.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/server/OnboardingCodesUtil.cpp b/src/app/server/OnboardingCodesUtil.cpp index b068264fb0c106..4ffc3c515f3699 100644 --- a/src/app/server/OnboardingCodesUtil.cpp +++ b/src/app/server/OnboardingCodesUtil.cpp @@ -79,7 +79,7 @@ void PrintOnboardingCodes(const chip::SetupPayload & payload) qrCodeBuffer.Alloc(qrCodeBufferMaxSize); ChipLogProgress(AppServer, "SetupQRCode: [%s]", QRCode.c_str()); - if (GetQRCodeUrl(&qrCodeBuffer[0], qrCodeBufferMaxSize, QRCode) == CHIP_NO_ERROR) + if (GetQRCodeUrl(qrCodeBuffer.Get(), qrCodeBufferMaxSize, QRCode) == CHIP_NO_ERROR) { ChipLogProgress(AppServer, "Copy/paste the below URL in a browser to see the QR Code:"); ChipLogProgress(AppServer, "%s", qrCodeBuffer.Get()); From 2bc4d6a76d67c2b35b729c2fc037ba48bf6b3783 Mon Sep 17 00:00:00 2001 From: Yufeng Wang Date: Fri, 23 Jul 2021 12:40:34 -0700 Subject: [PATCH 4/5] Rename QRCode to qrCode --- src/app/server/OnboardingCodesUtil.cpp | 26 +++++++++++++------------- src/app/server/OnboardingCodesUtil.h | 4 ++-- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/src/app/server/OnboardingCodesUtil.cpp b/src/app/server/OnboardingCodesUtil.cpp index 4ffc3c515f3699..a4cfde4980a6d2 100644 --- a/src/app/server/OnboardingCodesUtil.cpp +++ b/src/app/server/OnboardingCodesUtil.cpp @@ -36,17 +36,17 @@ using namespace ::chip::DeviceLayer; void PrintOnboardingCodes(chip::RendezvousInformationFlags aRendezvousFlags) { - std::string QRCode; + std::string qrCode; std::string manualPairingCode; - if (GetQRCode(QRCode, aRendezvousFlags) == CHIP_NO_ERROR) + if (GetQRCode(qrCode, aRendezvousFlags) == CHIP_NO_ERROR) { chip::Platform::ScopedMemoryBuffer qrCodeBuffer; - const size_t qrCodeBufferMaxSize = strlen(kQrCodeBaseUrl) + strlen(kUrlDataAssignmentPhrase) + 3 * QRCode.size() + 1; + const size_t qrCodeBufferMaxSize = strlen(kQrCodeBaseUrl) + strlen(kUrlDataAssignmentPhrase) + 3 * qrCode.size() + 1; qrCodeBuffer.Alloc(qrCodeBufferMaxSize); - ChipLogProgress(AppServer, "SetupQRCode: [%s]", QRCode.c_str()); - if (GetQRCodeUrl(&qrCodeBuffer[0], qrCodeBufferMaxSize, QRCode) == CHIP_NO_ERROR) + ChipLogProgress(AppServer, "SetupQRCode: [%s]", qrCode.c_str()); + if (GetQRCodeUrl(&qrCodeBuffer[0], qrCodeBufferMaxSize, qrCode) == CHIP_NO_ERROR) { ChipLogProgress(AppServer, "Copy/paste the below URL in a browser to see the QR Code:"); ChipLogProgress(AppServer, "%s", &qrCodeBuffer[0]); @@ -69,17 +69,17 @@ void PrintOnboardingCodes(chip::RendezvousInformationFlags aRendezvousFlags) void PrintOnboardingCodes(const chip::SetupPayload & payload) { - std::string QRCode; + std::string qrCode; std::string manualPairingCode; - if (GetQRCode(QRCode, payload) == CHIP_NO_ERROR) + if (GetQRCode(qrCode, payload) == CHIP_NO_ERROR) { chip::Platform::ScopedMemoryBuffer qrCodeBuffer; - const size_t qrCodeBufferMaxSize = strlen(kQrCodeBaseUrl) + strlen(kUrlDataAssignmentPhrase) + 3 * QRCode.size() + 1; + const size_t qrCodeBufferMaxSize = strlen(kQrCodeBaseUrl) + strlen(kUrlDataAssignmentPhrase) + 3 * qrCode.size() + 1; qrCodeBuffer.Alloc(qrCodeBufferMaxSize); - ChipLogProgress(AppServer, "SetupQRCode: [%s]", QRCode.c_str()); - if (GetQRCodeUrl(qrCodeBuffer.Get(), qrCodeBufferMaxSize, QRCode) == CHIP_NO_ERROR) + ChipLogProgress(AppServer, "SetupQRCode: [%s]", qrCode.c_str()); + if (GetQRCodeUrl(qrCodeBuffer.Get(), qrCodeBufferMaxSize, qrCode) == CHIP_NO_ERROR) { ChipLogProgress(AppServer, "Copy/paste the below URL in a browser to see the QR Code:"); ChipLogProgress(AppServer, "%s", qrCodeBuffer.Get()); @@ -104,10 +104,10 @@ void PrintOnboardingCodes(const chip::SetupPayload & payload) void ShareQRCodeOverNFC(chip::RendezvousInformationFlags aRendezvousFlags) { // Get QR Code and emulate its content using NFC tag - std::string QRCode; - ReturnOnFailure(GetQRCode(QRCode, chip::RendezvousInformationFlags(chip::RendezvousInformationFlag::kBLE))); + std::string qrCode; + ReturnOnFailure(GetQRCode(qrCode, chip::RendezvousInformationFlags(chip::RendezvousInformationFlag::kBLE))); - ReturnOnFailure(NFCMgr().StartTagEmulation(QRCode.c_str(), QRCode.size())); + ReturnOnFailure(NFCMgr().StartTagEmulation(qrCode.c_str(), qrCode.size())); } #endif diff --git a/src/app/server/OnboardingCodesUtil.h b/src/app/server/OnboardingCodesUtil.h index 1d2cb73022365e..e586b852c132eb 100644 --- a/src/app/server/OnboardingCodesUtil.h +++ b/src/app/server/OnboardingCodesUtil.h @@ -22,8 +22,8 @@ void PrintOnboardingCodes(chip::RendezvousInformationFlags aRendezvousFlags); void PrintOnboardingCodes(const chip::SetupPayload & payload); void ShareQRCodeOverNFC(chip::RendezvousInformationFlags aRendezvousFlags); -CHIP_ERROR GetQRCode(std::string & QRCode, chip::RendezvousInformationFlags aRendezvousFlags); -CHIP_ERROR GetQRCode(std::string & QRCode, const chip::SetupPayload & payload); +CHIP_ERROR GetQRCode(std::string & aQRCode, chip::RendezvousInformationFlags aRendezvousFlags); +CHIP_ERROR GetQRCode(std::string & aQRCode, const chip::SetupPayload & payload); CHIP_ERROR GetQRCodeUrl(char * aQRCodeUrl, size_t aUrlMaxSize, const std::string & aQRCode); CHIP_ERROR GetManualPairingCode(std::string & aManualPairingCode, chip::RendezvousInformationFlags aRendezvousFlags); CHIP_ERROR GetManualPairingCode(std::string & aManualPairingCode, const chip::SetupPayload & payload); From 2891409b54faf8a8323768819bb049bfe6c925c9 Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Wed, 28 Jul 2021 01:07:26 -0400 Subject: [PATCH 5/5] Apply suggestions from code review --- src/app/server/OnboardingCodesUtil.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/server/OnboardingCodesUtil.cpp b/src/app/server/OnboardingCodesUtil.cpp index a4cfde4980a6d2..82ff28d4d5ee39 100644 --- a/src/app/server/OnboardingCodesUtil.cpp +++ b/src/app/server/OnboardingCodesUtil.cpp @@ -46,10 +46,10 @@ void PrintOnboardingCodes(chip::RendezvousInformationFlags aRendezvousFlags) qrCodeBuffer.Alloc(qrCodeBufferMaxSize); ChipLogProgress(AppServer, "SetupQRCode: [%s]", qrCode.c_str()); - if (GetQRCodeUrl(&qrCodeBuffer[0], qrCodeBufferMaxSize, qrCode) == CHIP_NO_ERROR) + if (GetQRCodeUrl(qrCodeBuffer.Get(), qrCodeBufferMaxSize, qrCode) == CHIP_NO_ERROR) { ChipLogProgress(AppServer, "Copy/paste the below URL in a browser to see the QR Code:"); - ChipLogProgress(AppServer, "%s", &qrCodeBuffer[0]); + ChipLogProgress(AppServer, "%s", qrCodeBuffer.Get()); } } else