blob: 5c84d9c455e13a97b42322ae7d1895f4b7e6f8fb [file] [log] [blame]
// Copyright 2015 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <bitset>
#include <base/bind.h>
#include <base/values.h>
#include <weave/device.h>
#include <weave/error.h>
#include "examples/ubuntu/avahi_client.h"
#include "examples/ubuntu/bluez_client.h"
#include "examples/ubuntu/curl_http_client.h"
#include "examples/ubuntu/event_http_server.h"
#include "examples/ubuntu/event_task_runner.h"
#include "examples/ubuntu/file_config_store.h"
#include "examples/ubuntu/network_manager.h"
namespace {
// Supported LED count on this device
const size_t kLedCount = 3;
void ShowUsage(const std::string& name) {
LOG(ERROR) << "\nUsage: " << name << " <option(s)>"
<< "\nOptions:\n"
<< "\t-h,--help Show this help message\n"
<< "\t-b,--bootstrapping Force WiFi bootstrapping\n"
<< "\t-d,--disable_security Disable privet security\n"
<< "\t--registration_ticket=TICKET Register device with the "
"given ticket\n";
}
class CommandHandler {
public:
explicit CommandHandler(weave::Device* device) : device_{device} {
device->AddCommandAddedCallback(base::Bind(&CommandHandler::OnNewCommand,
weak_ptr_factory_.GetWeakPtr()));
}
private:
void OnNewCommand(weave::Command* cmd) {
LOG(INFO) << "received command: " << cmd->GetName();
if (cmd->GetName() == "_greeter._greet") {
std::string name;
if (!cmd->GetParameters()->GetString("_name", &name))
name = "anonymous";
LOG(INFO) << cmd->GetName() << " command in progress";
cmd->SetProgress(base::DictionaryValue{}, nullptr);
base::DictionaryValue result;
result.SetString("_greeting", "Hello " + name);
cmd->SetResults(result, nullptr);
LOG(INFO) << cmd->GetName() << " command finished: " << result;
base::DictionaryValue state;
state.SetIntegerWithoutPathExpansion("_greeter._greetings_counter",
++counter_);
device_->SetStateProperties(state, nullptr);
LOG(INFO) << "New state: " << *device_->GetState();
cmd->Done();
} else if (cmd->GetName() == "_ledflasher._set") {
int32_t led_index;
bool cmd_value;
if (cmd->GetParameters()->GetInteger("_led", &led_index) &&
cmd->GetParameters()->GetBoolean("_on", &cmd_value)) {
// Display this command in terminal
LOG(INFO) << cmd->GetName() << " _led: " << led_index
<< ", _on: " << (cmd_value ? "true" : "false");
led_index--;
int new_state = cmd_value ? 1 : 0;
int cur_state = led_status_[led_index];
led_status_[led_index] = new_state;
if (cmd_value != cur_state) {
UpdateLedState();
}
}
cmd->Done();
} else if (cmd->GetName() == "_ledflasher._toggle") {
int32_t led_index;
if (cmd->GetParameters()->GetInteger("_led", &led_index)) {
LOG(INFO) << cmd->GetName() << " _led: " << led_index;
led_index--;
led_status_[led_index] = ~led_status_[led_index];
UpdateLedState();
}
cmd->Done();
} else {
LOG(INFO) << cmd->GetName() << " unimplemented command: ignored";
}
}
void UpdateLedState(void) {
base::ListValue list;
for (uint32_t i = 0; i < led_status_.size(); i++)
list.AppendBoolean(led_status_[i] ? true : false);
device_->SetStateProperty("_ledflasher._leds", list, nullptr);
}
weave::Device* device_{nullptr};
int counter_{0};
// Simulate LED status on this device so client app could explore
// Each bit represents one device, indexing from LSB
std::bitset<kLedCount> led_status_{0};
base::WeakPtrFactory<CommandHandler> weak_ptr_factory_{this};
};
} // namespace
int main(int argc, char** argv) {
bool force_bootstrapping = false;
bool disable_security = false;
std::string registration_ticket;
for (int i = 1; i < argc; ++i) {
std::string arg = argv[i];
if (arg == "-h" || arg == "--help") {
ShowUsage(argv[0]);
return 0;
} else if (arg == "-b" || arg == "--bootstrapping") {
force_bootstrapping = true;
} else if (arg == "-d" || arg == "--disable_security") {
disable_security = true;
} else if (arg.find("--registration_ticket") != std::string::npos) {
auto pos = arg.find("=");
if (pos == std::string::npos) {
ShowUsage(argv[0]);
return 1;
}
registration_ticket = arg.substr(pos + 1);
} else {
ShowUsage(argv[0]);
return 1;
}
}
weave::examples::FileConfigStore config_store{disable_security};
weave::examples::EventTaskRunner task_runner;
weave::examples::CurlHttpClient http_client{&task_runner};
weave::examples::NetworkImpl network{&task_runner, force_bootstrapping};
weave::examples::AvahiClient dns_sd;
weave::examples::HttpServerImpl http_server{&task_runner};
weave::examples::BluetoothImpl bluetooth;
auto device = weave::Device::Create(
&config_store, &task_runner, &http_client, &network, &dns_sd,
&http_server,
weave::examples::NetworkImpl::HasWifiCapability() ? &network : nullptr,
&bluetooth);
if (!registration_ticket.empty()) {
weave::ErrorPtr error;
auto device_id = device->Register(registration_ticket, &error);
if (error != nullptr) {
LOG(ERROR) << "Fail to register device: " << error->GetMessage();
} else {
LOG(INFO) << "Device registered: " << device_id;
}
}
CommandHandler handler(device.get());
task_runner.Run();
LOG(INFO) << "exit";
return 0;
}