use of org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient in project thingsboard by thingsboard.
the class DefaultLwM2mUplinkMsgHandler method getKvToThingsBoard.
private TransportProtos.KeyValueProto getKvToThingsBoard(String pathIdVer, Registration registration) {
LwM2mClient lwM2MClient = this.clientContext.getClientByEndpoint(registration.getEndpoint());
Map<String, String> names = clientContext.getProfile(lwM2MClient.getProfileId()).getObserveAttr().getKeyName();
if (names != null && names.containsKey(pathIdVer)) {
String resourceName = names.get(pathIdVer);
if (resourceName != null && !resourceName.isEmpty()) {
try {
LwM2mResource resourceValue = LwM2MTransportUtil.getResourceValueFromLwM2MClient(lwM2MClient, pathIdVer);
if (resourceValue != null) {
ResourceModel.Type currentType = resourceValue.getType();
ResourceModel.Type expectedType = this.helper.getResourceModelTypeEqualsKvProtoValueType(currentType, pathIdVer);
Object valueKvProto = null;
if (resourceValue.isMultiInstances()) {
valueKvProto = new JsonObject();
Object finalvalueKvProto = valueKvProto;
Gson gson = new GsonBuilder().create();
ResourceModel.Type finalCurrentType = currentType;
resourceValue.getInstances().forEach((k, v) -> {
Object val = this.converter.convertValue(v.getValue(), finalCurrentType, expectedType, new LwM2mPath(fromVersionedIdToObjectId(pathIdVer)));
JsonElement element = gson.toJsonTree(val, val.getClass());
((JsonObject) finalvalueKvProto).add(String.valueOf(k), element);
});
valueKvProto = gson.toJson(valueKvProto);
} else {
valueKvProto = this.converter.convertValue(resourceValue.getValue(), currentType, expectedType, new LwM2mPath(fromVersionedIdToObjectId(pathIdVer)));
}
LwM2mOtaConvert lwM2mOtaConvert = convertOtaUpdateValueToString(pathIdVer, valueKvProto, currentType);
valueKvProto = lwM2mOtaConvert.getValue();
currentType = lwM2mOtaConvert.getCurrentType();
return valueKvProto != null ? this.helper.getKvAttrTelemetryToThingsboard(currentType, resourceName, valueKvProto, resourceValue.isMultiInstances()) : null;
}
} catch (Exception e) {
log.error("Failed to add parameters.", e);
}
}
} else {
log.error("Failed to add parameters. path: [{}], names: [{}]", pathIdVer, names);
}
return null;
}
use of org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient in project thingsboard by thingsboard.
the class DefaultLwM2mUplinkMsgHandler method onRegistered.
/**
* 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 registration - Registration LwM2M Client
* @param previousObservations - may be null
*/
public void onRegistered(Registration registration, Collection<Observation> previousObservations) {
executor.submit(() -> {
LwM2mClient lwM2MClient = this.clientContext.getClientByEndpoint(registration.getEndpoint());
try {
log.debug("[{}] [{{}] Client: create after Registration", registration.getEndpoint(), registration.getId());
Optional<SessionInfoProto> oldSessionInfo = this.clientContext.register(lwM2MClient, registration);
if (oldSessionInfo.isPresent()) {
log.info("[{}] Closing old session: {}", registration.getEndpoint(), new UUID(oldSessionInfo.get().getSessionIdMSB(), oldSessionInfo.get().getSessionIdLSB()));
sessionManager.deregister(oldSessionInfo.get());
}
logService.log(lwM2MClient, LOG_LWM2M_INFO + ": Client registered with registration id: " + registration.getId() + " version: " + registration.getLwM2mVersion() + " and modes: " + registration.getQueueMode() + ", " + registration.getBindingMode());
sessionManager.register(lwM2MClient.getSession());
this.initClientTelemetry(lwM2MClient);
this.initAttributes(lwM2MClient, true);
otaService.init(lwM2MClient);
lwM2MClient.getRetryAttempts().set(0);
} catch (LwM2MClientStateException stateException) {
if (LwM2MClientState.UNREGISTERED.equals(stateException.getState())) {
log.info("[{}] retry registration due to race condition: [{}].", registration.getEndpoint(), stateException.getState());
// Race condition detected and the client was in progress of unregistration while new registration arrived. Let's try again.
if (lwM2MClient.getRetryAttempts().incrementAndGet() <= 5) {
context.getScheduler().schedule(() -> onRegistered(registration, previousObservations), 1, TimeUnit.SECONDS);
} else {
logService.log(lwM2MClient, LOG_LWM2M_WARN + ": Client registration failed due to retry attempts: " + lwM2MClient.getRetryAttempts().get());
}
} else {
logService.log(lwM2MClient, LOG_LWM2M_WARN + ": Client registration failed due to invalid state: " + stateException.getState());
}
} catch (Throwable t) {
log.error("[{}] endpoint [{}] error Unable registration.", registration.getEndpoint(), t);
logService.log(lwM2MClient, LOG_LWM2M_WARN + ": Client registration failed due to: " + t.getMessage());
}
});
}
use of org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient in project thingsboard by thingsboard.
the class DefaultLwM2mDownlinkMsgHandler method sendCreateRequest.
public void sendCreateRequest(LwM2mClient client, TbLwM2MCreateRequest request, DownlinkRequestCallback<CreateRequest, CreateResponse> callback) {
validateVersionedId(client, request);
CreateRequest downlink = null;
LwM2mPath resultIds = new LwM2mPath(request.getObjectId());
ObjectModel objectModel = client.getObjectModel(request.getVersionedId(), modelProvider);
// POST /{Object ID}/{Object Instance ID} && Resources is Mandatory
if (objectModel != null) {
if (objectModel.multiple) {
// LwM2M CBOR, SenML CBOR, SenML JSON, or TLV (see [LwM2M-CORE])
ContentFormat contentFormat = getWriteRequestContentFormat(client, request, modelProvider);
if (resultIds.isObject() || resultIds.isObjectInstance()) {
Collection<LwM2mResource> resources;
if (resultIds.isObject()) {
if (request.getValue() != null) {
resources = client.getNewResourcesForInstance(request.getVersionedId(), request.getValue(), modelProvider, this.converter);
downlink = new CreateRequest(contentFormat, resultIds.getObjectId(), resources);
} else if (request.getNodes() != null && request.getNodes().size() > 0) {
Set<LwM2mObjectInstance> instances = ConcurrentHashMap.newKeySet();
request.getNodes().forEach((key, value) -> {
Collection<LwM2mResource> resourcesForInstance = client.getNewResourcesForInstance(request.getVersionedId(), value, modelProvider, this.converter);
LwM2mObjectInstance instance = new LwM2mObjectInstance(Integer.parseInt(key), resourcesForInstance);
instances.add(instance);
});
LwM2mObjectInstance[] instanceArrays = instances.toArray(new LwM2mObjectInstance[instances.size()]);
downlink = new CreateRequest(contentFormat, resultIds.getObjectId(), instanceArrays);
}
} else {
resources = client.getNewResourcesForInstance(request.getVersionedId(), request.getValue(), modelProvider, this.converter);
LwM2mObjectInstance instance = new LwM2mObjectInstance(resultIds.getObjectInstanceId(), resources);
downlink = new CreateRequest(contentFormat, resultIds.getObjectId(), instance);
}
}
if (downlink != null) {
sendSimpleRequest(client, downlink, request.getTimeout(), callback);
} else {
callback.onValidationError(toString(request), "Path " + request.getVersionedId() + ". Object must be Multiple !");
}
} else {
throw new IllegalArgumentException("Path " + request.getVersionedId() + ". Object must be Multiple !");
}
} else {
callback.onValidationError(toString(request), "Resource " + request.getVersionedId() + " is not configured in the device profile!");
}
}
use of org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient in project thingsboard by thingsboard.
the class DefaultLwM2MAttributesService method onAttributesUpdate.
/**
* Update - send request in change value resources in Client
* 1. FirmwareUpdate:
* - If msg.getSharedUpdatedList().forEach(tsKvProto -> {tsKvProto.getKv().getKey().indexOf(FIRMWARE_UPDATE_PREFIX, 0) == 0
* 2. Shared Other AttributeUpdate
* -- Path to resources from profile equal keyName or from ModelObject equal name
* -- Only for resources: isWritable && isPresent as attribute in profile -> LwM2MClientProfile (format: CamelCase)
* 3. Delete - nothing
*
* @param msg -
*/
@Override
public void onAttributesUpdate(TransportProtos.AttributeUpdateNotificationMsg msg, TransportProtos.SessionInfoProto sessionInfo) {
LwM2mClient lwM2MClient = clientContext.getClientBySessionInfo(sessionInfo);
if (msg.getSharedUpdatedCount() > 0 && lwM2MClient != null) {
String newFirmwareTitle = null;
String newFirmwareVersion = null;
String newFirmwareTag = null;
String newFirmwareUrl = null;
String newSoftwareTitle = null;
String newSoftwareVersion = null;
String newSoftwareTag = null;
String newSoftwareUrl = null;
List<TransportProtos.TsKvProto> otherAttributes = new ArrayList<>();
for (TransportProtos.TsKvProto tsKvProto : msg.getSharedUpdatedList()) {
String attrName = tsKvProto.getKv().getKey();
if (compareAttNameKeyOta(attrName)) {
if (FIRMWARE_TITLE.equals(attrName)) {
newFirmwareTitle = getStrValue(tsKvProto);
} else if (FIRMWARE_VERSION.equals(attrName)) {
newFirmwareVersion = getStrValue(tsKvProto);
} else if (FIRMWARE_TAG.equals(attrName)) {
newFirmwareTag = getStrValue(tsKvProto);
} else if (FIRMWARE_URL.equals(attrName)) {
newFirmwareUrl = getStrValue(tsKvProto);
} else if (SOFTWARE_TITLE.equals(attrName)) {
newSoftwareTitle = getStrValue(tsKvProto);
} else if (SOFTWARE_VERSION.equals(attrName)) {
newSoftwareVersion = getStrValue(tsKvProto);
} else if (SOFTWARE_TAG.equals(attrName)) {
newSoftwareTag = getStrValue(tsKvProto);
} else if (SOFTWARE_URL.equals(attrName)) {
newSoftwareUrl = getStrValue(tsKvProto);
}
} else {
otherAttributes.add(tsKvProto);
}
}
if (newFirmwareTitle != null || newFirmwareVersion != null) {
otaUpdateService.onTargetFirmwareUpdate(lwM2MClient, newFirmwareTitle, newFirmwareVersion, Optional.ofNullable(newFirmwareUrl), Optional.ofNullable(newFirmwareTag));
}
if (newSoftwareTitle != null || newSoftwareVersion != null) {
otaUpdateService.onTargetSoftwareUpdate(lwM2MClient, newSoftwareTitle, newSoftwareVersion, Optional.ofNullable(newSoftwareUrl), Optional.ofNullable(newSoftwareTag));
}
if (!otherAttributes.isEmpty()) {
onAttributesUpdate(lwM2MClient, otherAttributes, true);
}
} else if (lwM2MClient == null) {
log.error("OnAttributeUpdate, lwM2MClient is null");
}
}
use of org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient in project thingsboard by thingsboard.
the class TbRedisLwM2MClientStore method getAll.
@Override
public Set<LwM2mClient> getAll() {
try (var connection = connectionFactory.getConnection()) {
Set<LwM2mClient> clients = new HashSet<>();
ScanOptions scanOptions = ScanOptions.scanOptions().count(100).match(CLIENT_EP + "*").build();
List<Cursor<byte[]>> scans = new ArrayList<>();
if (connection instanceof RedisClusterConnection) {
((RedisClusterConnection) connection).clusterGetNodes().forEach(node -> {
scans.add(((RedisClusterConnection) connection).scan(node, scanOptions));
});
} else {
scans.add(connection.scan(scanOptions));
}
scans.forEach(scan -> {
scan.forEachRemaining(key -> {
byte[] element = connection.get(key);
clients.add(deserialize(element));
});
});
return clients;
}
}
Aggregations