@@ -353,10 +353,57 @@ CHIP_ERROR DeviceController::GetPeerAddressAndPort(PeerId peerId, Inet::IPAddres
353
353
return CHIP_NO_ERROR;
354
354
}
355
355
356
+ void DeviceController::OnPIDReadResponse (void * context, uint16_t value)
357
+ {
358
+ ChipLogProgress (Controller, " Received PID for the device. Value %d" , value);
359
+ DeviceController * controller = static_cast <DeviceController *>(context);
360
+ controller->mSetupPayload .productID = value;
361
+
362
+ if (controller->OpenCommissioningWindowInternal () != CHIP_NO_ERROR)
363
+ {
364
+ OnOpenPairingWindowFailureResponse (context, 0 );
365
+ }
366
+ }
367
+
368
+ void DeviceController::OnVIDReadResponse (void * context, uint16_t value)
369
+ {
370
+ ChipLogProgress (Controller, " Received VID for the device. Value %d" , value);
371
+
372
+ DeviceController * controller = static_cast <DeviceController *>(context);
373
+
374
+ controller->mSetupPayload .vendorID = value;
375
+
376
+ OperationalDeviceProxy * device =
377
+ controller->mCASESessionManager ->FindExistingSession (controller->mDeviceWithCommissioningWindowOpen );
378
+ if (device == nullptr )
379
+ {
380
+ ChipLogError (Controller, " Could not find device for opening commissioning window" );
381
+ OnOpenPairingWindowFailureResponse (context, 0 );
382
+ return ;
383
+ }
384
+
385
+ constexpr EndpointId kBasicClusterEndpoint = 0 ;
386
+ chip::Controller::BasicCluster cluster;
387
+ cluster.Associate (device, kBasicClusterEndpoint );
388
+
389
+ if (cluster.ReadAttribute <app::Clusters::Basic::Attributes::ProductID::TypeInfo>(context, OnPIDReadResponse,
390
+ OnVIDPIDReadFailureResponse) != CHIP_NO_ERROR)
391
+ {
392
+ ChipLogError (Controller, " Could not read PID for opening commissioning window" );
393
+ OnOpenPairingWindowFailureResponse (context, 0 );
394
+ }
395
+ }
396
+
397
+ void DeviceController::OnVIDPIDReadFailureResponse (void * context, EmberAfStatus status)
398
+ {
399
+ ChipLogProgress (Controller, " Failed to read VID/PID for the device. status %d" , status);
400
+ OnOpenPairingWindowFailureResponse (context, status);
401
+ }
402
+
356
403
void DeviceController::OnOpenPairingWindowSuccessResponse (void * context)
357
404
{
358
405
ChipLogProgress (Controller, " Successfully opened pairing window on the device" );
359
- DeviceController * controller = reinterpret_cast <DeviceController *>(context);
406
+ DeviceController * controller = static_cast <DeviceController *>(context);
360
407
if (controller->mCommissioningWindowCallback != nullptr )
361
408
{
362
409
controller->mCommissioningWindowCallback ->mCall (controller->mCommissioningWindowCallback ->mContext ,
@@ -368,12 +415,11 @@ void DeviceController::OnOpenPairingWindowSuccessResponse(void * context)
368
415
void DeviceController::OnOpenPairingWindowFailureResponse (void * context, uint8_t status)
369
416
{
370
417
ChipLogError (Controller, " Failed to open pairing window on the device. Status %d" , status);
371
- DeviceController * controller = reinterpret_cast <DeviceController *>(context);
418
+ DeviceController * controller = static_cast <DeviceController *>(context);
372
419
if (controller->mCommissioningWindowCallback != nullptr )
373
420
{
374
421
CHIP_ERROR error = CHIP_ERROR_INVALID_PASE_PARAMETER;
375
- // TODO - Use cluster enum chip::app::Clusters::AdministratorCommissioning::StatusCode::kBusy
376
- if (status == 1 )
422
+ if (status == EmberAfStatusCode::EMBER_ZCL_STATUS_CODE_BUSY)
377
423
{
378
424
error = CHIP_ERROR_ANOTHER_COMMISSIONING_IN_PROGRESS;
379
425
}
@@ -393,38 +439,60 @@ CHIP_ERROR DeviceController::ComputePASEVerifier(uint32_t iterations, uint32_t s
393
439
394
440
CHIP_ERROR DeviceController::OpenCommissioningWindowWithCallback (NodeId deviceId, uint16_t timeout, uint16_t iteration,
395
441
uint16_t discriminator, uint8_t option,
396
- Callback::Callback<OnOpenCommissioningWindow> * callback)
442
+ Callback::Callback<OnOpenCommissioningWindow> * callback,
443
+ bool readVIDPIDAttributes)
397
444
{
398
- ChipLogProgress (Controller, " OpenCommissioningWindow for device ID %" PRIu64, deviceId);
399
- VerifyOrReturnError (mState == State::Initialized, CHIP_ERROR_INCORRECT_STATE);
400
-
401
- OperationalDeviceProxy * device = mCASESessionManager ->FindExistingSession (deviceId);
402
- VerifyOrReturnError (device != nullptr , CHIP_ERROR_INVALID_ARGUMENT);
445
+ mSetupPayload = SetupPayload ();
403
446
404
- std::string QRCode;
405
- std::string manualPairingCode;
406
- SetupPayload payload;
407
- CommissioningWindowOption commissioningWindowOption;
408
- ByteSpan salt (reinterpret_cast <const uint8_t *>(kSpake2pKeyExchangeSalt ), strlen (kSpake2pKeyExchangeSalt ));
447
+ mSetupPayload .version = 0 ;
448
+ mSetupPayload .discriminator = discriminator;
449
+ mSetupPayload .rendezvousInformation = RendezvousInformationFlags (RendezvousInformationFlag::kOnNetwork );
409
450
410
- payload.discriminator = discriminator;
451
+ mCommissioningWindowCallback = callback;
452
+ mDeviceWithCommissioningWindowOpen = deviceId;
453
+ mCommissioningWindowTimeout = timeout;
454
+ mCommissioningWindowIteration = iteration;
411
455
412
456
switch (option)
413
457
{
414
458
case 0 :
415
- commissioningWindowOption = CommissioningWindowOption::kOriginalSetupCode ;
459
+ mCommissioningWindowOption = CommissioningWindowOption::kOriginalSetupCode ;
416
460
break ;
417
461
case 1 :
418
- commissioningWindowOption = CommissioningWindowOption::kTokenWithRandomPIN ;
462
+ mCommissioningWindowOption = CommissioningWindowOption::kTokenWithRandomPIN ;
419
463
break ;
420
464
case 2 :
421
- commissioningWindowOption = CommissioningWindowOption::kTokenWithProvidedPIN ;
465
+ mCommissioningWindowOption = CommissioningWindowOption::kTokenWithProvidedPIN ;
422
466
break ;
423
467
default :
424
468
ChipLogError (Controller, " Invalid Pairing Window option" );
425
469
return CHIP_ERROR_INVALID_ARGUMENT;
426
470
}
427
471
472
+ if (callback != nullptr && mCommissioningWindowOption != CommissioningWindowOption::kOriginalSetupCode && readVIDPIDAttributes)
473
+ {
474
+ OperationalDeviceProxy * device = mCASESessionManager ->FindExistingSession (mDeviceWithCommissioningWindowOpen );
475
+ VerifyOrReturnError (device != nullptr , CHIP_ERROR_INVALID_ARGUMENT);
476
+
477
+ constexpr EndpointId kBasicClusterEndpoint = 0 ;
478
+ chip::Controller::BasicCluster cluster;
479
+ cluster.Associate (device, kBasicClusterEndpoint );
480
+
481
+ return cluster.ReadAttribute <app::Clusters::Basic::Attributes::VendorID::TypeInfo>(this , OnVIDReadResponse,
482
+ OnVIDPIDReadFailureResponse);
483
+ }
484
+
485
+ return OpenCommissioningWindowInternal ();
486
+ }
487
+
488
+ CHIP_ERROR DeviceController::OpenCommissioningWindowInternal ()
489
+ {
490
+ ChipLogProgress (Controller, " OpenCommissioningWindow for device ID %" PRIu64, mDeviceWithCommissioningWindowOpen );
491
+ VerifyOrReturnError (mState == State::Initialized, CHIP_ERROR_INCORRECT_STATE);
492
+
493
+ OperationalDeviceProxy * device = mCASESessionManager ->FindExistingSession (mDeviceWithCommissioningWindowOpen );
494
+ VerifyOrReturnError (device != nullptr , CHIP_ERROR_INVALID_ARGUMENT);
495
+
428
496
constexpr EndpointId kAdministratorCommissioningClusterEndpoint = 0 ;
429
497
430
498
chip::Controller::AdministratorCommissioningCluster cluster;
@@ -433,41 +501,40 @@ CHIP_ERROR DeviceController::OpenCommissioningWindowWithCallback(NodeId deviceId
433
501
Callback::Cancelable * successCallback = mOpenPairingSuccessCallback .Cancel ();
434
502
Callback::Cancelable * failureCallback = mOpenPairingFailureCallback .Cancel ();
435
503
436
- payload.version = 0 ;
437
- payload.rendezvousInformation = RendezvousInformationFlags (RendezvousInformationFlag::kOnNetwork );
438
-
439
- mCommissioningWindowCallback = callback;
440
- if (commissioningWindowOption != CommissioningWindowOption::kOriginalSetupCode )
504
+ if (mCommissioningWindowOption != CommissioningWindowOption::kOriginalSetupCode )
441
505
{
442
- bool randomSetupPIN = (commissioningWindowOption == CommissioningWindowOption::kTokenWithRandomPIN );
506
+ ByteSpan salt (Uint8::from_const_char (kSpake2pKeyExchangeSalt ), strlen (kSpake2pKeyExchangeSalt ));
507
+ bool randomSetupPIN = (mCommissioningWindowOption == CommissioningWindowOption::kTokenWithRandomPIN );
443
508
PASEVerifier verifier;
444
509
445
- ReturnErrorOnFailure (PASESession::GeneratePASEVerifier (verifier, iteration, salt, randomSetupPIN, payload.setUpPINCode ));
510
+ ReturnErrorOnFailure (PASESession::GeneratePASEVerifier (verifier, mCommissioningWindowIteration , salt, randomSetupPIN,
511
+ mSetupPayload .setUpPINCode ));
446
512
447
513
uint8_t serializedVerifier[2 * kSpake2p_WS_Length ];
448
514
VerifyOrReturnError (sizeof (serializedVerifier) == sizeof (verifier), CHIP_ERROR_INTERNAL);
449
515
450
516
memcpy (serializedVerifier, verifier.mW0 , kSpake2p_WS_Length );
451
517
memcpy (&serializedVerifier[kSpake2p_WS_Length ], verifier.mL , kSpake2p_WS_Length );
452
518
453
- ReturnErrorOnFailure (cluster.OpenCommissioningWindow (successCallback, failureCallback, timeout,
454
- ByteSpan (serializedVerifier, sizeof (serializedVerifier)),
455
- payload.discriminator , iteration, salt, mPAKEVerifierID ++));
519
+ ReturnErrorOnFailure (cluster.OpenCommissioningWindow (
520
+ successCallback, failureCallback, mCommissioningWindowTimeout , ByteSpan (serializedVerifier, sizeof (serializedVerifier)),
521
+ mSetupPayload .discriminator , mCommissioningWindowIteration , salt, mPAKEVerifierID ++));
522
+
523
+ char payloadBuffer[QRCodeBasicSetupPayloadGenerator::kMaxQRCodeBase38RepresentationLength ];
456
524
457
- ReturnErrorOnFailure (ManualSetupPayloadGenerator (payload).payloadDecimalStringRepresentation (manualPairingCode));
458
- ChipLogProgress (Controller, " Manual pairing code: [%s]" , manualPairingCode.c_str ());
525
+ MutableCharSpan manualCode (payloadBuffer);
526
+ ReturnErrorOnFailure (ManualSetupPayloadGenerator (mSetupPayload ).payloadDecimalStringRepresentation (manualCode));
527
+ ChipLogProgress (Controller, " Manual pairing code: [%s]" , payloadBuffer);
459
528
460
- ReturnErrorOnFailure (QRCodeSetupPayloadGenerator (payload).payloadBase38Representation (QRCode));
461
- ChipLogProgress (Controller, " SetupQRCode: [%s]" , QRCode.c_str ());
529
+ MutableCharSpan QRCode (payloadBuffer);
530
+ ReturnErrorOnFailure (QRCodeBasicSetupPayloadGenerator (mSetupPayload ).payloadBase38Representation (QRCode));
531
+ ChipLogProgress (Controller, " SetupQRCode: [%s]" , payloadBuffer);
462
532
}
463
533
else
464
534
{
465
- ReturnErrorOnFailure (cluster.OpenBasicCommissioningWindow (successCallback, failureCallback, timeout ));
535
+ ReturnErrorOnFailure (cluster.OpenBasicCommissioningWindow (successCallback, failureCallback, mCommissioningWindowTimeout ));
466
536
}
467
537
468
- mSetupPayload = payload;
469
- mDeviceWithCommissioningWindowOpen = deviceId;
470
-
471
538
return CHIP_NO_ERROR;
472
539
}
473
540
0 commit comments