Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(nm): add NetworkManagerDbusWrapper and ModemManagerDbusWrapper objects #4757

Merged
merged 29 commits into from
Jul 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
4a6e269
refactor: add NetworkManagerDbusWrapper class
mattdibi Jul 11, 2023
8a84e61
refactor: migrated Version and Permissions getter to wrapper object
mattdibi Jul 11, 2023
bc643c1
refactor: move getDeviceInterface and getDeviceState to new object
mattdibi Jul 11, 2023
130a92b
style: fix indentation
mattdibi Jul 11, 2023
12da045
refactor: move isDeviceManaged
mattdibi Jul 11, 2023
677246a
refactor: move setDeviceManaged
mattdibi Jul 11, 2023
5ba7675
refactor: move getDeviceType
mattdibi Jul 11, 2023
35ae8ee
refactor: move getAllDevices
mattdibi Jul 11, 2023
a0b9e19
refactor: move connection getters
mattdibi Jul 11, 2023
bb544af
feat: add activateConnection method
mattdibi Jul 11, 2023
a511669
refactor: move getAllAccessPoints
mattdibi Jul 11, 2023
b998057
refactor: move getModemManagerDbusPath
mattdibi Jul 11, 2023
3e84ce1
refactor: remove unused objects
mattdibi Jul 11, 2023
026127f
refactor: add ModemManagerDbusWrapper class
mattdibi Jul 11, 2023
694bbbb
refactor: move getModemProperties
mattdibi Jul 11, 2023
701e9ca
refactor: move modem properties getters
mattdibi Jul 11, 2023
001eb07
refactor: move enableModem method
mattdibi Jul 11, 2023
7a0b01d
refactor: move handleModemManagerGPSSetup
mattdibi Jul 11, 2023
ebda046
refactor: rename handleModemManagerGPSSetup -> setGPS
mattdibi Jul 11, 2023
7dead76
fix: remove unused private field
mattdibi Jul 11, 2023
efe38a7
refactor: move reset handlers to ModemManager wrapper
mattdibi Jul 17, 2023
362b8de
refactor: removed obsolete imports and constants
mattdibi Jul 17, 2023
0172dfc
refactor: removed unused member variables and related imports
mattdibi Jul 17, 2023
03f79a2
refactor: move getHardwarePath method to ModemManager wrapper
mattdibi Jul 17, 2023
80f358a
refactor: getHardwarePath -> getHardwareSysfsPath
mattdibi Jul 17, 2023
1b721a2
refactor: simplify getDeviceByInterfaceId by calling getDeviceIdByDBu…
mattdibi Jul 17, 2023
2dea24b
refactor: move methods close to other similar methods
mattdibi Jul 17, 2023
2569d01
refactor: remove unused constant
mattdibi Jul 17, 2023
ce1d92d
refactor: move methods close to other similar methods
mattdibi Jul 17, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,239 @@
package org.eclipse.kura.nm;

import java.util.ArrayList;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;

