|
|
|
@ -21,7 +21,10 @@ import lombok.Setter; |
|
|
|
import lombok.ToString; |
|
|
|
import lombok.extern.slf4j.Slf4j; |
|
|
|
import org.eclipse.leshan.core.LwM2m; |
|
|
|
import org.eclipse.leshan.core.LwM2m.Version; |
|
|
|
import org.eclipse.leshan.core.link.Link; |
|
|
|
import org.eclipse.leshan.core.link.attributes.Attribute; |
|
|
|
import org.eclipse.leshan.core.link.lwm2m.MixedLwM2mLink; |
|
|
|
import org.eclipse.leshan.core.model.ObjectModel; |
|
|
|
import org.eclipse.leshan.core.model.ResourceModel; |
|
|
|
import org.eclipse.leshan.core.node.LwM2mMultipleResource; |
|
|
|
@ -37,6 +40,7 @@ import org.thingsboard.server.common.data.Device; |
|
|
|
import org.thingsboard.server.common.data.DeviceProfile; |
|
|
|
import org.thingsboard.server.common.data.device.data.Lwm2mDeviceTransportConfiguration; |
|
|
|
import org.thingsboard.server.common.data.device.data.PowerMode; |
|
|
|
import org.thingsboard.server.common.data.device.profile.Lwm2mDeviceProfileTransportConfiguration; |
|
|
|
import org.thingsboard.server.common.data.id.TenantId; |
|
|
|
import org.thingsboard.server.common.transport.auth.ValidateDeviceCredentialsResponse; |
|
|
|
import org.thingsboard.server.gen.transport.TransportProtos.SessionInfoProto; |
|
|
|
@ -61,8 +65,8 @@ import java.util.stream.Collectors; |
|
|
|
import java.util.stream.Stream; |
|
|
|
|
|
|
|
import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPARATOR_PATH; |
|
|
|
import static org.thingsboard.server.transport.lwm2m.utils.LwM2MTransportUtil.LWM2M_OBJECT_VERSION_DEFAULT; |
|
|
|
import static org.thingsboard.server.transport.lwm2m.utils.LwM2MTransportUtil.convertMultiResourceValuesFromRpcBody; |
|
|
|
import static org.thingsboard.server.transport.lwm2m.utils.LwM2MTransportUtil.convertObjectIdToVersionedId; |
|
|
|
import static org.thingsboard.server.transport.lwm2m.utils.LwM2MTransportUtil.equalsResourceTypeGetSimpleName; |
|
|
|
import static org.thingsboard.server.transport.lwm2m.utils.LwM2MTransportUtil.fromVersionedIdToObjectId; |
|
|
|
import static org.thingsboard.server.transport.lwm2m.utils.LwM2MTransportUtil.getVerFromPathIdVerOrId; |
|
|
|
@ -129,6 +133,12 @@ public class LwM2mClient { |
|
|
|
@Setter |
|
|
|
private UUID lastSentRpcId; |
|
|
|
|
|
|
|
@Setter |
|
|
|
private LwM2m.Version defaultObjectIDVer; |
|
|
|
|
|
|
|
@Getter |
|
|
|
private Map<Integer, Version> supportedClientObjects; |
|
|
|
|
|
|
|
public Object clone() throws CloneNotSupportedException { |
|
|
|
return super.clone(); |
|
|
|
} |
|
|
|
@ -142,6 +152,7 @@ public class LwM2mClient { |
|
|
|
this.state = LwM2MClientState.CREATED; |
|
|
|
this.lock = new ReentrantLock(); |
|
|
|
this.retryAttempts = new AtomicInteger(0); |
|
|
|
this.supportedClientObjects = null; |
|
|
|
} |
|
|
|
|
|
|
|
public void init(ValidateDeviceCredentialsResponse credentials, UUID sessionId) { |
|
|
|
@ -153,12 +164,14 @@ public class LwM2mClient { |
|
|
|
this.edrxCycle = credentials.getDeviceInfo().getEdrxCycle(); |
|
|
|
this.psmActivityTimer = credentials.getDeviceInfo().getPsmActivityTimer(); |
|
|
|
this.pagingTransmissionWindow = credentials.getDeviceInfo().getPagingTransmissionWindow(); |
|
|
|
this.defaultObjectIDVer = getObjectIDVerFromDeviceProfile(credentials.getDeviceProfile()); |
|
|
|
} |
|
|
|
|
|
|
|
public void setRegistration(Registration registration) { |
|
|
|
this.registration = registration; |
|
|
|
this.clientSupportContentFormats = clientSupportContentFormat(registration); |
|
|
|
this.defaultContentFormat = calculateDefaultContentFormat(registration); |
|
|
|
this.setSupportedClientObjects(); |
|
|
|
} |
|
|
|
|
|
|
|
public void lock() { |
|
|
|
@ -197,6 +210,15 @@ public class LwM2mClient { |
|
|
|
builder.setDeviceType(deviceProfile.getName()); |
|
|
|
} |
|
|
|
|
|
|
|
private LwM2m.Version getObjectIDVerFromDeviceProfile(DeviceProfile deviceProfile) { |
|
|
|
String defaultObjectIdVer = ((Lwm2mDeviceProfileTransportConfiguration)deviceProfile |
|
|
|
.getProfileData() |
|
|
|
.getTransportConfiguration()) |
|
|
|
.getClientLwM2mSettings() |
|
|
|
.getDefaultObjectIDVer(); |
|
|
|
return new Version(defaultObjectIdVer == null ? LWM2M_OBJECT_VERSION_DEFAULT : defaultObjectIdVer); |
|
|
|
} |
|
|
|
|
|
|
|
public void refreshSessionId(String nodeId) { |
|
|
|
UUID newId = UUID.randomUUID(); |
|
|
|
SessionInfoProto.Builder builder = SessionInfoProto.newBuilder().mergeFrom(session); |
|
|
|
@ -240,67 +262,28 @@ public class LwM2mClient { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
public Object getResourceValue(String pathRezIdVer, String pathRezId) { |
|
|
|
String pathRez = pathRezIdVer == null ? convertObjectIdToVersionedId(pathRezId, this.registration) : pathRezIdVer; |
|
|
|
if (this.resources.get(pathRez) != null) { |
|
|
|
return this.resources.get(pathRez).getLwM2mResource().getValue(); |
|
|
|
} |
|
|
|
return null; |
|
|
|
} |
|
|
|
|
|
|
|
public Object getResourceNameByRezId(String pathRezIdVer, String pathRezId) { |
|
|
|
String pathRez = pathRezIdVer == null ? convertObjectIdToVersionedId(pathRezId, this.registration) : pathRezIdVer; |
|
|
|
if (this.resources.get(pathRez) != null) { |
|
|
|
return this.resources.get(pathRez).getResourceModel().name; |
|
|
|
} |
|
|
|
return null; |
|
|
|
} |
|
|
|
|
|
|
|
public String getRezIdByResourceNameAndObjectInstanceId(String resourceName, String pathObjectInstanceIdVer, LwM2mModelProvider modelProvider) { |
|
|
|
LwM2mPath pathIds = getLwM2mPathFromString(pathObjectInstanceIdVer); |
|
|
|
if (pathIds.isObjectInstance()) { |
|
|
|
Set<Integer> rezIds = modelProvider.getObjectModel(registration) |
|
|
|
.getObjectModel(pathIds.getObjectId()).resources.entrySet() |
|
|
|
.stream() |
|
|
|
.filter(map -> resourceName.equals(map.getValue().name)) |
|
|
|
.map(map -> map.getKey()) |
|
|
|
.collect(Collectors.toSet()); |
|
|
|
return rezIds.size() > 0 ? String.valueOf(rezIds.stream().findFirst().get()) : null; |
|
|
|
} |
|
|
|
return null; |
|
|
|
} |
|
|
|
|
|
|
|
public ResourceModel getResourceModel(String pathIdVer, LwM2mModelProvider modelProvider) { |
|
|
|
LwM2mPath pathIds = getLwM2mPathFromString(pathIdVer); |
|
|
|
String verSupportedObject = String.valueOf(registration.getSupportedObject().get(pathIds.getObjectId())); |
|
|
|
String verSupportedObject = String.valueOf(this.getSupportedObjectVersion(pathIds.getObjectId())); |
|
|
|
String verRez = getVerFromPathIdVerOrId(pathIdVer); |
|
|
|
return verRez != null && verRez.equals(verSupportedObject) ? modelProvider.getObjectModel(registration) |
|
|
|
.getResourceModel(pathIds.getObjectId(), pathIds.getResourceId()) : null; |
|
|
|
} |
|
|
|
|
|
|
|
public boolean isResourceMultiInstances(String pathIdVer, LwM2mModelProvider modelProvider) { |
|
|
|
var resourceModel = getResourceModel(pathIdVer, modelProvider); |
|
|
|
if (resourceModel != null && resourceModel.multiple != null) { |
|
|
|
return resourceModel.multiple; |
|
|
|
} else { |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
public ObjectModel getObjectModel(String pathIdVer, LwM2mModelProvider modelProvider) { |
|
|
|
try { |
|
|
|
LwM2mPath pathIds = getLwM2mPathFromString(pathIdVer); |
|
|
|
String verSupportedObject = String.valueOf(registration.getSupportedObject().get(pathIds.getObjectId())); |
|
|
|
String verSupportedObject = String.valueOf(this.getSupportedObjectVersion(pathIds.getObjectId())); |
|
|
|
String verRez = getVerFromPathIdVerOrId(pathIdVer); |
|
|
|
return verRez != null && verRez.equals(verSupportedObject) ? modelProvider.getObjectModel(registration) |
|
|
|
.getObjectModel(pathIds.getObjectId()) : null; |
|
|
|
} catch (Exception e) { |
|
|
|
if (registration == null) { |
|
|
|
log.error("[{}] Failed Registration is null, GetObjectModelRegistration. ", this.endpoint, e); |
|
|
|
} else if (registration.getSupportedObject() == null) { |
|
|
|
} else if (this.getSupportedClientObjects() == null) { |
|
|
|
log.error("[{}] Failed SupportedObject in Registration, GetObjectModelRegistration.", this.endpoint, e); |
|
|
|
} else { |
|
|
|
log.error("[{}] Failed ModelProvider.getObjectModel [{}] in Registration. ", this.endpoint, registration.getSupportedObject(), e); |
|
|
|
log.error("[{}] Failed ModelProvider.getObjectModel [{}] in Registration. ", this.endpoint, this.getSupportedClientObjects(), e); |
|
|
|
} |
|
|
|
return null; |
|
|
|
} |
|
|
|
@ -371,7 +354,7 @@ public class LwM2mClient { |
|
|
|
|
|
|
|
public String isValidObjectVersion(String path) { |
|
|
|
LwM2mPath pathIds = getLwM2mPathFromString(path); |
|
|
|
LwM2m.Version verSupportedObject = registration.getSupportedObject().get(pathIds.getObjectId()); |
|
|
|
LwM2m.Version verSupportedObject = this.getSupportedObjectVersion(pathIds.getObjectId()); |
|
|
|
if (verSupportedObject == null) { |
|
|
|
return String.format("Specified object id %s absent in the list supported objects of the client or is security object!", pathIds.getObjectId()); |
|
|
|
} else { |
|
|
|
@ -460,5 +443,34 @@ public class LwM2mClient { |
|
|
|
return new LwM2mPath(fromVersionedIdToObjectId(path)); |
|
|
|
} |
|
|
|
|
|
|
|
public LwM2m.Version getDefaultObjectIDVer() { |
|
|
|
return this.defaultObjectIDVer == null ? new Version(LWM2M_OBJECT_VERSION_DEFAULT) : this.defaultObjectIDVer; |
|
|
|
} |
|
|
|
|
|
|
|
public LwM2m.Version getSupportedObjectVersion(Integer objectid) { |
|
|
|
return this.supportedClientObjects.get(objectid); |
|
|
|
} |
|
|
|
|
|
|
|
private void setSupportedClientObjects(){ |
|
|
|
this.supportedClientObjects = new ConcurrentHashMap<>(); |
|
|
|
for (Link link: this.registration.getSortedObjectLinks()) { |
|
|
|
MixedLwM2mLink mixedLwM2mLink = (MixedLwM2mLink)link; |
|
|
|
if(!mixedLwM2mLink.getPath().isRoot()){ |
|
|
|
LwM2mPath lwM2mPath = mixedLwM2mLink.getPath(); |
|
|
|
if (lwM2mPath.isObject()) { |
|
|
|
LwM2m.Version ver; |
|
|
|
if (mixedLwM2mLink.getAttributes().get("ver")!= null) { |
|
|
|
ver = (Version) mixedLwM2mLink.getAttributes().get("ver").getValue(); |
|
|
|
} else { |
|
|
|
ver = getDefaultObjectIDVer(); |
|
|
|
} |
|
|
|
this.supportedClientObjects.put(lwM2mPath.getObjectId(), ver); |
|
|
|
} else if (this.supportedClientObjects.get(lwM2mPath.getObjectId()) == null){ |
|
|
|
this.supportedClientObjects.put(lwM2mPath.getObjectId(), getDefaultObjectIDVer()); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|