Skip to content

Commit d418d53

Browse files
Use NMDbusConnector for managing modem reset and autoconnection
Signed-off-by: pierantoniomerlino <pierantonio.merlino@eurotech.com>
1 parent 0d30e3d commit d418d53

7 files changed

Lines changed: 168 additions & 134 deletions

File tree

kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/ModemManagerDbusWrapper.java

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@
3434
import org.freedesktop.modemmanager1.Modem;
3535
import org.freedesktop.modemmanager1.modem.Location;
3636
import org.freedesktop.networkmanager.Device;
37-
import org.freedesktop.networkmanager.settings.Connection;
3837
import org.slf4j.Logger;
3938
import org.slf4j.LoggerFactory;
4039

@@ -249,14 +248,16 @@ private List<Properties> getBearersPropertiesFromPaths(List<DBusPath> bearerPath
249248

250249
}
251250

252-
protected void modemTaskHandler(String deviceId, ModemManagerDbusWrapper modemManager,
253-
NetworkManagerDbusWrapper networkManager, Connection connection, Device device,
254-
NetworkProperties properties) throws DBusException {
255-
modemTaskHandlerDisable(deviceId);
256-
ModemTaskScheduler connectionScheduler = new ModemTaskScheduler(networkManager, modemManager, connection,
257-
device, deviceId, properties);
251+
protected void modemTaskHandler(String deviceId, Device device, NetworkProperties properties) throws DBusException {
258252
int resetDelayMinutes = properties.get(Integer.class, "net.interface.%s.config.resetTimeout", deviceId);
259253
boolean autoconnect = properties.get(Boolean.class, "net.interface.%s.config.persist", deviceId);
254+
if (isModemTaskAlreadyActivated(deviceId, resetDelayMinutes, autoconnect)) {
255+
return;
256+
}
257+
modemTaskHandlerDisable(deviceId);
258+
259+
logger.info("Modem {} activated. Starting monitoring task...", deviceId);
260+
ModemTaskScheduler connectionScheduler = new ModemTaskScheduler(deviceId, device, properties);
260261
if (autoconnect) {
261262
connectionScheduler.scheduleConnection();
262263
}
@@ -273,6 +274,25 @@ protected void modemTaskHandler(String deviceId, ModemManagerDbusWrapper modemMa
273274
}
274275
}
275276

277+
private boolean isModemTaskAlreadyActivated(String deviceId, int resetDelayMinutes, boolean autoconnect) {
278+
return isModemTaskHandlerPresent(deviceId) && (isModemTaskHandlerResetActivated(deviceId, resetDelayMinutes)
279+
|| isModemTaskHandlerAutoconnectActivated(deviceId, autoconnect));
280+
}
281+
282+
protected boolean isModemTaskHandlerPresent(String deviceId) {
283+
return this.modemTaskHandlers.containsKey(deviceId);
284+
}
285+
286+
private boolean isModemTaskHandlerResetActivated(String deviceId, int resetDelayMinutes) {
287+
return resetDelayMinutes > 0
288+
&& this.modemTaskHandlers.get(deviceId).getModemConnectionScheduler().isResetScheduled();
289+
}
290+
291+
private boolean isModemTaskHandlerAutoconnectActivated(String deviceId, boolean autoconnect) {
292+
return autoconnect
293+
&& this.modemTaskHandlers.get(deviceId).getModemConnectionScheduler().isConnectionScheduled();
294+
}
295+
276296
protected void modemTaskHandlerDisable(String deviceId) {
277297
if (this.modemTaskHandlers.containsKey(deviceId)) {
278298
NMModemTaskHandler handler = this.modemTaskHandlers.get(deviceId);
@@ -293,7 +313,4 @@ protected void modemTaskHandlerDisable() {
293313
this.modemTaskHandlers.clear();
294314
}
295315

296-
protected boolean isModemTaskHandlerActive(String deviceId) {
297-
return this.modemTaskHandlers.containsKey(deviceId);
298-
}
299316
}

kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/ModemTaskScheduler.java

Lines changed: 38 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -20,59 +20,55 @@
2020
import java.util.concurrent.TimeUnit;
2121
import java.util.concurrent.atomic.AtomicBoolean;
2222

23-
import org.eclipse.kura.nm.enums.MMModemState;
2423
import org.freedesktop.dbus.exceptions.DBusException;
2524
import org.freedesktop.dbus.exceptions.DBusExecutionException;
2625
import org.freedesktop.modemmanager1.Modem;
2726
import org.freedesktop.networkmanager.Device;
28-
import org.freedesktop.networkmanager.settings.Connection;
2927
import org.slf4j.Logger;
3028
import org.slf4j.LoggerFactory;
3129

3230
public class ModemTaskScheduler {
3331

3432
private static final Logger logger = LoggerFactory.getLogger(ModemTaskScheduler.class);
3533

36-
private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(5);
37-
private final NetworkManagerDbusWrapper networkManager;
38-
private final ModemManagerDbusWrapper modemManager;
34+
private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(3);
3935
private final Device device;
40-
private final Connection connection;
4136
private final int maxFail;
4237
private final int holdoff;
4338
private final boolean autoconnect;
4439
private final int resetDelayMinutes;
4540
private final String deviceId;
4641

42+
private Optional<NMDbusConnector> nmDbusConnector = Optional.empty();
4743
private ScheduledFuture<?> connectionHandler;
4844
private ScheduledFuture<?> resetHandler;
4945
private AtomicBoolean isConnectionScheduled = new AtomicBoolean(false);
5046
private AtomicBoolean isResetScheduled = new AtomicBoolean(false);
51-
private Optional<String> mmDbusPath;
5247
private int delay = 0;
5348

54-
public ModemTaskScheduler(NetworkManagerDbusWrapper networkManager, ModemManagerDbusWrapper modemManager,
55-
Connection connection, Device device, String deviceId, NetworkProperties properties) {
56-
this.networkManager = Objects.requireNonNull(networkManager);
57-
this.modemManager = Objects.requireNonNull(modemManager);
49+
public ModemTaskScheduler(String deviceId, Device device, NetworkProperties properties) {
50+
51+
try {
52+
this.nmDbusConnector = Optional.of(NMDbusConnector.getInstance());
53+
} catch (DBusExecutionException | DBusException e) {
54+
logger.error("Cannot initialize NMDbusConnector due to: ", e);
55+
}
56+
5857
this.device = Objects.requireNonNull(device);
59-
this.connection = Objects.requireNonNull(connection);
6058
this.resetDelayMinutes = properties.get(Integer.class, "net.interface.%s.config.resetTimeout", deviceId);
6159
this.autoconnect = properties.get(Boolean.class, "net.interface.%s.config.persist", deviceId);
6260
this.holdoff = properties.get(Integer.class, "net.interface.%s.config.holdoff", deviceId);
6361
this.maxFail = properties.get(Integer.class, "net.interface.%s.config.maxFail", deviceId);
6462
this.deviceId = deviceId;
6563

6664
this.delay = this.holdoff != 0 && this.maxFail != 0 ? this.holdoff * this.maxFail : 90;
67-
try {
68-
this.mmDbusPath = this.networkManager.getModemManagerDbusPath(this.device.getObjectPath());
69-
} catch (DBusException e) {
70-
logger.warn("Could not get ModemManager dbus path for device {} because: ", this.device.getObjectPath(), e);
71-
this.mmDbusPath = Optional.empty();
72-
}
7365
}
7466

7567
public void scheduleConnection() {
68+
if (isModemConnected()) {
69+
logger.info("Connection for modem {} successful", this.deviceId);
70+
return;
71+
}
7672
if (isConnectionScheduled.get() || !this.autoconnect) {
7773
return;
7874
}
@@ -85,7 +81,9 @@ private void tryConnection(int attemptNumber) {
8581
try {
8682
logger.debug("Connection attempt {} for modem {} with path {} ...", attemptNumber, this.deviceId,
8783
this.device.getObjectPath());
88-
this.networkManager.activateConnection(this.connection, this.device);
84+
if (this.nmDbusConnector.isPresent()) {
85+
this.nmDbusConnector.get().apply(deviceId);
86+
}
8987
if (isModemConnected()) {
9088
logger.info("Connection for modem {} successful", this.deviceId);
9189
if (this.connectionHandler != null) {
@@ -114,7 +112,7 @@ private void scheduleConnectInternal(int attemptNumber) {
114112
}
115113

116114
public void scheduleReset() {
117-
if (isResetScheduled.get() || this.resetDelayMinutes <= 0) {
115+
if (isResetScheduled.get() || this.resetDelayMinutes <= 0 || isModemConnected()) {
118116
return;
119117
}
120118
logger.info("Schedule reset for modem {} with path {}", this.deviceId, this.device.getObjectPath());
@@ -126,9 +124,12 @@ public void scheduleReset() {
126124
this.connectionHandler.cancel(true);
127125
}
128126
this.isConnectionScheduled.set(false);
129-
if (this.mmDbusPath.isPresent()) {
130-
Modem modem = this.modemManager.getModem(mmDbusPath.get());
131-
modem.Reset();
127+
Optional<Modem> modem = Optional.empty();
128+
if (this.nmDbusConnector.isPresent()) {
129+
modem = this.nmDbusConnector.get().getModem(device);
130+
}
131+
if (modem.isPresent()) {
132+
modem.get().Reset();
132133
logger.info("Modem reset successful for modem {} with path {}", this.deviceId,
133134
this.device.getObjectPath());
134135
}
@@ -169,11 +170,20 @@ protected boolean isResetScheduled() {
169170
return this.isResetScheduled.get();
170171
}
171172

172-
private boolean isModemConnected() throws DBusException {
173-
if (!this.mmDbusPath.isPresent()) {
174-
return false;
173+
private boolean isModemConnected() {
174+
boolean isConnected = false;
175+
try {
176+
if (this.nmDbusConnector.isPresent()) {
177+
isConnected = this.nmDbusConnector.get().isModemConnected(this.device);
178+
}
179+
} catch (DBusException e) {
180+
logger.warn("Could not get modem connection status for modem {} with path {} because: ", this.deviceId,
181+
this.device.getObjectPath(), e);
175182
}
176-
MMModemState modemState = this.modemManager.getMMModemState(mmDbusPath.get());
177-
return MMModemState.MM_MODEM_STATE_CONNECTED.equals(modemState);
183+
return isConnected;
184+
}
185+
186+
protected void setNMDBusConnector(NMDbusConnector nmDbusConnector) {
187+
this.nmDbusConnector = Optional.of(nmDbusConnector);
178188
}
179189
}

kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/NMDbusConnector.java

Lines changed: 48 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import org.eclipse.kura.net.wifi.WifiSecurity;
3636
import org.eclipse.kura.nm.configuration.NMSettingsConverter;
3737
import org.eclipse.kura.nm.enums.MMModemLocationSource;
38+
import org.eclipse.kura.nm.enums.MMModemState;
3839
import org.eclipse.kura.nm.enums.NMDeviceState;
3940
import org.eclipse.kura.nm.enums.NMDeviceType;
4041
import org.eclipse.kura.nm.signal.handlers.DeviceCreationLock;
@@ -54,6 +55,7 @@
5455
import org.freedesktop.dbus.exceptions.DBusExecutionException;
5556
import org.freedesktop.dbus.interfaces.Properties;
5657
import org.freedesktop.dbus.types.Variant;
58+
import org.freedesktop.modemmanager1.Modem;
5759
import org.freedesktop.modemmanager1.modem.Location;
5860
import org.freedesktop.networkmanager.Device;
5961
import org.freedesktop.networkmanager.Settings;
@@ -139,7 +141,7 @@ protected boolean configurationEnforcementIsActive() {
139141
}
140142

141143
protected boolean modemTaskHandlerIsPresent(String modemId) {
142-
return this.modemManager.isModemTaskHandlerActive(modemId);
144+
return this.modemManager.isModemTaskHandlerPresent(modemId);
143145
}
144146

145147
public void checkPermissions() {
@@ -357,6 +359,7 @@ ip4configProperties, ip6configProperties, new AccessPointsProperties(activeAcces
357359
public synchronized void apply(Map<String, Object> networkConfiguration) throws DBusException {
358360
try {
359361
configurationEnforcementDisable();
362+
// Disable ModemTaskHandler since it is supposed to be a new configuration
360363
this.modemManager.modemTaskHandlerDisable();
361364
doApply(networkConfiguration);
362365
this.cachedConfiguration = networkConfiguration;
@@ -372,7 +375,6 @@ public synchronized void apply() throws DBusException {
372375
}
373376
try {
374377
configurationEnforcementDisable();
375-
this.modemManager.modemTaskHandlerDisable();
376378
doApply(this.cachedConfiguration);
377379
} finally {
378380
configurationEnforcementEnable();
@@ -389,7 +391,6 @@ public synchronized void apply(String deviceId) throws DBusException {
389391
}
390392
try {
391393
configurationEnforcementDisable();
392-
this.modemManager.modemTaskHandlerDisable(deviceId);
393394
doApply(deviceId, this.cachedConfiguration);
394395
} finally {
395396
configurationEnforcementEnable();
@@ -560,31 +561,18 @@ private void enableInterface(String deviceId, NetworkProperties properties, Devi
560561
connection = Optional.of(createdConnection);
561562
}
562563

563-
if (deviceType == NMDeviceType.NM_DEVICE_TYPE_MODEM) {
564-
this.modemManager.modemTaskHandlerDisable(deviceId);
565-
Optional<String> mmDbusPath = this.networkManager.getModemManagerDbusPath(device.getObjectPath());
566-
if (!mmDbusPath.isPresent()) {
567-
return;
568-
}
564+
try {
565+
this.networkManager.activateConnection(connection.get(), device);
566+
dsLock.waitForSignal();
567+
} catch (DBusExecutionException e) {
568+
logger.warn("Couldn't complete activation of {} interface, caused by:", deviceId, e);
569+
}
569570

571+
if (deviceType == NMDeviceType.NM_DEVICE_TYPE_MODEM) {
570572
int resetDelayMinutes = properties.get(Integer.class, "net.interface.%s.config.resetTimeout", deviceId);
571573
boolean autoconnect = properties.get(Boolean.class, "net.interface.%s.config.persist", deviceId);
572-
if (resetDelayMinutes == 0 && !autoconnect) {
573-
this.networkManager.activateConnection(connection.get(), device);
574-
dsLock.waitForSignal();
575-
return;
576-
}
577-
578-
logger.info("Modem {} activated. Starting monitoring task...", deviceId);
579-
this.modemManager.modemTaskHandler(deviceId, this.modemManager, this.networkManager, connection.get(),
580-
device, properties);
581-
582-
} else {
583-
try {
584-
this.networkManager.activateConnection(connection.get(), device);
585-
dsLock.waitForSignal();
586-
} catch (DBusExecutionException e) {
587-
logger.warn("Couldn't complete activation of {} interface, caused by:", deviceId, e);
574+
if (resetDelayMinutes > 0 || autoconnect) {
575+
this.modemManager.modemTaskHandler(deviceId, device, properties);
588576
}
589577
}
590578

@@ -733,13 +721,8 @@ private List<String> getModemsPaths() {
733721
List<String> modemsPath = new ArrayList<>();
734722

735723
try {
736-
737724
for (Device device : this.networkManager.getAllDevices()) {
738-
if (networkManager.getDeviceType(device.getObjectPath()).equals(NMDeviceType.NM_DEVICE_TYPE_MODEM)) {
739-
Optional<String> modemPath = this.networkManager.getModemManagerDbusPath(device.getObjectPath());
740-
741-
modemPath.ifPresent(modemsPath::add);
742-
}
725+
getModemPath(device).ifPresent(modemsPath::add);
743726
}
744727
} catch (DBusException ex) {
745728
logger.debug("Impossible to retrieve information regarding available modems");
@@ -748,4 +731,38 @@ private List<String> getModemsPaths() {
748731
return modemsPath;
749732
}
750733

734+
private Optional<String> getModemPath(Device device) throws DBusException {
735+
Optional<String> mmDbusPath = Optional.empty();
736+
737+
if (networkManager.getDeviceType(device.getObjectPath()).equals(NMDeviceType.NM_DEVICE_TYPE_MODEM)) {
738+
mmDbusPath = this.networkManager.getModemManagerDbusPath(device.getObjectPath());
739+
}
740+
741+
return mmDbusPath;
742+
}
743+
744+
public boolean isModemConnected(Device modemDevice) throws DBusException {
745+
Optional<String> mmDbusPath = Optional.empty();
746+
try {
747+
mmDbusPath = getModemPath(modemDevice);
748+
} catch (DBusException e) {
749+
logger.warn("Could not get ModemManager dbus path for device {} because: ", modemDevice.getObjectPath(), e);
750+
}
751+
752+
if (!mmDbusPath.isPresent()) {
753+
return false;
754+
}
755+
MMModemState modemState = this.modemManager.getMMModemState(mmDbusPath.get());
756+
return MMModemState.MM_MODEM_STATE_CONNECTED.equals(modemState);
757+
}
758+
759+
public Optional<Modem> getModem(Device device) throws DBusException {
760+
Optional<Modem> modem = Optional.empty();
761+
Optional<String> mmDbusPath = getModemPath(device);
762+
if (mmDbusPath.isPresent()) {
763+
modem = Optional.of(this.modemManager.getModem(mmDbusPath.get()));
764+
}
765+
return modem;
766+
}
767+
751768
}

kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/signal/handlers/DeviceStateLock.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2023 Eurotech and/or its affiliates and others
2+
* Copyright (c) 2023, 2025 Eurotech and/or its affiliates and others
33
*
44
* This program and the accompanying materials are made
55
* available under the terms of the Eclipse Public License 2.0
@@ -34,7 +34,7 @@ public class DeviceStateLock {
3434
public DeviceStateLock(DBusConnection dbusConnection, String dbusPath, NMDeviceState expectedNmDeviceState)
3535
throws DBusException {
3636
if (Objects.isNull(dbusPath) || dbusPath.isEmpty() || dbusPath.equals("/")) {
37-
throw new IllegalArgumentException(String.format("Illegal DBus path for DeviceSateLock \"%s\"", dbusPath));
37+
throw new IllegalArgumentException(String.format("Illegal DBus path for DeviceStateLock \"%s\"", dbusPath));
3838
}
3939
this.dbusConnection = Objects.requireNonNull(dbusConnection);
4040
this.stateHandler = new NMDeviceStateChangeHandler(this.latch, dbusPath, expectedNmDeviceState);

kura/org.eclipse.kura.nm/src/main/java/org/eclipse/kura/nm/signal/handlers/NMConfigurationEnforcementHandler.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,7 @@ public void handle(Device.StateChanged s) {
5151
try {
5252
logger.info("Network change detected on interface {}. Roll-back to cached configuration", s.getPath());
5353
String deviceId = this.nm.getInterfaceIdByDBusPath(s.getPath());
54-
// Disable the configuration rollback for now
55-
// this.nm.apply(deviceId);
54+
this.nm.apply(deviceId);
5655
} catch (DBusException e) {
5756
logger.error("Failed to handle network configuration change event for device: {}. Caused by:",
5857
s.getPath(), e);

0 commit comments

Comments
 (0)