Firmware updates

This commit is contained in:
Mike Hansen
2020-07-06 13:36:10 -04:00
parent 95a78546d3
commit 25870f88ac
4 changed files with 272 additions and 67 deletions

View File

@@ -39,6 +39,7 @@ import com.telecominfraproject.wlan.core.model.equipment.MacAddress;
import com.telecominfraproject.wlan.core.model.equipment.NeighborScanPacketType;
import com.telecominfraproject.wlan.core.model.equipment.NetworkType;
import com.telecominfraproject.wlan.core.model.equipment.RadioType;
import com.telecominfraproject.wlan.core.model.json.BaseJsonModel;
import com.telecominfraproject.wlan.customer.models.Customer;
import com.telecominfraproject.wlan.customer.models.EquipmentAutoProvisioningSettings;
import com.telecominfraproject.wlan.customer.service.CustomerServiceInterface;
@@ -49,13 +50,20 @@ import com.telecominfraproject.wlan.equipment.models.ElementRadioConfiguration;
import com.telecominfraproject.wlan.equipment.models.Equipment;
import com.telecominfraproject.wlan.equipment.models.RadioConfiguration;
import com.telecominfraproject.wlan.equipment.models.StateSetting;
import com.telecominfraproject.wlan.equipmentgateway.models.CEGWBaseCommand;
import com.telecominfraproject.wlan.equipmentgateway.models.CEGWFirmwareDownloadRequest;
import com.telecominfraproject.wlan.equipmentgateway.models.CEGWFirmwareFlashRequest;
import com.telecominfraproject.wlan.firmware.FirmwareServiceInterface;
import com.telecominfraproject.wlan.firmware.models.CustomerFirmwareTrackRecord;
import com.telecominfraproject.wlan.firmware.models.CustomerFirmwareTrackSettings;
import com.telecominfraproject.wlan.firmware.models.CustomerFirmwareTrackSettings.TrackFlag;
import com.telecominfraproject.wlan.firmware.models.FirmwareTrackAssignmentDetails;
import com.telecominfraproject.wlan.firmware.models.FirmwareTrackRecord;
import com.telecominfraproject.wlan.firmware.models.FirmwareVersion;
import com.telecominfraproject.wlan.location.models.Location;
import com.telecominfraproject.wlan.location.service.LocationServiceInterface;
import com.telecominfraproject.wlan.opensync.external.integration.controller.OpensyncCloudGatewayController;
import com.telecominfraproject.wlan.opensync.external.integration.controller.OpensyncCloudGatewayController.ListOfEquipmentCommandResponses;
import com.telecominfraproject.wlan.opensync.external.integration.models.ConnectNodeInfo;
import com.telecominfraproject.wlan.opensync.external.integration.models.OpensyncAPConfig;
import com.telecominfraproject.wlan.opensync.external.integration.models.OpensyncAPInetState;
@@ -90,6 +98,7 @@ import com.telecominfraproject.wlan.status.equipment.models.EquipmentAdminStatus
import com.telecominfraproject.wlan.status.equipment.models.EquipmentLANStatusData;
import com.telecominfraproject.wlan.status.equipment.models.EquipmentProtocolState;
import com.telecominfraproject.wlan.status.equipment.models.EquipmentProtocolStatusData;
import com.telecominfraproject.wlan.status.equipment.models.EquipmentResetMethod;
import com.telecominfraproject.wlan.status.equipment.models.EquipmentUpgradeState;
import com.telecominfraproject.wlan.status.equipment.models.EquipmentUpgradeStatusData;
import com.telecominfraproject.wlan.status.equipment.models.VLANStatusData;
@@ -225,32 +234,6 @@ public class OpensyncExternalIntegrationCloud implements OpensyncExternalIntegra
public void apConnected(String apId, ConnectNodeInfo connectNodeInfo) {
if (isAutoconfigEnabled) {
// default track settings for firmware
CustomerFirmwareTrackSettings trackSettings = firmwareServiceInterface.getDefaultCustomerTrackSetting();
// check for updated/modified track settings for this customer
CustomerFirmwareTrackRecord custFwTrackRecord = firmwareServiceInterface
.getCustomerFirmwareTrackRecord(autoProvisionedCustomerId);
if (custFwTrackRecord != null) {
trackSettings = custFwTrackRecord.getSettings();
}
// determine if AP requires FW upgrade before cloud
// connection/provision
if (trackSettings.getAutoUpgradeDeprecatedOnBind().equals(TrackFlag.ALWAYS)
|| trackSettings.getAutoUpgradeUnknownOnBind().equals(TrackFlag.ALWAYS)) {
// check the reported fw version for the AP, if it is < than
// the default version for the cloud, then download and
// flash the firmware before proceeding.
// then return;
LOG.debug(
"Automatic firmware upgrade is configured for track {}. Firmware will be flashed to newer version if required.",
trackSettings);
} else {
// auto upgrade not configured for this customer
LOG.debug("Automatic firmware upgrade is not configured for track {}", trackSettings);
}
Equipment ce = getCustomerEquipment(apId);
@@ -418,6 +401,8 @@ public class OpensyncExternalIntegrationCloud implements OpensyncExternalIntegra
LOG.info("AP {} got connected to the gateway", apId);
LOG.info("ConnectNodeInfo {}", connectNodeInfo);
reconcileFwVersionToTrack(ce, connectNodeInfo);
} catch (Exception e) {
LOG.error("Could not process connection from AP {}", apId, e);
throw e;
@@ -629,6 +614,108 @@ public class OpensyncExternalIntegrationCloud implements OpensyncExternalIntegra
}
private void reconcileFwVersionToTrack(Equipment ce, ConnectNodeInfo connectNodeInfo) {
Status statusRecord = statusServiceInterface.getOrNull(ce.getCustomerId(), ce.getId(), StatusDataType.FIRMWARE);
EquipmentUpgradeStatusData fwUpgradeStatusData = (EquipmentUpgradeStatusData) statusRecord.getDetails();
// default track settings for firmware
CustomerFirmwareTrackSettings trackSettings = firmwareServiceInterface.getDefaultCustomerTrackSetting();
// check for updated/modified track settings for this customer
CustomerFirmwareTrackRecord custFwTrackRecord = firmwareServiceInterface
.getCustomerFirmwareTrackRecord(ce.getCustomerId());
long trackRecordId = 0;
if (custFwTrackRecord != null) {
trackSettings = custFwTrackRecord.getSettings();
trackRecordId = custFwTrackRecord.getTrackRecordId();
}
// determine if AP requires FW upgrade before cloud
// connection/provision
if (trackSettings.getAutoUpgradeDeprecatedOnBind().equals(TrackFlag.ALWAYS)
|| trackSettings.getAutoUpgradeUnknownOnBind().equals(TrackFlag.ALWAYS)) {
// check the reported fw version for the AP, if it is < than
// the default version for the cloud, then download and
// flash the firmware before proceeding.
// then return;
FirmwareTrackRecord fwTrackRecord = firmwareServiceInterface.getFirmwareTrackById(trackRecordId);
if (fwTrackRecord != null) {
List<FirmwareTrackAssignmentDetails> fwTrackAssignmentDetails = firmwareServiceInterface
.getFirmwareTrackAssignments(fwTrackRecord.getTrackName());
String fwVersionName = null;
if (fwTrackAssignmentDetails != null) {
for (FirmwareTrackAssignmentDetails details : fwTrackAssignmentDetails) {
if (connectNodeInfo.model.equalsIgnoreCase(details.getModelId())) {
fwVersionName = details.getVersionName();
break;
}
}
}
if (fwVersionName != null && !fwVersionName.equals(connectNodeInfo.firmwareVersion)) {
fwUpgradeStatusData.setTargetSwVersion(fwVersionName);
fwUpgradeStatusData.setUpgradeState(EquipmentUpgradeState.out_of_date);
statusRecord.setDetails(fwUpgradeStatusData);
} else {
fwUpgradeStatusData.setUpgradeState(EquipmentUpgradeState.up_to_date);
statusRecord.setDetails(fwUpgradeStatusData);
}
statusRecord = statusServiceInterface.update(statusRecord);
}
if (((EquipmentUpgradeStatusData) statusRecord.getDetails()).getUpgradeState()
.equals(EquipmentUpgradeState.out_of_date)) {
LOG.debug(
"Automatic firmware upgrade is configured for track {}. Firmware will be flashed to newer version if required.",
trackSettings);
FirmwareVersion fwVersion = firmwareServiceInterface
.getFirmwareVersionByName(fwUpgradeStatusData.getTargetSwVersion());
if (fwVersion != null) {
OvsdbSession ovsdbSession = ovsdbSessionMapInterface.getSession(ce.getInventoryId());
if (ovsdbSession == null) {
throw new IllegalStateException("AP is not connected " + ce.getInventoryId());
}
CEGWFirmwareDownloadRequest fwDownloadRequest = new CEGWFirmwareDownloadRequest(ce.getInventoryId(),
ce.getId(), fwVersion.getVersionName(), fwVersion.getFilename(),
fwVersion.getValidationMethod(), fwVersion.getValidationCode());
List<CEGWBaseCommand> commands = new ArrayList<>();
commands.add(fwDownloadRequest);
gatewayController.updateActiveCustomer(ce.getCustomerId());
ListOfEquipmentCommandResponses responses = gatewayController.sendCommands(commands);
LOG.debug("FW Download Response {}", responses);
CEGWFirmwareFlashRequest fwFlashRequest = new CEGWFirmwareFlashRequest(ce.getInventoryId(),
ce.getId(), fwVersion.getVersionName());
commands = new ArrayList<>();
commands.add(fwFlashRequest);
responses = gatewayController.sendCommands(commands);
LOG.debug("FW Upgrade Response {}", responses);
LOG.info("FW upgrade request response {}", responses);
}
}
} else {
LOG.debug("Automatic firmware upgrade is not configured for track {}", trackSettings);
}
}
@Override
public void apDisconnected(String apId) {
LOG.info("AP {} got disconnected from the gateway", apId);
@@ -2044,6 +2131,7 @@ public class OpensyncExternalIntegrationCloud implements OpensyncExternalIntegra
@Override
public void awlanNodeDbTableUpdate(OpensyncAWLANNode opensyncAPState, String apId) {
LOG.debug("AP {} table AWLAN_Node updated {}", apId, opensyncAPState);
OvsdbSession ovsdbSession = ovsdbSessionMapInterface.getSession(apId);
if (ovsdbSession == null) {
@@ -2079,9 +2167,42 @@ public class OpensyncExternalIntegrationCloud implements OpensyncExternalIntegra
protocolStatusData.setReportedHwVersion(opensyncAPState.getPlatformVersion());
protocolStatusData.setSystemName(opensyncAPState.getModel());
protocolStatus.setDetails(protocolStatusData);
List<Status> updates = new ArrayList<>();
// only post update if there is a change
if (!((EquipmentProtocolStatusData) statusServiceInterface
.getOrNull(customerId, equipmentId, StatusDataType.PROTOCOL).getDetails()).equals(protocolStatusData)) {
protocolStatus.setDetails(protocolStatusData);
updates.add(protocolStatus);
}
Status firmwareStatus = statusServiceInterface.getOrNull(customerId, equipmentId, StatusDataType.FIRMWARE);
if (firmwareStatus == null) {
firmwareStatus = new Status();
firmwareStatus.setCustomerId(customerId);
firmwareStatus.setEquipmentId(equipmentId);
firmwareStatus.setStatusDataType(StatusDataType.FIRMWARE);
firmwareStatus.setDetails(new EquipmentUpgradeStatusData());
firmwareStatus = statusServiceInterface.update(firmwareStatus);
}
EquipmentUpgradeStatusData firmwareStatusData = (EquipmentUpgradeStatusData) firmwareStatus.getDetails();
firmwareStatusData.setActiveSwVersion(opensyncAPState.getFirmwareVersion());
firmwareStatusData.setTargetSwVersion(opensyncAPState.getVersionMatrix().get("FIRMWARE"));
firmwareStatusData.setUpgradeState(EquipmentUpgradeState.getById(opensyncAPState.getUpgradeStatus()));
// only post update if there is a change
if (!((EquipmentUpgradeStatusData) statusServiceInterface
.getOrNull(customerId, equipmentId, StatusDataType.FIRMWARE).getDetails()).equals(firmwareStatusData)) {
firmwareStatus.setDetails(firmwareStatusData);
updates.add(firmwareStatus);
}
if (!updates.isEmpty()) {
statusServiceInterface.update(updates);
}
protocolStatus = statusServiceInterface.update(protocolStatus);
}

View File

@@ -280,10 +280,12 @@ public class OpensyncCloudGatewayController {
} else if (command instanceof CEGWFirmwareDownloadRequest) {
String filepath = ((CEGWFirmwareDownloadRequest) command).getFilePath();
String firmwareVersion = ((CEGWFirmwareDownloadRequest) command).getFirmwareVersion();
String username = ((CEGWFirmwareDownloadRequest) command).getUsername();
String validationCode = ((CEGWFirmwareDownloadRequest) command).getUsername();
CEGWFirmwareDownloadRequest dlRequest = (CEGWFirmwareDownloadRequest)command;
String filepath = dlRequest.getFilePath();
String firmwareVersion = dlRequest.getFirmwareVersion();
String username = dlRequest.getUsername();
String validationCode = dlRequest.getValidationCode();
connectusOvsdbClient.processFirmwareDownload(inventoryId, filepath, firmwareVersion, username,
validationCode);

View File

@@ -164,20 +164,6 @@ public class ConnectusOvsdbClient implements ConnectusOvsdbClientInterface {
LOG.info("Manager waiting for connection on port {}...", ovsdbListenPort);
}
private void cancelMonitors(OvsdbClient ovsdbClient, String key) {
try {
ovsdbClient.cancelMonitor(OvsdbDao.wifiRadioStateDbTable + "_" + key).join();
ovsdbClient.cancelMonitor(OvsdbDao.wifiVifStateDbTable + "_delete_" + key).join();
ovsdbClient.cancelMonitor(OvsdbDao.wifiVifStateDbTable + "_" + key).join();
ovsdbClient.cancelMonitor(OvsdbDao.wifiInetStateDbTable + "_" + key).join();
ovsdbClient.cancelMonitor(OvsdbDao.wifiAssociatedClientsDbTable + "_" + key).join();
ovsdbClient.cancelMonitor(OvsdbDao.wifiAssociatedClientsDbTable + "_delete_" + key).join();
ovsdbClient.cancelMonitor(OvsdbDao.awlanNodeDbTable + "_" + key).join();
} catch (OvsdbClientException e) {
LOG.debug("Unable to cancel monitor for state table. {}", e.getMessage());
}
}
private ConnectNodeInfo processConnectRequest(OvsdbClient ovsdbClient, String clientCn,
ConnectNodeInfo connectNodeInfo) {
@@ -313,7 +299,10 @@ public class ConnectusOvsdbClient implements ConnectusOvsdbClientInterface {
}
});
awCf.join();
extIntegrationInterface.awlanNodeDbTableUpdate(ovsdbDao.getOpensyncAWLANNode(awCf.join(), key, ovsdbClient),
key);
}
private void monitorWifiAssociatedClientsDbTable(OvsdbClient ovsdbClient, String key) throws OvsdbClientException {
@@ -336,7 +325,10 @@ public class ConnectusOvsdbClient implements ConnectusOvsdbClientInterface {
}
});
acCf.join();
extIntegrationInterface.wifiAssociatedClientsDbTableUpdate(
ovsdbDao.getOpensyncWifiAssociatedClients(acCf.join(), key, ovsdbClient), key);
}
private void monitorWifiInetStateDbTable(OvsdbClient ovsdbClient, String key) throws OvsdbClientException {
@@ -356,7 +348,9 @@ public class ConnectusOvsdbClient implements ConnectusOvsdbClientInterface {
}
});
isCf.join();
extIntegrationInterface
.wifiInetStateDbTableUpdate(ovsdbDao.getOpensyncAPInetState(isCf.join(), key, ovsdbClient), key);
}
private void monitorWifiRadioStateDbTable(OvsdbClient ovsdbClient, String key) throws OvsdbClientException {
@@ -375,7 +369,8 @@ public class ConnectusOvsdbClient implements ConnectusOvsdbClientInterface {
}
});
rsCf.join();
extIntegrationInterface
.wifiRadioStatusDbTableUpdate(ovsdbDao.getOpensyncAPRadioState(rsCf.join(), key, ovsdbClient), key);
}
private void monitorWifiVifStateDbTableDeletion(OvsdbClient ovsdbClient, String key) throws OvsdbClientException {
@@ -476,7 +471,7 @@ public class ConnectusOvsdbClient implements ConnectusOvsdbClientInterface {
CompletableFuture<TableUpdates> vsCf = ovsdbClient
.monitor(OvsdbDao.ovsdbName, OvsdbDao.wifiVifStateDbTable + "_" + key,
new MonitorRequests(ImmutableMap.of(OvsdbDao.wifiVifStateDbTable,
new MonitorRequest(new MonitorSelect(true, true, false, true)))),
new MonitorRequest(new MonitorSelect(true, true, true, true)))),
new MonitorCallback() {
@Override
public void update(TableUpdates tableUpdates) {
@@ -489,7 +484,9 @@ public class ConnectusOvsdbClient implements ConnectusOvsdbClientInterface {
});
vsCf.join();
extIntegrationInterface.wifiVIFStateDbTableUpdate(ovsdbDao.getOpensyncAPVIFState(vsCf.join(), key, ovsdbClient),
key);
}
@Override

View File

@@ -1,10 +1,14 @@
package com.telecominfraproject.wlan.opensync.ovsdb.dao;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
@@ -115,6 +119,10 @@ public class OvsdbDao {
public String ifName5GHzL;
@org.springframework.beans.factory.annotation.Value("${connectus.ovsdb.wifi-iface.default_radio0:home-ap-u50}")
public String ifName5GHzU;
@org.springframework.beans.factory.annotation.Value("${connectus.ovsdb.awlan-node.upgrade_dl_timer:300}")
public long upgradeDlTimer;
@org.springframework.beans.factory.annotation.Value("${connectus.ovsdb.awlan-node.upgrade_timer:300}")
public long upgradeTimer;
public static final String ovsdbName = "Open_vSwitch";
public static final String awlanNodeDbTable = "AWLAN_Node";
@@ -2840,18 +2848,103 @@ public class OvsdbDao {
return newRedirectorAddress;
}
private Row getAWLANNodeDbTableForFirmwareUpdate(OvsdbClient ovsdbClient) {
Row row = null;
try {
List<Operation> operations = new ArrayList<>();
List<Condition> conditions = new ArrayList<>();
List<String> columns = new ArrayList<>();
columns.add("firmware_version");
columns.add("firmware_pass");
columns.add("firmware_url");
columns.add("version_matrix");
columns.add("upgrade_timer");
columns.add("upgrade_status");
columns.add("upgrade_dl_timer");
operations.add(new Select(awlanNodeDbTable, conditions, columns));
CompletableFuture<OperationResult[]> fResult = ovsdbClient.transact(ovsdbName, operations);
OperationResult[] result = fResult.get(ovsdbTimeoutSec, TimeUnit.SECONDS);
if (LOG.isDebugEnabled()) {
LOG.debug("Select from {}:", awlanNodeDbTable);
for (OperationResult res : result) {
LOG.debug("Op Result {}", res);
}
}
if ((result != null) && (result.length > 0) && !((SelectResult) result[0]).getRows().isEmpty()) {
row = ((SelectResult) result[0]).getRows().iterator().next();
}
} catch (OvsdbClientException | TimeoutException | ExecutionException | InterruptedException e) {
throw new RuntimeException(e);
}
LOG.debug("AWLAN_Node {}", row);
return row;
}
public void configureFirmwareDownload(OvsdbClient ovsdbClient, String apId, String firmwareUrl,
String firmwareVersion, String username, String validationCode) throws Exception {
LOG.debug("configureFirmwareDownload for {} to version {} url {}", apId, firmwareVersion, firmwareUrl);
try {
LOG.debug("configureFirmwareDownload for {} to version {} url {} validationCode {} username {}", apId,
firmwareVersion, firmwareUrl, validationCode, username);
// get existing table info
Row awlanNode = getAWLANNodeDbTableForFirmwareUpdate(ovsdbClient);
if (awlanNode == null) {
LOG.error("Cannot update AWLAN_Node firmware information");
return;
}
URL aURL = new URL(firmwareUrl);
Map<String, String> versionMap = awlanNode.getMapColumn("version_matrix");
versionMap.put("vendor/ipq40xx", aURL.getPath().substring(0, aURL.getPath().lastIndexOf('/')));
versionMap.put("FIRMWARE", firmwareVersion);
versionMap.put("FW_VERSION", firmwareVersion.substring(0, firmwareVersion.indexOf('-')));
versionMap.put("FW_BUILD",
firmwareVersion.substring(firmwareVersion.indexOf('-') + 1, firmwareVersion.lastIndexOf('-')));
versionMap.put("FW_COMMIT", firmwareVersion.substring(firmwareVersion.lastIndexOf('-') + 1));
versionMap.put("HOST", aURL.getHost());
versionMap.put("FW_PROFILE", firmwareVersion.substring(0, firmwareVersion.indexOf('-')));
SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd HH:mm:ss z yyyy");
versionMap.put("DATE", sdf.format(new Date()));
List<Operation> operations = new ArrayList<>();
Map<String, Value> updateColumns = new HashMap<>();
updateColumns.put("upgrade_dl_timer", new Atom<Long>(upgradeDlTimer));
updateColumns.put("firmware_pass", new Atom<String>(validationCode));
updateColumns.put("firmware_url", new Atom<String>(firmwareUrl));
updateColumns.put("version_matrix", com.vmware.ovsdb.protocol.operation.notation.Map.of(versionMap));
Row row = new Row(updateColumns);
operations.add(new Update(awlanNodeDbTable, row));
CompletableFuture<OperationResult[]> fResult = ovsdbClient.transact(ovsdbName, operations);
OperationResult[] result = fResult.get(ovsdbTimeoutSec, TimeUnit.SECONDS);
for (OperationResult r : result) {
LOG.debug("Op Result {}", r);
}
} catch (Exception e) {
LOG.error("Could not download firmware to AP", e);
}
}
public void flashFirmware(OvsdbClient ovsdbClient, String apId, String firmwareVersion) throws Exception {
LOG.debug("flashFirmware for {} to version {}", apId, firmwareVersion);
List<Operation> operations = new ArrayList<>();
Map<String, Value> updateColumns = new HashMap<>();
updateColumns.put("firmware_pass", new Atom<>(validationCode));
updateColumns.put("firmware_version", new Atom<>(firmwareVersion));
// Until AP enables Upgrade Manager this does nothing
updateColumns.put("firmware_url", new Atom<>(firmwareUrl));
updateColumns.put("upgrade_timer", new Atom<Long>(upgradeTimer));
Row row = new Row(updateColumns);
operations.add(new Update(awlanNodeDbTable, row));
@@ -2865,14 +2958,6 @@ public class OvsdbDao {
}
public void flashFirmware(OvsdbClient ovsdbClient, String apId, String firmwareVersion) throws Exception {
LOG.debug("flashFirmware for {} to version {}", apId, firmwareVersion);
// TODO: This needs to be implemented when the AP has Firmware Upgrade
}
public void removeAllStatsConfigs(OvsdbClient ovsdbClient) {
LOG.info("Remove existing Wifi_Stats_Config table entries");