Lwm2m: Fw/Sw updare with test successful/error (#4566)
* Lwm2m: start Sw * Lwm2m: FwUpdate - new * Lwm2m: SwUpdate - error * Lwm2m: SwUpdate - successful/error -test ok * Lwm2m: SwUpdate - change * Lwm2m: add executor to observe * Lwm2m: add operation observe_cancel_All * Lwm2m: fix bug add software to profile * Lwm2m: add for logs object to string * Lwm2m: fix bug swUpdate * Lwm2m: add new commands only for rpc
This commit is contained in:
parent
c768fcbac1
commit
8d3e30e8a3
@ -47,6 +47,7 @@ import java.util.UUID;
|
||||
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.BOOTSTRAP_SERVER;
|
||||
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LOG_LW2M_ERROR;
|
||||
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LOG_LW2M_INFO;
|
||||
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LOG_LW2M_TELEMETRY;
|
||||
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LWM2M_SERVER;
|
||||
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.SERVERS;
|
||||
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.getBootstrapParametersFromThingsboard;
|
||||
@ -167,13 +168,13 @@ public class LwM2MBootstrapSecurityStore implements BootstrapSecurityStore {
|
||||
lwM2MBootstrapConfig.bootstrapServer = new LwM2MServerBootstrap(lwM2MBootstrapConfig.bootstrapServer, profileServerBootstrap);
|
||||
lwM2MBootstrapConfig.lwm2mServer = new LwM2MServerBootstrap(lwM2MBootstrapConfig.lwm2mServer, profileLwm2mServer);
|
||||
String logMsg = String.format("%s: getParametersBootstrap: %s Access connect client with bootstrap server.", LOG_LW2M_INFO, store.getEndPoint());
|
||||
helper.sendParametersOnThingsboardTelemetry(helper.getKvLogyToThingsboard(logMsg), sessionInfo);
|
||||
helper.sendParametersOnThingsboardTelemetry(helper.getKvStringtoThingsboard(LOG_LW2M_TELEMETRY, logMsg), sessionInfo);
|
||||
return lwM2MBootstrapConfig;
|
||||
} else {
|
||||
log.error(" [{}] Different values SecurityMode between of client and profile.", store.getEndPoint());
|
||||
log.error("{} getParametersBootstrap: [{}] Different values SecurityMode between of client and profile.", LOG_LW2M_ERROR, store.getEndPoint());
|
||||
String logMsg = String.format("%s: getParametersBootstrap: %s Different values SecurityMode between of client and profile.", LOG_LW2M_ERROR, store.getEndPoint());
|
||||
helper.sendParametersOnThingsboardTelemetry(helper.getKvLogyToThingsboard(logMsg), sessionInfo);
|
||||
helper.sendParametersOnThingsboardTelemetry(helper.getKvStringtoThingsboard(LOG_LW2M_TELEMETRY, logMsg), sessionInfo);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -156,9 +156,7 @@ public class LwM2MTransportServerConfig implements LwM2MSecureServerConfig {
|
||||
keyStoreValue = KeyStore.getInstance(keyStoreType);
|
||||
keyStoreValue.load(inKeyStore, keyStorePassword == null ? null : keyStorePassword.toCharArray());
|
||||
} catch (Exception e) {
|
||||
log.warn("Unable to lookup LwM2M keystore. Reason: {}, {}" , uri, e.getMessage());
|
||||
// Absence of the key store should not block user from using plain LwM2M
|
||||
// throw new RuntimeException("Failed to lookup LwM2M keystore: " + (uri != null ? uri.toString() : ""), e);
|
||||
log.trace("Unable to lookup LwM2M keystore. Reason: {}, {}" , uri, e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -23,13 +23,12 @@ import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.eclipse.leshan.core.model.ObjectModel;
|
||||
import org.eclipse.leshan.core.model.ResourceModel;
|
||||
import org.eclipse.leshan.core.node.LwM2mMultipleResource;
|
||||
import org.eclipse.leshan.core.node.LwM2mObject;
|
||||
import org.eclipse.leshan.core.node.LwM2mObjectInstance;
|
||||
import org.eclipse.leshan.core.node.LwM2mPath;
|
||||
import org.eclipse.leshan.core.node.LwM2mResource;
|
||||
import org.eclipse.leshan.core.node.LwM2mSingleResource;
|
||||
import org.eclipse.leshan.core.observation.Observation;
|
||||
import org.eclipse.leshan.core.request.ContentFormat;
|
||||
import org.eclipse.leshan.core.request.WriteRequest;
|
||||
@ -44,7 +43,6 @@ import org.thingsboard.server.common.data.Device;
|
||||
import org.thingsboard.server.common.data.DeviceProfile;
|
||||
import org.thingsboard.server.common.data.firmware.FirmwareKey;
|
||||
import org.thingsboard.server.common.data.firmware.FirmwareType;
|
||||
import org.thingsboard.server.common.data.firmware.FirmwareUpdateStatus;
|
||||
import org.thingsboard.server.common.data.firmware.FirmwareUtil;
|
||||
import org.thingsboard.server.common.data.id.FirmwareId;
|
||||
import org.thingsboard.server.common.transport.TransportService;
|
||||
@ -57,6 +55,7 @@ import org.thingsboard.server.gen.transport.TransportProtos.SessionEvent;
|
||||
import org.thingsboard.server.gen.transport.TransportProtos.SessionInfoProto;
|
||||
import org.thingsboard.server.queue.util.TbLwM2mTransportComponent;
|
||||
import org.thingsboard.server.transport.lwm2m.config.LwM2MTransportServerConfig;
|
||||
import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper;
|
||||
import org.thingsboard.server.transport.lwm2m.server.adaptors.LwM2MJsonAdaptor;
|
||||
import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient;
|
||||
import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientContext;
|
||||
@ -85,19 +84,19 @@ import java.util.stream.Collectors;
|
||||
|
||||
import static org.eclipse.californium.core.coap.CoAP.ResponseCode.BAD_REQUEST;
|
||||
import static org.eclipse.leshan.core.attributes.Attribute.OBJECT_VERSION;
|
||||
import static org.thingsboard.server.common.data.firmware.FirmwareUpdateStatus.DOWNLOADED;
|
||||
import static org.thingsboard.server.common.data.firmware.FirmwareUpdateStatus.UPDATING;
|
||||
import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPARATOR_PATH;
|
||||
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportServerHelper.getValueFromKvProto;
|
||||
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.CLIENT_NOT_AUTHORIZED;
|
||||
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.DEVICE_ATTRIBUTES_REQUEST;
|
||||
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.EqualsFwSateToFirmwareUpdateStatus;
|
||||
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.FW_ID;
|
||||
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.FW_RESULT_ID;
|
||||
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.FW_STATE_ID;
|
||||
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LOG_LW2M_ERROR;
|
||||
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LOG_LW2M_INFO;
|
||||
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LOG_LW2M_TELEMETRY;
|
||||
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LOG_LW2M_VALUE;
|
||||
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LWM2M_STRATEGY_2;
|
||||
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper;
|
||||
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.DISCOVER;
|
||||
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.DISCOVER_All;
|
||||
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.EXECUTE;
|
||||
@ -109,6 +108,7 @@ import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.L
|
||||
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.WRITE_REPLACE;
|
||||
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.WRITE_UPDATE;
|
||||
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.SW_ID;
|
||||
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.SW_RESULT_ID;
|
||||
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.convertJsonArrayToSet;
|
||||
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.convertPathFromIdVerToObjectId;
|
||||
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.convertPathFromObjectIdToIdVer;
|
||||
@ -123,7 +123,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
|
||||
|
||||
private ExecutorService registrationExecutor;
|
||||
private ExecutorService updateRegistrationExecutor;
|
||||
private ExecutorService unregistrationExecutor;
|
||||
private ExecutorService unRegistrationExecutor;
|
||||
private LwM2mValueConverterImpl converter;
|
||||
|
||||
private final TransportService transportService;
|
||||
@ -155,7 +155,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
|
||||
this.context.getScheduler().scheduleAtFixedRate(this::reportActivity, new Random().nextInt((int) config.getSessionReportTimeout()), config.getSessionReportTimeout(), TimeUnit.MILLISECONDS);
|
||||
this.registrationExecutor = ThingsBoardExecutors.newWorkStealingPool(this.config.getRegisteredPoolSize(), "LwM2M registration");
|
||||
this.updateRegistrationExecutor = ThingsBoardExecutors.newWorkStealingPool(this.config.getUpdateRegisteredPoolSize(), "LwM2M update registration");
|
||||
this.unregistrationExecutor = ThingsBoardExecutors.newWorkStealingPool(this.config.getUnRegisteredPoolSize(), "LwM2M unregistration");
|
||||
this.unRegistrationExecutor = ThingsBoardExecutors.newWorkStealingPool(this.config.getUnRegisteredPoolSize(), "LwM2M unRegistration");
|
||||
this.converter = LwM2mValueConverterImpl.getInstance();
|
||||
}
|
||||
|
||||
@ -219,11 +219,14 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
|
||||
request.send();
|
||||
}
|
||||
}
|
||||
this.sendLogsToThingsboard(LOG_LW2M_INFO + ": Client update Registration", registration.getId());
|
||||
} else {
|
||||
log.error("Client: [{}] updatedReg [{}] name [{}] sessionInfo ", registration.getId(), registration.getEndpoint(), null);
|
||||
this.sendLogsToThingsboard(LOG_LW2M_ERROR + ": Client update Registration", registration.getId());
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
log.error("[{}] endpoint [{}] error Unable update registration.", registration.getEndpoint(), t);
|
||||
this.sendLogsToThingsboard(LOG_LW2M_ERROR + String.format(": Client update Registration, %s", t.getMessage()), registration.getId());
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -234,13 +237,14 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
|
||||
* !!! Warn: if have not finishing unReg, then this operation will be finished on next Client`s connect
|
||||
*/
|
||||
public void unReg(Registration registration, Collection<Observation> observations) {
|
||||
unregistrationExecutor.submit(() -> {
|
||||
unRegistrationExecutor.submit(() -> {
|
||||
try {
|
||||
this.setCancelObservations(registration);
|
||||
this.setCancelObservationsAll(registration);
|
||||
this.sendLogsToThingsboard(LOG_LW2M_INFO + ": Client unRegistration", registration.getId());
|
||||
this.closeClientSession(registration);
|
||||
this.closeClientSession(registration); ;
|
||||
} catch (Throwable t) {
|
||||
log.error("[{}] endpoint [{}] error Unable un registration.", registration.getEndpoint(), t);
|
||||
this.sendLogsToThingsboard(LOG_LW2M_ERROR + String.format(": Client Unable un Registration, %s", t.getMessage()), registration.getId());
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -265,13 +269,18 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
|
||||
//TODO: associate endpointId with device information.
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancel observation for All objects for this registration
|
||||
*/
|
||||
@Override
|
||||
public void setCancelObservations(Registration registration) {
|
||||
public void setCancelObservationsAll(Registration registration) {
|
||||
if (registration != null) {
|
||||
Set<Observation> observations = context.getServer().getObservationService().getObservations(registration);
|
||||
observations.forEach(observation -> lwM2mTransportRequest.sendAllRequest(registration,
|
||||
convertPathFromObjectIdToIdVer(observation.getPath().toString(), registration), OBSERVE_CANCEL,
|
||||
null, null, this.config.getTimeout(), null));
|
||||
lwM2mTransportRequest.sendAllRequest(registration, null, OBSERVE_CANCEL,
|
||||
null, null, this.config.getTimeout(), null);
|
||||
// Set<Observation> observations = context.getServer().getObservationService().getObservations(registration);
|
||||
// observations.forEach(observation -> lwM2mTransportRequest.sendAllRequest(registration,
|
||||
// convertPathFromObjectIdToIdVer(observation.getPath().toString(), registration), OBSERVE_CANCEL,
|
||||
// null, null, this.config.getTimeout(), null));
|
||||
}
|
||||
}
|
||||
|
||||
@ -285,34 +294,43 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
|
||||
@Override
|
||||
public void onUpdateValueAfterReadResponse(Registration registration, String path, ReadResponse response, Lwm2mClientRpcRequest rpcRequest) {
|
||||
if (response.getContent() != null) {
|
||||
Object value = null;
|
||||
if (response.getContent() instanceof LwM2mObject) {
|
||||
LwM2mObject lwM2mObject = (LwM2mObject) response.getContent();
|
||||
if (rpcRequest != null) {
|
||||
value = lwM2mObject.toString();
|
||||
LwM2mClient lwM2MClient = clientContext.getOrRegister(registration);
|
||||
ObjectModel objectModelVersion = lwM2MClient.getObjectModel(path, this.config.getModelProvider());
|
||||
if (objectModelVersion != null) {
|
||||
if (response.getContent() instanceof LwM2mObject) {
|
||||
LwM2mObject lwM2mObject = (LwM2mObject) response.getContent();
|
||||
this.updateObjectResourceValue(registration, lwM2mObject, path);
|
||||
} else if (response.getContent() instanceof LwM2mObjectInstance) {
|
||||
LwM2mObjectInstance lwM2mObjectInstance = (LwM2mObjectInstance) response.getContent();
|
||||
this.updateObjectInstanceResourceValue(registration, lwM2mObjectInstance, path);
|
||||
} else if (response.getContent() instanceof LwM2mResource) {
|
||||
LwM2mResource lwM2mResource = (LwM2mResource) response.getContent();
|
||||
this.updateResourcesValue(registration, lwM2mResource, path);
|
||||
}
|
||||
this.updateObjectResourceValue(registration, lwM2mObject, path);
|
||||
} else if (response.getContent() instanceof LwM2mObjectInstance) {
|
||||
LwM2mObjectInstance lwM2mObjectInstance = (LwM2mObjectInstance) response.getContent();
|
||||
if (rpcRequest != null) {
|
||||
value = lwM2mObjectInstance.toString();
|
||||
}
|
||||
this.updateObjectInstanceResourceValue(registration, lwM2mObjectInstance, path);
|
||||
} else if (response.getContent() instanceof LwM2mResource) {
|
||||
LwM2mResource lwM2mResource = (LwM2mResource) response.getContent();
|
||||
if (rpcRequest != null) {
|
||||
value = lwM2mResource.isMultiInstances() ? ((LwM2mMultipleResource) lwM2mResource).toString() :
|
||||
((LwM2mSingleResource) lwM2mResource).toString();
|
||||
}
|
||||
this.updateResourcesValue(registration, lwM2mResource, path);
|
||||
}
|
||||
if (rpcRequest != null) {
|
||||
rpcRequest.setValueMsg(String.format("%s", value));
|
||||
this.sentRpcRequest(rpcRequest, response.getCode().getName(), (String) value, LOG_LW2M_VALUE);
|
||||
this.sendRpcRequestAfterReadResponse(registration, lwM2MClient, path, response, rpcRequest);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void sendRpcRequestAfterReadResponse(Registration registration, LwM2mClient lwM2MClient, String pathIdVer, ReadResponse response,
|
||||
Lwm2mClientRpcRequest rpcRequest) {
|
||||
Object value = null;
|
||||
if (response.getContent() instanceof LwM2mObject) {
|
||||
value = lwM2MClient.objectToString((LwM2mObject) response.getContent(), this.converter, pathIdVer);
|
||||
} else if (response.getContent() instanceof LwM2mObjectInstance) {
|
||||
value = lwM2MClient.instanceToString((LwM2mObjectInstance) response.getContent(), this.converter, pathIdVer);
|
||||
} else if (response.getContent() instanceof LwM2mResource) {
|
||||
value = lwM2MClient.resourceToString ((LwM2mResource) response.getContent(), this.converter, pathIdVer);
|
||||
}
|
||||
String msg = String.format("%s: type operation %s path - %s value - %s", LOG_LW2M_INFO,
|
||||
READ, pathIdVer, value);
|
||||
this.sendLogsToThingsboard(msg, registration.getId());
|
||||
rpcRequest.setValueMsg(String.format("%s", value));
|
||||
this.sentRpcRequest(rpcRequest, response.getCode().getName(), (String) value, LOG_LW2M_VALUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update - send request in change value resources in Client
|
||||
* 1. FirmwareUpdate:
|
||||
@ -411,12 +429,12 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onToDeviceRpcRequest(TransportProtos.ToDeviceRpcRequestMsg toDeviceRequest, SessionInfoProto sessionInfo) {
|
||||
public void onToDeviceRpcRequest(TransportProtos.ToDeviceRpcRequestMsg toDeviceRpcRequestMsg, SessionInfoProto sessionInfo) {
|
||||
log.warn("4) RPC-OK finish to [{}]", toDeviceRpcRequestMsg);
|
||||
Lwm2mClientRpcRequest lwm2mClientRpcRequest = null;
|
||||
try {
|
||||
log.info("[{}] toDeviceRpcRequest", toDeviceRequest);
|
||||
Registration registration = clientContext.getClient(new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB())).getRegistration();
|
||||
lwm2mClientRpcRequest = this.getDeviceRpcRequest(toDeviceRequest, sessionInfo, registration);
|
||||
lwm2mClientRpcRequest = this.getDeviceRpcRequest(toDeviceRpcRequestMsg, sessionInfo, registration);
|
||||
if (lwm2mClientRpcRequest.getErrorMsg() != null) {
|
||||
lwm2mClientRpcRequest.setResponseCode(BAD_REQUEST.name());
|
||||
this.onToDeviceRpcResponse(lwm2mClientRpcRequest.getDeviceRpcResponseResultMsg(), sessionInfo);
|
||||
@ -486,7 +504,8 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
|
||||
}
|
||||
lwm2mClientRpcRequest.setSessionInfo(sessionInfo);
|
||||
if (!(OBSERVE_READ_ALL == lwm2mClientRpcRequest.getTypeOper()
|
||||
|| DISCOVER_All == lwm2mClientRpcRequest.getTypeOper())
|
||||
|| DISCOVER_All == lwm2mClientRpcRequest.getTypeOper()
|
||||
|| OBSERVE_CANCEL == lwm2mClientRpcRequest.getTypeOper())
|
||||
&& lwm2mClientRpcRequest.getTargetIdVer() == null) {
|
||||
lwm2mClientRpcRequest.setErrorMsg(lwm2mClientRpcRequest.targetIdVerKey + " and " +
|
||||
lwm2mClientRpcRequest.keyNameKey + " is null or bad format");
|
||||
@ -599,7 +618,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
|
||||
*/
|
||||
@Override
|
||||
public void onAwakeDev(Registration registration) {
|
||||
log.info("[{}] [{}] Received endpoint Awake version event", registration.getId(), registration.getEndpoint());
|
||||
log.trace("[{}] [{}] Received endpoint Awake version event", registration.getId(), registration.getEndpoint());
|
||||
this.sendLogsToThingsboard(LOG_LW2M_INFO + ": Client is awake!", registration.getId());
|
||||
//TODO: associate endpointId with device information.
|
||||
}
|
||||
@ -615,7 +634,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
|
||||
if (logMsg.length() > 1024) {
|
||||
logMsg = logMsg.substring(0, 1024);
|
||||
}
|
||||
this.helper.sendParametersOnThingsboardTelemetry(this.helper.getKvLogyToThingsboard(logMsg), sessionInfo);
|
||||
this.helper.sendParametersOnThingsboardTelemetry(this.helper.getKvStringtoThingsboard(LOG_LW2M_TELEMETRY, logMsg), sessionInfo);
|
||||
}
|
||||
}
|
||||
|
||||
@ -699,22 +718,54 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
|
||||
if (lwM2MClient.getSwUpdate().isInfoFwSwUpdate()) {
|
||||
lwM2MClient.getSwUpdate().initReadValue(this, path);
|
||||
}
|
||||
if (lwM2MClient.getFwUpdate().getStateUpdate() != null
|
||||
&& !FirmwareUpdateStatus.DOWNLOADING.name().equals(lwM2MClient.getFwUpdate().getStateUpdate())
|
||||
&& (convertPathFromObjectIdToIdVer(FW_STATE_ID, registration).equals(path)
|
||||
|| convertPathFromObjectIdToIdVer(FW_RESULT_ID, registration).equals(path))) {
|
||||
Long stateFw = (Long) lwM2MClient.getResourceValue(null, FW_STATE_ID);
|
||||
Long updateResultFw = (Long) lwM2MClient.getResourceValue(null, FW_RESULT_ID);
|
||||
FirmwareUpdateStatus state = EqualsFwSateToFirmwareUpdateStatus(LwM2mTransportUtil.StateFw.fromStateFwByCode(stateFw.intValue()),
|
||||
LwM2mTransportUtil.UpdateResultFw.fromUpdateResultFwByCode(updateResultFw.intValue()));
|
||||
if (state != FirmwareUpdateStatus.DOWNLOADING && state != FirmwareUpdateStatus.DOWNLOADED) {
|
||||
lwM2MClient.getFwUpdate().setStateUpdate(state.name());
|
||||
lwM2MClient.getFwUpdate().sendLogs(OBSERVE.name());
|
||||
}
|
||||
log.warn ("update Resource [{}]", lwM2mResource);
|
||||
}
|
||||
if (FirmwareUpdateStatus.DOWNLOADED.name().equals(lwM2MClient.getSwUpdate().getStateUpdate())) {
|
||||
|
||||
/**
|
||||
* Before operation Execute (FwUpdate) inspection Update Result :
|
||||
* - after finished operation Write result: success (FwUpdate): fw_state = DOWNLOADED
|
||||
* - before start operation Execute (FwUpdate) Update Result = 0 - Initial value
|
||||
* - start Execute (FwUpdate)
|
||||
* After finished operation Execute (FwUpdate) inspection Update Result :
|
||||
* - after start operation Execute (FwUpdate): fw_state = UPDATING
|
||||
* - after success finished operation Execute (FwUpdate) Update Result == 1 ("Firmware updated successfully")
|
||||
* - finished operation Execute (FwUpdate)
|
||||
*/
|
||||
if (lwM2MClient.getFwUpdate() != null
|
||||
&& (convertPathFromObjectIdToIdVer(FW_RESULT_ID, registration).equals(path))) {
|
||||
if (DOWNLOADED.name().equals(lwM2MClient.getFwUpdate().getStateUpdate())
|
||||
&& lwM2MClient.getFwUpdate().conditionalFwExecuteStart()) {
|
||||
lwM2MClient.getFwUpdate().executeFwSwWare();
|
||||
} else if (UPDATING.name().equals(lwM2MClient.getFwUpdate().getStateUpdate())
|
||||
&& lwM2MClient.getFwUpdate().conditionalFwExecuteAfterSuccess()) {
|
||||
lwM2MClient.getFwUpdate().finishFwSwUpdate(true);
|
||||
} else if (UPDATING.name().equals(lwM2MClient.getFwUpdate().getStateUpdate())
|
||||
&& lwM2MClient.getFwUpdate().conditionalFwExecuteAfterError()) {
|
||||
lwM2MClient.getFwUpdate().finishFwSwUpdate(false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Before operation Execute (SwUpdate) inspection Update Result :
|
||||
* - after finished operation Write result: success (SwUpdate): fw_state = DOWNLOADED
|
||||
* - before operation Execute (SwUpdate) Update Result = 3 - Successfully Downloaded and package integrity verified
|
||||
* - start Execute (SwUpdate)
|
||||
* After finished operation Execute (SwUpdate) inspection Update Result :
|
||||
* - after start operation Execute (SwUpdate): fw_state = UPDATING
|
||||
* - after success finished operation Execute (SwUpdate) Update Result == 2 "Software successfully installed.""
|
||||
* - after success finished operation Execute (SwUpdate) Update Result == 2 "Software successfully installed.""
|
||||
* - finished operation Execute (SwUpdate)
|
||||
*/
|
||||
if (lwM2MClient.getSwUpdate() != null
|
||||
&& (convertPathFromObjectIdToIdVer(SW_RESULT_ID, registration).equals(path))) {
|
||||
if (DOWNLOADED.name().equals(lwM2MClient.getSwUpdate().getStateUpdate())
|
||||
&& lwM2MClient.getSwUpdate().conditionalSwUpdateExecute()) {
|
||||
lwM2MClient.getSwUpdate().executeFwSwWare();
|
||||
} else if (UPDATING.name().equals(lwM2MClient.getSwUpdate().getStateUpdate())
|
||||
&& lwM2MClient.getSwUpdate().conditionalSwExecuteAfterSuccess()) {
|
||||
lwM2MClient.getSwUpdate().finishFwSwUpdate(true);
|
||||
} else if (UPDATING.name().equals(lwM2MClient.getSwUpdate().getStateUpdate())
|
||||
&& lwM2MClient.getSwUpdate().conditionalSwExecuteAfterError()) {
|
||||
lwM2MClient.getSwUpdate().finishFwSwUpdate(false);
|
||||
}
|
||||
}
|
||||
Set<String> paths = new HashSet<>();
|
||||
paths.add(path);
|
||||
@ -736,7 +787,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
|
||||
*/
|
||||
private void updateAttrTelemetry(Registration registration, Set<String> paths) {
|
||||
try {
|
||||
ResultsAddKeyValueProto results = getParametersFromProfile(registration, paths);
|
||||
ResultsAddKeyValueProto results = this.getParametersFromProfile(registration, paths);
|
||||
SessionInfoProto sessionInfo = this.getSessionInfoOrCloseSession(registration);
|
||||
if (results != null && sessionInfo != null) {
|
||||
if (results.getResultAttributes().size() > 0) {
|
||||
@ -1020,8 +1071,6 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
|
||||
registrationIds.forEach(registrationId -> {
|
||||
Registration registration = clientContext.getRegistration(registrationId);
|
||||
this.readObserveFromProfile(registration, sendAttrToThingsboard.getPathPostParametersAdd(), READ);
|
||||
// send attr/telemetry to tingsboard for new path
|
||||
// this.updateAttrTelemetry(registration, sendAttrToThingsboard.getPathPostParametersAdd());
|
||||
});
|
||||
}
|
||||
// #4.2 del
|
||||
@ -1348,7 +1397,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
|
||||
TransportProtos.GetAttributeRequestMsg getAttributeMsg = adaptor.convertToGetAttributes(null, keyNamesMap.values());
|
||||
transportService.process(sessionInfo, getAttributeMsg, getAckCallback(lwM2MClient, getAttributeMsg.getRequestId(), DEVICE_ATTRIBUTES_REQUEST));
|
||||
} catch (AdaptorException e) {
|
||||
log.warn("Failed to decode get attributes request", e);
|
||||
log.trace("Failed to decode get attributes request", e);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1369,7 +1418,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
|
||||
lwM2MClient.getFwUpdate().setCurrentVersion(response.getVersion());
|
||||
lwM2MClient.getFwUpdate().setCurrentTitle(response.getTitle());
|
||||
lwM2MClient.getFwUpdate().setCurrentId(new FirmwareId(new UUID(response.getFirmwareIdMSB(), response.getFirmwareIdLSB())).getId());
|
||||
lwM2MClient.getFwUpdate().sendReadInfo(serviceImpl);
|
||||
lwM2MClient.getFwUpdate().sendReadObserveInfo(serviceImpl);
|
||||
} else {
|
||||
log.trace("Firmware [{}] [{}]", lwM2MClient.getDeviceName(), response.getResponseStatus().toString());
|
||||
}
|
||||
@ -1377,7 +1426,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
|
||||
|
||||
@Override
|
||||
public void onError(Throwable e) {
|
||||
log.warn("Failed to process firmwareUpdate ", e);
|
||||
log.trace("Failed to process firmwareUpdate ", e);
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -1398,7 +1447,7 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
|
||||
lwM2MClient.getSwUpdate().setCurrentVersion(response.getVersion());
|
||||
lwM2MClient.getSwUpdate().setCurrentTitle(response.getTitle());
|
||||
lwM2MClient.getSwUpdate().setCurrentId(new FirmwareId(new UUID(response.getFirmwareIdMSB(), response.getFirmwareIdLSB())).getId());
|
||||
lwM2MClient.getSwUpdate().sendReadInfo(serviceImpl);
|
||||
lwM2MClient.getSwUpdate().sendReadObserveInfo(serviceImpl);
|
||||
} else {
|
||||
log.trace("Software [{}] [{}]", lwM2MClient.getDeviceName(), response.getResponseStatus().toString());
|
||||
}
|
||||
@ -1448,4 +1497,8 @@ public class DefaultLwM2MTransportMsgHandler implements LwM2mTransportMsgHandler
|
||||
objectId != null && objectVer != null && objectVer.equals(lwM2mClient.getRegistration().getSupportedVersion(objectId)));
|
||||
}
|
||||
|
||||
public LwM2MTransportServerConfig getConfig() {
|
||||
return this.config;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -117,7 +117,6 @@ public class DefaultLwM2mTransportService implements LwM2MTransportService {
|
||||
}
|
||||
|
||||
private LeshanServer getLhServer() {
|
||||
// this.registrationStoreExecutor = (ScheduledExecutorService) ThingsBoardExecutors.newWorkStealingPool(this.config.getRegistrationStorePoolSize(), "LwM2M registrationStore");
|
||||
this.registrationStoreExecutor = Executors.newScheduledThreadPool(this.config.getRegistrationStorePoolSize(), ThingsBoardThreadFactory.forName("LwM2M registrationStore"));
|
||||
|
||||
LeshanServerBuilder builder = new LeshanServerBuilder();
|
||||
|
||||
@ -86,7 +86,7 @@ public class LwM2mServerListener {
|
||||
|
||||
@Override
|
||||
public void cancelled(Observation observation) {
|
||||
String msg = String.format("%s: Cancel Observation %s.", LOG_LW2M_INFO, observation.getPath());
|
||||
String msg = String.format("%s: Canceled Observation %s.", LOG_LW2M_INFO, observation.getPath());
|
||||
service.sendLogsToThingsboard(msg, observation.getRegistrationId());
|
||||
log.warn(msg);
|
||||
}
|
||||
@ -94,13 +94,14 @@ public class LwM2mServerListener {
|
||||
@Override
|
||||
public void onResponse(Observation observation, Registration registration, ObserveResponse response) {
|
||||
if (registration != null) {
|
||||
try {
|
||||
service.onUpdateValueAfterReadResponse(registration, convertPathFromObjectIdToIdVer(observation.getPath().toString(),
|
||||
registration), response, null);
|
||||
} catch (Exception e) {
|
||||
log.error("Observation/Read onResponse", e);
|
||||
|
||||
}
|
||||
// if (observation.getPath().isResource() || observation.getPath().isResourceInstance()) {
|
||||
// String msg = String.format("%s: Successful Observation %s.", LOG_LW2M_INFO,
|
||||
// observation.getPath());
|
||||
// log.warn(msg);
|
||||
// service.sendLogsToThingsboard(msg, registration.getId());
|
||||
// }
|
||||
service.onUpdateValueAfterReadResponse(registration, convertPathFromObjectIdToIdVer(observation.getPath().toString(),
|
||||
registration), response, null);
|
||||
}
|
||||
}
|
||||
|
||||
@ -113,9 +114,8 @@ public class LwM2mServerListener {
|
||||
public void newObservation(Observation observation, Registration registration) {
|
||||
String msg = String.format("%s: Successful start newObservation %s.", LOG_LW2M_INFO,
|
||||
observation.getPath());
|
||||
log.warn(msg);
|
||||
service.sendLogsToThingsboard(msg, registration.getId());
|
||||
log.trace(msg);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@ -21,6 +21,7 @@ import org.eclipse.leshan.server.registration.Registration;
|
||||
import org.thingsboard.server.common.data.Device;
|
||||
import org.thingsboard.server.common.data.DeviceProfile;
|
||||
import org.thingsboard.server.gen.transport.TransportProtos;
|
||||
import org.thingsboard.server.transport.lwm2m.config.LwM2MTransportServerConfig;
|
||||
import org.thingsboard.server.transport.lwm2m.server.client.Lwm2mClientRpcRequest;
|
||||
|
||||
import java.util.Collection;
|
||||
@ -36,7 +37,7 @@ public interface LwM2mTransportMsgHandler {
|
||||
|
||||
void onSleepingDev(Registration registration);
|
||||
|
||||
void setCancelObservations(Registration registration);
|
||||
void setCancelObservationsAll(Registration registration);
|
||||
|
||||
void onUpdateValueAfterReadResponse(Registration registration, String path, ReadResponse response, Lwm2mClientRpcRequest rpcRequest);
|
||||
|
||||
@ -63,4 +64,6 @@ public interface LwM2mTransportMsgHandler {
|
||||
void onAwakeDev(Registration registration);
|
||||
|
||||
void sendLogsToThingsboard(String msg, String registrationId);
|
||||
|
||||
LwM2MTransportServerConfig getConfig();
|
||||
}
|
||||
|
||||
@ -36,7 +36,6 @@ import org.eclipse.leshan.core.request.ObserveRequest;
|
||||
import org.eclipse.leshan.core.request.ReadRequest;
|
||||
import org.eclipse.leshan.core.request.WriteRequest;
|
||||
import org.eclipse.leshan.core.request.exception.ClientSleepingException;
|
||||
import org.eclipse.leshan.core.response.CancelObservationResponse;
|
||||
import org.eclipse.leshan.core.response.DeleteResponse;
|
||||
import org.eclipse.leshan.core.response.DiscoverResponse;
|
||||
import org.eclipse.leshan.core.response.ExecuteResponse;
|
||||
@ -49,7 +48,6 @@ import org.eclipse.leshan.core.util.Hex;
|
||||
import org.eclipse.leshan.core.util.NamedThreadFactory;
|
||||
import org.eclipse.leshan.server.registration.Registration;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.thingsboard.server.common.data.firmware.FirmwareUpdateStatus;
|
||||
import org.thingsboard.server.queue.util.TbLwM2mTransportComponent;
|
||||
import org.thingsboard.server.transport.lwm2m.config.LwM2MTransportServerConfig;
|
||||
import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient;
|
||||
@ -70,16 +68,25 @@ import java.util.stream.Collectors;
|
||||
import static org.eclipse.californium.core.coap.CoAP.ResponseCode.CONTENT;
|
||||
import static org.eclipse.leshan.core.ResponseCode.BAD_REQUEST;
|
||||
import static org.eclipse.leshan.core.ResponseCode.NOT_FOUND;
|
||||
import static org.thingsboard.server.common.data.firmware.FirmwareUpdateStatus.DOWNLOADED;
|
||||
import static org.thingsboard.server.common.data.firmware.FirmwareUpdateStatus.FAILED;
|
||||
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportServerHelper.getContentFormatByResourceModelType;
|
||||
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.DEFAULT_TIMEOUT;
|
||||
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.FW_PACKAGE_ID;
|
||||
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.FW_UPDATE_ID;
|
||||
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LOG_LW2M_ERROR;
|
||||
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LOG_LW2M_INFO;
|
||||
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LOG_LW2M_VALUE;
|
||||
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper;
|
||||
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.DISCOVER;
|
||||
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.DISCOVER_All;
|
||||
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.EXECUTE;
|
||||
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.OBSERVE_CANCEL;
|
||||
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.OBSERVE_READ_ALL;
|
||||
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.RESPONSE_CHANNEL;
|
||||
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.WRITE_REPLACE;
|
||||
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.WRITE_UPDATE;
|
||||
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.RESPONSE_REQUEST_CHANNEL;
|
||||
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.SW_INSTALL_ID;
|
||||
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.SW_PACKAGE_ID;
|
||||
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.convertPathFromIdVerToObjectId;
|
||||
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.convertPathFromObjectIdToIdVer;
|
||||
@ -90,7 +97,7 @@ import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.c
|
||||
@TbLwM2mTransportComponent
|
||||
@RequiredArgsConstructor
|
||||
public class LwM2mTransportRequest {
|
||||
private ExecutorService executorResponse;
|
||||
private ExecutorService responseRequestExecutor;
|
||||
|
||||
public LwM2mValueConverterImpl converter;
|
||||
|
||||
@ -102,8 +109,8 @@ public class LwM2mTransportRequest {
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
this.converter = LwM2mValueConverterImpl.getInstance();
|
||||
executorResponse = Executors.newFixedThreadPool(this.config.getResponsePoolSize(),
|
||||
new NamedThreadFactory(String.format("LwM2M %s channel response", RESPONSE_CHANNEL)));
|
||||
responseRequestExecutor = Executors.newFixedThreadPool(this.config.getResponsePoolSize(),
|
||||
new NamedThreadFactory(String.format("LwM2M %s channel response after request", RESPONSE_REQUEST_CHANNEL)));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -119,118 +126,14 @@ public class LwM2mTransportRequest {
|
||||
String contentFormatName, Object params, long timeoutInMs, Lwm2mClientRpcRequest rpcRequest) {
|
||||
try {
|
||||
String target = convertPathFromIdVerToObjectId(targetIdVer);
|
||||
DownlinkRequest request = null;
|
||||
ContentFormat contentFormat = contentFormatName != null ? ContentFormat.fromName(contentFormatName.toUpperCase()) : ContentFormat.DEFAULT;
|
||||
LwM2mClient lwM2MClient = this.lwM2mClientContext.getOrRegister(registration);
|
||||
LwM2mPath resultIds = target != null ? new LwM2mPath(target) : null;
|
||||
if (!OBSERVE_READ_ALL.name().equals(typeOper.name()) && resultIds != null && registration != null && resultIds.getObjectId() >= 0 && lwM2MClient != null) {
|
||||
if (lwM2MClient.isValidObjectVersion(targetIdVer)) {
|
||||
timeoutInMs = timeoutInMs > 0 ? timeoutInMs : DEFAULT_TIMEOUT;
|
||||
ResourceModel resourceModel = null;
|
||||
switch (typeOper) {
|
||||
case READ:
|
||||
request = new ReadRequest(contentFormat, target);
|
||||
break;
|
||||
case DISCOVER:
|
||||
request = new DiscoverRequest(target);
|
||||
break;
|
||||
case OBSERVE:
|
||||
if (resultIds.isResource()) {
|
||||
Set<Observation> observations = context.getServer().getObservationService().getObservations(registration);
|
||||
Set<Observation> paths = observations.stream().filter(observation -> observation.getPath().equals(resultIds)).collect(Collectors.toSet());
|
||||
if (paths.size() == 0) {
|
||||
request = new ObserveRequest(contentFormat, resultIds.getObjectId(), resultIds.getObjectInstanceId(), resultIds.getResourceId());
|
||||
} else {
|
||||
request = new ReadRequest(contentFormat, target);
|
||||
}
|
||||
} else if (resultIds.isObjectInstance()) {
|
||||
request = new ObserveRequest(contentFormat, resultIds.getObjectId(), resultIds.getObjectInstanceId());
|
||||
} else if (resultIds.getObjectId() >= 0) {
|
||||
request = new ObserveRequest(contentFormat, resultIds.getObjectId());
|
||||
}
|
||||
break;
|
||||
case OBSERVE_CANCEL:
|
||||
/*
|
||||
lwM2MTransportRequest.sendAllRequest(lwServer, registration, path, POST_TYPE_OPER_OBSERVE_CANCEL, null, null, null, null, context.getTimeout());
|
||||
At server side this will not remove the observation from the observation store, to do it you need to use
|
||||
{@code ObservationService#cancelObservation()}
|
||||
*/
|
||||
context.getServer().getObservationService().cancelObservations(registration, target);
|
||||
break;
|
||||
case EXECUTE:
|
||||
resourceModel = lwM2MClient.getResourceModel(targetIdVer, this.config
|
||||
.getModelProvider());
|
||||
if (params != null && !resourceModel.multiple) {
|
||||
request = new ExecuteRequest(target, (String) this.converter.convertValue(params, resourceModel.type, ResourceModel.Type.STRING, resultIds));
|
||||
} else {
|
||||
request = new ExecuteRequest(target);
|
||||
}
|
||||
break;
|
||||
case WRITE_REPLACE:
|
||||
// Request to write a <b>String Single-Instance Resource</b> using the TLV content format.
|
||||
resourceModel = lwM2MClient.getResourceModel(targetIdVer, this.config.getModelProvider());
|
||||
if (contentFormat.equals(ContentFormat.TLV)) {
|
||||
request = this.getWriteRequestSingleResource(null, resultIds.getObjectId(),
|
||||
resultIds.getObjectInstanceId(), resultIds.getResourceId(), params, resourceModel.type,
|
||||
registration, rpcRequest);
|
||||
}
|
||||
// Mode.REPLACE && Request to write a <b>String Single-Instance Resource</b> using the given content format (TEXT, TLV, JSON)
|
||||
else if (!contentFormat.equals(ContentFormat.TLV)) {
|
||||
request = this.getWriteRequestSingleResource(contentFormat, resultIds.getObjectId(),
|
||||
resultIds.getObjectInstanceId(), resultIds.getResourceId(), params, resourceModel.type,
|
||||
registration, rpcRequest);
|
||||
}
|
||||
break;
|
||||
case WRITE_UPDATE:
|
||||
if (resultIds.isResource()) {
|
||||
/**
|
||||
* send request: path = '/3/0' node == wM2mObjectInstance
|
||||
* with params == "\"resources\": {15: resource:{id:15. value:'+01'...}}
|
||||
**/
|
||||
Collection<LwM2mResource> resources = lwM2MClient.getNewOneResourceForInstance(
|
||||
targetIdVer, params,
|
||||
this.config.getModelProvider(),
|
||||
this.converter);
|
||||
request = new WriteRequest(WriteRequest.Mode.UPDATE, contentFormat, resultIds.getObjectId(),
|
||||
resultIds.getObjectInstanceId(), resources);
|
||||
}
|
||||
|
||||
/**
|
||||
* params = "{\"id\":0,\"resources\":[{\"id\":14,\"value\":\"+5\"},{\"id\":15,\"value\":\"+9\"}]}"
|
||||
*
|
||||
* int rscId = resultIds.getObjectInstanceId();
|
||||
*/
|
||||
|
||||
else if (resultIds.isObjectInstance()) {
|
||||
if (((ConcurrentHashMap) params).size() > 0) {
|
||||
Collection<LwM2mResource> resources = lwM2MClient.getNewManyResourcesForInstance(
|
||||
targetIdVer, params,
|
||||
this.config.getModelProvider(),
|
||||
this.converter);
|
||||
if (resources.size() > 0) {
|
||||
request = new WriteRequest(WriteRequest.Mode.UPDATE, contentFormat, resultIds.getObjectId(),
|
||||
resultIds.getObjectInstanceId(), resources);
|
||||
} else {
|
||||
Lwm2mClientRpcRequest rpcRequestClone = (Lwm2mClientRpcRequest) rpcRequest.clone();
|
||||
if (rpcRequestClone != null) {
|
||||
String errorMsg = String.format("Path %s params is not valid", targetIdVer);
|
||||
serviceImpl.sentRpcRequest(rpcRequestClone, BAD_REQUEST.getName(), errorMsg, LOG_LW2M_ERROR);
|
||||
rpcRequest = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (resultIds.getObjectId() >= 0) {
|
||||
request = new ObserveRequest(resultIds.getObjectId());
|
||||
}
|
||||
break;
|
||||
case WRITE_ATTRIBUTES:
|
||||
request = createWriteAttributeRequest(target, params);
|
||||
break;
|
||||
case DELETE:
|
||||
request = new DeleteRequest(target);
|
||||
break;
|
||||
}
|
||||
|
||||
DownlinkRequest request = createRequest (registration, lwM2MClient, typeOper, contentFormat, target,
|
||||
targetIdVer, resultIds, params, rpcRequest);
|
||||
if (request != null) {
|
||||
try {
|
||||
this.sendRequest(registration, lwM2MClient, request, timeoutInMs, rpcRequest);
|
||||
@ -242,15 +145,19 @@ public class LwM2mTransportRequest {
|
||||
} catch (Exception e) {
|
||||
log.error("[{}] [{}] [{}] Failed to send downlink.", registration.getEndpoint(), targetIdVer, typeOper.name(), e);
|
||||
}
|
||||
} else if (OBSERVE_CANCEL == typeOper) {
|
||||
log.trace("[{}], [{}] - [{}] SendRequest", registration.getEndpoint(), typeOper.name(), targetIdVer);
|
||||
if (rpcRequest != null) {
|
||||
rpcRequest.setInfoMsg(null);
|
||||
serviceImpl.sentRpcRequest(rpcRequest, CONTENT.name(), null, null);
|
||||
}
|
||||
else if (WRITE_UPDATE.name().equals(typeOper.name())) {
|
||||
Lwm2mClientRpcRequest rpcRequestClone = (Lwm2mClientRpcRequest) rpcRequest.clone();
|
||||
if (rpcRequestClone != null) {
|
||||
String errorMsg = String.format("Path %s params is not valid", targetIdVer);
|
||||
serviceImpl.sentRpcRequest(rpcRequestClone, BAD_REQUEST.getName(), errorMsg, LOG_LW2M_ERROR);
|
||||
rpcRequest = null;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else if (!OBSERVE_CANCEL.name().equals(typeOper.name())) {
|
||||
log.error("[{}], [{}] - [{}] error SendRequest", registration.getEndpoint(), typeOper.name(), targetIdVer);
|
||||
if (rpcRequest != null) {
|
||||
ResourceModel resourceModel = lwM2MClient.getResourceModel(targetIdVer, this.config.getModelProvider());
|
||||
String errorMsg = resourceModel == null ? String.format("Path %s not found in object version", targetIdVer) : "SendRequest - null";
|
||||
serviceImpl.sentRpcRequest(rpcRequest, NOT_FOUND.getName(), errorMsg, LOG_LW2M_ERROR);
|
||||
}
|
||||
@ -265,30 +172,140 @@ public class LwM2mTransportRequest {
|
||||
Set<Observation> observations = context.getServer().getObservationService().getObservations(registration);
|
||||
paths = observations.stream().map(observation -> observation.getPath().toString()).collect(Collectors.toUnmodifiableSet());
|
||||
} else {
|
||||
assert registration != null;
|
||||
Link[] objectLinks = registration.getSortedObjectLinks();
|
||||
paths = Arrays.stream(objectLinks).map(link -> link.toString()).collect(Collectors.toUnmodifiableSet());
|
||||
paths = Arrays.stream(objectLinks).map(Link::toString).collect(Collectors.toUnmodifiableSet());
|
||||
String msg = String.format("%s: type operation %s paths - %s", LOG_LW2M_INFO,
|
||||
typeOper.name(), paths);
|
||||
serviceImpl.sendLogsToThingsboard(msg, registration.getId());
|
||||
}
|
||||
String msg = String.format("%s: type operation %s paths - %s", LOG_LW2M_INFO,
|
||||
OBSERVE_READ_ALL.type, paths);
|
||||
serviceImpl.sendLogsToThingsboard(msg, registration.getId());
|
||||
log.warn("[{}] [{}], [{}]", typeOper.name(), registration.getEndpoint(), msg);
|
||||
if (rpcRequest != null) {
|
||||
String valueMsg = String.format("Paths - %s", paths);
|
||||
serviceImpl.sentRpcRequest(rpcRequest, CONTENT.name(), valueMsg, LOG_LW2M_VALUE);
|
||||
}
|
||||
} else if (OBSERVE_CANCEL.name().equals(typeOper.name())) {
|
||||
int observeCancelCnt = context.getServer().getObservationService().cancelObservations(registration);
|
||||
String observeCancelMsgAll = String.format("%s: type operation %s paths: All count: %d", LOG_LW2M_INFO,
|
||||
OBSERVE_CANCEL.name(), observeCancelCnt);
|
||||
this.afterObserveCancel(registration, observeCancelCnt, observeCancelMsgAll, rpcRequest);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
String msg = String.format("%s: type operation %s %s", LOG_LW2M_ERROR,
|
||||
typeOper.name(), e.getMessage());
|
||||
serviceImpl.sendLogsToThingsboard(msg, registration.getId());
|
||||
try {
|
||||
throw new Exception(e);
|
||||
} catch (Exception exception) {
|
||||
exception.printStackTrace();
|
||||
if (rpcRequest != null) {
|
||||
String errorMsg = String.format("Path %s type operation %s %s", targetIdVer, typeOper.name(), e.getMessage());
|
||||
serviceImpl.sentRpcRequest(rpcRequest, NOT_FOUND.getName(), errorMsg, LOG_LW2M_ERROR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private DownlinkRequest createRequest (Registration registration, LwM2mClient lwM2MClient, LwM2mTypeOper typeOper,
|
||||
ContentFormat contentFormat, String target, String targetIdVer,
|
||||
LwM2mPath resultIds, Object params, Lwm2mClientRpcRequest rpcRequest) {
|
||||
DownlinkRequest request = null;
|
||||
switch (typeOper) {
|
||||
case READ:
|
||||
request = new ReadRequest(contentFormat, target);
|
||||
break;
|
||||
case DISCOVER:
|
||||
request = new DiscoverRequest(target);
|
||||
break;
|
||||
case OBSERVE:
|
||||
String msg = String.format("%s: Send Observation %s.", LOG_LW2M_INFO, targetIdVer);
|
||||
log.warn(msg);
|
||||
if (resultIds.isResource()) {
|
||||
Set<Observation> observations = context.getServer().getObservationService().getObservations(registration);
|
||||
Set<Observation> paths = observations.stream().filter(observation -> observation.getPath().equals(resultIds)).collect(Collectors.toSet());
|
||||
if (paths.size() == 0) {
|
||||
request = new ObserveRequest(contentFormat, resultIds.getObjectId(), resultIds.getObjectInstanceId(), resultIds.getResourceId());
|
||||
} else {
|
||||
request = new ReadRequest(contentFormat, target);
|
||||
}
|
||||
} else if (resultIds.isObjectInstance()) {
|
||||
request = new ObserveRequest(contentFormat, resultIds.getObjectId(), resultIds.getObjectInstanceId());
|
||||
} else if (resultIds.getObjectId() >= 0) {
|
||||
request = new ObserveRequest(contentFormat, resultIds.getObjectId());
|
||||
}
|
||||
break;
|
||||
case OBSERVE_CANCEL:
|
||||
/*
|
||||
lwM2MTransportRequest.sendAllRequest(lwServer, registration, path, POST_TYPE_OPER_OBSERVE_CANCEL, null, null, null, null, context.getTimeout());
|
||||
At server side this will not remove the observation from the observation store, to do it you need to use
|
||||
{@code ObservationService#cancelObservation()}
|
||||
*/
|
||||
int observeCancelCnt = context.getServer().getObservationService().cancelObservations(registration, target);
|
||||
String observeCancelMsg = String.format("%s: type operation %s paths: %s count: %d", LOG_LW2M_INFO,
|
||||
OBSERVE_CANCEL.name(), target, observeCancelCnt);
|
||||
this.afterObserveCancel(registration, observeCancelCnt, observeCancelMsg, rpcRequest);
|
||||
break;
|
||||
case EXECUTE:
|
||||
ResourceModel resourceModelExe = lwM2MClient.getResourceModel(targetIdVer, this.config.getModelProvider());
|
||||
if (params != null && !resourceModelExe.multiple) {
|
||||
request = new ExecuteRequest(target, (String) this.converter.convertValue(params, resourceModelExe.type, ResourceModel.Type.STRING, resultIds));
|
||||
} else {
|
||||
request = new ExecuteRequest(target);
|
||||
}
|
||||
break;
|
||||
case WRITE_REPLACE:
|
||||
/**
|
||||
* Request to write a <b>String Single-Instance Resource</b> using the TLV content format.
|
||||
* Type from resourceModel -> STRING, INTEGER, FLOAT, BOOLEAN, OPAQUE, TIME, OBJLNK
|
||||
* contentFormat -> TLV, TLV, TLV, TLV, OPAQUE, TLV, LINK
|
||||
* JSON, TEXT;
|
||||
**/
|
||||
ResourceModel resourceModelWrite = lwM2MClient.getResourceModel(targetIdVer, this.config.getModelProvider());
|
||||
contentFormat = getContentFormatByResourceModelType(resourceModelWrite, contentFormat);
|
||||
request = this.getWriteRequestSingleResource(contentFormat, resultIds.getObjectId(),
|
||||
resultIds.getObjectInstanceId(), resultIds.getResourceId(), params, resourceModelWrite.type,
|
||||
registration, rpcRequest);
|
||||
break;
|
||||
case WRITE_UPDATE:
|
||||
if (resultIds.isResource()) {
|
||||
/**
|
||||
* send request: path = '/3/0' node == wM2mObjectInstance
|
||||
* with params == "\"resources\": {15: resource:{id:15. value:'+01'...}}
|
||||
**/
|
||||
Collection<LwM2mResource> resources = lwM2MClient.getNewResourceForInstance(
|
||||
targetIdVer, params,
|
||||
this.config.getModelProvider(),
|
||||
this.converter);
|
||||
contentFormat = getContentFormatByResourceModelType(lwM2MClient.getResourceModel(targetIdVer, this.config.getModelProvider()),
|
||||
contentFormat);
|
||||
request = new WriteRequest(WriteRequest.Mode.UPDATE, contentFormat, resultIds.getObjectId(),
|
||||
resultIds.getObjectInstanceId(), resources);
|
||||
}
|
||||
/**
|
||||
* params = "{\"id\":0,\"resources\":[{\"id\":14,\"value\":\"+5\"},{\"id\":15,\"value\":\"+9\"}]}"
|
||||
* int rscId = resultIds.getObjectInstanceId();
|
||||
* contentFormat – Format of the payload (TLV or JSON).
|
||||
*/
|
||||
else if (resultIds.isObjectInstance()) {
|
||||
if (((ConcurrentHashMap) params).size() > 0) {
|
||||
Collection<LwM2mResource> resources = lwM2MClient.getNewResourcesForInstance(
|
||||
targetIdVer, params,
|
||||
this.config.getModelProvider(),
|
||||
this.converter);
|
||||
if (resources.size() > 0) {
|
||||
contentFormat = contentFormat.equals(ContentFormat.JSON) ? contentFormat : ContentFormat.TLV;
|
||||
request = new WriteRequest(WriteRequest.Mode.UPDATE, contentFormat, resultIds.getObjectId(),
|
||||
resultIds.getObjectInstanceId(), resources);
|
||||
}
|
||||
}
|
||||
} else if (resultIds.getObjectId() >= 0) {
|
||||
request = new ObserveRequest(resultIds.getObjectId());
|
||||
}
|
||||
break;
|
||||
case WRITE_ATTRIBUTES:
|
||||
request = createWriteAttributeRequest(target, params);
|
||||
break;
|
||||
case DELETE:
|
||||
request = new DeleteRequest(target);
|
||||
break;
|
||||
}
|
||||
return request;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param registration -
|
||||
* @param request -
|
||||
@ -314,6 +331,7 @@ public class LwM2mTransportRequest {
|
||||
if (!lwM2MClient.isInit()) {
|
||||
lwM2MClient.initReadValue(this.serviceImpl, convertPathFromObjectIdToIdVer(request.getPath().toString(), registration));
|
||||
}
|
||||
/** Not Found */
|
||||
if (rpcRequest != null) {
|
||||
serviceImpl.sentRpcRequest(rpcRequest, response.getCode().getName(), response.getErrorMessage(), LOG_LW2M_ERROR);
|
||||
}
|
||||
@ -322,7 +340,15 @@ public class LwM2mTransportRequest {
|
||||
**/
|
||||
if (lwM2MClient.getFwUpdate().isInfoFwSwUpdate()) {
|
||||
lwM2MClient.getFwUpdate().initReadValue(serviceImpl, request.getPath().toString());
|
||||
log.warn("updateFirmwareClient1");
|
||||
}
|
||||
if (lwM2MClient.getSwUpdate().isInfoFwSwUpdate()) {
|
||||
lwM2MClient.getSwUpdate().initReadValue(serviceImpl, request.getPath().toString());
|
||||
}
|
||||
if (request.getPath().toString().equals(FW_PACKAGE_ID) || request.getPath().toString().equals(SW_PACKAGE_ID)) {
|
||||
this.afterWriteFwSWUpdateError(registration, request, response.getErrorMessage());
|
||||
}
|
||||
if (request.getPath().toString().equals(FW_UPDATE_ID) || request.getPath().toString().equals(SW_INSTALL_ID)) {
|
||||
this.afterExecuteFwSwUpdateError(registration, request, response.getErrorMessage());
|
||||
}
|
||||
}
|
||||
}, e -> {
|
||||
@ -331,7 +357,15 @@ public class LwM2mTransportRequest {
|
||||
**/
|
||||
if (lwM2MClient.getFwUpdate().isInfoFwSwUpdate()) {
|
||||
lwM2MClient.getFwUpdate().initReadValue(serviceImpl, request.getPath().toString());
|
||||
log.warn("updateFirmwareClient2");
|
||||
}
|
||||
if (lwM2MClient.getSwUpdate().isInfoFwSwUpdate()) {
|
||||
lwM2MClient.getSwUpdate().initReadValue(serviceImpl, request.getPath().toString());
|
||||
}
|
||||
if (request.getPath().toString().equals(FW_PACKAGE_ID) || request.getPath().toString().equals(SW_PACKAGE_ID)) {
|
||||
this.afterWriteFwSWUpdateError(registration, request, e.getMessage());
|
||||
}
|
||||
if (request.getPath().toString().equals(FW_UPDATE_ID) || request.getPath().toString().equals(SW_INSTALL_ID)) {
|
||||
this.afterExecuteFwSwUpdateError(registration, request, e.getMessage());
|
||||
}
|
||||
if (!lwM2MClient.isInit()) {
|
||||
lwM2MClient.initReadValue(this.serviceImpl, convertPathFromObjectIdToIdVer(request.getPath().toString(), registration));
|
||||
@ -395,7 +429,7 @@ public class LwM2mTransportRequest {
|
||||
|
||||
private void handleResponse(Registration registration, final String path, LwM2mResponse response,
|
||||
DownlinkRequest request, Lwm2mClientRpcRequest rpcRequest) {
|
||||
executorResponse.submit(() -> {
|
||||
responseRequestExecutor.submit(() -> {
|
||||
try {
|
||||
this.sendResponse(registration, path, response, request, rpcRequest);
|
||||
} catch (Exception e) {
|
||||
@ -414,28 +448,26 @@ public class LwM2mTransportRequest {
|
||||
private void sendResponse(Registration registration, String path, LwM2mResponse response,
|
||||
DownlinkRequest request, Lwm2mClientRpcRequest rpcRequest) {
|
||||
String pathIdVer = convertPathFromObjectIdToIdVer(path, registration);
|
||||
String msgLog = "";
|
||||
if (response instanceof ReadResponse) {
|
||||
serviceImpl.onUpdateValueAfterReadResponse(registration, pathIdVer, (ReadResponse) response, rpcRequest);
|
||||
} else if (response instanceof CancelObservationResponse) {
|
||||
log.info("[{}] Path [{}] CancelObservationResponse 3_Send", pathIdVer, response);
|
||||
|
||||
} else if (response instanceof DeleteResponse) {
|
||||
log.info("[{}] Path [{}] DeleteResponse 5_Send", pathIdVer, response);
|
||||
log.warn("[{}] Path [{}] DeleteResponse 5_Send", pathIdVer, response);
|
||||
} else if (response instanceof DiscoverResponse) {
|
||||
log.info("[{}] [{}] - [{}] [{}] Discovery value: [{}]", registration.getEndpoint(),
|
||||
((Response) response.getCoapResponse()).getCode(), response.getCode(),
|
||||
request.getPath().toString(), ((DiscoverResponse) response).getObjectLinks());
|
||||
String discoverValue = Link.serialize(((DiscoverResponse)response).getObjectLinks());
|
||||
msgLog = String.format("%s: type operation: %s path: %s value: %s",
|
||||
LOG_LW2M_INFO, DISCOVER.name(), request.getPath().toString(), discoverValue);
|
||||
serviceImpl.sendLogsToThingsboard(msgLog, registration.getId());
|
||||
log.warn("DiscoverResponse: [{}]", (DiscoverResponse) response);
|
||||
if (rpcRequest != null) {
|
||||
String discoveryMsg = String.format("%s",
|
||||
Arrays.stream(((DiscoverResponse) response).getObjectLinks()).collect(Collectors.toSet()));
|
||||
serviceImpl.sentRpcRequest(rpcRequest, response.getCode().getName(), discoveryMsg, LOG_LW2M_VALUE);
|
||||
serviceImpl.sentRpcRequest(rpcRequest, response.getCode().getName(), discoverValue, LOG_LW2M_VALUE);
|
||||
}
|
||||
} else if (response instanceof ExecuteResponse) {
|
||||
log.info("[{}] Path [{}] ExecuteResponse 7_Send", pathIdVer, response);
|
||||
log.warn("[{}] Path [{}] ExecuteResponse 7_Send", pathIdVer, response);
|
||||
} else if (response instanceof WriteAttributesResponse) {
|
||||
log.info("[{}] Path [{}] WriteAttributesResponse 8_Send", pathIdVer, response);
|
||||
log.warn("[{}] Path [{}] WriteAttributesResponse 8_Send", pathIdVer, response);
|
||||
} else if (response instanceof WriteResponse) {
|
||||
log.info("[{}] Path [{}] WriteResponse 9_Send", pathIdVer, response);
|
||||
log.warn("[{}] Path [{}] WriteResponse 9_Send", pathIdVer, response);
|
||||
this.infoWriteResponse(registration, response, request);
|
||||
serviceImpl.onWriteResponseOk(registration, pathIdVer, (WriteRequest) request);
|
||||
}
|
||||
@ -480,9 +512,8 @@ public class LwM2mTransportRequest {
|
||||
}
|
||||
if (msg != null) {
|
||||
serviceImpl.sendLogsToThingsboard(msg, registration.getId());
|
||||
log.warn(msg);
|
||||
if (request.getPath().toString().equals(FW_PACKAGE_ID) || request.getPath().toString().equals(SW_PACKAGE_ID)) {
|
||||
this.executeFwSwUpdate(registration, request);
|
||||
this.afterWriteSuccessFwSwUpdate(registration, request);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
@ -490,15 +521,54 @@ public class LwM2mTransportRequest {
|
||||
}
|
||||
}
|
||||
|
||||
private void executeFwSwUpdate(Registration registration, DownlinkRequest request) {
|
||||
LwM2mClient lwM2mClient = this.lwM2mClientContext.getClientByRegistrationId(registration.getId());
|
||||
if (request.getPath().toString().equals(FW_PACKAGE_ID)
|
||||
&& FirmwareUpdateStatus.DOWNLOADING.name().equals(lwM2mClient.getFwUpdate().getStateUpdate())) {
|
||||
lwM2mClient.getFwUpdate().sendReadInfoForWrite();
|
||||
/**
|
||||
* After finish operation FwSwUpdate Write (success):
|
||||
* fw_state/sw_state = DOWNLOADED
|
||||
* send operation Execute
|
||||
*/
|
||||
private void afterWriteSuccessFwSwUpdate(Registration registration, DownlinkRequest request) {
|
||||
LwM2mClient lwM2MClient = this.lwM2mClientContext.getClientByRegistrationId(registration.getId());
|
||||
if (request.getPath().toString().equals(FW_PACKAGE_ID) && lwM2MClient.getFwUpdate() != null) {
|
||||
lwM2MClient.getFwUpdate().setStateUpdate(DOWNLOADED.name());
|
||||
lwM2MClient.getFwUpdate().sendLogs(WRITE_REPLACE.name(), LOG_LW2M_INFO, null);
|
||||
}
|
||||
if (request.getPath().toString().equals(SW_PACKAGE_ID)
|
||||
&& FirmwareUpdateStatus.DOWNLOADING.name().equals(lwM2mClient.getSwUpdate().getStateUpdate())) {
|
||||
lwM2mClient.getSwUpdate().sendReadInfoForWrite();
|
||||
if (request.getPath().toString().equals(SW_PACKAGE_ID) && lwM2MClient.getSwUpdate() != null) {
|
||||
lwM2MClient.getSwUpdate().setStateUpdate(DOWNLOADED.name());
|
||||
lwM2MClient.getSwUpdate().sendLogs(WRITE_REPLACE.name(), LOG_LW2M_INFO, null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* After finish operation FwSwUpdate Write (error): fw_state = FAILED
|
||||
*/
|
||||
private void afterWriteFwSWUpdateError(Registration registration, DownlinkRequest request, String msgError) {
|
||||
LwM2mClient lwM2MClient = this.lwM2mClientContext.getClientByRegistrationId(registration.getId());
|
||||
if (request.getPath().toString().equals(FW_PACKAGE_ID) && lwM2MClient.getFwUpdate() != null) {
|
||||
lwM2MClient.getFwUpdate().setStateUpdate(FAILED.name());
|
||||
lwM2MClient.getFwUpdate().sendLogs(WRITE_REPLACE.name(), LOG_LW2M_ERROR, msgError);
|
||||
}
|
||||
if (request.getPath().toString().equals(SW_PACKAGE_ID) && lwM2MClient.getSwUpdate() != null) {
|
||||
lwM2MClient.getSwUpdate().setStateUpdate(FAILED.name());
|
||||
lwM2MClient.getSwUpdate().sendLogs(WRITE_REPLACE.name(), LOG_LW2M_ERROR, msgError);
|
||||
}
|
||||
}
|
||||
|
||||
private void afterExecuteFwSwUpdateError(Registration registration, DownlinkRequest request, String msgError) {
|
||||
LwM2mClient lwM2MClient = this.lwM2mClientContext.getClientByRegistrationId(registration.getId());
|
||||
if (request.getPath().toString().equals(FW_UPDATE_ID) && lwM2MClient.getFwUpdate() != null) {
|
||||
lwM2MClient.getFwUpdate().sendLogs(EXECUTE.name(), LOG_LW2M_ERROR, msgError);
|
||||
}
|
||||
if (request.getPath().toString().equals(SW_INSTALL_ID) && lwM2MClient.getSwUpdate() != null) {
|
||||
lwM2MClient.getSwUpdate().sendLogs(EXECUTE.name(), LOG_LW2M_ERROR, msgError);
|
||||
}
|
||||
}
|
||||
|
||||
private void afterObserveCancel(Registration registration, int observeCancelCnt, String observeCancelMsg, Lwm2mClientRpcRequest rpcRequest) {
|
||||
serviceImpl.sendLogsToThingsboard(observeCancelMsg, registration.getId());
|
||||
log.warn("[{}]", observeCancelMsg);
|
||||
if (rpcRequest != null) {
|
||||
rpcRequest.setInfoMsg(String.format("Count: %d", observeCancelCnt));
|
||||
serviceImpl.sentRpcRequest(rpcRequest, CONTENT.name(), null, LOG_LW2M_INFO);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -38,6 +38,7 @@ import org.eclipse.leshan.core.model.InvalidDDFFileException;
|
||||
import org.eclipse.leshan.core.model.ObjectModel;
|
||||
import org.eclipse.leshan.core.model.ResourceModel;
|
||||
import org.eclipse.leshan.core.node.codec.CodecException;
|
||||
import org.eclipse.leshan.core.request.ContentFormat;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.thingsboard.server.common.transport.TransportServiceCallback;
|
||||
import org.thingsboard.server.gen.transport.TransportProtos;
|
||||
@ -53,7 +54,6 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.thingsboard.server.gen.transport.TransportProtos.KeyValueType.BOOLEAN_V;
|
||||
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LOG_LW2M_TELEMETRY;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
@ -68,7 +68,7 @@ public class LwM2mTransportServerHelper {
|
||||
* send to Thingsboard Attribute || Telemetry
|
||||
*
|
||||
* @param msg - JsonObject: [{name: value}]
|
||||
* @return - dummy
|
||||
* @return - dummyWriteReplace {\"targetIdVer\":\"/19_1.0/0/0\",\"value\":0082}
|
||||
*/
|
||||
private <T> TransportServiceCallback<Void> getPubAckCallbackSendAttrTelemetry(final T msg) {
|
||||
return new TransportServiceCallback<>() {
|
||||
@ -135,16 +135,16 @@ public class LwM2mTransportServerHelper {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param logMsg - info about Logs
|
||||
* @param value - info about Logs
|
||||
* @return- KeyValueProto for telemetry (Logs)
|
||||
*/
|
||||
public List<TransportProtos.KeyValueProto> getKvLogyToThingsboard(String logMsg) {
|
||||
public List<TransportProtos.KeyValueProto> getKvStringtoThingsboard(String key, String value) {
|
||||
List<TransportProtos.KeyValueProto> result = new ArrayList<>();
|
||||
value = value.replaceAll("<", "").replaceAll(">", "");
|
||||
result.add(TransportProtos.KeyValueProto.newBuilder()
|
||||
.setKey(LOG_LW2M_TELEMETRY)
|
||||
.setKey(key)
|
||||
.setType(TransportProtos.KeyValueType.STRING_V)
|
||||
.setStringV(logMsg).build());
|
||||
.setStringV(value).build());
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -180,8 +180,7 @@ public class LwM2mTransportServerHelper {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param currentType -
|
||||
* @param currentType -
|
||||
* @param resourcePath -
|
||||
* @return
|
||||
*/
|
||||
@ -203,6 +202,28 @@ public class LwM2mTransportServerHelper {
|
||||
throw new CodecException("Invalid ResourceModel_Type for resource %s, got %s", resourcePath, currentType);
|
||||
}
|
||||
|
||||
public static ContentFormat convertResourceModelTypeToContentFormat(ResourceModel.Type type) {
|
||||
switch (type) {
|
||||
case BOOLEAN:
|
||||
case STRING:
|
||||
case TIME:
|
||||
case INTEGER:
|
||||
case FLOAT:
|
||||
return ContentFormat.TLV;
|
||||
case OPAQUE:
|
||||
return ContentFormat.OPAQUE;
|
||||
case OBJLNK:
|
||||
return ContentFormat.LINK;
|
||||
default:
|
||||
}
|
||||
throw new CodecException("Invalid ResourceModel_Type for %s ContentFormat.", type);
|
||||
}
|
||||
|
||||
public static ContentFormat getContentFormatByResourceModelType(ResourceModel resourceModel, ContentFormat contentFormat) {
|
||||
return contentFormat.equals(ContentFormat.TLV) ? convertResourceModelTypeToContentFormat(resourceModel.type) :
|
||||
contentFormat;
|
||||
}
|
||||
|
||||
public static Object getValueFromKvProto(TransportProtos.KeyValueProto kv) {
|
||||
switch (kv.getType()) {
|
||||
case BOOLEAN_V:
|
||||
|
||||
@ -104,7 +104,8 @@ public class LwM2mTransportUtil {
|
||||
|
||||
public static final long DEFAULT_TIMEOUT = 2 * 60 * 1000L; // 2min in ms
|
||||
|
||||
public static final String LOG_LW2M_TELEMETRY = "logLwm2m";
|
||||
public static final String
|
||||
LOG_LW2M_TELEMETRY = "logLwm2m";
|
||||
public static final String LOG_LW2M_INFO = "info";
|
||||
public static final String LOG_LW2M_ERROR = "error";
|
||||
public static final String LOG_LW2M_WARN = "warn";
|
||||
@ -208,8 +209,13 @@ public class LwM2mTransportUtil {
|
||||
DELETE(10, "Delete"),
|
||||
|
||||
// only for RPC
|
||||
READ_INFO_FW(11, "ReadInfoFirmware"),
|
||||
READ_INFO_SW(12, "ReadInfoSoftware");
|
||||
FW_READ_INFO(11, "FirmwareReadInfo"),
|
||||
FW_UPDATE(12, "FirmwareUpdate"),
|
||||
FW_UPDATE_URL(14, "FirmwareUpdateUrl"),
|
||||
SW_READ_INFO(15, "SoftwareReadInfo"),
|
||||
SW_UPDATE(16, "SoftwareUpdate"),
|
||||
SW_UPDATE_URL(17, "SoftwareUpdateUrl"),
|
||||
SW_UNINSTALL(18, "SoftwareUninstall");
|
||||
|
||||
public int code;
|
||||
public String type;
|
||||
@ -357,7 +363,7 @@ public class LwM2mTransportUtil {
|
||||
}
|
||||
|
||||
/**
|
||||
* Update State R
|
||||
* SW Update State R
|
||||
* 0: INITIAL Before downloading. (see 5.1.2.1)
|
||||
* 1: DOWNLOAD STARTED The downloading process has started and is on-going. (see 5.1.2.2)
|
||||
* 2: DOWNLOADED The package has been completely downloaded (see 5.1.2.3)
|
||||
@ -429,7 +435,7 @@ public class LwM2mTransportUtil {
|
||||
INITIAL(0, "Initial value", false),
|
||||
DOWNLOADING(1, "Downloading", false),
|
||||
SUCCESSFULLY_INSTALLED(2, "Software successfully installed", false),
|
||||
SUCCESSFULLY_INSTALLED_VERIFIED(3, "Successfully Downloaded and package integrity verified", false),
|
||||
SUCCESSFULLY_DOWNLOADED_VERIFIED(3, "Successfully Downloaded and package integrity verified", false),
|
||||
NOT_ENOUGH_STORAGE(50, "Not enough storage for the new software package", true),
|
||||
OUT_OFF_MEMORY(51, "Out of memory during downloading process", true),
|
||||
CONNECTION_LOST(52, "Connection lost during downloading process", false),
|
||||
@ -489,7 +495,7 @@ public class LwM2mTransportUtil {
|
||||
return DOWNLOADING;
|
||||
case SUCCESSFULLY_INSTALLED:
|
||||
return UPDATED;
|
||||
case SUCCESSFULLY_INSTALLED_VERIFIED:
|
||||
case SUCCESSFULLY_DOWNLOADED_VERIFIED:
|
||||
return VERIFIED;
|
||||
case NOT_ENOUGH_STORAGE:
|
||||
case OUT_OFF_MEMORY:
|
||||
@ -507,7 +513,9 @@ public class LwM2mTransportUtil {
|
||||
}
|
||||
|
||||
public static final String EVENT_AWAKE = "AWAKE";
|
||||
public static final String RESPONSE_REQUEST_CHANNEL = "RESP_REQ";
|
||||
public static final String RESPONSE_CHANNEL = "RESP";
|
||||
public static final String OBSERVE_CHANNEL = "OBSERVE";
|
||||
|
||||
public static boolean equalsResourceValue(Object valueOld, Object valueNew, ResourceModel.Type type, LwM2mPath
|
||||
resourcePath) throws CodecException {
|
||||
|
||||
@ -82,7 +82,7 @@ public class LwM2mVersionedModelProvider implements LwM2mModelProvider {
|
||||
if (objectModel != null)
|
||||
return objectModel.resources.get(resourceId);
|
||||
else
|
||||
log.warn("TbResources (Object model) with id [{}/0/{}] not found on the server", objectId, resourceId);
|
||||
log.trace("TbResources (Object model) with id [{}/0/{}] not found on the server", objectId, resourceId);
|
||||
return null;
|
||||
} catch (Exception e) {
|
||||
log.error("", e);
|
||||
|
||||
@ -64,7 +64,6 @@ public class LwM2MJsonAdaptor implements LwM2MTransportAdaptor {
|
||||
}
|
||||
return result.build();
|
||||
} catch (RuntimeException e) {
|
||||
log.warn("Failed to decode get attributes request", e);
|
||||
throw new AdaptorException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@ -18,7 +18,11 @@ package org.thingsboard.server.transport.lwm2m.server.client;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.eclipse.leshan.core.model.ObjectModel;
|
||||
import org.eclipse.leshan.core.model.ResourceModel;
|
||||
import org.eclipse.leshan.core.node.LwM2mMultipleResource;
|
||||
import org.eclipse.leshan.core.node.LwM2mObject;
|
||||
import org.eclipse.leshan.core.node.LwM2mObjectInstance;
|
||||
import org.eclipse.leshan.core.node.LwM2mPath;
|
||||
import org.eclipse.leshan.core.node.LwM2mResource;
|
||||
import org.eclipse.leshan.core.node.LwM2mSingleResource;
|
||||
@ -47,6 +51,8 @@ import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.eclipse.leshan.core.model.ResourceModel.Type.OPAQUE;
|
||||
import static org.eclipse.leshan.core.model.ResourceModel.Type.STRING;
|
||||
import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPARATOR_PATH;
|
||||
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.TRANSPORT_DEFAULT_LWM2M_VERSION;
|
||||
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.convertPathFromIdVerToObjectId;
|
||||
@ -192,6 +198,14 @@ public class LwM2mClient implements Cloneable {
|
||||
return null;
|
||||
}
|
||||
|
||||
public Object getResourceName (String pathRezIdVer, String pathRezId) {
|
||||
String pathRez = pathRezIdVer == null ? convertPathFromObjectIdToIdVer(pathRezId, this.registration) : pathRezIdVer;
|
||||
if (this.resources.get(pathRez) != null) {
|
||||
return this.resources.get(pathRez).getResourceModel().name;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public ResourceModel getResourceModel(String pathIdVer, LwM2mModelProvider modelProvider) {
|
||||
LwM2mPath pathIds = new LwM2mPath(convertPathFromIdVerToObjectId(pathIdVer));
|
||||
String verSupportedObject = registration.getSupportedObject().get(pathIds.getObjectId());
|
||||
@ -200,8 +214,55 @@ public class LwM2mClient implements Cloneable {
|
||||
.getResourceModel(pathIds.getObjectId(), pathIds.getResourceId()) : null;
|
||||
}
|
||||
|
||||
public Collection<LwM2mResource> getNewOneResourceForInstance(String pathRezIdVer, Object params, LwM2mModelProvider modelProvider,
|
||||
LwM2mValueConverterImpl converter) {
|
||||
public ObjectModel getObjectModel(String pathIdVer, LwM2mModelProvider modelProvider) {
|
||||
LwM2mPath pathIds = new LwM2mPath(convertPathFromIdVerToObjectId(pathIdVer));
|
||||
String verSupportedObject = registration.getSupportedObject().get(pathIds.getObjectId());
|
||||
String verRez = getVerFromPathIdVerOrId(pathIdVer);
|
||||
return verRez == null || verRez.equals(verSupportedObject) ? modelProvider.getObjectModel(registration)
|
||||
.getObjectModel(pathIds.getObjectId()) : null;
|
||||
}
|
||||
|
||||
public String objectToString (LwM2mObject lwM2mObject, LwM2mValueConverterImpl converter, String pathIdVer) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append("LwM2mObject [id=").append(lwM2mObject.getId()).append(", instances={");
|
||||
lwM2mObject.getInstances().forEach((instId, inst) -> {
|
||||
builder.append(instId).append("=").append(this.instanceToString(inst, converter, pathIdVer)).append(", ");
|
||||
});
|
||||
int startInd = builder.lastIndexOf(", ");
|
||||
if (startInd > 0) {
|
||||
builder.delete(startInd, startInd + 2);
|
||||
}
|
||||
builder.append("}]");
|
||||
return builder.toString();
|
||||
}
|
||||
public String instanceToString (LwM2mObjectInstance objectInstance, LwM2mValueConverterImpl converter, String pathIdVer) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append("LwM2mObjectInstance [id=").append(objectInstance.getId()).append(", resources={");
|
||||
objectInstance.getResources().forEach((resId, res) -> {
|
||||
builder.append(resId).append("=").append(this.resourceToString (res, converter, pathIdVer)).append(", ");
|
||||
});
|
||||
int startInd = builder.lastIndexOf(", ");
|
||||
if (startInd > 0) {
|
||||
builder.delete(startInd, startInd + 2);
|
||||
}
|
||||
builder.append("}]");
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
public String resourceToString (LwM2mResource lwM2mResource, LwM2mValueConverterImpl converter, String pathIdVer) {
|
||||
if (!OPAQUE.equals(lwM2mResource.getType())) {
|
||||
return lwM2mResource.isMultiInstances() ? ((LwM2mMultipleResource) lwM2mResource).toString() :
|
||||
((LwM2mSingleResource) lwM2mResource).toString();
|
||||
}
|
||||
else {
|
||||
return String.format("LwM2mSingleResource [id=%s, value=%s, type=%s]", lwM2mResource.getId(),
|
||||
converter.convertValue(lwM2mResource.getValue(),
|
||||
OPAQUE, STRING, new LwM2mPath(convertPathFromIdVerToObjectId(pathIdVer))), lwM2mResource.getType().name());
|
||||
}
|
||||
}
|
||||
|
||||
public Collection<LwM2mResource> getNewResourceForInstance(String pathRezIdVer, Object params, LwM2mModelProvider modelProvider,
|
||||
LwM2mValueConverterImpl converter) {
|
||||
LwM2mPath pathIds = new LwM2mPath(convertPathFromIdVerToObjectId(pathRezIdVer));
|
||||
Collection<LwM2mResource> resources = ConcurrentHashMap.newKeySet();
|
||||
Map<Integer, ResourceModel> resourceModels = modelProvider.getObjectModel(registration)
|
||||
@ -215,8 +276,8 @@ public class LwM2mClient implements Cloneable {
|
||||
return resources;
|
||||
}
|
||||
|
||||
public Collection<LwM2mResource> getNewManyResourcesForInstance(String pathRezIdVer, Object params, LwM2mModelProvider modelProvider,
|
||||
LwM2mValueConverterImpl converter) {
|
||||
public Collection<LwM2mResource> getNewResourcesForInstance(String pathRezIdVer, Object params, LwM2mModelProvider modelProvider,
|
||||
LwM2mValueConverterImpl converter) {
|
||||
LwM2mPath pathIds = new LwM2mPath(convertPathFromIdVerToObjectId(pathRezIdVer));
|
||||
Collection<LwM2mResource> resources = ConcurrentHashMap.newKeySet();
|
||||
Map<Integer, ResourceModel> resourceModels = modelProvider.getObjectModel(registration)
|
||||
|
||||
@ -34,6 +34,7 @@ import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import static org.thingsboard.server.common.data.firmware.FirmwareKey.STATE;
|
||||
import static org.thingsboard.server.common.data.firmware.FirmwareType.FIRMWARE;
|
||||
import static org.thingsboard.server.common.data.firmware.FirmwareType.SOFTWARE;
|
||||
import static org.thingsboard.server.common.data.firmware.FirmwareUpdateStatus.UPDATING;
|
||||
import static org.thingsboard.server.common.data.firmware.FirmwareUtil.getAttributeKey;
|
||||
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.FW_NAME_ID;
|
||||
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.FW_PACKAGE_ID;
|
||||
@ -42,10 +43,10 @@ import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.F
|
||||
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.FW_UPDATE;
|
||||
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.FW_UPDATE_ID;
|
||||
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.FW_VER_ID;
|
||||
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LOG_LW2M_ERROR;
|
||||
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LOG_LW2M_INFO;
|
||||
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.EXECUTE;
|
||||
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.OBSERVE;
|
||||
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.READ;
|
||||
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.LwM2mTypeOper.WRITE_REPLACE;
|
||||
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.SW_INSTALL_ID;
|
||||
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.SW_NAME_ID;
|
||||
@ -56,6 +57,7 @@ import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.S
|
||||
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.SW_UPDATE_STATE_ID;
|
||||
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.SW_VER_ID;
|
||||
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.convertPathFromObjectIdToIdVer;
|
||||
import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportUtil.splitCamelCaseString;
|
||||
|
||||
@Slf4j
|
||||
public class LwM2mFwSwUpdate {
|
||||
@ -111,7 +113,7 @@ public class LwM2mFwSwUpdate {
|
||||
}
|
||||
|
||||
private void initPathId() {
|
||||
if (this.type.equals(FIRMWARE)) {
|
||||
if (FIRMWARE.equals(this.type) ) {
|
||||
this.pathPackageId = FW_PACKAGE_ID;
|
||||
this.pathStateId = FW_STATE_ID;
|
||||
this.pathResultId = FW_RESULT_ID;
|
||||
@ -119,7 +121,7 @@ public class LwM2mFwSwUpdate {
|
||||
this.pathVerId = FW_VER_ID;
|
||||
this.pathInstallId = FW_UPDATE_ID;
|
||||
this.wUpdate = FW_UPDATE;
|
||||
} else if (this.type.equals(SOFTWARE)) {
|
||||
} else if (SOFTWARE.equals(this.type) ) {
|
||||
this.pathPackageId = SW_PACKAGE_ID;
|
||||
this.pathStateId = SW_UPDATE_STATE_ID;
|
||||
this.pathResultId = SW_RESULT_ID;
|
||||
@ -142,25 +144,20 @@ public class LwM2mFwSwUpdate {
|
||||
boolean conditionalStart = this.type.equals(FIRMWARE) ? this.conditionalFwUpdateStart() :
|
||||
this.conditionalSwUpdateStart();
|
||||
if (conditionalStart) {
|
||||
this.stateUpdate = FirmwareUpdateStatus.DOWNLOADING.name();
|
||||
this.observeStateUpdate();
|
||||
this.writeFwSwWare();
|
||||
this.sendLogs(WRITE_REPLACE.name());
|
||||
}
|
||||
} else {
|
||||
boolean conditionalExecute = this.type.equals(FIRMWARE) ? conditionalFwUpdateExecute() :
|
||||
conditionalSwUpdateExecute();
|
||||
if (conditionalExecute) {
|
||||
this.stateUpdate = FirmwareUpdateStatus.DOWNLOADED.name();
|
||||
this.observeStateUpdate();
|
||||
this.executeFwSwWare();
|
||||
this.sendLogs(EXECUTE.name());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send FsSw to Lwm2mClient:
|
||||
* before operation Write: fw_state = DOWNLOADING
|
||||
*/
|
||||
private void writeFwSwWare() {
|
||||
this.stateUpdate = FirmwareUpdateStatus.DOWNLOADING.name();
|
||||
// this.observeStateUpdate();
|
||||
this.sendLogs(WRITE_REPLACE.name(), LOG_LW2M_INFO, null);
|
||||
int chunkSize = 0;
|
||||
int chunk = 0;
|
||||
byte[] firmwareChunk = this.serviceImpl.firmwareDataCache.get(this.currentId.toString(), chunkSize, chunk);
|
||||
@ -169,124 +166,155 @@ public class LwM2mFwSwUpdate {
|
||||
firmwareChunk, this.serviceImpl.config.getTimeout(), null);
|
||||
}
|
||||
|
||||
public void sendLogs(String typeOper) {
|
||||
public void sendLogs(String typeOper, String typeInfo, String msgError) {
|
||||
this.sendSateOnThingsboard();
|
||||
String msg = String.format("%s: %s, %s, pkgVer: %s: pkgName - %s.",
|
||||
LOG_LW2M_INFO, this.wUpdate, typeOper, this.currentVersion, this.currentTitle);
|
||||
String msg = String.format("%s: %s, %s, pkgVer: %s: pkgName - %s state - %s.",
|
||||
typeInfo, this.wUpdate, typeOper, this.currentVersion, this.currentTitle, this.stateUpdate);
|
||||
if (LOG_LW2M_ERROR.equals(typeInfo)) {
|
||||
msg = String.format("%s Error: %s", msg, msgError);
|
||||
}
|
||||
serviceImpl.sendLogsToThingsboard(msg, lwM2MClient.getRegistration().getId());
|
||||
log.warn("{} state: [{}]", msg, this.stateUpdate);
|
||||
}
|
||||
|
||||
public void executeFwSwWare() {
|
||||
this.serviceImpl.lwM2mTransportRequest.sendAllRequest(this.lwM2MClient.getRegistration(), this.pathInstallId, EXECUTE, ContentFormat.TLV.getName(),
|
||||
null, 0, null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* FW: start
|
||||
* Проверяем состояние State (5.3) и Update Result (5.5).
|
||||
* 1. Если Update Result > 1 (some errors) - Это означает что пред. апдейт не прошел.
|
||||
* - Запускаем апдейт в независимости от состяния прошивки и ее версии.
|
||||
* 2. Если Update Result = 1 && State = 0 - Это означает что пред. апдейт прошел.
|
||||
* 3. Если Update Result = 0 && State = 0 && Ver = "" - Это означает что апдейта еще не было.
|
||||
* After inspection Update Result
|
||||
* fw_state/sw_state = UPDATING
|
||||
* send execute
|
||||
*/
|
||||
public void executeFwSwWare() {
|
||||
this.setStateUpdate(UPDATING.name());
|
||||
this.sendLogs(EXECUTE.name(), LOG_LW2M_INFO, null);
|
||||
this.serviceImpl.lwM2mTransportRequest.sendAllRequest(this.lwM2MClient.getRegistration(), this.pathInstallId, EXECUTE, ContentFormat.TLV.getName(),
|
||||
null, 0, null);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Firmware start:
|
||||
* -- Если Update Result -errors (более 1) - Это означает что пред. апдейт не прошел.
|
||||
* - Запускаем апдейт в независимости от состяния прошивки и ее версии.
|
||||
* -- Если Update Result - не errors (менее или равно 1) и ver не пустой - Это означает что пред. апдейт прошел.
|
||||
* -- Если Update Result - не errors и ver пустой - Это означает что апдейта еще не было.
|
||||
* - Проверяем поменялась ли версия и запускаем новый апдейт.
|
||||
* Новый апдейт:
|
||||
* 1. Запись новой прошивки в Lwm2mClient
|
||||
* 2. Мониторим итог зиписи:
|
||||
* 2.1 State = 2 "Downloaded" и Update Result = 0 "INITIAL" стартуем Update 5.2 (Execute):
|
||||
* Мониторим состояние Update Result и State и мапим его на наш enum (DOWNLOADING, DOWNLOADED, VERIFIED, UPDATING, UPDATED, FAILED)
|
||||
* + пишем лог (в телеметрию отдельным полем error) с подробным статусом.
|
||||
*
|
||||
* @valerii.sosliuk Вопрос к клиенту - как будем реагировать на Failed update? Когда повторять операцию?
|
||||
* - На update reg?
|
||||
* - Или клиент должен послать комканду на рестарт девайса?
|
||||
* - или переодически?
|
||||
* отправили прошивку мониторим:
|
||||
* -- Observe "Update Result" id=5 && "State" id=3
|
||||
* --- "Update Result" id=5 value must be = 0
|
||||
* --- "State" id=3 value must be > 0
|
||||
* --- to telemetry - DOWNLOADING
|
||||
* "Update Result" id=5 value change > 1 "Firmware updated not successfully" отправили прошивку: telemetry - FAILED
|
||||
* "Update Result" id=5 value change ==1 "State" id=3 value == 0 "Firmware updated successfully" отправили прошивку: telemetry - UPDATED
|
||||
*/
|
||||
private boolean conditionalFwUpdateStart() {
|
||||
Long stateFw = (Long) this.lwM2MClient.getResourceValue(null, this.pathStateId);
|
||||
Long updateResultFw = (Long) this.lwM2MClient.getResourceValue(null, this.pathResultId);
|
||||
String pkgName = (String) this.lwM2MClient.getResourceValue(null, this.pathNameId);
|
||||
// #1/#2
|
||||
return updateResultFw > LwM2mTransportUtil.UpdateResultFw.UPDATE_SUCCESSFULLY.code ||
|
||||
(
|
||||
(
|
||||
(stateFw == LwM2mTransportUtil.StateFw.IDLE.code && updateResultFw == LwM2mTransportUtil.UpdateResultFw.UPDATE_SUCCESSFULLY.code) ||
|
||||
(stateFw == LwM2mTransportUtil.StateFw.IDLE.code && updateResultFw == LwM2mTransportUtil.UpdateResultFw.INITIAL.code
|
||||
&& StringUtils.trimToEmpty(pkgName).isEmpty())
|
||||
(updateResultFw <= LwM2mTransportUtil.UpdateResultFw.UPDATE_SUCCESSFULLY.code
|
||||
) &&
|
||||
(
|
||||
(this.currentVersion != null && !this.currentVersion.equals(this.lwM2MClient.getResourceValue(null, this.pathVerId))) ||
|
||||
(this.currentTitle != null && !this.currentTitle.equals(this.lwM2MClient.getResourceValue(null, this.pathNameId)))
|
||||
)
|
||||
);
|
||||
// if (condFwUpdateStart) {
|
||||
// this.sendSateOnThingsboard(stateFw, updateResultFw, pkgName);
|
||||
// }
|
||||
// return condFwUpdateStart;
|
||||
}
|
||||
|
||||
private boolean conditionalFwUpdateExecute() {
|
||||
Long state = (Long) this.lwM2MClient.getResourceValue(null, this.pathStateId);
|
||||
|
||||
/**
|
||||
* Before operation Execute inspection Update Result :
|
||||
* 0 - Initial value
|
||||
*/
|
||||
public boolean conditionalFwExecuteStart() {
|
||||
Long updateResult = (Long) this.lwM2MClient.getResourceValue(null, this.pathResultId);
|
||||
// #1/#2
|
||||
return updateResult == LwM2mTransportUtil.UpdateResultFw.INITIAL.code && state == LwM2mTransportUtil.StateFw.DOWNLOADED.code;
|
||||
return LwM2mTransportUtil.UpdateResultFw.INITIAL.code == updateResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* FW: start
|
||||
* Проверяем состояние Update_State (9.7) и Update_Result (9.9).
|
||||
* 1. Если Update Result > 3 (some errors) - Это означает что пред. апдейт не прошел.
|
||||
* - Запускаем апдейт в независимости от состяния прошивки и ее версии.
|
||||
* 2. Если Update Result = 2 && Update State = 4 - Это означает что пред. апдейт прошел
|
||||
* 3. Если Update Result = 0 && Update State = 0 && Ver = "" - Это означает что апдейта еще не было.
|
||||
* 4. Если Update Result = 0 && Update State = 0 - Это означает что пред. апдейт UnInstall
|
||||
* After operation Execute success inspection Update Result :
|
||||
* 1 - "Firmware updated successfully"
|
||||
*/
|
||||
public boolean conditionalFwExecuteAfterSuccess() {
|
||||
Long updateResult = (Long) this.lwM2MClient.getResourceValue(null, this.pathResultId);
|
||||
return LwM2mTransportUtil.UpdateResultFw.UPDATE_SUCCESSFULLY.code == updateResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* After operation Execute success inspection Update Result :
|
||||
* > 1 error: "Firmware updated successfully"
|
||||
*/
|
||||
public boolean conditionalFwExecuteAfterError() {
|
||||
Long updateResult = (Long) this.lwM2MClient.getResourceValue(null, this.pathResultId);
|
||||
return LwM2mTransportUtil.UpdateResultFw.UPDATE_SUCCESSFULLY.code < updateResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* Software start
|
||||
* -- Если Update Result -errors (равно и более 50) - Это означает что пред. апдейт не прошел.
|
||||
* * - Запускаем апдейт в независимости от состяния прошивки и ее версии.
|
||||
* -- Если Update Result - не errors (менее 50) и ver не пустой - Это означает что пред. апдейт прошел.
|
||||
* -- Если Update Result - не errors и ver пустой - Это означает что апдейта еще не было или пред. апдейт UnInstall
|
||||
* -- Если Update Result - не errors и ver не пустой - Это означает что пред. апдейт UnInstall
|
||||
* - Проверяем поменялась ли версия и запускаем новый апдейт.
|
||||
* Новый апдейт:
|
||||
* 1. Запись новой прошивки в Lwm2mClient
|
||||
* 2. Мониторим итог зиписи:
|
||||
* 2.1 Update State = 3 "DELIVERED" стартуем Install 9.4 (Execute):
|
||||
* Мониторим состояние Update Result и State и мапим его на наш enum (DOWNLOADING, DOWNLOADED, VERIFIED, UPDATING, UPDATED, FAILED)
|
||||
* + пишем лог (в телеметрию отдельным полем error) с подробным статусом.
|
||||
*/
|
||||
private boolean conditionalSwUpdateStart() {
|
||||
Long updateState = (Long) this.lwM2MClient.getResourceValue(null, this.pathStateId);
|
||||
Long updateResult = (Long) this.lwM2MClient.getResourceValue(null, this.pathResultId);
|
||||
String pkgName = (String) this.lwM2MClient.getResourceValue(null, this.pathNameId);
|
||||
Long updateResultSw = (Long) this.lwM2MClient.getResourceValue(null, this.pathResultId);
|
||||
// #1/#2
|
||||
return updateResult > LwM2mTransportUtil.UpdateResultSw.SUCCESSFULLY_INSTALLED_VERIFIED.code ||
|
||||
return updateResultSw >= LwM2mTransportUtil.UpdateResultSw.NOT_ENOUGH_STORAGE.code ||
|
||||
(
|
||||
(
|
||||
(
|
||||
(
|
||||
(updateState == LwM2mTransportUtil.UpdateStateSw.INSTALLED.code && updateResult == LwM2mTransportUtil.UpdateResultSw.SUCCESSFULLY_INSTALLED.code) ||
|
||||
(updateState == LwM2mTransportUtil.UpdateStateSw.INITIAL.code && updateResult == LwM2mTransportUtil.UpdateResultSw.INITIAL.code &&
|
||||
StringUtils.trimToEmpty(pkgName).isEmpty())
|
||||
)
|
||||
) &&
|
||||
(updateState == LwM2mTransportUtil.UpdateStateSw.INITIAL.code && updateResult == LwM2mTransportUtil.UpdateResultSw.INITIAL.code)
|
||||
(updateResultSw <= LwM2mTransportUtil.UpdateResultSw.NOT_ENOUGH_STORAGE.code
|
||||
) &&
|
||||
(
|
||||
(this.currentVersion != null && !this.currentVersion.equals(this.lwM2MClient.getResourceValue(null, this.pathVerId))) ||
|
||||
(this.currentTitle != null && !this.currentTitle.equals(this.lwM2MClient.getResourceValue(null, this.pathNameId)))
|
||||
)
|
||||
);
|
||||
// return condSwUpdateStart;
|
||||
}
|
||||
|
||||
private boolean conditionalSwUpdateExecute() {
|
||||
Long updateState = (Long) this.lwM2MClient.getResourceValue(null, this.pathStateId);
|
||||
/**
|
||||
* Before operation Execute inspection Update Result :
|
||||
* 3 - Successfully Downloaded and package integrity verified
|
||||
*/
|
||||
public boolean conditionalSwUpdateExecute() {
|
||||
Long updateResult = (Long) this.lwM2MClient.getResourceValue(null, this.pathResultId);
|
||||
// #1/#2
|
||||
return (updateResult == LwM2mTransportUtil.UpdateResultSw.INITIAL.code || updateResult == LwM2mTransportUtil.UpdateResultSw.SUCCESSFULLY_INSTALLED_VERIFIED.code) &&
|
||||
updateState == LwM2mTransportUtil.UpdateStateSw.DELIVERED.code;
|
||||
return LwM2mTransportUtil.UpdateResultSw.SUCCESSFULLY_DOWNLOADED_VERIFIED.code == updateResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* After finish operation Execute (success):
|
||||
* -- inspection Update Result:
|
||||
* ---- FW если Update Result == 1 ("Firmware updated successfully") или SW если Update Result == 2 ("Software successfully installed.")
|
||||
* -- fw_state/sw_state = UPDATED
|
||||
*
|
||||
* After finish operation Execute (error):
|
||||
* -- inspection updateResult and send to thingsboard info about error
|
||||
* --- send to telemetry ( key - this is name Update Result in model) (
|
||||
* -- fw_state/sw_state = FAILED
|
||||
*/
|
||||
public void finishFwSwUpdate(boolean success) {
|
||||
Long updateResult = (Long) this.lwM2MClient.getResourceValue(null, this.pathResultId);
|
||||
String value = FIRMWARE.equals(this.type) ? LwM2mTransportUtil.UpdateResultFw.fromUpdateResultFwByCode(updateResult.intValue()).type :
|
||||
LwM2mTransportUtil.UpdateResultSw.fromUpdateResultSwByCode(updateResult.intValue()).type;
|
||||
String key = splitCamelCaseString((String) this.lwM2MClient.getResourceName (null, this.pathResultId));
|
||||
if (success) {
|
||||
this.stateUpdate = FirmwareUpdateStatus.UPDATED.name();
|
||||
this.sendLogs(EXECUTE.name(), LOG_LW2M_INFO, null);
|
||||
}
|
||||
else {
|
||||
this.stateUpdate = FirmwareUpdateStatus.FAILED.name();
|
||||
this.sendLogs(EXECUTE.name(), LOG_LW2M_ERROR, value);
|
||||
}
|
||||
this.serviceImpl.helper.sendParametersOnThingsboardTelemetry(
|
||||
this.serviceImpl.helper.getKvStringtoThingsboard(key, value), this.lwM2MClient.getSession());
|
||||
}
|
||||
|
||||
/**
|
||||
* After operation Execute success inspection Update Result :
|
||||
* 2 - "Software successfully installed."
|
||||
*/
|
||||
public boolean conditionalSwExecuteAfterSuccess() {
|
||||
Long updateResult = (Long) this.lwM2MClient.getResourceValue(null, this.pathResultId);
|
||||
return LwM2mTransportUtil.UpdateResultSw.SUCCESSFULLY_INSTALLED.code == updateResult;
|
||||
}
|
||||
/**
|
||||
* After operation Execute success inspection Update Result :
|
||||
* >= 50 - error "NOT_ENOUGH_STORAGE"
|
||||
*/
|
||||
public boolean conditionalSwExecuteAfterError() {
|
||||
Long updateResult = (Long) this.lwM2MClient.getResourceValue(null, this.pathResultId);
|
||||
return LwM2mTransportUtil.UpdateResultSw.NOT_ENOUGH_STORAGE.code <= updateResult;
|
||||
}
|
||||
|
||||
private void observeStateUpdate() {
|
||||
@ -309,25 +337,21 @@ public class LwM2mFwSwUpdate {
|
||||
}
|
||||
}
|
||||
|
||||
public void sendReadInfo(DefaultLwM2MTransportMsgHandler serviceImpl) {
|
||||
public void sendReadObserveInfo(DefaultLwM2MTransportMsgHandler serviceImpl) {
|
||||
this.infoFwSwUpdate = true;
|
||||
this.serviceImpl = this.serviceImpl == null ? serviceImpl : this.serviceImpl;
|
||||
this.pendingInfoRequestsStart.add(convertPathFromObjectIdToIdVer(
|
||||
this.pathVerId, this.lwM2MClient.getRegistration()));
|
||||
this.pendingInfoRequestsStart.add(convertPathFromObjectIdToIdVer(
|
||||
this.pathNameId, this.lwM2MClient.getRegistration()));
|
||||
this.sendReadInfoForWrite();
|
||||
}
|
||||
|
||||
public void sendReadInfoForWrite() {
|
||||
|
||||
this.infoFwSwUpdate = true;
|
||||
this.pendingInfoRequestsStart.add(convertPathFromObjectIdToIdVer(
|
||||
this.pathStateId, this.lwM2MClient.getRegistration()));
|
||||
this.pendingInfoRequestsStart.add(convertPathFromObjectIdToIdVer(
|
||||
this.pathResultId, this.lwM2MClient.getRegistration()));
|
||||
this.pendingInfoRequestsStart.forEach(pathIdVer -> {
|
||||
this.serviceImpl.lwM2mTransportRequest.sendAllRequest(this.lwM2MClient.getRegistration(), pathIdVer, READ, ContentFormat.TLV.getName(),
|
||||
this.serviceImpl.lwM2mTransportRequest.sendAllRequest(this.lwM2MClient.getRegistration(), pathIdVer, OBSERVE, ContentFormat.TLV.getName(),
|
||||
null, 0, null);
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -70,7 +70,7 @@ public class TbLwM2mSecurityStore implements EditableSecurityStore {
|
||||
add(securityInfo);
|
||||
}
|
||||
} catch (NonUniqueSecurityInfoException e) {
|
||||
log.warn("Failed to add security info: {}", securityInfo, e);
|
||||
log.trace("Failed to add security info: {}", securityInfo, e);
|
||||
}
|
||||
}
|
||||
return securityInfo;
|
||||
@ -86,7 +86,7 @@ public class TbLwM2mSecurityStore implements EditableSecurityStore {
|
||||
add(securityInfo);
|
||||
}
|
||||
} catch (NonUniqueSecurityInfoException e) {
|
||||
log.warn("Failed to add security info: {}", securityInfo, e);
|
||||
log.trace("Failed to add security info: {}", securityInfo, e);
|
||||
}
|
||||
}
|
||||
return securityInfo;
|
||||
|
||||
@ -121,9 +121,11 @@ public class LwM2mValueConverterImpl implements LwM2mValueConverter {
|
||||
/** let's assume we received an ISO 8601 format date */
|
||||
try {
|
||||
return new Date(Long.decode(value.toString()));
|
||||
// DatatypeFactory datatypeFactory = DatatypeFactory.newInstance();
|
||||
// XMLGregorianCalendar cal = datatypeFactory.newXMLGregorianCalendar((String) value);
|
||||
// return cal.toGregorianCalendar().getTime();
|
||||
/**
|
||||
DatatypeFactory datatypeFactory = DatatypeFactory.newInstance();
|
||||
XMLGregorianCalendar cal = datatypeFactory.newXMLGregorianCalendar((String) value);
|
||||
return cal.toGregorianCalendar().getTime();
|
||||
**/
|
||||
} catch (IllegalArgumentException e) {
|
||||
log.debug("Unable to convert string to date", e);
|
||||
throw new CodecException("Unable to convert string (%s) to date for resource %s", value,
|
||||
|
||||
@ -117,7 +117,6 @@ public final class DeviceProfileEntity extends BaseSqlEntity<DeviceProfile> impl
|
||||
this.setCreatedTime(deviceProfile.getCreatedTime());
|
||||
this.name = deviceProfile.getName();
|
||||
this.type = deviceProfile.getType();
|
||||
this.image = deviceProfile.getImage();
|
||||
this.transportType = deviceProfile.getTransportType();
|
||||
this.provisionType = deviceProfile.getProvisionType();
|
||||
this.description = deviceProfile.getDescription();
|
||||
@ -126,16 +125,13 @@ public final class DeviceProfileEntity extends BaseSqlEntity<DeviceProfile> impl
|
||||
if (deviceProfile.getDefaultRuleChainId() != null) {
|
||||
this.defaultRuleChainId = deviceProfile.getDefaultRuleChainId().getId();
|
||||
}
|
||||
if (deviceProfile.getDefaultDashboardId() != null) {
|
||||
this.defaultDashboardId = deviceProfile.getDefaultDashboardId().getId();
|
||||
}
|
||||
this.defaultQueueName = deviceProfile.getDefaultQueueName();
|
||||
this.provisionDeviceKey = deviceProfile.getProvisionDeviceKey();
|
||||
if (deviceProfile.getFirmwareId() != null) {
|
||||
this.firmwareId = deviceProfile.getFirmwareId().getId();
|
||||
}
|
||||
if (deviceProfile.getSoftwareId() != null) {
|
||||
this.firmwareId = deviceProfile.getSoftwareId().getId();
|
||||
this.softwareId = deviceProfile.getSoftwareId().getId();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user