Home | History | Annotate | Download | only in src
      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