blob: 1eea4385449259fff7bb3b9948395fd6a6216926 [file] [log] [blame]
// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "shill/modem.h"
#include <base/file_util.h>
#include <base/stl_util.h>
#include <ModemManager/ModemManager.h>
#include "shill/cellular.h"
#include "shill/device_info.h"
using std::string;
namespace shill {
namespace {
// The default place where the system keeps symbolic links for network device
const char kDefaultNetfilesPath[] = "/sys/class/net";
} // namespace
Modem1::Modem1(const string &owner,
const string &service,
const string &path,
ControlInterface *control_interface,
EventDispatcher *dispatcher,
Metrics *metrics,
Manager *manager,
CellularOperatorInfo *cellular_operator_info,
mobile_provider_db *provider_db)
: Modem(owner, service, path, control_interface, dispatcher, metrics,
manager, cellular_operator_info, provider_db),
netfiles_path_(kDefaultNetfilesPath) {
}
Modem1::~Modem1() {}
bool Modem1::GetLinkName(const DBusPropertiesMap &modem_props,
string *name) const {
string device_prop;
if (!DBusProperties::GetString(modem_props,
MM_MODEM_PROPERTY_DEVICE,
&device_prop)) {
LOG(ERROR) << "Device missing property: " << MM_MODEM_PROPERTY_DEVICE;
return false;
}
if (device_prop.find(DeviceInfo::kModemPseudoDeviceNamePrefix) == 0) {
*name = device_prop;
return true;
}
// |device_prop| will be a sysfs path such as:
// /sys/devices/pci0000:00/0000:00:1d.7/usb1/1-2
FilePath device_path(device_prop);
// Each entry in |netfiles_path_" (typically /sys/class/net)
// has the name of a network interface and is a symlink into the
// actual device structure:
// eth0 -> ../../devices/pci0000:00/0000:00:1c.5/0000:01:00.0/net/eth0
// Iterate over all of these and see if any of them point into
// subdirectories of the sysfs path from the Device property.
// FileEnumerator warns that it is a blocking interface; that
// shouldn't be a problem here.
file_util::FileEnumerator netfiles(netfiles_path_,
false, // don't recurse
file_util::FileEnumerator::DIRECTORIES);
for (FilePath link = netfiles.Next(); !link.empty(); link = netfiles.Next()) {
FilePath target;
if (!file_util::ReadSymbolicLink(link, &target))
continue;
if (!target.IsAbsolute())
target = netfiles_path_.Append(target);
if (file_util::ContainsPath(device_path, target)) {
*name = link.BaseName().value();
return true;
}
}
LOG(ERROR) << "No link name found for: " << device_prop;
return false;
}
void Modem1::CreateDeviceMM1(const DBusInterfaceToProperties &properties) {
Init();
if (!ContainsKey(properties, MM_DBUS_INTERFACE_MODEM)) {
LOG(ERROR) << "Cellular device with no modem properties";
return;
}
set_type(Cellular::kTypeUniversal);
// We cannot check the IP method to make sure it's not PPP. The IP
// method will be checked later when the bearer object is fetched.
CreateDeviceFromModemProperties(properties);
}
string Modem1::GetModemInterface(void) const {
return string(MM_DBUS_INTERFACE_MODEM);
}
} // namespace shill