574 changed files with 204 additions and 70717 deletions
@ -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); |
|||
} |
|||
} |
|||
} |
|||
@ -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; |
|||
} |
|||
} |
|||
|
|||
@ -1,10 +1,3 @@ |
|||
______ __ _ __ __ |
|||
/_ __/ / /_ (_) ____ ____ _ _____ / /_ ____ ____ _ _____ ____/ / |
|||
/ / / __ \ / / / __ \ / __ `/ / ___/ / __ \ / __ \ / __ `/ / ___/ / __ / |
|||
/ / / / / / / / / / / / / /_/ / (__ ) / /_/ // /_/ // /_/ / / / / /_/ / |
|||
/_/ /_/ /_/ /_/ /_/ /_/ \__, / /____/ /_.___/ \____/ \__,_/ /_/ \__,_/ |
|||
/____/ |
|||
|
|||
=================================================== |
|||
:: ${application.title} :: ${application.formatted-version} |
|||
=================================================== |
|||
|
|||
@ -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; |
|||
|
|||
} |
|||
@ -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; |
|||
} |
|||
@ -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; |
|||
} |
|||
} |
|||
@ -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; |
|||
} |
|||
@ -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> |
|||
@ -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(); |
|||
} |
|||
} |
|||
@ -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!"); |
|||
} |
|||
} |
|||
@ -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; |
|||
} |
|||
} |
|||
@ -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; |
|||
} |
|||
} |
|||
@ -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())); |
|||
} |
|||
} |
|||
@ -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"; |
|||
} |
|||
@ -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); |
|||
} |
|||
} |
|||
@ -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; |
|||
} |
|||
} |
|||
@ -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();
|
|||
// }
|
|||
// }
|
|||
} |
|||
@ -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; |
|||
} |
|||
} |
|||
@ -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())); |
|||
} |
|||
} |
|||
} |
|||
|
|||
@ -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); |
|||
} |
|||
} |
|||
@ -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)); |
|||
} |
|||
} |
|||
@ -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); |
|||
} |
|||
} |
|||
} |
|||
@ -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; |
|||
} |
|||
@ -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); |
|||
} |
|||
} |
|||
@ -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; |
|||
} |
|||
} |
|||
@ -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, ""); |
|||
} |
|||
} |
|||
@ -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>=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); |
|||
} |
|||
} |
|||
} |
|||
@ -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(); |
|||
} |
|||
} |
|||
@ -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!"); |
|||
} |
|||
} |
|||
@ -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); |
|||
} |
|||
} |
|||
|
|||
} |
|||
@ -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()); |
|||
} |
|||
}; |
|||
} |
|||
@ -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; |
|||
} |
|||
} |
|||
} |
|||
@ -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); |
|||
} |
|||
} |
|||
} |
|||
@ -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; |
|||
} |
|||
@ -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; |
|||
} |
|||
@ -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); |
|||
} |
|||
} |
|||
}); |
|||
} |
|||
} |
|||
@ -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); |
|||
} |
|||
} |
|||
@ -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; |
|||
} |
|||
@ -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(); |
|||
} |
|||
} |
|||
@ -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)."); |
|||
} |
|||
} |
|||
} |
|||
@ -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); |
|||
} |
|||
|
|||
} |
|||
@ -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); |
|||
} |
|||
} |
|||
@ -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; |
|||
} |
|||
} |
|||
Binary file not shown.
@ -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 |
|||
@ -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` |
|||
@ -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> |
|||
@ -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> |
|||
@ -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> |
|||
@ -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> |
|||
@ -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> |
|||
@ -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> |
|||
@ -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> |
|||
@ -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> |
|||
@ -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> |
|||
@ -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> |
|||
@ -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> |
|||
@ -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> |
|||
@ -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> |
|||
@ -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> |
|||
@ -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> |
|||
@ -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> |
|||
@ -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> |
|||
@ -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> |
|||
@ -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> |
|||
@ -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> |
|||
@ -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> |
|||
|
|||
@ -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> |
|||
|
|||
@ -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> |
|||
|
|||
@ -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> |
|||
|
|||
@ -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> |
|||
|
|||
@ -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> |
|||
|
|||
@ -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> |
|||
|
|||
@ -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> |
|||
|
|||
@ -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> |
|||
|
|||
@ -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> |
|||
|
|||
@ -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> |
|||
|
|||
@ -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> |
|||
|
|||
@ -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> |
|||
|
|||
@ -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> |
|||
|
|||
@ -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> |
|||
|
|||
@ -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> |
|||
|
|||
@ -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…
Reference in new issue