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