// 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 #include #include "src/commands/schema_constants.h" #include "src/device_registration_info.h" namespace weave { namespace { const char kDeviceComponent[] = "device"; const char kDeviceTrait[] = "device"; const char kPrivetTrait[] = "privet"; } // namespace BaseApiHandler::BaseApiHandler(DeviceRegistrationInfo* device_info, Device* device) : device_info_{device_info}, device_{device} { device_->AddTraitDefinitionsFromJson(R"({ "device": { "commands": { "setConfig": { "minimalRole": "user", "parameters": { "name": { "type": "string" }, "description": { "type": "string" }, "location": { "type": "string" } } } }, "state": { "name": { "isRequired": true, "type": "string" }, "description": { "isRequired": true, "type": "string" }, "location": { "type": "string" }, "hardwareId": { "isRequired": true, "type": "string" }, "serialNumber": { "isRequired": true, "type": "string" }, "firmwareVersion": { "isRequired": true, "type": "string" } } }, "privet": { "commands": { "setConfig": { "minimalRole": "manager", "parameters": { "isLocalAccessEnabled": { "type": "boolean" }, "maxRoleForAnonymousAccess": { "type": "string", "enum": [ "none", "viewer", "user", "manager" ] } } } }, "state": { "apiVersion": { "isRequired": true, "type": "string" }, "isLocalAccessEnabled": { "isRequired": true, "type": "boolean" }, "maxRoleForAnonymousAccess": { "isRequired": true, "type": "string", "enum": [ "none", "viewer", "user", "manager" ] } } } })"); CHECK(device_->AddComponent(kDeviceComponent, {kDeviceTrait, kPrivetTrait}, nullptr)); OnConfigChanged(device_->GetSettings()); const auto& settings = device_info_->GetSettings(); base::DictionaryValue state; state.SetString("device.firmwareVersion", settings.firmware_version); state.SetString("device.hardwareId", settings.device_id); state.SetString("device.serialNumber", settings.serial_number); state.SetString("privet.apiVersion", "3"); // Presently Privet v3. CHECK(device_->SetStateProperties(kDeviceComponent, state, nullptr)); device_->AddCommandHandler( kDeviceComponent, "device.setConfig", base::Bind(&BaseApiHandler::DeviceSetConfig, weak_ptr_factory_.GetWeakPtr())); device_->AddCommandHandler(kDeviceComponent, "privet.setConfig", base::Bind(&BaseApiHandler::PrivetSetConfig, weak_ptr_factory_.GetWeakPtr())); device_info_->GetMutableConfig()->AddOnChangedCallback(base::Bind( &BaseApiHandler::OnConfigChanged, weak_ptr_factory_.GetWeakPtr())); } void BaseApiHandler::PrivetSetConfig(const std::weak_ptr& 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 local_access_enabled{settings.local_access_enabled}; const auto& parameters = command->GetParameters(); parameters.GetString("maxRoleForAnonymousAccess", &anonymous_access_role); parameters.GetBoolean("isLocalAccessEnabled", &local_access_enabled); AuthScope auth_scope{AuthScope::kNone}; if (!StringToEnum(anonymous_access_role, &auth_scope)) { ErrorPtr error; Error::AddToPrintf(&error, FROM_HERE, errors::commands::kInvalidPropValue, "Invalid maxRoleForAnonymousAccess value '%s'", anonymous_access_role.c_str()); command->Abort(error.get(), nullptr); return; } device_info_->UpdatePrivetConfig(auth_scope, local_access_enabled); command->Complete({}, nullptr); } void BaseApiHandler::OnConfigChanged(const Settings& settings) { base::DictionaryValue state; state.SetString("privet.maxRoleForAnonymousAccess", EnumToString(settings.local_anonymous_access_role)); state.SetBoolean("privet.isLocalAccessEnabled", settings.local_access_enabled); state.SetString("device.name", settings.name); state.SetString("device.location", settings.location); state.SetString("device.description", settings.description); device_->SetStateProperties(kDeviceComponent, state, nullptr); } void BaseApiHandler::DeviceSetConfig(const std::weak_ptr& 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