|  | // Copyright 2015 The Weave Authors. All rights reserved. | 
|  | // Use of this source code is governed by a BSD-style license that can be | 
|  | // found in the LICENSE file. | 
|  |  | 
|  | #include "src/base_api_handler.h" | 
|  |  | 
|  | #include <base/bind.h> | 
|  | #include <weave/device.h> | 
|  |  | 
|  | #include "src/commands/schema_constants.h" | 
|  | #include "src/device_registration_info.h" | 
|  |  | 
|  | namespace weave { | 
|  |  | 
|  | namespace { | 
|  | const char kBaseComponent[] = "base"; | 
|  | const char kBaseTrait[] = "base"; | 
|  | const char kBaseStateFirmwareVersion[] = "base.firmwareVersion"; | 
|  | const char kBaseStateAnonymousAccessRole[] = "base.localAnonymousAccessMaxRole"; | 
|  | const char kBaseStateDiscoveryEnabled[] = "base.localDiscoveryEnabled"; | 
|  | const char kBaseStatePairingEnabled[] = "base.localPairingEnabled"; | 
|  | }  // namespace | 
|  |  | 
|  | BaseApiHandler::BaseApiHandler(DeviceRegistrationInfo* device_info, | 
|  | Device* device) | 
|  | : device_info_{device_info}, device_{device} { | 
|  | device_->AddTraitDefinitionsFromJson(R"({ | 
|  | "base": { | 
|  | "commands": { | 
|  | "updateBaseConfiguration": { | 
|  | "minimalRole": "manager", | 
|  | "parameters": { | 
|  | "localAnonymousAccessMaxRole": { | 
|  | "enum": [ "none", "viewer", "user" ], | 
|  | "type": "string" | 
|  | }, | 
|  | "localDiscoveryEnabled": { | 
|  | "type": "boolean" | 
|  | }, | 
|  | "localPairingEnabled": { | 
|  | "type": "boolean" | 
|  | } | 
|  | } | 
|  | }, | 
|  | "updateDeviceInfo": { | 
|  | "minimalRole": "manager", | 
|  | "parameters": { | 
|  | "description": { | 
|  | "type": "string" | 
|  | }, | 
|  | "location": { | 
|  | "type": "string" | 
|  | }, | 
|  | "name": { | 
|  | "type": "string" | 
|  | } | 
|  | } | 
|  | }, | 
|  | "reboot": { | 
|  | "minimalRole": "user", | 
|  | "parameters": {}, | 
|  | "errors": ["notEnoughBattery"] | 
|  | }, | 
|  | "identify": { | 
|  | "minimalRole": "user", | 
|  | "parameters": {} | 
|  | } | 
|  | }, | 
|  | "state": { | 
|  | "firmwareVersion": { | 
|  | "type": "string", | 
|  | "isRequired": true | 
|  | }, | 
|  | "localDiscoveryEnabled": { | 
|  | "type": "boolean", | 
|  | "isRequired": true | 
|  | }, | 
|  | "localAnonymousAccessMaxRole": { | 
|  | "type": "string", | 
|  | "enum": [ "none", "viewer", "user" ], | 
|  | "isRequired": true | 
|  | }, | 
|  | "localPairingEnabled": { | 
|  | "type": "boolean", | 
|  | "isRequired": true | 
|  | }, | 
|  | "connectionStatus": { | 
|  | "type": "string" | 
|  | }, | 
|  | "network": { | 
|  | "type": "object", | 
|  | "additionalProperties": false, | 
|  | "properties": { | 
|  | "name": { "type": "string" } | 
|  | } | 
|  | } | 
|  | } | 
|  | } | 
|  | })"); | 
|  | CHECK(device_->AddComponent(kBaseComponent, {kBaseTrait}, nullptr)); | 
|  | OnConfigChanged(device_->GetSettings()); | 
|  |  | 
|  | const auto& settings = device_info_->GetSettings(); | 
|  | base::DictionaryValue state; | 
|  | state.SetString(kBaseStateFirmwareVersion, settings.firmware_version); | 
|  | CHECK(device_->SetStateProperty(kBaseComponent, kBaseStateFirmwareVersion, | 
|  | base::StringValue{settings.firmware_version}, | 
|  | nullptr)); | 
|  |  | 
|  | device_->AddCommandHandler( | 
|  | kBaseComponent, "base.updateBaseConfiguration", | 
|  | base::Bind(&BaseApiHandler::UpdateBaseConfiguration, | 
|  | weak_ptr_factory_.GetWeakPtr())); | 
|  |  | 
|  | device_->AddCommandHandler(kBaseComponent, "base.updateDeviceInfo", | 
|  | base::Bind(&BaseApiHandler::UpdateDeviceInfo, | 
|  | weak_ptr_factory_.GetWeakPtr())); | 
|  |  | 
|  | device_info_->GetMutableConfig()->AddOnChangedCallback(base::Bind( | 
|  | &BaseApiHandler::OnConfigChanged, weak_ptr_factory_.GetWeakPtr())); | 
|  | } | 
|  |  | 
|  | void BaseApiHandler::UpdateBaseConfiguration( | 
|  | const std::weak_ptr<Command>& cmd) { | 
|  | auto command = cmd.lock(); | 
|  | if (!command) | 
|  | return; | 
|  | CHECK(command->GetState() == Command::State::kQueued) | 
|  | << EnumToString(command->GetState()); | 
|  | command->SetProgress(base::DictionaryValue{}, nullptr); | 
|  |  | 
|  | const auto& settings = device_info_->GetSettings(); | 
|  | std::string anonymous_access_role{ | 
|  | EnumToString(settings.local_anonymous_access_role)}; | 
|  | bool discovery_enabled{settings.local_discovery_enabled}; | 
|  | bool pairing_enabled{settings.local_pairing_enabled}; | 
|  |  | 
|  | const auto& parameters = command->GetParameters(); | 
|  | parameters.GetString("localAnonymousAccessMaxRole", &anonymous_access_role); | 
|  | parameters.GetBoolean("localDiscoveryEnabled", &discovery_enabled); | 
|  | parameters.GetBoolean("localPairingEnabled", &pairing_enabled); | 
|  |  | 
|  | AuthScope auth_scope{AuthScope::kNone}; | 
|  | if (!StringToEnum(anonymous_access_role, &auth_scope)) { | 
|  | ErrorPtr error; | 
|  | Error::AddToPrintf(&error, FROM_HERE, errors::commands::kInvalidPropValue, | 
|  | "Invalid localAnonymousAccessMaxRole value '%s'", | 
|  | anonymous_access_role.c_str()); | 
|  | command->Abort(error.get(), nullptr); | 
|  | return; | 
|  | } | 
|  |  | 
|  | device_info_->UpdateBaseConfig(auth_scope, discovery_enabled, | 
|  | pairing_enabled); | 
|  |  | 
|  | command->Complete({}, nullptr); | 
|  | } | 
|  |  | 
|  | void BaseApiHandler::OnConfigChanged(const Settings& settings) { | 
|  | base::DictionaryValue state; | 
|  | state.SetString(kBaseStateAnonymousAccessRole, | 
|  | EnumToString(settings.local_anonymous_access_role)); | 
|  | state.SetBoolean(kBaseStateDiscoveryEnabled, | 
|  | settings.local_discovery_enabled); | 
|  | state.SetBoolean(kBaseStatePairingEnabled, settings.local_pairing_enabled); | 
|  | device_->SetStateProperties(kBaseComponent, state, nullptr); | 
|  | } | 
|  |  | 
|  | void BaseApiHandler::UpdateDeviceInfo(const std::weak_ptr<Command>& cmd) { | 
|  | auto command = cmd.lock(); | 
|  | if (!command) | 
|  | return; | 
|  | CHECK(command->GetState() == Command::State::kQueued) | 
|  | << EnumToString(command->GetState()); | 
|  | command->SetProgress(base::DictionaryValue{}, nullptr); | 
|  |  | 
|  | const auto& settings = device_info_->GetSettings(); | 
|  | std::string name{settings.name}; | 
|  | std::string description{settings.description}; | 
|  | std::string location{settings.location}; | 
|  |  | 
|  | const auto& parameters = command->GetParameters(); | 
|  | parameters.GetString("name", &name); | 
|  | parameters.GetString("description", &description); | 
|  | parameters.GetString("location", &location); | 
|  |  | 
|  | device_info_->UpdateDeviceInfo(name, description, location); | 
|  | command->Complete({}, nullptr); | 
|  | } | 
|  |  | 
|  | }  // namespace weave |