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 42 Manager::Manager(TaskRunner* task_runner) : task_runner_{task_runner} {} 43 44 Manager::~Manager() {} 45 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 97 std::string Manager::GetCurrentlyConnectedSsid() const { 98 return wifi_bootstrap_manager_ 99 ? wifi_bootstrap_manager_->GetCurrentlyConnectedSsid() 100 : ""; 101 } 102 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 109 void Manager::OnDeviceInfoChanged() { 110 OnChanged(); 111 } 112 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 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 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 155 void Manager::OnChanged() { 156 VLOG(1) << "Manager::OnChanged"; 157 if (publisher_) 158 publisher_->Update(); 159 } 160 161 void Manager::OnConnectivityChanged() { 162 OnChanged(); 163 } 164 165 } // namespace privet 166 } // namespace weave 167