| // 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 |