PairingCommand.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. /*
  2. * Copyright (c) 2020 Project CHIP Authors
  3. * All rights reserved.
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. *
  17. */
  18. #pragma once
  19. #include "../common/CHIPCommand.h"
  20. #include <controller/CommissioningDelegate.h>
  21. #include <controller/CurrentFabricRemover.h>
  22. #include <zap-generated/CHIPClusters.h>
  23. #include <commands/common/CredentialIssuerCommands.h>
  24. #include <lib/support/Span.h>
  25. #include <lib/support/ThreadOperationalDataset.h>
  26. enum class PairingMode
  27. {
  28. None,
  29. Code,
  30. CodePaseOnly,
  31. Ble,
  32. SoftAP,
  33. AlreadyDiscovered,
  34. AlreadyDiscoveredByIndex,
  35. AlreadyDiscoveredByIndexWithCode,
  36. OnNetwork,
  37. };
  38. enum class PairingNetworkType
  39. {
  40. None,
  41. WiFi,
  42. Thread,
  43. };
  44. class PairingCommand : public CHIPCommand,
  45. public chip::Controller::DevicePairingDelegate,
  46. public chip::Controller::DeviceDiscoveryDelegate,
  47. public chip::Credentials::DeviceAttestationDelegate
  48. {
  49. public:
  50. PairingCommand(const char * commandName, PairingMode mode, PairingNetworkType networkType,
  51. CredentialIssuerCommands * credIssuerCmds,
  52. chip::Dnssd::DiscoveryFilterType filterType = chip::Dnssd::DiscoveryFilterType::kNone) :
  53. CHIPCommand(commandName, credIssuerCmds),
  54. mPairingMode(mode), mNetworkType(networkType),
  55. mFilterType(filterType), mRemoteAddr{ IPAddress::Any, chip::Inet::InterfaceId::Null() }, mComplex_TimeZones(&mTimeZoneList),
  56. mComplex_DSTOffsets(&mDSTOffsetList), mCurrentFabricRemoveCallback(OnCurrentFabricRemove, this)
  57. {
  58. AddArgument("node-id", 0, UINT64_MAX, &mNodeId);
  59. AddArgument("bypass-attestation-verifier", 0, 1, &mBypassAttestationVerifier,
  60. "Bypass the attestation verifier. If not provided or false, the attestation verifier is not bypassed."
  61. " If true, the commissioning will continue in case of attestation verification failure.");
  62. AddArgument("case-auth-tags", 1, UINT32_MAX, &mCASEAuthTags, "The CATs to be encoded in the NOC sent to the commissionee");
  63. switch (networkType)
  64. {
  65. case PairingNetworkType::None:
  66. break;
  67. case PairingNetworkType::WiFi:
  68. AddArgument("ssid", &mSSID);
  69. AddArgument("password", &mPassword);
  70. break;
  71. case PairingNetworkType::Thread:
  72. AddArgument("operationalDataset", &mOperationalDataset);
  73. break;
  74. }
  75. switch (mode)
  76. {
  77. case PairingMode::None:
  78. break;
  79. case PairingMode::Code:
  80. AddArgument("skip-commissioning-complete", 0, 1, &mSkipCommissioningComplete);
  81. FALLTHROUGH;
  82. case PairingMode::CodePaseOnly:
  83. AddArgument("payload", &mOnboardingPayload);
  84. AddArgument("discover-once", 0, 1, &mDiscoverOnce);
  85. AddArgument("use-only-onnetwork-discovery", 0, 1, &mUseOnlyOnNetworkDiscovery);
  86. break;
  87. case PairingMode::Ble:
  88. AddArgument("skip-commissioning-complete", 0, 1, &mSkipCommissioningComplete);
  89. AddArgument("setup-pin-code", 0, 134217727, &mSetupPINCode);
  90. AddArgument("discriminator", 0, 4096, &mDiscriminator);
  91. break;
  92. case PairingMode::OnNetwork:
  93. AddArgument("skip-commissioning-complete", 0, 1, &mSkipCommissioningComplete);
  94. AddArgument("setup-pin-code", 0, 134217727, &mSetupPINCode);
  95. AddArgument("pase-only", 0, 1, &mPaseOnly);
  96. break;
  97. case PairingMode::SoftAP:
  98. AddArgument("skip-commissioning-complete", 0, 1, &mSkipCommissioningComplete);
  99. AddArgument("setup-pin-code", 0, 134217727, &mSetupPINCode);
  100. AddArgument("discriminator", 0, 4096, &mDiscriminator);
  101. AddArgument("device-remote-ip", &mRemoteAddr);
  102. AddArgument("device-remote-port", 0, UINT16_MAX, &mRemotePort);
  103. AddArgument("pase-only", 0, 1, &mPaseOnly);
  104. break;
  105. case PairingMode::AlreadyDiscovered:
  106. AddArgument("skip-commissioning-complete", 0, 1, &mSkipCommissioningComplete);
  107. AddArgument("setup-pin-code", 0, 134217727, &mSetupPINCode);
  108. AddArgument("device-remote-ip", &mRemoteAddr);
  109. AddArgument("device-remote-port", 0, UINT16_MAX, &mRemotePort);
  110. AddArgument("pase-only", 0, 1, &mPaseOnly);
  111. break;
  112. case PairingMode::AlreadyDiscoveredByIndex:
  113. AddArgument("skip-commissioning-complete", 0, 1, &mSkipCommissioningComplete);
  114. AddArgument("setup-pin-code", 0, 134217727, &mSetupPINCode);
  115. AddArgument("index", 0, UINT16_MAX, &mIndex);
  116. AddArgument("pase-only", 0, 1, &mPaseOnly);
  117. break;
  118. case PairingMode::AlreadyDiscoveredByIndexWithCode:
  119. AddArgument("skip-commissioning-complete", 0, 1, &mSkipCommissioningComplete);
  120. AddArgument("payload", &mOnboardingPayload);
  121. AddArgument("index", 0, UINT16_MAX, &mIndex);
  122. AddArgument("pase-only", 0, 1, &mPaseOnly);
  123. break;
  124. }
  125. switch (filterType)
  126. {
  127. case chip::Dnssd::DiscoveryFilterType::kNone:
  128. break;
  129. case chip::Dnssd::DiscoveryFilterType::kShortDiscriminator:
  130. AddArgument("discriminator", 0, 15, &mDiscoveryFilterCode);
  131. break;
  132. case chip::Dnssd::DiscoveryFilterType::kLongDiscriminator:
  133. AddArgument("discriminator", 0, 4096, &mDiscoveryFilterCode);
  134. break;
  135. case chip::Dnssd::DiscoveryFilterType::kVendorId:
  136. AddArgument("vendor-id", 0, UINT16_MAX, &mDiscoveryFilterCode);
  137. break;
  138. case chip::Dnssd::DiscoveryFilterType::kCompressedFabricId:
  139. AddArgument("fabric-id", 0, UINT64_MAX, &mDiscoveryFilterCode);
  140. break;
  141. case chip::Dnssd::DiscoveryFilterType::kCommissioningMode:
  142. case chip::Dnssd::DiscoveryFilterType::kCommissioner:
  143. break;
  144. case chip::Dnssd::DiscoveryFilterType::kDeviceType:
  145. AddArgument("device-type", 0, UINT16_MAX, &mDiscoveryFilterCode);
  146. break;
  147. case chip::Dnssd::DiscoveryFilterType::kInstanceName:
  148. AddArgument("name", &mDiscoveryFilterInstanceName);
  149. break;
  150. }
  151. if (mode != PairingMode::None)
  152. {
  153. AddArgument("country-code", &mCountryCode,
  154. "Country code to use to set the Basic Information cluster's Location attribute");
  155. // mTimeZoneList is an optional argument managed by TypedComplexArgument mComplex_TimeZones.
  156. // Since optional Complex arguments are not currently supported via the <chip::Optional> class,
  157. // we explicitly set the kOptional flag.
  158. AddArgument("time-zone", &mComplex_TimeZones,
  159. "TimeZone list to use when setting Time Synchronization cluster's TimeZone attribute", Argument::kOptional);
  160. // mDSTOffsetList is an optional argument managed by TypedComplexArgument mComplex_DSTOffsets.
  161. // Since optional Complex arguments are not currently supported via the <chip::Optional> class,
  162. // we explicitly set the kOptional flag.
  163. AddArgument("dst-offset", &mComplex_DSTOffsets,
  164. "DSTOffset list to use when setting Time Synchronization cluster's DSTOffset attribute",
  165. Argument::kOptional);
  166. }
  167. AddArgument("timeout", 0, UINT16_MAX, &mTimeout);
  168. }
  169. /////////// CHIPCommand Interface /////////
  170. CHIP_ERROR RunCommand() override;
  171. chip::System::Clock::Timeout GetWaitDuration() const override { return chip::System::Clock::Seconds16(mTimeout.ValueOr(120)); }
  172. /////////// DevicePairingDelegate Interface /////////
  173. void OnStatusUpdate(chip::Controller::DevicePairingDelegate::Status status) override;
  174. void OnPairingComplete(CHIP_ERROR error) override;
  175. void OnPairingDeleted(CHIP_ERROR error) override;
  176. void OnCommissioningComplete(NodeId deviceId, CHIP_ERROR error) override;
  177. /////////// DeviceDiscoveryDelegate Interface /////////
  178. void OnDiscoveredDevice(const chip::Dnssd::DiscoveredNodeData & nodeData) override;
  179. /////////// DeviceAttestationDelegate /////////
  180. chip::Optional<uint16_t> FailSafeExpiryTimeoutSecs() const override;
  181. void OnDeviceAttestationCompleted(chip::Controller::DeviceCommissioner * deviceCommissioner, chip::DeviceProxy * device,
  182. const chip::Credentials::DeviceAttestationVerifier::AttestationDeviceInfo & info,
  183. chip::Credentials::AttestationVerificationResult attestationResult) override;
  184. private:
  185. CHIP_ERROR RunInternal(NodeId remoteId);
  186. CHIP_ERROR Pair(NodeId remoteId, PeerAddress address);
  187. CHIP_ERROR PairWithMdns(NodeId remoteId);
  188. CHIP_ERROR PairWithCode(NodeId remoteId);
  189. CHIP_ERROR PaseWithCode(NodeId remoteId);
  190. CHIP_ERROR PairWithMdnsOrBleByIndex(NodeId remoteId, uint16_t index);
  191. CHIP_ERROR PairWithMdnsOrBleByIndexWithCode(NodeId remoteId, uint16_t index);
  192. CHIP_ERROR Unpair(NodeId remoteId);
  193. chip::Controller::CommissioningParameters GetCommissioningParameters();
  194. const PairingMode mPairingMode;
  195. const PairingNetworkType mNetworkType;
  196. const chip::Dnssd::DiscoveryFilterType mFilterType;
  197. Command::AddressWithInterface mRemoteAddr;
  198. NodeId mNodeId;
  199. chip::Optional<uint16_t> mTimeout;
  200. chip::Optional<bool> mDiscoverOnce;
  201. chip::Optional<bool> mUseOnlyOnNetworkDiscovery;
  202. chip::Optional<bool> mPaseOnly;
  203. chip::Optional<bool> mSkipCommissioningComplete;
  204. chip::Optional<bool> mBypassAttestationVerifier;
  205. chip::Optional<std::vector<uint32_t>> mCASEAuthTags;
  206. chip::Optional<char *> mCountryCode;
  207. chip::app::DataModel::List<chip::app::Clusters::TimeSynchronization::Structs::TimeZoneStruct::Type> mTimeZoneList;
  208. TypedComplexArgument<chip::app::DataModel::List<chip::app::Clusters::TimeSynchronization::Structs::TimeZoneStruct::Type>>
  209. mComplex_TimeZones;
  210. chip::app::DataModel::List<chip::app::Clusters::TimeSynchronization::Structs::DSTOffsetStruct::Type> mDSTOffsetList;
  211. TypedComplexArgument<chip::app::DataModel::List<chip::app::Clusters::TimeSynchronization::Structs::DSTOffsetStruct::Type>>
  212. mComplex_DSTOffsets;
  213. uint16_t mRemotePort;
  214. uint16_t mDiscriminator;
  215. uint32_t mSetupPINCode;
  216. uint16_t mIndex;
  217. chip::ByteSpan mOperationalDataset;
  218. chip::ByteSpan mSSID;
  219. chip::ByteSpan mPassword;
  220. char * mOnboardingPayload;
  221. uint64_t mDiscoveryFilterCode;
  222. char * mDiscoveryFilterInstanceName;
  223. // For unpair
  224. chip::Platform::UniquePtr<chip::Controller::CurrentFabricRemover> mCurrentFabricRemover;
  225. chip::Callback::Callback<chip::Controller::OnCurrentFabricRemove> mCurrentFabricRemoveCallback;
  226. static void OnCurrentFabricRemove(void * context, NodeId remoteNodeId, CHIP_ERROR status);
  227. };