• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/privet/privet_manager.h"
6 
7 #include <memory>
8 #include <set>
9 #include <string>
10 
11 #include <base/bind.h>
12 #include <base/json/json_reader.h>
13 #include <base/json/json_writer.h>
14 #include <base/memory/weak_ptr.h>
15 #include <base/scoped_observer.h>
16 #include <base/strings/string_number_conversions.h>
17 #include <base/values.h>
18 #include <weave/provider/network.h>
19 
20 #include "src/bind_lambda.h"
21 #include "src/component_manager.h"
22 #include "src/device_registration_info.h"
23 #include "src/http_constants.h"
24 #include "src/privet/auth_manager.h"
25 #include "src/privet/cloud_delegate.h"
26 #include "src/privet/constants.h"
27 #include "src/privet/device_delegate.h"
28 #include "src/privet/privet_handler.h"
29 #include "src/privet/publisher.h"
30 #include "src/streams.h"
31 #include "src/string_utils.h"
32 
33 namespace weave {
34 namespace privet {
35 
36 using provider::TaskRunner;
37 using provider::Network;
38 using provider::DnsServiceDiscovery;
39 using provider::HttpServer;
40 using provider::Wifi;
41 
Manager(TaskRunner * task_runner)42 Manager::Manager(TaskRunner* task_runner) : task_runner_{task_runner} {}
43 
~Manager()44 Manager::~Manager() {}
45 
Start(Network * network,DnsServiceDiscovery * dns_sd,HttpServer * http_server,Wifi * wifi,AuthManager * auth_manager,DeviceRegistrationInfo * device,ComponentManager * component_manager)46 void Manager::Start(Network* network,
47                     DnsServiceDiscovery* dns_sd,
48                     HttpServer* http_server,
49                     Wifi* wifi,
50                     AuthManager* auth_manager,
51                     DeviceRegistrationInfo* device,
52                     ComponentManager* component_manager) {
53   CHECK(auth_manager);
54   CHECK(device);
55 
56   device_ = DeviceDelegate::CreateDefault(
57       task_runner_, http_server->GetHttpPort(), http_server->GetHttpsPort(),
58       http_server->GetRequestTimeout());
59   cloud_ =
60       CloudDelegate::CreateDefault(task_runner_, device, component_manager);
61   cloud_observer_.Add(cloud_.get());
62 
63   security_.reset(new SecurityManager(device->GetMutableConfig(), auth_manager,
64                                       task_runner_));
65   network->AddConnectionChangedCallback(
66       base::Bind(&Manager::OnConnectivityChanged, base::Unretained(this)));
67 
68   if (wifi && device->GetSettings().wifi_auto_setup_enabled) {
69     VLOG(1) << "Enabling WiFi bootstrapping.";
70     wifi_bootstrap_manager_.reset(new WifiBootstrapManager(
71         device->GetMutableConfig(), task_runner_, network, wifi, cloud_.get()));
72     wifi_bootstrap_manager_->Init();
73   }
74 
75   if (dns_sd) {
76     publisher_.reset(new Publisher(device_.get(), cloud_.get(),
77                                    wifi_bootstrap_manager_.get(), dns_sd));
78   }
79 
80   privet_handler_.reset(new PrivetHandler(cloud_.get(), device_.get(),
81                                           security_.get(),
82                                           wifi_bootstrap_manager_.get()));
83 
84   for (const auto& path : privet_handler_->GetHttpPaths()) {
85     http_server->AddHttpRequestHandler(
86         path, base::Bind(&Manager::PrivetRequestHandler,
87                          weak_ptr_factory_.GetWeakPtr()));
88   }
89 
90   for (const auto& path : privet_handler_->GetHttpsPaths()) {
91     http_server->AddHttpsRequestHandler(
92         path, base::Bind(&Manager::PrivetRequestHandler,
93                          weak_ptr_factory_.GetWeakPtr()));
94   }
95 }
96 
GetCurrentlyConnectedSsid() const97 std::string Manager::GetCurrentlyConnectedSsid() const {
98   return wifi_bootstrap_manager_
99              ? wifi_bootstrap_manager_->GetCurrentlyConnectedSsid()
100              : "";
101 }
102 
AddOnPairingChangedCallbacks(const SecurityManager::PairingStartListener & on_start,const SecurityManager::PairingEndListener & on_end)103 void Manager::AddOnPairingChangedCallbacks(
104     const SecurityManager::PairingStartListener& on_start,
105     const SecurityManager::PairingEndListener& on_end) {
106   security_->RegisterPairingListeners(on_start, on_end);
107 }
108 
OnDeviceInfoChanged()109 void Manager::OnDeviceInfoChanged() {
110   OnChanged();
111 }
112 
PrivetRequestHandler(std::unique_ptr<provider::HttpServer::Request> req)113 void Manager::PrivetRequestHandler(
114     std::unique_ptr<provider::HttpServer::Request> req) {
115   std::shared_ptr<provider::HttpServer::Request> request{std::move(req)};
116 
117   std::string content_type =
118       SplitAtFirst(request->GetFirstHeader(http::kContentType), ";", true)
119           .first;
120 
121   return PrivetRequestHandlerWithData(request, content_type == http::kJson
122                                                    ? request->GetData()
123                                                    : std::string{});
124 }
125 
PrivetRequestHandlerWithData(const std::shared_ptr<provider::HttpServer::Request> & request,const std::string & data)126 void Manager::PrivetRequestHandlerWithData(
127     const std::shared_ptr<provider::HttpServer::Request>& request,
128     const std::string& data) {
129   std::string auth_header = request->GetFirstHeader(http::kAuthorization);
130   base::DictionaryValue empty;
131   auto value = base::JSONReader::Read(data);
132   const base::DictionaryValue* dictionary = &empty;
133   if (value)
134     value->GetAsDictionary(&dictionary);
135 
136   VLOG(3) << "Input: " << *dictionary;
137 
138   privet_handler_->HandleRequest(
139       request->GetPath(), auth_header, dictionary,
140       base::Bind(&Manager::PrivetResponseHandler,
141                  weak_ptr_factory_.GetWeakPtr(), request));
142 }
143 
PrivetResponseHandler(const std::shared_ptr<provider::HttpServer::Request> & request,int status,const base::DictionaryValue & output)144 void Manager::PrivetResponseHandler(
145     const std::shared_ptr<provider::HttpServer::Request>& request,
146     int status,
147     const base::DictionaryValue& output) {
148   VLOG(3) << "status: " << status << ", Output: " << output;
149   std::string data;
150   base::JSONWriter::WriteWithOptions(
151       output, base::JSONWriter::OPTIONS_PRETTY_PRINT, &data);
152   request->SendReply(status, data, http::kJson);
153 }
154 
OnChanged()155 void Manager::OnChanged() {
156   VLOG(1) << "Manager::OnChanged";
157   if (publisher_)
158     publisher_->Update();
159 }
160 
OnConnectivityChanged()161 void Manager::OnConnectivityChanged() {
162   OnChanged();
163 }
164 
165 }  // namespace privet
166 }  // namespace weave
167