blob: 90be67e50a89cdec898bf0e2c781fb4bb4eb649b [file] [log] [blame]
David Rochbergfa1d31d2012-03-20 10:38:07 -04001// Copyright (c) 2012 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
Nathan Williamsfd10ec22012-04-11 20:29:16 -04007#include <base/file_util.h>
Ben Chanf6120e92012-06-28 18:56:17 -07008#include <ModemManager/ModemManager-enums.h>
9#include <ModemManager/ModemManager-names.h>
David Rochbergfa1d31d2012-03-20 10:38:07 -040010
11#include "shill/cellular.h"
Jason Glasgowabc54032012-04-20 16:08:32 -040012#include "shill/device_info.h"
David Rochbergfa1d31d2012-03-20 10:38:07 -040013
14using std::string;
15
16namespace shill {
17
Jason Glasgow82f9ab32012-04-04 14:27:19 -040018namespace {
19// The default place where the system keeps symbolic links for network device
20const char kDefaultNetfilesPath[] = "/sys/class/net";
21} // namespace {}
22
David Rochbergfa1d31d2012-03-20 10:38:07 -040023Modem1::Modem1(const string &owner,
Jason Glasgowa585fc32012-06-06 11:04:09 -040024 const string &service,
David Rochbergfa1d31d2012-03-20 10:38:07 -040025 const string &path,
26 ControlInterface *control_interface,
27 EventDispatcher *dispatcher,
28 Metrics *metrics,
29 Manager *manager,
30 mobile_provider_db *provider_db)
Jason Glasgowa585fc32012-06-06 11:04:09 -040031 : Modem(owner, service, path, control_interface, dispatcher, metrics,
32 manager, provider_db),
Jason Glasgow82f9ab32012-04-04 14:27:19 -040033 netfiles_path_(kDefaultNetfilesPath) {
David Rochbergfa1d31d2012-03-20 10:38:07 -040034}
35
36Modem1::~Modem1() {}
37
Nathan Williamsfd10ec22012-04-11 20:29:16 -040038bool Modem1::GetLinkName(const DBusPropertiesMap &modem_props,
David Rochbergfa1d31d2012-03-20 10:38:07 -040039 string *name) const {
Nathan Williamsfd10ec22012-04-11 20:29:16 -040040 string device_prop;
41 if (!DBusProperties::GetString(modem_props,
Jason Glasgow82f9ab32012-04-04 14:27:19 -040042 MM_MODEM_PROPERTY_DEVICE,
Nathan Williamsfd10ec22012-04-11 20:29:16 -040043 &device_prop)) {
Jason Glasgowabc54032012-04-20 16:08:32 -040044 LOG(ERROR) << "Device missing property: " << MM_MODEM_PROPERTY_DEVICE;
Nathan Williamsfd10ec22012-04-11 20:29:16 -040045 return false;
46 }
47
Jason Glasgowabc54032012-04-20 16:08:32 -040048 if (device_prop.find(DeviceInfo::kModemPseudoDeviceNamePrefix) == 0) {
49 *name = device_prop;
50 return true;
51 }
52
Nathan Williamsfd10ec22012-04-11 20:29:16 -040053 // |device_prop| will be a sysfs path such as:
54 // /sys/devices/pci0000:00/0000:00:1d.7/usb1/1-2
55 FilePath device_path(device_prop);
56
Jason Glasgow82f9ab32012-04-04 14:27:19 -040057 // Each entry in |netfiles_path_" (typically /sys/class/net)
58 // has the name of a network interface and is a symlink into the
59 // actual device structure:
Nathan Williamsfd10ec22012-04-11 20:29:16 -040060 // eth0 -> ../../devices/pci0000:00/0000:00:1c.5/0000:01:00.0/net/eth0
61 // Iterate over all of these and see if any of them point into
62 // subdirectories of the sysfs path from the Device property.
Nathan Williamsfd10ec22012-04-11 20:29:16 -040063 // FileEnumerator warns that it is a blocking interface; that
64 // shouldn't be a problem here.
Jason Glasgow82f9ab32012-04-04 14:27:19 -040065 file_util::FileEnumerator netfiles(netfiles_path_,
Nathan Williamsfd10ec22012-04-11 20:29:16 -040066 false, // don't recurse
67 file_util::FileEnumerator::DIRECTORIES);
68 for (FilePath link = netfiles.Next(); !link.empty(); link = netfiles.Next()) {
69 FilePath target;
70 if (!file_util::ReadSymbolicLink(link, &target))
71 continue;
72 if (!target.IsAbsolute())
Jason Glasgow82f9ab32012-04-04 14:27:19 -040073 target = netfiles_path_.Append(target);
Nathan Williamsfd10ec22012-04-11 20:29:16 -040074 if (file_util::ContainsPath(device_path, target)) {
75 *name = link.BaseName().value();
76 return true;
77 }
78 }
Jason Glasgowabc54032012-04-20 16:08:32 -040079 LOG(ERROR) << "No link name found for: " << device_prop;
Nathan Williamsfd10ec22012-04-11 20:29:16 -040080 return false;
David Rochbergfa1d31d2012-03-20 10:38:07 -040081}
82
83void Modem1::CreateDeviceMM1(const DBusInterfaceToProperties &i_to_p) {
Eric Shienbrood11567d02012-04-10 18:08:49 -040084 Init();
David Rochbergfa1d31d2012-03-20 10:38:07 -040085 DBusInterfaceToProperties::const_iterator modem_properties =
86 i_to_p.find(MM_DBUS_INTERFACE_MODEM);
87 if (modem_properties == i_to_p.end()) {
88 LOG(ERROR) << "Cellular device with no modem properties";
89 return;
90 }
91 set_type(Cellular::kTypeUniversal);
92
93 // We cannot check the IP method to make sure it's not PPP. The IP
94 // method will be checked later when the bearer object is fetched.
Jason Glasgow82f9ab32012-04-04 14:27:19 -040095 // TODO(jglasgow): We should pass i_to_p because there are lots of
96 // properties we might want
David Rochbergfa1d31d2012-03-20 10:38:07 -040097 CreateDeviceFromModemProperties(modem_properties->second);
98}
99
Jason Glasgow4c0724a2012-04-17 15:47:40 -0400100string Modem1::GetModemInterface(void) const {
101 return string(MM_DBUS_INTERFACE_MODEM);
102}
103
David Rochbergfa1d31d2012-03-20 10:38:07 -0400104} // namespace shill