blob: 4f24ede42eac9af8eab2df94112920706c711979 [file] [log] [blame]
Peter Qiufb39ba42014-11-21 09:09:59 -08001// Copyright 2014 The Chromium OS 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 "apmanager/device.h"
6
7#include <base/strings/stringprintf.h>
8#include <chromeos/dbus/service_constants.h>
9#include <shill/net/ieee80211.h>
10
11using chromeos::dbus_utils::AsyncEventSequencer;
12using chromeos::dbus_utils::ExportedObjectManager;
13using shill::ByteString;
14using std::string;
15
16namespace apmanager {
17
Peter Qiu1ff67a72014-11-22 07:06:10 -080018Device::Device(const string& device_name)
Peter Qiufb39ba42014-11-21 09:09:59 -080019 : org::chromium::apmanager::DeviceAdaptor(this) {
Peter Qiu1ff67a72014-11-22 07:06:10 -080020 SetDeviceName(device_name);
Peter Qiufb39ba42014-11-21 09:09:59 -080021 SetInUsed(false);
22}
23
24Device::~Device() {}
25
26void Device::RegisterAsync(ExportedObjectManager* object_manager,
27 AsyncEventSequencer* sequencer,
28 int device_identifier) {
29 CHECK(!dbus_object_) << "Already registered";
30 dbus_path_ = dbus::ObjectPath(
31 base::StringPrintf("%s/devices/%d",
32 kManagerPath,
33 device_identifier));
34 dbus_object_.reset(
35 new chromeos::dbus_utils::DBusObject(
36 object_manager,
37 object_manager ? object_manager->GetBus() : nullptr,
38 dbus_path_));
39 RegisterWithDBusObject(dbus_object_.get());
40 dbus_object_->RegisterAsync(
41 sequencer->GetHandler("Config.RegisterAsync() failed.", true));
42}
43
44void Device::RegisterInterface(const WiFiInterface& new_interface) {
45 LOG(INFO) << "RegisteringInterface " << new_interface.iface_name
46 << " on device " << GetDeviceName();
47 for (const auto& interface : interface_list_) {
48 // Done if interface already in the list.
49 if (interface.iface_index == new_interface.iface_index) {
50 LOG(INFO) << "Interface " << new_interface.iface_name
51 << " already registered.";
52 return;
53 }
54 }
55 interface_list_.push_back(new_interface);
56 UpdatePreferredAPInterface();
57}
58
59void Device::DeregisterInterface(const WiFiInterface& interface) {
60 LOG(INFO) << "DeregisteringInterface " << interface.iface_name
61 << " on device " << GetDeviceName();
62 for (auto it = interface_list_.begin(); it != interface_list_.end(); ++it) {
63 if (it->iface_index == interface.iface_index) {
64 interface_list_.erase(it);
65 UpdatePreferredAPInterface();
66 return;
67 }
68 }
69}
70
Peter Qiu1ff67a72014-11-22 07:06:10 -080071void Device::ParseWiphyCapability(const shill::Nl80211Message& msg) {
Peter Qiufb39ba42014-11-21 09:09:59 -080072 // TODO(zqiu): Parse capabilities.
73}
74
75bool Device::ClaimDevice() {
76 if (GetInUsed()) {
77 LOG(ERROR) << "Failed to claim device [" << GetDeviceName()
78 << "]: already in used.";
79 return false;
80 }
81
82 // TODO(zqiu): Issue dbus call to shill to claim all interfaces on this
83 // device.
84
85 SetInUsed(true);
86 return true;
87}
88
89bool Device::ReleaseDevice() {
90 if (!GetInUsed()) {
91 LOG(ERROR) << "Failed to release device [" << GetDeviceName()
92 << "]: not currently in-used.";
93 return false;
94 }
95
96 // TODO(zqiu): Issue dbus call to shill to release all interfaces on this
97 // device.
98
99 SetInUsed(false);
100 return true;
101}
102
103bool Device::InterfaceExists(const string& interface_name) {
104 for (const auto& interface : interface_list_) {
105 if (interface.iface_name == interface_name) {
106 return true;
107 }
108 }
109 return false;
110}
111
112void Device::UpdatePreferredAPInterface() {
113 // Use the first registered AP mode interface if there is one, otherwise use
114 // the first registered managed mode interface. If none are available, then
115 // no interface can be used for AP operation on this device.
116 WiFiInterface preferred_interface;
117 for (const auto& interface : interface_list_) {
118 if (interface.iface_type == NL80211_IFTYPE_AP) {
119 preferred_interface = interface;
120 break;
121 } else if (interface.iface_type == NL80211_IFTYPE_STATION &&
122 preferred_interface.iface_name.empty()) {
123 preferred_interface = interface;
124 }
125 // Ignore all other interface types.
126 }
127 // Update preferred AP interface property.
128 SetPreferredApInterface(preferred_interface.iface_name);
129}
130
131} // namespace apmanager