Skip to content

Commit 2b99f24

Browse files
committed
HandleLogin in ContentAppPlatform::ManageClientAccess
1 parent 8f98caf commit 2b99f24

File tree

7 files changed

+83
-50
lines changed

7 files changed

+83
-50
lines changed

examples/tv-app/android/include/account-login/AccountLoginManager.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ AccountLoginManager::AccountLoginManager(ContentAppCommandDelegate * commandDele
5858
CopyString(mSetupPin, sizeof(mSetupPin), setupPin);
5959
}
6060

61-
bool AccountLoginManager::HandleLogin(const CharSpan & tempAccountIdentifier, const CharSpan & setupPin,
61+
bool AccountLoginManager::HandleLogin(const CharSpan & tempAccountId, const CharSpan & setupPIN,
6262
const chip::Optional<chip::NodeId> & nodeId)
6363
{
6464
ChipLogProgress(DeviceLayer, "AccountLoginManager::HandleLogin called for endpoint %d", mEndpointId);
@@ -76,7 +76,7 @@ bool AccountLoginManager::HandleLogin(const CharSpan & tempAccountIdentifier, co
7676

7777
Json::Value response;
7878
bool commandHandled = true;
79-
AccountLogin::Commands::Login::Type cmd = { tempAccountIdentifier, setupPin, nodeId };
79+
AccountLogin::Commands::Login::Type cmd = { tempAccountId, setupPIN, nodeId };
8080

8181
// Deliberately ignore returned status
8282
mCommandDelegate->InvokeCommand(mEndpointId, AccountLogin::Id,

examples/tv-app/android/java/TVApp-JNI.cpp

+9-5
Original file line numberDiff line numberDiff line change
@@ -252,13 +252,13 @@ SampleTvAppInstallationService gSampleTvAppInstallationService;
252252

253253
class MyPostCommissioningListener : public PostCommissioningListener
254254
{
255-
void CommissioningCompleted(uint16_t vendorId, uint16_t productId, NodeId nodeId, Messaging::ExchangeManager & exchangeMgr,
256-
const SessionHandle & sessionHandle) override
255+
void CommissioningCompleted(uint16_t vendorId, uint16_t productId, NodeId nodeId, std::string rotatingId, uint32_t passcode,
256+
Messaging::ExchangeManager & exchangeMgr, const SessionHandle & sessionHandle) override
257257
{
258258
// read current binding list
259259
chip::Controller::ClusterBase cluster(exchangeMgr, sessionHandle, kTargetBindingClusterEndpointId);
260260

261-
cacheContext(vendorId, productId, nodeId, exchangeMgr, sessionHandle);
261+
cacheContext(vendorId, productId, nodeId, std::move(rotatingId), passcode, exchangeMgr, sessionHandle);
262262

263263
CHIP_ERROR err =
264264
cluster.ReadAttribute<Binding::Attributes::Binding::TypeInfo>(this, OnReadSuccessResponse, OnReadFailureResponse);
@@ -342,17 +342,19 @@ class MyPostCommissioningListener : public PostCommissioningListener
342342

343343
Optional<SessionHandle> opt = mSecureSession.Get();
344344
SessionHandle & sessionHandle = opt.Value();
345-
ContentAppPlatform::GetInstance().ManageClientAccess(*mExchangeMgr, sessionHandle, mVendorId, mProductId, localNodeId,
345+
ContentAppPlatform::GetInstance().ManageClientAccess(*mExchangeMgr, sessionHandle, mVendorId, mProductId, localNodeId, mRotatingId, mPasscode,
346346
bindings, OnSuccessResponse, OnFailureResponse);
347347
clearContext();
348348
}
349349

350-
void cacheContext(uint16_t vendorId, uint16_t productId, NodeId nodeId, Messaging::ExchangeManager & exchangeMgr,
350+
void cacheContext(uint16_t vendorId, uint16_t productId, NodeId nodeId, std::string rotatingId, uint32_t passcode, Messaging::ExchangeManager & exchangeMgr,
351351
const SessionHandle & sessionHandle)
352352
{
353353
mVendorId = vendorId;
354354
mProductId = productId;
355355
mNodeId = nodeId;
356+
mRotatingId = std::move(rotatingId);
357+
mPasscode = passcode;
356358
mExchangeMgr = &exchangeMgr;
357359
mSecureSession.ShiftToSession(sessionHandle);
358360
}
@@ -368,6 +370,8 @@ class MyPostCommissioningListener : public PostCommissioningListener
368370
uint16_t mVendorId = 0;
369371
uint16_t mProductId = 0;
370372
NodeId mNodeId = 0;
373+
std::string mRotatingId;
374+
uint32_t mPasscode = 0;
371375
Messaging::ExchangeManager * mExchangeMgr = nullptr;
372376
SessionHolder mSecureSession;
373377
};

examples/tv-app/tv-common/src/AppTv.cpp

+10-6
Original file line numberDiff line numberDiff line change
@@ -158,13 +158,13 @@ MyAppInstallationService gMyAppInstallationService;
158158

159159
class MyPostCommissioningListener : public PostCommissioningListener
160160
{
161-
void CommissioningCompleted(uint16_t vendorId, uint16_t productId, NodeId nodeId, Messaging::ExchangeManager & exchangeMgr,
162-
const SessionHandle & sessionHandle) override
161+
void CommissioningCompleted(uint16_t vendorId, uint16_t productId, NodeId nodeId, std::string rotatingId, uint32_t passcode,
162+
Messaging::ExchangeManager & exchangeMgr, const SessionHandle & sessionHandle) override
163163
{
164164
// read current binding list
165165
chip::Controller::ClusterBase cluster(exchangeMgr, sessionHandle, kTargetBindingClusterEndpointId);
166166

167-
cacheContext(vendorId, productId, nodeId, exchangeMgr, sessionHandle);
167+
cacheContext(vendorId, productId, nodeId, std::move(rotatingId), passcode, exchangeMgr, sessionHandle);
168168

169169
CHIP_ERROR err =
170170
cluster.ReadAttribute<Binding::Attributes::Binding::TypeInfo>(this, OnReadSuccessResponse, OnReadFailureResponse);
@@ -248,17 +248,19 @@ class MyPostCommissioningListener : public PostCommissioningListener
248248

249249
Optional<SessionHandle> opt = mSecureSession.Get();
250250
SessionHandle & sessionHandle = opt.Value();
251-
ContentAppPlatform::GetInstance().ManageClientAccess(*mExchangeMgr, sessionHandle, mVendorId, mProductId, localNodeId,
251+
ContentAppPlatform::GetInstance().ManageClientAccess(*mExchangeMgr, sessionHandle, mVendorId, mProductId, localNodeId, rotatingId, passcode,
252252
bindings, OnSuccessResponse, OnFailureResponse);
253253
clearContext();
254254
}
255255

256-
void cacheContext(uint16_t vendorId, uint16_t productId, NodeId nodeId, Messaging::ExchangeManager & exchangeMgr,
257-
const SessionHandle & sessionHandle)
256+
void cacheContext(uint16_t vendorId, uint16_t productId, NodeId nodeId, std::string rotatingId, uint32_t passcode,
257+
Messaging::ExchangeManager & exchangeMgr, const SessionHandle & sessionHandle)
258258
{
259259
mVendorId = vendorId;
260260
mProductId = productId;
261261
mNodeId = nodeId;
262+
mRotatingId = std::move(rotatingId);
263+
mPassocde = passcode;
262264
mExchangeMgr = &exchangeMgr;
263265
mSecureSession.ShiftToSession(sessionHandle);
264266
}
@@ -274,6 +276,8 @@ class MyPostCommissioningListener : public PostCommissioningListener
274276
uint16_t mVendorId = 0;
275277
uint16_t mProductId = 0;
276278
NodeId mNodeId = 0;
279+
std::string rotatingId;
280+
uint32_t passcode = 0;
277281
Messaging::ExchangeManager * mExchangeMgr = nullptr;
278282
SessionHolder mSecureSession;
279283
};

src/app/app-platform/ContentAppPlatform.cpp

+14
Original file line numberDiff line numberDiff line change
@@ -609,6 +609,7 @@ CHIP_ERROR ContentAppPlatform::GetACLEntryIndex(size_t * foundIndex, FabricIndex
609609
// and create bindings on the given client so that it knows what it has access to.
610610
CHIP_ERROR ContentAppPlatform::ManageClientAccess(Messaging::ExchangeManager & exchangeMgr, SessionHandle & sessionHandle,
611611
uint16_t targetVendorId, uint16_t targetProductId, NodeId localNodeId,
612+
const std::string& rotatingId, uint32_t passcode,
612613
std::vector<Binding::Structs::TargetStruct::Type> bindings,
613614
Controller::WriteResponseSuccessCallback successCb,
614615
Controller::WriteResponseFailureCallback failureCb)
@@ -755,6 +756,19 @@ CHIP_ERROR ContentAppPlatform::ManageClientAccess(Messaging::ExchangeManager & e
755756
{
756757
// notify content app about this nodeId
757758
app->AddClientNode(subjectNodeId);
759+
760+
auto tempAccountId = CharSpan::fromCharString(rotatingId.c_str());
761+
auto setupPIN = CharSpan::fromCharString(std::to_string(passcode).c_str());
762+
auto nodeId = MakeOptional(subjectNodeId); // Q: Is subjectNodeId correct NodeId to use?
763+
764+
// send login command to content app
765+
if (!tempAccountId.empty() && !setupPIN.empty()) {
766+
// Q: Should we only do this if (commissioner) passcode is not 0, e.g when user was shown PIN prompt?
767+
auto status = app->GetAccountLoginDelegate()->HandleLogin(tempAccountId, setupPIN, nodeId);
768+
ChipLogProgress(Controller, "AccountLogin::Login command sent and returned with status: %d", status);
769+
} else {
770+
ChipLogError(Controller, "Failed to get tempAccountId or setupPIN to set AccountLogin::Login command");
771+
}
758772
}
759773
}
760774
}

src/app/app-platform/ContentAppPlatform.h

+3
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,8 @@ class DLL_EXPORT ContentAppPlatform
176176
* @param[in] targetVendorId Vendor ID for the target device.
177177
* @param[in] targetProductId Product ID for the target device.
178178
* @param[in] localNodeId The NodeId for the local device.
179+
* @param[in] rotatingId The rotating account ID to handle account login.
180+
* @param[in] passcode The passcode to handle account login.
179181
* @param[in] bindings Any additional bindings to include. This may include current bindings.
180182
* @param[in] successCb The function to be called on success of adding the binding.
181183
* @param[in] failureCb The function to be called on failure of adding the binding.
@@ -184,6 +186,7 @@ class DLL_EXPORT ContentAppPlatform
184186
*/
185187
CHIP_ERROR ManageClientAccess(Messaging::ExchangeManager & exchangeMgr, SessionHandle & sessionHandle, uint16_t targetVendorId,
186188
uint16_t targetProductId, NodeId localNodeId,
189+
const std::string& rotatingId, uint32_t passcode,
187190
std::vector<app::Clusters::Binding::Structs::TargetStruct::Type> bindings,
188191
Controller::WriteResponseSuccessCallback successCb,
189192
Controller::WriteResponseFailureCallback failureCb);

src/controller/CommissionerDiscoveryController.cpp

+42-34
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,33 @@
3232

3333
#if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY
3434

35+
namespace {
36+
37+
bool fillRotatingIdBuffer(UDCClientState* client, char[] buffer) {
38+
auto rotatingIdLength = client->GetRotatingIdLength();
39+
auto hexBufferByteCount = 2 * rotatingIdLength;
40+
if (sizeof(buffer) < hexBufferByteCount) {
41+
return false;
42+
}
43+
auto err = Encoding::BytesToUppercaseHexBuffer(client->GetRotatingId(), rotatingIdLength, buffer, sizeof(buffer));
44+
return err == CHIP_NO_ERROR;
45+
}
46+
47+
// Returned CharSpan valid lifetime equals buffer lifetime.
48+
CharSpan getRotatingIdSpan(UDCClientState* client, char[] buffer) {
49+
auto ok = fillRotatingIdBuffer(client, buffer);
50+
return ok ? { buffer, hexBufferByteCount } : {};
51+
}
52+
53+
// Allocates memory for rotating ID string and copies to string
54+
std::string getRotatingIdString(UDCClientState* client) {
55+
auto buffer = char[Dnssd::kMaxRotatingIdLen * 2];
56+
auto ok = fillRotatingIdBuffer(client, buffer);
57+
return ok ? { buffer, hexBufferByteCount } : {};
58+
}
59+
60+
}
61+
3562
using namespace ::chip;
3663
using namespace chip::Protocols::UserDirectedCommissioning;
3764

@@ -246,15 +273,11 @@ void CommissionerDiscoveryController::InternalOk()
246273
}
247274

248275
char rotatingIdBuffer[Dnssd::kMaxRotatingIdLen * 2];
249-
size_t rotatingIdLength = client->GetRotatingIdLength();
250-
CHIP_ERROR err =
251-
Encoding::BytesToUppercaseHexBuffer(client->GetRotatingId(), rotatingIdLength, rotatingIdBuffer, sizeof(rotatingIdBuffer));
252-
if (err != CHIP_NO_ERROR)
253-
{
276+
CharSpan rotatingIdSpan = getRotatingIdSpan(client, rotatingIdBuffer);
277+
if (rotatingIdSpan.empty()) {
254278
ChipLogError(AppServer, "UX InternalOk: could not convert rotating id to hex");
255279
return;
256280
}
257-
CharSpan rotatingIdSpan(rotatingIdBuffer, 2 * rotatingIdLength);
258281

259282
uint8_t targetAppCount = client->GetNumTargetAppInfos();
260283

@@ -406,7 +429,6 @@ void CommissionerDiscoveryController::InternalHandleContentAppPasscodeResponse()
406429
ValidateSession();
407430
uint32_t passcode = mPasscode;
408431

409-
// Q: Seems like getting rotating ID is done twice - once here and once in InternalOk. Is this necessary or could it be cached?
410432
if (mUdcServer == nullptr)
411433
{
412434
ChipLogError(AppServer, "UX Ok - HandleContentAppPasscodeResponse: no udc server");
@@ -432,18 +454,11 @@ void CommissionerDiscoveryController::InternalHandleContentAppPasscodeResponse()
432454
if (passcode == 0 && client->GetCommissionerPasscode() && client->GetCdPort() != 0)
433455
{
434456
char rotatingIdBuffer[Dnssd::kMaxRotatingIdLen * 2];
435-
size_t rotatingIdLength = client->GetRotatingIdLength();
436-
CHIP_ERROR err = Encoding::BytesToUppercaseHexBuffer(client->GetRotatingId(), rotatingIdLength, rotatingIdBuffer,
437-
sizeof(rotatingIdBuffer));
438-
if (err != CHIP_NO_ERROR)
439-
{
457+
CharSpan rotatingIdSpan = getRotatingIdSpan(client, rotatingIdBuffer);
458+
if (rotatingIdSpan.empty()) {
440459
ChipLogError(AppServer, "UX Ok - HandleContentAppPasscodeResponse: could not convert rotating id to hex");
441460
return;
442461
}
443-
CharSpan rotatingIdSpan(rotatingIdBuffer, 2 * rotatingIdLength);
444-
445-
// Store rotating ID as tempAccountIdentifier to use in AccountLogin::Login payload later.
446-
mTempAccountIdentifier = rotatingIdSpan;
447462

448463
// first step of commissioner passcode
449464
ChipLogError(AppServer, "UX Ok: commissioner passcode, sending CDC");
@@ -460,9 +475,6 @@ void CommissionerDiscoveryController::InternalHandleContentAppPasscodeResponse()
460475
cd, Transport::PeerAddress::UDP(client->GetPeerAddress().GetIPAddress(), client->GetCdPort()));
461476
return;
462477
}
463-
// Store commissioner passcode as setup PIN (string/charspan).
464-
// If this PIN is not empty it signals that user prompt was shown to enter PIN and AccountLogin::Login command has to be sent.
465-
mCommissionerSetupPin = CharSpan::fromCharString(std::to_string(passcode));
466478

467479
client->SetCachedCommissionerPasscode(passcode);
468480
client->SetUDCClientProcessingState(UDCClientProcessingState::kWaitingForCommissionerPasscodeReady);
@@ -616,26 +628,22 @@ void CommissionerDiscoveryController::CommissioningSucceeded(uint16_t vendorId,
616628
mProductId = productId;
617629
mNodeId = nodeId;
618630

619-
// Send AccountLogin::Login command if user was prompted to enter setup PIN manually.
620-
// Q: Is this the correct place to have this logic?
621-
// Q: Is there an easier way call AccountLoginDelegate from here?
622-
if (!mCommissionerSetupPIN.empty()) {
623-
ChipLogProgress(AppServer, "UX ComissioningSucceeded with setupPIN prompt flow");
624-
auto app = ContentAppPlatform::GetInstance().LoadContentAppByClient(vendorId, productId);
625-
if (app == nullptr) {
626-
ChipLogError(AppServer, "UX ComissioningSucceeded with setupPIN prompt flow: Failed to get ContentApp");
627-
// Q: Any action to take?
628-
} else {
629-
auto status = app->GetAccountLoginDelegate()->HandleLogin(mTempAccountIdentifier, mCommissionerSetupPin, {mNodeId});
630-
ChipLogProgress(AppServer, "UX ComissioningSucceeded with setupPIN prompt flow: HandleLogin response status: %d", status);
631-
// Q: Any action to take here if status is true/false?
632-
}
631+
auto rotatingId = std::string{};
632+
auto passcode = uint32_t{ 0 };
633+
634+
auto client = GetUDCClientState();
635+
if (client != nullptr)
636+
{
637+
// Get rotating ID and cached (commissioner?) passcode to handle AccountLogin
638+
rotatingId = getRotatingIdString(client);
639+
// Q: Should we use mPasscode, client->GetCommissionerPasscode, or client->GetCachedCommissionerPasscode?
640+
passcode = std::to_string(client->GetCachedCommissionerPasscode());
633641
}
634642

635643
if (mPostCommissioningListener != nullptr)
636644
{
637645
ChipLogDetail(Controller, "CommissionerDiscoveryController calling listener");
638-
mPostCommissioningListener->CommissioningCompleted(vendorId, productId, nodeId, exchangeMgr, sessionHandle);
646+
mPostCommissioningListener->CommissioningCompleted(vendorId, productId, nodeId, std::move(rotatingId), passcode, exchangeMgr, sessionHandle);
639647
}
640648
else
641649
{

src/controller/CommissionerDiscoveryController.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@
3838

3939
#if CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY
4040

41-
using chip::CharSpan;
4241
using chip::NodeId;
4342
using chip::OperationalSessionSetup;
4443
using chip::Protocols::UserDirectedCommissioning::UDCClientState;
@@ -233,11 +232,14 @@ class DLL_EXPORT PostCommissioningListener
233232
* @param[in] vendorId The vendorid from the DAC of the new node.
234233
* @param[in] productId The productid from the DAC of the new node.
235234
* @param[in] nodeId The node id for the newly commissioned node.
235+
* @param[in] rotatingId The rotating ID to handle account login.
236+
* @param[in] passcode The passcode to handle account login.
236237
* @param[in] exchangeMgr The exchange manager to be used to get an exchange context.
237238
* @param[in] sessionHandle A reference to an established session.
238239
*
239240
*/
240241
virtual void CommissioningCompleted(uint16_t vendorId, uint16_t productId, NodeId nodeId,
242+
std::string rotatingId, uint32_t passcode,
241243
chip::Messaging::ExchangeManager & exchangeMgr,
242244
const chip::SessionHandle & sessionHandle) = 0;
243245

@@ -452,8 +454,6 @@ class CommissionerDiscoveryController : public chip::Protocols::UserDirectedComm
452454
uint16_t mProductId = 0;
453455
NodeId mNodeId = 0;
454456
uint32_t mPasscode = 0;
455-
CharSpan mTempAccountIdentifier;
456-
CharSpan mCommissionerSetupPin;
457457

458458
UserDirectedCommissioningServer * mUdcServer = nullptr;
459459
UserPrompter * mUserPrompter = nullptr;

0 commit comments

Comments
 (0)