Skip to content

Commit 4798028

Browse files
yufengwangcawoody-applebzbarsky-apple
authored andcommitted
[linux] Enable setup code options for linux example apps (#8547)
* [TE4] Enable setup code options in linux example apps * Update src/app/server/OnboardingCodesUtil.cpp Co-authored-by: Boris Zbarsky <[email protected]> * Update src/app/server/OnboardingCodesUtil.cpp Co-authored-by: Boris Zbarsky <[email protected]> * Rename QRCode to qrCode * Apply suggestions from code review Co-authored-by: Justin Wood <[email protected]> Co-authored-by: Boris Zbarsky <[email protected]>
1 parent d661e76 commit 4798028

File tree

6 files changed

+162
-28
lines changed

6 files changed

+162
-28
lines changed

examples/bridge-app/linux/include/Options.h

+2
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,11 @@
2727
#include <cstdint>
2828

2929
#include <core/CHIPError.h>
30+
#include <setup_payload/SetupPayload.h>
3031

3132
struct LinuxDeviceOptions
3233
{
34+
chip::SetupPayload payload;
3335
uint32_t mBleDevice = 0;
3436

3537
static LinuxDeviceOptions & GetInstance();

examples/platform/linux/AppMain.cpp

+11-6
Original file line numberDiff line numberDiff line change
@@ -72,23 +72,28 @@ void EventHandler(const chip::DeviceLayer::ChipDeviceEvent * event, intptr_t arg
7272

7373
int ChipLinuxAppInit(int argc, char ** argv)
7474
{
75-
CHIP_ERROR err = CHIP_NO_ERROR;
75+
CHIP_ERROR err = CHIP_NO_ERROR;
76+
chip::RendezvousInformationFlags rendezvousFlags = chip::RendezvousInformationFlag::kBLE;
77+
78+
#ifdef CONFIG_RENDEZVOUS_MODE
79+
rendezvousFlags = static_cast<chip::RendezvousInformationFlags>(CONFIG_RENDEZVOUS_MODE);
80+
#endif
7681

7782
err = chip::Platform::MemoryInit();
7883
SuccessOrExit(err);
7984

85+
err = GetSetupPayload(LinuxDeviceOptions::GetInstance().payload, rendezvousFlags);
86+
SuccessOrExit(err);
87+
8088
err = ParseArguments(argc, argv);
8189
SuccessOrExit(err);
8290

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

8694
ConfigurationMgr().LogDeviceConfig();
87-
#ifdef CONFIG_RENDEZVOUS_MODE
88-
PrintOnboardingCodes(static_cast<chip::RendezvousInformationFlags>(CONFIG_RENDEZVOUS_MODE));
89-
#else
90-
PrintOnboardingCodes(chip::RendezvousInformationFlag::kBLE);
91-
#endif
95+
96+
PrintOnboardingCodes(LinuxDeviceOptions::GetInstance().payload);
9297

9398
#if defined(PW_RPC_ENABLED)
9499
chip::rpc::Init();

examples/platform/linux/Options.cpp

+77-12
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
#include "Options.h"
2020

21+
#include <app/server/OnboardingCodesUtil.h>
2122
#include <platform/CHIPDeviceLayer.h>
2223

2324
#include <core/CHIPError.h>
@@ -32,9 +33,16 @@ LinuxDeviceOptions gDeviceOptions;
3233
// Follow the code style of command line arguments in case we need to add more options in the future.
3334
enum
3435
{
35-
kDeviceOption_BleDevice = 0x1000,
36-
kDeviceOption_WiFi = 0x1001,
37-
kDeviceOption_Thread = 0x1002,
36+
kDeviceOption_BleDevice = 0x1000,
37+
kDeviceOption_WiFi = 0x1001,
38+
kDeviceOption_Thread = 0x1002,
39+
kDeviceOption_Version = 0x1003,
40+
kDeviceOption_VendorID = 0x1004,
41+
kDeviceOption_ProductID = 0x1005,
42+
kDeviceOption_CustomFlow = 0x1006,
43+
kDeviceOption_Capabilities = 0x1007,
44+
kDeviceOption_Discriminator = 0x1008,
45+
kDeviceOption_Passcode = 0x1009
3846
};
3947

4048
constexpr unsigned kAppUsageLength = 64;
@@ -46,21 +54,50 @@ OptionDef sDeviceOptionDefs[] = { { "ble-device", kArgumentRequired, kDeviceOpti
4654
#if CHIP_ENABLE_OPENTHREAD
4755
{ "thread", kNoArgument, kDeviceOption_Thread },
4856
#endif // CHIP_ENABLE_OPENTHREAD
57+
{ "version", kArgumentRequired, kDeviceOption_Version },
58+
{ "vendor-id", kArgumentRequired, kDeviceOption_VendorID },
59+
{ "product-id", kArgumentRequired, kDeviceOption_ProductID },
60+
{ "custom-flow", kArgumentRequired, kDeviceOption_CustomFlow },
61+
{ "capabilities", kArgumentRequired, kDeviceOption_Capabilities },
62+
{ "discriminator", kArgumentRequired, kDeviceOption_Discriminator },
63+
{ "passcode", kArgumentRequired, kDeviceOption_Passcode },
4964
{} };
5065

51-
const char * sDeviceOptionHelp = " --ble-device <number>\n"
52-
" The device number for CHIPoBLE, without 'hci' prefix, can be found by hciconfig.\n"
66+
const char * sDeviceOptionHelp =
67+
" --ble-device <number>\n"
68+
" The device number for CHIPoBLE, without 'hci' prefix, can be found by hciconfig.\n"
5369
#if CHIP_DEVICE_CONFIG_ENABLE_WPA
54-
"\n"
55-
" --wifi\n"
56-
" Enable WiFi management via wpa_supplicant.\n"
70+
"\n"
71+
" --wifi\n"
72+
" Enable WiFi management via wpa_supplicant.\n"
5773
#endif // CHIP_DEVICE_CONFIG_ENABLE_WPA
5874
#if CHIP_ENABLE_OPENTHREAD
59-
"\n"
60-
" --thread\n"
61-
" Enable Thread management via ot-agent.\n"
75+
"\n"
76+
" --thread\n"
77+
" Enable Thread management via ot-agent.\n"
6278
#endif // CHIP_ENABLE_OPENTHREAD
63-
"\n";
79+
"\n"
80+
" --version <version>\n"
81+
" The version indication provides versioning of the setup payload.\n"
82+
"\n"
83+
" --vendor-id <id>\n"
84+
" The Vendor ID is assigned by the Connectivity Standards Alliance.\n"
85+
"\n"
86+
" --product-id <id>\n"
87+
" The Product ID is specified by vendor.\n"
88+
"\n"
89+
" --custom-flow <Standard = 0 | UserActionRequired = 1 | Custom = 2>\n"
90+
" A 2-bit unsigned enumeration specifying manufacturer-specific custom flow options.\n"
91+
"\n"
92+
" --capabilities <None = 0, SoftAP = 1 << 0, BLE = 1 << 1, OnNetwork = 1 << 2>\n"
93+
" Discovery Capabilities Bitmask which contains information about Device’s available technologies for device discovery.\n"
94+
"\n"
95+
" --discriminator <discriminator>\n"
96+
" A 12-bit unsigned integer match the value which a device advertises during commissioning.\n"
97+
"\n"
98+
" --passcode <passcode>\n"
99+
" A 27-bit unsigned integer, which serves as proof of possession during commissioning.\n"
100+
"\n";
64101

65102
bool HandleOption(const char * aProgram, OptionSet * aOptions, int aIdentifier, const char * aName, const char * aValue)
66103
{
@@ -85,6 +122,34 @@ bool HandleOption(const char * aProgram, OptionSet * aOptions, int aIdentifier,
85122
LinuxDeviceOptions::GetInstance().mThread = true;
86123
break;
87124

125+
case kDeviceOption_Version:
126+
LinuxDeviceOptions::GetInstance().payload.version = static_cast<uint8_t>(atoi(aValue));
127+
break;
128+
129+
case kDeviceOption_VendorID:
130+
LinuxDeviceOptions::GetInstance().payload.vendorID = static_cast<uint16_t>(atoi(aValue));
131+
break;
132+
133+
case kDeviceOption_ProductID:
134+
LinuxDeviceOptions::GetInstance().payload.productID = static_cast<uint16_t>(atoi(aValue));
135+
break;
136+
137+
case kDeviceOption_CustomFlow:
138+
LinuxDeviceOptions::GetInstance().payload.commissioningFlow = static_cast<CommissioningFlow>(atoi(aValue));
139+
break;
140+
141+
case kDeviceOption_Capabilities:
142+
LinuxDeviceOptions::GetInstance().payload.rendezvousInformation.SetRaw(static_cast<uint8_t>(atoi(aValue)));
143+
break;
144+
145+
case kDeviceOption_Discriminator:
146+
LinuxDeviceOptions::GetInstance().payload.discriminator = static_cast<uint16_t>(atoi(aValue));
147+
break;
148+
149+
case kDeviceOption_Passcode:
150+
LinuxDeviceOptions::GetInstance().payload.setUpPINCode = static_cast<uint32_t>(atoi(aValue));
151+
break;
152+
88153
default:
89154
PrintArgError("%s: INTERNAL ERROR: Unhandled option: %s\n", aProgram, aName);
90155
retval = false;

examples/platform/linux/Options.h

+2
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,11 @@
2727
#include <cstdint>
2828

2929
#include <core/CHIPError.h>
30+
#include <setup_payload/SetupPayload.h>
3031

3132
struct LinuxDeviceOptions
3233
{
34+
chip::SetupPayload payload;
3335
uint32_t mBleDevice = 0;
3436
bool mWiFi = false;
3537
bool mThread = false;

src/app/server/OnboardingCodesUtil.cpp

+66-9
Original file line numberDiff line numberDiff line change
@@ -36,20 +36,20 @@ using namespace ::chip::DeviceLayer;
3636

3737
void PrintOnboardingCodes(chip::RendezvousInformationFlags aRendezvousFlags)
3838
{
39-
std::string QRCode;
39+
std::string qrCode;
4040
std::string manualPairingCode;
4141

42-
if (GetQRCode(QRCode, aRendezvousFlags) == CHIP_NO_ERROR)
42+
if (GetQRCode(qrCode, aRendezvousFlags) == CHIP_NO_ERROR)
4343
{
4444
chip::Platform::ScopedMemoryBuffer<char> qrCodeBuffer;
45-
const size_t qrCodeBufferMaxSize = strlen(kQrCodeBaseUrl) + strlen(kUrlDataAssignmentPhrase) + 3 * QRCode.size() + 1;
45+
const size_t qrCodeBufferMaxSize = strlen(kQrCodeBaseUrl) + strlen(kUrlDataAssignmentPhrase) + 3 * qrCode.size() + 1;
4646
qrCodeBuffer.Alloc(qrCodeBufferMaxSize);
4747

48-
ChipLogProgress(AppServer, "SetupQRCode: [%s]", QRCode.c_str());
49-
if (GetQRCodeUrl(&qrCodeBuffer[0], qrCodeBufferMaxSize, QRCode) == CHIP_NO_ERROR)
48+
ChipLogProgress(AppServer, "SetupQRCode: [%s]", qrCode.c_str());
49+
if (GetQRCodeUrl(qrCodeBuffer.Get(), qrCodeBufferMaxSize, qrCode) == CHIP_NO_ERROR)
5050
{
5151
ChipLogProgress(AppServer, "Copy/paste the below URL in a browser to see the QR Code:");
52-
ChipLogProgress(AppServer, "%s", &qrCodeBuffer[0]);
52+
ChipLogProgress(AppServer, "%s", qrCodeBuffer.Get());
5353
}
5454
}
5555
else
@@ -67,14 +67,47 @@ void PrintOnboardingCodes(chip::RendezvousInformationFlags aRendezvousFlags)
6767
}
6868
}
6969

70+
void PrintOnboardingCodes(const chip::SetupPayload & payload)
71+
{
72+
std::string qrCode;
73+
std::string manualPairingCode;
74+
75+
if (GetQRCode(qrCode, payload) == CHIP_NO_ERROR)
76+
{
77+
chip::Platform::ScopedMemoryBuffer<char> qrCodeBuffer;
78+
const size_t qrCodeBufferMaxSize = strlen(kQrCodeBaseUrl) + strlen(kUrlDataAssignmentPhrase) + 3 * qrCode.size() + 1;
79+
qrCodeBuffer.Alloc(qrCodeBufferMaxSize);
80+
81+
ChipLogProgress(AppServer, "SetupQRCode: [%s]", qrCode.c_str());
82+
if (GetQRCodeUrl(qrCodeBuffer.Get(), qrCodeBufferMaxSize, qrCode) == CHIP_NO_ERROR)
83+
{
84+
ChipLogProgress(AppServer, "Copy/paste the below URL in a browser to see the QR Code:");
85+
ChipLogProgress(AppServer, "%s", qrCodeBuffer.Get());
86+
}
87+
}
88+
else
89+
{
90+
ChipLogError(AppServer, "Getting QR code failed!");
91+
}
92+
93+
if (GetManualPairingCode(manualPairingCode, payload) == CHIP_NO_ERROR)
94+
{
95+
ChipLogProgress(AppServer, "Manual pairing code: [%s]", manualPairingCode.c_str());
96+
}
97+
else
98+
{
99+
ChipLogError(AppServer, "Getting manual pairing code failed!");
100+
}
101+
}
102+
70103
#if CHIP_DEVICE_CONFIG_ENABLE_NFC
71104
void ShareQRCodeOverNFC(chip::RendezvousInformationFlags aRendezvousFlags)
72105
{
73106
// Get QR Code and emulate its content using NFC tag
74-
std::string QRCode;
75-
ReturnOnFailure(GetQRCode(QRCode, chip::RendezvousInformationFlags(chip::RendezvousInformationFlag::kBLE)));
107+
std::string qrCode;
108+
ReturnOnFailure(GetQRCode(qrCode, chip::RendezvousInformationFlags(chip::RendezvousInformationFlag::kBLE)));
76109

77-
ReturnOnFailure(NFCMgr().StartTagEmulation(QRCode.c_str(), QRCode.size()));
110+
ReturnOnFailure(NFCMgr().StartTagEmulation(qrCode.c_str(), qrCode.size()));
78111
}
79112
#endif
80113

@@ -138,6 +171,18 @@ CHIP_ERROR GetQRCode(std::string & aQRCode, chip::RendezvousInformationFlags aRe
138171
return CHIP_NO_ERROR;
139172
}
140173

174+
CHIP_ERROR GetQRCode(std::string & aQRCode, const chip::SetupPayload & payload)
175+
{
176+
CHIP_ERROR err = chip::QRCodeSetupPayloadGenerator(payload).payloadBase38Representation(aQRCode);
177+
if (err != CHIP_NO_ERROR)
178+
{
179+
ChipLogProgress(AppServer, "Generating QR Code failed: %s", chip::ErrorStr(err));
180+
return err;
181+
}
182+
183+
return CHIP_NO_ERROR;
184+
}
185+
141186
CHIP_ERROR GetQRCodeUrl(char * aQRCodeUrl, size_t aUrlMaxSize, const std::string & aQRCode)
142187
{
143188
VerifyOrReturnError(aQRCodeUrl, CHIP_ERROR_INVALID_ARGUMENT);
@@ -173,6 +218,18 @@ CHIP_ERROR GetManualPairingCode(std::string & aManualPairingCode, chip::Rendezvo
173218
return CHIP_NO_ERROR;
174219
}
175220

221+
CHIP_ERROR GetManualPairingCode(std::string & aManualPairingCode, const chip::SetupPayload & payload)
222+
{
223+
CHIP_ERROR err = chip::ManualSetupPayloadGenerator(payload).payloadDecimalStringRepresentation(aManualPairingCode);
224+
if (err != CHIP_NO_ERROR)
225+
{
226+
ChipLogProgress(AppServer, "Generating Manual Pairing Code failed: %s", chip::ErrorStr(err));
227+
return err;
228+
}
229+
230+
return CHIP_NO_ERROR;
231+
}
232+
176233
static inline bool isCharUnreservedInRfc3986(const char c)
177234
{
178235
return isalpha(c) || isdigit(c) || (strchr(kSpecialCharsUnreservedInRfc3986, c) != nullptr);

src/app/server/OnboardingCodesUtil.h

+4-1
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,13 @@
2020
#include <setup_payload/SetupPayload.h>
2121

2222
void PrintOnboardingCodes(chip::RendezvousInformationFlags aRendezvousFlags);
23+
void PrintOnboardingCodes(const chip::SetupPayload & payload);
2324
void ShareQRCodeOverNFC(chip::RendezvousInformationFlags aRendezvousFlags);
24-
CHIP_ERROR GetQRCode(std::string & QRCode, chip::RendezvousInformationFlags aRendezvousFlags);
25+
CHIP_ERROR GetQRCode(std::string & aQRCode, chip::RendezvousInformationFlags aRendezvousFlags);
26+
CHIP_ERROR GetQRCode(std::string & aQRCode, const chip::SetupPayload & payload);
2527
CHIP_ERROR GetQRCodeUrl(char * aQRCodeUrl, size_t aUrlMaxSize, const std::string & aQRCode);
2628
CHIP_ERROR GetManualPairingCode(std::string & aManualPairingCode, chip::RendezvousInformationFlags aRendezvousFlags);
29+
CHIP_ERROR GetManualPairingCode(std::string & aManualPairingCode, const chip::SetupPayload & payload);
2730
CHIP_ERROR GetSetupPayload(chip::SetupPayload & aSetupPayload, chip::RendezvousInformationFlags aRendezvousFlags);
2831

2932
/**

0 commit comments

Comments
 (0)