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