Browse Source

Revert "[3.2.1] Develop/lwm2m (#3547)"

This reverts commit df6151f5ae.
pull/3832/head
Andrew Shvayka 6 years ago
parent
commit
24ccd2a2b5
  1. 4
      application/pom.xml
  2. 2
      application/src/main/java/org/thingsboard/server/actors/device/DeviceActor.java
  3. 35
      application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java
  4. 4
      application/src/main/java/org/thingsboard/server/controller/BaseController.java
  5. 5
      application/src/main/java/org/thingsboard/server/controller/DeviceController.java
  6. 75
      application/src/main/java/org/thingsboard/server/controller/DeviceLwm2mController.java
  7. 256
      application/src/main/java/org/thingsboard/server/service/lwm2m/LwM2MModelsRepository.java
  8. 4
      application/src/main/java/org/thingsboard/server/service/security/device/DefaultDeviceAuthService.java
  9. 1
      application/src/main/java/org/thingsboard/server/service/telemetry/DefaultTelemetrySubscriptionService.java
  10. 44
      application/src/main/java/org/thingsboard/server/service/transport/DefaultTransportApiService.java
  11. 7
      application/src/main/resources/banner.txt
  12. 72
      application/src/main/resources/thingsboard.yml
  13. 25
      common/data/src/main/java/org/thingsboard/server/common/data/lwm2m/LwM2mInstance.java
  14. 27
      common/data/src/main/java/org/thingsboard/server/common/data/lwm2m/LwM2mObject.java
  15. 63
      common/data/src/main/java/org/thingsboard/server/common/data/lwm2m/LwM2mResource.java
  16. 34
      common/data/src/main/java/org/thingsboard/server/common/data/lwm2m/ServerSecurityConfig.java
  17. 4
      common/data/src/main/java/org/thingsboard/server/common/data/security/DeviceCredentialsType.java
  18. 46
      common/queue/src/main/proto/queue.proto
  19. 1
      common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/CoapTransportContext.java
  20. 66
      common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/CoapTransportResource.java
  21. 11
      common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/CoapTransportService.java
  22. 1
      common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/adaptors/JsonCoapAdaptor.java
  23. 21
      common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/client/DeviceEmulator.java
  24. 1
      common/transport/http/src/main/java/org/thingsboard/server/transport/http/DeviceApiController.java
  25. 123
      common/transport/lwm2m/pom.xml
  26. 101
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/LwM2MTransportBootstrapServerConfiguration.java
  27. 70
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/LwM2MTransportBootstrapServerInitializer.java
  28. 60
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/LwM2MTransportContextBootstrap.java
  29. 102
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/secure/LwM2MBootstrapConfig.java
  30. 181
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/secure/LwM2MBootstrapSecurityStore.java
  31. 33
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/secure/LwM2MBootstrapServers.java
  32. 71
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/secure/LwM2MInMemoryBootstrapConfigStore.java
  33. 65
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/secure/LwM2MServerBootstrap.java
  34. 205
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/secure/LwM2MSetSecurityStoreBootstrap.java
  35. 66
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/secure/LwM2mDefaultBootstrapSessionManager.java
  36. 121
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/LWM2MGenerationPSkRPkECC.java
  37. 170
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/LwM2MGetSecurityInfo.java
  38. 58
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/LwM2MSecurityMode.java
  39. 84
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/LwM2mRPkCredentials.java
  40. 40
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/ReadResultSecurityStore.java
  41. 88
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2MSessionMsgListener.java
  42. 60
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2MTransportContextServer.java
  43. 333
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2MTransportHandler.java
  44. 335
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2MTransportRequest.java
  45. 102
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2MTransportServerConfiguration.java
  46. 72
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2MTransportServerInitializer.java
  47. 999
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2MTransportService.java
  48. 111
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mServerListener.java
  49. 38
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/ResultIds.java
  50. 49
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/adaptors/LwM2MJsonAdaptor.java
  51. 27
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/adaptors/LwM2MTransportAdaptor.java
  52. 47
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/AttrTelemetryObserveValue.java
  53. 107
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2MClient.java
  54. 41
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/ModelObject.java
  55. 26
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/ResourceValue.java
  56. 32
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/ResultsAnalyzerParameters.java
  57. 234
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/secure/LwM2MSetSecurityStoreServer.java
  58. 212
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/secure/LwM2mInMemorySecurityStore.java
  59. 146
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/utils/LwM2mValueConverterImpl.java
  60. 29
      common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/utils/TypeServer.java
  61. BIN
      common/transport/lwm2m/src/main/resources/credentials/serverKeyStore.jks
  62. 208
      common/transport/lwm2m/src/main/resources/credentials/shell/lwM2M_credentials.sh
  63. 58
      common/transport/lwm2m/src/main/resources/credentials/shell/lwM2M_keygen.properties
  64. 81
      common/transport/lwm2m/src/main/resources/models/10241.xml
  65. 659
      common/transport/lwm2m/src/main/resources/models/10242.xml
  66. 263
      common/transport/lwm2m/src/main/resources/models/10243.xml
  67. 301
      common/transport/lwm2m/src/main/resources/models/10244.xml
  68. 217
      common/transport/lwm2m/src/main/resources/models/10245.xml
  69. 108
      common/transport/lwm2m/src/main/resources/models/10246.xml
  70. 98
      common/transport/lwm2m/src/main/resources/models/10247.xml
  71. 78
      common/transport/lwm2m/src/main/resources/models/10248.xml
  72. 138
      common/transport/lwm2m/src/main/resources/models/10249.xml
  73. 70
      common/transport/lwm2m/src/main/resources/models/10250.xml
  74. 96
      common/transport/lwm2m/src/main/resources/models/10251.xml
  75. 229
      common/transport/lwm2m/src/main/resources/models/10252.xml
  76. 72
      common/transport/lwm2m/src/main/resources/models/10253.xml
  77. 119
      common/transport/lwm2m/src/main/resources/models/10254.xml
  78. 165
      common/transport/lwm2m/src/main/resources/models/10255.xml
  79. 117
      common/transport/lwm2m/src/main/resources/models/10256.xml
  80. 275
      common/transport/lwm2m/src/main/resources/models/10257.xml
  81. 89
      common/transport/lwm2m/src/main/resources/models/10258.xml
  82. 115
      common/transport/lwm2m/src/main/resources/models/10259.xml
  83. 95
      common/transport/lwm2m/src/main/resources/models/10260-2_0.xml
  84. 87
      common/transport/lwm2m/src/main/resources/models/10262.xml
  85. 90
      common/transport/lwm2m/src/main/resources/models/10263.xml
  86. 117
      common/transport/lwm2m/src/main/resources/models/10264.xml
  87. 136
      common/transport/lwm2m/src/main/resources/models/10265.xml
  88. 244
      common/transport/lwm2m/src/main/resources/models/10266.xml
  89. 244
      common/transport/lwm2m/src/main/resources/models/10267.xml
  90. 244
      common/transport/lwm2m/src/main/resources/models/10268.xml
  91. 244
      common/transport/lwm2m/src/main/resources/models/10269.xml
  92. 244
      common/transport/lwm2m/src/main/resources/models/10270.xml
  93. 244
      common/transport/lwm2m/src/main/resources/models/10271.xml
  94. 230
      common/transport/lwm2m/src/main/resources/models/10272.xml
  95. 230
      common/transport/lwm2m/src/main/resources/models/10273.xml
  96. 230
      common/transport/lwm2m/src/main/resources/models/10274.xml
  97. 230
      common/transport/lwm2m/src/main/resources/models/10275.xml
  98. 230
      common/transport/lwm2m/src/main/resources/models/10276.xml
  99. 230
      common/transport/lwm2m/src/main/resources/models/10277.xml
  100. 230
      common/transport/lwm2m/src/main/resources/models/10278.xml

4
application/pom.xml

@ -85,10 +85,6 @@
<groupId>org.thingsboard.common.transport</groupId>
<artifactId>coap</artifactId>
</dependency>
<dependency>
<groupId>org.thingsboard.common.transport</groupId>
<artifactId>lwm2m</artifactId>
</dependency>
<dependency>
<groupId>org.thingsboard</groupId>
<artifactId>dao</artifactId>

2
application/src/main/java/org/thingsboard/server/actors/device/DeviceActor.java

@ -62,7 +62,7 @@ public class DeviceActor extends ContextAwareActor {
processor.processAttributesUpdate(ctx, (DeviceAttributesEventNotificationMsg) msg);
break;
case DEVICE_CREDENTIALS_UPDATE_TO_DEVICE_ACTOR_MSG:
processor.processCredentialsUpdate(msg);
processor.processCredentialsUpdate();
break;
case DEVICE_NAME_OR_TYPE_UPDATE_TO_DEVICE_ACTOR_MSG:
processor.processNameOrTypeUpdate((DeviceNameOrTypeUpdateMsg) msg);

35
application/src/main/java/org/thingsboard/server/actors/device/DeviceActorMessageProcessor.java

@ -24,7 +24,6 @@ import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.thingsboard.rule.engine.api.RpcError;
import org.thingsboard.rule.engine.api.msg.DeviceAttributesEventNotificationMsg;
import org.thingsboard.rule.engine.api.msg.DeviceCredentialsUpdateNotificationMsg;
import org.thingsboard.rule.engine.api.msg.DeviceNameOrTypeUpdateMsg;
import org.thingsboard.server.actors.ActorSystemContext;
import org.thingsboard.server.actors.TbActorCtx;
@ -37,9 +36,6 @@ import org.thingsboard.server.common.data.kv.AttributeKey;
import org.thingsboard.server.common.data.kv.AttributeKvEntry;
import org.thingsboard.server.common.data.kv.KvEntry;
import org.thingsboard.server.common.data.rpc.ToDeviceRpcRequestBody;
import org.thingsboard.server.common.data.security.DeviceCredentials;
import org.thingsboard.server.common.data.security.DeviceCredentialsType;
import org.thingsboard.server.common.msg.TbActorMsg;
import org.thingsboard.server.common.msg.TbMsgMetaData;
import org.thingsboard.server.common.msg.queue.TbCallback;
import org.thingsboard.server.common.msg.rpc.ToDeviceRpcRequest;
@ -65,7 +61,6 @@ import org.thingsboard.server.gen.transport.TransportProtos.ToDeviceRpcResponseM
import org.thingsboard.server.gen.transport.TransportProtos.ToServerRpcResponseMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToTransportMsg;
import org.thingsboard.server.gen.transport.TransportProtos.TransportToDeviceActorMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToTransportUpdateCredentialsProto;
import org.thingsboard.server.gen.transport.TransportProtos.TsKvProto;
import org.thingsboard.server.service.rpc.FromDeviceRpcResponse;
import org.thingsboard.server.service.rpc.ToDeviceRpcRequestActorMsg;
@ -455,19 +450,11 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor {
dumpSessions();
}
void processCredentialsUpdate(TbActorMsg msg) {
if (((DeviceCredentialsUpdateNotificationMsg) msg).getDeviceCredentials().getCredentialsType() == DeviceCredentialsType.LWM2M_CREDENTIALS) {
log.info("1) LwM2Mtype: ");
sessions.forEach((k, v) -> {
notifyTransportAboutProfileUpdate(k, v, ((DeviceCredentialsUpdateNotificationMsg) msg).getDeviceCredentials());
});
} else {
sessions.forEach(this::notifyTransportAboutClosedSession);
attributeSubscriptions.clear();
rpcSubscriptions.clear();
dumpSessions();
}
void processCredentialsUpdate() {
sessions.forEach(this::notifyTransportAboutClosedSession);
attributeSubscriptions.clear();
rpcSubscriptions.clear();
dumpSessions();
}
private void notifyTransportAboutClosedSession(UUID sessionId, SessionInfoMetaData sessionMd) {
@ -478,18 +465,6 @@ class DeviceActorMessageProcessor extends AbstractContextAwareMsgProcessor {
systemContext.getTbCoreToTransportService().process(sessionMd.getSessionInfo().getNodeId(), msg);
}
void notifyTransportAboutProfileUpdate(UUID sessionId, SessionInfoMetaData sessionMd, DeviceCredentials deviceCredentials) {
log.info("2) LwM2Mtype: ");
TransportProtos.ToTransportUpdateCredentialsProto.Builder notification = TransportProtos.ToTransportUpdateCredentialsProto.newBuilder();
notification.addCredentialsId(deviceCredentials.getCredentialsId());
notification.addCredentialsValue(deviceCredentials.getCredentialsValue());
ToTransportMsg msg = ToTransportMsg.newBuilder()
.setSessionIdMSB(sessionId.getMostSignificantBits())
.setSessionIdLSB(sessionId.getLeastSignificantBits())
.setToTransportUpdateCredentialsNotification(notification).build();
systemContext.getTbCoreToTransportService().process(sessionMd.getSessionInfo().getNodeId(), msg);
}
void processNameOrTypeUpdate(DeviceNameOrTypeUpdateMsg msg) {
this.deviceName = msg.getDeviceName();
this.deviceType = msg.getDeviceType();

4
application/src/main/java/org/thingsboard/server/controller/BaseController.java

@ -92,7 +92,6 @@ import org.thingsboard.server.queue.discovery.PartitionService;
import org.thingsboard.server.queue.provider.TbQueueProducerProvider;
import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.service.component.ComponentDiscoveryService;
import org.thingsboard.server.service.lwm2m.LwM2MModelsRepository;
import org.thingsboard.server.service.profile.TbDeviceProfileCache;
import org.thingsboard.server.dao.tenant.TbTenantProfileCache;
import org.thingsboard.server.service.queue.TbClusterService;
@ -212,9 +211,6 @@ public abstract class BaseController {
@Autowired
protected TbDeviceProfileCache deviceProfileCache;
@Autowired
protected LwM2MModelsRepository lwM2MModelsRepository;
@Value("${server.log_controller_error_stack_trace}")
@Getter
private boolean logControllerErrorStackTrace;

5
application/src/main/java/org/thingsboard/server/controller/DeviceController.java

@ -278,8 +278,9 @@ public class DeviceController extends BaseController {
try {
Device device = checkDeviceId(deviceCredentials.getDeviceId(), Operation.WRITE_CREDENTIALS);
DeviceCredentials result = checkNotNull(deviceCredentialsService.updateDeviceCredentials(getCurrentUser().getTenantId(), deviceCredentials));
//log.info("0 LwM2M CredentialsUpdate start)
tbClusterService.pushMsgToCore(new DeviceCredentialsUpdateNotificationMsg(getCurrentUser().getTenantId(), deviceCredentials.getDeviceId(), result), null);
tbClusterService.pushMsgToCore(new DeviceCredentialsUpdateNotificationMsg(getCurrentUser().getTenantId(), deviceCredentials.getDeviceId()), null);
logEntityAction(device.getId(), device,
device.getCustomerId(),
ActionType.CREDENTIALS_UPDATED, null, deviceCredentials);

75
application/src/main/java/org/thingsboard/server/controller/DeviceLwm2mController.java

@ -1,75 +0,0 @@
/**
* Copyright © 2016-2020 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.controller;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.lwm2m.LwM2mObject;
import org.thingsboard.server.common.data.lwm2m.ServerSecurityConfig;
import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.queue.util.TbCoreComponent;
import java.util.List;
@Slf4j
@RestController
@TbCoreComponent
@RequestMapping("/api")
public class DeviceLwm2mController extends BaseController {
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
@RequestMapping(value = "/lwm2m/deviceProfile/{objectIds}", method = RequestMethod.GET)
@ResponseBody
public List<LwM2mObject> getLwm2mListObjects(@PathVariable("objectIds") int[] objectIds) throws ThingsboardException {
try {
return lwM2MModelsRepository.getLwm2mObjects(objectIds, null);
} catch (Exception e) {
throw handleException(e);
}
}
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
@RequestMapping(value = "/lwm2m/deviceProfile/objects", params = {"pageSize", "page"}, method = RequestMethod.GET)
@ResponseBody
public PageData<LwM2mObject> getLwm2mListObjects(@RequestParam int pageSize,
@RequestParam int page,
@RequestParam(required = false) String textSearch,
@RequestParam(required = false) String sortProperty,
@RequestParam(required = false) String sortOrder) throws ThingsboardException {
try {
PageLink pageLink = createPageLink(pageSize, page, textSearch, sortProperty, sortOrder);
return checkNotNull(lwM2MModelsRepository.findDeviceLwm2mObjects(getTenantId(), pageLink));
} catch (Exception e) {
throw handleException(e);
}
}
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
@RequestMapping(value = "/lwm2m/deviceProfile/bootstrap/{securityMode}/{bootstrapServerIs}", method = RequestMethod.GET)
@ResponseBody
public ServerSecurityConfig getLwm2mBootstrapSecurityInfo(@PathVariable("securityMode") String securityMode,
@PathVariable("bootstrapServerIs") boolean bootstrapServerIs) throws ThingsboardException {
try {
return lwM2MModelsRepository.getBootstrapSecurityInfo(securityMode, bootstrapServerIs);
} catch (Exception e) {
throw handleException(e);
}
}
}

256
application/src/main/java/org/thingsboard/server/service/lwm2m/LwM2MModelsRepository.java

@ -1,256 +0,0 @@
/**
* Copyright © 2016-2020 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.service.lwm2m;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.leshan.core.model.ObjectModel;
import org.eclipse.leshan.core.util.Hex;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.data.domain.PageImpl;
import org.springframework.stereotype.Service;
import org.thingsboard.server.common.data.lwm2m.*;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.page.PageData;
import org.thingsboard.server.common.data.page.PageLink;
import org.thingsboard.server.common.transport.lwm2m.LwM2MTransportConfigBootstrap;
import org.thingsboard.server.common.transport.lwm2m.LwM2MTransportConfigServer;
import org.thingsboard.server.dao.service.Validator;
import org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode;
import java.math.BigInteger;
import java.security.*;
import java.security.cert.CertificateEncodingException;
import java.security.cert.X509Certificate;
import java.security.spec.ECGenParameterSpec;
import java.security.spec.ECParameterSpec;
import java.security.spec.ECPublicKeySpec;
import java.security.spec.ECPoint;
import java.security.spec.KeySpec;
import java.util.List;
import java.util.ArrayList;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import static org.thingsboard.server.dao.service.Validator.validateId;
@Slf4j
@Service
@ConditionalOnExpression("('${service.type:null}'=='tb-transport' && '${transport.lwm2m.enabled:false}'=='true') || '${service.type:null}'=='monolith' || '${service.type:null}'=='tb-core'")
public class LwM2MModelsRepository {
private static final String INCORRECT_TENANT_ID = "Incorrect tenantId ";
@Autowired
LwM2MTransportConfigServer contextServer;
@Autowired
LwM2MTransportConfigBootstrap contextBootStrap;
/**
* @param objectIds
* @param textSearch
* @return list of LwM2mObject
* Filter by Predicate (uses objectIds, if objectIds is null then it uses textSearch,
* if textSearch is null then it uses AllList from List<ObjectModel>)
*/
public List<LwM2mObject> getLwm2mObjects(int[] objectIds, String textSearch) {
return getLwm2mObjects((objectIds != null && objectIds.length > 0) ?
(ObjectModel element) -> IntStream.of(objectIds).anyMatch(x -> x == element.id) :
(textSearch != null && !textSearch.isEmpty()) ? (ObjectModel element) -> element.name.contains(textSearch) : null);
}
/**
* @param predicate
* @return list of LwM2mObject
*/
private List<LwM2mObject> getLwm2mObjects(Predicate<? super ObjectModel> predicate) {
List<LwM2mObject> lwM2mObjects = new ArrayList<>();
List<ObjectModel> listObjects = (predicate == null) ? this.contextServer.getModelsValue() :
contextServer.getModelsValue().stream()
.filter(predicate)
.collect(Collectors.toList());
listObjects.forEach(obj -> {
LwM2mObject lwM2mObject = new LwM2mObject();
lwM2mObject.setId(obj.id);
lwM2mObject.setName(obj.name);
lwM2mObject.setMultiple(obj.multiple);
lwM2mObject.setMandatory(obj.mandatory);
LwM2mInstance instance = new LwM2mInstance();
instance.setId(0);
List<LwM2mResource> resources = new ArrayList<>();
obj.resources.forEach((k, v) -> {
if (!v.operations.isExecutable()) {
LwM2mResource resource = new LwM2mResource(k, v.name, false, false, false);
resources.add(resource);
}
});
instance.setResources(resources.stream().toArray(LwM2mResource[]::new));
lwM2mObject.setInstances(new LwM2mInstance[]{instance});
lwM2mObjects.add(lwM2mObject);
});
return lwM2mObjects;
}
/**
* @param tenantId
* @param pageLink
* @return List of LwM2mObject in PageData format
*/
public PageData<LwM2mObject> findDeviceLwm2mObjects(TenantId tenantId, PageLink pageLink) {
log.trace("Executing findDeviceProfileInfos tenantId [{}], pageLink [{}]", tenantId, pageLink);
validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
Validator.validatePageLink(pageLink);
return this.findLwm2mListObjects(pageLink);
}
/**
* @param pageLink
* @return List of LwM2mObject in PageData format, filter == TextSearch
* PageNumber = 1, PageSize = List<LwM2mObject>.size()
*/
public PageData<LwM2mObject> findLwm2mListObjects(PageLink pageLink) {
PageImpl page = new PageImpl(getLwm2mObjects(null, pageLink.getTextSearch()));
PageData pageData = new PageData(page.getContent(), page.getTotalPages(), page.getTotalElements(), page.hasNext());
return pageData;
}
/**
*
* @param securityMode
* @param bootstrapServerIs
* @return ServerSecurityConfig more value is default: Important - port, host, publicKey
*/
public ServerSecurityConfig getBootstrapSecurityInfo(String securityMode, boolean bootstrapServerIs) {
LwM2MSecurityMode lwM2MSecurityMode = LwM2MSecurityMode.fromSecurityMode(securityMode.toLowerCase());
return getBootstrapServer(bootstrapServerIs, lwM2MSecurityMode);
}
/**
*
* @param bootstrapServerIs
* @param mode
* @return ServerSecurityConfig more value is default: Important - port, host, publicKey
*/
private ServerSecurityConfig getBootstrapServer(boolean bootstrapServerIs, LwM2MSecurityMode mode) {
ServerSecurityConfig bsServ = new ServerSecurityConfig();
if (bootstrapServerIs) {
switch (mode) {
case NO_SEC:
bsServ.setHost(contextBootStrap.getBootstrapHost());
bsServ.setPort(contextBootStrap.getBootstrapPort());
bsServ.setServerPublicKey("");
break;
case PSK:
bsServ.setHost(contextBootStrap.getBootstrapSecureHost());
bsServ.setPort(contextBootStrap.getBootstrapSecurePort());
bsServ.setServerPublicKey("");
break;
case RPK:
bsServ.setHost(contextBootStrap.getBootstrapSecureHost());
bsServ.setPort(contextBootStrap.getBootstrapSecurePort());
bsServ.setServerPublicKey(getRPKPublicKey(this.contextBootStrap.getBootstrapPublicX(), this.contextBootStrap.getBootstrapPublicY()));
break;
case X509:
bsServ.setHost(contextBootStrap.getBootstrapSecureHost());
bsServ.setPort(contextBootStrap.getBootstrapSecurePortCert());
bsServ.setServerPublicKey(getServerPublicKeyX509(contextBootStrap.getBootstrapAlias()));
break;
default:
break;
}
} else {
bsServ.setBootstrapServerIs(bootstrapServerIs);
bsServ.setServerId(123);
switch (mode) {
case NO_SEC:
bsServ.setHost(contextServer.getServerHost());
bsServ.setPort(contextServer.getServerPort());
bsServ.setServerPublicKey("");
break;
case PSK:
bsServ.setHost(contextServer.getServerSecureHost());
bsServ.setPort(contextServer.getServerSecurePort());
bsServ.setServerPublicKey("");
break;
case RPK:
bsServ.setHost(contextServer.getServerSecureHost());
bsServ.setPort(contextServer.getServerSecurePort());
bsServ.setServerPublicKey(getRPKPublicKey(this.contextServer.getServerPublicX(), this.contextServer.getServerPublicY()));
break;
case X509:
bsServ.setHost(contextServer.getServerSecureHost());
bsServ.setPort(contextServer.getServerSecurePortCert());
bsServ.setServerPublicKey(getServerPublicKeyX509(contextServer.getServerAlias()));
break;
default:
break;
}
}
return bsServ;
}
/**
*
* @param alias
* @return PublicKey format HexString or null
*/
private String getServerPublicKeyX509 (String alias) {
try {
X509Certificate serverCertificate = (X509Certificate) contextServer.getKeyStoreValue().getCertificate(alias);
return Hex.encodeHexString(serverCertificate.getEncoded());
} catch (CertificateEncodingException | KeyStoreException e) {
e.printStackTrace();
}
return null;
}
/**
*
* @param publicServerX
* @param publicServerY
* @return PublicKey format HexString or null
*/
private String getRPKPublicKey(String publicServerX, String publicServerY) {
try {
/** Get Elliptic Curve Parameter spec for secp256r1 */
AlgorithmParameters algoParameters = AlgorithmParameters.getInstance("EC");
algoParameters.init(new ECGenParameterSpec("secp256r1"));
ECParameterSpec parameterSpec = algoParameters.getParameterSpec(ECParameterSpec.class);
if (publicServerX != null && !publicServerX.isEmpty() && publicServerY != null && !publicServerY.isEmpty()) {
/** Get point values */
byte[] publicX = Hex.decodeHex(publicServerX.toCharArray());
byte[] publicY = Hex.decodeHex(publicServerY.toCharArray());
/** Create key specs */
KeySpec publicKeySpec = new ECPublicKeySpec(new ECPoint(new BigInteger(publicX), new BigInteger(publicY)),
parameterSpec);
/** Get keys */
PublicKey publicKey = KeyFactory.getInstance("EC").generatePublic(publicKeySpec);
if (publicKey != null && publicKey.getEncoded().length > 0 ) {
return Hex.encodeHexString(publicKey.getEncoded());
}
}
} catch (GeneralSecurityException | IllegalArgumentException e) {
log.error("[{}] Failed generate Server RPK for profile", e.getMessage());
throw new RuntimeException(e);
}
return null;
}
}

4
application/src/main/java/org/thingsboard/server/service/security/device/DefaultDeviceAuthService.java

@ -53,8 +53,6 @@ public class DefaultDeviceAuthService implements DeviceAuthService {
return DeviceAuthResult.of(credentials.getDeviceId());
case X509_CERTIFICATE:
return DeviceAuthResult.of(credentials.getDeviceId());
case LWM2M_CREDENTIALS:
return DeviceAuthResult.of(credentials.getDeviceId());
default:
return DeviceAuthResult.of("Credentials Type is not supported yet!");
}
@ -67,4 +65,4 @@ public class DefaultDeviceAuthService implements DeviceAuthService {
}
}
}
}

1
application/src/main/java/org/thingsboard/server/service/telemetry/DefaultTelemetrySubscriptionService.java

@ -201,7 +201,6 @@ public class DefaultTelemetrySubscriptionService extends AbstractSubscriptionSer
}
@Override
public void saveAndNotify(TenantId tenantId, EntityId entityId, String scope, List<AttributeKvEntry> attributes, FutureCallback<Void> callback) {
saveAndNotify(tenantId, entityId, scope, attributes, true, callback);
}

44
application/src/main/java/org/thingsboard/server/service/transport/DefaultTransportApiService.java

@ -69,7 +69,6 @@ import org.thingsboard.server.gen.transport.TransportProtos.TransportApiResponse
import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceCredentialsResponseMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceTokenRequestMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceX509CertRequestMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceLwM2MCredentialsRequestMsg;
import org.thingsboard.server.queue.common.TbProtoQueueMsg;
import org.thingsboard.server.queue.util.TbCoreComponent;
import org.thingsboard.server.dao.device.provision.ProvisionFailedException;
@ -150,13 +149,6 @@ public class DefaultTransportApiService implements TransportApiService {
} else if (transportApiRequestMsg.hasEntityProfileRequestMsg()) {
return Futures.transform(handle(transportApiRequestMsg.getEntityProfileRequestMsg()),
value -> new TbProtoQueueMsg<>(tbProtoQueueMsg.getKey(), value, tbProtoQueueMsg.getHeaders()), MoreExecutors.directExecutor());
} else if (transportApiRequestMsg.hasLwM2MRequestMsg()) {
return Futures.transform(handle(transportApiRequestMsg.getLwM2MRequestMsg()),
value -> new TbProtoQueueMsg<>(tbProtoQueueMsg.getKey(), value, tbProtoQueueMsg.getHeaders()), MoreExecutors.directExecutor());
} else if (transportApiRequestMsg.hasValidateDeviceLwM2MCredentialsRequestMsg()) {
ValidateDeviceLwM2MCredentialsRequestMsg msg = transportApiRequestMsg.getValidateDeviceLwM2MCredentialsRequestMsg();
return Futures.transform(validateCredentials(msg.getCredentialsId(), DeviceCredentialsType.LWM2M_CREDENTIALS),
value -> new TbProtoQueueMsg<>(tbProtoQueueMsg.getKey(), value, tbProtoQueueMsg.getHeaders()), MoreExecutors.directExecutor());
} else if (transportApiRequestMsg.hasProvisionDeviceRequestMsg()) {
return Futures.transform(handle(transportApiRequestMsg.getProvisionDeviceRequestMsg()),
value -> new TbProtoQueueMsg<>(tbProtoQueueMsg.getKey(), value, tbProtoQueueMsg.getHeaders()), MoreExecutors.directExecutor());
@ -404,40 +396,4 @@ public class DefaultTransportApiService implements TransportApiService {
return TransportApiResponseMsg.newBuilder()
.setValidateCredResponseMsg(ValidateDeviceCredentialsResponseMsg.getDefaultInstance()).build();
}
private ListenableFuture<TransportApiResponseMsg> handle(TransportProtos.LwM2MRequestMsg requestMsg) {
if (requestMsg.hasRegistrationMsg()) {
return handleRegistration(requestMsg.getRegistrationMsg());
} else {
return Futures.immediateFailedFuture(new RuntimeException("Not supported!"));
}
}
private ListenableFuture<TransportApiResponseMsg> handleRegistration(TransportProtos.LwM2MRegistrationRequestMsg msg) {
TenantId tenantId = new TenantId(UUID.fromString(msg.getTenantId()));
String deviceName = msg.getEndpoint();
Lock deviceCreationLock = deviceCreationLocks.computeIfAbsent(deviceName, id -> new ReentrantLock());
deviceCreationLock.lock();
try {
Device device = deviceService.findDeviceByTenantIdAndName(tenantId, deviceName);
if (device == null) {
device = new Device();
device.setTenantId(tenantId);
device.setName(deviceName);
device.setType("LwM2M");
device = deviceService.saveDevice(device);
deviceStateService.onDeviceAdded(device);
}
TransportProtos.LwM2MRegistrationResponseMsg registrationResponseMsg =
TransportProtos.LwM2MRegistrationResponseMsg.newBuilder()
.setDeviceInfo(getDeviceInfoProto(device)).build();
TransportProtos.LwM2MResponseMsg responseMsg = TransportProtos.LwM2MResponseMsg.newBuilder().setRegistrationMsg(registrationResponseMsg).build();
return Futures.immediateFuture(TransportApiResponseMsg.newBuilder().setLwM2MResponseMsg(responseMsg).build());
} catch (JsonProcessingException e) {
log.warn("[{}][{}] Failed to lookup device by gateway id and name", tenantId, deviceName, e);
throw new RuntimeException(e);
} finally {
deviceCreationLock.unlock();
}
}
}

7
application/src/main/resources/banner.txt

@ -1,10 +1,3 @@
______ __ _ __ __
/_ __/ / /_ (_) ____ ____ _ _____ / /_ ____ ____ _ _____ ____/ /
/ / / __ \ / / / __ \ / __ `/ / ___/ / __ \ / __ \ / __ `/ / ___/ / __ /
/ / / / / / / / / / / / / /_/ / (__ ) / /_/ // /_/ // /_/ / / / / /_/ /
/_/ /_/ /_/ /_/ /_/ /_/ \__, / /____/ /_.___/ \____/ \__,_/ /_/ \__,_/
/____/
===================================================
:: ${application.title} :: ${application.formatted-version}
===================================================

72
application/src/main/resources/thingsboard.yml

@ -433,7 +433,7 @@ spring:
database-platform: "${SPRING_JPA_DATABASE_PLATFORM:org.hibernate.dialect.PostgreSQLDialect}"
datasource:
driverClassName: "${SPRING_DRIVER_CLASS_NAME:org.postgresql.Driver}"
url: "${SPRING_DATASOURCE_URL:jdbc:postgresql://localhost:5432/thingsboard_ce_3_2_2}"
url: "${SPRING_DATASOURCE_URL:jdbc:postgresql://localhost:5432/thingsboard}"
username: "${SPRING_DATASOURCE_USERNAME:postgres}"
password: "${SPRING_DATASOURCE_PASSWORD:postgres}"
hikari:
@ -488,7 +488,7 @@ js:
# Built-in JVM JavaScript environment properties
local:
# Use Sandboxed (secured) JVM JavaScript environment
use_js_sandbox: "${USE_LOCAL_JS_SANDBOX:false}"
use_js_sandbox: "${USE_LOCAL_JS_SANDBOX:true}"
# Specify thread pool size for JavaScript sandbox resource monitor
monitor_thread_pool_size: "${LOCAL_JS_SANDBOX_MONITOR_THREAD_POOL_SIZE:4}"
# Maximum CPU time in milliseconds allowed for script execution
@ -565,74 +565,6 @@ transport:
bind_address: "${COAP_BIND_ADDRESS:0.0.0.0}"
bind_port: "${COAP_BIND_PORT:5683}"
timeout: "${COAP_TIMEOUT:10000}"
# Local LwM2M transport parameters
lwm2m:
# Enable/disable lvm2m transport protocol.
enabled: "${LWM2M_ENABLED:true}"
# We choose a default timeout a bit higher to the MAX_TRANSMIT_WAIT(62-93s) which is the time from starting to
# send a Confirmable message to the time when an acknowledgement is no longer expected.
# DEFAULT_TIMEOUT = 2 * 60 * 1000l; 2 min in ms
timeout: "${LWM2M_TIMEOUT:120000}"
# model_path_file: "${LWM2M_MODEL_PATH_FILE:./common/transport/lwm2m/src/main/resources/models/}"
model_path_file: "${LWM2M_MODEL_PATH_FILE:}"
support_deprecated_ciphers_enable: "${LWM2M_SUPPORT_DEPRECATED_CIPHERS_ENABLED:true}"
secure:
# Only Certificate_x509:
# To get helps about files format and how to generate it, see: https://github.com/eclipse/leshan/wiki/Credential-files-format
# Create new X509 Certificates: common/transport/lwm2m/src/main/resources/credentials/shell/lwM2M_credentials.sh
key_store_type: "${LWM2M_KEYSTORE_TYPE:JKS}"
# key_store_type: "${LWM2M_KEYSTORE_TYPE:PKCS12}"
# key_store_path_file: "${KEY_STORE_PATH_FILE:/usr/share/thingsboard/conf/credentials/serverKeyStore.jks}"
key_store_path_file: "${KEY_STORE_PATH_FILE:}"
key_store_password: "${LWM2M_KEYSTORE_PASSWORD_SERVER:server_ks_password}"
root_alias: "${LWM2M_SERVER_ROOT_CA:rootca}"
enable_gen_psk_rpk: "${ENABLE_GEN_PSK_RPK:true}"
server:
bind_address: "${LWM2M_BIND_ADDRESS:0.0.0.0}"
bind_port: "${LWM2M_BIND_PORT:5685}"
bind_port_cert: "${LWM2M_BIND_PORT_CERT:5687}"
secure:
start_all: "${START_SERVER_ALL:true}"
#leshan.core (V1_1)
#DTLS security modes:
#0: Pre-Shared Key mode
#1: Raw Public Key mode
#2: Certificate mode X509
#3: NoSec mode *
#OMA-TS-LightweightM2M_Core-V1_1_1-20190617-A (add)
#4: Certificate mode X509 with EST
# If only startAll == false
dtls_mode: "${LWM2M_SECURITY_MODE:1}"
bind_address: "${LWM2M_BIND_ADDRESS:0.0.0.0}"
bind_port: "${LWM2M_BIND_PORT_SEC:5686}"
bind_port_cert: "${LWM2M_BIND_PORT_SEC_CERT:5688}"
# Only RPK: Public & Private Key
# create_rpk: "${CREATE_RPK:}"
public_x: "${LWM2M_SERVER_PUBLIC_X:405354ea8893471d9296afbc8b020a5c6201b0bb25812a53b849d4480fa5f069}"
public_y: "${LWM2M_SERVER_PUBLIC_Y:30c9237e946a3a1692c1cafaa01a238a077f632c99371348337512363f28212b}"
private_s: "${LWM2M_SERVER_PRIVATE_S:274671fe40ce937b8a6352cf0a418e8a39e4bf0bb9bf74c910db953c20c73802}"
# Only Certificate_x509:
alias: "${LWM2M_KEYSTORE_ALIAS_SERVER:server}"
bootstrap:
enable: "${BOOTSTRAP:true}"
bind_address: "${LWM2M_BIND_ADDRESS_BS:0.0.0.0}"
bind_port: "${LWM2M_BIND_PORT_BS:5689}"
bind_port_cert: "${LWM2M_BIND_PORT_SER_BS:5691}"
secure:
start_all: "${START_BOOTSTRAP_ALL:true}"
# If only startAll == false
dtls_mode: "${LWM2M_SECURITY_MODE_BS:1}"
bind_address: "${LWM2M_BIND_ADDRESS_BS:0.0.0.0}"
bind_port: "${LWM2M_BIND_PORT_SEC_BS:5690}"
bind_port_cert: "${LWM2M_BIND_PORT_SEC_CERT_BS:5692}"
# Only RPK: Public & Private Key
public_x: "${LWM2M_SERVER_PUBLIC_X_BS:993ef2b698c6a9c0c1d8be78b13a9383c0854c7c7c7a504d289b403794648183}"
public_y: "${LWM2M_SERVER_PUBLIC_Y_BS:267412d5fc4e5ceb2257cb7fd7f76ebdac2fa9aa100afb162e990074cc0bfaa2}"
private_s: "${LWM2M_SERVER_PRIVATE_S_BS:9dbdbb073fc63570693a9aaf1013414e261c571f27e27fc6a8c1c2ad9347875a}"
# Only Certificate_x509:
alias: "${LWM2M_KEYSTORE_ALIAS_BOOTSTRAP:bootstrap}"
# Redis
redis_url: "${LWM2M_REDIS_URL:''}"
swagger:
api_path_regex: "${SWAGGER_API_PATH_REGEX:/api.*}"

25
common/data/src/main/java/org/thingsboard/server/common/data/lwm2m/LwM2mInstance.java

@ -1,25 +0,0 @@
/**
* Copyright © 2016-2020 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.common.data.lwm2m;
import lombok.Data;
@Data
public class LwM2mInstance {
int id;
LwM2mResource [] resources;
}

27
common/data/src/main/java/org/thingsboard/server/common/data/lwm2m/LwM2mObject.java

@ -1,27 +0,0 @@
/**
* Copyright © 2016-2020 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.common.data.lwm2m;
import lombok.Data;
@Data
public class LwM2mObject {
int id;
String name;
boolean multiple;
boolean mandatory;
LwM2mInstance [] instances;
}

63
common/data/src/main/java/org/thingsboard/server/common/data/lwm2m/LwM2mResource.java

@ -1,63 +0,0 @@
/**
* Copyright © 2016-2020 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.common.data.lwm2m;
import lombok.AllArgsConstructor;
import lombok.Data;
import java.util.stream.Stream;
@Data
@AllArgsConstructor
public class LwM2mResource {
int id;
String name;
boolean observe;
boolean attribute;
boolean telemetry;
String keyName;
public LwM2mResource(int id, String name, boolean observe, boolean attribute, boolean telemetry) {
this.id = id;
this.name = name;
this.observe = observe;
this.attribute = attribute;
this.telemetry = telemetry;
this.keyName = getCamelCase (this.name);
}
private String getCamelCase (String name) {
name = name.replaceAll("-", " ");
name = name.replaceAll("_", " ");
String [] nameCamel1 = name.split(" ");
String [] nameCamel2 = new String[nameCamel1.length];
int[] idx = { 0 };
Stream.of(nameCamel1).forEach((s -> {
nameCamel2[idx[0]] = toProperCase(idx[0]++, s);
}));
return String.join("", nameCamel2);
}
private String toProperCase(int idx, String s) {
if (!s.isEmpty() && s.length()> 0) {
String s1 = (idx == 0) ? s.substring(0, 1).toLowerCase() : s.substring(0, 1).toUpperCase();
String s2 = "";
if (s.length()> 1) s2 = s.substring(1).toLowerCase();
s = s1 + s2;
}
return s;
}
}

34
common/data/src/main/java/org/thingsboard/server/common/data/lwm2m/ServerSecurityConfig.java

@ -1,34 +0,0 @@
/**
* Copyright © 2016-2020 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.common.data.lwm2m;
import lombok.Builder;
import lombok.Data;
@Data
public class ServerSecurityConfig {
String host;
Integer port;
String serverPublicKey;
@Builder.Default
boolean bootstrapServerIs = true;
@Builder.Default
Integer clientHoldOffTime = 1;
@Builder.Default
Integer serverId = 111;
@Builder.Default
Integer bootstrapServerAccountTimeout = 0;
}

4
common/data/src/main/java/org/thingsboard/server/common/data/security/DeviceCredentialsType.java

@ -19,8 +19,6 @@ public enum DeviceCredentialsType {
ACCESS_TOKEN,
X509_CERTIFICATE,
MQTT_BASIC,
LWM2M_CREDENTIALS
MQTT_BASIC
}

46
common/queue/src/main/proto/queue.proto

@ -183,47 +183,6 @@ message GetEntityProfileRequestMsg {
int64 entityIdLSB = 3;
}
message LwM2MRegistrationRequestMsg {
string tenantId = 1;
string endpoint = 2;
}
message LwM2MRegistrationResponseMsg {
DeviceInfoProto deviceInfo = 1;
}
message LwM2MRequestMsg {
LwM2MRegistrationRequestMsg registrationMsg = 1;
}
message LwM2MResponseMsg {
LwM2MRegistrationResponseMsg registrationMsg = 1;
}
message ValidateDeviceLwM2MCredentialsRequestMsg {
string credentialsId = 1;
}
message ToTransportUpdateCredentialsProto {
repeated string credentialsId = 1;
repeated string credentialsValue = 2;
}
message GetTenantRoutingInfoRequestMsg {
int64 tenantIdMSB = 1;
int64 tenantIdLSB = 2;
}
message GetTenantRoutingInfoResponseMsg {
bool isolatedTbCore = 1;
bool isolatedTbRuleEngine = 2;
}
message GetDeviceProfileRequestMsg {
int64 profileIdMSB = 1;
int64 profileIdLSB = 2;
}
message GetEntityProfileResponseMsg {
string entityType = 1;
bytes data = 2;
@ -520,10 +479,8 @@ message TransportApiRequestMsg {
ValidateDeviceX509CertRequestMsg validateX509CertRequestMsg = 2;
GetOrCreateDeviceFromGatewayRequestMsg getOrCreateDeviceRequestMsg = 3;
GetEntityProfileRequestMsg entityProfileRequestMsg = 4;
LwM2MRequestMsg lwM2MRequestMsg = 5;
ValidateBasicMqttCredRequestMsg validateBasicMqttCredRequestMsg = 6;
ProvisionDeviceRequestMsg provisionDeviceRequestMsg = 7;
ValidateDeviceLwM2MCredentialsRequestMsg validateDeviceLwM2MCredentialsRequestMsg = 8;
}
/* Response from ThingsBoard Core Service to Transport Service */
@ -532,7 +489,6 @@ message TransportApiResponseMsg {
GetOrCreateDeviceFromGatewayResponseMsg getOrCreateDeviceResponseMsg = 2;
GetEntityProfileResponseMsg entityProfileResponseMsg = 3;
ProvisionDeviceResponseMsg provisionDeviceResponseMsg = 4;
LwM2MResponseMsg lwM2MResponseMsg = 6;
}
/* Messages that are handled by ThingsBoard Core Service */
@ -573,10 +529,10 @@ message ToTransportMsg {
AttributeUpdateNotificationMsg attributeUpdateNotification = 5;
ToDeviceRpcRequestMsg toDeviceRequest = 6;
ToServerRpcResponseMsg toServerResponse = 7;
/* For Tenant, TenantProfile and DeviceProfile */
EntityUpdateMsg entityUpdateMsg = 8;
EntityDeleteMsg entityDeleteMsg = 9;
ProvisionDeviceResponseMsg provisionResponse = 10;
ToTransportUpdateCredentialsProto toTransportUpdateCredentialsNotification = 11;
}
message UsageStatsKVProto{

1
common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/CoapTransportContext.java

@ -24,7 +24,6 @@ import org.springframework.stereotype.Component;
import org.thingsboard.server.common.transport.TransportContext;
import org.thingsboard.server.transport.coap.adaptors.CoapTransportAdaptor;
/**
* Created by ashvayka on 18.10.18.
*/

66
common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/CoapTransportResource.java

@ -16,15 +16,14 @@
package org.thingsboard.server.transport.coap;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.californium.core.CoapObserveRelation;
import org.eclipse.californium.core.CoapResource;
import org.eclipse.californium.core.coap.CoAP;
import org.eclipse.californium.core.coap.CoAP.ResponseCode;
import org.eclipse.californium.core.coap.Request;
import org.eclipse.californium.core.network.Endpoint;
import org.eclipse.californium.core.network.Exchange;
import org.eclipse.californium.core.network.ExchangeObserver;
import org.eclipse.californium.core.server.resources.CoapExchange;
import org.eclipse.californium.core.server.resources.Resource;
import org.springframework.util.ReflectionUtils;
import org.thingsboard.server.common.data.DataConstants;
import org.thingsboard.server.common.data.DeviceTransportType;
import org.thingsboard.server.common.data.security.DeviceTokenCredentials;
@ -41,26 +40,26 @@ import org.thingsboard.server.common.transport.auth.ValidateDeviceCredentialsRes
import org.thingsboard.server.gen.transport.TransportProtos;
import org.thingsboard.server.gen.transport.TransportProtos.ProvisionDeviceResponseMsg;
import java.lang.reflect.Field;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
@Slf4j
public class CoapTransportResource extends CoapResource {
// coap://localhost:port/api/v1/DEVICE_TOKEN/[attributes|telemetry|rpc[/requestId]]
private static final int ACCESS_TOKEN_POSITION = 3;
private static final int FEATURE_TYPE_POSITION = 4;
private static final int REQUEST_ID_POSITION = 5;
private final CoapTransportContext transportContext;
private final TransportService transportService;
private final Field observerField;
private final long timeout;
private final ConcurrentMap<String, TransportProtos.SessionInfoProto> tokenToSessionIdMap = new ConcurrentHashMap<>();
private final Set<UUID> rpcSubscriptions = ConcurrentHashMap.newKeySet();
@ -74,20 +73,9 @@ public class CoapTransportResource extends CoapResource {
// This is important to turn off existing observable logic in
// CoapResource. We will have our own observe monitoring due to 1:1
// observe relationship.
this.setObservable(true); // enable observing
this.setObserveType(CoAP.Type.CON); // configure the notification type to CONs
this.getAttributes().setObservable(); // mark observable in the Link-Format
// schedule a periodic update task, otherwise let events call changed()
Timer timer = new Timer();
timer.schedule(new UpdateTask(), 0, 5000);
}
private class UpdateTask extends TimerTask {
@Override
public void run() {
// .. periodic update of the resource
changed(); // notify all observers
}
this.setObservable(false);
observerField = ReflectionUtils.findField(Exchange.class, "observer");
observerField.setAccessible(true);
}
@Override
@ -199,7 +187,9 @@ public class CoapTransportResource extends CoapResource {
new CoapOkCallback(exchange));
break;
case SUBSCRIBE_ATTRIBUTES_REQUEST:
transportService.registerSyncSession(sessionInfo, new CoapSessionListener(sessionId, exchange), transportContext.getTimeout());
attributeSubscriptions.add(sessionId);
advanced.setObserver(new CoapExchangeObserverProxy((ExchangeObserver) observerField.get(advanced),
registerAsyncCoapSession(exchange, request, sessionInfo, sessionId)));
transportService.process(sessionInfo,
TransportProtos.SubscribeToAttributeUpdatesMsg.getDefaultInstance(),
new CoapNoOpCallback(exchange));
@ -216,6 +206,8 @@ public class CoapTransportResource extends CoapResource {
break;
case SUBSCRIBE_RPC_COMMANDS_REQUEST:
rpcSubscriptions.add(sessionId);
advanced.setObserver(new CoapExchangeObserverProxy((ExchangeObserver) observerField.get(advanced),
registerAsyncCoapSession(exchange, request, sessionInfo, sessionId)));
transportService.process(sessionInfo,
TransportProtos.SubscribeToRPCMsg.getDefaultInstance(),
new CoapNoOpCallback(exchange));
@ -251,6 +243,9 @@ public class CoapTransportResource extends CoapResource {
} catch (AdaptorException e) {
log.trace("[{}] Failed to decode message: ", sessionId, e);
exchange.respond(ResponseCode.BAD_REQUEST);
} catch (IllegalAccessException e) {
log.trace("[{}] Failed to process message: ", sessionId, e);
exchange.respond(ResponseCode.INTERNAL_SERVER_ERROR);
}
}));
}
@ -464,17 +459,24 @@ public class CoapTransportResource extends CoapResource {
}
}
public class CoapExchangeObserverProxy extends CoapObserveRelation {
/**
* Constructs a new CoapObserveRelation with the specified request.
*
* @param request the request
* @param endpoint the endpoint
* @param executor
*/
protected CoapExchangeObserverProxy(Request request, Endpoint endpoint, ScheduledThreadPoolExecutor executor) {
super(request, endpoint, executor);
public class CoapExchangeObserverProxy implements ExchangeObserver {
private final ExchangeObserver proxy;
private final String token;
CoapExchangeObserverProxy(ExchangeObserver proxy, String token) {
super();
this.proxy = proxy;
this.token = token;
}
@Override
public void completed(Exchange exchange) {
proxy.completed(exchange);
TransportProtos.SessionInfoProto session = tokenToSessionIdMap.remove(token);
if (session != null) {
closeAndDeregister(session);
}
}
}

11
common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/CoapTransportService.java

@ -18,9 +18,8 @@ package org.thingsboard.server.transport.coap;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.californium.core.CoapResource;
import org.eclipse.californium.core.CoapServer;
import org.eclipse.californium.core.network.CoapEndpoint;
import org.eclipse.californium.core.network.CoapEndpoint.Builder;
import org.eclipse.californium.core.network.config.NetworkConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.stereotype.Service;
@ -48,15 +47,11 @@ public class CoapTransportService {
public void init() throws UnknownHostException {
log.info("Starting CoAP transport...");
log.info("Starting CoAP transport server");
this.server = new CoapServer();
this.server = new CoapServer(NetworkConfig.createStandardWithoutFile());
createResources();
InetAddress addr = InetAddress.getByName(coapTransportContext.getHost());
InetSocketAddress sockAddr = new InetSocketAddress(addr, coapTransportContext.getPort());
Builder builder = new Builder();
builder.setInetSocketAddress(sockAddr);
CoapEndpoint coapEndpoint = builder.build();
server.addEndpoint(coapEndpoint);
server.addEndpoint(new CoapEndpoint(sockAddr));
server.start();
log.info("CoAP transport started!");
}

1
common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/adaptors/JsonCoapAdaptor.java

@ -31,7 +31,6 @@ import org.thingsboard.server.common.transport.adaptor.JsonConverter;
import org.thingsboard.server.gen.transport.TransportProtos;
import org.thingsboard.server.transport.coap.CoapTransportResource;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;

21
common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/client/DeviceEmulator.java

@ -28,7 +28,6 @@ import org.eclipse.californium.core.CoapClient;
import org.eclipse.californium.core.CoapHandler;
import org.eclipse.californium.core.CoapResponse;
import org.eclipse.californium.core.coap.MediaTypeRegistry;
import org.eclipse.californium.elements.exception.ConnectorException;
import org.thingsboard.server.common.msg.session.FeatureType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -62,7 +61,7 @@ public class DeviceEmulator {
this.attributesClient = new CoapClient(getFeatureTokenUrl(host, port, token, FeatureType.ATTRIBUTES));
this.telemetryClient = new CoapClient(getFeatureTokenUrl(host, port, token, FeatureType.TELEMETRY));
this.rpcClient = new CoapClient(getFeatureTokenUrl(host, port, token, FeatureType.RPC));
this.keys = (keys != null && !keys.isEmpty()) ? keys.split(",") : null;
this.keys = keys.split(",");
}
public void start() {
@ -73,8 +72,11 @@ public class DeviceEmulator {
try {
sendObserveRequest(rpcClient);
while (!Thread.interrupted()) {
sendRequest(attributesClient, createAttributesRequest());
sendRequest(telemetryClient, createTelemetryRequest());
Thread.sleep(1000);
}
} catch (Exception e) {
@ -82,8 +84,8 @@ public class DeviceEmulator {
}
}
private void sendRequest(CoapClient client, JsonNode request) throws IOException, ConnectorException {
CoapResponse telemetryResponse = client.setTimeout((long) 60000).post(mapper.writeValueAsString(request),
private void sendRequest(CoapClient client, JsonNode request) throws JsonProcessingException {
CoapResponse telemetryResponse = client.setTimeout(60000).post(mapper.writeValueAsString(request),
MediaTypeRegistry.APPLICATION_JSON);
log.info("Response: {}, {}", telemetryResponse.getCode(), telemetryResponse.getResponseText());
}
@ -111,7 +113,6 @@ public class DeviceEmulator {
@Override
public void onError() {
log.info("Command Response Ack Error, No connect");
//Do nothing
}
}, mapper.writeValueAsString(response), MediaTypeRegistry.APPLICATION_JSON);
@ -156,15 +157,6 @@ public class DeviceEmulator {
if (args.length != 4) {
System.out.println("Usage: java -jar " + DeviceEmulator.class.getSimpleName() + ".jar host port device_token keys");
}
/**
* DeviceEmulator(String host, int port, String token, String keys)
* args[]:
* host = "localhost",
* port = 0,
* token = "{Tokrn device from thingboard}"), kSzbDRGwaZqZ6Y25gTLF
* keys = "{Telemetry}"
*
*/
final DeviceEmulator emulator = new DeviceEmulator(args[0], Integer.parseInt(args[1]), args[2], args[3]);
emulator.start();
Runtime.getRuntime().addShutdownHook(new Thread() {
@ -175,6 +167,7 @@ public class DeviceEmulator {
});
}
private String getFeatureTokenUrl(String host, int port, String token, FeatureType featureType) {
return getBaseUrl(host, port) + token + "/" + featureType.name().toLowerCase();
}

1
common/transport/http/src/main/java/org/thingsboard/server/transport/http/DeviceApiController.java

@ -327,7 +327,6 @@ public class DeviceApiController {
public void onToServerRpcResponse(ToServerRpcResponseMsg msg) {
responseWriter.setResult(new ResponseEntity<>(JsonConverter.toJson(msg).toString(), HttpStatus.OK));
}
}
private void reportActivity(SessionInfoProto sessionInfo) {

123
common/transport/lwm2m/pom.xml

@ -1,123 +0,0 @@
<!--
Copyright © 2016-2020 The Thingsboard Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.thingsboard.common</groupId>
<version>3.2.0-SNAPSHOT</version>
<artifactId>transport</artifactId>
</parent>
<groupId>org.thingsboard.common.transport</groupId>
<artifactId>lwm2m</artifactId>
<packaging>jar</packaging>
<name>Thingsboard LwM2M Transport Common</name>
<url>https://thingsboard.io</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<main.dir>${basedir}/../../..</main.dir>
</properties>
<dependencies>
<dependency>
<groupId>org.thingsboard.common.transport</groupId>
<artifactId>transport-api</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>log4j-over-slf4j</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
<!-- lechan start -->
<dependency>
<groupId>org.eclipse.leshan</groupId>
<artifactId>leshan-server-cf</artifactId>
</dependency>
<!-- <dependency>-->
<!-- <groupId>org.eclipse.leshan</groupId>-->
<!-- <artifactId>leshan-server-cf</artifactId>-->
<!-- </dependency> -->
<dependency>
<groupId>org.eclipse.leshan</groupId>
<artifactId>leshan-client-cf</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.leshan</groupId>
<artifactId>leshan-server-redis</artifactId>
</dependency>
<!-- <dependency>-->
<!-- <groupId>org.eclipse.californium</groupId>-->
<!-- <artifactId>californium-core</artifactId>-->
<!-- </dependency>-->
<!-- leshan finish -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.californium</groupId>
<artifactId>californium-core</artifactId>
<version>${californium.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.californium</groupId>
<artifactId>element-connector</artifactId>
<version>${californium.version}</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
</dependencies>
</project>

101
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/LwM2MTransportBootstrapServerConfiguration.java

@ -1,101 +0,0 @@
/**
* Copyright © 2016-2020 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.transport.lwm2m.bootstrap;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.californium.scandium.config.DtlsConnectorConfig;
import org.eclipse.leshan.core.model.StaticModel;
import org.eclipse.leshan.server.bootstrap.BootstrapSessionManager;
import org.eclipse.leshan.server.californium.bootstrap.LeshanBootstrapServer;
import org.eclipse.leshan.server.californium.bootstrap.LeshanBootstrapServerBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;
import org.thingsboard.server.transport.lwm2m.bootstrap.secure.LwM2MBootstrapSecurityStore;
import org.thingsboard.server.transport.lwm2m.bootstrap.secure.LwM2MInMemoryBootstrapConfigStore;
import org.thingsboard.server.transport.lwm2m.bootstrap.secure.LwM2MSetSecurityStoreBootstrap;
import org.thingsboard.server.transport.lwm2m.bootstrap.secure.LwM2mDefaultBootstrapSessionManager;
import org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode;
import org.thingsboard.server.transport.lwm2m.server.LwM2MTransportContextServer;
import static org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode.X509;
import static org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode.RPK;
import static org.thingsboard.server.transport.lwm2m.server.LwM2MTransportHandler.getCoapConfig;
@Slf4j
@Component
@ConditionalOnExpression("('${service.type:null}'=='tb-transport' && '${transport.lwm2m.enabled:false}'=='true'&& '${transport.lwm2m.bootstrap.enable:false}'=='true') || ('${service.type:null}'=='monolith' && '${transport.lwm2m.enabled}'=='true'&& '${transport.lwm2m.bootstrap.enable}'=='true')")
public class LwM2MTransportBootstrapServerConfiguration {
@Autowired
private LwM2MTransportContextBootstrap contextBs;
@Autowired
private LwM2MTransportContextServer contextS;
@Autowired
private LwM2MBootstrapSecurityStore lwM2MBootstrapSecurityStore;
@Autowired
private LwM2MInMemoryBootstrapConfigStore lwM2MInMemoryBootstrapConfigStore;
@Primary
@Bean(name = "leshanBootstrapCert")
public LeshanBootstrapServer getLeshanBootstrapServerCert() {
log.info("Prepare and start BootstrapServerCert... PostConstruct");
return getLeshanBootstrapServer(this.contextBs.getCtxBootStrap().getBootstrapPortCert(), this.contextBs.getCtxBootStrap().getBootstrapSecurePortCert(), X509);
}
@Bean(name = "leshanBootstrapRPK")
public LeshanBootstrapServer getLeshanBootstrapServerRPK() {
log.info("Prepare and start BootstrapServerRPK... PostConstruct");
return getLeshanBootstrapServer(this.contextBs.getCtxBootStrap().getBootstrapPort(), this.contextBs.getCtxBootStrap().getBootstrapSecurePort(), RPK);
}
public LeshanBootstrapServer getLeshanBootstrapServer(Integer bootstrapPort, Integer bootstrapSecurePort, LwM2MSecurityMode dtlsMode) {
LeshanBootstrapServerBuilder builder = new LeshanBootstrapServerBuilder();
builder.setLocalAddress(this.contextBs.getCtxBootStrap().getBootstrapHost(), bootstrapPort);
builder.setLocalSecureAddress(this.contextBs.getCtxBootStrap().getBootstrapSecureHost(), bootstrapSecurePort);
/** Create CoAP Config */
builder.setCoapConfig(getCoapConfig ());
/** ConfigStore */
builder.setConfigStore(lwM2MInMemoryBootstrapConfigStore);
/** SecurityStore */
builder.setSecurityStore(lwM2MBootstrapSecurityStore);
/** Define model provider (Create Models )*/
builder.setModel(new StaticModel(contextS.getCtxServer().getModelsValue()));
/** Create and Set DTLS Config */
DtlsConnectorConfig.Builder dtlsConfig = new DtlsConnectorConfig.Builder();
dtlsConfig.setRecommendedCipherSuitesOnly(contextS.getCtxServer().isSupportDeprecatedCiphersEnable());
builder.setDtlsConfig(dtlsConfig);
/** Create credentials */
new LwM2MSetSecurityStoreBootstrap(builder, contextBs, contextS, dtlsMode);
BootstrapSessionManager sessionManager = new LwM2mDefaultBootstrapSessionManager(lwM2MBootstrapSecurityStore);
builder.setSessionManager(sessionManager);
/** Create BootstrapServer */
return builder.build();
}
}

70
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/LwM2MTransportBootstrapServerInitializer.java

@ -1,70 +0,0 @@
/**
* Copyright © 2016-2020 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.transport.lwm2m.bootstrap;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.leshan.server.californium.bootstrap.LeshanBootstrapServer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.stereotype.Service;
import org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
@Slf4j
@Service
@ConditionalOnExpression("('${service.type:null}'=='tb-transport' && '${transport.lwm2m.enabled}'=='true'&& '${transport.lwm2m.bootstrap.enable}'=='true') || ('${service.type:null}'=='monolith' && '${transport.lwm2m.enabled}'=='true'&& '${transport.lwm2m.bootstrap.enable}'=='true')")
public class LwM2MTransportBootstrapServerInitializer {
@Autowired
@Qualifier("leshanBootstrapCert")
private LeshanBootstrapServer lhBServerCert;
@Autowired
@Qualifier("leshanBootstrapRPK")
private LeshanBootstrapServer lhBServerRPK;
@Autowired
private LwM2MTransportContextBootstrap contextBS;
@PostConstruct
public void init() {
if (this.contextBS.getCtxBootStrap().isBootstrapStartAll()) {
this.lhBServerCert.start();
this.lhBServerRPK.start();
}
else {
if (this.contextBS.getCtxBootStrap().getBootStrapDtlsMode() == LwM2MSecurityMode.X509.code) {
this.lhBServerCert.start();
}
else {
this.lhBServerRPK.start();
}
}
}
@PreDestroy
public void shutdown() throws InterruptedException {
log.info("Stopping LwM2M transport Bootstrap Server!");
try {
lhBServerCert.destroy();
lhBServerRPK.destroy();
} finally {
}
log.info("LwM2M transport Bootstrap Server stopped!");
}
}

60
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/LwM2MTransportContextBootstrap.java

@ -1,60 +0,0 @@
/**
* Copyright © 2016-2020 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.transport.lwm2m.bootstrap;
/**
* Copyright © 2016-2020 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.stereotype.Component;
import org.thingsboard.server.common.transport.TransportContext;
import org.thingsboard.server.common.transport.lwm2m.LwM2MTransportConfigBootstrap;
import javax.annotation.PostConstruct;
@Slf4j
@Component
@ConditionalOnExpression("('${service.type:null}'=='tb-transport' && '${transport.lwm2m.enabled:false}'=='true') || '${service.type:null}'=='monolith'")
public class LwM2MTransportContextBootstrap extends TransportContext {
private LwM2MTransportConfigBootstrap ctxBootStrap;
@Autowired
LwM2MTransportConfigBootstrap lwM2MTransportConfigBootstarp;
@PostConstruct
public void init() {
this.ctxBootStrap = lwM2MTransportConfigBootstarp;
}
public LwM2MTransportConfigBootstrap getCtxBootStrap() {
return this.ctxBootStrap;
}
}

102
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/secure/LwM2MBootstrapConfig.java

@ -1,102 +0,0 @@
/**
* Copyright © 2016-2020 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.transport.lwm2m.bootstrap.secure;
import lombok.Builder;
import lombok.Data;
import org.eclipse.leshan.core.SecurityMode;
import org.eclipse.leshan.core.request.BindingMode;
import org.eclipse.leshan.core.util.Hex;
import org.eclipse.leshan.server.bootstrap.BootstrapConfig;
import java.nio.charset.StandardCharsets;
@Data
public class LwM2MBootstrapConfig {
/**
* interface BootstrapSecurityConfig
* servers: BootstrapServersSecurityConfig,
* bootstrapServer: ServerSecurityConfig,
* lwm2mServer: ServerSecurityConfig
* }
*/
/** -servers
* shortId: number,
* lifetime: number,
* defaultMinPeriod: number,
* notifIfDisabled: boolean,
* binding: string
* */
@Builder.Default
LwM2MBootstrapServers servers;
/** -bootstrapServer, lwm2mServer
* interface ServerSecurityConfig
* host?: string,
* port?: number,
* isBootstrapServer?: boolean,
* securityMode: string,
* clientPublicKeyOrId?: string,
* clientSecretKey?: string,
* serverPublicKey?: string;
* clientHoldOffTime?: number,
* serverId?: number,
* bootstrapServerAccountTimeout: number
* */
LwM2MServerBootstrap bootstrapServer;
LwM2MServerBootstrap lwm2mServer;
public BootstrapConfig getLwM2MBootstrapConfig() {
BootstrapConfig configBs = new BootstrapConfig();
/** Delete old security objects */
configBs.toDelete.add("/0");
configBs.toDelete.add("/1");
/** Server Configuration (object 1) as defined in LWM2M 1.0.x TS. */
BootstrapConfig.ServerConfig server0 = new BootstrapConfig.ServerConfig();
server0.shortId = servers.getShortId();
server0.lifetime = servers.getLifetime();
server0.defaultMinPeriod = servers.getDefaultMinPeriod();
server0.notifIfDisabled = servers.isNotifIfDisabled();
server0.binding = BindingMode.valueOf(servers.getBinding());
configBs.servers.put(0, server0);
/** Security Configuration (object 0) as defined in LWM2M 1.0.x TS. Bootstrap instance = 0 */
this.bootstrapServer.setBootstrapServerIs(true);
configBs.security.put(0, setServerSecuruty(this.bootstrapServer.getHost(), this.bootstrapServer.getPort(), this.bootstrapServer.isBootstrapServerIs(), this.bootstrapServer.getSecurityMode(), this.bootstrapServer.getClientPublicKeyOrId(), this.bootstrapServer.getServerPublicKey(), this.bootstrapServer.getClientSecretKey(), this.bootstrapServer.getServerId()));
/** Security Configuration (object 0) as defined in LWM2M 1.0.x TS. Server instance = 1 */
configBs.security.put(1, setServerSecuruty(this.lwm2mServer.getHost(), this.lwm2mServer.getPort(), this.lwm2mServer.isBootstrapServerIs(), this.lwm2mServer.getSecurityMode(), this.lwm2mServer.getClientPublicKeyOrId(), this.lwm2mServer.getServerPublicKey(), this.lwm2mServer.getClientSecretKey(), this.lwm2mServer.getServerId()));
return configBs;
}
private BootstrapConfig.ServerSecurity setServerSecuruty(String host, Integer port, boolean bootstrapServer, String securityMode, String clientPublicKey, String serverPublicKey, String secretKey, int serverId) {
BootstrapConfig.ServerSecurity serverSecurity = new BootstrapConfig.ServerSecurity();
serverSecurity.uri = "coaps://" + host + ":" + Integer.toString(port);
serverSecurity.bootstrapServer = bootstrapServer;
serverSecurity.securityMode = SecurityMode.valueOf(securityMode);
serverSecurity.publicKeyOrId = setPublicKeyOrId(clientPublicKey, securityMode);
serverSecurity.serverPublicKey = (serverPublicKey != null && !serverPublicKey.isEmpty()) ? Hex.decodeHex(serverPublicKey.toCharArray()) : new byte[]{};
serverSecurity.secretKey = (secretKey != null && !secretKey.isEmpty()) ? Hex.decodeHex(secretKey.toCharArray()) : new byte[]{};
serverSecurity.serverId = serverId;
return serverSecurity;
}
private byte[] setPublicKeyOrId(String publicKeyOrIdStr, String securityMode) {
byte[] publicKey = (publicKeyOrIdStr == null || publicKeyOrIdStr.isEmpty()) ? new byte[]{} :
SecurityMode.valueOf(securityMode).equals(SecurityMode.PSK) ? publicKeyOrIdStr.getBytes(StandardCharsets.UTF_8) :
Hex.decodeHex(publicKeyOrIdStr.toCharArray());
return publicKey;
}
}

181
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/secure/LwM2MBootstrapSecurityStore.java

@ -1,181 +0,0 @@
/**
* Copyright © 2016-2020 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.transport.lwm2m.bootstrap.secure;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.JsonObject;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.leshan.core.SecurityMode;
import org.eclipse.leshan.core.util.Hex;
import org.eclipse.leshan.core.util.SecurityUtil;
import org.eclipse.leshan.server.bootstrap.BootstrapConfig;
import org.eclipse.leshan.server.bootstrap.EditableBootstrapConfigStore;
import org.eclipse.leshan.server.bootstrap.InvalidConfigurationException;
import org.eclipse.leshan.server.security.BootstrapSecurityStore;
import org.eclipse.leshan.server.security.SecurityInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.stereotype.Component;
import org.thingsboard.server.transport.lwm2m.secure.LwM2MGetSecurityInfo;
import org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode;
import org.thingsboard.server.transport.lwm2m.secure.ReadResultSecurityStore;
import org.thingsboard.server.transport.lwm2m.utils.TypeServer;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.Arrays;
import java.util.List;
import static org.thingsboard.server.transport.lwm2m.server.LwM2MTransportHandler.*;
@Slf4j
@Component("LwM2MBootstrapSecurityStore")
@ConditionalOnExpression("('${service.type:null}'=='tb-transport' && '${transport.lwm2m.enabled:false}'=='true' && '${transport.lwm2m.bootstrap.enable:false}'=='true') || ('${service.type:null}'=='monolith' && '${transport.lwm2m.enabled}'=='true' && '${transport.lwm2m.bootstrap.enable}'=='true')")
public class LwM2MBootstrapSecurityStore implements BootstrapSecurityStore {
private final EditableBootstrapConfigStore bootstrapConfigStore;
@Autowired
LwM2MGetSecurityInfo lwM2MGetSecurityInfo;
public LwM2MBootstrapSecurityStore(EditableBootstrapConfigStore bootstrapConfigStore) {
this.bootstrapConfigStore = bootstrapConfigStore;
}
@Override
public List<SecurityInfo> getAllByEndpoint(String endPoint) {
String endPointKey = endPoint;
ReadResultSecurityStore store = lwM2MGetSecurityInfo.getSecurityInfo(endPointKey, TypeServer.BOOTSTRAP);
if (store.getBootstrapJsonCredential() != null) {
/** add value to store from BootstrapJson */
this.setBootstrapConfigScurityInfo(store);
BootstrapConfig bsConfigNew = store.getBootstrapConfig();
if (bsConfigNew != null) {
try {
for (String config : bootstrapConfigStore.getAll().keySet()) {
if (config.equals(endPoint)) {
bootstrapConfigStore.remove(config);
}
}
bootstrapConfigStore.add(endPoint, bsConfigNew);
} catch (InvalidConfigurationException e) {
e.printStackTrace();
}
return store.getSecurityInfo() == null ? null : Arrays.asList(store.getSecurityInfo());
}
}
return null;
}
@Override
public SecurityInfo getByIdentity(String identity) {
ReadResultSecurityStore store = lwM2MGetSecurityInfo.getSecurityInfo(identity, TypeServer.BOOTSTRAP);
/** add value to store from BootstrapJson */
this.setBootstrapConfigScurityInfo(store);
if (store.getSecurityMode() < LwM2MSecurityMode.DEFAULT_MODE.code) {
BootstrapConfig bsConfig = store.getBootstrapConfig();
if (bsConfig.security != null) {
try {
bootstrapConfigStore.add(store.getEndPoint(), bsConfig);
} catch (InvalidConfigurationException e) {
e.printStackTrace();
}
return store.getSecurityInfo();
}
}
return null;
}
private void setBootstrapConfigScurityInfo(ReadResultSecurityStore store) {
/** BootstrapConfig */
LwM2MBootstrapConfig lwM2MBootstrapConfig = this.getParametersBootstrap(store);
if (lwM2MBootstrapConfig != null) {
/** Security info */
switch (SecurityMode.valueOf(lwM2MBootstrapConfig.getBootstrapServer().getSecurityMode())) {
/** Use RPK only */
case PSK:
store.setSecurityInfo(SecurityInfo.newPreSharedKeyInfo(store.getEndPoint(),
lwM2MBootstrapConfig.getBootstrapServer().getClientPublicKeyOrId(),
Hex.decodeHex(lwM2MBootstrapConfig.getBootstrapServer().getClientSecretKey().toCharArray())));
store.setSecurityMode(SecurityMode.PSK.code);
break;
case RPK:
try {
store.setSecurityInfo(SecurityInfo.newRawPublicKeyInfo(store.getEndPoint(),
SecurityUtil.publicKey.decode(Hex.decodeHex(lwM2MBootstrapConfig.getBootstrapServer().getClientPublicKeyOrId().toCharArray()))));
store.setSecurityMode(SecurityMode.RPK.code);
break;
} catch (IOException | GeneralSecurityException e) {
log.error("Unable to decode Client public key for [{}] [{}]", store.getEndPoint(), e.getMessage());
}
case X509:
store.setSecurityInfo(SecurityInfo.newX509CertInfo(store.getEndPoint()));
store.setSecurityMode(SecurityMode.X509.code);
break;
case NO_SEC:
store.setSecurityMode(SecurityMode.NO_SEC.code);
store.setSecurityInfo(null);
break;
default:
}
BootstrapConfig bootstrapConfig = lwM2MBootstrapConfig.getLwM2MBootstrapConfig();
store.setBootstrapConfig(bootstrapConfig);
}
}
private LwM2MBootstrapConfig getParametersBootstrap(ReadResultSecurityStore store) {
try {
JsonObject bootstrapJsonCredential = store.getBootstrapJsonCredential();
ObjectMapper mapper = new ObjectMapper();
LwM2MBootstrapConfig lwM2MBootstrapConfig = mapper.readValue(bootstrapJsonCredential.toString(), LwM2MBootstrapConfig.class);
JsonObject bootstrapObject = getBootstrapParametersFromThingsboard(store.getDeviceProfile());
lwM2MBootstrapConfig.servers = mapper.readValue(bootstrapObject.get(SERVERS).toString(), LwM2MBootstrapServers.class);
LwM2MServerBootstrap profileServerBootstrap = mapper.readValue(bootstrapObject.get(BOOTSTRAP_SERVER).toString(), LwM2MServerBootstrap.class);
LwM2MServerBootstrap profileLwm2mServer = mapper.readValue(bootstrapObject.get(LWM2M_SERVER).toString(), LwM2MServerBootstrap.class);
if (getValidatedSecurityMode(lwM2MBootstrapConfig.bootstrapServer, profileServerBootstrap, lwM2MBootstrapConfig.lwm2mServer, profileLwm2mServer)) {
lwM2MBootstrapConfig.bootstrapServer = new LwM2MServerBootstrap(lwM2MBootstrapConfig.bootstrapServer, profileServerBootstrap);
lwM2MBootstrapConfig.lwm2mServer = new LwM2MServerBootstrap(lwM2MBootstrapConfig.lwm2mServer, profileLwm2mServer);
return lwM2MBootstrapConfig;
}
else {
log.error(" [{}] Different values SecurityMode between of client and profile.", store.getEndPoint());
log.error(LOG_LW2M_ERROR + " getParametersBootstrap: [{}] Different values SecurityMode between of client and profile.", store.getEndPoint());
String logMsg = String.format(LOG_LW2M_ERROR + " getParametersBootstrap: %s Different values SecurityMode between of client and profile.", store.getEndPoint());
// sentLogsToThingsboard(logMsg, store.getEndPoint());
return null;
}
} catch (JsonProcessingException e) {
log.error("Unable to decode Json or Certificate for [{}] [{}]", store.getEndPoint(), e.getMessage());
return null;
}
}
/**
* Bootstrap security have to sync between (bootstrapServer in credential and bootstrapServer in profile)
* and (lwm2mServer in credential and lwm2mServer in profile
* @param bootstrapFromCredential - Bootstrap -> Security of bootstrapServer in credential
* @param profileServerBootstrap - Bootstrap -> Security of bootstrapServer in profile
* @param lwm2mFromCredential - Bootstrap -> Security of lwm2mServer in credential
* @param profileLwm2mServer - Bootstrap -> Security of lwm2mServer in profile
* @return false if not sync between SecurityMode of Bootstrap credential and profile
*/
private boolean getValidatedSecurityMode(LwM2MServerBootstrap bootstrapFromCredential, LwM2MServerBootstrap profileServerBootstrap, LwM2MServerBootstrap lwm2mFromCredential, LwM2MServerBootstrap profileLwm2mServer) {
return (bootstrapFromCredential.getSecurityMode().equals(profileServerBootstrap.getSecurityMode()) &&
lwm2mFromCredential.getSecurityMode().equals(profileLwm2mServer.getSecurityMode()));
}
}

33
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/secure/LwM2MBootstrapServers.java

@ -1,33 +0,0 @@
/**
* Copyright © 2016-2020 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.transport.lwm2m.bootstrap.secure;
import lombok.Builder;
import lombok.Data;
@Data
public class LwM2MBootstrapServers {
@Builder.Default
private Integer shortId = 123;
@Builder.Default
private Integer lifetime = 300;
@Builder.Default
private Integer defaultMinPeriod = 1;
@Builder.Default
private boolean notifIfDisabled = true;
@Builder.Default
private String binding = "U";
}

71
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/secure/LwM2MInMemoryBootstrapConfigStore.java

@ -1,71 +0,0 @@
/**
* Copyright © 2016-2020 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.transport.lwm2m.bootstrap.secure;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.leshan.server.bootstrap.BootstrapConfig;
import org.eclipse.leshan.server.bootstrap.InMemoryBootstrapConfigStore;
import org.eclipse.leshan.server.bootstrap.InvalidConfigurationException;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.stereotype.Component;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
@Slf4j
@Component("LwM2MInMemoryBootstrapConfigStore")
@ConditionalOnExpression("('${service.type:null}'=='tb-transport' && '${transport.lwm2m.enabled:false}'=='true' && '${transport.lwm2m.bootstrap.enable:false}'=='true') || ('${service.type:null}'=='monolith' && '${transport.lwm2m.enabled}'=='true'&& '${transport.lwm2m.bootstrap.enable}'=='true')")
public class LwM2MInMemoryBootstrapConfigStore extends InMemoryBootstrapConfigStore {
private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
private final Lock readLock = readWriteLock.readLock();
private final Lock writeLock = readWriteLock.writeLock();
@Override
public Map<String, BootstrapConfig> getAll() {
readLock.lock();
try {
return super.getAll();
} finally {
readLock.unlock();
}
}
@Override
public void add(String endpoint, BootstrapConfig config) throws InvalidConfigurationException {
writeLock.lock();
try {
addToStore(endpoint, config);
} finally {
writeLock.unlock();
}
}
@Override
public BootstrapConfig remove(String enpoint) {
writeLock.lock();
try {
BootstrapConfig res = super.remove(enpoint);
return res;
} finally {
writeLock.unlock();
}
}
public void addToStore(String endpoint, BootstrapConfig config) throws InvalidConfigurationException {
super.add(endpoint, config);
}
}

65
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/secure/LwM2MServerBootstrap.java

@ -1,65 +0,0 @@
/**
* Copyright © 2016-2020 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.transport.lwm2m.bootstrap.secure;
import lombok.Builder;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.leshan.core.SecurityMode;
@Slf4j
@Data
public class LwM2MServerBootstrap {
@Builder.Default
String clientPublicKeyOrId = "";
@Builder.Default
String clientSecretKey = "";
@Builder.Default
String serverPublicKey = "";
@Builder.Default
Integer clientHoldOffTime = 1;
@Builder.Default
Integer bootstrapServerAccountTimeout = 0;
@Builder.Default
String host = "0.0.0.0";
@Builder.Default
Integer port = 0;
@Builder.Default
String securityMode = SecurityMode.NO_SEC.name();
@Builder.Default
Integer serverId = 123;
@Builder.Default
boolean bootstrapServerIs = false;
public LwM2MServerBootstrap(){};
public LwM2MServerBootstrap(LwM2MServerBootstrap bootstrapFromCredential, LwM2MServerBootstrap profileServerBootstrap) {
this.clientPublicKeyOrId = bootstrapFromCredential.getClientPublicKeyOrId();
this.clientSecretKey = bootstrapFromCredential.getClientSecretKey();
this.serverPublicKey = profileServerBootstrap.getServerPublicKey();
this.clientHoldOffTime = profileServerBootstrap.getClientHoldOffTime();
this.bootstrapServerAccountTimeout = profileServerBootstrap.getBootstrapServerAccountTimeout();
this.host = (profileServerBootstrap.getHost().equals("0.0.0.0")) ? "localhost" : profileServerBootstrap.getHost();
this.port = profileServerBootstrap.getPort();
this.securityMode = profileServerBootstrap.getSecurityMode();
this.serverId = profileServerBootstrap.getServerId();
this.bootstrapServerIs = profileServerBootstrap.bootstrapServerIs;
}
}

205
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/secure/LwM2MSetSecurityStoreBootstrap.java

@ -1,205 +0,0 @@
/**
* Copyright © 2016-2020 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.transport.lwm2m.bootstrap.secure;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.leshan.core.util.Hex;
import org.eclipse.leshan.server.californium.bootstrap.LeshanBootstrapServerBuilder;
import org.eclipse.leshan.server.security.EditableSecurityStore;
import org.thingsboard.server.transport.lwm2m.bootstrap.LwM2MTransportContextBootstrap;
import org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode;
import org.thingsboard.server.transport.lwm2m.server.LwM2MTransportContextServer;
import java.math.BigInteger;
import java.security.AlgorithmParameters;
import java.security.KeyStore;
import java.security.PublicKey;
import java.security.PrivateKey;
import java.security.KeyFactory;
import java.security.GeneralSecurityException;
import java.security.KeyStoreException;
import java.security.cert.X509Certificate;
import java.security.interfaces.ECPublicKey;
import java.security.spec.ECGenParameterSpec;
import java.security.spec.ECParameterSpec;
import java.security.spec.ECPublicKeySpec;
import java.security.spec.ECPoint;
import java.security.spec.KeySpec;
import java.security.spec.ECPrivateKeySpec;
import java.util.Arrays;
import static org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode.NO_SEC;
import static org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode.X509;
@Slf4j
@Data
public class LwM2MSetSecurityStoreBootstrap {
private KeyStore keyStore;
private PublicKey publicKey;
private PrivateKey privateKey;
private LwM2MTransportContextBootstrap contextBs;
private LwM2MTransportContextServer contextS;
private LeshanBootstrapServerBuilder builder;
EditableSecurityStore securityStore;
public LwM2MSetSecurityStoreBootstrap(LeshanBootstrapServerBuilder builder, LwM2MTransportContextBootstrap contextBs, LwM2MTransportContextServer contextS, LwM2MSecurityMode dtlsMode) {
this.builder = builder;
this.contextBs = contextBs;
this.contextS = contextS;
/** Set securityStore with new registrationStore */
switch (dtlsMode) {
/** Use No_Sec only */
case NO_SEC:
setServerWithX509Cert(NO_SEC.code);
break;
/** Use PSK/RPK */
case PSK:
case RPK:
setRPK();
break;
case X509:
setServerWithX509Cert(X509.code);
break;
/** Use X509_EST only */
case X509_EST:
// TODO support sentinel pool and make pool configurable
break;
/** Use ather X509, PSK, No_Sec ?? */
default:
break;
}
}
private void setRPK() {
try {
/** Get Elliptic Curve Parameter spec for secp256r1 */
AlgorithmParameters algoParameters = AlgorithmParameters.getInstance("EC");
algoParameters.init(new ECGenParameterSpec("secp256r1"));
ECParameterSpec parameterSpec = algoParameters.getParameterSpec(ECParameterSpec.class);
if (this.contextBs.getCtxBootStrap().getBootstrapPublicX() != null && !this.contextBs.getCtxBootStrap().getBootstrapPublicX().isEmpty() && this.contextBs.getCtxBootStrap().getBootstrapPublicY() != null && !this.contextBs.getCtxBootStrap().getBootstrapPublicY().isEmpty()) {
/** Get point values */
byte[] publicX = Hex.decodeHex(this.contextBs.getCtxBootStrap().getBootstrapPublicX().toCharArray());
byte[] publicY = Hex.decodeHex(this.contextBs.getCtxBootStrap().getBootstrapPublicY().toCharArray());
/** Create key specs */
KeySpec publicKeySpec = new ECPublicKeySpec(new ECPoint(new BigInteger(publicX), new BigInteger(publicY)),
parameterSpec);
/** Get keys */
this.publicKey = KeyFactory.getInstance("EC").generatePublic(publicKeySpec);
}
if (this.contextBs.getCtxBootStrap().getBootstrapPrivateS() != null && !this.contextBs.getCtxBootStrap().getBootstrapPrivateS().isEmpty()) {
/** Get point values */
byte[] privateS = Hex.decodeHex(this.contextBs.getCtxBootStrap().getBootstrapPrivateS().toCharArray());
/** Create key specs */
KeySpec privateKeySpec = new ECPrivateKeySpec(new BigInteger(privateS), parameterSpec);
/** Get keys */
this.privateKey = KeyFactory.getInstance("EC").generatePrivate(privateKeySpec);
}
if (this.publicKey != null && this.publicKey.getEncoded().length > 0 &&
this.privateKey != null && this.privateKey.getEncoded().length > 0) {
this.builder.setPublicKey(this.publicKey);
this.builder.setPrivateKey(this.privateKey);
this.contextBs.getCtxBootStrap().setBootstrapPublicKey(this.publicKey);
getParamsRPK();
}
} catch (GeneralSecurityException | IllegalArgumentException e) {
log.error("[{}] Failed generate Server PSK/RPK", e.getMessage());
throw new RuntimeException(e);
}
}
private void setServerWithX509Cert(int securityModeCode) {
try {
if (this.contextS.getCtxServer().getKeyStoreValue() != null) {
KeyStore keyStoreServer = this.contextS.getCtxServer().getKeyStoreValue();
setBuilderX509();
X509Certificate rootCAX509Cert = (X509Certificate) keyStoreServer.getCertificate(this.contextS.getCtxServer().getRootAlias());
if (rootCAX509Cert != null && securityModeCode == X509.code) {
X509Certificate[] trustedCertificates = new X509Certificate[1];
trustedCertificates[0] = rootCAX509Cert;
this.builder.setTrustedCertificates(trustedCertificates);
} else {
/** by default trust all */
this.builder.setTrustedCertificates(new X509Certificate[0]);
}
}
else {
/** by default trust all */
this.builder.setTrustedCertificates(new X509Certificate[0]);
log.error("Unable to load X509 files for BootStrapServer");
}
} catch (KeyStoreException ex) {
log.error("[{}] Unable to load X509 files server", ex.getMessage());
}
}
private void setBuilderX509() {
/**
* For deb => KeyStorePathFile == yml or commandline: KEY_STORE_PATH_FILE
* For idea => KeyStorePathResource == common/transport/lwm2m/src/main/resources/credentials: in LwM2MTransportContextServer: credentials/serverKeyStore.jks
*/
try {
X509Certificate serverCertificate = (X509Certificate) this.contextS.getCtxServer().getKeyStoreValue().getCertificate(this.contextBs.getCtxBootStrap().getBootstrapAlias());
this.privateKey = (PrivateKey) this.contextS.getCtxServer().getKeyStoreValue().getKey(this.contextBs.getCtxBootStrap().getBootstrapAlias(), this.contextS.getCtxServer().getKeyStorePasswordServer() == null ? null : this.contextS.getCtxServer().getKeyStorePasswordServer().toCharArray());
if (this.privateKey != null && this.privateKey.getEncoded().length > 0) {
this.builder.setPrivateKey(this.privateKey);
}
if (serverCertificate != null) {
this.builder.setCertificateChain(new X509Certificate[]{serverCertificate});
this.contextBs.getCtxBootStrap().setBootstrapCertificate(serverCertificate);
}
} catch (Exception ex) {
log.error("[{}] Unable to load KeyStore files server", ex.getMessage());
}
}
private void getParamsRPK() {
if (this.publicKey instanceof ECPublicKey) {
/** Get x coordinate */
byte[] x = ((ECPublicKey) this.publicKey).getW().getAffineX().toByteArray();
if (x[0] == 0)
x = Arrays.copyOfRange(x, 1, x.length);
/** Get Y coordinate */
byte[] y = ((ECPublicKey) this.publicKey).getW().getAffineY().toByteArray();
if (y[0] == 0)
y = Arrays.copyOfRange(y, 1, y.length);
/** Get Curves params */
String params = ((ECPublicKey) this.publicKey).getParams().toString();
log.info(
" \nBootstrap uses RPK : \n Elliptic Curve parameters : [{}] \n Public x coord : [{}] \n Public y coord : [{}] \n Public Key (Hex): [{}] \n Private Key (Hex): [{}]",
params, Hex.encodeHexString(x), Hex.encodeHexString(y),
Hex.encodeHexString(this.publicKey.getEncoded()),
Hex.encodeHexString(this.privateKey.getEncoded()));
} else {
throw new IllegalStateException("Unsupported Public Key Format (only ECPublicKey supported).");
}
}
// private void getParamsX509() {
// try {
// log.info("BootStrap uses X509 : \n X509 Certificate (Hex): [{}] \n Private Key (Hex): [{}]",
// Hex.encodeHexString(this.certificate.getEncoded()),
// Hex.encodeHexString(this.privateKey.getEncoded()));
// } catch (CertificateEncodingException e) {
// e.printStackTrace();
// }
// }
}

66
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/bootstrap/secure/LwM2mDefaultBootstrapSessionManager.java

@ -1,66 +0,0 @@
/**
* Copyright © 2016-2020 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.transport.lwm2m.bootstrap.secure;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.leshan.core.request.Identity;
import org.eclipse.leshan.server.bootstrap.BootstrapSession;
import org.eclipse.leshan.server.bootstrap.DefaultBootstrapSession;
import org.eclipse.leshan.server.bootstrap.DefaultBootstrapSessionManager;
import org.eclipse.leshan.server.security.BootstrapSecurityStore;
import org.eclipse.leshan.server.security.SecurityChecker;
import org.eclipse.leshan.server.security.SecurityInfo;
import java.util.Arrays;
import java.util.List;
@Slf4j
public class LwM2mDefaultBootstrapSessionManager extends DefaultBootstrapSessionManager {
private BootstrapSecurityStore bsSecurityStore;
private SecurityChecker securityChecker;
/**
* Create a {@link DefaultBootstrapSessionManager} using a default {@link SecurityChecker} to accept or refuse new
* {@link BootstrapSession}.
*
* @param bsSecurityStore the {@link BootstrapSecurityStore} used by default {@link SecurityChecker}.
*/
public LwM2mDefaultBootstrapSessionManager(BootstrapSecurityStore bsSecurityStore) {
this(bsSecurityStore, new SecurityChecker());
}
public LwM2mDefaultBootstrapSessionManager(BootstrapSecurityStore bsSecurityStore, SecurityChecker securityChecker) {
super(bsSecurityStore);
this.bsSecurityStore = bsSecurityStore;
this.securityChecker = securityChecker;
}
@Override
public BootstrapSession begin(String endpoint, Identity clientIdentity) {
boolean authorized;
if (bsSecurityStore != null) {
List<SecurityInfo> securityInfos = (clientIdentity.getPskIdentity() != null && !clientIdentity.getPskIdentity().isEmpty()) ? Arrays.asList(bsSecurityStore.getByIdentity(clientIdentity.getPskIdentity())) : bsSecurityStore.getAllByEndpoint(endpoint);
log.info("Bootstrap session started securityInfos: [{}]", securityInfos);
authorized = securityChecker.checkSecurityInfos(endpoint, clientIdentity, securityInfos);
} else {
authorized = true;
}
DefaultBootstrapSession session = new DefaultBootstrapSession(endpoint, clientIdentity, authorized);
log.info("Bootstrap session started : {}", session);
return session;
}
}

121
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/LWM2MGenerationPSkRPkECC.java

@ -1,121 +0,0 @@
/**
* Copyright © 2016-2020 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.transport.lwm2m.secure;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.leshan.core.util.Hex;
import java.security.SecureRandom;
import java.security.KeyPairGenerator;
import java.security.KeyPair;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.InvalidAlgorithmParameterException;
import java.security.interfaces.ECPublicKey;
import java.security.spec.ECGenParameterSpec;
import java.util.Arrays;
@Slf4j
public class LWM2MGenerationPSkRPkECC {
public LWM2MGenerationPSkRPkECC(Integer dtlsMode) {
switch (LwM2MSecurityMode.fromSecurityMode(dtlsMode)) {
case PSK:
generationPSkKey();
break;
case RPK:
generationRPKECCKey();
}
}
public LWM2MGenerationPSkRPkECC() {
generationPSkKey();
generationRPKECCKey();
}
private void generationPSkKey() {
/** PSK */
int lenPSkKey = 32;
/** Start PSK
* Clients and Servers MUST support PSK keys of up to 64 bytes in length, as required by [RFC7925]
* SecureRandom object must be unpredictable, and all SecureRandom output sequences must be cryptographically strong, as described in [RFC4086]
* */
SecureRandom randomPSK = new SecureRandom();
byte bytesPSK[] = new byte[lenPSkKey];
randomPSK.nextBytes(bytesPSK);
log.info("\nCreating new PSK: \n for the next start PSK -> security key: [{}]", Hex.encodeHexString(bytesPSK));
}
private void generationRPKECCKey() {
/** RPK */
String algorithm = "EC";
String provider = "SunEC";
String nameParameterSpec = "secp256r1";
/** Start RPK
* Elliptic Curve parameters : [secp256r1 [NIST P-256, X9.62 prime256v1] (1.2.840.10045.3.1.7)]
* */
KeyPairGenerator kpg = null;
try {
kpg = KeyPairGenerator.getInstance(algorithm, provider);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchProviderException e) {
e.printStackTrace();
}
ECGenParameterSpec ecsp = new ECGenParameterSpec(nameParameterSpec);
try {
kpg.initialize(ecsp);
} catch (InvalidAlgorithmParameterException e) {
e.printStackTrace();
}
KeyPair kp = kpg.genKeyPair();
PrivateKey privKey = kp.getPrivate();
PublicKey pubKey = kp.getPublic();
if (pubKey instanceof ECPublicKey) {
ECPublicKey ecPublicKey = (ECPublicKey) pubKey;
/** Get x coordinate */
byte[] x = ecPublicKey.getW().getAffineX().toByteArray();
if (x[0] == 0)
x = Arrays.copyOfRange(x, 1, x.length);
/** Get Y coordinate */
byte[] y = ecPublicKey.getW().getAffineY().toByteArray();
if (y[0] == 0)
y = Arrays.copyOfRange(y, 1, y.length);
/** Get Curves params */
String privHex = Hex.encodeHexString(privKey.getEncoded());
log.info("\nCreating new RPK for the next start... \n" +
" Elliptic Curve parameters : [{}] \n" +
" public_x : [{}] \n" +
" public_y : [{}] \n" +
" private_s : [{}] \n" +
" Public Key (Hex): [{}]\n" +
" Private Key (Hex): [{}]",
ecPublicKey.getParams().toString(),
Hex.encodeHexString(x),
Hex.encodeHexString(y),
privHex.substring(privHex.length() - 64),
Hex.encodeHexString(pubKey.getEncoded()),
Hex.encodeHexString(privKey.getEncoded()));
}
}
}

170
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/LwM2MGetSecurityInfo.java

@ -1,170 +0,0 @@
/**
* Copyright © 2016-2020 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.transport.lwm2m.secure;
import com.google.gson.JsonObject;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.leshan.core.util.Hex;
import org.eclipse.leshan.core.util.SecurityUtil;
import org.eclipse.leshan.server.security.SecurityInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.stereotype.Component;
import org.thingsboard.server.common.data.DeviceProfile;
import org.thingsboard.server.common.transport.TransportServiceCallback;
import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceLwM2MCredentialsRequestMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceCredentialsResponseMsg;
import org.thingsboard.server.transport.lwm2m.bootstrap.LwM2MTransportContextBootstrap;
import org.thingsboard.server.transport.lwm2m.server.LwM2MTransportContextServer;
import org.thingsboard.server.transport.lwm2m.server.LwM2MTransportHandler;
import org.thingsboard.server.transport.lwm2m.utils.TypeServer;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.PublicKey;
import java.util.Optional;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import static org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode.*;
@Slf4j
@Component("LwM2MGetSecurityInfo")
@ConditionalOnExpression("('${service.type:null}'=='tb-transport' && '${transport.lwm2m.enabled:false}'=='true' ) || ('${service.type:null}'=='monolith' && '${transport.lwm2m.enabled}'=='true')")
public class LwM2MGetSecurityInfo {
@Autowired
public LwM2MTransportContextServer contextS;
@Autowired
public LwM2MTransportContextBootstrap contextBS;
public ReadResultSecurityStore getSecurityInfo(String endPoint, TypeServer keyValue) {
CountDownLatch latch = new CountDownLatch(1);
final ReadResultSecurityStore[] resultSecurityStore = new ReadResultSecurityStore[1];
contextS.getTransportService().process(ValidateDeviceLwM2MCredentialsRequestMsg.newBuilder().setCredentialsId(endPoint).build(),
new TransportServiceCallback<ValidateDeviceCredentialsResponseMsg>() {
@Override
public void onSuccess(ValidateDeviceCredentialsResponseMsg msg) {
String credentialsBody = msg.getCredentialsBody();
resultSecurityStore[0] = putSecurityInfo(endPoint, msg.getDeviceInfo().getDeviceName(), credentialsBody, keyValue);
resultSecurityStore[0].setMsg(msg);
Optional<DeviceProfile> deviceProfileOpt = LwM2MTransportHandler.decode(msg.getProfileBody().toByteArray());
deviceProfileOpt.ifPresent(profile -> resultSecurityStore[0].setDeviceProfile(profile));
latch.countDown();
}
@Override
public void onError(Throwable e) {
log.trace("[{}] Failed to process credentials PSK: {}", endPoint, e);
resultSecurityStore[0] = putSecurityInfo(endPoint, null, null, null);
latch.countDown();
}
});
try {
latch.await(contextS.getCtxServer().getTimeout(), TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
}
return resultSecurityStore[0];
}
private ReadResultSecurityStore putSecurityInfo(String endPoint, String deviceName, String jsonStr, TypeServer keyValue) {
ReadResultSecurityStore result = new ReadResultSecurityStore();
JsonObject objectMsg = LwM2MTransportHandler.validateJson(jsonStr);
if (objectMsg != null && !objectMsg.isJsonNull()) {
JsonObject object = (objectMsg.has(keyValue.type) && !objectMsg.get(keyValue.type).isJsonNull()) ? objectMsg.get(keyValue.type).getAsJsonObject() : null;
/**
* Only PSK
*/
String endPointPsk = (objectMsg.has("client")
&& objectMsg.get("client").getAsJsonObject().has("endpoint")
&& objectMsg.get("client").getAsJsonObject().get("endpoint").isJsonPrimitive()) ? objectMsg.get("client").getAsJsonObject().get("endpoint").getAsString() : null;
endPoint = (endPointPsk == null || endPointPsk.isEmpty()) ? endPoint : endPointPsk;
if (object != null && !object.isJsonNull()) {
if (keyValue.equals(TypeServer.BOOTSTRAP)) {
result.setBootstrapJsonCredential(object);
result.setEndPoint(endPoint);
} else {
LwM2MSecurityMode lwM2MSecurityMode = LwM2MSecurityMode.fromSecurityMode(object.get("securityConfigClientMode").getAsString().toLowerCase());
switch (lwM2MSecurityMode) {
case NO_SEC:
getClientSecurityInfoNoSec(result);
break;
case PSK:
getClientSecurityInfoPSK(result, endPoint, object);
break;
case RPK:
getClientSecurityInfoRPK(result, endPoint, object);
break;
case X509:
getClientSecurityInfoX509(result, endPoint);
break;
default:
break;
}
}
}
}
return result;
}
private void getClientSecurityInfoNoSec(ReadResultSecurityStore result) {
result.setSecurityInfo(null);
result.setSecurityMode(NO_SEC.code);
}
private void getClientSecurityInfoPSK(ReadResultSecurityStore result, String endPoint, JsonObject object) {
/** PSK Deserialization */
String identity = (object.has("identity") && object.get("identity").isJsonPrimitive()) ? object.get("identity").getAsString() : null;
if (identity != null && !identity.isEmpty()) {
try {
byte[] key = (object.has("key") && object.get("key").isJsonPrimitive()) ? Hex.decodeHex(object.get("key").getAsString().toCharArray()) : null;
if (key != null && key.length > 0) {
if (endPoint != null && !endPoint.isEmpty()) {
result.setSecurityInfo(SecurityInfo.newPreSharedKeyInfo(endPoint, identity, key));
result.setSecurityMode(PSK.code);
}
}
} catch (IllegalArgumentException e) {
log.error("Missing PSK key: " + e.getMessage());
}
} else {
log.error("Missing PSK identity");
}
}
private void getClientSecurityInfoRPK(ReadResultSecurityStore result, String endpoint, JsonObject object) {
try {
if (object.has("key") && object.get("key").isJsonPrimitive()) {
byte[] rpkkey = Hex.decodeHex(object.get("key").getAsString().toLowerCase().toCharArray());
PublicKey key = SecurityUtil.publicKey.decode(rpkkey);
result.setSecurityInfo(SecurityInfo.newRawPublicKeyInfo(endpoint, key));
result.setSecurityMode(RPK.code);
} else {
log.error("Missing RPK key");
}
} catch (IllegalArgumentException | IOException | GeneralSecurityException e) {
log.error("RPK: Invalid security info content: " + e.getMessage());
}
}
private void getClientSecurityInfoX509(ReadResultSecurityStore result, String endpoint) {
result.setSecurityInfo(SecurityInfo.newX509CertInfo(endpoint));
result.setSecurityMode(X509.code);
}
}

58
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/LwM2MSecurityMode.java

@ -1,58 +0,0 @@
/**
* Copyright © 2016-2020 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.transport.lwm2m.secure;
public enum LwM2MSecurityMode {
PSK(0, "psk"),
RPK(1, "rpk"),
X509(2, "x509"),
NO_SEC(3, "no_sec"),
X509_EST(4, "x509_est"),
REDIS(7, "redis"),
DEFAULT_MODE(255, "default_mode");
public int code;
public String subEndpoint;
LwM2MSecurityMode(int code, String subEndpoint) {
this.code = code;
this.subEndpoint = subEndpoint;
}
public static LwM2MSecurityMode fromSecurityMode(long code) {
return fromSecurityMode((int) code);
}
public static LwM2MSecurityMode fromSecurityMode(int code) {
for (LwM2MSecurityMode sm : LwM2MSecurityMode.values()) {
if (sm.code == code) {
return sm;
}
}
throw new IllegalArgumentException(String.format("Unsupported security code : %d", code));
}
public static LwM2MSecurityMode fromSecurityMode(String subEndpoint) {
for (LwM2MSecurityMode sm : LwM2MSecurityMode.values()) {
if (sm.subEndpoint.equals(subEndpoint)) {
return sm;
}
}
throw new IllegalArgumentException(String.format("Unsupported security subEndpoint : %d", subEndpoint));
}
}

84
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/LwM2mRPkCredentials.java

@ -1,84 +0,0 @@
/**
* Copyright © 2016-2020 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.transport.lwm2m.secure;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.leshan.core.util.Hex;
import java.math.BigInteger;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.AlgorithmParameters;
import java.security.KeyFactory;
import java.security.GeneralSecurityException;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.security.spec.ECGenParameterSpec;
import java.security.spec.ECParameterSpec;
import java.security.spec.ECPublicKeySpec;
import java.security.spec.KeySpec;
import java.security.spec.ECPrivateKeySpec;
import java.security.spec.ECPoint;
import java.util.List;
@Slf4j
@Data
public class LwM2mRPkCredentials {
private PublicKey serverPublicKey;
private PrivateKey serverPrivateKey;
private X509Certificate certificate;
private List<Certificate> trustStore;
/**
* create All key RPK credentials
* @param publX
* @param publY
* @param privS
*/
public LwM2mRPkCredentials(String publX, String publY, String privS) {
generatePublicKeyRPK(publX, publY, privS);
}
private void generatePublicKeyRPK(String publX, String publY, String privS) {
try {
/**Get Elliptic Curve Parameter spec for secp256r1 */
AlgorithmParameters algoParameters = AlgorithmParameters.getInstance("EC");
algoParameters.init(new ECGenParameterSpec("secp256r1"));
ECParameterSpec parameterSpec = algoParameters.getParameterSpec(ECParameterSpec.class);
if (publX != null && !publX.isEmpty() && publY != null && !publY.isEmpty()) {
// Get point values
byte[] publicX = Hex.decodeHex(publX.toCharArray());
byte[] publicY = Hex.decodeHex(publY.toCharArray());
/** Create key specs */
KeySpec publicKeySpec = new ECPublicKeySpec(new ECPoint(new BigInteger(publicX), new BigInteger(publicY)),
parameterSpec);
/** Get keys */
this.serverPublicKey = KeyFactory.getInstance("EC").generatePublic(publicKeySpec);
}
if (privS != null && !privS.isEmpty()) {
/** Get point values */
byte[] privateS = Hex.decodeHex(privS.toCharArray());
/** Create key specs */
KeySpec privateKeySpec = new ECPrivateKeySpec(new BigInteger(privateS), parameterSpec);
/** Get keys */
this.serverPrivateKey = KeyFactory.getInstance("EC").generatePrivate(privateKeySpec);
}
} catch (GeneralSecurityException | IllegalArgumentException e) {
log.error("[{}] Failed generate Server KeyRPK", e.getMessage());
throw new RuntimeException(e);
}
}
}

40
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/secure/ReadResultSecurityStore.java

@ -1,40 +0,0 @@
/**
* Copyright © 2016-2020 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.transport.lwm2m.secure;
import com.google.gson.JsonObject;
import lombok.Builder;
import lombok.Data;
import org.eclipse.leshan.server.bootstrap.BootstrapConfig;
import org.eclipse.leshan.server.security.SecurityInfo;
import org.thingsboard.server.common.data.DeviceProfile;
import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceCredentialsResponseMsg;
import static org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode.DEFAULT_MODE;
@Data
public class ReadResultSecurityStore {
private ValidateDeviceCredentialsResponseMsg msg;
private SecurityInfo securityInfo;
@Builder.Default
private int securityMode = DEFAULT_MODE.code;
/** bootstrap */
DeviceProfile deviceProfile;
JsonObject bootstrapJsonCredential;
String endPoint;
BootstrapConfig bootstrapConfig;
}

88
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2MSessionMsgListener.java

@ -1,88 +0,0 @@
/**
* Copyright © 2016-2020 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.transport.lwm2m.server;
import io.netty.util.concurrent.Future;
import io.netty.util.concurrent.GenericFutureListener;
import lombok.extern.slf4j.Slf4j;
import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.DeviceProfile;
import org.thingsboard.server.common.transport.SessionMsgListener;
import org.thingsboard.server.gen.transport.TransportProtos;
import org.thingsboard.server.gen.transport.TransportProtos.GetAttributeResponseMsg;
import org.thingsboard.server.gen.transport.TransportProtos.AttributeUpdateNotificationMsg;
import org.thingsboard.server.gen.transport.TransportProtos.SessionCloseNotificationProto;
import org.thingsboard.server.gen.transport.TransportProtos.ToDeviceRpcRequestMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToServerRpcResponseMsg;
import org.thingsboard.server.gen.transport.TransportProtos.ToTransportUpdateCredentialsProto;
import java.util.Optional;
@Slf4j
public class LwM2MSessionMsgListener implements GenericFutureListener<Future<? super Void>>, SessionMsgListener {
private LwM2MTransportService service;
private TransportProtos.SessionInfoProto sessionInfo;
LwM2MSessionMsgListener(LwM2MTransportService service, TransportProtos.SessionInfoProto sessionInfo) {
this.service = service;
this.sessionInfo = sessionInfo;
}
@Override
public void onGetAttributesResponse(GetAttributeResponseMsg getAttributesResponse) {
log.info("[{}] attributesResponse", getAttributesResponse);
}
@Override
public void onAttributeUpdate(AttributeUpdateNotificationMsg attributeUpdateNotification) {
this.service.onAttributeUpdate(attributeUpdateNotification, this.sessionInfo);
}
@Override
public void onRemoteSessionCloseCommand(SessionCloseNotificationProto sessionCloseNotification) {
log.info("[{}] sessionCloseNotification", sessionCloseNotification);
}
@Override
public void onToTransportUpdateCredentials(ToTransportUpdateCredentialsProto updateCredentials) {
this.service.onToTransportUpdateCredentials(updateCredentials);
}
@Override
public void onDeviceProfileUpdate(TransportProtos.SessionInfoProto sessionInfo, DeviceProfile deviceProfile) {
this.service.onDeviceProfileUpdate(sessionInfo, deviceProfile);
}
@Override
public void onDeviceUpdate(TransportProtos.SessionInfoProto sessionInfo, Device device, Optional<DeviceProfile> deviceProfileOpt) {
this.service.onDeviceUpdate(sessionInfo, device, deviceProfileOpt);
}
@Override
public void onToDeviceRpcRequest(ToDeviceRpcRequestMsg toDeviceRequest) {
log.info("[{}] toDeviceRpcRequest", toDeviceRequest);
}
@Override
public void onToServerRpcResponse(ToServerRpcResponseMsg toServerResponse) {
log.info("[{}] toServerRpcResponse", toServerResponse);
}
@Override
public void operationComplete(Future<? super Void> future) throws Exception {
log.info("[{}] operationComplete", future);
}
}

60
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2MTransportContextServer.java

@ -1,60 +0,0 @@
/**
* Copyright © 2016-2020 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.transport.lwm2m.server;
/**
* Copyright © 2016-2020 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.stereotype.Component;
import org.thingsboard.server.common.transport.TransportContext;
import org.thingsboard.server.common.transport.lwm2m.LwM2MTransportConfigServer;
import javax.annotation.PostConstruct;
@Slf4j
@Component
@ConditionalOnExpression("('${service.type:null}'=='tb-transport' && '${transport.lwm2m.enabled:false}'=='true') || ('${service.type:null}'=='monolith' && '${transport.lwm2m.enabled}'=='true')")
public class LwM2MTransportContextServer extends TransportContext {
private LwM2MTransportConfigServer ctxServer;
@Autowired
LwM2MTransportConfigServer lwM2MTransportConfigServer;
@PostConstruct
public void init() {
this.ctxServer = lwM2MTransportConfigServer;
}
public LwM2MTransportConfigServer getCtxServer () {
return this.ctxServer;
}
}

333
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2MTransportHandler.java

@ -1,333 +0,0 @@
/**
* Copyright © 2016-2020 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.transport.lwm2m.server;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.JsonSyntaxException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.californium.core.network.config.NetworkConfig;
import org.eclipse.leshan.core.model.ResourceModel;
import org.eclipse.leshan.core.node.LwM2mNode;
import org.eclipse.leshan.core.node.LwM2mObject;
import org.eclipse.leshan.core.node.LwM2mObjectInstance;
import org.eclipse.leshan.core.node.LwM2mSingleResource;
import org.eclipse.leshan.core.node.LwM2mMultipleResource;
import org.eclipse.leshan.core.util.Hex;
import org.eclipse.leshan.server.californium.LeshanServer;
import org.eclipse.leshan.server.californium.LeshanServerBuilder;
import org.nustaq.serialization.FSTConfiguration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.stereotype.Component;
import org.thingsboard.server.common.data.DeviceProfile;
import org.thingsboard.server.common.data.device.profile.Lwm2mDeviceProfileTransportConfiguration;
import org.thingsboard.server.transport.lwm2m.server.client.AttrTelemetryObserveValue;
import javax.annotation.PostConstruct;
import java.io.File;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Optional;
import java.util.Map;
import java.util.Arrays;
import java.util.List;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Collections;
@Slf4j
@Component("LwM2MTransportHandler")
@ConditionalOnExpression("('${service.type:null}'=='tb-transport' && '${transport.lwm2m.enabled:false}'=='true' )|| ('${service.type:null}'=='monolith' && '${transport.lwm2m.enabled}'=='true')")
public class LwM2MTransportHandler{
// We choose a default timeout a bit higher to the MAX_TRANSMIT_WAIT(62-93s) which is the time from starting to
// send a Confirmable message to the time when an acknowledgement is no longer expected.
public static final long DEFAULT_TIMEOUT = 2 * 60 * 1000l; // 2min in ms
public static final String OBSERVE_ATTRIBUTE_TELEMETRY = "observeAttr";
public static final String KEYNAME = "keyName";
public static final String ATTRIBUTE = "attribute";
public static final String TELEMETRY = "telemetry";
public static final String OBSERVE = "observe";
public static final String BOOTSTRAP = "bootstrap";
public static final String SERVERS = "servers";
public static final String LWM2M_SERVER = "lwm2mServer";
public static final String BOOTSTRAP_SERVER = "bootstrapServer";
public static final String BASE_DEVICE_API_TOPIC = "v1/devices/me";
public static final String DEVICE_ATTRIBUTES_TOPIC = BASE_DEVICE_API_TOPIC + "/attributes";
public static final String DEVICE_TELEMETRY_TOPIC = BASE_DEVICE_API_TOPIC + "/telemetry";
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";
public static final String CLIENT_NOT_AUTHORIZED = "Client not authorized";
public static final String GET_TYPE_OPER_READ = "read";
public static final String GET_TYPE_OPER_DISCOVER = "discover";
public static final String GET_TYPE_OPER_OBSERVE = "observe";
public static final String POST_TYPE_OPER_OBSERVE_CANCEL = "observeCancel";
public static final String POST_TYPE_OPER_EXECUTE = "execute";
/**
* Replaces the Object Instance or the Resource(s) with the new value provided in the Write operation. (see
* section 5.3.3 of the LW M2M spec).
*/
public static final String POST_TYPE_OPER_WRITE_REPLACE = "replace";
/**
* Adds or updates Resources provided in the new value and leaves other existing Resources unchanged. (see section
* 5.3.3 of the LW M2M spec).
*/
public static final String PUT_TYPE_OPER_WRITE_UPDATE = "update";
public static final String PUT_TYPE_OPER_WRITE_ATTRIBUTES = "wright-attributes";
public static final String EVENT_AWAKE = "AWAKE";
private static Gson gson = null;
@Autowired
@Qualifier("LeshanServerCert")
private LeshanServer lhServerCert;
@Autowired
@Qualifier("leshanServerNoSecPskRpk")
private LeshanServer lhServerNoSecPskRpk;
@Autowired
private LwM2MTransportService service;
@PostConstruct
public void init() {
LwM2mServerListener lwM2mServerListener = new LwM2mServerListener(lhServerCert, service);
this.lhServerCert.getRegistrationService().addListener(lwM2mServerListener.registrationListener);
this.lhServerCert.getPresenceService().addListener(lwM2mServerListener.presenceListener);
this.lhServerCert.getObservationService().addListener(lwM2mServerListener.observationListener);
lwM2mServerListener = new LwM2mServerListener(lhServerNoSecPskRpk, service);
this.lhServerNoSecPskRpk.getRegistrationService().addListener(lwM2mServerListener.registrationListener);
this.lhServerNoSecPskRpk.getPresenceService().addListener(lwM2mServerListener.presenceListener);
this.lhServerNoSecPskRpk.getObservationService().addListener(lwM2mServerListener.observationListener);
}
public static NetworkConfig getCoapConfig() {
NetworkConfig coapConfig;
File configFile = new File(NetworkConfig.DEFAULT_FILE_NAME);
if (configFile.isFile()) {
coapConfig = new NetworkConfig();
coapConfig.load(configFile);
} else {
coapConfig = LeshanServerBuilder.createDefaultNetworkConfig();
coapConfig.store(configFile);
}
return coapConfig;
}
public static String getValueTypeToString (Object value, ResourceModel.Type type) {
switch (type) {
case STRING: // String
case OBJLNK: // ObjectLink
return value.toString();
case INTEGER: // Long
return Long.toString((long) value);
case BOOLEAN: // Boolean
return Boolean.toString((Boolean) value);
case FLOAT: // Double
return Double.toString((Float)value);
case TIME: // Date
String DATE_FORMAT = "MMM d, yyyy HH:mm a";
DateFormat formatter = new SimpleDateFormat(DATE_FORMAT);
return formatter.format(new Date((Long) Integer.toUnsignedLong(Integer.valueOf((Integer) value))));
case OPAQUE: // byte[] value, base64
return Hex.encodeHexString((byte[])value);
default:
return null;
}
}
public static LwM2mNode getLvM2mNodeToObject(LwM2mNode content) {
if (content instanceof LwM2mObject) {
return (LwM2mObject) content;
} else if (content instanceof LwM2mObjectInstance) {
return (LwM2mObjectInstance) content;
} else if (content instanceof LwM2mSingleResource) {
return (LwM2mSingleResource) content;
} else if (content instanceof LwM2mMultipleResource) {
return (LwM2mMultipleResource) content;
}
return null;
}
public static AttrTelemetryObserveValue getNewProfileParameters(JsonObject profilesConfigData) {
AttrTelemetryObserveValue attrTelemetryObserveValue = new AttrTelemetryObserveValue();
attrTelemetryObserveValue.setPostKeyNameProfile(profilesConfigData.get(KEYNAME).getAsJsonObject());
attrTelemetryObserveValue.setPostAttributeProfile(profilesConfigData.get(ATTRIBUTE).getAsJsonArray());
attrTelemetryObserveValue.setPostTelemetryProfile(profilesConfigData.get(TELEMETRY).getAsJsonArray());
attrTelemetryObserveValue.setPostObserveProfile(profilesConfigData.get(OBSERVE).getAsJsonArray());
return attrTelemetryObserveValue;
}
/**
* @return deviceProfileBody with Observe&Attribute&Telemetry From Thingsboard
* Example: with pathResource (use only pathResource)
* property: "observeAttr"
* {"keyName": {
* "/3/0/1": "modelNumber",
* "/3/0/0": "manufacturer",
* "/3/0/2": "serialNumber"
* },
* "attribute":["/2/0/1","/3/0/9"],
* "telemetry":["/1/0/1","/2/0/1","/6/0/1"],
* "observe":["/2/0","/2/0/0","/4/0/2"]}
*/
public static JsonObject getObserveAttrTelemetryFromThingsboard(DeviceProfile deviceProfile) {
if (deviceProfile != null && ((Lwm2mDeviceProfileTransportConfiguration) deviceProfile.getProfileData().getTransportConfiguration()).getProperties().size() > 0) {
Lwm2mDeviceProfileTransportConfiguration lwm2mDeviceProfileTransportConfiguration = (Lwm2mDeviceProfileTransportConfiguration) deviceProfile.getProfileData().getTransportConfiguration();
Object observeAttr = ((Lwm2mDeviceProfileTransportConfiguration) deviceProfile.getProfileData().getTransportConfiguration()).getProperties();
try {
ObjectMapper mapper = new ObjectMapper();
String observeAttrStr = mapper.writeValueAsString(observeAttr);
JsonObject objectMsg = (observeAttrStr != null) ? validateJson(observeAttrStr) : null;
return (getValidateCredentialsBodyFromThingsboard(objectMsg)) ? objectMsg.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject() : null;
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
public static JsonObject getBootstrapParametersFromThingsboard(DeviceProfile deviceProfile) {
if (deviceProfile != null && ((Lwm2mDeviceProfileTransportConfiguration) deviceProfile.getProfileData().getTransportConfiguration()).getProperties().size() > 0) {
Lwm2mDeviceProfileTransportConfiguration lwm2mDeviceProfileTransportConfiguration = (Lwm2mDeviceProfileTransportConfiguration) deviceProfile.getProfileData().getTransportConfiguration();
Object bootstrap = ((Lwm2mDeviceProfileTransportConfiguration) deviceProfile.getProfileData().getTransportConfiguration()).getProperties();
try {
ObjectMapper mapper = new ObjectMapper();
String bootstrapStr = mapper.writeValueAsString(bootstrap);
JsonObject objectMsg = (bootstrapStr != null) ? validateJson(bootstrapStr) : null;
return (getValidateBootstrapProfileFromThingsboard(objectMsg)) ? objectMsg.get(BOOTSTRAP).getAsJsonObject() : null;
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
private static boolean getValidateCredentialsBodyFromThingsboard(JsonObject objectMsg) {
return (objectMsg != null &&
!objectMsg.isJsonNull() &&
objectMsg.has(OBSERVE_ATTRIBUTE_TELEMETRY) &&
!objectMsg.get(OBSERVE_ATTRIBUTE_TELEMETRY).isJsonNull() &&
objectMsg.get(OBSERVE_ATTRIBUTE_TELEMETRY).isJsonObject() &&
objectMsg.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().has(KEYNAME) &&
!objectMsg.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().get(KEYNAME).isJsonNull() &&
objectMsg.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().get(KEYNAME).isJsonObject() &&
objectMsg.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().has(ATTRIBUTE) &&
!objectMsg.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().get(ATTRIBUTE).isJsonNull() &&
objectMsg.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().get(ATTRIBUTE).isJsonArray() &&
objectMsg.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().has(TELEMETRY) &&
!objectMsg.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().get(TELEMETRY).isJsonNull() &&
objectMsg.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().get(TELEMETRY).isJsonArray() &&
objectMsg.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().has(OBSERVE) &&
!objectMsg.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().get(OBSERVE).isJsonNull() &&
objectMsg.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().get(OBSERVE).isJsonArray());
}
private static boolean getValidateBootstrapProfileFromThingsboard(JsonObject objectMsg) {
return (objectMsg != null &&
!objectMsg.isJsonNull() &&
objectMsg.has(BOOTSTRAP) &&
objectMsg.get(BOOTSTRAP).isJsonObject() &&
!objectMsg.get(BOOTSTRAP).isJsonNull() &&
objectMsg.get(BOOTSTRAP).getAsJsonObject().has(SERVERS) &&
!objectMsg.get(BOOTSTRAP).getAsJsonObject().get(SERVERS).isJsonNull() &&
objectMsg.get(BOOTSTRAP).getAsJsonObject().get(SERVERS).isJsonObject() &&
objectMsg.get(BOOTSTRAP).getAsJsonObject().has(BOOTSTRAP_SERVER) &&
!objectMsg.get(BOOTSTRAP).getAsJsonObject().get(BOOTSTRAP_SERVER).isJsonNull() &&
objectMsg.get(BOOTSTRAP).getAsJsonObject().get(BOOTSTRAP_SERVER).isJsonObject() &&
objectMsg.get(BOOTSTRAP).getAsJsonObject().has(LWM2M_SERVER) &&
!objectMsg.get(BOOTSTRAP).getAsJsonObject().get(LWM2M_SERVER).isJsonNull() &&
objectMsg.get(BOOTSTRAP).getAsJsonObject().get(LWM2M_SERVER).isJsonObject());
}
public static JsonObject validateJson(String jsonStr) {
JsonObject object = null;
if (jsonStr != null && !jsonStr.isEmpty()) {
String jsonValidFlesh = jsonStr.replaceAll("\\\\", "");
jsonValidFlesh = jsonValidFlesh.replaceAll("\n", "");
jsonValidFlesh = jsonValidFlesh.replaceAll("\t", "");
jsonValidFlesh = jsonValidFlesh.replaceAll(" ", "");
String jsonValid = (jsonValidFlesh.substring(0, 1).equals("\"") && jsonValidFlesh.substring(jsonValidFlesh.length() - 1).equals("\"")) ? jsonValidFlesh.substring(1, jsonValidFlesh.length() - 1) : jsonValidFlesh;
try {
object = new JsonParser().parse(jsonValid).getAsJsonObject();
} catch (JsonSyntaxException e) {
log.error("[{}] Fail validateJson [{}]", jsonStr, e.getMessage());
}
}
return object;
}
public static <T> Optional<T> decode(byte[] byteArray) {
try {
FSTConfiguration config = FSTConfiguration.createDefaultConfiguration();;
T msg = (T) config.asObject(byteArray);
return Optional.ofNullable(msg);
} catch (IllegalArgumentException e) {
log.error("Error during deserialization message, [{}]", e.getMessage());
return Optional.empty();
}
}
/**
* Equals to Map for values
* @param map1
* @param map2
* @param <V>
* @return
*/
public static <V extends Comparable<V>> boolean mapsEquals(Map<?,V> map1, Map<?,V> map2) {
List<V> values1 = new ArrayList<V>(map1.values());
List<V> values2 = new ArrayList<V>(map2.values());
Collections.sort(values1);
Collections.sort(values2);
return values1.equals(values2);
}
public static String convertCamelCase (String str) {
str = str.toLowerCase().replace("/[^a-z ]+/g", " ");
str = str.replace("/^(.)|\\s(.)/g", "$1");
str = str.replace("/[^a-zA-Z]+/g", "");
return str;
}
public static String splitCamelCaseString(String s){
LinkedList<String> linkedListOut = new LinkedList<String>();
LinkedList<String> linkedList = new LinkedList<String>((Arrays.asList(s.split(" "))));
linkedList.stream().forEach(str-> {
String strOut = str.replaceAll("\\W", "").replaceAll("_", "").toUpperCase();
if (strOut.length()>1) linkedListOut.add(strOut.substring(0, 1) + strOut.substring(1).toLowerCase());
else linkedListOut.add(strOut);
});
linkedListOut.set(0, (linkedListOut.get(0).substring(0, 1).toLowerCase() + linkedListOut.get(0).substring(1)));
return StringUtils.join(linkedListOut, "");
}
}

335
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2MTransportRequest.java

@ -1,335 +0,0 @@
/**
* Copyright © 2016-2020 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.transport.lwm2m.server;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.californium.core.coap.Response;
import org.eclipse.leshan.core.attributes.Attribute;
import org.eclipse.leshan.core.attributes.AttributeSet;
import org.eclipse.leshan.core.model.ResourceModel;
import org.eclipse.leshan.core.node.LwM2mSingleResource;
import org.eclipse.leshan.core.node.ObjectLink;
import org.eclipse.leshan.core.observation.Observation;
import org.eclipse.leshan.core.request.ContentFormat;
import org.eclipse.leshan.core.request.WriteRequest;
import org.eclipse.leshan.core.request.DiscoverRequest;
import org.eclipse.leshan.core.request.DownlinkRequest;
import org.eclipse.leshan.core.request.ObserveRequest;
import org.eclipse.leshan.core.request.CancelObservationRequest;
import org.eclipse.leshan.core.request.ReadRequest;
import org.eclipse.leshan.core.request.ExecuteRequest;
import org.eclipse.leshan.core.request.WriteAttributesRequest;
import org.eclipse.leshan.core.response.ResponseCallback;
import org.eclipse.leshan.core.response.LwM2mResponse;
import org.eclipse.leshan.core.response.ObserveResponse;
import org.eclipse.leshan.core.response.ReadResponse;
import org.eclipse.leshan.core.response.CancelObservationResponse;
import org.eclipse.leshan.core.response.DeleteResponse;
import org.eclipse.leshan.core.response.ExecuteResponse;
import org.eclipse.leshan.core.response.DiscoverResponse;
import org.eclipse.leshan.core.response.WriteAttributesResponse;
import org.eclipse.leshan.core.response.WriteResponse;
import org.eclipse.leshan.core.util.Hex;
import org.eclipse.leshan.core.util.NamedThreadFactory;
import org.eclipse.leshan.server.californium.LeshanServer;
import org.eclipse.leshan.server.registration.Registration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.stereotype.Service;
import org.thingsboard.server.transport.lwm2m.server.client.LwM2MClient;
import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import static org.eclipse.californium.core.coap.CoAP.ResponseCode.isSuccess;
import static org.eclipse.leshan.core.attributes.Attribute.MINIMUM_PERIOD;
import static org.thingsboard.server.transport.lwm2m.server.LwM2MTransportHandler.DEFAULT_TIMEOUT;
import static org.thingsboard.server.transport.lwm2m.server.LwM2MTransportHandler.GET_TYPE_OPER_DISCOVER;
import static org.thingsboard.server.transport.lwm2m.server.LwM2MTransportHandler.GET_TYPE_OPER_OBSERVE;
import static org.thingsboard.server.transport.lwm2m.server.LwM2MTransportHandler.GET_TYPE_OPER_READ;
import static org.thingsboard.server.transport.lwm2m.server.LwM2MTransportHandler.PUT_TYPE_OPER_WRITE_ATTRIBUTES;
import static org.thingsboard.server.transport.lwm2m.server.LwM2MTransportHandler.PUT_TYPE_OPER_WRITE_UPDATE;
import static org.thingsboard.server.transport.lwm2m.server.LwM2MTransportHandler.POST_TYPE_OPER_EXECUTE;
import static org.thingsboard.server.transport.lwm2m.server.LwM2MTransportHandler.POST_TYPE_OPER_OBSERVE_CANCEL;
import static org.thingsboard.server.transport.lwm2m.server.LwM2MTransportHandler.POST_TYPE_OPER_WRITE_REPLACE;
import static org.thingsboard.server.transport.lwm2m.server.LwM2MTransportHandler.LOG_LW2M_ERROR;
import static org.thingsboard.server.transport.lwm2m.server.LwM2MTransportHandler.LOG_LW2M_INFO;
@Slf4j
@Service("LwM2MTransportRequest")
@ConditionalOnExpression("('${service.type:null}'=='tb-transport' && '${transport.lwm2m.enabled:false}'=='true' ) || ('${service.type:null}'=='monolith' && '${transport.lwm2m.enabled}'=='true')")
public class LwM2MTransportRequest {
private final ExecutorService executorService;
private static final String RESPONSE_CHANNEL = "THINGSBOARD_RESP";
@Autowired
LwM2MTransportService service;
public LwM2MTransportRequest() {
executorService = Executors.newCachedThreadPool(
new NamedThreadFactory(String.format("LwM2M %s channel response", RESPONSE_CHANNEL)));
}
@PostConstruct
public void init() {
}
public Collection<Registration> doGetRegistrations(LeshanServer lwServer) {
Collection<Registration> registrations = new ArrayList<>();
for (Iterator<Registration> iterator = lwServer.getRegistrationService().getAllRegistrations(); iterator
.hasNext(); ) {
registrations.add(iterator.next());
}
return registrations;
}
/**
* Device management and service enablement, including Read, Write, Execute, Discover, Create, Delete and Write-Attributes
*
* @param lwServer
* @param registration
* @param target
* @param typeOper
* @param contentFormatParam
* @param lwM2MClient
* @param observation
*/
public void sendAllRequest(LeshanServer lwServer, Registration registration, String target, String typeOper,
String contentFormatParam, LwM2MClient lwM2MClient, Observation observation, Object params, long timeoutInMs) {
ResultIds resultIds = new ResultIds(target);
if (registration != null && resultIds.getObjectId() >= 0) {
DownlinkRequest request = null;
ContentFormat contentFormat = contentFormatParam != null ? ContentFormat.fromName(contentFormatParam.toUpperCase()) : null;
ResourceModel resource = (resultIds.resourceId >= 0) ? (lwM2MClient != null) ?
lwM2MClient.getModelObjects().get(resultIds.getObjectId()).getObjectModel().resources.get(resultIds.resourceId) : null : null;
ResourceModel.Type resType = (resource == null) ? null : resource.type;
boolean resMultiple = (resource == null) ? false : resource.multiple;
timeoutInMs = timeoutInMs > 0 ? timeoutInMs : DEFAULT_TIMEOUT;
switch (typeOper) {
case GET_TYPE_OPER_READ:
request = new ReadRequest(contentFormat, target);
break;
case GET_TYPE_OPER_DISCOVER:
request = new DiscoverRequest(target);
break;
case GET_TYPE_OPER_OBSERVE:
if (resultIds.getResourceId() >= 0) {
request = new ObserveRequest(resultIds.getObjectId(), resultIds.getInstanceId(), resultIds.getResourceId());
} else if (resultIds.getInstanceId() >= 0) {
request = new ObserveRequest(resultIds.getObjectId(), resultIds.getInstanceId());
} else if (resultIds.getObjectId() >= 0) {
request = new ObserveRequest(resultIds.getObjectId());
}
break;
case POST_TYPE_OPER_OBSERVE_CANCEL:
request = new CancelObservationRequest(observation);
break;
case POST_TYPE_OPER_EXECUTE:
if (params != null && !resMultiple) {
request = new ExecuteRequest(target, LwM2MTransportHandler.getValueTypeToString(params, resType));
} else {
request = new ExecuteRequest(target);
}
break;
case POST_TYPE_OPER_WRITE_REPLACE:
// Request to write a <b>String Single-Instance Resource</b> using the TLV content format.
if (contentFormat.equals(ContentFormat.TLV) && !resMultiple) {
request = this.getWriteRequestSingleResource(null, resultIds.getObjectId(), resultIds.getInstanceId(), resultIds.getResourceId(), params, resType);
}
// 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) && !resMultiple) {
request = this.getWriteRequestSingleResource(contentFormat, resultIds.getObjectId(), resultIds.getInstanceId(), resultIds.getResourceId(), params, resType);
}
break;
case PUT_TYPE_OPER_WRITE_UPDATE:
if (resultIds.getResourceId() >= 0) {
ResourceModel resourceModel = lwServer.getModelProvider().getObjectModel(registration).getObjectModel(resultIds.getObjectId()).resources.get(resultIds.getResourceId());
ResourceModel.Type typeRes = resourceModel.type;
// request = getWriteRequestResource(resultIds.getObjectId(), resultIds.getInstanceId(), resultIds.getResourceId(), params, typeRes);
}
break;
case PUT_TYPE_OPER_WRITE_ATTRIBUTES:
/**
* As example:
* a)Write-Attributes/3/0/9?pmin=1 means the Battery Level value will be notified
* to the Server with a minimum interval of 1sec;
* this value is set at theResource level.
* b)Write-Attributes/3/0/9?pmin means the Battery Level will be notified
* to the Server with a minimum value (pmin) given by the default one
* (resource 2 of Object Server ID=1),
* or with another value if this Attribute has been set at another level
* (Object or Object Instance: see section5.1.1).
* c)Write-Attributes/3/0?pmin=10 means that all Resources of Instance 0 of the Object Device (ID:3)
* will be notified to the Server with a minimum interval of 10 sec;
* this value is set at the Object Instance level.
* d)Write-Attributes /3/0/9?gt=45&st=10 means the Battery Level will be notified to the Server
* when:
* a.old value is 20 and new value is 35 due to step condition
* b.old value is 45 and new value is 50 due to gt condition
* c.old value is 50 and new value is 40 due to both gt and step conditions
* d.old value is 35 and new value is 20 due to step conditione)
* Write-Attributes /3/0/9?lt=20&gt=85&st=10 means the Battery Level will be notified to the Server
* when:
* a.old value is 17 and new value is 24 due to lt condition
* b.old value is 75 and new value is 90 due to both gt and step conditions
* String uriQueries = "pmin=10&pmax=60";
* AttributeSet attributes = AttributeSet.parse(uriQueries);
* WriteAttributesRequest request = new WriteAttributesRequest(target, attributes);
* Attribute gt = new Attribute(GREATER_THAN, Double.valueOf("45"));
* Attribute st = new Attribute(LESSER_THAN, Double.valueOf("10"));
* Attribute pmax = new Attribute(MAXIMUM_PERIOD, "60");
* Attribute [] attrs = {gt, st};
*/
Attribute pmin = new Attribute(MINIMUM_PERIOD, Integer.toUnsignedLong(Integer.valueOf("1")));
Attribute[] attrs = {pmin};
AttributeSet attrSet = new AttributeSet(attrs);
if (resultIds.getResourceId() >= 0) {
request = new WriteAttributesRequest(resultIds.getObjectId(), resultIds.getInstanceId(), resultIds.getResourceId(), attrSet);
} else if (resultIds.getInstanceId() >= 0) {
request = new WriteAttributesRequest(resultIds.getObjectId(), resultIds.getInstanceId(), attrSet);
} else if (resultIds.getObjectId() >= 0) {
request = new WriteAttributesRequest(resultIds.getObjectId(), attrSet);
}
break;
default:
}
if (request != null) sendRequest(lwServer, registration, request, lwM2MClient, timeoutInMs);
}
}
/**
*
* @param lwServer
* @param registration
* @param request
* @param lwM2MClient
* @param timeoutInMs
*/
private void sendRequest(LeshanServer lwServer, Registration registration, DownlinkRequest request, LwM2MClient lwM2MClient, long timeoutInMs) {
lwServer.send(registration, request, timeoutInMs, (ResponseCallback<?>) response -> {
if (isSuccess(((Response)response.getCoapResponse()).getCode())) {
this.handleResponse(registration, request.getPath().toString(), response, request, lwM2MClient);
if (request instanceof WriteRequest && ((WriteRequest) request).isReplaceRequest()) {
String msg = String.format(LOG_LW2M_INFO + " sendRequest Replace: CoapCde - %s Lwm2m code - %d name - %s Resource path - %s value - %s SendRequest to Client",
((Response)response.getCoapResponse()).getCode(), response.getCode().getCode(), response.getCode().getName(), request.getPath().toString(),
((LwM2mSingleResource)((WriteRequest) request).getNode()).getValue().toString());
service.sentLogsToThingsboard(msg, registration.getId());
log.info("[{}] - [{}] [{}] [{}] Update SendRequest", ((Response)response.getCoapResponse()).getCode(), response.getCode(), request.getPath().toString(), ((LwM2mSingleResource)((WriteRequest) request).getNode()).getValue());
}
}
else {
String msg = String.format(LOG_LW2M_ERROR + " sendRequest: CoapCde - %s Lwm2m code - %d name - %s Resource path - %s SendRequest to Client",
((Response)response.getCoapResponse()).getCode(), response.getCode().getCode(), response.getCode().getName(), request.getPath().toString());
service.sentLogsToThingsboard(msg, registration.getId());
log.error("[{}] - [{}] [{}] error SendRequest", ((Response)response.getCoapResponse()).getCode(), response.getCode(), request.getPath().toString());
}
}, e -> {
String msg = String.format(LOG_LW2M_ERROR + " sendRequest: Resource path - %s msg error - %s SendRequest to Client",
request.getPath().toString(), e.toString());
service.sentLogsToThingsboard(msg, registration.getId());
log.error("[{}] - [{}] error SendRequest", request.getPath().toString(), e.toString());
});
}
private WriteRequest getWriteRequestSingleResource(ContentFormat contentFormat, Integer objectId, Integer instanceId, Integer resourceId, Object value, ResourceModel.Type type) {
try {
switch (type) {
case STRING: // String
return (contentFormat == null) ? new WriteRequest(objectId, instanceId, resourceId, value.toString()) : new WriteRequest(contentFormat, objectId, instanceId, resourceId, value.toString());
case INTEGER: // Long
return (contentFormat == null) ? new WriteRequest(objectId, instanceId, resourceId, Integer.toUnsignedLong(Integer.valueOf(value.toString()))) : new WriteRequest(contentFormat, objectId, instanceId, resourceId, Integer.toUnsignedLong(Integer.valueOf(value.toString())));
case OBJLNK: // ObjectLink
return (contentFormat == null) ? new WriteRequest(objectId, instanceId, resourceId, ObjectLink.fromPath(value.toString())) : new WriteRequest(contentFormat, objectId, instanceId, resourceId, ObjectLink.fromPath(value.toString()));
case BOOLEAN: // Boolean
return (contentFormat == null) ? new WriteRequest(objectId, instanceId, resourceId, Boolean.valueOf(value.toString())) : new WriteRequest(contentFormat, objectId, instanceId, resourceId, Boolean.valueOf(value.toString()));
case FLOAT: // Double
return (contentFormat == null) ? new WriteRequest(objectId, instanceId, resourceId, Double.valueOf(value.toString())) : new WriteRequest(contentFormat, objectId, instanceId, resourceId, Double.valueOf(value.toString()));
case TIME: // Date
return (contentFormat == null) ? new WriteRequest(objectId, instanceId, resourceId, new Date((Long) Integer.toUnsignedLong(Integer.valueOf(value.toString())))) : new WriteRequest(contentFormat, objectId, instanceId, resourceId, new Date((Long) Integer.toUnsignedLong(Integer.valueOf(value.toString()))));
case OPAQUE: // byte[] value, base64
return (contentFormat == null) ? new WriteRequest(objectId, instanceId, resourceId, Hex.decodeHex(value.toString().toCharArray())) : new WriteRequest(contentFormat, objectId, instanceId, resourceId, Hex.decodeHex(value.toString().toCharArray()));
default:
}
return null;
} catch (NumberFormatException e) {
String patn = "/" + objectId + "/" + instanceId + "/" + resourceId;
log.error("Path: [{}] type: [{}] value: [{}] errorMsg: [{}]]", patn, type, value, e.toString());
return null;
}
}
private void handleResponse(Registration registration, final String path, LwM2mResponse response, DownlinkRequest request, LwM2MClient lwM2MClient) {
executorService.submit(new Runnable() {
@Override
public void run() {
try {
sendResponse(registration, path, response, request, lwM2MClient);
} catch (RuntimeException t) {
log.error("[{}] endpoint [{}] path [{}] error Unable to after send response.", registration.getEndpoint(), path, t.toString());
}
}
});
}
/**
* processing a response from a client
* @param registration -
* @param path -
* @param response -
* @param lwM2MClient -
*/
private void sendResponse(Registration registration, String path, LwM2mResponse response, DownlinkRequest request, LwM2MClient lwM2MClient) {
if (response instanceof ObserveResponse) {
service.onObservationResponse(registration, path, (ReadResponse) response);
} else if (response instanceof CancelObservationResponse) {
log.info("[{}] Path [{}] CancelObservationResponse 3_Send", path, response);
} else if (response instanceof ReadResponse) {
/**
* Use only at the first start after registration
* Fill with data -> Model client
*/
if (lwM2MClient != null) {
if (lwM2MClient.getPendingRequests().size() > 0) {
lwM2MClient.onSuccessHandler(path, response);
}
}
/**
* Use after registration on request
*/
else {
service.onObservationResponse(registration, path, (ReadResponse) response);
}
} else if (response instanceof DeleteResponse) {
log.info("[{}] Path [{}] DeleteResponse 5_Send", path, response);
} else if (response instanceof DiscoverResponse) {
log.info("[{}] Path [{}] DiscoverResponse 6_Send", path, response);
} else if (response instanceof ExecuteResponse) {
log.info("[{}] Path [{}] ExecuteResponse 7_Send", path, response);
} else if (response instanceof WriteAttributesResponse) {
log.info("[{}] Path [{}] WriteAttributesResponse 8_Send", path, response);
} else if (response instanceof WriteResponse) {
log.info("[{}] Path [{}] WriteAttributesResponse 9_Send", path, response);
service.onAttributeUpdateOk(registration, path, (WriteRequest) request);
}
}
}

102
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2MTransportServerConfiguration.java

@ -1,102 +0,0 @@
/**
* Copyright © 2016-2020 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.transport.lwm2m.server;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.californium.scandium.config.DtlsConnectorConfig;
import org.eclipse.leshan.core.node.codec.DefaultLwM2mNodeDecoder;
import org.eclipse.leshan.core.node.codec.DefaultLwM2mNodeEncoder;
import org.eclipse.leshan.core.node.codec.LwM2mNodeDecoder;
import org.eclipse.leshan.server.californium.LeshanServer;
import org.eclipse.leshan.server.californium.LeshanServerBuilder;
import org.eclipse.leshan.server.model.LwM2mModelProvider;
import org.eclipse.leshan.server.model.VersionedModelProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode;
import org.thingsboard.server.transport.lwm2m.server.secure.LwM2MSetSecurityStoreServer;
import org.thingsboard.server.transport.lwm2m.server.secure.LwM2mInMemorySecurityStore;
import org.thingsboard.server.transport.lwm2m.utils.LwM2mValueConverterImpl;
import static org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode.X509;
import static org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode.RPK;
import static org.thingsboard.server.transport.lwm2m.server.LwM2MTransportHandler.getCoapConfig;
@Slf4j
@ComponentScan("org.thingsboard.server.transport.lwm2m.server")
@ComponentScan("org.thingsboard.server.transport.lwm2m.utils")
@Configuration("LwM2MTransportServerConfiguration")
@ConditionalOnExpression("('${service.type:null}'=='tb-transport' && '${transport.lwm2m.enabled:false}'=='true' ) || ('${service.type:null}'=='monolith' && '${transport.lwm2m.enabled}'=='true')")
public class LwM2MTransportServerConfiguration {
@Autowired
private LwM2MTransportContextServer context;
@Autowired
private LwM2mInMemorySecurityStore lwM2mInMemorySecurityStore;
@Primary
@Bean(name = "LeshanServerCert")
public LeshanServer getLeshanServerCert() {
log.info("Starting LwM2M transport ServerCert... PostConstruct");
return getLeshanServer(this.context.getCtxServer().getServerPortCert(), this.context.getCtxServer().getServerSecurePortCert(), X509);
}
@Bean(name = "leshanServerNoSecPskRpk")
public LeshanServer getLeshanServerNoSecPskRpk() {
log.info("Starting LwM2M transport ServerNoSecPskRpk... PostConstruct");
return getLeshanServer(this.context.getCtxServer().getServerPort(), this.context.getCtxServer().getServerSecurePort(), RPK);
}
private LeshanServer getLeshanServer(Integer serverPort, Integer serverSecurePort, LwM2MSecurityMode dtlsMode) {
LeshanServerBuilder builder = new LeshanServerBuilder();
builder.setLocalAddress(this.context.getCtxServer().getServerHost(), serverPort);
builder.setLocalSecureAddress(this.context.getCtxServer().getServerSecureHost(), serverSecurePort);
builder.setEncoder(new DefaultLwM2mNodeEncoder());
LwM2mNodeDecoder decoder = new DefaultLwM2mNodeDecoder();
builder.setDecoder(decoder);
builder.setEncoder(new DefaultLwM2mNodeEncoder(new LwM2mValueConverterImpl()));
/** Create CoAP Config */
builder.setCoapConfig(getCoapConfig());
/** Define model provider (Create Models )*/
LwM2mModelProvider modelProvider = new VersionedModelProvider(this.context.getCtxServer().getModelsValue());
builder.setObjectModelProvider(modelProvider);
/** Create DTLS Config */
DtlsConnectorConfig.Builder dtlsConfig = new DtlsConnectorConfig.Builder();
dtlsConfig.setRecommendedCipherSuitesOnly(this.context.getCtxServer().isSupportDeprecatedCiphersEnable());
/** Set DTLS Config */
builder.setDtlsConfig(dtlsConfig);
/** Use a magic converter to support bad type send by the UI. */
builder.setEncoder(new DefaultLwM2mNodeEncoder(new LwM2mValueConverterImpl()));
/** Create DTLS security mode
* There can be only one DTLS security mode
*/
new LwM2MSetSecurityStoreServer(builder, context, lwM2mInMemorySecurityStore, dtlsMode);
/** Create LWM2M server */
return builder.build();
}
}

72
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2MTransportServerInitializer.java

@ -1,72 +0,0 @@
/**
* Copyright © 2016-2020 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.transport.lwm2m.server;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.leshan.server.californium.LeshanServer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.stereotype.Service;
import org.thingsboard.server.transport.lwm2m.secure.LWM2MGenerationPSkRPkECC;
import org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
@Slf4j
@Service("LwM2MTransportServerInitializer")
@ConditionalOnExpression("('${service.type:null}'=='tb-transport' && '${transport.lwm2m.enabled:false}'=='true' ) || ('${service.type:null}'=='monolith' && '${transport.lwm2m.enabled}'=='true')")
public class LwM2MTransportServerInitializer {
@Autowired
@Qualifier("LeshanServerCert")
private LeshanServer lhServerCert;
@Autowired
@Qualifier("leshanServerNoSecPskRpk")
private LeshanServer lhServerNoSecPskRpk;
@Autowired
private LwM2MTransportContextServer context;
@PostConstruct
public void init() {
if (this.context.getCtxServer().getEnableGenPskRpk()) new LWM2MGenerationPSkRPkECC();
if (this.context.getCtxServer().isServerStartAll()) {
this.lhServerCert.start();
this.lhServerNoSecPskRpk.start();
}
else {
if (this.context.getCtxServer().getServerDtlsMode() == LwM2MSecurityMode.X509.code) {
this.lhServerCert.start();
}
else {
this.lhServerNoSecPskRpk.start();
}
}
}
@PreDestroy
public void shutdown() {
log.info("Stopping LwM2M transport Server!");
try {
lhServerCert.destroy();
lhServerNoSecPskRpk.destroy();
} finally {
}
log.info("LwM2M transport Server stopped!");
}
}

999
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2MTransportService.java

@ -1,999 +0,0 @@
/**
* Copyright © 2016-2020 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.transport.lwm2m.server;
import com.google.gson.*;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
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.LwM2mSingleResource;
import org.eclipse.leshan.core.node.LwM2mResource;
import org.eclipse.leshan.core.node.LwM2mPath;
import org.eclipse.leshan.core.observation.Observation;
import org.eclipse.leshan.core.request.ContentFormat;
import org.eclipse.leshan.core.request.WriteRequest;
import org.eclipse.leshan.core.response.ReadResponse;
import org.eclipse.leshan.core.util.Hex;
import org.eclipse.leshan.server.californium.LeshanServer;
import org.eclipse.leshan.server.registration.Registration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.stereotype.Service;
import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.DeviceProfile;
import org.thingsboard.server.common.transport.TransportService;
import org.thingsboard.server.common.transport.TransportServiceCallback;
import org.thingsboard.server.common.transport.adaptor.AdaptorException;
import org.thingsboard.server.common.transport.adaptor.JsonConverter;
import org.thingsboard.server.common.transport.service.DefaultTransportService;
import org.thingsboard.server.gen.transport.TransportProtos;
import org.thingsboard.server.gen.transport.TransportProtos.ToTransportUpdateCredentialsProto;
import org.thingsboard.server.gen.transport.TransportProtos.SessionEvent;
import org.thingsboard.server.gen.transport.TransportProtos.SessionInfoProto;
import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceCredentialsResponseMsg;
import org.thingsboard.server.gen.transport.TransportProtos.PostTelemetryMsg;
import org.thingsboard.server.gen.transport.TransportProtos.PostAttributeMsg;
import org.thingsboard.server.transport.lwm2m.server.adaptors.LwM2MJsonAdaptor;
import org.thingsboard.server.transport.lwm2m.server.client.AttrTelemetryObserveValue;
import org.thingsboard.server.transport.lwm2m.server.client.LwM2MClient;
import org.thingsboard.server.transport.lwm2m.server.client.ModelObject;
import org.thingsboard.server.transport.lwm2m.server.client.ResultsAnalyzerParameters;
import org.thingsboard.server.transport.lwm2m.server.client.ResourceValue;
import org.thingsboard.server.transport.lwm2m.server.secure.LwM2mInMemorySecurityStore;
import javax.annotation.PostConstruct;
import java.util.Collection;
import java.util.UUID;
import java.util.Random;
import java.util.Map;
import java.util.HashMap;
import java.util.Arrays;
import java.util.Set;
import java.util.HashSet;
import java.util.NoSuchElementException;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static org.eclipse.leshan.core.model.ResourceModel.Type.OPAQUE;
import static org.thingsboard.server.transport.lwm2m.server.LwM2MTransportHandler.*;
@Slf4j
@Service("LwM2MTransportService")
@ConditionalOnExpression("('${service.type:null}'=='tb-transport' && '${transport.lwm2m.enabled:false}'=='true' ) || ('${service.type:null}'=='monolith' && '${transport.lwm2m.enabled}'=='true')")
public class LwM2MTransportService {
@Autowired
private LwM2MJsonAdaptor adaptor;
@Autowired
private TransportService transportService;
@Autowired
public LwM2MTransportContextServer context;
@Autowired
private LwM2MTransportRequest lwM2MTransportRequest;
@Autowired
LwM2mInMemorySecurityStore lwM2mInMemorySecurityStore;
@PostConstruct
public void init() {
context.getScheduler().scheduleAtFixedRate(() -> checkInactivityAndReportActivity(), new Random().nextInt((int) context.getCtxServer().getSessionReportTimeout()), context.getCtxServer().getSessionReportTimeout(), TimeUnit.MILLISECONDS);
}
/**
* Start registration device
* Create session: Map<String <registrationId >, LwM2MClient>
* 1. replaceNewRegistration -> (solving the problem of incorrect termination of the previous session with this endpoint)
* 1.1 When we initialize the registration, we register the session by endpoint.
* 1.2 If the server has incomplete requests (canceling the registration of the previous session),
* delete the previous session only by the previous registration.getId
* 1.2 Add Model (Entity) for client (from registration & observe) by registration.getId
* 1.2 Remove from sessions Model by enpPoint
* Next -> Create new LwM2MClient for current session -> setModelClient...
*
* @param lwServer - LeshanServer
* @param registration - Registration LwM2M Client
* @param previousObsersations - may be null
*/
public void onRegistered(LeshanServer lwServer, Registration registration, Collection<Observation> previousObsersations) {
LwM2MClient lwM2MClient = lwM2mInMemorySecurityStore.getlwM2MClient(lwServer, registration);
if (lwM2MClient != null) {
lwM2MClient.setLwM2MTransportService(this);
lwM2MClient.setLwM2MTransportService(this);
lwM2MClient.setSessionUuid(UUID.randomUUID());
this.setLwM2MClient(lwServer, registration, lwM2MClient);
SessionInfoProto sessionInfo = this.getValidateSessionInfo(registration.getId());
if (sessionInfo != null) {
lwM2MClient.setDeviceUuid(new UUID(sessionInfo.getDeviceIdMSB(), sessionInfo.getDeviceIdLSB()));
lwM2MClient.setProfileUuid(new UUID(sessionInfo.getDeviceProfileIdMSB(), sessionInfo.getDeviceProfileIdLSB()));
lwM2MClient.setDeviceName(sessionInfo.getDeviceName());
lwM2MClient.setDeviceProfileName(sessionInfo.getDeviceType());
transportService.registerAsyncSession(sessionInfo, new LwM2MSessionMsgListener(this, sessionInfo));
transportService.process(sessionInfo, DefaultTransportService.getSessionEventMsg(SessionEvent.OPEN), null);
transportService.process(sessionInfo, TransportProtos.SubscribeToAttributeUpdatesMsg.newBuilder().build(), null);
this.sentLogsToThingsboard(LOG_LW2M_INFO + ": Client registration", registration.getId());
} else {
log.error("Client: [{}] onRegistered [{}] name [{}] sessionInfo ", registration.getId(), registration.getEndpoint(), sessionInfo);
}
} else {
log.error("Client: [{}] onRegistered [{}] name [{}] lwM2MClient ", registration.getId(), registration.getEndpoint(), lwM2MClient);
}
}
/**
* @param lwServer - LeshanServer
* @param registration - Registration LwM2M Client
*/
public void updatedReg(LeshanServer lwServer, Registration registration) {
SessionInfoProto sessionInfo = this.getValidateSessionInfo(registration.getId());
if (sessionInfo != null) {
log.info("Client: [{}] updatedReg [{}] name [{}] profile ", registration.getId(), registration.getEndpoint(), sessionInfo.getDeviceType());
} else {
log.error("Client: [{}] updatedReg [{}] name [{}] sessionInfo ", registration.getId(), registration.getEndpoint(), sessionInfo);
}
}
/**
* @param registration - Registration LwM2M Client
* @param observations - All paths observations before unReg
* !!! 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) {
this.sentLogsToThingsboard(LOG_LW2M_INFO + ": Client unRegistration", registration.getId());
this.closeClientSession(registration);
}
private void closeClientSession(Registration registration) {
SessionInfoProto sessionInfo = this.getValidateSessionInfo(registration.getId());
if (sessionInfo != null) {
transportService.deregisterSession(sessionInfo);
this.doCloseSession(sessionInfo);
lwM2mInMemorySecurityStore.delRemoveSessionAndListener(registration.getId());
if (lwM2mInMemorySecurityStore.getProfiles().size() > 0) {
this.syncSessionsAndProfiles();
}
log.info("Client: [{}] unReg [{}] name [{}] profile ", registration.getId(), registration.getEndpoint(), sessionInfo.getDeviceType());
} else {
log.error("Client: [{}] unReg [{}] name [{}] sessionInfo ", registration.getId(), registration.getEndpoint(), sessionInfo);
}
}
public void onSleepingDev(Registration registration) {
log.info("[{}] [{}] Received endpoint Sleeping version event", registration.getId(), registration.getEndpoint());
//TODO: associate endpointId with device information.
}
/**
* Those methods are called by the protocol stage thread pool, this means that execution MUST be done in a short delay,
* * if you need to do long time processing use a dedicated thread pool.
*
* @param registration
*/
public void onAwakeDev(Registration registration) {
log.info("[{}] [{}] Received endpoint Awake version event", registration.getId(), registration.getEndpoint());
//TODO: associate endpointId with device information.
}
/**
* This method is used to sync with sessions
* Removes a profile if not used in sessions
*/
private void syncSessionsAndProfiles() {
Map<UUID, AttrTelemetryObserveValue> profilesClone = lwM2mInMemorySecurityStore.getProfiles().entrySet()
.stream()
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
profilesClone.forEach((k, v) -> {
String registrationId = lwM2mInMemorySecurityStore.getSessions().entrySet()
.stream()
.filter(e -> e.getValue().getProfileUuid().equals(k))
.findFirst()
.map(Map.Entry::getKey) // return the key of the matching entry if found
.orElse("");
if (registrationId.isEmpty()) {
lwM2mInMemorySecurityStore.getProfiles().remove(k);
}
});
}
/**
* Create new LwM2MClient for current session -> setModelClient...
* #1 Add all ObjectLinks (instance) to control the process of executing requests to the client
* to get the client model with current values
* #2 Get the client model with current values. Analyze the response in -> lwM2MTransportRequest.sendResponse
*
* @param lwServer - LeshanServer
* @param registration - Registration LwM2M Client
* @param lwM2MClient - object with All parameters off client
*/
private void setLwM2MClient(LeshanServer lwServer, Registration registration, LwM2MClient lwM2MClient) {
// #1
Arrays.stream(registration.getObjectLinks()).forEach(url -> {
ResultIds pathIds = new ResultIds(url.getUrl());
if (pathIds.instanceId > -1 && pathIds.resourceId == -1) {
lwM2MClient.getPendingRequests().add(url.getUrl());
}
});
// #2
Arrays.stream(registration.getObjectLinks()).forEach(url -> {
ResultIds pathIds = new ResultIds(url.getUrl());
if (pathIds.instanceId > -1 && pathIds.resourceId == -1) {
lwM2MTransportRequest.sendAllRequest(lwServer, registration, url.getUrl(), GET_TYPE_OPER_READ,
ContentFormat.TLV.getName(), lwM2MClient, null, null, this.context.getCtxServer().getTimeout());
}
});
}
/**
* @param registrationId - Id of Registration LwM2M Client
* @return - sessionInfo after access connect client
*/
private SessionInfoProto getValidateSessionInfo(String registrationId) {
SessionInfoProto sessionInfo = null;
LwM2MClient lwM2MClient = lwM2mInMemorySecurityStore.getlwM2MClient(registrationId);
if (lwM2MClient != null) {
ValidateDeviceCredentialsResponseMsg msg = lwM2MClient.getCredentialsResponse();
if (msg == null || msg.getDeviceInfo() == null) {
log.error("[{}] [{}]", lwM2MClient.getEndPoint(), CLIENT_NOT_AUTHORIZED);
this.closeClientSession(lwM2MClient.getRegistration());
} else {
sessionInfo = SessionInfoProto.newBuilder()
.setNodeId(this.context.getNodeId())
.setSessionIdMSB(lwM2MClient.getSessionUuid().getMostSignificantBits())
.setSessionIdLSB(lwM2MClient.getSessionUuid().getLeastSignificantBits())
.setDeviceIdMSB(msg.getDeviceInfo().getDeviceIdMSB())
.setDeviceIdLSB(msg.getDeviceInfo().getDeviceIdLSB())
.setTenantIdMSB(msg.getDeviceInfo().getTenantIdMSB())
.setTenantIdLSB(msg.getDeviceInfo().getTenantIdLSB())
.setDeviceName(msg.getDeviceInfo().getDeviceName())
.setDeviceType(msg.getDeviceInfo().getDeviceType())
.setDeviceProfileIdLSB(msg.getDeviceInfo().getDeviceProfileIdLSB())
.setDeviceProfileIdMSB(msg.getDeviceInfo().getDeviceProfileIdMSB())
.build();
}
}
return sessionInfo;
}
/**
* Add attribute/telemetry information from Client and credentials/Profile to client model and start observe
* !!! if the resource has an observation, but no telemetry or attribute - the observation will not use
* #1 Client`s starting info to send to thingsboard
* #2 Sending Attribute Telemetry with value to thingsboard only once at the start of the connection
* #3 Start observe
*
* @param lwServer - LeshanServer
* @param registration - Registration LwM2M Client
*/
public void updatesAndSentModelParameter(LeshanServer lwServer, Registration registration) {
// #1
// this.setParametersToModelClient(registration, modelClient, deviceProfile);
// #2
this.updateAttrTelemetry(registration, true, null);
// #3
this.onSentObserveToClient(lwServer, registration);
}
/**
* Sent Attribute and Telemetry to Thingsboard
* #1 - get AttrName/TelemetryName with value:
* #1.1 from Client
* #1.2 from LwM2MClient:
* -- resourceId == path from AttrTelemetryObserveValue.postAttributeProfile/postTelemetryProfile/postObserveProfile
* -- AttrName/TelemetryName == resourceName from ModelObject.objectModel, value from ModelObject.instance.resource(resourceId)
* #2 - set Attribute/Telemetry
*
* @param registration - Registration LwM2M Client
*/
private void updateAttrTelemetry(Registration registration, boolean start, Set<String> paths) {
JsonObject attributes = new JsonObject();
JsonObject telemetrys = new JsonObject();
if (start) {
// #1.1
JsonObject attributeClient = this.getAttributeClient(registration);
if (attributeClient != null) {
attributeClient.entrySet().forEach(p -> {
attributes.add(p.getKey(), p.getValue());
});
}
}
// #1.2
CountDownLatch cancelLatch = new CountDownLatch(1);
this.getParametersFromProfile(attributes, telemetrys, registration, paths);
cancelLatch.countDown();
try {
cancelLatch.await(DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
log.error("[{}] updateAttrTelemetry", e.toString());
}
if (attributes.getAsJsonObject().entrySet().size() > 0)
this.updateParametersOnThingsboard(attributes, DEVICE_ATTRIBUTES_TOPIC, registration.getId());
if (telemetrys.getAsJsonObject().entrySet().size() > 0)
this.updateParametersOnThingsboard(telemetrys, DEVICE_TELEMETRY_TOPIC, registration.getId());
}
/**
* get AttrName/TelemetryName with value from Client
*
* @param registration -
* @return - JsonObject, format: {name: value}}
*/
private JsonObject getAttributeClient(Registration registration) {
if (registration.getAdditionalRegistrationAttributes().size() > 0) {
JsonObject resNameValues = new JsonObject();
registration.getAdditionalRegistrationAttributes().entrySet().forEach(entry -> {
resNameValues.addProperty(entry.getKey(), entry.getValue());
});
return resNameValues;
}
return null;
}
/**
* @param attributes - new JsonObject
* @param telemetry - new JsonObject
* @param registration - Registration LwM2M Client
* result: add to JsonObject those resources to which the user is subscribed and they have a value
* if path==null add All resources else only one
* (attributes/telemetry): new {name(Attr/Telemetry):value}
*/
private void getParametersFromProfile(JsonObject attributes, JsonObject telemetry, Registration registration, Set<String> path) {
AttrTelemetryObserveValue attrTelemetryObserveValue = lwM2mInMemorySecurityStore.getProfiles().get(lwM2mInMemorySecurityStore.getSessions().get(registration.getId()).getProfileUuid());
attrTelemetryObserveValue.getPostAttributeProfile().forEach(p -> {
ResultIds pathIds = new ResultIds(p.getAsString().toString());
if (pathIds.getResourceId() > -1) {
if (path == null || path.contains(p.getAsString())) {
this.addParameters(pathIds, p.getAsString().toString(), attributes, registration);
}
}
});
attrTelemetryObserveValue.getPostTelemetryProfile().forEach(p -> {
ResultIds pathIds = new ResultIds(p.getAsString().toString());
if (pathIds.getResourceId() > -1) {
if (path == null || path.contains(p.getAsString())) {
this.addParameters(pathIds, p.getAsString().toString(), telemetry, registration);
}
}
});
}
/**
* @param pathIds - path resource
* @param parameters - JsonObject attributes/telemetry
* @param registration - Registration LwM2M Client
*/
private void addParameters(ResultIds pathIds, String path, JsonObject parameters, Registration registration) {
ModelObject modelObject = lwM2mInMemorySecurityStore.getSessions().get(registration.getId()).getModelObjects().get(pathIds.getObjectId());
JsonObject names = lwM2mInMemorySecurityStore.getProfiles().get(lwM2mInMemorySecurityStore.getSessions().get(registration.getId()).getProfileUuid()).getPostKeyNameProfile();
String resName = String.valueOf(names.get(path));
if (modelObject != null && resName != null && !resName.isEmpty()) {
String resValue = this.getResourceValue(modelObject, pathIds);
if (resValue != null) {
parameters.addProperty(resName, resValue);
}
}
}
/**
* @param modelObject - ModelObject of Client
* @param pathIds - path resource
* @return - value of Resource or null
*/
private String getResourceValue(ModelObject modelObject, ResultIds pathIds) {
String resValue = null;
if (modelObject.getInstances().get(pathIds.getInstanceId()) != null) {
LwM2mObjectInstance instance = modelObject.getInstances().get(pathIds.getInstanceId());
if (instance.getResource(pathIds.getResourceId()) != null) {
resValue = instance.getResource(pathIds.getResourceId()).getType() == OPAQUE ?
Hex.encodeHexString((byte[]) instance.getResource(pathIds.getResourceId()).getValue()).toLowerCase() :
(instance.getResource(pathIds.getResourceId()).isMultiInstances()) ?
instance.getResource(pathIds.getResourceId()).getValues().toString() :
instance.getResource(pathIds.getResourceId()).getValue().toString();
}
}
return resValue;
}
/**
* Prepare Sent to Thigsboard callback - Attribute or Telemetry
*
* @param msg - JsonArray: [{name: value}]
* @param topicName - Api Attribute or Telemetry
* @param registrationId - Id of Registration LwM2M Client
*/
public void updateParametersOnThingsboard(JsonElement msg, String topicName, String registrationId) {
SessionInfoProto sessionInfo = this.getValidateSessionInfo(registrationId);
if (sessionInfo != null) {
try {
if (topicName.equals(LwM2MTransportHandler.DEVICE_ATTRIBUTES_TOPIC)) {
PostAttributeMsg postAttributeMsg = adaptor.convertToPostAttributes(msg);
TransportServiceCallback call = this.getPubAckCallbackSentAttrTelemetry(-1, postAttributeMsg);
transportService.process(sessionInfo, postAttributeMsg, call);
} else if (topicName.equals(LwM2MTransportHandler.DEVICE_TELEMETRY_TOPIC)) {
PostTelemetryMsg postTelemetryMsg = adaptor.convertToPostTelemetry(msg);
TransportServiceCallback call = this.getPubAckCallbackSentAttrTelemetry(-1, postTelemetryMsg);
transportService.process(sessionInfo, postTelemetryMsg, this.getPubAckCallbackSentAttrTelemetry(-1, call));
}
} catch (AdaptorException e) {
log.error("[{}] Failed to process publish msg [{}]", topicName, e);
log.info("[{}] Closing current session due to invalid publish", topicName);
}
} else {
log.error("Client: [{}] updateParametersOnThingsboard [{}] sessionInfo ", registrationId, sessionInfo);
}
}
/**
* Sent to Thingsboard Attribute || Telemetry
*
* @param msgId - always == -1
* @param msg - JsonObject: [{name: value}]
* @return - dummy
*/
private <T> TransportServiceCallback<Void> getPubAckCallbackSentAttrTelemetry(final int msgId, final T msg) {
return new TransportServiceCallback<Void>() {
@Override
public void onSuccess(Void dummy) {
log.trace("Success to publish msg: {}, dummy: {}", msg, dummy);
}
@Override
public void onError(Throwable e) {
log.trace("[{}] Failed to publish msg: {}", msg, e);
}
};
}
/**
* Start observe
* #1 - Analyze:
* #1.1 path in observe == (attribute or telemetry)
* #1.2 recourseValue notNull
* #2 Analyze after sent request (response):
* #2.1 First: lwM2MTransportRequest.sendResponse -> ObservationListener.newObservation
* #2.2 Next: ObservationListener.onResponse *
*
* @param lwServer - LeshanServer
* @param registration - Registration LwM2M Client
*/
private void onSentObserveToClient(LeshanServer lwServer, Registration registration) {
if (lwServer.getObservationService().getObservations(registration).size() > 0) {
this.setCancelObservations(lwServer, registration);
}
UUID profileUUid = lwM2mInMemorySecurityStore.getSessions().get(registration.getId()).getProfileUuid();
AttrTelemetryObserveValue attrTelemetryObserveValue = lwM2mInMemorySecurityStore.getProfiles().get(profileUUid);
attrTelemetryObserveValue.getPostObserveProfile().forEach(p -> {
// #1.1
String target = (getValidateObserve(attrTelemetryObserveValue.getPostAttributeProfile(), p.getAsString().toString())) ?
p.getAsString().toString() : (getValidateObserve(attrTelemetryObserveValue.getPostTelemetryProfile(), p.getAsString().toString())) ?
p.getAsString().toString() : null;
if (target != null) {
// #1.2
ResultIds pathIds = new ResultIds(target);
ModelObject modelObject = lwM2mInMemorySecurityStore.getSessions().get(registration.getId()).getModelObjects().get(pathIds.getObjectId());
// #2
if (modelObject != null) {
if (getResourceValue(modelObject, pathIds) != null) {
lwM2MTransportRequest.sendAllRequest(lwServer, registration, target, GET_TYPE_OPER_OBSERVE,
null, null, null, null, this.context.getCtxServer().getTimeout());
}
}
}
});
}
public void setCancelObservations(LeshanServer lwServer, Registration registration) {
if (registration != null) {
Set<Observation> observations = lwServer.getObservationService().getObservations(registration);
observations.forEach(observation -> {
this.setCancelObservationRecourse(lwServer, registration, observation.getPath().toString());
});
}
}
/**
* 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()}
*/
public void setCancelObservationRecourse(LeshanServer lwServer, Registration registration, String path) {
CountDownLatch cancelLatch = new CountDownLatch(1);
lwServer.getObservationService().cancelObservations(registration, path);
cancelLatch.countDown();
try {
cancelLatch.await(DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
}
}
/**
* @param parameters - JsonArray postAttributeProfile/postTelemetryProfile
* @param path - recourse from postObserveProfile
* @return rez - true if path observe is in attribute/telemetry
*/
private boolean getValidateObserve(JsonElement parameters, String path) {
AtomicBoolean rez = new AtomicBoolean(false);
if (parameters.isJsonArray()) {
parameters.getAsJsonArray().forEach(p -> {
if (p.getAsString().toString().equals(path)) rez.set(true);
}
);
} else if (parameters.isJsonObject()) {
rez.set((parameters.getAsJsonObject().entrySet()).stream().map(json -> json.toString())
.filter(path::equals).findAny().orElse(null) != null);
}
return rez.get();
}
/**
* Sending observe value to thingsboard from ObservationListener.onResponse: object, instance, SingleResource or MultipleResource
*
* @param registration - Registration LwM2M Client
* @param path - observe
* @param response - observe
*/
@SneakyThrows
public void onObservationResponse(Registration registration, String path, ReadResponse response) {
if (response.getContent() != null) {
if (response.getContent() instanceof LwM2mObject) {
LwM2mObject content = (LwM2mObject) response.getContent();
String target = "/" + content.getId();
} else if (response.getContent() instanceof LwM2mObjectInstance) {
LwM2mObjectInstance content = (LwM2mObjectInstance) response.getContent();
} else if (response.getContent() instanceof LwM2mSingleResource) {
LwM2mSingleResource content = (LwM2mSingleResource) response.getContent();
this.onObservationSetResourcesValue(registration, content.getValue(), null, path);
} else if (response.getContent() instanceof LwM2mMultipleResource) {
LwM2mSingleResource content = (LwM2mSingleResource) response.getContent();
this.onObservationSetResourcesValue(registration, null, content.getValues(), path);
}
}
}
/**
* Sending observe value of resources to thingsboard
* #1 Return old Resource from ModelObject
* #2 Create new Resource with value from observation
* #3 Create new Resources from old Resources
* #4 Update new Resources (replace old Resource on new Resource)
* #5 Remove old Instance from modelClient
* #6 Create new Instance with new Resources values
* #7 Update modelClient.getModelObjects(idObject) (replace old Instance on new Instance)
*
* @param registration - Registration LwM2M Client
* @param value - LwM2mSingleResource response.getContent()
* @param values - LwM2mSingleResource response.getContent()
* @param path - resource
*/
private void onObservationSetResourcesValue(Registration registration, Object value, Map<Integer, ?> values, String path) {
ResultIds resultIds = new ResultIds(path);
// #1
LwM2MClient lwM2MClient = lwM2mInMemorySecurityStore.getlwM2MClient(registration.getId());
ModelObject modelObject = lwM2MClient.getModelObjects().get(resultIds.getObjectId());
Map<Integer, LwM2mObjectInstance> instancesModelObject = modelObject.getInstances();
LwM2mObjectInstance instanceOld = (instancesModelObject.get(resultIds.instanceId) != null) ? instancesModelObject.get(resultIds.instanceId) : null;
Map<Integer, LwM2mResource> resourcesOld = (instanceOld != null) ? instanceOld.getResources() : null;
LwM2mResource resourceOld = (resourcesOld != null && resourcesOld.get(resultIds.getResourceId()) != null) ? resourcesOld.get(resultIds.getResourceId()) : null;
// #2
LwM2mResource resourceNew;
if (resourceOld.isMultiInstances()) {
resourceNew = LwM2mMultipleResource.newResource(resultIds.getResourceId(), values, resourceOld.getType());
} else {
resourceNew = LwM2mSingleResource.newResource(resultIds.getResourceId(), value, resourceOld.getType());
}
//#3
Map<Integer, LwM2mResource> resourcesNew = new HashMap<>(resourcesOld);
// #4
resourcesNew.remove(resourceOld);
// #5
resourcesNew.put(resultIds.getResourceId(), resourceNew);
// #6
LwM2mObjectInstance instanceNew = new LwM2mObjectInstance(resultIds.instanceId, resourcesNew.values());
// #7
CountDownLatch respLatch = new CountDownLatch(1);
lwM2MClient.getModelObjects().get(resultIds.getObjectId()).removeInstance(resultIds.instanceId);
instancesModelObject.put(resultIds.instanceId, instanceNew);
respLatch.countDown();
try {
respLatch.await(DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS);
} catch (InterruptedException ex) {
}
Set<String> paths = new HashSet<String>();
paths.add(path);
this.updateAttrTelemetry(registration, false, paths);
}
/**
* @param updateCredentials - Credentials include config only security Client (without config attr/telemetry...)
* config attr/telemetry... in profile
*/
public void onToTransportUpdateCredentials(ToTransportUpdateCredentialsProto updateCredentials) {
log.info("[{}] idList [{}] valueList updateCredentials", updateCredentials.getCredentialsIdList(), updateCredentials.getCredentialsValueList());
}
/**
* Update - sent request in change value resources in Client (path to resources from profile by keyName)
* Only fo resources W
* Delete - nothing
*
* @param msg -
* @param sessionInfo -
*/
public void onAttributeUpdate(TransportProtos.AttributeUpdateNotificationMsg msg, SessionInfoProto sessionInfo) {
if (msg.getSharedUpdatedCount() > 0) {
JsonElement el = JsonConverter.toJson(msg);
el.getAsJsonObject().entrySet().forEach(de -> {
String profilePath = lwM2mInMemorySecurityStore.getProfiles().get(new UUID(sessionInfo.getDeviceProfileIdMSB(), sessionInfo.getDeviceProfileIdLSB()))
.getPostKeyNameProfile().getAsJsonObject().entrySet().stream()
.filter(e -> e.getValue().getAsString().equals(de.getKey())).findFirst().map(Map.Entry::getKey)
.orElse("");
String path = !profilePath.isEmpty() ? profilePath : this.getPathAttributeUpdate(sessionInfo, de.getKey());
if (path != null) {
ResultIds resultIds = new ResultIds(path);
LwM2MClient lwM2MClient = lwM2mInMemorySecurityStore.getSession(new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB())).entrySet().iterator().next().getValue();
ResourceModel.Operations operations = lwM2MClient.getModelObjects().get(resultIds.getObjectId()).getObjectModel().resources.get(resultIds.getResourceId()).operations;
String value = ((JsonPrimitive) de.getValue()).getAsString();
if (operations.isWritable()) {
lwM2MTransportRequest.sendAllRequest(lwM2MClient.getLwServer(), lwM2MClient.getRegistration(), path, POST_TYPE_OPER_WRITE_REPLACE,
ContentFormat.TLV.getName(), lwM2MClient, null, value, this.context.getCtxServer().getTimeout());
log.info("[{}] path onAttributeUpdate", path);
}
else {
log.error(LOG_LW2M_ERROR + ": Resource path - [{}] value - [{}] is not Writable and cannot be updated", path, value);
String logMsg = String.format(LOG_LW2M_ERROR + " attributeUpdate: Resource path - %s value - %s is not Writable and cannot be updated", path, value);
this.sentLogsToThingsboard(logMsg, lwM2MClient.getRegistration().getId());
}
}
});
} else if (msg.getSharedDeletedCount() > 0) {
log.info("[{}] delete [{}] onAttributeUpdate", msg.getSharedDeletedList(), sessionInfo);
}
}
private String getPathAttributeUpdate(SessionInfoProto sessionInfo, String keyName) {
try {
LwM2MClient lwM2MClient = lwM2mInMemorySecurityStore.getSession(new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB())).entrySet().iterator().next().getValue();
Predicate<Map.Entry<Integer, ResourceModel>> predicateRes = res -> keyName.equals(splitCamelCaseString(res.getValue().name));
Predicate<Map.Entry<Integer, ModelObject>> predicateObj = (obj -> {
return obj.getValue().getObjectModel().resources.entrySet().stream().filter(predicateRes).findFirst().isPresent();
});
Stream<Map.Entry<Integer, ModelObject>> objectStream = lwM2MClient.getModelObjects().entrySet().stream().filter(predicateObj);
Predicate<Map.Entry<Integer, ResourceModel>> predicateResFinal = (objectStream.count() > 0) ? predicateRes : res -> keyName.equals(res.getValue().name);
Predicate<Map.Entry<Integer, ModelObject>> predicateObjFinal = (obj -> {
return obj.getValue().getObjectModel().resources.entrySet().stream().filter(predicateResFinal).findFirst().isPresent();
});
Map.Entry<Integer, ModelObject> object = lwM2MClient.getModelObjects().entrySet().stream().filter(predicateObjFinal).findFirst().get();
ModelObject modelObject = object.getValue();
LwM2mObjectInstance instance = modelObject.getInstances().entrySet().stream().findFirst().get().getValue();
ResourceModel resource = modelObject.getObjectModel().resources.entrySet().stream().filter(predicateResFinal).findFirst().get().getValue();
return new LwM2mPath(object.getKey(), instance.getId(), resource.id).toString();
} catch (NoSuchElementException e) {
log.error("[{}] keyName [{}]", keyName, e.toString());
return null;
}
}
public void onAttributeUpdateOk(Registration registration, String path, WriteRequest request) {
ResultIds resultIds = new ResultIds(path);
LwM2MClient lwM2MClient = lwM2mInMemorySecurityStore.getlwM2MClient(registration.getId());
LwM2mResource resource = lwM2MClient.getModelObjects().get(resultIds.getObjectId()).getInstances().get(resultIds.getInstanceId()).getResource(resultIds.getResourceId());
if (resource.isMultiInstances()) {
this.onObservationSetResourcesValue(registration, null, ((LwM2mSingleResource) request.getNode()).getValues(), path);
} else {
this.onObservationSetResourcesValue(registration, ((LwM2mSingleResource) request.getNode()).getValue(), null, path);
}
}
/**
* @param sessionInfo -
* @param deviceProfile -
*/
public void onDeviceProfileUpdate(TransportProtos.SessionInfoProto sessionInfo, DeviceProfile deviceProfile) {
String registrationId = lwM2mInMemorySecurityStore.getSessions().entrySet()
.stream()
.filter(e -> e.getValue().getDeviceUuid().equals(new UUID(sessionInfo.getDeviceIdMSB(), sessionInfo.getDeviceIdLSB())))
.findFirst()
.map(Map.Entry::getKey)
.orElse("");
if (!registrationId.isEmpty()) {
this.onDeviceUpdateChangeProfile(registrationId, deviceProfile);
}
}
/**
* @param sessionInfo -
* @param device -
* @param deviceProfileOpt -
*/
public void onDeviceUpdate(TransportProtos.SessionInfoProto sessionInfo, Device device, Optional<DeviceProfile> deviceProfileOpt) {
Optional<String> registrationIdOpt = lwM2mInMemorySecurityStore.getSessions().entrySet().stream()
.filter(e -> device.getUuidId().equals(e.getValue().getDeviceUuid()))
.map(Map.Entry::getKey)
.findFirst();
registrationIdOpt.ifPresent(registrationId -> this.onDeviceUpdateLwM2MClient(registrationId, device, deviceProfileOpt));
}
/**
* Update parameters device in LwM2MClient
* If new deviceProfile != old deviceProfile => update deviceProfile
*
* @param registrationId -
* @param device -
*/
private void onDeviceUpdateLwM2MClient(String registrationId, Device device, Optional<DeviceProfile> deviceProfileOpt) {
LwM2MClient lwM2MClient = lwM2mInMemorySecurityStore.getSessions().get(registrationId);
lwM2MClient.setDeviceName(device.getName());
if (!lwM2MClient.getProfileUuid().equals(device.getDeviceProfileId().getId())) {
deviceProfileOpt.ifPresent(deviceProfile -> this.onDeviceUpdateChangeProfile(registrationId, deviceProfile));
}
}
/**
* #1 Read new, old Value (Attribute, Telemetry, Observe, KeyName)
* #2 Update in lwM2MClient: ...Profile
* #3 Equivalence test: old <> new Value (Attribute, Telemetry, Observe, KeyName)
* #3.1 Attribute isChange (add&del)
* #3.2 Telemetry isChange (add&del)
* #3.3 KeyName isChange (add)
* #4 update
* #4.1 add If #3 isChange, then analyze and update Value in Transport form Client and sent Value ti thingsboard
* #4.2 del
* -- if add attributes includes del telemetry - result del for observe
* #5
* #5.1 Observe isChange (add&del)
* #5.2 Observe.add
* -- path Attr/Telemetry includes newObserve and does not include oldObserve: sent Request observe to Client
* #5.3 Observe.del
* -- different between newObserve and oldObserve: sent Request cancel observe to client
*
* @param registrationId -
* @param deviceProfile -
*/
public void onDeviceUpdateChangeProfile(String registrationId, DeviceProfile deviceProfile) {
LwM2MClient lwM2MClient = lwM2mInMemorySecurityStore.getlwM2MClient(registrationId);
AttrTelemetryObserveValue attrTelemetryObserveValueOld = lwM2mInMemorySecurityStore.getProfiles().get(lwM2MClient.getProfileUuid());
if (lwM2mInMemorySecurityStore.addUpdateProfileParameters(deviceProfile)) {
LeshanServer lwServer = lwM2MClient.getLwServer();
Registration registration = lwM2mInMemorySecurityStore.getByRegistration(registrationId);
// #1
JsonArray attributeOld = attrTelemetryObserveValueOld.getPostAttributeProfile();
Set<String> attributeSetOld = new Gson().fromJson(attributeOld, Set.class);
JsonArray telemetryOld = attrTelemetryObserveValueOld.getPostTelemetryProfile();
Set<String> telemetrySetOld = new Gson().fromJson(telemetryOld, Set.class);
JsonArray observeOld = attrTelemetryObserveValueOld.getPostObserveProfile();
JsonObject keyNameOld = attrTelemetryObserveValueOld.getPostKeyNameProfile();
AttrTelemetryObserveValue attrTelemetryObserveValueNew = lwM2mInMemorySecurityStore.getProfiles().get(deviceProfile.getUuidId());
JsonArray attributeNew = attrTelemetryObserveValueNew.getPostAttributeProfile();
Set<String> attributeSetNew = new Gson().fromJson(attributeNew, Set.class);
JsonArray telemetryNew = attrTelemetryObserveValueNew.getPostTelemetryProfile();
Set<String> telemetrySetNew = new Gson().fromJson(telemetryNew, Set.class);
JsonArray observeNew = attrTelemetryObserveValueNew.getPostObserveProfile();
JsonObject keyNameNew = attrTelemetryObserveValueNew.getPostKeyNameProfile();
// #2
lwM2MClient.setDeviceProfileName(deviceProfile.getName());
lwM2MClient.setProfileUuid(deviceProfile.getUuidId());
// #3
ResultsAnalyzerParameters sentAttrToThingsboard = new ResultsAnalyzerParameters();
// #3.1
if (!attributeOld.equals(attributeNew)) {
ResultsAnalyzerParameters postAttributeAnalyzer = this.getAnalyzerParameters(new Gson().fromJson(attributeOld, Set.class), attributeSetNew);
sentAttrToThingsboard.getPathPostParametersAdd().addAll(postAttributeAnalyzer.getPathPostParametersAdd());
sentAttrToThingsboard.getPathPostParametersDel().addAll(postAttributeAnalyzer.getPathPostParametersDel());
}
// #3.2
if (!attributeOld.equals(attributeNew)) {
ResultsAnalyzerParameters postTelemetryAnalyzer = this.getAnalyzerParameters(new Gson().fromJson(telemetryOld, Set.class), telemetrySetNew);
sentAttrToThingsboard.getPathPostParametersAdd().addAll(postTelemetryAnalyzer.getPathPostParametersAdd());
sentAttrToThingsboard.getPathPostParametersDel().addAll(postTelemetryAnalyzer.getPathPostParametersDel());
}
// #3.3
if (!keyNameOld.equals(keyNameNew)) {
ResultsAnalyzerParameters keyNameChange = this.getAnalyzerKeyName(new Gson().fromJson(keyNameOld.toString(), ConcurrentHashMap.class),
new Gson().fromJson(keyNameNew.toString(), ConcurrentHashMap.class));
sentAttrToThingsboard.getPathPostParametersAdd().addAll(keyNameChange.getPathPostParametersAdd());
}
// #4.1 add
if (sentAttrToThingsboard.getPathPostParametersAdd().size() > 0) {
// update value in Resources
this.updateResourceValueObserve(lwServer, registration, lwM2MClient, sentAttrToThingsboard.getPathPostParametersAdd(), GET_TYPE_OPER_READ);
// sent attr/telemetry to tingsboard for new path
this.updateAttrTelemetry(registration, false, sentAttrToThingsboard.getPathPostParametersAdd());
}
// #4.2 del
if (sentAttrToThingsboard.getPathPostParametersDel().size() > 0) {
ResultsAnalyzerParameters sentAttrToThingsboardDel = this.getAnalyzerParameters(sentAttrToThingsboard.getPathPostParametersAdd(), sentAttrToThingsboard.getPathPostParametersDel());
sentAttrToThingsboard.setPathPostParametersDel(sentAttrToThingsboardDel.getPathPostParametersDel());
}
// #5.1
if (!observeOld.equals(observeNew)) {
Set<String> observeSetOld = new Gson().fromJson(observeOld, Set.class);
Set<String> observeSetNew = new Gson().fromJson(observeNew, Set.class);
//#5.2 add
// path Attr/Telemetry includes newObserve
attributeSetOld.addAll(telemetrySetOld);
ResultsAnalyzerParameters sentObserveToClientOld = this.getAnalyzerParametersIn(attributeSetOld, observeSetOld); // add observe
attributeSetNew.addAll(telemetrySetNew);
ResultsAnalyzerParameters sentObserveToClientNew = this.getAnalyzerParametersIn(attributeSetNew, observeSetNew); // add observe
// does not include oldObserve
ResultsAnalyzerParameters postObserveAnalyzer = this.getAnalyzerParameters(sentObserveToClientOld.getPathPostParametersAdd(), sentObserveToClientNew.getPathPostParametersAdd());
// sent Request observe to Client
this.updateResourceValueObserve(lwServer, registration, lwM2MClient, postObserveAnalyzer.getPathPostParametersAdd(), GET_TYPE_OPER_OBSERVE);
// 5.3 del
// sent Request cancel observe to Client
this.cancelObserveIsValue(lwServer, registration, postObserveAnalyzer.getPathPostParametersDel());
}
}
}
/**
* Compare old list with new list after change AttrTelemetryObserve in config Profile
*
* @param parametersOld -
* @param parametersNew -
* @return ResultsAnalyzerParameters: add && new
*/
private ResultsAnalyzerParameters getAnalyzerParameters(Set<String> parametersOld, Set<String> parametersNew) {
ResultsAnalyzerParameters analyzerParameters = null;
if (!parametersOld.equals(parametersNew)) {
analyzerParameters = new ResultsAnalyzerParameters();
analyzerParameters.setPathPostParametersAdd(parametersNew
.stream().filter(p -> !parametersOld.contains(p)).collect(Collectors.toSet()));
analyzerParameters.setPathPostParametersDel(parametersOld
.stream().filter(p -> !parametersNew.contains(p)).collect(Collectors.toSet()));
}
return analyzerParameters;
}
private ResultsAnalyzerParameters getAnalyzerKeyName(ConcurrentMap<String, String> keyNameOld, ConcurrentMap<String, String> keyNameNew) {
ResultsAnalyzerParameters analyzerParameters = new ResultsAnalyzerParameters();
Set<String> paths = keyNameNew.entrySet()
.stream()
.filter(e -> !e.getValue().equals(keyNameOld.get(e.getKey())))
.collect(Collectors.toMap(map -> map.getKey(), map -> map.getValue())).keySet();
analyzerParameters.setPathPostParametersAdd(paths);
return analyzerParameters;
}
private ResultsAnalyzerParameters getAnalyzerParametersIn(Set<String> parametersObserve, Set<String> parameters) {
ResultsAnalyzerParameters analyzerParameters = new ResultsAnalyzerParameters();
analyzerParameters.setPathPostParametersAdd(parametersObserve
.stream().filter(p -> parameters.contains(p)).collect(Collectors.toSet()));
return analyzerParameters;
}
/**
* Update Resource value after change RezAttrTelemetry in config Profile
* sent response Read to Client and add path to pathResAttrTelemetry in LwM2MClient.getAttrTelemetryObserveValue()
*
* @param lwServer - LeshanServer
* @param registration - Registration LwM2M Client
* @param lwM2MClient - object with All parameters off client
* @param targets - path Resources == [ "/2/0/0", "/2/0/1"]
*/
private void updateResourceValueObserve(LeshanServer lwServer, Registration registration, LwM2MClient lwM2MClient, Set<String> targets, String typeOper) {
targets.stream().forEach(target -> {
ResultIds pathIds = new ResultIds(target);
if (pathIds.resourceId >= 0 && lwM2MClient.getModelObjects().get(pathIds.getObjectId())
.getInstances().get(pathIds.getInstanceId()).getResource(pathIds.getResourceId()).getValue() != null) {
if (GET_TYPE_OPER_READ.equals(typeOper)) {
lwM2MTransportRequest.sendAllRequest(lwServer, registration, target, typeOper,
ContentFormat.TLV.getName(), null, null, null, this.context.getCtxServer().getTimeout());
} else if (GET_TYPE_OPER_OBSERVE.equals(typeOper)) {
lwM2MTransportRequest.sendAllRequest(lwServer, registration, target, typeOper,
null, null, null, null, this.context.getCtxServer().getTimeout());
}
}
});
}
private void cancelObserveIsValue(LeshanServer lwServer, Registration registration, Set<String> paramAnallyzer) {
LwM2MClient lwM2MClient = lwM2mInMemorySecurityStore.getlwM2MClient(registration.getId());
paramAnallyzer.forEach(p -> {
if (this.getResourceValue(lwM2MClient, p) != null) {
this.setCancelObservationRecourse(lwServer, registration, p);
}
}
);
}
private ResourceValue getResourceValue(LwM2MClient lwM2MClient, String path) {
ResourceValue resourceValue = null;
ResultIds pathIds = new ResultIds(path);
if (pathIds.getResourceId() > -1) {
LwM2mResource resource = lwM2MClient.getModelObjects().get(pathIds.getObjectId()).getInstances().get(pathIds.getInstanceId()).getResource(pathIds.getResourceId());
if (resource.isMultiInstances()) {
Map<Integer, ?> values = resource.getValues();
if (resource.getValues().size() > 0) {
resourceValue = new ResourceValue();
resourceValue.setMultiInstances(resource.isMultiInstances());
resourceValue.setValues(resource.getValues());
}
} else {
if (resource.getValue() != null) {
resourceValue = new ResourceValue();
resourceValue.setMultiInstances(resource.isMultiInstances());
resourceValue.setValue(resource.getValue());
}
}
}
return resourceValue;
}
/**
* Trigger Server path = "/1/0/8"
*
* Trigger bootStrap path = "/1/0/9" - have to implemented on client
*/
public void doTrigger(LeshanServer lwServer, Registration registration, String path) {
lwM2MTransportRequest.sendAllRequest(lwServer, registration, path, POST_TYPE_OPER_EXECUTE,
ContentFormat.TLV.getName(), null, null, null, this.context.getCtxServer().getTimeout());
}
/**
* Session device in thingsboard is closed
*
* @param sessionInfo - lwm2m client
*/
private void doCloseSession(SessionInfoProto sessionInfo) {
TransportProtos.SessionEvent event = SessionEvent.CLOSED;
TransportProtos.SessionEventMsg msg = TransportProtos.SessionEventMsg.newBuilder()
.setSessionType(TransportProtos.SessionType.ASYNC)
.setEvent(event).build();
transportService.process(sessionInfo, msg, null);
}
/**
* Deregister session in transport
* @param sessionInfo - lwm2m client
*/
private void doDisconnect(SessionInfoProto sessionInfo) {
transportService.process(sessionInfo, DefaultTransportService.getSessionEventMsg(SessionEvent.CLOSED), null);
transportService.deregisterSession(sessionInfo);
}
private void checkInactivityAndReportActivity() {
lwM2mInMemorySecurityStore.getSessions().forEach((key, value) -> transportService.reportActivity(this.getValidateSessionInfo(key)));
}
public void sentLogsToThingsboard(String msg, String registrationId) {
if (msg != null) {
JsonObject telemetrys = new JsonObject();
telemetrys.addProperty(LOG_LW2M_TELEMETRY, msg);
this.updateParametersOnThingsboard(telemetrys, LwM2MTransportHandler.DEVICE_TELEMETRY_TOPIC, registrationId);
}
}
}

111
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/LwM2mServerListener.java

@ -1,111 +0,0 @@
/**
* Copyright © 2016-2020 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.transport.lwm2m.server;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.leshan.core.observation.Observation;
import org.eclipse.leshan.core.response.ObserveResponse;
import org.eclipse.leshan.server.californium.LeshanServer;
import org.eclipse.leshan.server.observation.ObservationListener;
import org.eclipse.leshan.server.queue.PresenceListener;
import org.eclipse.leshan.server.registration.Registration;
import org.eclipse.leshan.server.registration.RegistrationListener;
import org.eclipse.leshan.server.registration.RegistrationUpdate;
import java.util.Collection;
@Slf4j
public class LwM2mServerListener {
private LeshanServer lhServer;
private LwM2MTransportService service;
public LwM2mServerListener(LeshanServer lhServer, LwM2MTransportService service) {
this.lhServer = lhServer;
this.service = service;
}
public final RegistrationListener registrationListener = new RegistrationListener() {
/**
* Register запрос, представленный в виде POST /rd?
*/
@Override
public void registered(Registration registration, Registration previousReg,
Collection<Observation> previousObsersations) {
service.onRegistered(lhServer, registration, previousObsersations);
}
/**
* Update представляет из себя CoAP POST запрос на URL, полученный в ответ на Register.
*/
@Override
public void updated(RegistrationUpdate update, Registration updatedRegistration,
Registration previousRegistration) {
service.updatedReg(lhServer, updatedRegistration);
}
/**
* De-register (CoAP DELETE) отправляется клиентом в случае инициирования процедуры выключения.
*/
@Override
public void unregistered(Registration registration, Collection<Observation> observations, boolean expired,
Registration newReg) {
service.unReg(registration, observations);
}
};
public final PresenceListener presenceListener = new PresenceListener() {
@Override
public void onSleeping(Registration registration) {
service.onSleepingDev(registration);
}
@Override
public void onAwake(Registration registration) {
service.onAwakeDev(registration);
}
};
public final ObservationListener observationListener = new ObservationListener() {
@Override
public void cancelled(Observation observation) {
log.info("Received notification cancelled from [{}] ", observation.getPath());
}
@Override
public void onResponse(Observation observation, Registration registration, ObserveResponse response) {
if (registration != null) {
try {
service.onObservationResponse(registration, observation.getPath().toString(), response);
} catch (java.lang.NullPointerException e) {
log.error(e.toString());
}
}
}
@Override
public void onError(Observation observation, Registration registration, Exception error) {
log.error(String.format("Unable to handle notification of [%s:%s]", observation.getRegistrationId(), observation.getPath()), error);
}
@Override
public void newObservation(Observation observation, Registration registration) {
log.info("Received newObservation from [{}] endpoint [{}] ", observation.getPath(), registration.getEndpoint());
}
};
}

38
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/ResultIds.java

@ -1,38 +0,0 @@
/**
* Copyright © 2016-2020 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.transport.lwm2m.server;
import lombok.Builder;
import lombok.Data;
@Data
public class ResultIds {
@Builder.Default
int objectId = -1;
@Builder.Default
int instanceId = -1;
@Builder.Default
int resourceId = -1;
public ResultIds (String path) {
String[] paths = path.split("/");
if (paths != null && paths.length > 1) {
this.objectId = (paths.length > 1) ? Integer.parseInt(paths[1]) : this.objectId;
this.instanceId = (paths.length > 2) ? Integer.parseInt(paths[2]) : this.instanceId;
this.resourceId = (paths.length > 3) ? Integer.parseInt(paths[3]) : this.resourceId;
}
}
}

49
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/adaptors/LwM2MJsonAdaptor.java

@ -1,49 +0,0 @@
/**
* Copyright © 2016-2020 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.transport.lwm2m.server.adaptors;
import com.google.gson.JsonElement;
import com.google.gson.JsonSyntaxException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.stereotype.Component;
import org.thingsboard.server.common.transport.adaptor.AdaptorException;
import org.thingsboard.server.common.transport.adaptor.JsonConverter;
import org.thingsboard.server.gen.transport.TransportProtos;
@Slf4j
@Component("LwM2MJsonAdaptor")
@ConditionalOnExpression("('${service.type:null}'=='tb-transport' && '${transport.lwm2m.enabled:false}'=='true' )|| ('${service.type:null}'=='monolith' && '${transport.lwm2m.enabled}'=='true')")
public class LwM2MJsonAdaptor implements LwM2MTransportAdaptor {
@Override
public TransportProtos.PostTelemetryMsg convertToPostTelemetry(JsonElement jsonElement) throws AdaptorException {
try {
return JsonConverter.convertToTelemetryProto(jsonElement);
} catch (IllegalStateException | JsonSyntaxException ex) {
throw new AdaptorException(ex);
}
}
@Override
public TransportProtos.PostAttributeMsg convertToPostAttributes(JsonElement jsonElement) throws AdaptorException {
try {
return JsonConverter.convertToAttributesProto(jsonElement);
} catch (IllegalStateException | JsonSyntaxException ex) {
throw new AdaptorException(ex);
}
}
}

27
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/adaptors/LwM2MTransportAdaptor.java

@ -1,27 +0,0 @@
/**
* Copyright © 2016-2020 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.transport.lwm2m.server.adaptors;
import com.google.gson.JsonElement;
import org.thingsboard.server.common.transport.adaptor.AdaptorException;
import org.thingsboard.server.gen.transport.TransportProtos;
public interface LwM2MTransportAdaptor {
TransportProtos.PostTelemetryMsg convertToPostTelemetry(JsonElement jsonElement) throws AdaptorException;
TransportProtos.PostAttributeMsg convertToPostAttributes(JsonElement jsonElement) throws AdaptorException;
}

47
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/AttrTelemetryObserveValue.java

@ -1,47 +0,0 @@
/**
* Copyright © 2016-2020 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.transport.lwm2m.server.client;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import lombok.Data;
@Data
public class AttrTelemetryObserveValue {
/**
* {"keyName": {
* "/3/0/1": "modelNumber",
* "/3/0/0": "manufacturer",
* "/3/0/2": "serialNumber"
* }
**/
JsonObject postKeyNameProfile;
/**
* [ "/2/0/0", "/2/0/1"]
*/
JsonArray postAttributeProfile;
/**
* [ "/2/0/0", "/2/0/1"]
*/
JsonArray postTelemetryProfile;
/**
* [ "/2/0/0", "/2/0/1"]
*/
JsonArray postObserveProfile;
}

107
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2MClient.java

@ -1,107 +0,0 @@
/**
* Copyright © 2016-2020 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.transport.lwm2m.server.client;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.leshan.core.model.ObjectModel;
import org.eclipse.leshan.core.node.LwM2mObjectInstance;
import org.eclipse.leshan.core.response.LwM2mResponse;
import org.eclipse.leshan.core.response.ReadResponse;
import org.eclipse.leshan.server.californium.LeshanServer;
import org.eclipse.leshan.server.registration.Registration;
import org.eclipse.leshan.server.security.SecurityInfo;
import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceCredentialsResponseMsg;
import org.thingsboard.server.transport.lwm2m.server.LwM2MTransportService;
import org.thingsboard.server.transport.lwm2m.server.ResultIds;
import java.util.UUID;
import java.util.Map;
import java.util.Set;
import java.util.Collection;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
@Slf4j
@Data
public class LwM2MClient implements Cloneable {
private String deviceName;
private String deviceProfileName;
private String endPoint;
private String identity;
private SecurityInfo info;
private UUID deviceUuid;
private UUID sessionUuid;
private UUID profileUuid;
private LeshanServer lwServer;
private LwM2MTransportService lwM2MTransportService;
private Registration registration;
private ValidateDeviceCredentialsResponseMsg credentialsResponse;
private Map<String, String> attributes;
private Map<Integer, ModelObject> modelObjects;
private Set<String> pendingRequests;
private Map<String, LwM2mResponse> responses;
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
public LwM2MClient(String endPoint, String identity, SecurityInfo info, ValidateDeviceCredentialsResponseMsg credentialsResponse, Map<String, String> attributes, Map<Integer, ModelObject> modelObjects, UUID profileUuid) {
this.endPoint = endPoint;
this.identity = identity;
this.info = info;
this.credentialsResponse = credentialsResponse;
this.attributes = (attributes != null && attributes.size() > 0) ? attributes : new ConcurrentHashMap<String, String>();
this.modelObjects = (modelObjects != null && modelObjects.size() > 0) ? modelObjects : new ConcurrentHashMap<Integer, ModelObject>();
this.pendingRequests = ConcurrentHashMap.newKeySet();
this.profileUuid = profileUuid;
/**
* Key <objectId>, response<Value -> instance -> resources: value...>
*/
this.responses = new ConcurrentHashMap<>();
}
/**
* Fill with data -> Model client
* @param path -
* @param response -
*/
public void onSuccessHandler(String path, LwM2mResponse response) {
this.responses.put(path, response);
this.pendingRequests.remove(path);
if (this.pendingRequests.size() == 0) {
this.initValue();
this.lwM2MTransportService.updatesAndSentModelParameter(this.lwServer, this.registration);
}
}
private void initValue() {
this.responses.forEach((key, resp) -> {
ResultIds pathIds = new ResultIds(key);
if (pathIds.getObjectId() > -1) {
ObjectModel objectModel = ((Collection<ObjectModel>) this.lwServer.getModelProvider().getObjectModel(registration).getObjectModels()).stream().filter(v -> v.id == pathIds.getObjectId()).collect(Collectors.toList()).get(0);
if (this.modelObjects.get(pathIds.getObjectId()) != null) {
this.modelObjects.get(pathIds.getObjectId()).getInstances().put(((ReadResponse) resp).getContent().getId(), (LwM2mObjectInstance) ((ReadResponse) resp).getContent());
} else {
Map<Integer, LwM2mObjectInstance> instances = new ConcurrentHashMap<>();
instances.put(((ReadResponse) resp).getContent().getId(), (LwM2mObjectInstance) ((ReadResponse) resp).getContent());
ModelObject modelObject = new ModelObject(objectModel, instances);
this.modelObjects.put(pathIds.getObjectId(), modelObject);
}
}
});
}
}

41
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/ModelObject.java

@ -1,41 +0,0 @@
/**
* Copyright © 2016-2020 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.transport.lwm2m.server.client;
import lombok.Data;
import org.eclipse.leshan.core.model.ObjectModel;
import org.eclipse.leshan.core.node.LwM2mObjectInstance;
import java.util.Map;
@Data
public class ModelObject {
/**
* model one on all instance
* for each instance only id resource with parameters of resources (observe, attr, telemetry)
*/
private ObjectModel objectModel;
private Map<Integer, LwM2mObjectInstance> instances;
public ModelObject(ObjectModel objectModel, Map<Integer, LwM2mObjectInstance> instances) {
this.objectModel = objectModel;
this.instances = instances;
}
public boolean removeInstance (int id ) {
LwM2mObjectInstance instance = this.instances.get(id);
return this.instances.remove(id, instance);
}
}

26
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/ResourceValue.java

@ -1,26 +0,0 @@
/**
* Copyright © 2016-2020 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.transport.lwm2m.server.client;
import lombok.Data;
import java.util.Map;
@Data
public class ResourceValue {
Map<Integer, ?> values;
Object value;
boolean multiInstances;
}

32
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/ResultsAnalyzerParameters.java

@ -1,32 +0,0 @@
/**
* Copyright © 2016-2020 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.transport.lwm2m.server.client;
import lombok.Data;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
@Data
public class ResultsAnalyzerParameters {
Set<String> pathPostParametersAdd;
Set<String> pathPostParametersDel;
public ResultsAnalyzerParameters() {
this.pathPostParametersAdd = ConcurrentHashMap.newKeySet();
this.pathPostParametersDel = ConcurrentHashMap.newKeySet();
}
}

234
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/secure/LwM2MSetSecurityStoreServer.java

@ -1,234 +0,0 @@
/**
* Copyright © 2016-2020 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.transport.lwm2m.server.secure;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.leshan.core.util.Hex;
import org.eclipse.leshan.server.californium.LeshanServerBuilder;
import org.eclipse.leshan.server.redis.RedisRegistrationStore;
import org.eclipse.leshan.server.redis.RedisSecurityStore;
import org.eclipse.leshan.server.security.DefaultAuthorizer;
import org.eclipse.leshan.server.security.EditableSecurityStore;
import org.eclipse.leshan.server.security.SecurityChecker;
import org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode;
import org.thingsboard.server.transport.lwm2m.server.LwM2MTransportContextServer;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.util.Pool;
import java.math.BigInteger;
import java.net.URI;
import java.net.URISyntaxException;
import java.security.KeyStore;
import java.security.PublicKey;
import java.security.PrivateKey;
import java.security.AlgorithmParameters;
import java.security.KeyFactory;
import java.security.GeneralSecurityException;
import java.security.KeyStoreException;
import java.security.cert.X509Certificate;
import java.security.interfaces.ECPublicKey;
import java.security.spec.*;
import java.util.Arrays;
import static org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode.*;
@Slf4j
@Data
public class LwM2MSetSecurityStoreServer {
private KeyStore keyStore;
private X509Certificate certificate;
private PublicKey publicKey;
private PrivateKey privateKey;
private LwM2MTransportContextServer context;
private LwM2mInMemorySecurityStore lwM2mInMemorySecurityStore;
private LeshanServerBuilder builder;
EditableSecurityStore securityStore;
public LwM2MSetSecurityStoreServer(LeshanServerBuilder builder, LwM2MTransportContextServer context, LwM2mInMemorySecurityStore lwM2mInMemorySecurityStore, LwM2MSecurityMode dtlsMode) {
this.builder = builder;
this.context = context;
this.lwM2mInMemorySecurityStore = lwM2mInMemorySecurityStore;
/** Set securityStore with new registrationStore */
switch (dtlsMode) {
/** Use PSK only */
case PSK:
generatePSK_RPK();
if (this.privateKey != null && this.privateKey.getEncoded().length > 0) {
builder.setPrivateKey(this.privateKey);
builder.setPublicKey(null);
getParamsPSK();
}
break;
/** Use RPK only */
case RPK:
generatePSK_RPK();
if (this.publicKey != null && this.publicKey.getEncoded().length > 0 &&
this.privateKey != null && this.privateKey.getEncoded().length > 0) {
builder.setPublicKey(this.publicKey);
builder.setPrivateKey(this.privateKey);
getParamsRPK();
}
break;
/** Use x509 only */
case X509:
setServerWithX509Cert();
break;
/** No security */
case NO_SEC:
builder.setTrustedCertificates(new X509Certificate[0]);
break;
/** Use x509 with EST */
case X509_EST:
// TODO support sentinel pool and make pool configurable
break;
case REDIS:
/**
* Set securityStore with new registrationStore (if use redis store)
* Connect to redis
*/
Pool<Jedis> jedis = null;
try {
jedis = new JedisPool(new URI(this.context.getCtxServer().getRedisUrl()));
securityStore = new RedisSecurityStore(jedis);
builder.setRegistrationStore(new RedisRegistrationStore(jedis));
} catch (URISyntaxException e) {
e.printStackTrace();
}
break;
default:
}
/** Set securityStore with new registrationStore (if not redis)*/
if (dtlsMode.code < REDIS.code) {
securityStore = lwM2mInMemorySecurityStore;
if (dtlsMode == X509) {
builder.setAuthorizer(new DefaultAuthorizer(securityStore, new SecurityChecker() {
@Override
protected boolean matchX509Identity(String endpoint, String receivedX509CommonName,
String expectedX509CommonName) {
return endpoint.startsWith(expectedX509CommonName);
}
}));
}
}
/** Set securityStore with new registrationStore */
builder.setSecurityStore(securityStore);
}
private void generatePSK_RPK() {
try {
/** Get Elliptic Curve Parameter spec for secp256r1 */
AlgorithmParameters algoParameters = AlgorithmParameters.getInstance("EC");
algoParameters.init(new ECGenParameterSpec("secp256r1"));
ECParameterSpec parameterSpec = algoParameters.getParameterSpec(ECParameterSpec.class);
if (this.context.getCtxServer().getServerPublicX() != null && !this.context.getCtxServer().getServerPublicX().isEmpty() && this.context.getCtxServer().getServerPublicY() != null && !this.context.getCtxServer().getServerPublicY().isEmpty()) {
/** Get point values */
byte[] publicX = Hex.decodeHex(this.context.getCtxServer().getServerPublicX().toCharArray());
byte[] publicY = Hex.decodeHex(this.context.getCtxServer().getServerPublicY().toCharArray());
/** Create key specs */
KeySpec publicKeySpec = new ECPublicKeySpec(new ECPoint(new BigInteger(publicX), new BigInteger(publicY)),
parameterSpec);
/** Get keys */
this.publicKey = KeyFactory.getInstance("EC").generatePublic(publicKeySpec);
}
if (this.context.getCtxServer().getServerPrivateS() != null && !this.context.getCtxServer().getServerPrivateS().isEmpty()) {
/** Get point values */
byte[] privateS = Hex.decodeHex(this.context.getCtxServer().getServerPrivateS().toCharArray());
/** Create key specs */
KeySpec privateKeySpec = new ECPrivateKeySpec(new BigInteger(privateS), parameterSpec);
/** Get keys */
this.privateKey = KeyFactory.getInstance("EC").generatePrivate(privateKeySpec);
}
} catch (GeneralSecurityException | IllegalArgumentException e) {
log.error("[{}] Failed generate Server PSK/RPK", e.getMessage());
throw new RuntimeException(e);
}
}
private void setServerWithX509Cert() {
try {
if (this.context.getCtxServer().getKeyStoreValue() != null) {
setBuilderX509();
X509Certificate rootCAX509Cert = (X509Certificate) this.context.getCtxServer().getKeyStoreValue().getCertificate(this.context.getCtxServer().getRootAlias());
if (rootCAX509Cert != null) {
X509Certificate[] trustedCertificates = new X509Certificate[1];
trustedCertificates[0] = rootCAX509Cert;
builder.setTrustedCertificates(trustedCertificates);
} else {
/** by default trust all */
builder.setTrustedCertificates(new X509Certificate[0]);
}
}
else {
/** by default trust all */
this.builder.setTrustedCertificates(new X509Certificate[0]);
log.error("Unable to load X509 files for LWM2MServer");
}
} catch (KeyStoreException ex) {
log.error("[{}] Unable to load X509 files server", ex.getMessage());
}
}
private void setBuilderX509() {
/**
* For deb => KeyStorePathFile == yml or commandline: KEY_STORE_PATH_FILE
* For idea => KeyStorePathResource == common/transport/lwm2m/src/main/resources/credentials: in LwM2MTransportContextServer: credentials/serverKeyStore.jks
*/
try {
X509Certificate serverCertificate = (X509Certificate) this.context.getCtxServer().getKeyStoreValue().getCertificate(this.context.getCtxServer().getServerAlias());
PrivateKey privateKey = (PrivateKey) this.context.getCtxServer().getKeyStoreValue().getKey(this.context.getCtxServer().getServerAlias(), this.context.getCtxServer().getKeyStorePasswordServer() == null ? null : this.context.getCtxServer().getKeyStorePasswordServer().toCharArray());
this.builder.setPrivateKey(privateKey);
this.builder.setCertificateChain(new X509Certificate[]{serverCertificate});
} catch (Exception ex) {
log.error("[{}] Unable to load KeyStore files server", ex.getMessage());
}
}
private void getParamsPSK() {
log.info("\nServer uses PSK -> private key : \n security key : [{}] \n serverSecureURI : [{}]",
Hex.encodeHexString(this.privateKey.getEncoded()),
this.context.getCtxServer().getServerSecureHost() + ":" + Integer.toString(this.context.getCtxServer().getServerSecurePort()));
}
private void getParamsRPK() {
if (this.publicKey instanceof ECPublicKey) {
/** Get x coordinate */
byte[] x = ((ECPublicKey) this.publicKey).getW().getAffineX().toByteArray();
if (x[0] == 0)
x = Arrays.copyOfRange(x, 1, x.length);
/** Get Y coordinate */
byte[] y = ((ECPublicKey) this.publicKey).getW().getAffineY().toByteArray();
if (y[0] == 0)
y = Arrays.copyOfRange(y, 1, y.length);
/** Get Curves params */
String params = ((ECPublicKey) this.publicKey).getParams().toString();
log.info(
" \nServer uses RPK : \n Elliptic Curve parameters : [{}] \n Public x coord : [{}] \n Public y coord : [{}] \n Public Key (Hex): [{}] \n Private Key (Hex): [{}]",
params, Hex.encodeHexString(x), Hex.encodeHexString(y),
Hex.encodeHexString(this.publicKey.getEncoded()),
Hex.encodeHexString(this.privateKey.getEncoded()));
} else {
throw new IllegalStateException("Unsupported Public Key Format (only ECPublicKey supported).");
}
}
}

212
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/secure/LwM2mInMemorySecurityStore.java

@ -1,212 +0,0 @@
/**
* Copyright © 2016-2020 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.transport.lwm2m.server.secure;
import com.google.gson.JsonObject;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.leshan.server.californium.LeshanServer;
import org.eclipse.leshan.server.registration.Registration;
import org.eclipse.leshan.server.security.InMemorySecurityStore;
import org.eclipse.leshan.server.security.SecurityInfo;
import org.eclipse.leshan.server.security.SecurityStoreListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.stereotype.Component;
import org.thingsboard.server.common.data.DeviceProfile;
import org.thingsboard.server.transport.lwm2m.secure.LwM2MGetSecurityInfo;
import org.thingsboard.server.transport.lwm2m.secure.ReadResultSecurityStore;
import org.thingsboard.server.transport.lwm2m.server.LwM2MTransportHandler;
import org.thingsboard.server.transport.lwm2m.server.client.AttrTelemetryObserveValue;
import org.thingsboard.server.transport.lwm2m.server.client.LwM2MClient;
import org.thingsboard.server.transport.lwm2m.utils.TypeServer;
import java.util.Map;
import java.util.UUID;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.stream.Collectors;
import static org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode.*;
@Slf4j
@Component("LwM2mInMemorySecurityStore")
@ConditionalOnExpression("('${service.type:null}'=='tb-transport' && '${transport.lwm2m.enabled:false}'=='true' )|| ('${service.type:null}'=='monolith' && '${transport.lwm2m.enabled}'=='true')")
public class LwM2mInMemorySecurityStore extends InMemorySecurityStore {
// lock for the two maps
protected final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
protected final Lock readLock = readWriteLock.readLock();
protected final Lock writeLock = readWriteLock.writeLock();
private final boolean infosAreCompromised = false;
protected Map<String /** registrationId */, LwM2MClient> sessions = new ConcurrentHashMap<>();
protected Map<UUID /** profileUUid */, AttrTelemetryObserveValue> profiles = new ConcurrentHashMap<>();
private SecurityStoreListener listener;
@Autowired
LwM2MGetSecurityInfo lwM2MGetSecurityInfo;
@Override
public SecurityInfo getByEndpoint(String endPoint) {
readLock.lock();
try {
String registrationId = this.getByRegistrationId(endPoint, null);
return (registrationId != null && sessions.size() > 0 && sessions.get(registrationId) != null) ? sessions.get(registrationId).getInfo() : this.add(endPoint);
} finally {
readLock.unlock();
}
}
@Override
public SecurityInfo getByIdentity(String identity) {
readLock.lock();
try {
String integrationId = this.getByRegistrationId(null, identity);
return (integrationId != null) ? sessions.get(integrationId).getInfo() : add(identity);
} finally {
readLock.unlock();
}
}
@Override
public Collection<SecurityInfo> getAll() {
readLock.lock();
try {
return Collections.unmodifiableCollection(this.sessions.entrySet().stream().map(model -> model.getValue().getInfo()).collect(Collectors.toList()));
} finally {
readLock.unlock();
}
}
/**
* Removed registration Client from sessions and listener
* @param registrationId if Client
*/
public void delRemoveSessionAndListener(String registrationId) {
writeLock.lock();
try {
LwM2MClient lwM2MClient = (sessions.get(registrationId) != null) ? sessions.get(registrationId) : null;
if (lwM2MClient != null) {
if (listener != null) {
listener.securityInfoRemoved(infosAreCompromised, lwM2MClient.getInfo());
}
sessions.remove(registrationId);
}
} finally {
writeLock.unlock();
}
}
@Override
public void setListener(SecurityStoreListener listener) {
this.listener = listener;
}
public LwM2MClient getlwM2MClient(String endPoint, String identity) {
Map.Entry<String, LwM2MClient> modelClients = (endPoint != null) ?
this.sessions.entrySet().stream().filter(model -> endPoint.equals(model.getValue().getEndPoint())).findAny().orElse(null) :
this.sessions.entrySet().stream().filter(model -> identity.equals(model.getValue().getIdentity())).findAny().orElse(null);
return (modelClients != null) ? modelClients.getValue() : null;
}
public LwM2MClient getlwM2MClient(String registrationId) {
return this.sessions.get(registrationId);
}
public LwM2MClient getlwM2MClient(LeshanServer lwServer, Registration registration) {
writeLock.lock();
try {
if (this.sessions.get(registration.getEndpoint()) == null) {
this.add(registration.getEndpoint());
}
LwM2MClient lwM2MClient = this.sessions.get(registration.getEndpoint());
lwM2MClient.setLwServer(lwServer);
lwM2MClient.setRegistration(registration);
lwM2MClient.setAttributes(registration.getAdditionalRegistrationAttributes());
this.sessions.put(registration.getId(), lwM2MClient);
this.sessions.remove(registration.getEndpoint());
return lwM2MClient;
} finally {
writeLock.unlock();
}
}
private String getByRegistrationId(String endPoint, String identity) {
List<String> registrationIds = (endPoint != null) ?
this.sessions.entrySet().stream().filter(model -> endPoint.equals(model.getValue().getEndPoint())).map(model -> model.getKey()).collect(Collectors.toList()) :
this.sessions.entrySet().stream().filter(model -> identity.equals(model.getValue().getIdentity())).map(model -> model.getKey()).collect(Collectors.toList());
return (registrationIds != null && registrationIds.size() > 0) ? registrationIds.get(0) : null;
}
public String getByRegistrationId(String credentialsId) {
List<String> registrationIds = (this.sessions.entrySet().stream().filter(model -> credentialsId.equals(model.getValue().getEndPoint())).map(model -> model.getKey()).collect(Collectors.toList()).size() > 0) ?
this.sessions.entrySet().stream().filter(model -> credentialsId.equals(model.getValue().getEndPoint())).map(model -> model.getKey()).collect(Collectors.toList()) :
this.sessions.entrySet().stream().filter(model -> credentialsId.equals(model.getValue().getIdentity())).map(model -> model.getKey()).collect(Collectors.toList());
return (registrationIds != null && registrationIds.size() > 0) ? registrationIds.get(0) : null;
}
public Registration getByRegistration(String registrationId) {
return this.sessions.get(registrationId).getRegistration();
}
private SecurityInfo add(String identity) {
ReadResultSecurityStore store = lwM2MGetSecurityInfo.getSecurityInfo(identity, TypeServer.CLIENT);
UUID profileUuid = (addUpdateProfileParameters(store.getDeviceProfile())) ? store.getDeviceProfile().getUuidId() : null;
if (store.getSecurityInfo() != null) {
if (store.getSecurityMode() < DEFAULT_MODE.code) {
String endpoint = store.getSecurityInfo().getEndpoint();
sessions.put(endpoint, new LwM2MClient(endpoint, store.getSecurityInfo().getIdentity(), store.getSecurityInfo(), store.getMsg(), null, null, profileUuid));
}
} else {
if (store.getSecurityMode() == NO_SEC.code)
sessions.put(identity, new LwM2MClient(identity, null, null, store.getMsg(), null, null, profileUuid));
else log.error("Registration failed: FORBIDDEN, endpointId: [{}]", identity);
}
return store.getSecurityInfo();
}
public Map<String, LwM2MClient> getSession (UUID sessionUuId){
return this.sessions.entrySet().stream().filter(e -> e.getValue().getSessionUuid().equals(sessionUuId)).collect(Collectors.toMap(map -> map.getKey(), map -> map.getValue()));
}
public Map<String, LwM2MClient> getSessions() {
return this.sessions;
}
public Map<UUID, AttrTelemetryObserveValue> getProfiles() {
return this.profiles;
}
public Map<UUID, AttrTelemetryObserveValue>setProfiles(Map<UUID, AttrTelemetryObserveValue> profiles) {
return this.profiles = profiles;
}
/**
*
* @param deviceProfile
*/
public boolean addUpdateProfileParameters(DeviceProfile deviceProfile) {
JsonObject profilesConfigData = LwM2MTransportHandler.getObserveAttrTelemetryFromThingsboard(deviceProfile);
if (profilesConfigData != null) {
profiles.put(deviceProfile.getUuidId(), LwM2MTransportHandler.getNewProfileParameters(profilesConfigData));
}
return (profilesConfigData != null);
}
}

146
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/utils/LwM2mValueConverterImpl.java

@ -1,146 +0,0 @@
/**
* Copyright © 2016-2020 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.transport.lwm2m.utils;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.leshan.core.model.ResourceModel.Type;
import org.eclipse.leshan.core.node.LwM2mPath;
import org.eclipse.leshan.core.node.codec.CodecException;
import org.eclipse.leshan.core.node.codec.LwM2mValueConverter;
import org.eclipse.leshan.core.util.Hex;
import org.eclipse.leshan.core.util.StringUtils;
import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;
import java.util.Date;
@Slf4j
public class LwM2mValueConverterImpl implements LwM2mValueConverter {
@Override
public Object convertValue(Object value, Type currentType, Type expectedType, LwM2mPath resourcePath)
throws CodecException {
if (expectedType == null) {
/** unknown resource, trusted value */
return value;
}
if (currentType == expectedType) {
/** expected type */
return value;
}
switch (expectedType) {
case INTEGER:
switch (currentType) {
case FLOAT:
log.debug("Trying to convert float value [{}] to integer", value);
Long longValue = ((Double) value).longValue();
if ((double) value == longValue.doubleValue()) {
return longValue;
}
default:
break;
}
break;
case FLOAT:
switch (currentType) {
case INTEGER:
log.debug("Trying to convert integer value [{}] to float", value);
Double floatValue = ((Long) value).doubleValue();
if ((long) value == floatValue.longValue()) {
return floatValue;
}
default:
break;
}
break;
case BOOLEAN:
switch (currentType) {
case STRING:
log.debug("Trying to convert string value {} to boolean", value);
if (StringUtils.equalsIgnoreCase((String) value, "true")) {
return true;
} else if (StringUtils.equalsIgnoreCase((String) value, "false")) {
return false;
}
break;
case INTEGER:
log.debug("Trying to convert int value {} to boolean", value);
Long val = (Long) value;
if (val == 1) {
return true;
} else if (val == 0) {
return false;
}
break;
default:
break;
}
break;
case TIME:
switch (currentType) {
case INTEGER:
log.debug("Trying to convert long value {} to date", value);
/** let's assume we received the millisecond since 1970/1/1 */
return new Date((Long) value);
case STRING:
log.debug("Trying to convert string value {} to date", value);
/** let's assume we received an ISO 8601 format date */
try {
DatatypeFactory datatypeFactory = DatatypeFactory.newInstance();
XMLGregorianCalendar cal = datatypeFactory.newXMLGregorianCalendar((String) value);
return cal.toGregorianCalendar().getTime();
} catch (DatatypeConfigurationException | 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,
resourcePath);
}
default:
break;
}
break;
case STRING:
switch (currentType) {
case BOOLEAN:
case INTEGER:
case FLOAT:
return String.valueOf(value);
default:
break;
}
break;
case OPAQUE:
if (currentType == Type.STRING) {
/** let's assume we received an hexadecimal string */
log.debug("Trying to convert hexadecimal string [{}] to byte array", value);
// TODO check if we shouldn't instead assume that the string contains Base64 encoded data
try {
return Hex.decodeHex(((String) value).toCharArray());
} catch (IllegalArgumentException e) {
throw new CodecException("Unable to convert hexastring [%s] to byte array for resource %s", value,
resourcePath);
}
}
break;
default:
}
throw new CodecException("Invalid value type for resource %s, expected %s, got %s", resourcePath, expectedType,
currentType);
}
}

29
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/utils/TypeServer.java

@ -1,29 +0,0 @@
/**
* Copyright © 2016-2020 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.transport.lwm2m.utils;
public enum TypeServer {
BOOTSTRAP(0, "bootstrap"),
CLIENT(1, "client");
public int code;
public String type;
TypeServer(int code, String type) {
this.code = code;
this.type = type;
}
}

BIN
common/transport/lwm2m/src/main/resources/credentials/serverKeyStore.jks

Binary file not shown.

208
common/transport/lwm2m/src/main/resources/credentials/shell/lwM2M_credentials.sh

@ -1,208 +0,0 @@
#!/bin/sh
#
# Copyright © 2016-2020 The Thingsboard Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# source the properties:
. ./lwM2M_keygen.properties
# Generation of the keystore.
echo "${H0}====START========${RESET}"
echo "${H1}Server Keystore : ${RESET}"
echo "${H1}==================${RESET}"
echo "${H2}Creating the trusted root CA key and certificate...${RESET}"
# -keysize
# 1024 (when using -genkeypair)
keytool \
-genkeypair \
-alias $ROOT_KEY_ALIAS \
-keyalg EC \
-dname "CN=$ROOT_CN, OU=$ORGANIZATIONAL_UNIT, O=$ORGANIZATION, L=$CITY, ST=$STATE_OR_PROVINCE, C=$TWO_LETTER_COUNTRY_CODE" \
-validity $VALIDITY \
-storetype $STORETYPE \
-keypass $SERVER_STORE_PWD \
-keystore $SERVER_STORE \
-storepass $SERVER_STORE_PWD
echo
echo "${H2}Creating server key and self-signed certificate ...${RESET}"
keytool \
-genkeypair \
-alias $SERVER_ALIAS \
-keyalg EC \
-dname "CN=$SERVER_SELF_CN, OU=$ORGANIZATIONAL_UNIT, O=$ORGANIZATION, L=$CITY, ST=$STATE_OR_PROVINCE, C=$TWO_LETTER_COUNTRY_CODE" \
-validity $VALIDITY \
-storetype $STORETYPE \
-keypass $SERVER_STORE_PWD \
-keystore $SERVER_STORE \
-storepass $SERVER_STORE_PWD
keytool \
-exportcert \
-alias $SERVER_ALIAS \
-keystore $SERVER_STORE \
-storepass $SERVER_STORE_PWD | \
keytool \
-importcert \
-alias $SERVER_SELF_ALIAS \
-keystore $SERVER_STORE \
-storepass $SERVER_STORE_PWD \
-noprompt
echo
echo "${H2}Creating server certificate signed by root CA...${RESET}"
keytool \
-certreq \
-alias $SERVER_ALIAS \
-dname "CN=$SERVER_CN, OU=$ORGANIZATIONAL_UNIT, O=$ORGANIZATION, L=$CITY, ST=$STATE_OR_PROVINCE, C=$TWO_LETTER_COUNTRY_CODE" \
-keystore $SERVER_STORE \
-storepass $SERVER_STORE_PWD | \
keytool \
-gencert \
-alias $ROOT_KEY_ALIAS \
-keystore $SERVER_STORE \
-storepass $SERVER_STORE_PWD \
-storetype $STORETYPE \
-validity $VALIDITY | \
keytool \
-importcert \
-alias $SERVER_ALIAS \
-keystore $SERVER_STORE \
-storepass $SERVER_STORE_PWD
echo
echo "${H2}Creating server key and self-signed certificate ...${RESET}"
keytool \
-genkeypair \
-alias $BOOTSTRAP_ALIAS \
-keyalg EC \
-dname "CN=$BOOTSTRAP_SELF_CN, OU=$ORGANIZATIONAL_UNIT, O=$ORGANIZATION, L=$CITY, ST=$STATE_OR_PROVINCE, C=$TWO_LETTER_COUNTRY_CODE" \
-validity $VALIDITY \
-storetype $STORETYPE \
-keypass $SERVER_STORE_PWD \
-keystore $SERVER_STORE \
-storepass $SERVER_STORE_PWD
keytool \
-exportcert \
-alias $BOOTSTRAP_ALIAS \
-keystore $SERVER_STORE \
-storepass $SERVER_STORE_PWD | \
keytool \
-importcert \
-alias $BOOTSTRAP_SELF_ALIAS \
-keystore $SERVER_STORE \
-storepass $SERVER_STORE_PWD \
-noprompt
echo
echo "${H2}Creating bootstrap certificate signed by root CA...${RESET}"
keytool \
-certreq \
-alias $BOOTSTRAP_ALIAS \
-dname "CN=$BOOTSTRAP_CN, OU=$ORGANIZATIONAL_UNIT, O=$ORGANIZATION, L=$CITY, ST=$STATE_OR_PROVINCE, C=$TWO_LETTER_COUNTRY_CODE" \
-keystore $SERVER_STORE \
-storepass $SERVER_STORE_PWD | \
keytool \
-gencert \
-alias $ROOT_KEY_ALIAS \
-keystore $SERVER_STORE \
-storepass $SERVER_STORE_PWD \
-storetype $STORETYPE \
-validity $VALIDITY | \
keytool \
-importcert \
-alias $BOOTSTRAP_ALIAS \
-keystore $SERVER_STORE \
-storepass $SERVER_STORE_PWD
echo
echo "${H1}Client Keystore : ${RESET}"
echo "${H1}==================${RESET}"
echo "${H2}Creating client key and self-signed certificate with expected CN...${RESET}"
keytool \
-genkeypair \
-alias $CLIENT_ALIAS \
-keyalg EC \
-dname "CN=$CLIENT_SELF_CN, OU=$ORGANIZATIONAL_UNIT, O=$ORGANIZATION, L=$CITY, ST=$STATE_OR_PROVINCE, C=$TWO_LETTER_COUNTRY_CODE" \
-validity $VALIDITY \
-storetype $STORETYPE \
-keypass $CLIENT_STORE_PWD \
-keystore $CLIENT_STORE \
-storepass $CLIENT_STORE_PWD
keytool \
-exportcert \
-alias $CLIENT_ALIAS \
-keystore $CLIENT_STORE \
-storepass $CLIENT_STORE_PWD | \
keytool \
-importcert \
-alias $CLIENT_SELF_ALIAS \
-keystore $CLIENT_STORE \
-storepass $CLIENT_STORE_PWD \
-noprompt
echo
echo "${H2}Import root certificate just to be able to import ned by root CA with expected CN...${RESET}"
keytool \
-exportcert \
-alias $ROOT_KEY_ALIAS \
-keystore $SERVER_STORE \
-storepass $SERVER_STORE_PWD | \
keytool \
-importcert \
-alias $ROOT_KEY_ALIAS \
-keystore $CLIENT_STORE \
-storepass $CLIENT_STORE_PWD \
-noprompt
echo
echo "${H2}Creating client certificate signed by root CA with expected CN...${RESET}"
keytool \
-certreq \
-alias $CLIENT_ALIAS \
-dname "CN=$CLIENT_CN, OU=$ORGANIZATIONAL_UNIT, O=$ORGANIZATION, L=$CITY, ST=$STATE_OR_PROVINCE, C=$TWO_LETTER_COUNTRY_CODE" \
-keystore $CLIENT_STORE \
-storepass $CLIENT_STORE_PWD | \
keytool \
-gencert \
-alias $ROOT_KEY_ALIAS \
-keystore $SERVER_STORE \
-storepass $SERVER_STORE_PWD \
-storetype $STORETYPE \
-validity $VALIDITY | \
keytool \
-importcert \
-alias $CLIENT_ALIAS \
-keystore $CLIENT_STORE \
-storepass $CLIENT_STORE_PWD \
-noprompt
echo
echo "${H0}!!! Warning ${H2}Migrate ${H1}${SERVER_STORE} ${H2}to ${H1}PKCS12 ${H2}which is an industry standard format..${RESET}"
keytool \
-importkeystore \
-srckeystore $SERVER_STORE \
-destkeystore $SERVER_STORE \
-deststoretype pkcs12 \
-srcstorepass $SERVER_STORE_PWD
echo
echo "${H0}!!! Warning ${H2}Migrate ${H1}${CLIENT_STORE} ${H2}to ${H1}PKCS12 ${H2}which is an industry standard format..${RESET}"
keytool \
-importkeystore \
-srckeystore $CLIENT_STORE \
-destkeystore $CLIENT_STORE \
-deststoretype pkcs12 \
-srcstorepass $CLIENT_STORE_PWD

58
common/transport/lwm2m/src/main/resources/credentials/shell/lwM2M_keygen.properties

@ -1,58 +0,0 @@
#
# Copyright © 2016-2017 The Thingsboard Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Keystore common parameters
ROOT_KEY_ALIAS=rootCA
DOMAIN_SUFFIX="$(hostname)"
ROOT_CN="$DOMAIN_SUFFIX rootCA"
ORGANIZATIONAL_UNIT=Thingsboard
ORGANIZATION=Thingsboard
CITY=SF
STATE_OR_PROVINCE=CA
TWO_LETTER_COUNTRY_CODE=US
VALIDITY=36500 #days
STORETYPE="JKS"
#Server
SERVER_STORE=serverKeyStore.jks
SERVER_STORE_PWD=server_ks_password
SERVER_ALIAS=server
SERVER_CN="$DOMAIN_SUFFIX server LwM2M signed by root CA"
SERVER_SELF_ALIAS=server_self_signed
SERVER_SELF_CN="$DOMAIN_SUFFIX server LwM2M self-signed"
BOOTSTRAP_ALIAS=bootstrap
BOOTSTRAP_CN="$DOMAIN_SUFFIX bootstrap server LwM2M signed by root CA"
BOOTSTRAP_SELF_ALIAS=bootstrap_self_signed
BOOTSTRAP_SELF_CN="$DOMAIN_SUFFIX bootstrap server LwM2M self-signed"
# Client
CLIENT_STORE=clientKeyStore.jks
CLIENT_STORE_PWD=client_ks_password
CLIENT_ALIAS=client
#CLIENT_CN=client_lwm2m_x509
CLIENT_CN=mobile_lwm2m_x509
CLIENT_SELF_ALIAS=client_self_signed
CLIENT_SELF_CN="$DOMAIN_SUFFIX client LwM2M self-signed"
# Color output stuff
red=`tput setaf 1`
green=`tput setaf 2`
blue=`tput setaf 4`
bold=`tput bold`
H0=${red}${bold}
H1=${green}${bold}
H2=${blue}
RESET=`tput sgr0`

81
common/transport/lwm2m/src/main/resources/models/10241.xml

@ -1,81 +0,0 @@
<!-- BSD-3 Clause License
Copyright 2019 ATT.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
-->
<LWM2M xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://openmobilealliance.org/tech/profiles/LWM2M.xsd">
<Object ObjectType="MODefinition">
<Name>HostDeviceInfo</Name>
<Description1><![CDATA[This LWM2M Object provides a range of host device related information which can be queried by the LWM2M Server. The host device is any integrated device with an embedded cellular radio module.]]></Description1>
<ObjectID>10241</ObjectID>
<ObjectURN>urn:oma:lwm2m:x:10241</ObjectURN>
<LWM2MVersion />
<ObjectVersion />
<MultipleInstances>Multiple</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Resources>
<Item ID="5905"><Name>Host Device Manufacturer</Name>
<Operations>R</Operations>
<MultipleInstances>Multiple</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>String</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Human readable host device manufacturer name]]></Description>
</Item>
<Item ID="5906"><Name>Host Device Model Number</Name>
<Operations>R</Operations>
<MultipleInstances>Multiple</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>String</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[A host device model identifier (manufacturer specified string)]]></Description>
</Item>
<Item ID="5907"><Name>Host Device Unique ID</Name>
<Operations>R</Operations>
<MultipleInstances>Multiple</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>String</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[The host device unique ID as assigned by an OEM, MNO, or other as the Device ID in the onboarding or manufacturing process.]]></Description>
</Item>
<Item ID="5908"><Name>Host Device Software Version</Name>
<Operations>R</Operations>
<MultipleInstances>Multiple</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>String</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Current software version of the host device. (manufacturer specified string).]]></Description>
</Item></Resources>
<Description2 />
</Object>
</LWM2M>

659
common/transport/lwm2m/src/main/resources/models/10242.xml

@ -1,659 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- BSD-3 Clause License
Copyright 2019 Odins.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
-->
<LWM2M xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://openmobilealliance.org/tech/profiles/LWM2M.xsd" >
<Object ObjectType="MODefinition">
<Name>3-Phase Power Meter</Name>
<Description1>
<![CDATA[This Object provides the information to represent a generic 3-Phase Power Meter.]]>
</Description1>
<ObjectID>10242</ObjectID>
<ObjectURN>urn:oma:lwm2m:x:10242</ObjectURN>
<LWM2MVersion>1.0</LWM2MVersion>
<ObjectVersion>1.0</ObjectVersion>
<MultipleInstances>Multiple</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Resources>
<Item ID="0">
<Name>Manufacturer</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>String</Type>
<RangeEnumeration/>
<Units/>
<Description>
<![CDATA[Human readable manufacturer name]]>
</Description>
</Item>
<Item ID="1">
<Name>Model Number</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>String</Type>
<RangeEnumeration/>
<Units/>
<Description>
<![CDATA[A model identifier (manufacturer specified string)]]>
</Description>
</Item>
<Item ID="2">
<Name>Serial Number</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>String</Type>
<RangeEnumeration/>
<Units/>
<Description>
<![CDATA[Serial number of the meter]]>
</Description>
</Item>
<Item ID="3">
<Name>Description</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>String</Type>
<RangeEnumeration/>
<Units/>
<Description>
<![CDATA[Description of the meter]]>
</Description>
</Item>
<Item ID="4">
<Name>Tension R</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Float</Type>
<RangeEnumeration/>
<Units>V</Units>
<Description>
<![CDATA[Voltage phase 1 (phase to neutral)]]>
</Description>
</Item>
<Item ID="5">
<Name>Current R</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Float</Type>
<RangeEnumeration/>
<Units>A</Units>
<Description>
<![CDATA[Current phase 1]]>
</Description>
</Item>
<Item ID="6">
<Name>Active Power R</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration/>
<Units>kW</Units>
<Description>
<![CDATA[Active Power phase 1]]>
</Description>
</Item>
<Item ID="7">
<Name>Reactive Power R</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration/>
<Units>kvar</Units>
<Description>
<![CDATA[Reactive Power phase 1]]>
</Description>
</Item>
<Item ID="8">
<Name>Inductive Reactive Power R</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration/>
<Units>kvar</Units>
<Description>
<![CDATA[Inductive Reactive Power phase 1]]>
</Description>
</Item>
<Item ID="9">
<Name>Capacitive Reactive Power R</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration/>
<Units>kvar</Units>
<Description>
<![CDATA[Capacitive Reactive Power phase 1]]>
</Description>
</Item>
<Item ID="10">
<Name>Apparent Power R</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration/>
<Units>kVA</Units>
<Description>
<![CDATA[Apparent Power phase 1]]>
</Description>
</Item>
<Item ID="11">
<Name>Power Factor R</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration>-1..1</RangeEnumeration>
<Units/>
<Description>
<![CDATA[Power Factor phase 1]]>
</Description>
</Item>
<Item ID="12">
<Name>THD-V R</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration/>
<Units>/100</Units>
<Description>
<![CDATA[Total Harmonic Distortion phase 1 (Tension)]]>
</Description>
</Item>
<Item ID="13">
<Name>THD-A R</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration/>
<Units>/100</Units>
<Description>
<![CDATA[Total Harmonig Distortion phase 1 (Current)]]>
</Description>
</Item>
<Item ID="14">
<Name>Tension S</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Float</Type>
<RangeEnumeration/>
<Units>V</Units>
<Description>
<![CDATA[Voltage phase 2 (phase to neutral)]]>
</Description>
</Item>
<Item ID="15">
<Name>Current S</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Float</Type>
<RangeEnumeration/>
<Units>A</Units>
<Description>
<![CDATA[Current phase 2]]>
</Description>
</Item>
<Item ID="16">
<Name>Active Power S</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration/>
<Units>kW</Units>
<Description>
<![CDATA[Active Power phase 2]]>
</Description>
</Item>
<Item ID="17">
<Name>Reactive Power S</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration/>
<Units>kvar</Units>
<Description>
<![CDATA[Reactive Power phase 2]]>
</Description>
</Item>
<Item ID="18">
<Name>Inductive Reactive Power S</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration/>
<Units>kvar</Units>
<Description>
<![CDATA[Inductive Reactive Power phase 2]]>
</Description>
</Item>
<Item ID="19">
<Name>Capacitive Reactive Power S</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration/>
<Units>kvar</Units>
<Description>
<![CDATA[Capacitive Reactive Power phase 2]]>
</Description>
</Item>
<Item ID="20">
<Name>Apparent Power S</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration/>
<Units>kVA</Units>
<Description>
<![CDATA[Apparent Power phase 2]]>
</Description>
</Item>
<Item ID="21">
<Name>Power Factor S</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration>-1..1</RangeEnumeration>
<Units/>
<Description>
<![CDATA[Power Factor phase 2]]>
</Description>
</Item>
<Item ID="22">
<Name>THD-V S</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration/>
<Units>/100</Units>
<Description>
<![CDATA[Total Harmonic Distortion phase 2 (Tension)]]>
</Description>
</Item>
<Item ID="23">
<Name>THD-A S</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration/>
<Units>/100</Units>
<Description>
<![CDATA[Total Harmonic Distortion phase 2 (Current)]]>
</Description>
</Item>
<Item ID="24">
<Name>Tension T</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Float</Type>
<RangeEnumeration/>
<Units>V</Units>
<Description>
<![CDATA[Voltage phase 3 (phase to neutral)]]>
</Description>
</Item>
<Item ID="25">
<Name>Current T</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Float</Type>
<RangeEnumeration/>
<Units>A</Units>
<Description>
<![CDATA[Current phase 3]]>
</Description>
</Item>
<Item ID="26">
<Name>Active Power T</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration/>
<Units>kW</Units>
<Description>
<![CDATA[Active Power phase 3]]>
</Description>
</Item>
<Item ID="27">
<Name>Reactive Power T</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration/>
<Units>kvar</Units>
<Description>
<![CDATA[Reactive Power phase 3]]>
</Description>
</Item>
<Item ID="28">
<Name>Inductive Reactive Power T</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration/>
<Units>kvar</Units>
<Description>
<![CDATA[Inductive Reactive Power phase 3]]>
</Description>
</Item>
<Item ID="29">
<Name>Capacitive Reactive Power T</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration/>
<Units>kvar</Units>
<Description>
<![CDATA[Capacitive Reactive Power phase 3]]>
</Description>
</Item>
<Item ID="30">
<Name>Apparent Power T</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration/>
<Units>kVA</Units>
<Description>
<![CDATA[Apparent Power phase 3]]>
</Description>
</Item>
<Item ID="31">
<Name>Power Factor T</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration>-1..1</RangeEnumeration>
<Units/>
<Description>
<![CDATA[Power Factor phase 3]]>
</Description>
</Item>
<Item ID="32">
<Name>THD-V T</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration/>
<Units>/100</Units>
<Description>
<![CDATA[Total Harmonic Distortion phase 3 (Tension)]]>
</Description>
</Item>
<Item ID="33">
<Name>THD-A T</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration/>
<Units>/100</Units>
<Description>
<![CDATA[Total Harmonic Distortion phase 3 (Current)]]>
</Description>
</Item>
<Item ID="34">
<Name>3-Phase Active Power</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration/>
<Units>kW</Units>
<Description>
<![CDATA[3-Phase Active Power]]>
</Description>
</Item>
<Item ID="35">
<Name>3-Phase Reactive Power</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration/>
<Units>kvar</Units>
<Description>
<![CDATA[3-Phase Reactive Power]]>
</Description>
</Item>
<Item ID="36">
<Name>3-Phase Inductive Reactive Power</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration/>
<Units>kvar</Units>
<Description>
<![CDATA[3-Phase Inductive Reactive Power]]>
</Description>
</Item>
<Item ID="37">
<Name>3-Phase Capacitive Reactive Power</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration/>
<Units>kvar</Units>
<Description>
<![CDATA[3-Phase Capacitive Reactive Power]]>
</Description>
</Item>
<Item ID="38">
<Name>3-Phase Apparent Power</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration/>
<Units>kVA</Units>
<Description>
<![CDATA[3-Phase Apparent Power]]>
</Description>
</Item>
<Item ID="39">
<Name>3-Phase Power Factor</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration>-1..1</RangeEnumeration>
<Units/>
<Description>
<![CDATA[3-Phase Power Factor]]>
</Description>
</Item>
<Item ID="40">
<Name>3-Phase phi cosine</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration>-1..1</RangeEnumeration>
<Units/>
<Description>
<![CDATA[3-Phase phi cosine]]>
</Description>
</Item>
<Item ID="41">
<Name>Active Energy</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration/>
<Units>kWh</Units>
<Description>
<![CDATA[Active Energy]]>
</Description>
</Item>
<Item ID="42">
<Name>Reactive Energy</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration/>
<Units>kvarh</Units>
<Description>
<![CDATA[Reactive Energy]]>
</Description>
</Item>
<Item ID="43">
<Name>Inductive Reactive Energy</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration/>
<Units>kvarh</Units>
<Description>
<![CDATA[Inductive Reactive Energy]]>
</Description>
</Item>
<Item ID="44">
<Name>Capacitive Reactive Energy</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration/>
<Units>kvarh</Units>
<Description>
<![CDATA[Capacitive Reactive Energy]]>
</Description>
</Item>
<Item ID="45">
<Name>Apparent Energy</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration/>
<Units>kVAh</Units>
<Description>
<![CDATA[Apparent Energy]]>
</Description>
</Item>
<Item ID="46">
<Name>Tension R-S</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration/>
<Units>V</Units>
<Description>
<![CDATA[Voltage phase 1 to phase 2]]>
</Description>
</Item>
<Item ID="47">
<Name>Tension S-T</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration/>
<Units>V</Units>
<Description>
<![CDATA[Voltage phase 2 to phase 3]]>
</Description>
</Item>
<Item ID="48">
<Name>Tension T-R</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration/>
<Units>V</Units>
<Description>
<![CDATA[Voltage phase 3 to phase 1]]>
</Description>
</Item>
<Item ID="49">
<Name>Frequency</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration/>
<Units>Hz</Units>
<Description>
<![CDATA[Frequency]]>
</Description>
</Item>
<Item ID="50">
<Name>Neutral Current</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration/>
<Units>A</Units>
<Description>
<![CDATA[Neutral Current]]>
</Description>
</Item>
</Resources>
<Description2/>
</Object>
</LWM2M>

263
common/transport/lwm2m/src/main/resources/models/10243.xml

@ -1,263 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- BSD-3 Clause License
Copyright 2019 Odins.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
-->
<LWM2M xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://openmobilealliance.org/tech/profiles/LWM2M.xsd" >
<Object ObjectType="MODefinition">
<Name>Single-Phase Power Meter</Name>
<Description1>
<![CDATA[This Object provides the information to represent a generic Single-Phase Power Meter.]]>
</Description1>
<ObjectID>10243</ObjectID>
<ObjectURN>urn:oma:lwm2m:x:10243</ObjectURN>
<LWM2MVersion>1.0</LWM2MVersion>
<ObjectVersion>1.0</ObjectVersion>
<MultipleInstances>Multiple</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Resources>
<Item ID="0">
<Name>Manufacturer</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>String</Type>
<RangeEnumeration/>
<Units/>
<Description>
<![CDATA[Human readable manufacturer name]]>
</Description>
</Item>
<Item ID="1">
<Name>Model Number</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>String</Type>
<RangeEnumeration/>
<Units/>
<Description>
<![CDATA[A model identifier (manufacturer specified string)]]>
</Description>
</Item>
<Item ID="2">
<Name>Serial Number</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>String</Type>
<RangeEnumeration/>
<Units/>
<Description>
<![CDATA[Serial number of the meter]]>
</Description>
</Item>
<Item ID="3">
<Name>Description</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>String</Type>
<RangeEnumeration/>
<Units/>
<Description>
<![CDATA[Description of the meter]]>
</Description>
</Item>
<Item ID="4">
<Name>Tension</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>String</Type>
<RangeEnumeration/>
<Units>V</Units>
<Description>
<![CDATA[Voltage]]>
</Description>
</Item>
<Item ID="5">
<Name>Current</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Float</Type>
<RangeEnumeration/>
<Units>A</Units>
<Description>
<![CDATA[Current]]>
</Description>
</Item>
<Item ID="6">
<Name>Active Power</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration/>
<Units>kW</Units>
<Description>
<![CDATA[Active Power]]>
</Description>
</Item>
<Item ID="7">
<Name>Reactive Power</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration/>
<Units>kvar</Units>
<Description>
<![CDATA[Reactive Power]]>
</Description>
</Item>
<Item ID="8">
<Name>Inductive Reactive Power</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration/>
<Units>kvar</Units>
<Description>
<![CDATA[Inductive Reactive Power]]>
</Description>
</Item>
<Item ID="9">
<Name>Capacitive Reactive Power</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration/>
<Units>kvar</Units>
<Description>
<![CDATA[Capacitive Reactive Power]]>
</Description>
</Item>
<Item ID="10">
<Name>Apparent Power</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration/>
<Units>kVA</Units>
<Description>
<![CDATA[Apparent Power]]>
</Description>
</Item>
<Item ID="11">
<Name>Power Factor</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration>-1..1</RangeEnumeration>
<Units/>
<Description>
<![CDATA[Power Factor]]>
</Description>
</Item>
<Item ID="12">
<Name>THD-V</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration/>
<Units>/100</Units>
<Description>
<![CDATA[Total Harmonic Distortion (Tension)]]>
</Description>
</Item>
<Item ID="13">
<Name>THD-A</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration/>
<Units>/100</Units>
<Description>
<![CDATA[Total Harmonic Distortion (Current)]]>
</Description>
</Item>
<Item ID="14">
<Name>Active Energy</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration/>
<Units>kWh</Units>
<Description>
<![CDATA[Active Energy]]>
</Description>
</Item>
<Item ID="15">
<Name>Reactive Energy</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration/>
<Units>kvarh</Units>
<Description>
<![CDATA[Reactive Energy]]>
</Description>
</Item>
<Item ID="16">
<Name>Apparent Energy</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration/>
<Units>kVAh</Units>
<Description>
<![CDATA[Apparent Energy]]>
</Description>
</Item>
<Item ID="17">
<Name>Frequency</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration/>
<Units>Hz</Units>
<Description>
<![CDATA[Frequency]]>
</Description>
</Item>
</Resources>
<Description2/>
</Object>
</LWM2M>

301
common/transport/lwm2m/src/main/resources/models/10244.xml

@ -1,301 +0,0 @@
<?xml version="1.0" encoding="utf-8"?><LWM2M xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://openmobilealliance.org/tech/profiles/LWM2M.xsd">
<Object ObjectType="MODefinition">
<Name>VehicleControlUnit</Name>
<Description1><![CDATA[This Object provides the information to represent a generic VCU(vehicle control unit).]]></Description1>
<ObjectID>10244</ObjectID>
<ObjectURN>urn:oma:lwm2m:x:10244</ObjectURN>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Resources>
<Item ID="0"><Name>Vehicle UI State</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Integer</Type>
<RangeEnumeration>0..15</RangeEnumeration>
<Units></Units>
<Description><![CDATA[The UI state of the vehicle. 0: idle 1: driving 2: charging 3: limp-home 4-15: reserved for future use]]></Description>
</Item>
<Item ID="1"><Name>Vehicle Speed</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Integer</Type>
<RangeEnumeration></RangeEnumeration>
<Units>km/h</Units>
<Description><![CDATA[Current speed of the vehicle.]]></Description>
</Item>
<Item ID="2"><Name>Vehicle Shift Status</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Integer</Type>
<RangeEnumeration>0..3</RangeEnumeration>
<Units></Units>
<Description><![CDATA[Current shift status of the vehicle. 0: Neutral 1: Forward 2: Reverse]]></Description>
</Item>
<Item ID="3"><Name>Vehicle AP Position</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Integer</Type>
<RangeEnumeration>0..100</RangeEnumeration>
<Units>/100</Units>
<Description><![CDATA[Current position of the accelerator pedal.]]></Description>
</Item>
<Item ID="4"><Name>Vehicle Power</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration></RangeEnumeration>
<Units>kW</Units>
<Description><![CDATA[Current power of drive output/regenerative braking.]]></Description>
</Item>
<Item ID="5"><Name>Vehicle Drive Energy</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration></RangeEnumeration>
<Units>Wh</Units>
<Description><![CDATA[Accumulated drive energy of the vehicle.]]></Description>
</Item>
<Item ID="6"><Name>Vehicle Energy Consumption Efficiency</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration></RangeEnumeration>
<Units>Wh/km</Units>
<Description><![CDATA[Energy consumption efficiency of the vehicle.]]></Description>
</Item>
<Item ID="7"><Name>Vehicle Estimated Mileage</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Integer</Type>
<RangeEnumeration></RangeEnumeration>
<Units>km</Units>
<Description><![CDATA[Estimated mileage of current battery capacity.]]></Description>
</Item>
<Item ID="8"><Name>Vehicle Charge Cable Status</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Boolean</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Whether the charge cable is connected or not. 0: unconnected 1: connected]]></Description>
</Item>
<Item ID="9"><Name>Vehicle Charge Status</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Integer</Type>
<RangeEnumeration>0..15</RangeEnumeration>
<Units></Units>
<Description><![CDATA[Charging status of the vehicle. 1: non-charge mode 2: charging 3: charge completed 4: charging abort abnormally ]]></Description>
</Item>
<Item ID="10"><Name>Vehicle Charge Voltage</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Float</Type>
<RangeEnumeration></RangeEnumeration>
<Units>V</Units>
<Description><![CDATA[Charging voltage]]></Description>
</Item>
<Item ID="11"><Name>Vehicle Charge Current</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Float</Type>
<RangeEnumeration></RangeEnumeration>
<Units>A</Units>
<Description><![CDATA[Charging current]]></Description>
</Item>
<Item ID="12"><Name>Vehicle Charge Remaining Time</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Integer</Type>
<RangeEnumeration></RangeEnumeration>
<Units>min</Units>
<Description><![CDATA[Remaining charging time]]></Description>
</Item>
<Item ID="13"><Name>Battery Pack Voltage</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Float</Type>
<RangeEnumeration></RangeEnumeration>
<Units>V</Units>
<Description><![CDATA[Voltage of the battery pack]]></Description>
</Item>
<Item ID="14"><Name>Battery Pack Current</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Float</Type>
<RangeEnumeration></RangeEnumeration>
<Units>A</Units>
<Description><![CDATA[Current of the battery pack]]></Description>
</Item>
<Item ID="15"><Name>Battery Pack Remaining Capacity</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Integer</Type>
<RangeEnumeration></RangeEnumeration>
<Units>Ah</Units>
<Description><![CDATA[Remaining capacity of the battery pack]]></Description>
</Item>
<Item ID="16"><Name>Battery Pack SOC</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Integer</Type>
<RangeEnumeration>0..100</RangeEnumeration>
<Units>/100</Units>
<Description><![CDATA[SOC(state of charge) of the battery pack]]></Description>
</Item>
<Item ID="17"><Name>Battery Pack SOH</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Integer</Type>
<RangeEnumeration>0..100</RangeEnumeration>
<Units>/100</Units>
<Description><![CDATA[SOH(state of health) of the battery pack]]></Description>
</Item>
<Item ID="18"><Name>Battery Cell MinVolt</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Integer</Type>
<RangeEnumeration></RangeEnumeration>
<Units>mV</Units>
<Description><![CDATA[Minimum voltage of the battery module (with parallel connection of cells)]]></Description>
</Item>
<Item ID="19"><Name>Battery Cell MaxVolt</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Integer</Type>
<RangeEnumeration></RangeEnumeration>
<Units>mV</Units>
<Description><![CDATA[Maximum voltage of the battery module (with parallel connection of cells)]]></Description>
</Item>
<Item ID="20"><Name>Battery Module MinTemp</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Integer</Type>
<RangeEnumeration></RangeEnumeration>
<Units>Cel</Units>
<Description><![CDATA[Minimum temperature of the battery module]]></Description>
</Item>
<Item ID="21"><Name>Battery Module MaxTemp</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Integer</Type>
<RangeEnumeration></RangeEnumeration>
<Units>Cel</Units>
<Description><![CDATA[Maximum temperature of the battery module]]></Description>
</Item>
<Item ID="22"><Name>Battery Connection Status</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Boolean</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Whether the battery is connected or not. 0: unconnected 1: connected]]></Description>
</Item>
<Item ID="24"><Name>MCU Voltage</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Integer</Type>
<RangeEnumeration></RangeEnumeration>
<Units>V</Units>
<Description><![CDATA[Voltage of the MCU(motor control unit)]]></Description>
</Item>
<Item ID="25"><Name>MCU Temperature</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Integer</Type>
<RangeEnumeration></RangeEnumeration>
<Units>Cel</Units>
<Description><![CDATA[Temperature of MCU(motor control unit)]]></Description>
</Item>
<Item ID="26"><Name>Motor Speed</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Integer</Type>
<RangeEnumeration></RangeEnumeration>
<Units>1/min</Units>
<Description><![CDATA[Rotational speed of the motor]]></Description>
</Item>
<Item ID="27"><Name>Motor Temperature</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Integer</Type>
<RangeEnumeration></RangeEnumeration>
<Units>Cel</Units>
<Description><![CDATA[Temperature of the motor]]></Description>
</Item>
<Item ID="28"><Name>Motor OT Warning</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Boolean</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Whether the motor is OT or not. 0: normal 1: OT warning]]></Description>
</Item>
<Item ID="29"><Name>MCU OT Warning</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Boolean</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Whether the MCU is OT or not. 0: normal 1: OT warning]]></Description>
</Item>
<Item ID="30"><Name>Battery Pack OT Warning</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Boolean</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Whether the battery pack is OT or not. 0: normal 1: OT warning]]></Description>
</Item>
<Item ID="31"><Name>MCU fault</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Boolean</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Status of MCU. 0: normal 1: level 1 minor fault 2: level 2 critical fault]]></Description>
</Item>
<Item ID="32"><Name>Motor Error</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Boolean</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Status of the battery pack. 0: normal 1: level D25 minor fault 2: level 2 critical fault]]></Description>
</Item></Resources>
<Description2><![CDATA[]]></Description2>
</Object>
</LWM2M>

217
common/transport/lwm2m/src/main/resources/models/10245.xml

@ -1,217 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- BSD-3 Clause License
Copyright 2019 Vodafone Group.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
-->
<LWM2M xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://openmobilealliance.org/tech/profiles/LWM2M.xsd">
<Object ObjectType="MODefinition">
<Name>Relay Management</Name>
<Description1>This LWM2M Object provides a range of eNB related measurements and parameters of which several are changeable. Furthermore, it includes Resources to enable/disable the eNB.</Description1>
<ObjectID>10245</ObjectID>
<ObjectURN>urn:oma:lwm2m:x:10245</ObjectURN>
<LWM2MVersion/>
<ObjectVersion/>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Resources>
<Item ID="0">
<Name>eNB Availability</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Boolean</Type>
<RangeEnumeration>AVAILABLE; UNAVAILABLE</RangeEnumeration>
<Units></Units>
<Description>This field indicates to the CCC whether or not the eNB of the CrowdBox is available for activation: AVAILABLE = TRUE; UNAVAILABLE = FALSE This is set by the CrowdBox itself using an algorithm specific to the use case and based on parameters known to the CrowdBox which may not necessarily be signalled to the network. In the absence of a more specific algorithm, this parameter should be set to AVAILABLE, unless a fault is detected which would prevent activation of the eNB, in which case it should be set to UNAVAILABLE.</Description>
</Item>
<Item ID="1">
<Name>GPS Status</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Boolean</Type>
<RangeEnumeration>UNSYNCHRONISED; SYNCHRONISED</RangeEnumeration>
<Units></Units>
<Description>States whether the CrowdBox GPS receiver is synchronised to GPS time or not: UNSYCHRONISED = FALSE; SYNCHRONISED = TRUE If more than one GPS receiver is used by the CrowdBox, then SYNCHRONISED should be reported only if all receivers are synchronised.</Description>
</Item>
<Item ID="2">
<Name>Orientation</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Integer</Type>
<RangeEnumeration>-180..180</RangeEnumeration>
<Units>deg</Units>
<Description>Orientation of CrowdBox with respect to magnetic north. The reference orientation of the CrowdBox shall be the pointing direction of the eNB antenna(s) or, in the case of an omni-directional CrowdBox antenna, as defined in the accompanying product documentation.</Description>
</Item>
<Item ID="3">
<Name>eNB EARFCN</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Integer</Type>
<RangeEnumeration>0..65535</RangeEnumeration>
<Units></Units>
<Description>EARFCN currently used by the eNB. Highest valid value in 3GPP is currently 46589. If the requested EARFCN is not supported by the eNB, the response should be "Bad Request". The CrowdBox shall only apply a change of this resource upon execution of the “Enable eNB” command.</Description>
</Item>
<Item ID="4">
<Name>eNB Bandwidth</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Integer</Type>
<RangeEnumeration>5, 10, 15, 20</RangeEnumeration>
<Units></Units>
<Description>Bandwidth of the currently used eNB carrier. If the requested bandwidth is not supported by the eNB, the response should be "Bad Request". The CrowdBox shall only apply a change of this resource upon execution of the “Enable eNB” command.</Description>
</Item>
<Item ID="5">
<Name>Backhaul Primary EARFCN</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Integer</Type>
<RangeEnumeration>0..65535</RangeEnumeration>
<Units></Units>
<Description>EARFCN of primary cell used for the backhaul. If the requested EARFCN is not supported by the CrowdBox UE, the response should be "Bad Request". The CrowdBox shall only apply a change of this resource upon execution of the “Enable eNB” command.</Description>
</Item>
<Item ID="6">
<Name>Backhaul Secondary EARFCN</Name>
<Operations>RW</Operations>
<MultipleInstances>Multiple</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Integer</Type>
<RangeEnumeration>0..65535</RangeEnumeration>
<Units></Units>
<Description>EARFCN of any secondary cells used for the backhaul, in the event that carrier aggregation is being used. If the requested EARFCN is not supported by the CrowdBox UE, the response should be "Bad Request". The CrowdBox shall only apply a change of this resource upon execution of the “Enable eNB” command.</Description>
</Item>
<Item ID="7">
<Name>Cumulative Measurement Window</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Integer</Type>
<RangeEnumeration>0..65535</RangeEnumeration>
<Units>s</Units>
<Description>The current measurement interval over which cumulative statistics are collected for the following resources: Cumulative Number of Unique Users, Cumulative Downlink Throughput per Connected User, Cumulative Uplink Throughput per Connected User. Note that this measurement period is a sliding window rather than a granularity period. Measurements should never be reset, but rather old measurements should be removed from the cumulative total as they fall outside of the window. A value of 0 shall be interpreted as meaning only the current value should be reported. A value of 65535 shall be interpreted as an infinite window size (i.e. old measurements are never discarded).</Description>
</Item>
<Item ID="8">
<Name>eNB ECI</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Integer</Type>
<RangeEnumeration>0..2^28-1</RangeEnumeration>
<Units></Units>
<Description>A 28 bit E-UTRAN Cell Identifier (ECI)</Description>
</Item>
<Item ID="9">
<Name>eNB Status</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Boolean</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description>This resource indicates the current status of the eNB and can be used by the CCC to change the state from enabled to disabled. TRUE = eNB enabled FALSE = eNB disabled</Description>
</Item>
<Item ID="10">
<Name>Enable eNB</Name>
<Operations>E</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type></Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description>Enables the eNB. In addition the CrowdBox shall also update its configuration to reflect the current state of other relevant parameters. This might require a reboot.</Description>
</Item>
<Item ID="11">
<Name>eNB Maximum Power</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Integer</Type>
<RangeEnumeration>0..63</RangeEnumeration>
<Units>dBm</Units>
<Description>Maximum power for the eNB measured as the sum of input powers to all antenna connectors. The maximum power per antenna port is equal to the maximum eNB power divided by the number of antenna ports. If the requested power is above or below the maximum or minimum power levels of the eNB, then the power level should be set to the maximum or minimum respectively. The CrowdBox shall only apply a change of this resource upon execution of the “Enable eNB” command.</Description>
</Item>
<Item ID="12">
<Name>Backhaul Primary q-OffsetFreq</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Integer</Type>
<RangeEnumeration>-24..24</RangeEnumeration>
<Units>dB</Units>
<Description>q-OffsetFreq parameter for the backhaul primary EARFCN in SIB5 of the CrowdBox eNB BCCH. See TS 36.331 for details. Range: dB-24; dB-22 .. dB24 The CrowdBox shall only apply a change of this resource upon execution of the “Enable eNB” command.</Description>
</Item>
<Item ID="13">
<Name>Backhaul Secondary q-OffsetFreq</Name>
<Operations>RW</Operations>
<MultipleInstances>Multiple</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Integer</Type>
<RangeEnumeration>-24..24</RangeEnumeration>
<Units>dB</Units>
<Description>q-OffsetFreq parameter for the backhaul secondary EARFCN in SIB5 of the CrowdBox eNB BCCH. See TS 36.331 for details Range: dB-24; dB-22 .. dB24 The CrowdBox shall only apply a change of this resource upon execution of the “Enable eNB” command.</Description>
</Item>
<Item ID="14">
<Name>Neighbour CrowdBox EARFCN</Name>
<Operations>RW</Operations>
<MultipleInstances>Multiple</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Integer</Type>
<RangeEnumeration>0..66635</RangeEnumeration>
<Units></Units>
<Description>EARFCN of a neighbour CrowdBox. Each instance of this resource relates to the same instance of resource ID 15.</Description>
</Item>
<Item ID="15">
<Name>Neighbour CrowdBox q-OffsetFreq</Name>
<Operations>RW</Operations>
<MultipleInstances>Multiple</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Integer</Type>
<RangeEnumeration>-24..24</RangeEnumeration>
<Units>dB</Units>
<Description>q-OffsetFreq parameter of the Neighbour CrowdBox EARFCN in SIB5 of the Neighbour CrowdBox eNB BCCH. See TS 36.331 for details Range: dB-24; dB-22 .. dB24 Each instance of this resource relates to the same instance of resource ID 14. The CrowdBox shall only apply a change of this resource upon execution of the “Enable eNB” command.</Description>
</Item>
<Item ID="16">
<Name>Serving Macro eNB cellIndividualOffset</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Integer</Type>
<RangeEnumeration>-24..24</RangeEnumeration>
<Units>dB</Units>
<Description>Specifies the value of the cellIndividualOffset parameter applicable to the CrowdBox macro serving cell that is to be signalled to connected UEs in their measurement configuration information . See TS 36.331 for details. The CrowdBox shall only apply a change of this resource upon execution of the “Enable eNB” command.</Description>
</Item>
</Resources>
<Description2></Description2>
</Object>
</LWM2M>

108
common/transport/lwm2m/src/main/resources/models/10246.xml

@ -1,108 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- BSD-3 Clause License
Copyright 2019 Vodafone Group.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
-->
<LWM2M xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://openmobilealliance.org/tech/profiles/LWM2M.xsd">
<Object ObjectType="MODefinition">
<Name>CrowdBox Measurements</Name>
<Description1>This LWM2M Object provides CrowdBox-related measurements such as serving cell parameters, backhaul timing advance, and neighbour cell reports.</Description1>
<ObjectID>10246</ObjectID>
<ObjectURN>urn:oma:lwm2m:x:10246</ObjectURN>
<LWM2MVersion/>
<ObjectVersion/>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Resources>
<Item ID="0">
<Name>Serving Cell ID</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Integer</Type>
<RangeEnumeration>0..2^32-1</RangeEnumeration>
<Units></Units>
<Description>Serving cell ID as specified by the cellIdentity field broadcast in SIB1 of the serving cell (see TS 36.331).</Description>
</Item>
<Item ID="1">
<Name>Serving Cell RSRP</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Integer</Type>
<RangeEnumeration>0..97</RangeEnumeration>
<Units></Units>
<Description>Serving cell RSRP, as defined in TS 36.133, Section 9.1.4. Range: RSRP_00; RSRP_01 .. RSRP_97</Description>
</Item>
<Item ID="2">
<Name>Serving Cell RSRQ</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Integer</Type>
<RangeEnumeration>-30..46</RangeEnumeration>
<Units></Units>
<Description>Serving cell RSRQ, as defined in TS 36.133, Section 9.1.7. Range: RSRQ_-30; RSRQ_-29 .. RSRQ_46</Description>
</Item>
<Item ID="3">
<Name>Serving Cell SINR</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Integer</Type>
<RangeEnumeration>-10..30</RangeEnumeration>
<Units>dB</Units>
<Description>SINR of serving cell as estimated by the CrowdBox. Note that this is a proprietary measurement dependent on the UE chipset manufacturer. The UE chipset used should be stated in the accompanying product documentation.</Description>
</Item>
<Item ID="4">
<Name>Cumulative Backhaul Timing Advance</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Integer</Type>
<RangeEnumeration>0..65535</RangeEnumeration>
<Units></Units>
<Description>The cumulative timing advance signalled by the current serving cell to the CrowdBox. This is the sum of the initial timing advance signalled in the MAC payload of the Random Access Response (11 bits, 0 .. 1282) and subsequent adjustments signalled in the MAC PDU of DL-SCH transmissions (6 bits, -31 .. 32). See TS 36.321 for details.</Description>
</Item>
<Item ID="5">
<Name>Neighbour Cell Report</Name>
<Operations>R</Operations>
<MultipleInstances>Multiple</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Objlnk</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description>A link to the "Neighbour Cell Report" object for each neighbour cell of the CrowdBox.</Description>
</Item>
</Resources>
<Description2></Description2>
</Object>
</LWM2M>

98
common/transport/lwm2m/src/main/resources/models/10247.xml

@ -1,98 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- BSD-3 Clause License
Copyright 2019 Vodafone Group.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
-->
<LWM2M xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://openmobilealliance.org/tech/profiles/LWM2M.xsd">
<Object ObjectType="MODefinition">
<Name>Neighbour Cell Report</Name>
<Description1>This LWM2M Object provides the neighbour cell report. The CrowdBox Measurements Object and the Connected UE Report Object have both Objlnk Resources pointing to this Object.</Description1>
<ObjectID>10247</ObjectID>
<ObjectURN>urn:oma:lwm2m:x:10247</ObjectURN>
<LWM2MVersion/>
<ObjectVersion/>
<MultipleInstances>Multiple</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Resources>
<Item ID="0">
<Name>Neighbour PCI</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Integer</Type>
<RangeEnumeration>0..503</RangeEnumeration>
<Units></Units>
<Description>Physical Cell ID of neighbouring LTE cell, as defined in TS 36.211</Description>
</Item>
<Item ID="1">
<Name>Neighbour Cell ID</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Integer</Type>
<RangeEnumeration>0..2^32-1</RangeEnumeration>
<Units></Units>
<Description>Neighbour cell ID as specified by the cellIdentity field broadcast in SIB1 of the neighbour cell (see TS 36.331).</Description>
</Item>
<Item ID="2">
<Name>Neighbour Cell Rank</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Integer</Type>
<RangeEnumeration>0..255</RangeEnumeration>
<Units></Units>
<Description>Current neighbour cell rank. Neighbour cells should be ordered (ranked) by the CrowdBox according to neighbour cell RSRP, with a higher RSRP corresponding to a lower index. Hence the neighbouring cell with the highest RSRP should be neighbour cell 0, the second neighbour cell 1, and so on.</Description>
</Item>
<Item ID="3">
<Name>Neighbour Cell RSRP</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Integer</Type>
<RangeEnumeration>0..97</RangeEnumeration>
<Units></Units>
<Description>Neighbour cell RSRP, as defined in TS 36.133, Section 9.1.4. Range: RSRP_00; RSRP_01 .. RSRP_97</Description>
</Item>
<Item ID="4">
<Name>Neighbour Cell RSRQ</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Integer</Type>
<RangeEnumeration>-30..46</RangeEnumeration>
<Units></Units>
<Description>Neighbour cell RSRQ, as defined in TS 36.133, Section 9.1.7. Range: RSRQ_-30; RSRQ_-29 .. RSRQ_46</Description>
</Item>
</Resources>
<Description2></Description2>
</Object>
</LWM2M>

78
common/transport/lwm2m/src/main/resources/models/10248.xml

@ -1,78 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- BSD-3 Clause License
Copyright 2019 Vodafone Group.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
-->
<LWM2M xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://openmobilealliance.org/tech/profiles/LWM2M.xsd">
<Object ObjectType="MODefinition">
<Name>Connected UE Measurements</Name>
<Description1>This LWM2M Object provides a range of measurements of connected UEs and provides an Object link to the Connected UE report.</Description1>
<ObjectID>10248</ObjectID>
<ObjectURN>urn:oma:lwm2m:x:10248</ObjectURN>
<LWM2MVersion/>
<ObjectVersion/>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Resources>
<Item ID="0">
<Name>Number of Connected Users</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Integer</Type>
<RangeEnumeration>0..255</RangeEnumeration>
<Units></Units>
<Description>The number of different UEs currently connected to the eNB (i.e. in RRC_CONNECTED state).</Description>
</Item>
<Item ID="1">
<Name>Cumulative Number of Unique Users</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Integer</Type>
<RangeEnumeration>0..65535</RangeEnumeration>
<Units></Units>
<Description>The number of different UEs that have connected to the eNB over the immediately preceding period specified by the "Cumulative Measurement Window" field.</Description>
</Item>
<Item ID="2">
<Name>Connected UE Report</Name>
<Operations>R</Operations>
<MultipleInstances>Multiple</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Objlnk</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description>Provides an Object link to the Connected UE Report which provides a range of information related to the connected UEs.</Description>
</Item>
</Resources>
<Description2></Description2>
</Object>
</LWM2M>

138
common/transport/lwm2m/src/main/resources/models/10249.xml

@ -1,138 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- BSD-3 Clause License
Copyright 2019 Vodafone Group.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
-->
<LWM2M xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://openmobilealliance.org/tech/profiles/LWM2M.xsd">
<Object ObjectType="MODefinition">
<Name>Connected UE Report</Name>
<Description1>This LWM2M Object provides a range of information related to the connected UEs.</Description1>
<ObjectID>10249</ObjectID>
<ObjectURN>urn:oma:lwm2m:x:10249</ObjectURN>
<LWM2MVersion/>
<ObjectVersion/>
<MultipleInstances>Multiple</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Resources>
<Item ID="0">
<Name>Connected User MMEC</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Integer</Type>
<RangeEnumeration>0..255</RangeEnumeration>
<Units></Units>
<Description>MMEC signalled by the UE to the eNB in the RRCConnectionRequest message (see TS 36.331).</Description>
</Item>
<Item ID="1">
<Name>Connected User M-TMSI</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Integer</Type>
<RangeEnumeration>0..2^32-1</RangeEnumeration>
<Units></Units>
<Description>M-TMSI signalled by the UE to the eNB in the RRCConnectionRequest message (see TS 36.331).</Description>
</Item>
<Item ID="2">
<Name>Serving Cell (CrowdBox) eNB RSRP</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Integer</Type>
<RangeEnumeration>0..97</RangeEnumeration>
<Units></Units>
<Description>The RSRP of the CrowdBox eNB, as defined in TS 36.133, Section 9.1.4. Range: RSRP_00; RSRP_01 .. RSRP_97</Description>
</Item>
<Item ID="3">
<Name>Serving Cell (CrowdBox) eNB RSRQ</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Integer</Type>
<RangeEnumeration>-30..46</RangeEnumeration>
<Units></Units>
<Description>The RSRQ of the CrowdBox eNB, as defined in TS 36.133, Section 9.1.7. Range: RSRQ_-30; RSRQ_-29 .. RSRQ_46</Description>
</Item>
<Item ID="4">
<Name>Cumulative Timing Advance per Connected User</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Integer</Type>
<RangeEnumeration>0..65535</RangeEnumeration>
<Units></Units>
<Description>The cumulative timing advance signalled by the eNB to each currently connected UE. This is the sum of the initial timing advance signalled in the MAC payload of the Random Access Response (11 bits, 0 .. 1282) and subsequent adjustments signalled in the MAC PDU of DL-SCH transmissions (6 bits, -31 .. 32). See TS 36.321 for details.</Description>
</Item>
<Item ID="5">
<Name>Last downlink CQI report per Connected User</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Integer</Type>
<RangeEnumeration>0..255</RangeEnumeration>
<Units></Units>
<Description>The last downlink wideband CQI reported by a connected user the eNB. The CQI format is defined in Table 7.2.3-1 of TS 36.213.</Description>
</Item>
<Item ID="6">
<Name>Cumulative Downlink Throughput per Connected User</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Integer</Type>
<RangeEnumeration>0..2^32-1</RangeEnumeration>
<Units>B</Units>
<Description>The total number of MAC bytes sent to the connected user over the immediately preceding period specified by the "Cumulative Measurement Window" field.</Description>
</Item>
<Item ID="7">
<Name>Cumulative Uplink Throughput per Connected User</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Integer</Type>
<RangeEnumeration>0..2^32-1</RangeEnumeration>
<Units>B</Units>
<Description>The total number of MAC bytes received from the connected user over the immediately preceding period specified by the "Cumulative Measurement Window" field.</Description>
</Item>
<Item ID="8">
<Name>Neighbour Cell Report</Name>
<Operations>R</Operations>
<MultipleInstances>Multiple</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Objlnk</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description>A link to the "Neighbour Cell Report" object for each neighbour cell reported to the CrowdBox by the connected UE</Description>
</Item>
</Resources>
<Description2></Description2>
</Object>
</LWM2M>

70
common/transport/lwm2m/src/main/resources/models/10250.xml

@ -1,70 +0,0 @@
<?xml version="1.0" encoding="utf-8"?><!--BSD 3-Clause License
Copyright (c) 2018, Huawei
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-->
<LWM2M xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://openmobilealliance.org/tech/profiles/LWM2M.xsd">
<Object ObjectType="MODefinition">
<Name>App Data Container</Name>
<Description1><![CDATA[This LWM2M Object is used for reporting application data of a device.]]></Description1>
<ObjectID>10250</ObjectID>
<ObjectURN>urn:oma:lwm2m:x:10250</ObjectURN>
<LWM2MVersion>1.0</LWM2MVersion>
<ObjectVersion>1.0</ObjectVersion>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Resources>
<Item ID="0">
<Name>UL data</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Opaque</Type>
<RangeEnumeration>
</RangeEnumeration>
<Units>
</Units>
<Description><![CDATA[Uplink application data, e.g. gas meter reporting data.]]></Description>
</Item>
<Item ID="1">
<Name>DL data</Name>
<Operations>W</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Opaque</Type>
<RangeEnumeration>
</RangeEnumeration>
<Units>
</Units>
<Description><![CDATA[Downlink application data, e.g. application response message of uplink data.]]></Description>
</Item>
</Resources>
<Description2 />
</Object>
</LWM2M>

96
common/transport/lwm2m/src/main/resources/models/10251.xml

@ -1,96 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--BSD 3-Clause License
Copyright (c) 2017, Cisco
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -->
<LWM2M xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://openmobilealliance.org/tech/profiles/LWM2M.xsd">
<Object ObjectType="MODefinition">
<Name>AT Command</Name>
<Description1><![CDATA[Used to execute an AT command on a cellular modem]]></Description1>
<ObjectID>10251</ObjectID>
<ObjectURN>urn:oma:lwm2m:x:10251</ObjectURN>
<LWM2MVersion>1.0</LWM2MVersion>
<ObjectVersion>1.0</ObjectVersion>
<MultipleInstances>Multiple</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Resources>
<Item ID="0">
<Name>Command</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>String</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[The AT command to run. Example: AT+CREG? to query registration status]]></Description>
</Item>
<Item ID="1">
<Name>Response</Name>
<Operations>R</Operations>
<MultipleInstances>Multiple</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>String</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Response to the AT command. Example: +CREG:0,5 If multiple lines are returned as the modem response, each line will be returned in a separate resource.]]></Description>
</Item>
<Item ID="2">
<Name>Status</Name>
<Operations>R</Operations>
<MultipleInstances>Multiple</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>String</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Status of the command execution as returned by the modem. Typical values:OK ERROR]]></Description>
</Item>
<Item ID="3">
<Name>Timeout</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Integer</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Amount of time in seconds allowed for the modem to respond to the command.]]></Description>
</Item>
<Item ID="4">
<Name>Run</Name>
<Operations>E</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type></Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Executing this resource will cause the command to be sent to the modem. And the result to be populated using the Response (1) and Status (2) resources]]></Description>
</Item>
</Resources>
<Description2></Description2>
</Object>
</LWM2M>

229
common/transport/lwm2m/src/main/resources/models/10252.xml

@ -1,229 +0,0 @@
<!--
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
(a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives.
Copyright 2018 ARM.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<LWM2M xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://openmobilealliance.org/tech/profiles/LWM2M.xsd">
<Object ObjectType="MODefinition">
<Name>Manifest</Name>
<Description1><![CDATA[This object provides a range of information related to updating packages on a device]]></Description1>
<ObjectID>10252</ObjectID>
<ObjectURN>urn:oma:lwm2m:x:10252</ObjectURN>
<LWM2MVersion>1.0</LWM2MVersion>
<ObjectVersion>1.0</ObjectVersion>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Resources>
<Item ID="1">
<Name>Manifest</Name>
<Operations>W</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Opaque</Type>
<RangeEnumeration>
</RangeEnumeration>
<Units>
</Units>
<Description><![CDATA[Content of a new manifest]]></Description>
</Item>
<Item ID="2">
<Name>State</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Integer</Type>
<RangeEnumeration>0..8</RangeEnumeration>
<Units>
</Units>
<Description><![CDATA[Current state of manifest processing
0. Uninitialised
1. Idle
2. Processing manifest
3. Awaiting download approval
4. Downloading
5. Downloaded
6. Awaiting application approval
7. Updating
8. Rebooting
]]></Description>
</Item>
<Item ID="3">
<Name>Manifest Result</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Integer</Type>
<RangeEnumeration>0..19</RangeEnumeration>
<Units>
</Units>
<Description><![CDATA[Final result of the device processing a manifest.
0. Uninitialised
1. Success
2. Manifest timeout. The Manifest URI has timed-out.
3. Manifest not found. The Manifest URI not found.
4. Manifest failed integrity check. The manifest integrity check failed.
5. Manifest rejected. The Manifest attributes do not apply to this device.
6. Manifest certificate not found
7. Manifest signature failed. The Manifest signature is not recognised by this device.
8. Dependent manifest not found
9. Not enough storage for the new asset
10. Out of memory during download process
11. Connection lost during download process
12. Asset failed integrity check
13. Unsupported asset type
14. Invalid asset URI
15. Timed out downloading asset
16. Unsupported delta format
17. Unsupported encryption format
18. Asset update successfully completed
19. Asset updated successfully after recovery]]></Description>
</Item>
<Item ID="4">
<Name>Payload Result</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Opaque</Type>
<RangeEnumeration>
</RangeEnumeration>
<Units>
</Units>
<Description><![CDATA[Contains payload-specific errors or output.]]></Description>
</Item>
<Item ID="5">
<Name>Asset Hash</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Opaque</Type>
<RangeEnumeration>
</RangeEnumeration>
<Units>
</Units>
<Description><![CDATA[Hash of the installed asset.]]></Description>
</Item>
<Item ID="6">
<Name>Manifest version</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Integer</Type>
<RangeEnumeration>
</RangeEnumeration>
<Units>
</Units>
<Description><![CDATA[Version of the current manifest.]]></Description>
</Item>
<Item ID="7">
<Name>Asset Installation Progress</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Integer</Type>
<RangeEnumeration>
</RangeEnumeration>
<Units>
</Units>
<Description><![CDATA[Progress update of the asset installation process (in bytes).]]></Description>
</Item>
<Item ID="8">
<Name>Campaign Id</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>String</Type>
<RangeEnumeration>
</RangeEnumeration>
<Units>
</Units>
<Description><![CDATA[Id of campaign affecting this device. There currently isn’t any logic on the server or the client to handle this. ]]></Description>
</Item>
<Item ID="9">
<Name>Manual Trigger</Name>
<Operations>E</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type></Type>
<RangeEnumeration>
</RangeEnumeration>
<Units>
</Units>
<Description><![CDATA[Manually apply the asset update. This will only have effect if the manifest requires this. The state resource must also be in the downloaded state for the execute command to be actioned.]]></Description>
</Item>
</Resources>
<Description2><![CDATA[]]></Description2>
</Object>
</LWM2M>

72
common/transport/lwm2m/src/main/resources/models/10253.xml

@ -1,72 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- BSD-3 Clause License
Copyright 2019 Lab R&D Atos Pessac.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
-->
<LWM2M xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://openmobilealliance.org/tech/profiles/LWM2M.xsd">
<Object ObjectType="MODefinition">
<Name>Confidential Data</Name>
<Description1><![CDATA[This LWM2M Object is used for reporting data, but in a confidential way]]></Description1>
<ObjectID>10253</ObjectID>
<ObjectURN>urn:oma:lwm2m:x:10253</ObjectURN>
<LWM2MVersion>1.0</LWM2MVersion>
<ObjectVersion>1.0</ObjectVersion>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Resources>
<Item ID="0">
<Name>Public Key</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Opaque</Type>
<RangeEnumeration>
</RangeEnumeration>
<Units>
</Units>
<Description><![CDATA[Object public key provided from the server side]]></Description>
</Item>
<Item ID="1">
<Name>Application Data</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Opaque</Type>
<RangeEnumeration>
</RangeEnumeration>
<Units>
</Units>
<Description><![CDATA[Application Data encrypted by the Public Key]]></Description>
</Item>
</Resources>
<Description2 />
</Object>
</LWM2M>

119
common/transport/lwm2m/src/main/resources/models/10254.xml

@ -1,119 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2017 World-Direct eBusiness solutions GmbH
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE SOFTWARE.
-->
<LWM2M xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://openmobilealliance.org/tech/profiles/LWM2M.xsd">
<Object ObjectType="MODefinition">
<Name>Current Loop Input</Name>
<Description1><![CDATA[This LWM2M Object provides a representation of a current loop sensor, which indicates the value emitted by a current source.]]></Description1>
<ObjectID>10254</ObjectID>
<ObjectURN>urn:oma:lwm2m:x:10254:1.0</ObjectURN>
<LWM2MVersion>1.0</LWM2MVersion>
<ObjectVersion>1.0</ObjectVersion>
<MultipleInstances>Multiple</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Resources>
<Item ID="0">
<Name>Current Loop Input Current Value</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Float</Type>
<RangeEnumeration>0; 3.8-20.5</RangeEnumeration>
<Units>mA</Units>
<Description><![CDATA[The current value of the current loop input. A value of 0 indicates the not-connected state and/or invalid (i.e. out-of-range) values.]]></Description>
</Item>
<Item ID="5601">
<Name>Min Measured Value</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[The minimum value measured by the sensor since it is ON or Reset. Defined by “Units” resource.]]></Description>
</Item>
<Item ID="5602">
<Name>Max Measured Value</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[The maximum value measured by the sensor since it is ON or Reset. Defined by “Units” resource.]]></Description>
</Item>
<Item ID="5603">
<Name>Min Range Value</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[The minimum value that can be measured by the sensor. Defined by “Units” resource.]]></Description>
</Item>
<Item ID="5604">
<Name>Max Range Value</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[The maximum value that can be measured by the sensor. Defined by “Units” resource.]]></Description>
</Item>
<Item ID="5605">
<Name>Reset Min and Max Measured Values</Name>
<Operations>E</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type></Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Reset the Min and Max Measured Values to Current Value]]></Description>
</Item>
<Item ID="5701">
<Name>Sensor Units</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>String</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Measurement Units Definition.]]></Description>
</Item>
<Item ID="5750">
<Name>Application Type</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>String</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[The application type of the sensor or actuator as a string, for instance, “Air Pressure”.]]></Description>
</Item>
<Item ID="5821">
<Name>Current Calibration</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Read or Write the current calibration coefficient.]]></Description>
</Item>
</Resources>
<Description2><![CDATA[]]></Description2>
</Object>
</LWM2M>

165
common/transport/lwm2m/src/main/resources/models/10255.xml

@ -1,165 +0,0 @@
<!--
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
(a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives.
Copyright 2018 ARM.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<LWM2M xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://openmobilealliance.org/tech/profiles/LWM2M.xsd">
<Object ObjectType="MODefinition">
<Name>Device Metadata</Name>
<Description1><![CDATA[This object provides a range of information related to device metadata]]></Description1>
<ObjectID>10255</ObjectID>
<ObjectURN>urn:oma:lwm2m:x:10255</ObjectURN>
<LWM2MVersion>1.0</LWM2MVersion>
<ObjectVersion>1.0</ObjectVersion>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Resources>
<Item ID="0">
<Name>Protocol supported</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Integer</Type>
<RangeEnumeration>
</RangeEnumeration>
<Units>
</Units>
<Description><![CDATA[Manifest protocol supported]]></Description>
</Item>
<Item ID="1">
<Name>Bootloader hash</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Opaque</Type>
<RangeEnumeration>
</RangeEnumeration>
<Units>
</Units>
<Description><![CDATA[Hash of the bootloader. This is used for tracking the version of the bootloader used.]]></Description>
</Item>
<Item ID="2">
<Name>OEM bootloader hash</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Opaque</Type>
<RangeEnumeration>
</RangeEnumeration>
<Units>
</Units>
<Description><![CDATA[If the end-user has modified the bootloader the hash of the modified bootloader is recorded here]]></Description>
</Item>
<Item ID="3">
<Name>Vendor</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>String</Type>
<RangeEnumeration>
</RangeEnumeration>
<Units>
</Units>
<Description><![CDATA[Vendor Class UUID]]></Description>
</Item>
<Item ID="4">
<Name>Class</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>String</Type>
<RangeEnumeration>
</RangeEnumeration>
<Units>
</Units>
<Description><![CDATA[Class UUID]]></Description>
</Item>
<Item ID="5">
<Name>Device</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>String</Type>
<RangeEnumeration>
</RangeEnumeration>
<Units>
</Units>
<Description><![CDATA[Device UUID]]></Description>
</Item>
</Resources>
<Description2 />
</Object>
</LWM2M>

117
common/transport/lwm2m/src/main/resources/models/10256.xml

@ -1,117 +0,0 @@
<?xml version="1.0" encoding="utf-8"?><!--BSD 3-Clause License
Copyright (c) 2017, Huawei
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-->
<LWM2M xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://openmobilealliance.org/tech/profiles/LWM2M.xsd">
<Object ObjectType="MODefinition">
<Name>ECID-Signal Measurement Information</Name>
<Description1><![CDATA[This LWM2M Object provides ECID signal measurements of a device.]]></Description1>
<ObjectID>10256</ObjectID>
<ObjectURN>urn:oma:lwm2m:x:10256</ObjectURN>
<LWM2MVersion>1.0</LWM2MVersion>
<ObjectVersion>1.0</ObjectVersion>
<MultipleInstances>Multiple</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Resources>
<Item ID="0">
<Name>physCellId</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Integer</Type>
<RangeEnumeration>
</RangeEnumeration>
<Units>
</Units>
<Description><![CDATA[This field specifies the physical cell identity of the measured cell.]]></Description>
</Item>
<Item ID="1">
<Name>ECGI</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Integer</Type>
<RangeEnumeration>
</RangeEnumeration>
<Units>
</Units>
<Description><![CDATA[This field specifies cell global ID of the measured cell. The target device shall provide this field if it was able to determine the ECGI of the measured cell at the time of measurement.]]></Description>
</Item>
<Item ID="2">
<Name>arfcnEUTRA</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Integer</Type>
<RangeEnumeration>
</RangeEnumeration>
<Units>
</Units>
<Description><![CDATA[This field specifies the ARFCN of the measured E-UTRA carrier frequency.]]></Description>
</Item>
<Item ID="3">
<Name>rsrp-Result </Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Integer</Type>
<RangeEnumeration>
</RangeEnumeration>
<Units>
</Units>
<Description><![CDATA[This field specifies the reference signal received power (RSRP) measurement.]]></Description>
</Item>
<Item ID="4">
<Name>rsrq-Result</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Integer</Type>
<RangeEnumeration>
</RangeEnumeration>
<Units>
</Units>
<Description><![CDATA[This field specifies the reference signal received quality (RSRQ) measurement.]]></Description>
</Item>
<Item ID="5">
<Name>ue-RxTxTimeDiff</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Integer</Type>
<RangeEnumeration>
</RangeEnumeration>
<Units>
</Units>
<Description><![CDATA[This field specifies the UE Rx–Tx time difference measurement.]]></Description>
</Item>
</Resources>
<Description2><![CDATA[]]></Description2>
</Object>
</LWM2M>

275
common/transport/lwm2m/src/main/resources/models/10257.xml

@ -1,275 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?><!--Apache License 2.0
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
(a) You must give any other recipients of the Work or Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives.
Copyright 2017 Comsel System Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<LWM2M xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://openmobilealliance.org/tech/profiles/LWM2M.xsd">
<Object ObjectType="MODefinition">
<Name>Heat / Cooling meter</Name>
<Description1><![CDATA[
This Object provides the information to represent a generic (district) heat or cooling meter
]]></Description1>
<ObjectID>10257</ObjectID>
<ObjectURN>urn:oma:lwm2m:x:10257</ObjectURN>
<LWM2MVersion>1.0</LWM2MVersion>
<ObjectVersion>1.0</ObjectVersion>
<MultipleInstances>Multiple</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Resources>
<Item ID="0">
<Name>Manufacturer</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>String</Type>
<RangeEnumeration />
<Units />
<Description><![CDATA[Human readable manufacturer name]]></Description>
</Item>
<Item ID="1">
<Name>Model Number</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>String</Type>
<RangeEnumeration />
<Units />
<Description><![CDATA[A model identifier (manufacturer specified string)]]></Description>
</Item>
<Item ID="2">
<Name>Serial Number</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>String</Type>
<RangeEnumeration />
<Units />
<Description><![CDATA[Serial number of the meter]]></Description>
</Item>
<Item ID="3">
<Name>Description</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>String</Type>
<RangeEnumeration />
<Units />
<Description><![CDATA[Description of the meter]]></Description>
</Item>
<Item ID="11">
<Name>Error code</Name>
<Operations>R</Operations>
<MultipleInstances>Multiple</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Integer</Type>
<RangeEnumeration>
</RangeEnumeration>
<Units></Units>
<Description><![CDATA[Error code reported by the meter]]></Description>
</Item>
<Item ID="5800">
<Name>Instantaneous active power</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration></RangeEnumeration>
<Units>W</Units>
<Description><![CDATA[The current active power]]></Description>
</Item>
<Item ID="5802">
<Name>Max Measured active power</Name>
<Operations>R</Operations>
<MultipleInstances>Multiple</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Float</Type>
<RangeEnumeration></RangeEnumeration>
<Units>W</Units>
<Description><![CDATA[The maximum active power measured by the sensor since it is ON]]></Description>
</Item>
<Item ID="5805">
<Name>Cumulative active power</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration></RangeEnumeration>
<Units>Wh</Units>
<Description><![CDATA[The cumulative active power since the last cumulative energy reset or device start]]></Description>
</Item>
<Item ID="12">
<Name>Flow temperature</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration></RangeEnumeration>
<Units>Cel</Units>
<Description><![CDATA[Flow temperature]]></Description>
</Item>
<Item ID="13">
<Name>Max Measured flow temperature</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration></RangeEnumeration>
<Units>Cel</Units>
<Description><![CDATA[The maximum flow temperature measured by the meter]]></Description>
</Item>
<Item ID="14">
<Name>Return temperature</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration></RangeEnumeration>
<Units>Cel</Units>
<Description><![CDATA[Return temperature]]></Description>
</Item>
<Item ID="15">
<Name>Max Measured return temperature</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration></RangeEnumeration>
<Units>Cel</Units>
<Description><![CDATA[The maximum return temperature measured by the meter ]]></Description>
</Item>
<Item ID="16">
<Name>Temperature difference</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration></RangeEnumeration>
<Units>K</Units>
<Description><![CDATA[Temperature difference]]></Description>
</Item>
<Item ID="17">
<Name>Flow rate</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration></RangeEnumeration>
<Units>m3/s</Units>
<Description><![CDATA[The flow rate]]></Description>
</Item>
<Item ID="18">
<Name>Max Measured flow</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration></RangeEnumeration>
<Units>m3/s</Units>
<Description><![CDATA[The maximum flow measured by the meter ]]></Description>
</Item>
<Item ID="20">
<Name>Flow volume</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration></RangeEnumeration>
<Units>m3</Units>
<Description><![CDATA[The cumulative flow volume measured on the flow pipe]]></Description>
</Item>
<Item ID="21">
<Name>Return volume</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration></RangeEnumeration>
<Units>m3</Units>
<Description><![CDATA[The cumulative flow volume measured on the return pipe]]></Description>
</Item>
<Item ID="5506">
<Name>Current Time</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Time</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Unix Time. A signed integer representing the number of seconds since Jan 1st, 1970 in the UTC time zone.]]></Description>
</Item>
</Resources>
<Description2 />
</Object>
</LWM2M>

89
common/transport/lwm2m/src/main/resources/models/10258.xml

@ -1,89 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2017 World-Direct eBusiness solutions GmbH
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE SOFTWARE.
-->
<LWM2M xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://openmobilealliance.org/tech/profiles/LWM2M.xsd">
<Object ObjectType="MODefinition">
<Name>Current Loop Output</Name>
<Description1><![CDATA[This LWM2M Object provides a representation of a current loop source, which may be used to carry control signals.]]></Description1>
<ObjectID>10258</ObjectID>
<ObjectURN>urn:oma:lwm2m:x:10258</ObjectURN>
<LWM2MVersion>1.0</LWM2MVersion>
<ObjectVersion>1.0</ObjectVersion>
<MultipleInstances>Multiple</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Resources>
<Item ID="0">
<Name>Current Loop Output Current Value</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Float</Type>
<RangeEnumeration>3.8-20.5</RangeEnumeration>
<Units>mA</Units>
<Description><![CDATA[The current value of the current loop output.]]></Description>
</Item>
<Item ID="5603">
<Name>Min Range Value</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[The minimum value that can be measured by the sensor. Defined by “Units” resource.]]></Description>
</Item>
<Item ID="5604">
<Name>Max Range Value</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[The maximum value that can be measured by the sensor. Defined by “Units” resource.]]></Description>
</Item>
<Item ID="5701">
<Name>Sensor Units</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>String</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Measurement Units Definition.]]></Description>
</Item>
<Item ID="5750">
<Name>Application Type</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>String</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[The application type of the sensor or actuator as a string, for instance, “Air Pressure”.]]></Description>
</Item>
<Item ID="5821">
<Name>Current Calibration</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Read or Write the current calibration coefficient]]></Description>
</Item>
</Resources>
<Description2><![CDATA[]]></Description2>
</Object>
</LWM2M>

115
common/transport/lwm2m/src/main/resources/models/10259.xml

@ -1,115 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- BSD-3 Clause License
Copyright 2019 Casa Systems.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
-->
<LWM2M xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://openmobilealliance.org/tech/profiles/LWM2M.xsd">
<Object ObjectType="MODefinition">
<Name>System Log</Name>
<Description1><![CDATA[This object provides read access to log buffers as well as limited configuration of logging services.]]></Description1>
<ObjectID>10259</ObjectID>
<ObjectURN>urn:oma:lwm2m:x:10259</ObjectURN>
<LWM2MVersion>1.0</LWM2MVersion>
<ObjectVersion>1.0</ObjectVersion>
<MultipleInstances>Multiple</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Resources>
<Item ID="0">
<Name>Name</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>String</Type>
<RangeEnumeration>
</RangeEnumeration>
<Units>
</Units>
<Description><![CDATA[Short name describing the log source represented by this particular instance.
For syslog-compatible log sources this value should be "syslog". If multiple syslog-compatible log sources exist on a device then each should be given a distinct name that is then prefixed with "syslog-".]]></Description>
</Item>
<Item ID="1">
<Name>Read All</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>String</Type>
<RangeEnumeration>
</RangeEnumeration>
<Units>
</Units>
<Description><![CDATA[Read the entire current contents of the log buffer.
Result is delivered as a display-formatted UTF-8 string, with each message entry on a new line.]]></Description>
</Item>
<Item ID="2">
<Name>Read</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>String</Type>
<RangeEnumeration>
</RangeEnumeration>
<Units>
</Units>
<Description><![CDATA[Similar to Read All, but only reads log entries that have arrived since the last time this log buffer was read.
If the LwM2M client is connected to multiple servers then the last read position should be tracked separately for each server.
If this is the first attempt to read the log for a given connection then this resource behaves the same as Read All.]]></Description>
</Item>
<Item ID="3">
<Name>Enabled</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Boolean</Type>
<RangeEnumeration>
</RangeEnumeration>
<Units>
</Units>
<Description><![CDATA[Enable or disable log capture for this source.
If this resource is not provided by an implementation, then the existence of a System Log instance is taken as implicit confirmation that the log source it represents is currently enabled.]]></Description>
</Item>
<Item ID="4">
<Name>Capture Level</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Integer</Type>
<RangeEnumeration>
</RangeEnumeration>
<Units>
</Units>
<Description><![CDATA[For log sources that support message priorities, this resource configures the minimum priority to capture.
For syslog-compatible log sources the following enumeration must be used: 1 = Emergency, 2 = Alert, 3 = Critical, 4 = Error, 5 = Warning, 6 = Notice, 7 = Info, 8 = Debug.
For other log sources this is left up to the implementer, with the requirement that consecutive values are used, starting at 1 and sorted so that message verbosity increases as the number ascends.]]></Description>
</Item>
</Resources>
<Description2><![CDATA[]]></Description2>
</Object>
</LWM2M>

95
common/transport/lwm2m/src/main/resources/models/10260-2_0.xml

@ -1,95 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- BSD-3 Clause License
Copyright 2019 Casa Systems.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
-->
<LWM2M xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://openmobilealliance.org/tech/profiles/LWM2M.xsd">
<Object ObjectType="MODefinition">
<Name>RDB</Name>
<Description1><![CDATA[This object allows manipulation of Runtime Database variables.]]></Description1>
<ObjectID>10260</ObjectID>
<ObjectURN>urn:oma:lwm2m:x:10260:2.0</ObjectURN>
<LWM2MVersion>1.0</LWM2MVersion>
<ObjectVersion>2.0</ObjectVersion>
<MultipleInstances>Multiple</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Resources>
<Item ID="0">
<Name>Key</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>String</Type>
<RangeEnumeration>
</RangeEnumeration>
<Units>
</Units>
<Description><![CDATA[The name of the RDB variable that this instance currently represents. Writing to this resource will not rename or otherwise modify the associated RDB variable, rather it will re-assign the instance to represent a different variable.]]></Description>
</Item>
<Item ID="1">
<Name>Value</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>String</Type>
<RangeEnumeration>
</RangeEnumeration>
<Units>
</Units>
<Description><![CDATA[The current value of the RDB variable associated with this instance. Reading this resource will return a "Not Found" response code if the associated variable does not exist. Writing to this resource will create the associated variable if it does not already exist.]]></Description>
</Item>
<Item ID="2">
<Name>Exists</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Boolean</Type>
<RangeEnumeration>
</RangeEnumeration>
<Units>
</Units>
<Description><![CDATA[Indicates whether the RDB variable associated with this instance currently exists. Writing FALSE to this resource will delete the associated variable if it exists. Writing TRUE to this resource will create the associated variable if it does not already exist. Variables created by this resource will be initialised to an empty string.]]></Description>
</Item>
<Item ID="3">
<Name>Persistent</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Boolean</Type>
<RangeEnumeration>
</RangeEnumeration>
<Units>
</Units>
<Description><![CDATA[Configure whether or not the RDB variable associated with this instance will be saved to persistent storage.]]></Description>
</Item>
</Resources>
<Description2 />
</Object>
</LWM2M>

87
common/transport/lwm2m/src/main/resources/models/10262.xml

@ -1,87 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- BSD-3 Clause License
Copyright 2019 South East Water Corporation.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
-->
<LWM2M xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://openmobilealliance.org/tech/profiles/LWM2M.xsd">
<Object ObjectType="MODefinition">
<Name>Interval Data Delivery</Name>
<Description1><![CDATA[The Interval Data Delivery object provides an optimised means for managing the delivery of interval data from multiple Interval Data Object instances. ]]></Description1>
<ObjectID>10262</ObjectID>
<ObjectURN>urn:oma:lwm2m:x:10262</ObjectURN>
<MultipleInstances>Multiple</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Resources>
<Item ID="0">
<Name>Name</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>String</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[The Name resource provides a way to identify different Interval Data Delivery instances. Name is a readable and writable attribute. Name is defined as an arbitrary length text string]]></Description>
</Item>
<Item ID="1">
<Name>Interval Data Links</Name>
<Operations>RW</Operations>
<MultipleInstances>Multiple</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Objlnk</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[The Interval Data Links resource is a set of object links that point to each of the Interval Data Object Instances that are managed by this Interval Data Delivery Object Instance. An Object Link is two 16-bit integer values representing the Object ID and the Object Instance ID. This resource can have multiple instances allowing this Interval Data Delivery object to manage many Interval Data instances.]]></Description>
</Item>
<Item ID="2">
<Name>Latest Payload</Name>
<Operations>R</Operations>
<MultipleInstances>Multiple</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Opaque</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[The Latest Payload resource is a multiple instance resource representing the Latest Payload resource from each of the Interval Data objects defined in the Interval Data Links Resource. When this payload is delivered to the LwM2M server, via either a read request or a confirmed observation on this Object, Object Instance or Resource, the Latest Delivered Interval should for each of the Interval Data objects defined in the Interval Data Links Resource must be updated. When no new data exists for a specific Interval Data instance and empty Opaque value should be provided. When a specific Interval Data Instance is disabled (Recording Enabled Resource = 0), no payload data should be provided at all.]]></Description>
</Item>
<Item ID="3">
<Name>Schedule</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Objlnk</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[The Schedule resource provides link to a schedule object. This Schedule object is used to provide fine grain control the Notification schedule delivery when the default LwM2M NOTIFICATION attributes do not provide sufficient control. If no schedule is required, an Object Link referencing no Object Instance will contain the concatenation of 2 MAX-ID values (null link).]]></Description>
</Item>
</Resources>
<Description2></Description2>
</Object>
</LWM2M>

90
common/transport/lwm2m/src/main/resources/models/10263.xml

@ -1,90 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- BSD-3 Clause License
Copyright 2019 South East Water Corporation.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
-->
<LWM2M xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://openmobilealliance.org/tech/profiles/LWM2M.xsd">
<Object ObjectType="MODefinition">
<Name>Event Data Delivery</Name>
<Description1><![CDATA[The Event Data Delivery object provides a simple means for managing the delivery of event data from multiple Event Data Object instances. ]]></Description1>
<ObjectID>10263</ObjectID>
<ObjectURN>urn:oma:lwm2m:x:10263</ObjectURN>
<MultipleInstances>Multiple</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Resources>
<Item ID="0">
<Name>Name</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>String</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[The Name resource provides a way to identify different Event Data Delivery instances. Name is a readable and writable attribute. Name is defined as an arbitrary length text string]]></Description>
</Item>
<Item ID="1">
<Name>Event Data Links</Name>
<Operations>RW</Operations>
<MultipleInstances>Multiple</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Objlnk</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[The Event Data Links resource is a set of object links that point to each of the Event Data Object Instances that are managed by this Event Data Delivery Object Instance. An Object Link is two 16-bit integer values representing the Object ID and the Object Instance ID. This resource can have multiple instances allowing this Event Data Delivery object to manage many Event Data instances.]]></Description>
</Item>
<Item ID="2">
<Name>Latest Eventlog</Name>
<Operations>R</Operations>
<MultipleInstances>Multiple</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Opaque</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[The Latest Eventlog resource is a multiple instance resource representing the Latest Eventlog resource from each of the Event Data objects defined in the Event Data Links Resource. When this payload is delivered to the LwM2M server, via either a read request or a confirmed observation on this Object, Object Instance or Resource, the Latest Delivered Event Time for each of the Event Data objects defined in the Event Data Links Resource must be updated. When no new event data exists for any of the linked Event Data instances an empty Opaque value should be provided.
If this resource has an LwM2M server observation and one of the Event Data Instance is configured as Realtime and has been triggered, the Event Data Delivery object must send all undelivered events for all linked Event Data objects.
]]></Description>
</Item>
<Item ID="3">
<Name>Schedule</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Objlnk</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[The Schedule resource provides link to a schedule object. This Schedule object is used to provide fine grain control the Notification schedule delivery when the default LwM2M NOTIFICATION attributes do not provide sufficient control. If no schedule is required, an Object Link referencing no Object Instance will contain the concatenation of 2 MAX-ID values (null link).]]></Description>
</Item>
</Resources>
<Description2></Description2>
</Object>
</LWM2M>

117
common/transport/lwm2m/src/main/resources/models/10264.xml

@ -1,117 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- BSD-3 Clause License
Copyright 2019 South East Water Corporation.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
-->
<LWM2M xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://openmobilealliance.org/tech/profiles/LWM2M.xsd">
<Object ObjectType="MODefinition">
<Name>Delivery Schedule</Name>
<Description1><![CDATA[The Delivery Schedule object provides a means for controlling the periodic delivery of interval and event data to the LwM2M server.]]></Description1>
<ObjectID>10264</ObjectID>
<ObjectURN>urn:oma:lwm2m:x:10264</ObjectURN>
<MultipleInstances>Multiple</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Resources>
<Item ID="0">
<Name>Schedule Start Time</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Integer</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Schedule Start Time is a readable and writable resource representing the number of seconds past midnight for which this schedule commences]]></Description>
</Item>
<Item ID="1">
<Name>Schedule UTC Offset</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>String</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[The Schedule UTC Offset resource is a readable and writable resource representing the time zone offset for the Schedule Start Time Resource for this Delivery Schedule instance. If this resource is empty, the application should use the UTC offset provided in the Device [/3/0/14] object instance resource or UTC if not provided. UTC+X [ISO 8601].]]></Description>
</Item>
<Item ID="2">
<Name>Delivery Frequency</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Integer</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[The Delivery Frequency resource is a readable and writable resource representing the number of seconds between deliveries. It is recommended that the Delivery Frequency be set to a devisor of 24 hours (86400 seconds) to provide a consistent interval period. Examples of Delivery Frequency include:-
30 = Every 30 seconds
600 = Every 10 minutes
1800 = Every 30 minutes
3600 = Hourly
7200 = Every 2 hours
14400 = Every 4 hours
43200 = Every 12 hours
86400 = Every Day
172600 = Every Second Day
]]></Description>
</Item>
<Item ID="3">
<Name>Randomised Delivery Window</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Integer</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[The Randomised Delivery Window resource is a readable and writable resource representing a randomisation widow in seconds for the triggering of the notification delivery to the LwM2M server. If not provided, the randomised delivery window should default to 0 and the Notification should be sent immediately. The Randomised Delivery Window resource should be set to a value smaller than the delivery frequency.]]></Description>
</Item>
<Item ID="4">
<Name>Number of Retries</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Integer</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[The Number of Retries resource is a readable and writable resource representing the number of retry attempts that should be attempted when the delivery notification is not successful. If not provided, this value defaults to 0 and no retries are attempted. This retry behaviour is at an application level and should be set with consideration of standard CoAP retry behaviour.]]></Description>
</Item>
<Item ID="5">
<Name>Retry Period</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Integer</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[The Retry Period resource is a readable and writable resource representing the number of seconds between each application level retry. ]]></Description>
</Item>
</Resources>
<Description2></Description2>
</Object>
</LWM2M>

136
common/transport/lwm2m/src/main/resources/models/10265.xml

@ -1,136 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- BSD-3 Clause License
Copyright 2019 South East Water Corporation.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
-->
<LWM2M xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://openmobilealliance.org/tech/profiles/LWM2M.xsd">
<Object ObjectType="MODefinition">
<Name>Leakage Detection Configuration</Name>
<Description1><![CDATA[The leakage detection configuration object provides a means for configuring the timing and sampling frequency of a vibration based network leak detector]]></Description1>
<ObjectID>10265</ObjectID>
<ObjectURN>urn:oma:lwm2m:x:10265</ObjectURN>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Resources>
<Item ID="0">
<Name>Sample Times</Name>
<Operations>RW</Operations>
<MultipleInstances>Multiple</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Integer</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Sample Times is a readable and writable multi value resource used to control when leak detection vibration sampling should occur. This is an integer value representing seconds since midnight]]></Description>
</Item>
<Item ID="1">
<Name>Sample UTC Offset</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>String</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[The Sample UTC Offset resource is a readable and writable resource representing the time zone offset for this Leakage Detection Schedule instance. If this resource is empty, the application should use the UTC offset provided in the Device [/3/0/14] object instance resource or UTC if not provided.]]></Description>
</Item>
<Item ID="2">
<Name>Detection Mode</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Integer</Type>
<RangeEnumeration>0..3</RangeEnumeration>
<Units></Units>
<Description><![CDATA[Detection Mode is a readable and writeable resource used to indicate which mode to run the leak detection sensor. Values are one of:-
0. Disabled
1. Alarm Only (default)
2. Top Frequency Values
3. All Frequency Values
Disabled (0) the leak detection function should be disabled.
Alarm Only (1) for this mode no detailed frequency data is provided to the LwM2M server and an alarm is raised if the Leakage Detection Daughter board indicates that leak was detected.
Top Frequency Values (2) for this mode, only the top (Top Frequency Count) values will be delivered to the LwM2M server via the Frequency Value Resource
All Frequency Values(3) for this mode, all frequency values for all frequency bands will be provided to the LwM2M server via the Frequency Value Resource
]]></Description>
</Item>
<Item ID="3">
<Name>Top Frequency Count</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Integer</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Top Frequency Count is a readable and writeable resource used represent the number of samples to provide if the Detection Mode is set to Mode 2 (Top Frequency Values). If not provided, this value should default to 3]]></Description>
</Item>
<Item ID="4">
<Name>Frequency Thresholds</Name>
<Operations>RW</Operations>
<MultipleInstances>Multiple</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Integer</Type>
<RangeEnumeration>0..999</RangeEnumeration>
<Units></Units>
<Description><![CDATA[Frequency Thresholds is a multiple value readable and writeable resource used to represent upper bound thresholds for each of the frequency bands configured on the daughter board. Being a multiple value resource, this resource only needs to contain the values that are required to override the default values provided by the daughter board firmware. As an example if the frequency threshold for band 7 and band 52 needs to be overridden, then this resource should just contain those two values:-
/TBD/0/4/7 = 123
/TBD/0/4/52 = 345
]]></Description>
</Item>
<Item ID="5">
<Name>Frequency Values</Name>
<Operations>R</Operations>
<MultipleInstances>Multiple</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Integer</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Frequency Values is a multiple value readonly resource used represent the latest frequency values recorded by the daughter board. In Detection Mode 2 (Top Frequency Values) only the number of values configured in Top Frequency Count will be provided. As an example, if the Top Frequency Count is 3 and the top three frequency threshold deviations were on band 8, 44 and 101, this resource would present:-
/TBD/0/5/8 = 434
/TBD/0/5/44 = 39
/TBD/0/5/101 = 349
In Detection Mode 3, this resource would present all frequency readings from 1 through to the number of bands measured by the board.
This resource can either be observed by the LwM2M server (and subsequently notified by the Client daily) or Read adhoc from the LwM2M server.
]]></Description>
</Item>
<Item ID="7">
<Name>Firmware Version</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>String</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Firmware Version is a readonly resource representing the current firmware version of the Daughter Board.]]></Description>
</Item>
</Resources>
<Description2></Description2>
</Object>
</LWM2M>

244
common/transport/lwm2m/src/main/resources/models/10266.xml

@ -1,244 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- BSD-3 Clause License
Copyright 2019 South East Water Corporation.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
-->
<LWM2M xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://openmobilealliance.org/tech/profiles/LWM2M.xsd">
<Object ObjectType="MODefinition">
<Name>Water Flow Readings</Name>
<Description1><![CDATA[Measures the flow of water in regular intervals]]></Description1>
<ObjectID>10266</ObjectID>
<ObjectURN>urn:oma:lwm2m:x:10266</ObjectURN>
<MultipleInstances>Multiple</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Resources>
<Item ID="6000">
<Name>Interval Period</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Integer</Type>
<RangeEnumeration>1..864000</RangeEnumeration>
<Units>s</Units>
<Description><![CDATA[The Interval Period resource is an Integer value representing the width in seconds of the intervals being managed by this interval data object. This resource is read only and can only be changed by resource 11 (Change Interval Configuration). It is recommended that the Interval Period be set to a devisor of 24 hours (86400 seconds) to provide a consistent interval period. Examples of Interval Period include:-
30 = Every 30 seconds
600 = Every 10 minutes
1800 = Every 30 minutes
3600 = Hourly
7200 = Every 2 hours
14400 = Every 4 hours
43200 = Every 12 hours
86400 = Every Day
172600 = Every Second Day]]></Description>
</Item>
<Item ID="6001">
<Name>Interval Start Offset</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Integer</Type>
<RangeEnumeration>0..86399</RangeEnumeration>
<Units>s</Units>
<Description><![CDATA[The Interval Start Offset resource is a read only resource representing the number of seconds past midnight for which the first interval is recorded. If this resource is empty, it is assumed that the intervals are midnight aligned. This can be used to adjust interval boundaries. As an example, an Interval Period of 3600 seconds and an Interval Start time of 300 represents hourly interval data, starting at 00:05.]]></Description>
</Item>
<Item ID="6002">
<Name>Interval UTC Offset</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>String</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[The Interval UTC Offset resource is a read only resource representing the time zone offset for this Interval Data instance. If this resource is empty, the application should use the UTC offset provided in the Device [/3/0/14] object instance resource or UTC if not provided. UTC+X [ISO 8601].]]></Description>
</Item>
<Item ID="6003">
<Name>Interval Collection Start Time</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Time</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[The Collection Start Time resource is a read only resource representing the time when the first interval was recorded on the device. Interval times represent the end of the interval, not the beginning. As an example, the first four hourly interval past midnight will have a timestamp of 04:00 (adjusting for UTC offset). ]]></Description>
</Item>
<Item ID="6004">
<Name>Oldest Recorded Interval</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Time</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[The Oldest Recorded Interval resource is a read-only resource representing the oldest available interval on the device. Interval times represent the end of the interval, not the beginning.]]></Description>
</Item>
<Item ID="6005">
<Name>Last Delivered Interval</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Time</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[The Last Delivered Interval is a readable and writable resource used to represent the last interval delivered to the LwM2M server. Interval times represent the end of the interval, not the beginning. The setting of this resource is implementation specific but should be updated based on, either a Read request of the Latest Payload from the LwM2M server or via a confirmed delivery of Notify operation of the Latest Payload resource. This resource is writable to allow the server to adjust the Last Delivered Interval value if the server and client is out of sync.]]></Description>
</Item>
<Item ID="6006">
<Name>Latest Recorded Interval</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Time</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[The Latest Recorded Interval is a readable resource representing the currently highest recorded interval on the device. Interval times represent the end of the interval, not the beginning.]]></Description>
</Item>
<Item ID="6007">
<Name>Interval Delivery Midnight Aligned</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Boolean</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[The Delivery Midnight Aligned is a readable and writable resource used to indicate if data is delivered only to the previous midnight (1) or if part-day data can be delivered (0). Calculating Midnight should consider the Interval UTC Offset resource, or if empty, the Device [/3/0/14] object instance resource.]]></Description>
</Item>
<Item ID="6008">
<Name>Interval Historical Read</Name>
<Operations>E</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type></Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Historical Interval Read is an executable resource designed to retrieve ad-hoc interval read data. The resource takes two arguments:-
Argument 0: First Interval time to Retrieve represented as number of seconds since Jan 1st, 1970 in the UTC time zone.
Argument 1: Last interval time to Retrieve represented as number of seconds since Jan 1st, 1970 in the UTC time zone.
The dates should be inclusive based on the end time of the interval. The data retrieved from this resource will be readable (or observable) from the Historical Read Payload Resource.
As an example, the Argument List to retrieve data from Midnight 2nd March (UTC+10) to Midnight 6rd March (UTC+10) for a specific instance of the interval data object, would be constructed as follows:-
0='1488463200',1='1488808800']]></Description>
</Item>
<Item ID="6009">
<Name>Interval Historical Read Payload</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Opaque</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[The Historical Read Payload resource is the representation of the data requested by the Historical Interval Read executable resource. The format of this Opaque value should be identical to the Latest Payload resource. If no Historical Interval Read has been executed, this resource should return and empty Opaque value. This resource can either be Read from the Server or set up as an observation and Notified to the server as soon as the historical data is available. When this payload is delivered to the LwM2M server, via either a read request or a confirmed observation on this Object, Object Instance or Resource, the Historical Read Payload should be set to an empty Opaque value.]]></Description>
</Item>
<Item ID="6010">
<Name>Interval Change Configuration</Name>
<Operations>E</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type></Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Change Interval Configuration is an executable resource designed to allow the Interval Period, Interval Start Offset and Interval UTC Offset to be reconfigured. The resource takes three arguments:-
Argument 0: [Mandatory] Interval Period represented as an integer as defined in the Interval Period Resource.
Argument 1: [Optional] Interval start offset represented as an integer as defined in the Interval Start Offset Resource. If not provided, leave the value as per the current configuration
Argument 2: [Optional] Interval UTC offset represented as a String as defined in the Interval UTC Offset Resource. If not provided, leave the value as per the current configuration.
Depending on the specifics of the implementation of this object, reconfiguring the Interval data object may result in the removal of all historical data for this Interval Data Object Instance. Please consult with your device vendor as to the implications of reconfiguring an Interval Data Object Instance.
As an example, the Argument List to change an interval data object instance from its existing values to one hour intervals, midnight aligned in UTC+10 time zone:-
0='3600',1='0',1='UTC+10']]></Description>
</Item>
<Item ID="6026">
<Name>Start</Name>
<Operations>E</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type></Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Start is an executable resource that enables the recording of interval data. The first interval recorded will have a timestamp based on the Interval Start Offset resource. This executable resource takes no arguments. Refer to re-usable resource LogStart for further details.]]></Description>
</Item>
<Item ID="6027">
<Name>Stop</Name>
<Operations>E</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type></Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Stop (LogStop) is an executable resource that disables the recording of interval data for this object instance. This executable resource takes no arguments. Refer to re-usable resource LogStop for further details.]]></Description>
</Item>
<Item ID="6028">
<Name>Status</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Integer</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Recording Enabled is a read-only resource providing an indication of if interval data is currently being recorded for this object instance. Refer to re-usable resource LogStatus for further details.]]></Description>
</Item>
<Item ID="6029">
<Name>Latest Payload</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Opaque</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[The Latest Payload resource is a read-only serialised Opaque (Binary) representation of all the Interval Data between the Last Delivered Interval and the Latest Recorded Interval, accounting for the Delivery Midnight Aligned resource. When this payload is delivered to the LwM2M server, via either a read request or a confirmed observation on this Object, Object Instance or Resource, the Latest Delivered Interval should be updated. When no new data exists, an empty Opaque value should be provided.
The payload data can be provided in an implementation specific serialisation, but by default for fixed length values should use the OMA-LwM2M CBOR format encoded as follows:
1. 8-bit integer, value 2 representing OMA-LwM2M CBOR format.
2. Interval Data Instance ID/ Class [16-bit integer]
3. Timestamp of first Interval [32-bit integer] representing the number of seconds since Jan 1st, 1970 in the UTC time zone.
4. Interval Period in seconds [32-bit integer]
5. Number of intervals in Payload [16-bit integer]
6. Number of Values Per Interval [8-bit integer]
7. Size of Value 1 in bits [8-bit integer]
8. Size of Value 2 in bits [8-bit integer]
...
9. Size of Value N in bits [8-bit integer]
10. Interval 1 Value 1 [x bits]
11. Interval 1 Value 2 [x bits]
...
12. Interval 1 Value N [x bits]
...
13. Interval N Value N [x bits]
If for some implementation specific reason, there are missing intervals in the sequence, the payload may consist of multiple blocks of the above serialised data (appended into a single binary opaque value), each block representing a continuous series of interval data.
]]></Description>
</Item>
</Resources>
<Description2></Description2>
</Object>
</LWM2M>

244
common/transport/lwm2m/src/main/resources/models/10267.xml

@ -1,244 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- BSD-3 Clause License
Copyright 2019 South East Water Corporation.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
-->
<LWM2M xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://openmobilealliance.org/tech/profiles/LWM2M.xsd">
<Object ObjectType="MODefinition">
<Name>Daily Maximum Flow Rate Readings</Name>
<Description1><![CDATA[Measures the maximum flow rate and its time stamp for specified period]]></Description1>
<ObjectID>10267</ObjectID>
<ObjectURN>urn:oma:lwm2m:x:10267</ObjectURN>
<MultipleInstances>Multiple</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Resources>
<Item ID="6000">
<Name>Interval Period</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Integer</Type>
<RangeEnumeration>1..864000</RangeEnumeration>
<Units>s</Units>
<Description><![CDATA[The Interval Period resource is an Integer value representing the width in seconds of the intervals being managed by this interval data object. This resource is read only and can only be changed by resource 11 (Change Interval Configuration). It is recommended that the Interval Period be set to a devisor of 24 hours (86400 seconds) to provide a consistent interval period. Examples of Interval Period include:-
30 = Every 30 seconds
600 = Every 10 minutes
1800 = Every 30 minutes
3600 = Hourly
7200 = Every 2 hours
14400 = Every 4 hours
43200 = Every 12 hours
86400 = Every Day
172600 = Every Second Day]]></Description>
</Item>
<Item ID="6001">
<Name>Interval Start Offset</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Integer</Type>
<RangeEnumeration>0..86399</RangeEnumeration>
<Units>s</Units>
<Description><![CDATA[The Interval Start Offset resource is a read only resource representing the number of seconds past midnight for which the first interval is recorded. If this resource is empty, it is assumed that the intervals are midnight aligned. This can be used to adjust interval boundaries. As an example, an Interval Period of 3600 seconds and an Interval Start time of 300 represents hourly interval data, starting at 00:05.]]></Description>
</Item>
<Item ID="6002">
<Name>Interval UTC Offset</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>String</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[The Interval UTC Offset resource is a read only resource representing the time zone offset for this Interval Data instance. If this resource is empty, the application should use the UTC offset provided in the Device [/3/0/14] object instance resource or UTC if not provided. UTC+X [ISO 8601].]]></Description>
</Item>
<Item ID="6003">
<Name>Interval Collection Start Time</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Time</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[The Collection Start Time resource is a read only resource representing the time when the first interval was recorded on the device. Interval times represent the end of the interval, not the beginning. As an example, the first four hourly interval past midnight will have a timestamp of 04:00 (adjusting for UTC offset). ]]></Description>
</Item>
<Item ID="6004">
<Name>Oldest Recorded Interval</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Time</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[The Oldest Recorded Interval resource is a read-only resource representing the oldest available interval on the device. Interval times represent the end of the interval, not the beginning.]]></Description>
</Item>
<Item ID="6005">
<Name>Last Delivered Interval</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Time</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[The Last Delivered Interval is a readable and writable resource used to represent the last interval delivered to the LwM2M server. Interval times represent the end of the interval, not the beginning. The setting of this resource is implementation specific but should be updated based on, either a Read request of the Latest Payload from the LwM2M server or via a confirmed delivery of Notify operation of the Latest Payload resource. This resource is writable to allow the server to adjust the Last Delivered Interval value if the server and client is out of sync.]]></Description>
</Item>
<Item ID="6006">
<Name>Latest Recorded Interval</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Time</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[The Latest Recorded Interval is a readable resource representing the currently highest recorded interval on the device. Interval times represent the end of the interval, not the beginning.]]></Description>
</Item>
<Item ID="6007">
<Name>Interval Delivery Midnight Aligned</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Boolean</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[The Delivery Midnight Aligned is a readable and writable resource used to indicate if data is delivered only to the previous midnight (1) or if part-day data can be delivered (0). Calculating Midnight should consider the Interval UTC Offset resource, or if empty, the Device [/3/0/14] object instance resource.]]></Description>
</Item>
<Item ID="6008">
<Name>Interval Historical Read</Name>
<Operations>E</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type></Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Historical Interval Read is an executable resource designed to retrieve ad-hoc interval read data. The resource takes two arguments:-
Argument 0: First Interval time to Retrieve represented as number of seconds since Jan 1st, 1970 in the UTC time zone.
Argument 1: Last interval time to Retrieve represented as number of seconds since Jan 1st, 1970 in the UTC time zone.
The dates should be inclusive based on the end time of the interval. The data retrieved from this resource will be readable (or observable) from the Historical Read Payload Resource.
As an example, the Argument List to retrieve data from Midnight 2nd March (UTC+10) to Midnight 6rd March (UTC+10) for a specific instance of the interval data object, would be constructed as follows:-
0='1488463200',1='1488808800']]></Description>
</Item>
<Item ID="6009">
<Name>Interval Historical Read Payload</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Opaque</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[The Historical Read Payload resource is the representation of the data requested by the Historical Interval Read executable resource. The format of this Opaque value should be identical to the Latest Payload resource. If no Historical Interval Read has been executed, this resource should return and empty Opaque value. This resource can either be Read from the Server or set up as an observation and Notified to the server as soon as the historical data is available. When this payload is delivered to the LwM2M server, via either a read request or a confirmed observation on this Object, Object Instance or Resource, the Historical Read Payload should be set to an empty Opaque value.]]></Description>
</Item>
<Item ID="6010">
<Name>Interval Change Configuration</Name>
<Operations>E</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type></Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Change Interval Configuration is an executable resource designed to allow the Interval Period, Interval Start Offset and Interval UTC Offset to be reconfigured. The resource takes three arguments:-
Argument 0: [Mandatory] Interval Period represented as an integer as defined in the Interval Period Resource.
Argument 1: [Optional] Interval start offset represented as an integer as defined in the Interval Start Offset Resource. If not provided, leave the value as per the current configuration
Argument 2: [Optional] Interval UTC offset represented as a String as defined in the Interval UTC Offset Resource. If not provided, leave the value as per the current configuration.
Depending on the specifics of the implementation of this object, reconfiguring the Interval data object may result in the removal of all historical data for this Interval Data Object Instance. Please consult with your device vendor as to the implications of reconfiguring an Interval Data Object Instance.
As an example, the Argument List to change an interval data object instance from its existing values to one hour intervals, midnight aligned in UTC+10 time zone:-
0='3600',1='0',1='UTC+10']]></Description>
</Item>
<Item ID="6026">
<Name>Start</Name>
<Operations>E</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type></Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Start is an executable resource that enables the recording of interval data. The first interval recorded will have a timestamp based on the Interval Start Offset resource. This executable resource takes no arguments. Refer to re-usable resource LogStart for further details.]]></Description>
</Item>
<Item ID="6027">
<Name>Stop</Name>
<Operations>E</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type></Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Stop (LogStop) is an executable resource that disables the recording of interval data for this object instance. This executable resource takes no arguments. Refer to re-usable resource LogStop for further details.]]></Description>
</Item>
<Item ID="6028">
<Name>Status</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Integer</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Recording Enabled is a read-only resource providing an indication of if interval data is currently being recorded for this object instance. Refer to re-usable resource LogStatus for further details.]]></Description>
</Item>
<Item ID="6029">
<Name>Latest Payload</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Opaque</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[The Latest Payload resource is a read-only serialised Opaque (Binary) representation of all the Interval Data between the Last Delivered Interval and the Latest Recorded Interval, accounting for the Delivery Midnight Aligned resource. When this payload is delivered to the LwM2M server, via either a read request or a confirmed observation on this Object, Object Instance or Resource, the Latest Delivered Interval should be updated. When no new data exists, an empty Opaque value should be provided.
The payload data can be provided in an implementation specific serialisation, but by default for fixed length values should use the OMA-LwM2M CBOR format encoded as follows:
1. 8-bit integer, value 2 representing OMA-LwM2M CBOR format.
2. Interval Data Instance ID/ Class [16-bit integer]
3. Timestamp of first Interval [32-bit integer] representing the number of seconds since Jan 1st, 1970 in the UTC time zone.
4. Interval Period in seconds [32-bit integer]
5. Number of intervals in Payload [16-bit integer]
6. Number of Values Per Interval [8-bit integer]
7. Size of Value 1 in bits [8-bit integer]
8. Size of Value 2 in bits [8-bit integer]
...
9. Size of Value N in bits [8-bit integer]
10. Interval 1 Value 1 [x bits]
11. Interval 1 Value 2 [x bits]
...
12. Interval 1 Value N [x bits]
...
13. Interval N Value N [x bits]
If for some implementation specific reason, there are missing intervals in the sequence, the payload may consist of multiple blocks of the above serialised data (appended into a single binary opaque value), each block representing a continuous series of interval data.
]]></Description>
</Item>
</Resources>
<Description2></Description2>
</Object>
</LWM2M>

244
common/transport/lwm2m/src/main/resources/models/10268.xml

@ -1,244 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- BSD-3 Clause License
Copyright 2019 South East Water Corporation.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
-->
<LWM2M xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://openmobilealliance.org/tech/profiles/LWM2M.xsd">
<Object ObjectType="MODefinition">
<Name>Temperature Readings</Name>
<Description1><![CDATA[Periodic temperature measurements]]></Description1>
<ObjectID>10268</ObjectID>
<ObjectURN>urn:oma:lwm2m:x:10268</ObjectURN>
<MultipleInstances>Multiple</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Resources>
<Item ID="6000">
<Name>Interval Period</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Integer</Type>
<RangeEnumeration>1..864000</RangeEnumeration>
<Units>s</Units>
<Description><![CDATA[The Interval Period resource is an Integer value representing the width in seconds of the intervals being managed by this interval data object. This resource is read only and can only be changed by resource 11 (Change Interval Configuration). It is recommended that the Interval Period be set to a devisor of 24 hours (86400 seconds) to provide a consistent interval period. Examples of Interval Period include:-
30 = Every 30 seconds
600 = Every 10 minutes
1800 = Every 30 minutes
3600 = Hourly
7200 = Every 2 hours
14400 = Every 4 hours
43200 = Every 12 hours
86400 = Every Day
172600 = Every Second Day]]></Description>
</Item>
<Item ID="6001">
<Name>Interval Start Offset</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Integer</Type>
<RangeEnumeration>0..86399</RangeEnumeration>
<Units>s</Units>
<Description><![CDATA[The Interval Start Offset resource is a read only resource representing the number of seconds past midnight for which the first interval is recorded. If this resource is empty, it is assumed that the intervals are midnight aligned. This can be used to adjust interval boundaries. As an example, an Interval Period of 3600 seconds and an Interval Start time of 300 represents hourly interval data, starting at 00:05.]]></Description>
</Item>
<Item ID="6002">
<Name>Interval UTC Offset</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>String</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[The Interval UTC Offset resource is a read only resource representing the time zone offset for this Interval Data instance. If this resource is empty, the application should use the UTC offset provided in the Device [/3/0/14] object instance resource or UTC if not provided. UTC+X [ISO 8601].]]></Description>
</Item>
<Item ID="6003">
<Name>Interval Collection Start Time</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Time</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[The Collection Start Time resource is a read only resource representing the time when the first interval was recorded on the device. Interval times represent the end of the interval, not the beginning. As an example, the first four hourly interval past midnight will have a timestamp of 04:00 (adjusting for UTC offset). ]]></Description>
</Item>
<Item ID="6004">
<Name>Oldest Recorded Interval</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Time</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[The Oldest Recorded Interval resource is a read-only resource representing the oldest available interval on the device. Interval times represent the end of the interval, not the beginning.]]></Description>
</Item>
<Item ID="6005">
<Name>Last Delivered Interval</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Time</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[The Last Delivered Interval is a readable and writable resource used to represent the last interval delivered to the LwM2M server. Interval times represent the end of the interval, not the beginning. The setting of this resource is implementation specific but should be updated based on, either a Read request of the Latest Payload from the LwM2M server or via a confirmed delivery of Notify operation of the Latest Payload resource. This resource is writable to allow the server to adjust the Last Delivered Interval value if the server and client is out of sync.]]></Description>
</Item>
<Item ID="6006">
<Name>Latest Recorded Interval</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Time</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[The Latest Recorded Interval is a readable resource representing the currently highest recorded interval on the device. Interval times represent the end of the interval, not the beginning.]]></Description>
</Item>
<Item ID="6007">
<Name>Interval Delivery Midnight Aligned</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Boolean</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[The Delivery Midnight Aligned is a readable and writable resource used to indicate if data is delivered only to the previous midnight (1) or if part-day data can be delivered (0). Calculating Midnight should consider the Interval UTC Offset resource, or if empty, the Device [/3/0/14] object instance resource.]]></Description>
</Item>
<Item ID="6008">
<Name>Interval Historical Read</Name>
<Operations>E</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type></Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Historical Interval Read is an executable resource designed to retrieve ad-hoc interval read data. The resource takes two arguments:-
Argument 0: First Interval time to Retrieve represented as number of seconds since Jan 1st, 1970 in the UTC time zone.
Argument 1: Last interval time to Retrieve represented as number of seconds since Jan 1st, 1970 in the UTC time zone.
The dates should be inclusive based on the end time of the interval. The data retrieved from this resource will be readable (or observable) from the Historical Read Payload Resource.
As an example, the Argument List to retrieve data from Midnight 2nd March (UTC+10) to Midnight 6rd March (UTC+10) for a specific instance of the interval data object, would be constructed as follows:-
0='1488463200',1='1488808800']]></Description>
</Item>
<Item ID="6009">
<Name>Interval Historical Read Payload</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Opaque</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[The Historical Read Payload resource is the representation of the data requested by the Historical Interval Read executable resource. The format of this Opaque value should be identical to the Latest Payload resource. If no Historical Interval Read has been executed, this resource should return and empty Opaque value. This resource can either be Read from the Server or set up as an observation and Notified to the server as soon as the historical data is available. When this payload is delivered to the LwM2M server, via either a read request or a confirmed observation on this Object, Object Instance or Resource, the Historical Read Payload should be set to an empty Opaque value.]]></Description>
</Item>
<Item ID="6010">
<Name>Interval Change Configuration</Name>
<Operations>E</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type></Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Change Interval Configuration is an executable resource designed to allow the Interval Period, Interval Start Offset and Interval UTC Offset to be reconfigured. The resource takes three arguments:-
Argument 0: [Mandatory] Interval Period represented as an integer as defined in the Interval Period Resource.
Argument 1: [Optional] Interval start offset represented as an integer as defined in the Interval Start Offset Resource. If not provided, leave the value as per the current configuration
Argument 2: [Optional] Interval UTC offset represented as a String as defined in the Interval UTC Offset Resource. If not provided, leave the value as per the current configuration.
Depending on the specifics of the implementation of this object, reconfiguring the Interval data object may result in the removal of all historical data for this Interval Data Object Instance. Please consult with your device vendor as to the implications of reconfiguring an Interval Data Object Instance.
As an example, the Argument List to change an interval data object instance from its existing values to one hour intervals, midnight aligned in UTC+10 time zone:-
0='3600',1='0',1='UTC+10']]></Description>
</Item>
<Item ID="6026">
<Name>Start</Name>
<Operations>E</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type></Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Start is an executable resource that enables the recording of interval data. The first interval recorded will have a timestamp based on the Interval Start Offset resource. This executable resource takes no arguments. Refer to re-usable resource LogStart for further details.]]></Description>
</Item>
<Item ID="6027">
<Name>Stop</Name>
<Operations>E</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type></Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Stop (LogStop) is an executable resource that disables the recording of interval data for this object instance. This executable resource takes no arguments. Refer to re-usable resource LogStop for further details.]]></Description>
</Item>
<Item ID="6028">
<Name>Status</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Integer</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Recording Enabled is a read-only resource providing an indication of if interval data is currently being recorded for this object instance. Refer to re-usable resource LogStatus for further details.]]></Description>
</Item>
<Item ID="6029">
<Name>Latest Payload</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Opaque</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[The Latest Payload resource is a read-only serialised Opaque (Binary) representation of all the Interval Data between the Last Delivered Interval and the Latest Recorded Interval, accounting for the Delivery Midnight Aligned resource. When this payload is delivered to the LwM2M server, via either a read request or a confirmed observation on this Object, Object Instance or Resource, the Latest Delivered Interval should be updated. When no new data exists, an empty Opaque value should be provided.
The payload data can be provided in an implementation specific serialisation, but by default for fixed length values should use the OMA-LwM2M CBOR format encoded as follows:
1. 8-bit integer, value 2 representing OMA-LwM2M CBOR format.
2. Interval Data Instance ID/ Class [16-bit integer]
3. Timestamp of first Interval [32-bit integer] representing the number of seconds since Jan 1st, 1970 in the UTC time zone.
4. Interval Period in seconds [32-bit integer]
5. Number of intervals in Payload [16-bit integer]
6. Number of Values Per Interval [8-bit integer]
7. Size of Value 1 in bits [8-bit integer]
8. Size of Value 2 in bits [8-bit integer]
...
9. Size of Value N in bits [8-bit integer]
10. Interval 1 Value 1 [x bits]
11. Interval 1 Value 2 [x bits]
...
12. Interval 1 Value N [x bits]
...
13. Interval N Value N [x bits]
If for some implementation specific reason, there are missing intervals in the sequence, the payload may consist of multiple blocks of the above serialised data (appended into a single binary opaque value), each block representing a continuous series of interval data.
]]></Description>
</Item>
</Resources>
<Description2></Description2>
</Object>
</LWM2M>

244
common/transport/lwm2m/src/main/resources/models/10269.xml

@ -1,244 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- BSD-3 Clause License
Copyright 2019 South East Water Corporation.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
-->
<LWM2M xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://openmobilealliance.org/tech/profiles/LWM2M.xsd">
<Object ObjectType="MODefinition">
<Name>Pressure Readings</Name>
<Description1><![CDATA[Periodic pressure measurements]]></Description1>
<ObjectID>10269</ObjectID>
<ObjectURN>urn:oma:lwm2m:x:10269</ObjectURN>
<MultipleInstances>Multiple</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Resources>
<Item ID="6000">
<Name>Interval Period</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Integer</Type>
<RangeEnumeration>1..864000</RangeEnumeration>
<Units>s</Units>
<Description><![CDATA[The Interval Period resource is an Integer value representing the width in seconds of the intervals being managed by this interval data object. This resource is read only and can only be changed by resource 11 (Change Interval Configuration). It is recommended that the Interval Period be set to a devisor of 24 hours (86400 seconds) to provide a consistent interval period. Examples of Interval Period include:-
30 = Every 30 seconds
600 = Every 10 minutes
1800 = Every 30 minutes
3600 = Hourly
7200 = Every 2 hours
14400 = Every 4 hours
43200 = Every 12 hours
86400 = Every Day
172600 = Every Second Day]]></Description>
</Item>
<Item ID="6001">
<Name>Interval Start Offset</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Integer</Type>
<RangeEnumeration>0..86399</RangeEnumeration>
<Units>s</Units>
<Description><![CDATA[The Interval Start Offset resource is a read only resource representing the number of seconds past midnight for which the first interval is recorded. If this resource is empty, it is assumed that the intervals are midnight aligned. This can be used to adjust interval boundaries. As an example, an Interval Period of 3600 seconds and an Interval Start time of 300 represents hourly interval data, starting at 00:05.]]></Description>
</Item>
<Item ID="6002">
<Name>Interval UTC Offset</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>String</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[The Interval UTC Offset resource is a read only resource representing the time zone offset for this Interval Data instance. If this resource is empty, the application should use the UTC offset provided in the Device [/3/0/14] object instance resource or UTC if not provided. UTC+X [ISO 8601].]]></Description>
</Item>
<Item ID="6003">
<Name>Interval Collection Start Time</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Time</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[The Collection Start Time resource is a read only resource representing the time when the first interval was recorded on the device. Interval times represent the end of the interval, not the beginning. As an example, the first four hourly interval past midnight will have a timestamp of 04:00 (adjusting for UTC offset). ]]></Description>
</Item>
<Item ID="6004">
<Name>Oldest Recorded Interval</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Time</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[The Oldest Recorded Interval resource is a read-only resource representing the oldest available interval on the device. Interval times represent the end of the interval, not the beginning.]]></Description>
</Item>
<Item ID="6005">
<Name>Last Delivered Interval</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Time</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[The Last Delivered Interval is a readable and writable resource used to represent the last interval delivered to the LwM2M server. Interval times represent the end of the interval, not the beginning. The setting of this resource is implementation specific but should be updated based on, either a Read request of the Latest Payload from the LwM2M server or via a confirmed delivery of Notify operation of the Latest Payload resource. This resource is writable to allow the server to adjust the Last Delivered Interval value if the server and client is out of sync.]]></Description>
</Item>
<Item ID="6006">
<Name>Latest Recorded Interval</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Time</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[The Latest Recorded Interval is a readable resource representing the currently highest recorded interval on the device. Interval times represent the end of the interval, not the beginning.]]></Description>
</Item>
<Item ID="6007">
<Name>Interval Delivery Midnight Aligned</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Boolean</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[The Delivery Midnight Aligned is a readable and writable resource used to indicate if data is delivered only to the previous midnight (1) or if part-day data can be delivered (0). Calculating Midnight should consider the Interval UTC Offset resource, or if empty, the Device [/3/0/14] object instance resource.]]></Description>
</Item>
<Item ID="6008">
<Name>Interval Historical Read</Name>
<Operations>E</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type></Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Historical Interval Read is an executable resource designed to retrieve ad-hoc interval read data. The resource takes two arguments:-
Argument 0: First Interval time to Retrieve represented as number of seconds since Jan 1st, 1970 in the UTC time zone.
Argument 1: Last interval time to Retrieve represented as number of seconds since Jan 1st, 1970 in the UTC time zone.
The dates should be inclusive based on the end time of the interval. The data retrieved from this resource will be readable (or observable) from the Historical Read Payload Resource.
As an example, the Argument List to retrieve data from Midnight 2nd March (UTC+10) to Midnight 6rd March (UTC+10) for a specific instance of the interval data object, would be constructed as follows:-
0='1488463200',1='1488808800']]></Description>
</Item>
<Item ID="6009">
<Name>Interval Historical Read Payload</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Opaque</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[The Historical Read Payload resource is the representation of the data requested by the Historical Interval Read executable resource. The format of this Opaque value should be identical to the Latest Payload resource. If no Historical Interval Read has been executed, this resource should return and empty Opaque value. This resource can either be Read from the Server or set up as an observation and Notified to the server as soon as the historical data is available. When this payload is delivered to the LwM2M server, via either a read request or a confirmed observation on this Object, Object Instance or Resource, the Historical Read Payload should be set to an empty Opaque value.]]></Description>
</Item>
<Item ID="6010">
<Name>Interval Change Configuration</Name>
<Operations>E</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type></Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Change Interval Configuration is an executable resource designed to allow the Interval Period, Interval Start Offset and Interval UTC Offset to be reconfigured. The resource takes three arguments:-
Argument 0: [Mandatory] Interval Period represented as an integer as defined in the Interval Period Resource.
Argument 1: [Optional] Interval start offset represented as an integer as defined in the Interval Start Offset Resource. If not provided, leave the value as per the current configuration
Argument 2: [Optional] Interval UTC offset represented as a String as defined in the Interval UTC Offset Resource. If not provided, leave the value as per the current configuration.
Depending on the specifics of the implementation of this object, reconfiguring the Interval data object may result in the removal of all historical data for this Interval Data Object Instance. Please consult with your device vendor as to the implications of reconfiguring an Interval Data Object Instance.
As an example, the Argument List to change an interval data object instance from its existing values to one hour intervals, midnight aligned in UTC+10 time zone:-
0='3600',1='0',1='UTC+10']]></Description>
</Item>
<Item ID="6026">
<Name>Start</Name>
<Operations>E</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type></Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Start is an executable resource that enables the recording of interval data. The first interval recorded will have a timestamp based on the Interval Start Offset resource. This executable resource takes no arguments. Refer to re-usable resource LogStart for further details.]]></Description>
</Item>
<Item ID="6027">
<Name>Stop</Name>
<Operations>E</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type></Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Stop (LogStop) is an executable resource that disables the recording of interval data for this object instance. This executable resource takes no arguments. Refer to re-usable resource LogStop for further details.]]></Description>
</Item>
<Item ID="6028">
<Name>Status</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Integer</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Recording Enabled is a read-only resource providing an indication of if interval data is currently being recorded for this object instance. Refer to re-usable resource LogStatus for further details.]]></Description>
</Item>
<Item ID="6029">
<Name>Latest Payload</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Opaque</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[The Latest Payload resource is a read-only serialised Opaque (Binary) representation of all the Interval Data between the Last Delivered Interval and the Latest Recorded Interval, accounting for the Delivery Midnight Aligned resource. When this payload is delivered to the LwM2M server, via either a read request or a confirmed observation on this Object, Object Instance or Resource, the Latest Delivered Interval should be updated. When no new data exists, an empty Opaque value should be provided.
The payload data can be provided in an implementation specific serialisation, but by default for fixed length values should use the OMA-LwM2M CBOR format encoded as follows:
1. 8-bit integer, value 2 representing OMA-LwM2M CBOR format.
2. Interval Data Instance ID/ Class [16-bit integer]
3. Timestamp of first Interval [32-bit integer] representing the number of seconds since Jan 1st, 1970 in the UTC time zone.
4. Interval Period in seconds [32-bit integer]
5. Number of intervals in Payload [16-bit integer]
6. Number of Values Per Interval [8-bit integer]
7. Size of Value 1 in bits [8-bit integer]
8. Size of Value 2 in bits [8-bit integer]
...
9. Size of Value N in bits [8-bit integer]
10. Interval 1 Value 1 [x bits]
11. Interval 1 Value 2 [x bits]
...
12. Interval 1 Value N [x bits]
...
13. Interval N Value N [x bits]
If for some implementation specific reason, there are missing intervals in the sequence, the payload may consist of multiple blocks of the above serialised data (appended into a single binary opaque value), each block representing a continuous series of interval data.
]]></Description>
</Item>
</Resources>
<Description2></Description2>
</Object>
</LWM2M>

244
common/transport/lwm2m/src/main/resources/models/10270.xml

@ -1,244 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- BSD-3 Clause License
Copyright 2019 South East Water Corporation.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
-->
<LWM2M xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://openmobilealliance.org/tech/profiles/LWM2M.xsd">
<Object ObjectType="MODefinition">
<Name>Battery Level Readings</Name>
<Description1><![CDATA[Periodic battery level measurements]]></Description1>
<ObjectID>10270</ObjectID>
<ObjectURN>urn:oma:lwm2m:x:10270</ObjectURN>
<MultipleInstances>Multiple</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Resources>
<Item ID="6000">
<Name>Interval Period</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Integer</Type>
<RangeEnumeration>1..864000</RangeEnumeration>
<Units>s</Units>
<Description><![CDATA[The Interval Period resource is an Integer value representing the width in seconds of the intervals being managed by this interval data object. This resource is read only and can only be changed by resource 11 (Change Interval Configuration). It is recommended that the Interval Period be set to a devisor of 24 hours (86400 seconds) to provide a consistent interval period. Examples of Interval Period include:-
30 = Every 30 seconds
600 = Every 10 minutes
1800 = Every 30 minutes
3600 = Hourly
7200 = Every 2 hours
14400 = Every 4 hours
43200 = Every 12 hours
86400 = Every Day
172600 = Every Second Day]]></Description>
</Item>
<Item ID="6001">
<Name>Interval Start Offset</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Integer</Type>
<RangeEnumeration>0..86399</RangeEnumeration>
<Units>s</Units>
<Description><![CDATA[The Interval Start Offset resource is a read only resource representing the number of seconds past midnight for which the first interval is recorded. If this resource is empty, it is assumed that the intervals are midnight aligned. This can be used to adjust interval boundaries. As an example, an Interval Period of 3600 seconds and an Interval Start time of 300 represents hourly interval data, starting at 00:05.]]></Description>
</Item>
<Item ID="6002">
<Name>Interval UTC Offset</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>String</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[The Interval UTC Offset resource is a read only resource representing the time zone offset for this Interval Data instance. If this resource is empty, the application should use the UTC offset provided in the Device [/3/0/14] object instance resource or UTC if not provided. UTC+X [ISO 8601].]]></Description>
</Item>
<Item ID="6003">
<Name>Interval Collection Start Time</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Time</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[The Collection Start Time resource is a read only resource representing the time when the first interval was recorded on the device. Interval times represent the end of the interval, not the beginning. As an example, the first four hourly interval past midnight will have a timestamp of 04:00 (adjusting for UTC offset). ]]></Description>
</Item>
<Item ID="6004">
<Name>Oldest Recorded Interval</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Time</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[The Oldest Recorded Interval resource is a read-only resource representing the oldest available interval on the device. Interval times represent the end of the interval, not the beginning.]]></Description>
</Item>
<Item ID="6005">
<Name>Last Delivered Interval</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Time</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[The Last Delivered Interval is a readable and writable resource used to represent the last interval delivered to the LwM2M server. Interval times represent the end of the interval, not the beginning. The setting of this resource is implementation specific but should be updated based on, either a Read request of the Latest Payload from the LwM2M server or via a confirmed delivery of Notify operation of the Latest Payload resource. This resource is writable to allow the server to adjust the Last Delivered Interval value if the server and client is out of sync.]]></Description>
</Item>
<Item ID="6006">
<Name>Latest Recorded Interval</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Time</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[The Latest Recorded Interval is a readable resource representing the currently highest recorded interval on the device. Interval times represent the end of the interval, not the beginning.]]></Description>
</Item>
<Item ID="6007">
<Name>Interval Delivery Midnight Aligned</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Boolean</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[The Delivery Midnight Aligned is a readable and writable resource used to indicate if data is delivered only to the previous midnight (1) or if part-day data can be delivered (0). Calculating Midnight should consider the Interval UTC Offset resource, or if empty, the Device [/3/0/14] object instance resource.]]></Description>
</Item>
<Item ID="6008">
<Name>Interval Historical Read</Name>
<Operations>E</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type></Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Historical Interval Read is an executable resource designed to retrieve ad-hoc interval read data. The resource takes two arguments:-
Argument 0: First Interval time to Retrieve represented as number of seconds since Jan 1st, 1970 in the UTC time zone.
Argument 1: Last interval time to Retrieve represented as number of seconds since Jan 1st, 1970 in the UTC time zone.
The dates should be inclusive based on the end time of the interval. The data retrieved from this resource will be readable (or observable) from the Historical Read Payload Resource.
As an example, the Argument List to retrieve data from Midnight 2nd March (UTC+10) to Midnight 6rd March (UTC+10) for a specific instance of the interval data object, would be constructed as follows:-
0='1488463200',1='1488808800']]></Description>
</Item>
<Item ID="6009">
<Name>Interval Historical Read Payload</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Opaque</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[The Historical Read Payload resource is the representation of the data requested by the Historical Interval Read executable resource. The format of this Opaque value should be identical to the Latest Payload resource. If no Historical Interval Read has been executed, this resource should return and empty Opaque value. This resource can either be Read from the Server or set up as an observation and Notified to the server as soon as the historical data is available. When this payload is delivered to the LwM2M server, via either a read request or a confirmed observation on this Object, Object Instance or Resource, the Historical Read Payload should be set to an empty Opaque value.]]></Description>
</Item>
<Item ID="6010">
<Name>Interval Change Configuration</Name>
<Operations>E</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type></Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Change Interval Configuration is an executable resource designed to allow the Interval Period, Interval Start Offset and Interval UTC Offset to be reconfigured. The resource takes three arguments:-
Argument 0: [Mandatory] Interval Period represented as an integer as defined in the Interval Period Resource.
Argument 1: [Optional] Interval start offset represented as an integer as defined in the Interval Start Offset Resource. If not provided, leave the value as per the current configuration
Argument 2: [Optional] Interval UTC offset represented as a String as defined in the Interval UTC Offset Resource. If not provided, leave the value as per the current configuration.
Depending on the specifics of the implementation of this object, reconfiguring the Interval data object may result in the removal of all historical data for this Interval Data Object Instance. Please consult with your device vendor as to the implications of reconfiguring an Interval Data Object Instance.
As an example, the Argument List to change an interval data object instance from its existing values to one hour intervals, midnight aligned in UTC+10 time zone:-
0='3600',1='0',1='UTC+10']]></Description>
</Item>
<Item ID="6026">
<Name>Start</Name>
<Operations>E</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type></Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Start is an executable resource that enables the recording of interval data. The first interval recorded will have a timestamp based on the Interval Start Offset resource. This executable resource takes no arguments. Refer to re-usable resource LogStart for further details.]]></Description>
</Item>
<Item ID="6027">
<Name>Stop</Name>
<Operations>E</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type></Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Stop (LogStop) is an executable resource that disables the recording of interval data for this object instance. This executable resource takes no arguments. Refer to re-usable resource LogStop for further details.]]></Description>
</Item>
<Item ID="6028">
<Name>Status</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Integer</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Recording Enabled is a read-only resource providing an indication of if interval data is currently being recorded for this object instance. Refer to re-usable resource LogStatus for further details.]]></Description>
</Item>
<Item ID="6029">
<Name>Latest Payload</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Opaque</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[The Latest Payload resource is a read-only serialised Opaque (Binary) representation of all the Interval Data between the Last Delivered Interval and the Latest Recorded Interval, accounting for the Delivery Midnight Aligned resource. When this payload is delivered to the LwM2M server, via either a read request or a confirmed observation on this Object, Object Instance or Resource, the Latest Delivered Interval should be updated. When no new data exists, an empty Opaque value should be provided.
The payload data can be provided in an implementation specific serialisation, but by default for fixed length values should use the OMA-LwM2M CBOR format encoded as follows:
1. 8-bit integer, value 2 representing OMA-LwM2M CBOR format.
2. Interval Data Instance ID/ Class [16-bit integer]
3. Timestamp of first Interval [32-bit integer] representing the number of seconds since Jan 1st, 1970 in the UTC time zone.
4. Interval Period in seconds [32-bit integer]
5. Number of intervals in Payload [16-bit integer]
6. Number of Values Per Interval [8-bit integer]
7. Size of Value 1 in bits [8-bit integer]
8. Size of Value 2 in bits [8-bit integer]
...
9. Size of Value N in bits [8-bit integer]
10. Interval 1 Value 1 [x bits]
11. Interval 1 Value 2 [x bits]
...
12. Interval 1 Value N [x bits]
...
13. Interval N Value N [x bits]
If for some implementation specific reason, there are missing intervals in the sequence, the payload may consist of multiple blocks of the above serialised data (appended into a single binary opaque value), each block representing a continuous series of interval data.
]]></Description>
</Item>
</Resources>
<Description2></Description2>
</Object>
</LWM2M>

244
common/transport/lwm2m/src/main/resources/models/10271.xml

@ -1,244 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- BSD-3 Clause License
Copyright 2019 South East Water Corporation.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
-->
<LWM2M xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://openmobilealliance.org/tech/profiles/LWM2M.xsd">
<Object ObjectType="MODefinition">
<Name>Communications Activity Time Readings</Name>
<Description1><![CDATA[Measures the total duration that the meter was activating its radio for packet transmission or receipt for the period. Used to monitor for excess poower usage over time.]]></Description1>
<ObjectID>10271</ObjectID>
<ObjectURN>urn:oma:lwm2m:x:10271</ObjectURN>
<MultipleInstances>Multiple</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Resources>
<Item ID="6000">
<Name>Interval Period</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Integer</Type>
<RangeEnumeration>1..864000</RangeEnumeration>
<Units>s</Units>
<Description><![CDATA[The Interval Period resource is an Integer value representing the width in seconds of the intervals being managed by this interval data object. This resource is read only and can only be changed by resource 11 (Change Interval Configuration). It is recommended that the Interval Period be set to a devisor of 24 hours (86400 seconds) to provide a consistent interval period. Examples of Interval Period include:-
30 = Every 30 seconds
600 = Every 10 minutes
1800 = Every 30 minutes
3600 = Hourly
7200 = Every 2 hours
14400 = Every 4 hours
43200 = Every 12 hours
86400 = Every Day
172600 = Every Second Day]]></Description>
</Item>
<Item ID="6001">
<Name>Interval Start Offset</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Integer</Type>
<RangeEnumeration>0..86399</RangeEnumeration>
<Units>s</Units>
<Description><![CDATA[The Interval Start Offset resource is a read only resource representing the number of seconds past midnight for which the first interval is recorded. If this resource is empty, it is assumed that the intervals are midnight aligned. This can be used to adjust interval boundaries. As an example, an Interval Period of 3600 seconds and an Interval Start time of 300 represents hourly interval data, starting at 00:05.]]></Description>
</Item>
<Item ID="6002">
<Name>Interval UTC Offset</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>String</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[The Interval UTC Offset resource is a read only resource representing the time zone offset for this Interval Data instance. If this resource is empty, the application should use the UTC offset provided in the Device [/3/0/14] object instance resource or UTC if not provided. UTC+X [ISO 8601].]]></Description>
</Item>
<Item ID="6003">
<Name>Interval Collection Start Time</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Time</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[The Collection Start Time resource is a read only resource representing the time when the first interval was recorded on the device. Interval times represent the end of the interval, not the beginning. As an example, the first four hourly interval past midnight will have a timestamp of 04:00 (adjusting for UTC offset). ]]></Description>
</Item>
<Item ID="6004">
<Name>Oldest Recorded Interval</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Time</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[The Oldest Recorded Interval resource is a read-only resource representing the oldest available interval on the device. Interval times represent the end of the interval, not the beginning.]]></Description>
</Item>
<Item ID="6005">
<Name>Last Delivered Interval</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Time</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[The Last Delivered Interval is a readable and writable resource used to represent the last interval delivered to the LwM2M server. Interval times represent the end of the interval, not the beginning. The setting of this resource is implementation specific but should be updated based on, either a Read request of the Latest Payload from the LwM2M server or via a confirmed delivery of Notify operation of the Latest Payload resource. This resource is writable to allow the server to adjust the Last Delivered Interval value if the server and client is out of sync.]]></Description>
</Item>
<Item ID="6006">
<Name>Latest Recorded Interval</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Time</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[The Latest Recorded Interval is a readable resource representing the currently highest recorded interval on the device. Interval times represent the end of the interval, not the beginning.]]></Description>
</Item>
<Item ID="6007">
<Name>Interval Delivery Midnight Aligned</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Boolean</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[The Delivery Midnight Aligned is a readable and writable resource used to indicate if data is delivered only to the previous midnight (1) or if part-day data can be delivered (0). Calculating Midnight should consider the Interval UTC Offset resource, or if empty, the Device [/3/0/14] object instance resource.]]></Description>
</Item>
<Item ID="6008">
<Name>Interval Historical Read</Name>
<Operations>E</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type></Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Historical Interval Read is an executable resource designed to retrieve ad-hoc interval read data. The resource takes two arguments:-
Argument 0: First Interval time to Retrieve represented as number of seconds since Jan 1st, 1970 in the UTC time zone.
Argument 1: Last interval time to Retrieve represented as number of seconds since Jan 1st, 1970 in the UTC time zone.
The dates should be inclusive based on the end time of the interval. The data retrieved from this resource will be readable (or observable) from the Historical Read Payload Resource.
As an example, the Argument List to retrieve data from Midnight 2nd March (UTC+10) to Midnight 6rd March (UTC+10) for a specific instance of the interval data object, would be constructed as follows:-
0='1488463200',1='1488808800']]></Description>
</Item>
<Item ID="6009">
<Name>Interval Historical Read Payload</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Opaque</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[The Historical Read Payload resource is the representation of the data requested by the Historical Interval Read executable resource. The format of this Opaque value should be identical to the Latest Payload resource. If no Historical Interval Read has been executed, this resource should return and empty Opaque value. This resource can either be Read from the Server or set up as an observation and Notified to the server as soon as the historical data is available. When this payload is delivered to the LwM2M server, via either a read request or a confirmed observation on this Object, Object Instance or Resource, the Historical Read Payload should be set to an empty Opaque value.]]></Description>
</Item>
<Item ID="6010">
<Name>Interval Change Configuration</Name>
<Operations>E</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type></Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Change Interval Configuration is an executable resource designed to allow the Interval Period, Interval Start Offset and Interval UTC Offset to be reconfigured. The resource takes three arguments:-
Argument 0: [Mandatory] Interval Period represented as an integer as defined in the Interval Period Resource.
Argument 1: [Optional] Interval start offset represented as an integer as defined in the Interval Start Offset Resource. If not provided, leave the value as per the current configuration
Argument 2: [Optional] Interval UTC offset represented as a String as defined in the Interval UTC Offset Resource. If not provided, leave the value as per the current configuration.
Depending on the specifics of the implementation of this object, reconfiguring the Interval data object may result in the removal of all historical data for this Interval Data Object Instance. Please consult with your device vendor as to the implications of reconfiguring an Interval Data Object Instance.
As an example, the Argument List to change an interval data object instance from its existing values to one hour intervals, midnight aligned in UTC+10 time zone:-
0='3600',1='0',1='UTC+10']]></Description>
</Item>
<Item ID="6026">
<Name>Start</Name>
<Operations>E</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type></Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Start is an executable resource that enables the recording of interval data. The first interval recorded will have a timestamp based on the Interval Start Offset resource. This executable resource takes no arguments. Refer to re-usable resource LogStart for further details.]]></Description>
</Item>
<Item ID="6027">
<Name>Stop</Name>
<Operations>E</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type></Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Stop (LogStop) is an executable resource that disables the recording of interval data for this object instance. This executable resource takes no arguments. Refer to re-usable resource LogStop for further details.]]></Description>
</Item>
<Item ID="6028">
<Name>Status</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Integer</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Recording Enabled is a read-only resource providing an indication of if interval data is currently being recorded for this object instance. Refer to re-usable resource LogStatus for further details.]]></Description>
</Item>
<Item ID="6029">
<Name>Latest Payload</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Opaque</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[The Latest Payload resource is a read-only serialised Opaque (Binary) representation of all the Interval Data between the Last Delivered Interval and the Latest Recorded Interval, accounting for the Delivery Midnight Aligned resource. When this payload is delivered to the LwM2M server, via either a read request or a confirmed observation on this Object, Object Instance or Resource, the Latest Delivered Interval should be updated. When no new data exists, an empty Opaque value should be provided.
The payload data can be provided in an implementation specific serialisation, but by default for fixed length values should use the OMA-LwM2M CBOR format encoded as follows:
1. 8-bit integer, value 2 representing OMA-LwM2M CBOR format.
2. Interval Data Instance ID/ Class [16-bit integer]
3. Timestamp of first Interval [32-bit integer] representing the number of seconds since Jan 1st, 1970 in the UTC time zone.
4. Interval Period in seconds [32-bit integer]
5. Number of intervals in Payload [16-bit integer]
6. Number of Values Per Interval [8-bit integer]
7. Size of Value 1 in bits [8-bit integer]
8. Size of Value 2 in bits [8-bit integer]
...
9. Size of Value N in bits [8-bit integer]
10. Interval 1 Value 1 [x bits]
11. Interval 1 Value 2 [x bits]
...
12. Interval 1 Value N [x bits]
...
13. Interval N Value N [x bits]
If for some implementation specific reason, there are missing intervals in the sequence, the payload may consist of multiple blocks of the above serialised data (appended into a single binary opaque value), each block representing a continuous series of interval data.
]]></Description>
</Item>
</Resources>
<Description2></Description2>
</Object>
</LWM2M>

230
common/transport/lwm2m/src/main/resources/models/10272.xml

@ -1,230 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- BSD-3 Clause License
Copyright 2019 South East Water Corporation.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
-->
<LWM2M xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://openmobilealliance.org/tech/profiles/LWM2M.xsd">
<Object ObjectType="MODefinition">
<Name>Water Meter Customer Leakage Alarm</Name>
<Description1><![CDATA[A binary flag indicating continual usage (e.g. greater than 5 L/h for 24 hours and the flow never returning to zero at any time).]]></Description1>
<ObjectID>10272</ObjectID>
<ObjectURN>urn:oma:lwm2m:x:10272</ObjectURN>
<MultipleInstances>Multiple</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Resources>
<Item ID="6011">
<Name>Event Type</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Integer</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Event Type is a readable and writable resource used to represent how this event will behave. Event Type should be one of the following values:-
0. Disabled
1. Alarm Current State
2. Alarm State Change Log
3. Event Log
When the Event Type is set to Disabled (0), this event will not be recorded by the device. No Latest Eventlog payload should be delivered for events that are Disabled.
When the Event Type is set to Alarm Current State (1), this Event is treated as an alarm state manager and the Latest Eventlog Payload will only contain the current state of this alarm.
When the Event Type is set to Alarm State Change Log (2), the Event is treated as an alarm that reports whenever the Alarm is either set or cleared. The Latest Eventlog Payload will contain all alarm transitions since the previous delivery in this mode.
When the Event Type is set to Event Log (3), this object instance is treated as a raw event log. It is used to manage and deliver events. The Latest Eventlog Payload will contain all events since the previous delivery in this mode.
See the Event Log Payload for examples of each of these modes.
]]></Description>
</Item>
<Item ID="6012">
<Name>Alarm Realtime</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Boolean</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Realtime is a readable and writable resource used to indicate if an event should report immediately (1) at the point of occurrence, or delivered periodically as part of the Latest Eventlog Payload.]]></Description>
</Item>
<Item ID="6013">
<Name>Alarm State</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Boolean</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Alarm State is a read-only resource used to indicate the current alarm state for this Event configuration. This is only applicable if the Event Type is Alarm Current State (1) or Alarm State Change (2). ]]></Description>
</Item>
<Item ID="6014">
<Name>Alarm Set Threshold</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Set Threshold is a readable and writable resource used to represent the threshold for when an alarm is triggered. This resource is used in conjunction with the Set Operator resource. ]]></Description>
</Item>
<Item ID="6015">
<Name>Alarm Set Operator</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Integer</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Set Operator is a readable and writable resource used in conjunction with the Set Threshold to represent when an alarm is triggered. This resource should be set to one of the following values:-
0. Greater Than or Equal to
1. Less Than or Equal to
By setting the Set Operator to Greater Than (0), when the measured value for this event exceeds the Set Threshold resource, the event is considered to be in an Alarm State of 1
By setting the Set Operator to Less Than (1), when the measured value for this event falls below the Set Threshold resource, the event is considered to be in an Alarm State of 1]]></Description>
</Item>
<Item ID="6016">
<Name>Alarm Clear Threshold</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Clear Threshold is a readable and writable resource used to represent the threshold for when an alarm is cleared. This resource is used in conjunction with the Clear Operator resource. ]]></Description>
</Item>
<Item ID="6017">
<Name>Alarm Clear Operator</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Integer</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Clear Operator is a readable and writable resource used in conjunction with the Clear Threshold to represent when an alarm is Cleared. This resource should be set to one of the following values:-
0. Greater Than or Equal to
1. Less Than or Equal to
By setting the Clear Operator to Greater Than (0), when the measured value for this event exceeds the Clear Threshold resource, the event is considered to be in an Alarm State of 0
By setting the Clear Operator to Less Than (1), when the measured value for this event falls below the Clear Threshold resource, the event is considered to be in an Alarm State of 0]]></Description>
</Item>
<Item ID="6018">
<Name>Alarm Maximum Event Count</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Integer</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Maximum Event Count is a readable and writable resource used provide a ceiling on the number of events that can be raised within the time period defined in Maximum Event Period resource. If no Maximum Event Count is set, the number of events recorded is unconstrained. The intent of this resource is to control the number of events reported, particularly in the case of a faulty sensor.]]></Description>
</Item>
<Item ID="6019">
<Name>Alarm Maximum Event Period</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Integer</Type>
<RangeEnumeration>1..864000</RangeEnumeration>
<Units>s</Units>
<Description><![CDATA[Maximum Event Period is a readable and writable resource used in conjunction with the Maximum Event Count resource to control the number of events that can be raised in a given period. Maximum Event Period is an integer value representing the number of seconds for which the Maximum Event Count is measured. If no Maximum Event Period is set, the number of events recorded is unconstrained. The intent of this resource is to control the number of events reported, particularly in the case of a faulty sensor.]]></Description>
</Item>
<Item ID="6020">
<Name>Latest Delivered Event Time</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Time</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Latest Delivered Event Time is a readable and writable resource to represent the last recorded time that an event was delivered for this event code to the LwM2M server. The setting of this resource is implementation specific but should be updated based on, either a Read request of the Latest Eventlog Payload from the LwM2M server or via a confirmed delivery of Notify operation of the Latest Eventlog Payload resource. This resource is writable to allow the server to adjust the Last Delivered Event Time value if the server and client is out of sync.]]></Description>
</Item>
<Item ID="6021">
<Name>Latest Recorded Event Time</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Time</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Latest Recorded Event Time is a readonly resource used to represent the last recorded event time for this object instance on the device]]></Description>
</Item>
<Item ID="6022">
<Name>Alarm Clear</Name>
<Operations>E</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type></Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Clear Alarm is an executable resource used to allow the LwM2M server to clear alarms when they need to be manually acknowledged.]]></Description>
</Item>
<Item ID="6023">
<Name>Alarm Auto Clear</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Boolean</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Auto Clear Alarm is a readable and writable resource used to indicate if an alarm is automatically cleared once the delivery of the event data payload is complete ]]></Description>
</Item>
<Item ID="6024">
<Name>Event Code</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Integer</Type>
<RangeEnumeration>100..255</RangeEnumeration>
<Units></Units>
<Description><![CDATA[Event Code is a read-only resource used as an identifier to represent this class of event. The allocation of event codes is implementation specific but ideally be unique across the implementation. Event Codes use vendor specific LogClass value 100...255]]></Description>
</Item>
<Item ID="6025">
<Name>Latest Payload</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Opaque</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[The Latest Eventlog Payload resource is a read-only serialised Opaque (Binary) representation of all the Event Data between the Last Delivered Event Time and the Latest Recorded Event Time. When this payload is delivered to the LwM2M server, via either a read request or a confirmed observation on this Object, Object Instance or Resource, the Latest Delivered Interval should be updated. When no new data exists, an empty Opaque value should be provided.
The payload data can be provided in an implementation specific serialisation, but by default for fixed length values should use the OMA-LwM2M CBOR format encoded with one of these schemes:-
Event Type = Alarm Current State (1)
In this mode, only the current alarm state should be reported
1. 8-bit integer, value 2 representing OMA-LwM2M CBOR format.
2. Event Code [16-bit integer]
3. Event Type [8-bit Integer] - Alarm Current State (1)
4. Alarm Timestamp [32-bit unsigned integer] representing the number of seconds since Jan 1st, 1970 in the UTC time zone.
5. Alarm State [8-bit Integer]
]]></Description>
</Item>
</Resources>
<Description2></Description2>
</Object>
</LWM2M>

230
common/transport/lwm2m/src/main/resources/models/10273.xml

@ -1,230 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- BSD-3 Clause License
Copyright 2019 South East Water Corporation.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
-->
<LWM2M xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://openmobilealliance.org/tech/profiles/LWM2M.xsd">
<Object ObjectType="MODefinition">
<Name>Water Meter Reverse Flow Alarm</Name>
<Description1><![CDATA[An alarm indicating reverse flow through the pipe. Also supports delivery of the approximate volume of water flowing in the reverse direction in the preceding period.]]></Description1>
<ObjectID>10273</ObjectID>
<ObjectURN>urn:oma:lwm2m:x:10273</ObjectURN>
<MultipleInstances>Multiple</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Resources>
<Item ID="6011">
<Name>Event Type</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Integer</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Event Type is a readable and writable resource used to represent how this event will behave. Event Type should be one of the following values:-
0. Disabled
1. Alarm Current State
2. Alarm State Change Log
3. Event Log
When the Event Type is set to Disabled (0), this event will not be recorded by the device. No Latest Eventlog payload should be delivered for events that are Disabled.
When the Event Type is set to Alarm Current State (1), this Event is treated as an alarm state manager and the Latest Eventlog Payload will only contain the current state of this alarm.
When the Event Type is set to Alarm State Change Log (2), the Event is treated as an alarm that reports whenever the Alarm is either set or cleared. The Latest Eventlog Payload will contain all alarm transitions since the previous delivery in this mode.
When the Event Type is set to Event Log (3), this object instance is treated as a raw event log. It is used to manage and deliver events. The Latest Eventlog Payload will contain all events since the previous delivery in this mode.
See the Event Log Payload for examples of each of these modes.
]]></Description>
</Item>
<Item ID="6012">
<Name>Alarm Realtime</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Boolean</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Realtime is a readable and writable resource used to indicate if an event should report immediately (1) at the point of occurrence, or delivered periodically as part of the Latest Eventlog Payload.]]></Description>
</Item>
<Item ID="6013">
<Name>Alarm State</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Boolean</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Alarm State is a read-only resource used to indicate the current alarm state for this Event configuration. This is only applicable if the Event Type is Alarm Current State (1) or Alarm State Change (2). ]]></Description>
</Item>
<Item ID="6014">
<Name>Alarm Set Threshold</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Set Threshold is a readable and writable resource used to represent the threshold for when an alarm is triggered. This resource is used in conjunction with the Set Operator resource. ]]></Description>
</Item>
<Item ID="6015">
<Name>Alarm Set Operator</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Integer</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Set Operator is a readable and writable resource used in conjunction with the Set Threshold to represent when an alarm is triggered. This resource should be set to one of the following values:-
0. Greater Than or Equal to
1. Less Than or Equal to
By setting the Set Operator to Greater Than (0), when the measured value for this event exceeds the Set Threshold resource, the event is considered to be in an Alarm State of 1
By setting the Set Operator to Less Than (1), when the measured value for this event falls below the Set Threshold resource, the event is considered to be in an Alarm State of 1]]></Description>
</Item>
<Item ID="6016">
<Name>Alarm Clear Threshold</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Clear Threshold is a readable and writable resource used to represent the threshold for when an alarm is cleared. This resource is used in conjunction with the Clear Operator resource. ]]></Description>
</Item>
<Item ID="6017">
<Name>Alarm Clear Operator</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Integer</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Clear Operator is a readable and writable resource used in conjunction with the Clear Threshold to represent when an alarm is Cleared. This resource should be set to one of the following values:-
0. Greater Than or Equal to
1. Less Than or Equal to
By setting the Clear Operator to Greater Than (0), when the measured value for this event exceeds the Clear Threshold resource, the event is considered to be in an Alarm State of 0
By setting the Clear Operator to Less Than (1), when the measured value for this event falls below the Clear Threshold resource, the event is considered to be in an Alarm State of 0]]></Description>
</Item>
<Item ID="6018">
<Name>Alarm Maximum Event Count</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Integer</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Maximum Event Count is a readable and writable resource used provide a ceiling on the number of events that can be raised within the time period defined in Maximum Event Period resource. If no Maximum Event Count is set, the number of events recorded is unconstrained. The intent of this resource is to control the number of events reported, particularly in the case of a faulty sensor.]]></Description>
</Item>
<Item ID="6019">
<Name>Alarm Maximum Event Period</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Integer</Type>
<RangeEnumeration>1..864000</RangeEnumeration>
<Units>s</Units>
<Description><![CDATA[Maximum Event Period is a readable and writable resource used in conjunction with the Maximum Event Count resource to control the number of events that can be raised in a given period. Maximum Event Period is an integer value representing the number of seconds for which the Maximum Event Count is measured. If no Maximum Event Period is set, the number of events recorded is unconstrained. The intent of this resource is to control the number of events reported, particularly in the case of a faulty sensor.]]></Description>
</Item>
<Item ID="6020">
<Name>Latest Delivered Event Time</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Time</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Latest Delivered Event Time is a readable and writable resource to represent the last recorded time that an event was delivered for this event code to the LwM2M server. The setting of this resource is implementation specific but should be updated based on, either a Read request of the Latest Eventlog Payload from the LwM2M server or via a confirmed delivery of Notify operation of the Latest Eventlog Payload resource. This resource is writable to allow the server to adjust the Last Delivered Event Time value if the server and client is out of sync.]]></Description>
</Item>
<Item ID="6021">
<Name>Latest Recorded Event Time</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Time</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Latest Recorded Event Time is a readonly resource used to represent the last recorded event time for this object instance on the device]]></Description>
</Item>
<Item ID="6022">
<Name>Alarm Clear</Name>
<Operations>E</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type></Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Clear Alarm is an executable resource used to allow the LwM2M server to clear alarms when they need to be manually acknowledged.]]></Description>
</Item>
<Item ID="6023">
<Name>Alarm Auto Clear</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Boolean</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Auto Clear Alarm is a readable and writable resource used to indicate if an alarm is automatically cleared once the delivery of the event data payload is complete ]]></Description>
</Item>
<Item ID="6024">
<Name>Event Code</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Integer</Type>
<RangeEnumeration>100..255</RangeEnumeration>
<Units></Units>
<Description><![CDATA[Event Code is a read-only resource used as an identifier to represent this class of event. The allocation of event codes is implementation specific but ideally be unique across the implementation. Event Codes use vendor specific LogClass value 100...255]]></Description>
</Item>
<Item ID="6025">
<Name>Latest Payload</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Opaque</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[The Latest Eventlog Payload resource is a read-only serialised Opaque (Binary) representation of all the Event Data between the Last Delivered Event Time and the Latest Recorded Event Time. When this payload is delivered to the LwM2M server, via either a read request or a confirmed observation on this Object, Object Instance or Resource, the Latest Delivered Interval should be updated. When no new data exists, an empty Opaque value should be provided.
The payload data can be provided in an implementation specific serialisation, but by default for fixed length values should use the OMA-LwM2M CBOR format encoded with one of these schemes:-
Event Type = Alarm Current State (1)
In this mode, only the current alarm state should be reported
1. 8-bit integer, value 2 representing OMA-LwM2M CBOR format.
2. Event Code [16-bit integer]
3. Event Type [8-bit Integer] - Alarm Current State (1)
4. Alarm Timestamp [32-bit unsigned integer] representing the number of seconds since Jan 1st, 1970 in the UTC time zone.
5. Alarm State [8-bit Integer]
]]></Description>
</Item>
</Resources>
<Description2></Description2>
</Object>
</LWM2M>

230
common/transport/lwm2m/src/main/resources/models/10274.xml

@ -1,230 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- BSD-3 Clause License
Copyright 2019 South East Water Corporation.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
-->
<LWM2M xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://openmobilealliance.org/tech/profiles/LWM2M.xsd">
<Object ObjectType="MODefinition">
<Name>Water Meter Empty Pipe Alarm</Name>
<Description1><![CDATA[An alarm when meter detects there is no liquid in the pipe]]></Description1>
<ObjectID>10274</ObjectID>
<ObjectURN>urn:oma:lwm2m:x:10274</ObjectURN>
<MultipleInstances>Multiple</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Resources>
<Item ID="6011">
<Name>Event Type</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Integer</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Event Type is a readable and writable resource used to represent how this event will behave. Event Type should be one of the following values:-
0. Disabled
1. Alarm Current State
2. Alarm State Change Log
3. Event Log
When the Event Type is set to Disabled (0), this event will not be recorded by the device. No Latest Eventlog payload should be delivered for events that are Disabled.
When the Event Type is set to Alarm Current State (1), this Event is treated as an alarm state manager and the Latest Eventlog Payload will only contain the current state of this alarm.
When the Event Type is set to Alarm State Change Log (2), the Event is treated as an alarm that reports whenever the Alarm is either set or cleared. The Latest Eventlog Payload will contain all alarm transitions since the previous delivery in this mode.
When the Event Type is set to Event Log (3), this object instance is treated as a raw event log. It is used to manage and deliver events. The Latest Eventlog Payload will contain all events since the previous delivery in this mode.
See the Event Log Payload for examples of each of these modes.
]]></Description>
</Item>
<Item ID="6012">
<Name>Alarm Realtime</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Boolean</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Realtime is a readable and writable resource used to indicate if an event should report immediately (1) at the point of occurrence, or delivered periodically as part of the Latest Eventlog Payload.]]></Description>
</Item>
<Item ID="6013">
<Name>Alarm State</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Boolean</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Alarm State is a read-only resource used to indicate the current alarm state for this Event configuration. This is only applicable if the Event Type is Alarm Current State (1) or Alarm State Change (2). ]]></Description>
</Item>
<Item ID="6014">
<Name>Alarm Set Threshold</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Set Threshold is a readable and writable resource used to represent the threshold for when an alarm is triggered. This resource is used in conjunction with the Set Operator resource. ]]></Description>
</Item>
<Item ID="6015">
<Name>Alarm Set Operator</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Integer</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Set Operator is a readable and writable resource used in conjunction with the Set Threshold to represent when an alarm is triggered. This resource should be set to one of the following values:-
0. Greater Than or Equal to
1. Less Than or Equal to
By setting the Set Operator to Greater Than (0), when the measured value for this event exceeds the Set Threshold resource, the event is considered to be in an Alarm State of 1
By setting the Set Operator to Less Than (1), when the measured value for this event falls below the Set Threshold resource, the event is considered to be in an Alarm State of 1]]></Description>
</Item>
<Item ID="6016">
<Name>Alarm Clear Threshold</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Clear Threshold is a readable and writable resource used to represent the threshold for when an alarm is cleared. This resource is used in conjunction with the Clear Operator resource. ]]></Description>
</Item>
<Item ID="6017">
<Name>Alarm Clear Operator</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Integer</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Clear Operator is a readable and writable resource used in conjunction with the Clear Threshold to represent when an alarm is Cleared. This resource should be set to one of the following values:-
0. Greater Than or Equal to
1. Less Than or Equal to
By setting the Clear Operator to Greater Than (0), when the measured value for this event exceeds the Clear Threshold resource, the event is considered to be in an Alarm State of 0
By setting the Clear Operator to Less Than (1), when the measured value for this event falls below the Clear Threshold resource, the event is considered to be in an Alarm State of 0]]></Description>
</Item>
<Item ID="6018">
<Name>Alarm Maximum Event Count</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Integer</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Maximum Event Count is a readable and writable resource used provide a ceiling on the number of events that can be raised within the time period defined in Maximum Event Period resource. If no Maximum Event Count is set, the number of events recorded is unconstrained. The intent of this resource is to control the number of events reported, particularly in the case of a faulty sensor.]]></Description>
</Item>
<Item ID="6019">
<Name>Alarm Maximum Event Period</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Integer</Type>
<RangeEnumeration>1..864000</RangeEnumeration>
<Units>s</Units>
<Description><![CDATA[Maximum Event Period is a readable and writable resource used in conjunction with the Maximum Event Count resource to control the number of events that can be raised in a given period. Maximum Event Period is an integer value representing the number of seconds for which the Maximum Event Count is measured. If no Maximum Event Period is set, the number of events recorded is unconstrained. The intent of this resource is to control the number of events reported, particularly in the case of a faulty sensor.]]></Description>
</Item>
<Item ID="6020">
<Name>Latest Delivered Event Time</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Time</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Latest Delivered Event Time is a readable and writable resource to represent the last recorded time that an event was delivered for this event code to the LwM2M server. The setting of this resource is implementation specific but should be updated based on, either a Read request of the Latest Eventlog Payload from the LwM2M server or via a confirmed delivery of Notify operation of the Latest Eventlog Payload resource. This resource is writable to allow the server to adjust the Last Delivered Event Time value if the server and client is out of sync.]]></Description>
</Item>
<Item ID="6021">
<Name>Latest Recorded Event Time</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Time</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Latest Recorded Event Time is a readonly resource used to represent the last recorded event time for this object instance on the device]]></Description>
</Item>
<Item ID="6022">
<Name>Alarm Clear</Name>
<Operations>E</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type></Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Clear Alarm is an executable resource used to allow the LwM2M server to clear alarms when they need to be manually acknowledged.]]></Description>
</Item>
<Item ID="6023">
<Name>Alarm Auto Clear</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Boolean</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Auto Clear Alarm is a readable and writable resource used to indicate if an alarm is automatically cleared once the delivery of the event data payload is complete ]]></Description>
</Item>
<Item ID="6024">
<Name>Event Code</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Integer</Type>
<RangeEnumeration>100..255</RangeEnumeration>
<Units></Units>
<Description><![CDATA[Event Code is a read-only resource used as an identifier to represent this class of event. The allocation of event codes is implementation specific but ideally be unique across the implementation. Event Codes use vendor specific LogClass value 100...255]]></Description>
</Item>
<Item ID="6025">
<Name>Latest Payload</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Opaque</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[The Latest Eventlog Payload resource is a read-only serialised Opaque (Binary) representation of all the Event Data between the Last Delivered Event Time and the Latest Recorded Event Time. When this payload is delivered to the LwM2M server, via either a read request or a confirmed observation on this Object, Object Instance or Resource, the Latest Delivered Interval should be updated. When no new data exists, an empty Opaque value should be provided.
The payload data can be provided in an implementation specific serialisation, but by default for fixed length values should use the OMA-LwM2M CBOR format encoded with one of these schemes:-
Event Type = Alarm Current State (1)
In this mode, only the current alarm state should be reported
1. 8-bit integer, value 2 representing OMA-LwM2M CBOR format.
2. Event Code [16-bit integer]
3. Event Type [8-bit Integer] - Alarm Current State (1)
4. Alarm Timestamp [32-bit unsigned integer] representing the number of seconds since Jan 1st, 1970 in the UTC time zone.
5. Alarm State [8-bit Integer]
]]></Description>
</Item>
</Resources>
<Description2></Description2>
</Object>
</LWM2M>

230
common/transport/lwm2m/src/main/resources/models/10275.xml

@ -1,230 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- BSD-3 Clause License
Copyright 2019 South East Water Corporation.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
-->
<LWM2M xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://openmobilealliance.org/tech/profiles/LWM2M.xsd">
<Object ObjectType="MODefinition">
<Name>Water Meter Tamper Alarm</Name>
<Description1><![CDATA[Detects interference from strong magnetic field or other electrical sources. If this is not relevant for ultrasonic meters then the tamper alarm may be used to indicate someone attempting to open the physical enclosure or other options the manufacturer may present.]]></Description1>
<ObjectID>10275</ObjectID>
<ObjectURN>urn:oma:lwm2m:x:10275</ObjectURN>
<MultipleInstances>Multiple</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Resources>
<Item ID="6011">
<Name>Event Type</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Integer</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Event Type is a readable and writable resource used to represent how this event will behave. Event Type should be one of the following values:-
0. Disabled
1. Alarm Current State
2. Alarm State Change Log
3. Event Log
When the Event Type is set to Disabled (0), this event will not be recorded by the device. No Latest Eventlog payload should be delivered for events that are Disabled.
When the Event Type is set to Alarm Current State (1), this Event is treated as an alarm state manager and the Latest Eventlog Payload will only contain the current state of this alarm.
When the Event Type is set to Alarm State Change Log (2), the Event is treated as an alarm that reports whenever the Alarm is either set or cleared. The Latest Eventlog Payload will contain all alarm transitions since the previous delivery in this mode.
When the Event Type is set to Event Log (3), this object instance is treated as a raw event log. It is used to manage and deliver events. The Latest Eventlog Payload will contain all events since the previous delivery in this mode.
See the Event Log Payload for examples of each of these modes.
]]></Description>
</Item>
<Item ID="6012">
<Name>Alarm Realtime</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Boolean</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Realtime is a readable and writable resource used to indicate if an event should report immediately (1) at the point of occurrence, or delivered periodically as part of the Latest Eventlog Payload.]]></Description>
</Item>
<Item ID="6013">
<Name>Alarm State</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Boolean</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Alarm State is a read-only resource used to indicate the current alarm state for this Event configuration. This is only applicable if the Event Type is Alarm Current State (1) or Alarm State Change (2). ]]></Description>
</Item>
<Item ID="6014">
<Name>Alarm Set Threshold</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Set Threshold is a readable and writable resource used to represent the threshold for when an alarm is triggered. This resource is used in conjunction with the Set Operator resource. ]]></Description>
</Item>
<Item ID="6015">
<Name>Alarm Set Operator</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Integer</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Set Operator is a readable and writable resource used in conjunction with the Set Threshold to represent when an alarm is triggered. This resource should be set to one of the following values:-
0. Greater Than or Equal to
1. Less Than or Equal to
By setting the Set Operator to Greater Than (0), when the measured value for this event exceeds the Set Threshold resource, the event is considered to be in an Alarm State of 1
By setting the Set Operator to Less Than (1), when the measured value for this event falls below the Set Threshold resource, the event is considered to be in an Alarm State of 1]]></Description>
</Item>
<Item ID="6016">
<Name>Alarm Clear Threshold</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Clear Threshold is a readable and writable resource used to represent the threshold for when an alarm is cleared. This resource is used in conjunction with the Clear Operator resource. ]]></Description>
</Item>
<Item ID="6017">
<Name>Alarm Clear Operator</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Integer</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Clear Operator is a readable and writable resource used in conjunction with the Clear Threshold to represent when an alarm is Cleared. This resource should be set to one of the following values:-
0. Greater Than or Equal to
1. Less Than or Equal to
By setting the Clear Operator to Greater Than (0), when the measured value for this event exceeds the Clear Threshold resource, the event is considered to be in an Alarm State of 0
By setting the Clear Operator to Less Than (1), when the measured value for this event falls below the Clear Threshold resource, the event is considered to be in an Alarm State of 0]]></Description>
</Item>
<Item ID="6018">
<Name>Alarm Maximum Event Count</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Integer</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Maximum Event Count is a readable and writable resource used provide a ceiling on the number of events that can be raised within the time period defined in Maximum Event Period resource. If no Maximum Event Count is set, the number of events recorded is unconstrained. The intent of this resource is to control the number of events reported, particularly in the case of a faulty sensor.]]></Description>
</Item>
<Item ID="6019">
<Name>Alarm Maximum Event Period</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Integer</Type>
<RangeEnumeration>1..864000</RangeEnumeration>
<Units>s</Units>
<Description><![CDATA[Maximum Event Period is a readable and writable resource used in conjunction with the Maximum Event Count resource to control the number of events that can be raised in a given period. Maximum Event Period is an integer value representing the number of seconds for which the Maximum Event Count is measured. If no Maximum Event Period is set, the number of events recorded is unconstrained. The intent of this resource is to control the number of events reported, particularly in the case of a faulty sensor.]]></Description>
</Item>
<Item ID="6020">
<Name>Latest Delivered Event Time</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Time</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Latest Delivered Event Time is a readable and writable resource to represent the last recorded time that an event was delivered for this event code to the LwM2M server. The setting of this resource is implementation specific but should be updated based on, either a Read request of the Latest Eventlog Payload from the LwM2M server or via a confirmed delivery of Notify operation of the Latest Eventlog Payload resource. This resource is writable to allow the server to adjust the Last Delivered Event Time value if the server and client is out of sync.]]></Description>
</Item>
<Item ID="6021">
<Name>Latest Recorded Event Time</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Time</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Latest Recorded Event Time is a readonly resource used to represent the last recorded event time for this object instance on the device]]></Description>
</Item>
<Item ID="6022">
<Name>Alarm Clear</Name>
<Operations>E</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type></Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Clear Alarm is an executable resource used to allow the LwM2M server to clear alarms when they need to be manually acknowledged.]]></Description>
</Item>
<Item ID="6023">
<Name>Alarm Auto Clear</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Boolean</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Auto Clear Alarm is a readable and writable resource used to indicate if an alarm is automatically cleared once the delivery of the event data payload is complete ]]></Description>
</Item>
<Item ID="6024">
<Name>Event Code</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Integer</Type>
<RangeEnumeration>100..255</RangeEnumeration>
<Units></Units>
<Description><![CDATA[Event Code is a read-only resource used as an identifier to represent this class of event. The allocation of event codes is implementation specific but ideally be unique across the implementation. Event Codes use vendor specific LogClass value 100...255]]></Description>
</Item>
<Item ID="6025">
<Name>Latest Payload</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Opaque</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[The Latest Eventlog Payload resource is a read-only serialised Opaque (Binary) representation of all the Event Data between the Last Delivered Event Time and the Latest Recorded Event Time. When this payload is delivered to the LwM2M server, via either a read request or a confirmed observation on this Object, Object Instance or Resource, the Latest Delivered Interval should be updated. When no new data exists, an empty Opaque value should be provided.
The payload data can be provided in an implementation specific serialisation, but by default for fixed length values should use the OMA-LwM2M CBOR format encoded with one of these schemes:-
Event Type = Alarm Current State (1)
In this mode, only the current alarm state should be reported
1. 8-bit integer, value 2 representing OMA-LwM2M CBOR format.
2. Event Code [16-bit integer]
3. Event Type [8-bit Integer] - Alarm Current State (1)
4. Alarm Timestamp [32-bit unsigned integer] representing the number of seconds since Jan 1st, 1970 in the UTC time zone.
5. Alarm State [8-bit Integer]
]]></Description>
</Item>
</Resources>
<Description2></Description2>
</Object>
</LWM2M>

230
common/transport/lwm2m/src/main/resources/models/10276.xml

@ -1,230 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- BSD-3 Clause License
Copyright 2019 South East Water Corporation.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
-->
<LWM2M xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://openmobilealliance.org/tech/profiles/LWM2M.xsd">
<Object ObjectType="MODefinition">
<Name>Water Meter High Pressure Alarm</Name>
<Description1><![CDATA[Where supported by the meter this is an alarm that should be raised if the meter detects pressure above a pre-configured threshold.]]></Description1>
<ObjectID>10276</ObjectID>
<ObjectURN>urn:oma:lwm2m:x:10276</ObjectURN>
<MultipleInstances>Multiple</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Resources>
<Item ID="6011">
<Name>Event Type</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Integer</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Event Type is a readable and writable resource used to represent how this event will behave. Event Type should be one of the following values:-
0. Disabled
1. Alarm Current State
2. Alarm State Change Log
3. Event Log
When the Event Type is set to Disabled (0), this event will not be recorded by the device. No Latest Eventlog payload should be delivered for events that are Disabled.
When the Event Type is set to Alarm Current State (1), this Event is treated as an alarm state manager and the Latest Eventlog Payload will only contain the current state of this alarm.
When the Event Type is set to Alarm State Change Log (2), the Event is treated as an alarm that reports whenever the Alarm is either set or cleared. The Latest Eventlog Payload will contain all alarm transitions since the previous delivery in this mode.
When the Event Type is set to Event Log (3), this object instance is treated as a raw event log. It is used to manage and deliver events. The Latest Eventlog Payload will contain all events since the previous delivery in this mode.
See the Event Log Payload for examples of each of these modes.
]]></Description>
</Item>
<Item ID="6012">
<Name>Alarm Realtime</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Boolean</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Realtime is a readable and writable resource used to indicate if an event should report immediately (1) at the point of occurrence, or delivered periodically as part of the Latest Eventlog Payload.]]></Description>
</Item>
<Item ID="6013">
<Name>Alarm State</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Boolean</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Alarm State is a read-only resource used to indicate the current alarm state for this Event configuration. This is only applicable if the Event Type is Alarm Current State (1) or Alarm State Change (2). ]]></Description>
</Item>
<Item ID="6014">
<Name>Alarm Set Threshold</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Set Threshold is a readable and writable resource used to represent the threshold for when an alarm is triggered. This resource is used in conjunction with the Set Operator resource. ]]></Description>
</Item>
<Item ID="6015">
<Name>Alarm Set Operator</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Integer</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Set Operator is a readable and writable resource used in conjunction with the Set Threshold to represent when an alarm is triggered. This resource should be set to one of the following values:-
0. Greater Than or Equal to
1. Less Than or Equal to
By setting the Set Operator to Greater Than (0), when the measured value for this event exceeds the Set Threshold resource, the event is considered to be in an Alarm State of 1
By setting the Set Operator to Less Than (1), when the measured value for this event falls below the Set Threshold resource, the event is considered to be in an Alarm State of 1]]></Description>
</Item>
<Item ID="6016">
<Name>Alarm Clear Threshold</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Clear Threshold is a readable and writable resource used to represent the threshold for when an alarm is cleared. This resource is used in conjunction with the Clear Operator resource. ]]></Description>
</Item>
<Item ID="6017">
<Name>Alarm Clear Operator</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Integer</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Clear Operator is a readable and writable resource used in conjunction with the Clear Threshold to represent when an alarm is Cleared. This resource should be set to one of the following values:-
0. Greater Than or Equal to
1. Less Than or Equal to
By setting the Clear Operator to Greater Than (0), when the measured value for this event exceeds the Clear Threshold resource, the event is considered to be in an Alarm State of 0
By setting the Clear Operator to Less Than (1), when the measured value for this event falls below the Clear Threshold resource, the event is considered to be in an Alarm State of 0]]></Description>
</Item>
<Item ID="6018">
<Name>Alarm Maximum Event Count</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Integer</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Maximum Event Count is a readable and writable resource used provide a ceiling on the number of events that can be raised within the time period defined in Maximum Event Period resource. If no Maximum Event Count is set, the number of events recorded is unconstrained. The intent of this resource is to control the number of events reported, particularly in the case of a faulty sensor.]]></Description>
</Item>
<Item ID="6019">
<Name>Alarm Maximum Event Period</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Integer</Type>
<RangeEnumeration>1..864000</RangeEnumeration>
<Units>s</Units>
<Description><![CDATA[Maximum Event Period is a readable and writable resource used in conjunction with the Maximum Event Count resource to control the number of events that can be raised in a given period. Maximum Event Period is an integer value representing the number of seconds for which the Maximum Event Count is measured. If no Maximum Event Period is set, the number of events recorded is unconstrained. The intent of this resource is to control the number of events reported, particularly in the case of a faulty sensor.]]></Description>
</Item>
<Item ID="6020">
<Name>Latest Delivered Event Time</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Time</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Latest Delivered Event Time is a readable and writable resource to represent the last recorded time that an event was delivered for this event code to the LwM2M server. The setting of this resource is implementation specific but should be updated based on, either a Read request of the Latest Eventlog Payload from the LwM2M server or via a confirmed delivery of Notify operation of the Latest Eventlog Payload resource. This resource is writable to allow the server to adjust the Last Delivered Event Time value if the server and client is out of sync.]]></Description>
</Item>
<Item ID="6021">
<Name>Latest Recorded Event Time</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Time</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Latest Recorded Event Time is a readonly resource used to represent the last recorded event time for this object instance on the device]]></Description>
</Item>
<Item ID="6022">
<Name>Alarm Clear</Name>
<Operations>E</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type></Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Clear Alarm is an executable resource used to allow the LwM2M server to clear alarms when they need to be manually acknowledged.]]></Description>
</Item>
<Item ID="6023">
<Name>Alarm Auto Clear</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Boolean</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Auto Clear Alarm is a readable and writable resource used to indicate if an alarm is automatically cleared once the delivery of the event data payload is complete ]]></Description>
</Item>
<Item ID="6024">
<Name>Event Code</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Integer</Type>
<RangeEnumeration>100..255</RangeEnumeration>
<Units></Units>
<Description><![CDATA[Event Code is a read-only resource used as an identifier to represent this class of event. The allocation of event codes is implementation specific but ideally be unique across the implementation. Event Codes use vendor specific LogClass value 100...255]]></Description>
</Item>
<Item ID="6025">
<Name>Latest Payload</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Opaque</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[The Latest Eventlog Payload resource is a read-only serialised Opaque (Binary) representation of all the Event Data between the Last Delivered Event Time and the Latest Recorded Event Time. When this payload is delivered to the LwM2M server, via either a read request or a confirmed observation on this Object, Object Instance or Resource, the Latest Delivered Interval should be updated. When no new data exists, an empty Opaque value should be provided.
The payload data can be provided in an implementation specific serialisation, but by default for fixed length values should use the OMA-LwM2M CBOR format encoded with one of these schemes:-
Event Type = Alarm Current State (1)
In this mode, only the current alarm state should be reported
1. 8-bit integer, value 2 representing OMA-LwM2M CBOR format.
2. Event Code [16-bit integer]
3. Event Type [8-bit Integer] - Alarm Current State (1)
4. Alarm Timestamp [32-bit unsigned integer] representing the number of seconds since Jan 1st, 1970 in the UTC time zone.
5. Alarm State [8-bit Integer]
]]></Description>
</Item>
</Resources>
<Description2></Description2>
</Object>
</LWM2M>

230
common/transport/lwm2m/src/main/resources/models/10277.xml

@ -1,230 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- BSD-3 Clause License
Copyright 2019 South East Water Corporation.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
-->
<LWM2M xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://openmobilealliance.org/tech/profiles/LWM2M.xsd">
<Object ObjectType="MODefinition">
<Name>Water Meter Low Pressure Alarm</Name>
<Description1><![CDATA[Where supported by the meter this is an alarm that should be raised if the meter detects pressure below a pre-configured threshold.]]></Description1>
<ObjectID>10277</ObjectID>
<ObjectURN>urn:oma:lwm2m:x:10277</ObjectURN>
<MultipleInstances>Multiple</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Resources>
<Item ID="6011">
<Name>Event Type</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Integer</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Event Type is a readable and writable resource used to represent how this event will behave. Event Type should be one of the following values:-
0. Disabled
1. Alarm Current State
2. Alarm State Change Log
3. Event Log
When the Event Type is set to Disabled (0), this event will not be recorded by the device. No Latest Eventlog payload should be delivered for events that are Disabled.
When the Event Type is set to Alarm Current State (1), this Event is treated as an alarm state manager and the Latest Eventlog Payload will only contain the current state of this alarm.
When the Event Type is set to Alarm State Change Log (2), the Event is treated as an alarm that reports whenever the Alarm is either set or cleared. The Latest Eventlog Payload will contain all alarm transitions since the previous delivery in this mode.
When the Event Type is set to Event Log (3), this object instance is treated as a raw event log. It is used to manage and deliver events. The Latest Eventlog Payload will contain all events since the previous delivery in this mode.
See the Event Log Payload for examples of each of these modes.
]]></Description>
</Item>
<Item ID="6012">
<Name>Alarm Realtime</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Boolean</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Realtime is a readable and writable resource used to indicate if an event should report immediately (1) at the point of occurrence, or delivered periodically as part of the Latest Eventlog Payload.]]></Description>
</Item>
<Item ID="6013">
<Name>Alarm State</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Boolean</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Alarm State is a read-only resource used to indicate the current alarm state for this Event configuration. This is only applicable if the Event Type is Alarm Current State (1) or Alarm State Change (2). ]]></Description>
</Item>
<Item ID="6014">
<Name>Alarm Set Threshold</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Set Threshold is a readable and writable resource used to represent the threshold for when an alarm is triggered. This resource is used in conjunction with the Set Operator resource. ]]></Description>
</Item>
<Item ID="6015">
<Name>Alarm Set Operator</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Integer</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Set Operator is a readable and writable resource used in conjunction with the Set Threshold to represent when an alarm is triggered. This resource should be set to one of the following values:-
0. Greater Than or Equal to
1. Less Than or Equal to
By setting the Set Operator to Greater Than (0), when the measured value for this event exceeds the Set Threshold resource, the event is considered to be in an Alarm State of 1
By setting the Set Operator to Less Than (1), when the measured value for this event falls below the Set Threshold resource, the event is considered to be in an Alarm State of 1]]></Description>
</Item>
<Item ID="6016">
<Name>Alarm Clear Threshold</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Clear Threshold is a readable and writable resource used to represent the threshold for when an alarm is cleared. This resource is used in conjunction with the Clear Operator resource. ]]></Description>
</Item>
<Item ID="6017">
<Name>Alarm Clear Operator</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Integer</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Clear Operator is a readable and writable resource used in conjunction with the Clear Threshold to represent when an alarm is Cleared. This resource should be set to one of the following values:-
0. Greater Than or Equal to
1. Less Than or Equal to
By setting the Clear Operator to Greater Than (0), when the measured value for this event exceeds the Clear Threshold resource, the event is considered to be in an Alarm State of 0
By setting the Clear Operator to Less Than (1), when the measured value for this event falls below the Clear Threshold resource, the event is considered to be in an Alarm State of 0]]></Description>
</Item>
<Item ID="6018">
<Name>Alarm Maximum Event Count</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Integer</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Maximum Event Count is a readable and writable resource used provide a ceiling on the number of events that can be raised within the time period defined in Maximum Event Period resource. If no Maximum Event Count is set, the number of events recorded is unconstrained. The intent of this resource is to control the number of events reported, particularly in the case of a faulty sensor.]]></Description>
</Item>
<Item ID="6019">
<Name>Alarm Maximum Event Period</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Integer</Type>
<RangeEnumeration>1..864000</RangeEnumeration>
<Units>s</Units>
<Description><![CDATA[Maximum Event Period is a readable and writable resource used in conjunction with the Maximum Event Count resource to control the number of events that can be raised in a given period. Maximum Event Period is an integer value representing the number of seconds for which the Maximum Event Count is measured. If no Maximum Event Period is set, the number of events recorded is unconstrained. The intent of this resource is to control the number of events reported, particularly in the case of a faulty sensor.]]></Description>
</Item>
<Item ID="6020">
<Name>Latest Delivered Event Time</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Time</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Latest Delivered Event Time is a readable and writable resource to represent the last recorded time that an event was delivered for this event code to the LwM2M server. The setting of this resource is implementation specific but should be updated based on, either a Read request of the Latest Eventlog Payload from the LwM2M server or via a confirmed delivery of Notify operation of the Latest Eventlog Payload resource. This resource is writable to allow the server to adjust the Last Delivered Event Time value if the server and client is out of sync.]]></Description>
</Item>
<Item ID="6021">
<Name>Latest Recorded Event Time</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Time</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Latest Recorded Event Time is a readonly resource used to represent the last recorded event time for this object instance on the device]]></Description>
</Item>
<Item ID="6022">
<Name>Alarm Clear</Name>
<Operations>E</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type></Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Clear Alarm is an executable resource used to allow the LwM2M server to clear alarms when they need to be manually acknowledged.]]></Description>
</Item>
<Item ID="6023">
<Name>Alarm Auto Clear</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Boolean</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Auto Clear Alarm is a readable and writable resource used to indicate if an alarm is automatically cleared once the delivery of the event data payload is complete ]]></Description>
</Item>
<Item ID="6024">
<Name>Event Code</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Integer</Type>
<RangeEnumeration>100..255</RangeEnumeration>
<Units></Units>
<Description><![CDATA[Event Code is a read-only resource used as an identifier to represent this class of event. The allocation of event codes is implementation specific but ideally be unique across the implementation. Event Codes use vendor specific LogClass value 100...255]]></Description>
</Item>
<Item ID="6025">
<Name>Latest Payload</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Opaque</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[The Latest Eventlog Payload resource is a read-only serialised Opaque (Binary) representation of all the Event Data between the Last Delivered Event Time and the Latest Recorded Event Time. When this payload is delivered to the LwM2M server, via either a read request or a confirmed observation on this Object, Object Instance or Resource, the Latest Delivered Interval should be updated. When no new data exists, an empty Opaque value should be provided.
The payload data can be provided in an implementation specific serialisation, but by default for fixed length values should use the OMA-LwM2M CBOR format encoded with one of these schemes:-
Event Type = Alarm Current State (1)
In this mode, only the current alarm state should be reported
1. 8-bit integer, value 2 representing OMA-LwM2M CBOR format.
2. Event Code [16-bit integer]
3. Event Type [8-bit Integer] - Alarm Current State (1)
4. Alarm Timestamp [32-bit unsigned integer] representing the number of seconds since Jan 1st, 1970 in the UTC time zone.
5. Alarm State [8-bit Integer]
]]></Description>
</Item>
</Resources>
<Description2></Description2>
</Object>
</LWM2M>

230
common/transport/lwm2m/src/main/resources/models/10278.xml

@ -1,230 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- BSD-3 Clause License
Copyright 2019 South East Water Corporation.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
-->
<LWM2M xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://openmobilealliance.org/tech/profiles/LWM2M.xsd">
<Object ObjectType="MODefinition">
<Name>High Temperature Alarm</Name>
<Description1><![CDATA[Where supported by the meter this is an alarm that should be raised if the meter detects temperature above a pre-configured threshold. When the temperature drops below the clear threshold, the alarm should be cleared.]]></Description1>
<ObjectID>10278</ObjectID>
<ObjectURN>urn:oma:lwm2m:x:10278</ObjectURN>
<MultipleInstances>Multiple</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Resources>
<Item ID="6011">
<Name>Event Type</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Integer</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Event Type is a readable and writable resource used to represent how this event will behave. Event Type should be one of the following values:-
0. Disabled
1. Alarm Current State
2. Alarm State Change Log
3. Event Log
When the Event Type is set to Disabled (0), this event will not be recorded by the device. No Latest Eventlog payload should be delivered for events that are Disabled.
When the Event Type is set to Alarm Current State (1), this Event is treated as an alarm state manager and the Latest Eventlog Payload will only contain the current state of this alarm.
When the Event Type is set to Alarm State Change Log (2), the Event is treated as an alarm that reports whenever the Alarm is either set or cleared. The Latest Eventlog Payload will contain all alarm transitions since the previous delivery in this mode.
When the Event Type is set to Event Log (3), this object instance is treated as a raw event log. It is used to manage and deliver events. The Latest Eventlog Payload will contain all events since the previous delivery in this mode.
See the Event Log Payload for examples of each of these modes.
]]></Description>
</Item>
<Item ID="6012">
<Name>Alarm Realtime</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Boolean</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Realtime is a readable and writable resource used to indicate if an event should report immediately (1) at the point of occurrence, or delivered periodically as part of the Latest Eventlog Payload.]]></Description>
</Item>
<Item ID="6013">
<Name>Alarm State</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Boolean</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Alarm State is a read-only resource used to indicate the current alarm state for this Event configuration. This is only applicable if the Event Type is Alarm Current State (1) or Alarm State Change (2). ]]></Description>
</Item>
<Item ID="6014">
<Name>Alarm Set Threshold</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Set Threshold is a readable and writable resource used to represent the threshold for when an alarm is triggered. This resource is used in conjunction with the Set Operator resource. ]]></Description>
</Item>
<Item ID="6015">
<Name>Alarm Set Operator</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Integer</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Set Operator is a readable and writable resource used in conjunction with the Set Threshold to represent when an alarm is triggered. This resource should be set to one of the following values:-
0. Greater Than or Equal to
1. Less Than or Equal to
By setting the Set Operator to Greater Than (0), when the measured value for this event exceeds the Set Threshold resource, the event is considered to be in an Alarm State of 1
By setting the Set Operator to Less Than (1), when the measured value for this event falls below the Set Threshold resource, the event is considered to be in an Alarm State of 1]]></Description>
</Item>
<Item ID="6016">
<Name>Alarm Clear Threshold</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Float</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Clear Threshold is a readable and writable resource used to represent the threshold for when an alarm is cleared. This resource is used in conjunction with the Clear Operator resource. ]]></Description>
</Item>
<Item ID="6017">
<Name>Alarm Clear Operator</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Integer</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Clear Operator is a readable and writable resource used in conjunction with the Clear Threshold to represent when an alarm is Cleared. This resource should be set to one of the following values:-
0. Greater Than or Equal to
1. Less Than or Equal to
By setting the Clear Operator to Greater Than (0), when the measured value for this event exceeds the Clear Threshold resource, the event is considered to be in an Alarm State of 0
By setting the Clear Operator to Less Than (1), when the measured value for this event falls below the Clear Threshold resource, the event is considered to be in an Alarm State of 0]]></Description>
</Item>
<Item ID="6018">
<Name>Alarm Maximum Event Count</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Integer</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Maximum Event Count is a readable and writable resource used provide a ceiling on the number of events that can be raised within the time period defined in Maximum Event Period resource. If no Maximum Event Count is set, the number of events recorded is unconstrained. The intent of this resource is to control the number of events reported, particularly in the case of a faulty sensor.]]></Description>
</Item>
<Item ID="6019">
<Name>Alarm Maximum Event Period</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Integer</Type>
<RangeEnumeration>1..864000</RangeEnumeration>
<Units>s</Units>
<Description><![CDATA[Maximum Event Period is a readable and writable resource used in conjunction with the Maximum Event Count resource to control the number of events that can be raised in a given period. Maximum Event Period is an integer value representing the number of seconds for which the Maximum Event Count is measured. If no Maximum Event Period is set, the number of events recorded is unconstrained. The intent of this resource is to control the number of events reported, particularly in the case of a faulty sensor.]]></Description>
</Item>
<Item ID="6020">
<Name>Latest Delivered Event Time</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Time</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Latest Delivered Event Time is a readable and writable resource to represent the last recorded time that an event was delivered for this event code to the LwM2M server. The setting of this resource is implementation specific but should be updated based on, either a Read request of the Latest Eventlog Payload from the LwM2M server or via a confirmed delivery of Notify operation of the Latest Eventlog Payload resource. This resource is writable to allow the server to adjust the Last Delivered Event Time value if the server and client is out of sync.]]></Description>
</Item>
<Item ID="6021">
<Name>Latest Recorded Event Time</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Time</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Latest Recorded Event Time is a readonly resource used to represent the last recorded event time for this object instance on the device]]></Description>
</Item>
<Item ID="6022">
<Name>Alarm Clear</Name>
<Operations>E</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type></Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Clear Alarm is an executable resource used to allow the LwM2M server to clear alarms when they need to be manually acknowledged.]]></Description>
</Item>
<Item ID="6023">
<Name>Alarm Auto Clear</Name>
<Operations>RW</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Optional</Mandatory>
<Type>Boolean</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[Auto Clear Alarm is a readable and writable resource used to indicate if an alarm is automatically cleared once the delivery of the event data payload is complete ]]></Description>
</Item>
<Item ID="6024">
<Name>Event Code</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Integer</Type>
<RangeEnumeration>100..255</RangeEnumeration>
<Units></Units>
<Description><![CDATA[Event Code is a read-only resource used as an identifier to represent this class of event. The allocation of event codes is implementation specific but ideally be unique across the implementation. Event Codes use vendor specific LogClass value 100...255]]></Description>
</Item>
<Item ID="6025">
<Name>Latest Payload</Name>
<Operations>R</Operations>
<MultipleInstances>Single</MultipleInstances>
<Mandatory>Mandatory</Mandatory>
<Type>Opaque</Type>
<RangeEnumeration></RangeEnumeration>
<Units></Units>
<Description><![CDATA[The Latest Eventlog Payload resource is a read-only serialised Opaque (Binary) representation of all the Event Data between the Last Delivered Event Time and the Latest Recorded Event Time. When this payload is delivered to the LwM2M server, via either a read request or a confirmed observation on this Object, Object Instance or Resource, the Latest Delivered Interval should be updated. When no new data exists, an empty Opaque value should be provided.
The payload data can be provided in an implementation specific serialisation, but by default for fixed length values should use the OMA-LwM2M CBOR format encoded with one of these schemes:-
Event Type = Alarm Current State (1)
In this mode, only the current alarm state should be reported
1. 8-bit integer, value 2 representing OMA-LwM2M CBOR format.
2. Event Code [16-bit integer]
3. Event Type [8-bit Integer] - Alarm Current State (1)
4. Alarm Timestamp [32-bit unsigned integer] representing the number of seconds since Jan 1st, 1970 in the UTC time zone.
5. Alarm State [8-bit Integer]
]]></Description>
</Item>
</Resources>
<Description2></Description2>
</Object>
</LWM2M>

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save