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 = ∅
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