/* * Copyright (c) 2022 Project CHIP Authors * All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #pragma once #import #include #include #include #include #include #include "../provider/OTAProviderDelegate.h" inline constexpr char kIdentityAlpha[] = "alpha"; inline constexpr char kIdentityBeta[] = "beta"; inline constexpr char kIdentityGamma[] = "gamma"; class CHIPCommandBridge : public Command { public: CHIPCommandBridge(const char * commandName, const char * helpText = nullptr) : Command(commandName, helpText) { AddArgument("commissioner-name", &mCommissionerName); AddArgument("commissioner-nodeId", 0, UINT64_MAX, &mCommissionerNodeId, "Sets the commissioner node ID of the given " "commissioner-name. Interactive mode will only set a single commissioner on the inital command. " "The commissioner node ID will be persisted until a different one is specified."); AddArgument("commissioner-shared-storage", 0, 1, &mCommissionerSharedStorage, "Use a shared storage instance instead of individual storage for each commissioner. Default is true."); AddArgument("paa-trust-store-path", &mPaaTrustStorePath, "Path to directory holding PAA certificate information. Can be absolute or relative to the current working " "directory."); AddArgument( "storage-directory", &mStorageDirectory, "This option does nothing. It is here for API compatibility with chip-tool."); AddArgument("commissioner-vendor-id", 0, UINT16_MAX, &mCommissionerVendorId, "The vendor id to use for darwin-framework-tool. If not provided, chip::VendorId::TestVendor1 (65521, 0xFFF1) will be " "used."); } /////////// Command Interface ///////// CHIP_ERROR Run() override; // Will convert error to a CHIP_ERROR and call SetCommandExitStatus with the // result. If a log string is provided, will log that plus the string // representation of the CHIP_ERROR. void SetCommandExitStatus(NSError * error, const char * logString = nullptr); void SetCommandExitStatus(CHIP_ERROR status) { mCommandExitStatus = status; StopWaiting(); } static OTAProviderDelegate * mOTADelegate; protected: // Will be called in a setting in which it's safe to touch the CHIP // stack. The rules for Run() are as follows: // // 1) If error is returned, Run() must not call SetCommandExitStatus. // 2) If success is returned Run() must either have called // SetCommandExitStatus() or scheduled async work that will do that. virtual CHIP_ERROR RunCommand() = 0; // Get the wait duration, in seconds, before the command times out. virtual chip::System::Clock::Timeout GetWaitDuration() const = 0; // Shut down the command, in case any work needs to be done after the event // loop has been stopped. virtual void Shutdown() {} void SetIdentity(const char * identity); // This method returns the commissioner instance to be used for running the command. MTRDeviceController * CurrentCommissioner(); NSNumber * CurrentCommissionerFabricId(); MTRDeviceController * GetCommissioner(const char * identity); // Returns the MTRBaseDevice for the specified node ID. // Will utilize an existing PASE connection if the device is being commissioned. MTRBaseDevice * BaseDeviceWithNodeId(chip::NodeId nodeId); // Will log the given string and given error (as progress if success, error // if failure). void LogNSError(const char * logString, NSError * error); // Clean up any resources allocated by the command. Some commands may hold // on to resources after Shutdown(), but Cleanup() will guarantee those are // cleaned up. virtual void Cleanup() {} // If true, skip calling Cleanup() when in interactive mode, so the command // can keep doing work as needed. Cleanup() will be called when quitting // interactive mode. This method will be called before Shutdown, so it can // use member values that Shutdown will normally reset. virtual bool DeferInteractiveCleanup() { return NO; } // Execute any deferred cleanups. Used when exiting interactive mode. void ExecuteDeferredCleanups(); static std::set sDeferredCleanups; void StopCommissioners(); void RestartCommissioners(); private: CHIP_ERROR InitializeCommissioner( std::string key, chip::FabricId fabricId, const chip::Credentials::AttestationTrustStore * trustStore); void ShutdownCommissioner(); uint16_t CurrentCommissionerIndex(); CHIP_ERROR mCommandExitStatus = CHIP_ERROR_INTERNAL; CHIP_ERROR StartWaiting(chip::System::Clock::Timeout seconds); void StopWaiting(); CHIP_ERROR MaybeSetUpStack(); CHIP_ERROR SetUpStackWithSharedStorage(NSArray * productAttestationAuthorityCertificates); CHIP_ERROR SetUpStackWithPerControllerStorage(NSArray * productAttestationAuthorityCertificates); void MaybeTearDownStack(); CHIP_ERROR GetPAACertsFromFolder(NSArray * __autoreleasing * paaCertsResult); // Our three controllers: alpha, beta, gamma. static std::map mControllers; // The current controller; the one the current command should be using. MTRDeviceController * mCurrentController; static bool sUseSharedStorage; chip::Optional mCommissionerSharedStorage; std::condition_variable cvWaitingForResponse; std::mutex cvWaitingForResponseMutex; chip::Optional mCommissionerName; chip::Optional mCommissionerNodeId; bool mWaitingForResponse { true }; static dispatch_queue_t mOTAProviderCallbackQueue; chip::Optional mPaaTrustStorePath; chip::Optional mCommissionerVendorId; std::string mCurrentIdentity; };