blob: 8e15156a1c9225704adda5f2fea1e7b887d14ed2 [file] [log] [blame]
Darin Petkov5c97ac52011-07-19 16:30:49 -07001// Copyright (c) 2011 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 "shill/modem.h"
6
Darin Petkove0a312e2011-07-20 13:45:28 -07007#include <base/logging.h>
8#include <mm/mm-modem.h>
9
10#include "shill/cellular.h"
11#include "shill/manager.h"
Darin Petkov5c97ac52011-07-19 16:30:49 -070012#include "shill/proxy_factory.h"
Darin Petkove0a312e2011-07-20 13:45:28 -070013#include "shill/rtnl_handler.h"
14
15using std::string;
Darin Petkovc5f56562011-08-06 16:40:05 -070016using std::vector;
Darin Petkov5c97ac52011-07-19 16:30:49 -070017
18namespace shill {
19
Darin Petkove0a312e2011-07-20 13:45:28 -070020// TODO(petkov): Consider generating these in mm/mm-modem.h.
21const char Modem::kPropertyLinkName[] = "Device";
22const char Modem::kPropertyIPMethod[] = "IpMethod";
23const char Modem::kPropertyType[] = "Type";
24const char Modem::kPropertyUnlockRequired[] = "UnlockRequired";
25const char Modem::kPropertyUnlockRetries[] = "UnlockRetries";
26
Darin Petkov5c97ac52011-07-19 16:30:49 -070027Modem::Modem(const std::string &owner,
28 const std::string &path,
29 ControlInterface *control_interface,
30 EventDispatcher *dispatcher,
31 Manager *manager)
Darin Petkove0a312e2011-07-20 13:45:28 -070032 : owner_(owner),
33 path_(path),
Darin Petkov67d8ecf2011-07-26 16:03:30 -070034 task_factory_(this),
Darin Petkov5c97ac52011-07-19 16:30:49 -070035 control_interface_(control_interface),
36 dispatcher_(dispatcher),
Darin Petkove0a312e2011-07-20 13:45:28 -070037 manager_(manager) {
38 LOG(INFO) << "Modem created: " << owner << " at " << path;
39}
Darin Petkov5c97ac52011-07-19 16:30:49 -070040
41Modem::~Modem() {}
42
Darin Petkove0a312e2011-07-20 13:45:28 -070043void Modem::Init() {
Darin Petkov67d8ecf2011-07-26 16:03:30 -070044 VLOG(2) << __func__;
Darin Petkove0a312e2011-07-20 13:45:28 -070045 CHECK(!device_.get());
Darin Petkova7b89492011-07-27 12:48:17 -070046
47 // Defer device creation because dbus-c++ doesn't allow registration of new
48 // D-Bus objects in the context of a D-Bus signal handler.
49 dispatcher_->PostTask(task_factory_.NewRunnableMethod(&Modem::InitTask));
50}
51
52void Modem::InitTask() {
53 VLOG(2) << __func__;
54 CHECK(!device_.get());
55
Darin Petkove0a312e2011-07-20 13:45:28 -070056 dbus_properties_proxy_.reset(
57 ProxyFactory::factory()->CreateDBusPropertiesProxy(this, path_, owner_));
Darin Petkov67d8ecf2011-07-26 16:03:30 -070058
Darin Petkove0a312e2011-07-20 13:45:28 -070059 // TODO(petkov): Switch to asynchronous calls (crosbug.com/17583).
60 DBusPropertiesMap properties =
61 dbus_properties_proxy_->GetAll(MM_MODEM_INTERFACE);
Darin Petkova7b89492011-07-27 12:48:17 -070062 CreateCellularDevice(properties);
Darin Petkove0a312e2011-07-20 13:45:28 -070063}
64
65void Modem::CreateCellularDevice(const DBusPropertiesMap &properties) {
Darin Petkov67d8ecf2011-07-26 16:03:30 -070066 VLOG(2) << __func__;
Darin Petkove0a312e2011-07-20 13:45:28 -070067 uint32 ip_method = kuint32max;
68 if (!DBusProperties::GetUint32(properties, kPropertyIPMethod, &ip_method) ||
69 ip_method != MM_MODEM_IP_METHOD_DHCP) {
70 LOG(ERROR) << "Unsupported IP method: " << ip_method;
71 return;
72 }
73
74 string link_name;
75 if (!DBusProperties::GetString(properties, kPropertyLinkName, &link_name)) {
76 LOG(ERROR) << "Unable to create cellular device without a link name.";
77 return;
78 }
79 int interface_index =
80 RTNLHandler::GetInstance()->GetInterfaceIndex(link_name);
81 if (interface_index < 0) {
82 LOG(ERROR) << "Unable to create cellular device -- no interface index.";
83 return;
84 }
85
Darin Petkove9d12e02011-07-27 15:09:37 -070086 uint32 mm_type = kuint32max;
87 Cellular::Type type;
88 DBusProperties::GetUint32(properties, kPropertyType, &mm_type);
89 switch (mm_type) {
90 case MM_MODEM_TYPE_CDMA:
91 type = Cellular::kTypeCDMA;
92 break;
93 case MM_MODEM_TYPE_GSM:
94 type = Cellular::kTypeGSM;
95 break;
96 default:
97 LOG(ERROR) << "Unsupported cellular modem type: " << mm_type;
98 return;
99 }
Darin Petkove0a312e2011-07-20 13:45:28 -0700100
Darin Petkovbec79a22011-08-01 14:47:17 -0700101 // TODO(petkov): Handle the "State" property?
102
Darin Petkove0a312e2011-07-20 13:45:28 -0700103 LOG(INFO) << "Creating a cellular device on link " << link_name
104 << " interface index " << interface_index << ".";
105 device_ = new Cellular(control_interface_,
106 dispatcher_,
107 manager_,
108 link_name,
Darin Petkove9d12e02011-07-27 15:09:37 -0700109 interface_index,
110 type,
111 owner_,
112 path_);
Darin Petkove0a312e2011-07-20 13:45:28 -0700113 manager_->RegisterDevice(device_);
114
115 string unlock_required;
116 if (DBusProperties::GetString(
117 properties, kPropertyUnlockRequired, &unlock_required)) {
118 uint32 unlock_retries = 0;
119 DBusProperties::GetUint32(properties,
120 kPropertyUnlockRetries,
121 &unlock_retries);
122 // TODO(petkov): Set these properties on the device instance.
123 }
124}
125
Darin Petkovc5f56562011-08-06 16:40:05 -0700126void Modem::OnDBusPropertiesChanged(
127 const string &interface,
128 const DBusPropertiesMap &changed_properties,
129 const vector<string> &invalidated_properties) {
130 // Ignored.
131}
132
133void Modem::OnModemManagerPropertiesChanged(
134 const string &interface,
135 const DBusPropertiesMap &properties) {
136 // TODO(petkov): Implement this.
137 NOTIMPLEMENTED();
138}
139
Darin Petkov5c97ac52011-07-19 16:30:49 -0700140} // namespace shill