| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium OS Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium OS Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/device.h" | 5 #include "src/device.h" |
| 6 | 6 |
| 7 #include <glog/logging.h> | 7 #include <glog/logging.h> |
| 8 | 8 |
| 9 #include "src/service.h" | 9 #include "src/service.h" |
| 10 | 10 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 22 // Flimflam Device on-the-wire Type values | 22 // Flimflam Device on-the-wire Type values |
| 23 static const char* kFlimflamDeviceTypeEthernet = "ethernet"; | 23 static const char* kFlimflamDeviceTypeEthernet = "ethernet"; |
| 24 static const char* kFlimflamDeviceTypeWifi = "wifi"; | 24 static const char* kFlimflamDeviceTypeWifi = "wifi"; |
| 25 static const char* kFlimflamDeviceTypeWimax = "wimax"; | 25 static const char* kFlimflamDeviceTypeWimax = "wimax"; |
| 26 static const char* kFlimflamDeviceTypeBluetooth = "bluetooth"; | 26 static const char* kFlimflamDeviceTypeBluetooth = "bluetooth"; |
| 27 static const char* kFlimflamDeviceTypeGPS = "gps"; | 27 static const char* kFlimflamDeviceTypeGPS = "gps"; |
| 28 static const char* kFlimflamDeviceTypeCellular = "cellular"; | 28 static const char* kFlimflamDeviceTypeCellular = "cellular"; |
| 29 // TODO(vlaviano): what does vendor look like? | 29 // TODO(vlaviano): what does vendor look like? |
| 30 static const char* kFlimflamDeviceTypeVendor = ""; | 30 static const char* kFlimflamDeviceTypeVendor = ""; |
| 31 | 31 |
| 32 // GetDeviceProperties retry interval |
| 33 static const guint kSecondsPerMinute = 60; |
| 34 static const guint kGetDevicePropertiesIntervalSeconds = 1 * kSecondsPerMinute; |
| 35 |
| 32 Device::Device(Service * const parent, DBus::Connection& connection, // NOLINT | 36 Device::Device(Service * const parent, DBus::Connection& connection, // NOLINT |
| 33 const DBus::Path& path) | 37 const DBus::Path& path) |
| 34 : DBus::ObjectProxy(connection, path, kFlimflamDeviceName), | 38 : DBus::ObjectProxy(connection, path, kFlimflamDeviceName), |
| 35 parent_(CHECK_NOTNULL(parent)), path_(path), type_(kTypeUnknown), | 39 parent_(CHECK_NOTNULL(parent)), path_(path), type_(kTypeUnknown), |
| 36 carrier_(kCarrierUnknown) { | 40 carrier_(kCarrierUnknown), get_properties_source_id_(0), |
| 37 // init our state with a GetProperties() call to our Flimflam service path | 41 retrying_get_properties_(false) { |
| 38 // we'll update this state by monitoring PropertyChanged signals | 42 // schedule a GetProperties() call to our Flimflam service path to init state |
| 39 GetDeviceProperties(); | 43 // we'll keep trying periodically until we succeed |
| 44 // we'll subsequently update this state by monitoring PropertyChanged signals |
| 45 get_properties_source_id_ = |
| 46 g_idle_add(StaticGetDevicePropertiesCallback, this); |
| 47 if (get_properties_source_id_ == 0) { |
| 48 LOG(ERROR) << path_ << ": ctor: g_idle_add failed"; |
| 49 } |
| 40 } | 50 } |
| 41 | 51 |
| 42 Device::~Device() { | 52 Device::~Device() { |
| 53 if (get_properties_source_id_ != 0 && |
| 54 !g_source_remove(get_properties_source_id_)) { |
| 55 DLOG(WARNING) << path_ << ": dtor: g_source_remove failed"; |
| 56 } |
| 43 } | 57 } |
| 44 | 58 |
| 45 const DBus::Path& Device::GetPath() const { | 59 const DBus::Path& Device::GetPath() const { |
| 46 return path_; | 60 return path_; |
| 47 } | 61 } |
| 48 | 62 |
| 49 Device::Type Device::GetType() const { | 63 Device::Type Device::GetType() const { |
| 50 return type_; | 64 return type_; |
| 51 } | 65 } |
| 52 | 66 |
| 53 const std::string& Device::GetCarrier() const { | 67 const std::string& Device::GetCarrier() const { |
| 54 return carrier_; | 68 return carrier_; |
| 55 } | 69 } |
| 56 | 70 |
| 57 // Flimflam Device D-Bus Proxy methods | 71 // Flimflam Device D-Bus Proxy methods |
| 72 |
| 58 void Device::PropertyChanged(const std::string& property_name, | 73 void Device::PropertyChanged(const std::string& property_name, |
| 59 const DBus::Variant& new_value) { | 74 const DBus::Variant& new_value) { |
| 60 DLOG(INFO) << path_ << ": PropertyChanged: property_name = " << property_name; | 75 DLOG(INFO) << path_ << ": PropertyChanged: property_name = " << property_name; |
| 61 if (property_name == kFlimflamDeviceCarrierProperty) { | 76 if (property_name == kFlimflamDeviceCarrierProperty) { |
| 62 OnCarrierUpdate(new_value.reader().get_string()); | 77 OnCarrierUpdate(new_value.reader().get_string()); |
| 63 } else if (property_name == kFlimflamDeviceTypeProperty) { | 78 } else if (property_name == kFlimflamDeviceTypeProperty) { |
| 64 OnTypeUpdate(new_value.reader().get_string()); | 79 OnTypeUpdate(new_value.reader().get_string()); |
| 65 } else { | 80 } else { |
| 66 // we don't care about this property | 81 // we don't care about this property |
| 67 } | 82 } |
| 68 } | 83 } |
| 69 | 84 |
| 85 // glib integration interface |
| 86 |
| 87 guint Device::GetGetPropertiesSourceId() const { |
| 88 return get_properties_source_id_; |
| 89 } |
| 90 |
| 91 void Device::SetGetPropertiesSourceId(guint source_id) { |
| 92 get_properties_source_id_ = source_id; |
| 93 } |
| 94 |
| 95 bool Device::RetryingGetProperties() const { |
| 96 return retrying_get_properties_; |
| 97 } |
| 98 |
| 99 void Device::OnRetryingGetProperties(bool retrying) { |
| 100 retrying_get_properties_ = retrying; |
| 101 } |
| 102 |
| 70 // Private methods | 103 // Private methods |
| 71 | 104 |
| 72 Device::Type Device::TypeFromString(const std::string& type) const { | 105 Device::Type Device::TypeFromString(const std::string& type) const { |
| 73 if (type == kFlimflamDeviceTypeEthernet) { | 106 if (type == kFlimflamDeviceTypeEthernet) { |
| 74 return kTypeEthernet; | 107 return kTypeEthernet; |
| 75 } | 108 } |
| 76 if (type == kFlimflamDeviceTypeWifi) { | 109 if (type == kFlimflamDeviceTypeWifi) { |
| 77 return kTypeWifi; | 110 return kTypeWifi; |
| 78 } | 111 } |
| 79 if (type == kFlimflamDeviceTypeWimax) { | 112 if (type == kFlimflamDeviceTypeWimax) { |
| (...skipping 29 matching lines...) Expand all Loading... |
| 109 } | 142 } |
| 110 | 143 |
| 111 void Device::OnTypeUpdate(const std::string& type) { | 144 void Device::OnTypeUpdate(const std::string& type) { |
| 112 DLOG(INFO) << path_ << ": OnTypeUpdate: type = " << type; | 145 DLOG(INFO) << path_ << ": OnTypeUpdate: type = " << type; |
| 113 type_ = TypeFromString(type); | 146 type_ = TypeFromString(type); |
| 114 if (type_ != kTypeCellular) { | 147 if (type_ != kTypeCellular) { |
| 115 LOG(WARNING) << path_ << ": OnTypeUpdate: type is not cellular!"; | 148 LOG(WARNING) << path_ << ": OnTypeUpdate: type is not cellular!"; |
| 116 } | 149 } |
| 117 } | 150 } |
| 118 | 151 |
| 119 void Device::GetDeviceProperties() { | 152 // static |
| 153 gboolean Device::StaticGetDevicePropertiesCallback(gpointer data) { |
| 154 Device *device = reinterpret_cast<Device*>(data); |
| 155 CHECK_NOTNULL(device); |
| 156 DCHECK_NE(device->GetGetPropertiesSourceId(), 0); |
| 157 if (!device->GetDeviceProperties()) { |
| 158 // call failed, so try again later |
| 159 DLOG(WARNING) << device->GetPath() |
| 160 << ": StaticGetDevicePropertiesCallback: " |
| 161 << "GetDeviceProperties failed, will retry in " |
| 162 << kGetDevicePropertiesIntervalSeconds << " secs"; |
| 163 // if we've arrived here from our first g_idle_add call, set up a timer |
| 164 if (!device->RetryingGetProperties()) { |
| 165 guint source_id = |
| 166 g_timeout_add_seconds(kGetDevicePropertiesIntervalSeconds, |
| 167 StaticGetDevicePropertiesCallback, device); |
| 168 device->SetGetPropertiesSourceId(source_id); |
| 169 if (source_id == 0) { |
| 170 LOG(ERROR) << device->GetPath() |
| 171 << ": StaticGetDevicePropertiesCallback: " |
| 172 << "g_timeout_add_seconds failed"; |
| 173 return FALSE; // get rid of old glib source and give up |
| 174 } |
| 175 device->OnRetryingGetProperties(true); |
| 176 // get rid of our old glib source, but our new timer will call us |
| 177 return FALSE; |
| 178 } |
| 179 // otherwise, our timer is already set up |
| 180 // return TRUE to indicate that we want to be called again later |
| 181 return TRUE; |
| 182 } |
| 183 device->SetGetPropertiesSourceId(0); |
| 184 device->OnRetryingGetProperties(false); |
| 185 return FALSE; // we succeeded, so don't repeat |
| 186 } |
| 187 |
| 188 bool Device::GetDeviceProperties() { |
| 120 DLOG(INFO) << path_ << ": GetDeviceProperties"; | 189 DLOG(INFO) << path_ << ": GetDeviceProperties"; |
| 121 PropertyMap properties; | 190 PropertyMap properties; |
| 122 // dbus-c++ throws exceptions | 191 // dbus-c++ throws exceptions |
| 123 // invoke the "Existing Non-conformant Code" clause of the style guide and | 192 // invoke the "Existing Non-conformant Code" clause of the style guide and |
| 124 // isolate the rest of the system from this | 193 // isolate the rest of the system from this |
| 125 try { | 194 try { |
| 126 // TODO(vlaviano): make this call asynchronous | 195 // TODO(vlaviano): make this call asynchronous |
| 127 properties = GetProperties(); | 196 properties = GetProperties(); |
| 128 } catch (DBus::Error& error) { // NOLINT | 197 } catch (DBus::Error& error) { // NOLINT |
| 129 LOG(WARNING) << path_ | 198 LOG(WARNING) << path_ |
| 130 << ": GetDeviceProperties: GetProperties() -> Exception: " | 199 << ": GetDeviceProperties: GetProperties() -> Exception: " |
| 131 << error.name() << ": " << error.message(); | 200 << error.name() << ": " << error.message(); |
| 132 // TODO(vlaviano): schedule another attempt later | 201 return false; |
| 133 return; | |
| 134 } catch (...) { // NOLINT | 202 } catch (...) { // NOLINT |
| 135 LOG(WARNING) << path_ | 203 LOG(WARNING) << path_ |
| 136 << ": GetDeviceProperties: GetProperties() -> Exception"; | 204 << ": GetDeviceProperties: GetProperties() -> Exception"; |
| 137 // TODO(vlaviano): schedule another attempt later | 205 return false; |
| 138 return; | |
| 139 } | 206 } |
| 140 DLOG(INFO) << "Received " << properties.size() << " properties"; | 207 DLOG(INFO) << "Received " << properties.size() << " properties"; |
| 141 | 208 |
| 142 // grab the properties in which we're interested | 209 // grab the properties in which we're interested |
| 143 PropertyMap::const_iterator it; | 210 PropertyMap::const_iterator it; |
| 144 it = properties.find(kFlimflamDeviceTypeProperty); | 211 it = properties.find(kFlimflamDeviceTypeProperty); |
| 145 if (it != properties.end()) { | 212 if (it != properties.end()) { |
| 146 const DBus::Variant& value = static_cast<DBus::Variant>(it->second); | 213 const DBus::Variant& value = static_cast<DBus::Variant>(it->second); |
| 147 OnTypeUpdate(value.reader().get_string()); | 214 OnTypeUpdate(value.reader().get_string()); |
| 148 } else { | 215 } else { |
| 149 DLOG(WARNING) << path_ << ": GetDeviceProperties: no Type property"; | 216 DLOG(WARNING) << path_ << ": GetDeviceProperties: no Type property"; |
| 150 } | 217 } |
| 151 // don't expect to find Cellular.* properties if we're not a cellular device | 218 // don't expect to find Cellular.* properties if we're not a cellular device |
| 152 if (type_ != kTypeCellular) { | 219 if (type_ != kTypeCellular) { |
| 153 return; | 220 return true; |
| 154 } | 221 } |
| 155 it = properties.find(kFlimflamDeviceCarrierProperty); | 222 it = properties.find(kFlimflamDeviceCarrierProperty); |
| 156 if (it != properties.end()) { | 223 if (it != properties.end()) { |
| 157 const DBus::Variant& value = static_cast<DBus::Variant>(it->second); | 224 const DBus::Variant& value = static_cast<DBus::Variant>(it->second); |
| 158 OnCarrierUpdate(value.reader().get_string()); | 225 OnCarrierUpdate(value.reader().get_string()); |
| 159 } else { | 226 } else { |
| 160 DLOG(WARNING) << path_ | 227 DLOG(WARNING) << path_ |
| 161 << ": GetDeviceProperties: no Cellular.Carrier property"; | 228 << ": GetDeviceProperties: no Cellular.Carrier property"; |
| 162 } | 229 } |
| 230 return true; |
| 163 } | 231 } |
| 164 | 232 |
| 165 } // namespace cashew | 233 } // namespace cashew |
| OLD | NEW |