| OLD | NEW |
| (Empty) | |
| 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 |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "src/service.h" |
| 6 |
| 7 #include <glog/logging.h> |
| 8 |
| 9 #include "src/device.h" |
| 10 |
| 11 namespace cashew { |
| 12 |
| 13 // Flimflam Service D-Bus identifiers |
| 14 static const char* kFlimflamServiceName = "org.chromium.flimflam"; |
| 15 |
| 16 // Flimflam Service property names |
| 17 static const char *kFlimflamServiceDeviceProperty = "Device"; |
| 18 static const char *kFlimflamServiceStateProperty = "State"; |
| 19 static const char* kFlimflamServiceTypeProperty = "Type"; |
| 20 |
| 21 // Flimflam Service on-the-wire State values |
| 22 static const char* kFlimflamServiceStateIdle = "idle"; |
| 23 static const char* kFlimflamServiceStateCarrier = "carrier"; |
| 24 static const char* kFlimflamServiceStateAssociation = "association"; |
| 25 static const char* kFlimflamServiceStateConfiguration = "configuration"; |
| 26 static const char* kFlimflamServiceStateReady = "ready"; |
| 27 static const char* kFlimflamServiceStateDisconnect = "disconnect"; |
| 28 static const char* kFlimflamServiceStateFailure = "failure"; |
| 29 static const char* kFlimflamServiceStateActivationFailure = |
| 30 "activation-failure"; |
| 31 |
| 32 // Flimflam Service on-the-wire Type values |
| 33 static const char* kFlimflamServiceTypeEthernet = "ethernet"; |
| 34 static const char* kFlimflamServiceTypeWifi = "wifi"; |
| 35 static const char* kFlimflamServiceTypeWimax = "wimax"; |
| 36 static const char* kFlimflamServiceTypeBluetooth = "bluetooth"; |
| 37 static const char* kFlimflamServiceTypeCellular = "cellular"; |
| 38 |
| 39 Service::Service(DBus::Connection& connection, // NOLINT |
| 40 const DBus::Path& path) |
| 41 : DBus::ObjectProxy(connection, path, kFlimflamServiceName), |
| 42 connection_(connection), path_(path), state_(kStateUnknown), |
| 43 type_(kTypeUnknown), device_(NULL) { |
| 44 // init our state with a GetProperties() call to our Flimflam service path |
| 45 // we'll update this state by monitoring PropertyChanged signals |
| 46 GetServiceProperties(); |
| 47 |
| 48 // init our data plans list with a hardcoded plan |
| 49 // TODO(vlaviano): implement backend and return real data |
| 50 AddHardcodedDataPlan(); |
| 51 } |
| 52 |
| 53 Service::~Service() { |
| 54 DeleteDataPlans(); |
| 55 if (device_ != NULL) { |
| 56 DLOG(INFO) << path_ << ": deleting device " << device_->GetPath(); |
| 57 delete device_; |
| 58 device_ = NULL; |
| 59 } |
| 60 } |
| 61 |
| 62 const DBus::Path& Service::GetPath() const { |
| 63 return path_; |
| 64 } |
| 65 |
| 66 Service::State Service::GetState() const { |
| 67 return state_; |
| 68 } |
| 69 |
| 70 Service::Type Service::GetType() const { |
| 71 return type_; |
| 72 } |
| 73 |
| 74 Device* Service::GetDevice() const { |
| 75 return device_; |
| 76 } |
| 77 |
| 78 DBusDataPlanList Service::GetDBusDataPlans() const { |
| 79 DBusDataPlanList dbus_data_plans; |
| 80 DataPlanList::const_iterator it; |
| 81 for (it = data_plans_.begin(); it != data_plans_.end(); ++it) { |
| 82 DataPlan *plan = *it; |
| 83 DCHECK(plan != NULL); |
| 84 dbus_data_plans.push_back(plan->ToDBusFormat()); |
| 85 } |
| 86 return dbus_data_plans; |
| 87 } |
| 88 |
| 89 // Flimflam Service D-Bus Proxy methods |
| 90 |
| 91 void Service::PropertyChanged(const std::string& property_name, |
| 92 const DBus::Variant& new_value) { |
| 93 DLOG(INFO) << path_ << ": PropertyChanged: property_name = " << property_name; |
| 94 if (property_name.compare(kFlimflamServiceDeviceProperty) == 0) { |
| 95 OnDeviceUpdate(new_value.reader().get_path()); |
| 96 } else if (property_name.compare(kFlimflamServiceStateProperty) == 0) { |
| 97 OnStateUpdate(new_value.reader().get_string()); |
| 98 } else if (property_name.compare(kFlimflamServiceTypeProperty) == 0) { |
| 99 OnTypeUpdate(new_value.reader().get_string()); |
| 100 } else { |
| 101 // we don't care about this property |
| 102 } |
| 103 } |
| 104 |
| 105 // Private methods |
| 106 |
| 107 Service::State Service::StateFromString(const std::string& state) const { |
| 108 if (state.compare(kFlimflamServiceStateIdle) == 0) { |
| 109 return kStateIdle; |
| 110 } |
| 111 if (state.compare(kFlimflamServiceStateCarrier) == 0) { |
| 112 return kStateCarrier; |
| 113 } |
| 114 if (state.compare(kFlimflamServiceStateAssociation) == 0) { |
| 115 return kStateAssociation; |
| 116 } |
| 117 if (state.compare(kFlimflamServiceStateConfiguration) == 0) { |
| 118 return kStateConfiguration; |
| 119 } |
| 120 if (state.compare(kFlimflamServiceStateReady) == 0) { |
| 121 return kStateReady; |
| 122 } |
| 123 if (state.compare(kFlimflamServiceStateDisconnect) == 0) { |
| 124 return kStateDisconnect; |
| 125 } |
| 126 if (state.compare(kFlimflamServiceStateFailure) == 0) { |
| 127 return kStateFailure; |
| 128 } |
| 129 if (state.compare(kFlimflamServiceStateActivationFailure) == 0) { |
| 130 return kStateActivationFailure; |
| 131 } |
| 132 return kStateUnknown; |
| 133 } |
| 134 |
| 135 Service::Type Service::TypeFromString(const std::string& type) const { |
| 136 if (type.compare(kFlimflamServiceTypeEthernet) == 0) { |
| 137 return kTypeEthernet; |
| 138 } |
| 139 if (type.compare(kFlimflamServiceTypeWifi) == 0) { |
| 140 return kTypeWifi; |
| 141 } |
| 142 if (type.compare(kFlimflamServiceTypeWimax) == 0) { |
| 143 return kTypeWimax; |
| 144 } |
| 145 if (type.compare(kFlimflamServiceTypeBluetooth) == 0) { |
| 146 return kTypeBluetooth; |
| 147 } |
| 148 if (type.compare(kFlimflamServiceTypeCellular) == 0) { |
| 149 return kTypeCellular; |
| 150 } |
| 151 return kTypeUnknown; |
| 152 } |
| 153 |
| 154 void Service::OnDeviceUpdate(const DBus::Path& device_path) { |
| 155 DLOG(INFO) << path_ << ": OnDeviceUpdate: device_path = " << device_path; |
| 156 |
| 157 // if there's an existing device with a non-matching path: destroy it and |
| 158 // fall through to make a new one below. |
| 159 if (device_ != NULL && device_->GetPath().compare(device_path)) { |
| 160 LOG(WARNING) << path_ << ": OnDeviceUpdate: device path changed from " |
| 161 << device_->GetPath() << " to " << device_path; |
| 162 delete device_; |
| 163 device_ = NULL; |
| 164 } |
| 165 |
| 166 // if there's an existing device with matching path: all is well |
| 167 if (device_ != NULL) { |
| 168 return; |
| 169 } |
| 170 |
| 171 // if there's no existing device: make one |
| 172 device_ = new(std::nothrow) Device(connection_, device_path); |
| 173 if (device_ == NULL) { |
| 174 LOG(ERROR) << path_ << ": OnDeviceUpdate: couldn't create device for " |
| 175 << device_path; |
| 176 return; |
| 177 } |
| 178 DLOG(INFO) << path_ << ": OnDeviceUpdate: created device for " |
| 179 << device_path; |
| 180 } |
| 181 |
| 182 void Service::OnStateUpdate(const std::string& state) { |
| 183 DLOG(INFO) << path_ << ": OnStateUpdate: state = " << state; |
| 184 state_ = StateFromString(state); |
| 185 // TODO(vlaviano): react to state changes |
| 186 // note that ready does not necessarily mean that we're the default route |
| 187 } |
| 188 |
| 189 void Service::OnTypeUpdate(const std::string& type) { |
| 190 DLOG(INFO) << path_ << ": OnTypeUpdate: type = " << type; |
| 191 type_ = TypeFromString(type); |
| 192 if (type_ != kTypeCellular) { |
| 193 LOG(WARNING) << path_ << ": OnTypeUpdate: type is not cellular!"; |
| 194 } |
| 195 } |
| 196 |
| 197 void Service::GetServiceProperties() { |
| 198 DLOG(INFO) << path_ << ": GetServiceProperties"; |
| 199 PropertyMap properties; |
| 200 // dbus-c++ throws exceptions |
| 201 // invoke the "Existing Non-conformant Code" clause of the style guide and |
| 202 // isolate the rest of the system from this |
| 203 try { |
| 204 // TODO(vlaviano): make this call asynchronous |
| 205 properties = GetProperties(); |
| 206 } catch (DBus::Error& error) { // NOLINT |
| 207 LOG(WARNING) << path_ |
| 208 << ": GetServiceProperties: GetProperties() -> Exception: " |
| 209 << error.name() << ": " << error.message(); |
| 210 // TODO(vlaviano): schedule another attempt later |
| 211 return; |
| 212 } catch (...) { // NOLINT |
| 213 LOG(WARNING) << path_ |
| 214 << ": GetServiceProperties: GetProperties() -> Exception"; |
| 215 // TODO(vlaviano): schedule another attempt later |
| 216 return; |
| 217 } |
| 218 DLOG(INFO) << "Received " << properties.size() << " properties"; |
| 219 |
| 220 // grab the properties in which we're interested |
| 221 PropertyMap::const_iterator it; |
| 222 it = properties.find(kFlimflamServiceDeviceProperty); |
| 223 if (it != properties.end()) { |
| 224 const DBus::Variant& value = static_cast<DBus::Variant>(it->second); |
| 225 OnDeviceUpdate(value.reader().get_path()); |
| 226 } else { |
| 227 DLOG(WARNING) << path_ << ": GetServiceProperties: no Device property"; |
| 228 } |
| 229 it = properties.find(kFlimflamServiceStateProperty); |
| 230 if (it != properties.end()) { |
| 231 const DBus::Variant& value = static_cast<DBus::Variant>(it->second); |
| 232 OnStateUpdate(value.reader().get_string()); |
| 233 } else { |
| 234 DLOG(WARNING) << path_ << ": GetServiceProperties: no State property"; |
| 235 } |
| 236 it = properties.find(kFlimflamServiceTypeProperty); |
| 237 if (it != properties.end()) { |
| 238 const DBus::Variant& value = static_cast<DBus::Variant>(it->second); |
| 239 OnTypeUpdate(value.reader().get_string()); |
| 240 } else { |
| 241 DLOG(WARNING) << path_ << ": GetServiceProperties: no Type property"; |
| 242 } |
| 243 } |
| 244 |
| 245 void Service::DeleteDataPlans() { |
| 246 while (!data_plans_.empty()) { |
| 247 DataPlan *plan = *data_plans_.begin(); |
| 248 DCHECK(plan != NULL); |
| 249 DLOG(INFO) << path_ << ": DeleteDataPlans: deleting plan: " |
| 250 << plan->GetName(); |
| 251 delete plan; |
| 252 data_plans_.erase(data_plans_.begin()); |
| 253 } |
| 254 } |
| 255 |
| 256 void Service::AddHardcodedDataPlan() { |
| 257 const std::string name = "Chromium OS Test Plan"; |
| 258 DataPlan::Type type = DataPlan::kTypeMeteredPaid; |
| 259 base::Time update_time = base::Time::Now(); |
| 260 base::TimeDelta twelve_hours = base::TimeDelta::FromHours(12); |
| 261 base::Time start_time = base::Time::Now() - twelve_hours; |
| 262 base::Time end_time = base::Time::Now() + twelve_hours; |
| 263 Bytes data_bytes_max = 100*1024*1024; // 100 MB |
| 264 Bytes data_bytes_used = 30*1024*1024; // 30 MB |
| 265 |
| 266 DataPlan *plan = new(std::nothrow) DataPlan(name, type, update_time, |
| 267 start_time, end_time, |
| 268 data_bytes_max, data_bytes_used); |
| 269 if (plan == NULL) { |
| 270 LOG(ERROR) << path_ << ": AddHardcodedDataPlan: could not create plan"; |
| 271 return; |
| 272 } |
| 273 |
| 274 data_plans_.push_back(plan); |
| 275 } |
| 276 |
| 277 } // namespace cashew |
| OLD | NEW |