blob: 535fb40fc8d4c4ea62f3f224f0623266e2884fcf [file] [log] [blame]
// 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