1 // Copyright 2015 The Weave Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "src/base_api_handler.h" 6 7 #include <base/bind.h> 8 #include <weave/device.h> 9 10 #include "src/commands/schema_constants.h" 11 #include "src/device_registration_info.h" 12 13 namespace weave { 14 15 namespace { 16 const char kBaseComponent[] = "base"; 17 const char kBaseTrait[] = "base"; 18 const char kBaseStateFirmwareVersion[] = "base.firmwareVersion"; 19 const char kBaseStateAnonymousAccessRole[] = "base.localAnonymousAccessMaxRole"; 20 const char kBaseStateDiscoveryEnabled[] = "base.localDiscoveryEnabled"; 21 const char kBaseStatePairingEnabled[] = "base.localPairingEnabled"; 22 } // namespace 23 24 BaseApiHandler::BaseApiHandler(DeviceRegistrationInfo* device_info, 25 Device* device) 26 : device_info_{device_info}, device_{device} { 27 device_->AddTraitDefinitionsFromJson(R"({ 28 "base": { 29 "commands": { 30 "updateBaseConfiguration": { 31 "minimalRole": "manager", 32 "parameters": { 33 "localAnonymousAccessMaxRole": { 34 "enum": [ "none", "viewer", "user" ], 35 "type": "string" 36 }, 37 "localDiscoveryEnabled": { 38 "type": "boolean" 39 }, 40 "localPairingEnabled": { 41 "type": "boolean" 42 } 43 } 44 }, 45 "updateDeviceInfo": { 46 "minimalRole": "manager", 47 "parameters": { 48 "description": { 49 "type": "string" 50 }, 51 "location": { 52 "type": "string" 53 }, 54 "name": { 55 "type": "string" 56 } 57 } 58 }, 59 "reboot": { 60 "minimalRole": "user", 61 "parameters": {}, 62 "errors": ["notEnoughBattery"] 63 }, 64 "identify": { 65 "minimalRole": "user", 66 "parameters": {} 67 } 68 }, 69 "state": { 70 "firmwareVersion": { 71 "type": "string", 72 "isRequired": true 73 }, 74 "localDiscoveryEnabled": { 75 "type": "boolean", 76 "isRequired": true 77 }, 78 "localAnonymousAccessMaxRole": { 79 "type": "string", 80 "enum": [ "none", "viewer", "user" ], 81 "isRequired": true 82 }, 83 "localPairingEnabled": { 84 "type": "boolean", 85 "isRequired": true 86 }, 87 "connectionStatus": { 88 "type": "string" 89 }, 90 "network": { 91 "type": "object", 92 "additionalProperties": false, 93 "properties": { 94 "name": { "type": "string" } 95 } 96 } 97 } 98 } 99 })"); 100 CHECK(device_->AddComponent(kBaseComponent, {kBaseTrait}, nullptr)); 101 OnConfigChanged(device_->GetSettings()); 102 103 const auto& settings = device_info_->GetSettings(); 104 base::DictionaryValue state; 105 state.SetString(kBaseStateFirmwareVersion, settings.firmware_version); 106 CHECK(device_->SetStateProperty(kBaseComponent, kBaseStateFirmwareVersion, 107 base::StringValue{settings.firmware_version}, 108 nullptr)); 109 110 device_->AddCommandHandler( 111 kBaseComponent, "base.updateBaseConfiguration", 112 base::Bind(&BaseApiHandler::UpdateBaseConfiguration, 113 weak_ptr_factory_.GetWeakPtr())); 114 115 device_->AddCommandHandler(kBaseComponent, "base.updateDeviceInfo", 116 base::Bind(&BaseApiHandler::UpdateDeviceInfo, 117 weak_ptr_factory_.GetWeakPtr())); 118 119 device_info_->GetMutableConfig()->AddOnChangedCallback(base::Bind( 120 &BaseApiHandler::OnConfigChanged, weak_ptr_factory_.GetWeakPtr())); 121 } 122 123 void BaseApiHandler::UpdateBaseConfiguration( 124 const std::weak_ptr<Command>& cmd) { 125 auto command = cmd.lock(); 126 if (!command) 127 return; 128 CHECK(command->GetState() == Command::State::kQueued) 129 << EnumToString(command->GetState()); 130 command->SetProgress(base::DictionaryValue{}, nullptr); 131 132 const auto& settings = device_info_->GetSettings(); 133 std::string anonymous_access_role{ 134 EnumToString(settings.local_anonymous_access_role)}; 135 bool discovery_enabled{settings.local_discovery_enabled}; 136 bool pairing_enabled{settings.local_pairing_enabled}; 137 138 const auto& parameters = command->GetParameters(); 139 parameters.GetString("localAnonymousAccessMaxRole", &anonymous_access_role); 140 parameters.GetBoolean("localDiscoveryEnabled", &discovery_enabled); 141 parameters.GetBoolean("localPairingEnabled", &pairing_enabled); 142 143 AuthScope auth_scope{AuthScope::kNone}; 144 if (!StringToEnum(anonymous_access_role, &auth_scope)) { 145 ErrorPtr error; 146 Error::AddToPrintf(&error, FROM_HERE, errors::commands::kInvalidPropValue, 147 "Invalid localAnonymousAccessMaxRole value '%s'", 148 anonymous_access_role.c_str()); 149 command->Abort(error.get(), nullptr); 150 return; 151 } 152 153 device_info_->UpdateBaseConfig(auth_scope, discovery_enabled, 154 pairing_enabled); 155 156 command->Complete({}, nullptr); 157 } 158 159 void BaseApiHandler::OnConfigChanged(const Settings& settings) { 160 base::DictionaryValue state; 161 state.SetString(kBaseStateAnonymousAccessRole, 162 EnumToString(settings.local_anonymous_access_role)); 163 state.SetBoolean(kBaseStateDiscoveryEnabled, 164 settings.local_discovery_enabled); 165 state.SetBoolean(kBaseStatePairingEnabled, settings.local_pairing_enabled); 166 device_->SetStateProperties(kBaseComponent, state, nullptr); 167 } 168 169 void BaseApiHandler::UpdateDeviceInfo(const std::weak_ptr<Command>& cmd) { 170 auto command = cmd.lock(); 171 if (!command) 172 return; 173 CHECK(command->GetState() == Command::State::kQueued) 174 << EnumToString(command->GetState()); 175 command->SetProgress(base::DictionaryValue{}, nullptr); 176 177 const auto& settings = device_info_->GetSettings(); 178 std::string name{settings.name}; 179 std::string description{settings.description}; 180 std::string location{settings.location}; 181 182 const auto& parameters = command->GetParameters(); 183 parameters.GetString("name", &name); 184 parameters.GetString("description", &description); 185 parameters.GetString("location", &location); 186 187 device_info_->UpdateDeviceInfo(name, description, location); 188 command->Complete({}, nullptr); 189 } 190 191 } // namespace weave 192