import org.eclipse.kura.nm.enums.MMModemLocationSource;
import org.eclipse.kura.nm.enums.MMModemState;
import org.eclipse.kura.nm.signal.handlers.NMModemResetHandler;
import org.eclipse.kura.nm.status.SimProperties;
import org.freedesktop.dbus.DBusPath;
import org.freedesktop.dbus.connections.impl.DBusConnection;
import org.freedesktop.dbus.exceptions.DBusException;
import org.freedesktop.dbus.exceptions.DBusExecutionException;
import org.freedesktop.dbus.interfaces.Properties;
import org.freedesktop.dbus.types.UInt32;
import org.freedesktop.modemmanager1.Modem;
import org.freedesktop.modemmanager1.modem.Location;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ModemManagerDbusWrapper {

private static final Logger logger = LoggerFactory.getLogger(ModemManagerDbusWrapper.class);

private static final String MM_BUS_NAME = "org.freedesktop.ModemManager1";
private static final String MM_MODEM_NAME = "org.freedesktop.ModemManager1.Modem";
private static final String MM_SIM_NAME = "org.freedesktop.ModemManager1.Sim";
private static final String MM_MODEM_PROPERTY_STATE = "State";
private static final String MM_LOCATION_BUS_NAME = "org.freedesktop.ModemManager1.Modem.Location";

private DBusConnection dbusConnection;

private final Map<String, NMModemResetHandler> modemHandlers = new HashMap<>();

protected ModemManagerDbusWrapper(DBusConnection dbusConnection) {
this.dbusConnection = dbusConnection;
}

protected void setGPS(Optional<String> modemDevicePath, Optional<Boolean> enableGPS) throws DBusException {
if (!modemDevicePath.isPresent()) {
logger.warn("Cannot retrieve MM.Modem from NM.Modem. Skipping GPS configuration.");
return;
}

enableModem(modemDevicePath.get());

boolean isGPSSourceEnabled = enableGPS.isPresent() && enableGPS.get();

Location modemLocation = this.dbusConnection.getRemoteObject(MM_BUS_NAME, modemDevicePath.get(),
Location.class);
Properties modemLocationProperties = this.dbusConnection.getRemoteObject(MM_BUS_NAME,
modemLocation.getObjectPath(), Properties.class);

Set<MMModemLocationSource> availableLocationSources = EnumSet
.of(MMModemLocationSource.MM_MODEM_LOCATION_SOURCE_NONE);
Set<MMModemLocationSource> currentLocationSources = EnumSet
.of(MMModemLocationSource.MM_MODEM_LOCATION_SOURCE_NONE);
Set<MMModemLocationSource> desiredLocationSources = EnumSet
.of(MMModemLocationSource.MM_MODEM_LOCATION_SOURCE_NONE);

try {
availableLocationSources = MMModemLocationSource.toMMModemLocationSourceFromBitMask(
modemLocationProperties.Get(MM_LOCATION_BUS_NAME, "Capabilities"));
currentLocationSources = MMModemLocationSource
.toMMModemLocationSourceFromBitMask(modemLocationProperties.Get(MM_LOCATION_BUS_NAME, "Enabled"));
} catch (DBusExecutionException e) {
logger.warn("Cannot retrive Modem.Location capabilities for {}. Caused by: ",
modemLocationProperties.getObjectPath(), e);
return;
}

if (isGPSSourceEnabled) {
if (!availableLocationSources.contains(MMModemLocationSource.MM_MODEM_LOCATION_SOURCE_GPS_UNMANAGED)) {
logger.warn("Cannot setup Modem.Location, MM_MODEM_LOCATION_SOURCE_GPS_UNMANAGED not supported for {}",
modemLocationProperties.getObjectPath());
return;
}
desiredLocationSources = EnumSet.of(MMModemLocationSource.MM_MODEM_LOCATION_SOURCE_GPS_UNMANAGED);
}

logger.debug("Modem location setup {} for modem {}", currentLocationSources, modemDevicePath.get());

if (!currentLocationSources.equals(desiredLocationSources)) {
modemLocation.Setup(MMModemLocationSource.toBitMaskFromMMModemLocationSource(desiredLocationSources),
false);
}
}

protected void enableModem(String modemDevicePath) throws DBusException {
Modem modem = this.dbusConnection.getRemoteObject(MM_BUS_NAME, modemDevicePath, Modem.class);
Properties modemProperties = this.dbusConnection.getRemoteObject(MM_BUS_NAME, modemDevicePath,
Properties.class);

MMModemState currentModemState = MMModemState
.toMMModemState(modemProperties.Get(MM_MODEM_NAME, MM_MODEM_PROPERTY_STATE));

if (currentModemState.getValue() < MMModemState.MM_MODEM_STATE_ENABLED.getValue()) {
logger.info("Modem {} not enabled. Enabling modem...", modemDevicePath);
modem.Enable(true);
}
}

protected Optional<Properties> getModemProperties(String modemPath) throws DBusException {
Optional<Properties> modemProperties = Optional.empty();
Properties properties = this.dbusConnection.getRemoteObject(MM_BUS_NAME, modemPath, Properties.class);
if (Objects.nonNull(properties)) {
modemProperties = Optional.of(properties);
}
return modemProperties;
}

protected List<SimProperties> getModemSimProperties(Properties modemProperties) throws DBusException {
List<SimProperties> simProperties = new ArrayList<>();
try {
UInt32 primarySimSlot = modemProperties.Get(MM_MODEM_NAME, "PrimarySimSlot");

if (primarySimSlot.intValue() == 0) {
// Multiple SIM slots aren't supported
DBusPath simPath = modemProperties.Get(MM_MODEM_NAME, "Sim");
if (!simPath.getPath().equals("/")) {
Properties simProp = this.dbusConnection.getRemoteObject(MM_BUS_NAME, simPath.getPath(),
Properties.class);
simProperties.add(new SimProperties(simProp, true, true));
}
} else {
List<DBusPath> simPaths = modemProperties.Get(MM_MODEM_NAME, "SimSlots");
for (int index = 0; index < simPaths.size(); index++) {
String dbusPath = simPaths.get(index).getPath();

if (dbusPath.equals("/")) {
// SIM slot doesn't contain a SIM
continue;
}

Properties simProp = this.dbusConnection.getRemoteObject(MM_BUS_NAME, dbusPath, Properties.class);
boolean isActive = simProp.Get(MM_SIM_NAME, "Active");
boolean isPrimary = index == (primarySimSlot.intValue() - 1);

simProperties.add(new SimProperties(simProp, isActive, isPrimary));
}
}
} catch (DBusExecutionException e) {
// Fallback for ModemManager version prior to 1.16
DBusPath simPath = modemProperties.Get(MM_MODEM_NAME, "Sim");
if (!simPath.getPath().equals("/")) {
Properties simProp = this.dbusConnection.getRemoteObject(MM_BUS_NAME, simPath.getPath(),
Properties.class);
simProperties.add(new SimProperties(simProp, true, true));
}

}
return simProperties;
}

protected String getHardwareSysfsPath(Optional<String> dbusPath) throws DBusException {
if (!dbusPath.isPresent()) {
throw new IllegalStateException(String.format("Cannot retrieve modem path for: %s.", dbusPath));
}
Optional<Properties> modemDeviceProperties = getModemProperties(dbusPath.get());
if (!modemDeviceProperties.isPresent()) {
throw new IllegalStateException(String.format("Cannot retrieve modem properties for: %s.", dbusPath));
}
String modemDeviceProperty = (String) modemDeviceProperties.get().Get(MM_MODEM_NAME, "Device");
return modemDeviceProperty.substring(modemDeviceProperty.lastIndexOf("/") + 1);
}

protected List<Properties> getModemBearersProperties(String modemPath, Properties modemProperties)
throws DBusException {
List<Properties> bearerProperties = new ArrayList<>();
try {
Modem modem = this.dbusConnection.getRemoteObject(MM_BUS_NAME, modemPath, Modem.class);
if (Objects.nonNull(modem)) {
List<DBusPath> bearerPaths = modem.ListBearers();
bearerProperties = getBearersPropertiesFromPaths(bearerPaths);
}
} catch (DBusExecutionException e) {
try {
List<DBusPath> bearerPaths = modemProperties.Get(MM_BUS_NAME, "Bearers");
bearerProperties = getBearersPropertiesFromPaths(bearerPaths);
} catch (DBusExecutionException e1) {
logger.warn("Cannot get bearers for modem {}", modemPath, e1);
}
}
return bearerProperties;
}

private List<Properties> getBearersPropertiesFromPaths(List<DBusPath> bearerPaths) throws DBusException {
List<Properties> bearerProperties = new ArrayList<>();
for (DBusPath bearerPath : bearerPaths) {
if (!bearerPath.getPath().equals("/")) {
bearerProperties
.add(this.dbusConnection.getRemoteObject(MM_BUS_NAME, bearerPath.getPath(), Properties.class));
}
}
return bearerProperties;

}

protected void resetHandlerEnable(String deviceId, Optional<String> modemManagerDbusPath, int delayMinutes,
String networkManagerDbusPath) throws DBusException {
if (!modemManagerDbusPath.isPresent()) {
logger.warn("Cannot retrieve modem device for {}. Skipping modem reset monitor setup.", deviceId);
return;
}

Modem mmModemDevice = this.dbusConnection.getRemoteObject(MM_BUS_NAME, modemManagerDbusPath.get(), Modem.class);

NMModemResetHandler resetHandler = new NMModemResetHandler(networkManagerDbusPath, mmModemDevice,
delayMinutes * 60L * 1000L);

this.modemHandlers.put(deviceId, resetHandler);
this.dbusConnection.addSigHandler(org.freedesktop.networkmanager.Device.StateChanged.class, resetHandler);
}

protected void resetHandlersDisable() {
for (String deviceId : this.modemHandlers.keySet()) {
resetHandlersDisable(deviceId);
}
this.modemHandlers.clear();
}

protected void resetHandlersDisable(String deviceId) {
if (this.modemHandlers.containsKey(deviceId)) {
NMModemResetHandler handler = this.modemHandlers.get(deviceId);
handler.clearTimer();
try {
this.dbusConnection.removeSigHandler(org.freedesktop.networkmanager.Device.StateChanged.class, handler);
} catch (DBusException e) {
logger.warn("Couldn't remove signal handler for: {}. Caused by:", handler.getNMDevicePath(), e);
}
}
}
}
Loading