1//
2// Copyright (C) 2013 The Android Open Source Project
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8//      http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15//
16
17#include "shill/cellular/modem.h"
18
19#include <ModemManager/ModemManager.h>
20
21#include "shill/cellular/cellular.h"
22#include "shill/device_info.h"
23
24using std::string;
25using std::vector;
26
27namespace shill {
28
29Modem1::Modem1(const string& service,
30               const string& path,
31               ModemInfo* modem_info,
32               ControlInterface* control_interface)
33    : Modem(service, path, modem_info, control_interface) {}
34
35Modem1::~Modem1() {}
36
37bool Modem1::GetLinkName(const KeyValueStore& modem_props,
38                         string* name) const {
39  if (!modem_props.Contains(MM_MODEM_PROPERTY_PORTS)) {
40    LOG(ERROR) << "Device missing property: " << MM_MODEM_PROPERTY_PORTS;
41    return false;
42  }
43
44  auto ports = modem_props.Get(MM_MODEM_PROPERTY_PORTS).
45      Get<vector<std::tuple<string, uint32_t>>>();
46  string net_port;
47  for (const auto& port_pair : ports) {
48    if (std::get<1>(port_pair) == MM_MODEM_PORT_TYPE_NET) {
49      net_port = std::get<0>(port_pair);
50      break;
51    }
52  }
53
54  if (net_port.empty()) {
55    LOG(ERROR) << "Could not find net port used by the device.";
56    return false;
57  }
58
59  *name = net_port;
60  return true;
61}
62
63void Modem1::CreateDeviceMM1(const InterfaceToProperties& properties) {
64  Init();
65  uint32_t capabilities = std::numeric_limits<uint32_t>::max();
66  InterfaceToProperties::const_iterator it =
67      properties.find(MM_DBUS_INTERFACE_MODEM);
68  if (it == properties.end()) {
69    LOG(ERROR) << "Cellular device with no modem properties";
70    return;
71  }
72  const KeyValueStore& modem_props = it->second;
73  if (modem_props.ContainsUint(MM_MODEM_PROPERTY_CURRENTCAPABILITIES)) {
74    capabilities =
75      modem_props.GetUint(MM_MODEM_PROPERTY_CURRENTCAPABILITIES);
76  }
77
78  if ((capabilities & MM_MODEM_CAPABILITY_LTE) ||
79      (capabilities & MM_MODEM_CAPABILITY_GSM_UMTS)) {
80    set_type(Cellular::kTypeUniversal);
81  } else if (capabilities & MM_MODEM_CAPABILITY_CDMA_EVDO) {
82    set_type(Cellular::kTypeUniversalCDMA);
83  } else {
84    LOG(ERROR) << "Unsupported capabilities: " << capabilities;
85    return;
86  }
87
88  // We cannot check the IP method to make sure it's not PPP. The IP
89  // method will be checked later when the bearer object is fetched.
90  CreateDeviceFromModemProperties(properties);
91}
92
93string Modem1::GetModemInterface(void) const {
94  return string(MM_DBUS_INTERFACE_MODEM);
95}
96
97}  // namespace shill
98