Search in sources :

Example 1 with LwM2mClient

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;
}
Also used : GsonBuilder(com.google.gson.GsonBuilder) JsonObject(com.google.gson.JsonObject) Gson(com.google.gson.Gson) LwM2MTransportUtil.convertOtaUpdateValueToString(org.thingsboard.server.transport.lwm2m.utils.LwM2MTransportUtil.convertOtaUpdateValueToString) LwM2mResource(org.eclipse.leshan.core.node.LwM2mResource) LwM2MClientStateException(org.thingsboard.server.transport.lwm2m.server.client.LwM2MClientStateException) LwM2mOtaConvert(org.thingsboard.server.transport.lwm2m.server.LwM2mOtaConvert) LwM2mPath(org.eclipse.leshan.core.node.LwM2mPath) JsonElement(com.google.gson.JsonElement) ResourceModel(org.eclipse.leshan.core.model.ResourceModel) JsonObject(com.google.gson.JsonObject) LwM2mObject(org.eclipse.leshan.core.node.LwM2mObject) LwM2mClient(org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient)

Example 2 with LwM2mClient

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());
        }
    });
}
Also used : SessionInfoProto(org.thingsboard.server.gen.transport.TransportProtos.SessionInfoProto) LwM2MClientStateException(org.thingsboard.server.transport.lwm2m.server.client.LwM2MClientStateException) UUID(java.util.UUID) LwM2mClient(org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient)

Example 3 with LwM2mClient

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!");
    }
}
Also used : LwM2mObjectInstance(org.eclipse.leshan.core.node.LwM2mObjectInstance) LwM2MTransportServerConfig(org.thingsboard.server.transport.lwm2m.config.LwM2MTransportServerConfig) LwM2MTelemetryLogService(org.thingsboard.server.transport.lwm2m.server.log.LwM2MTelemetryLogService) Arrays(java.util.Arrays) Hex(org.eclipse.leshan.core.util.Hex) GREATER_THAN(org.eclipse.leshan.core.attributes.Attribute.GREATER_THAN) LwM2mModel(org.eclipse.leshan.core.model.LwM2mModel) Date(java.util.Date) ReadRequest(org.eclipse.leshan.core.request.ReadRequest) ClientSleepingException(org.eclipse.leshan.core.request.exception.ClientSleepingException) RequiredArgsConstructor(lombok.RequiredArgsConstructor) DeleteRequest(org.eclipse.leshan.core.request.DeleteRequest) ContentFormat(org.eclipse.leshan.core.request.ContentFormat) LwM2mPath(org.eclipse.leshan.core.node.LwM2mPath) CreateRequest(org.eclipse.leshan.core.request.CreateRequest) MINIMUM_PERIOD(org.eclipse.leshan.core.attributes.Attribute.MINIMUM_PERIOD) ObserveResponse(org.eclipse.leshan.core.response.ObserveResponse) OPAQUE(org.eclipse.leshan.core.model.ResourceModel.Type.OPAQUE) LwM2mModelProvider(org.eclipse.leshan.server.model.LwM2mModelProvider) LwM2mTransportContext(org.thingsboard.server.transport.lwm2m.server.LwM2mTransportContext) PreDestroy(javax.annotation.PreDestroy) LwM2MExecutorAwareService(org.thingsboard.server.transport.lwm2m.server.common.LwM2MExecutorAwareService) RpcWriteCompositeRequest(org.thingsboard.server.transport.lwm2m.server.rpc.composite.RpcWriteCompositeRequest) Registration(org.eclipse.leshan.server.registration.Registration) Observation(org.eclipse.leshan.core.observation.Observation) TimeoutException(org.eclipse.leshan.core.request.exception.TimeoutException) AttributeSet(org.eclipse.leshan.core.attributes.AttributeSet) ExecuteRequest(org.eclipse.leshan.core.request.ExecuteRequest) Map(java.util.Map) WriteCompositeResponse(org.eclipse.leshan.core.response.WriteCompositeResponse) LwM2mClientContext(org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientContext) OBJLNK(org.eclipse.leshan.core.model.ResourceModel.Type.OBJLNK) DownlinkRequest(org.eclipse.leshan.core.request.DownlinkRequest) Link(org.eclipse.leshan.core.link.Link) MAXIMUM_PERIOD(org.eclipse.leshan.core.attributes.Attribute.MAXIMUM_PERIOD) Predicate(java.util.function.Predicate) Collection(java.util.Collection) LESSER_THAN(org.eclipse.leshan.core.attributes.Attribute.LESSER_THAN) LwM2MTransportUtil.createModelsDefault(org.thingsboard.server.transport.lwm2m.utils.LwM2MTransportUtil.createModelsDefault) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Set(java.util.Set) LwM2MTransportUtil.validateVersionedId(org.thingsboard.server.transport.lwm2m.utils.LwM2MTransportUtil.validateVersionedId) ExecuteResponse(org.eclipse.leshan.core.response.ExecuteResponse) Collectors(java.util.stream.Collectors) Slf4j(lombok.extern.slf4j.Slf4j) List(java.util.List) ObjectLink(org.eclipse.leshan.core.node.ObjectLink) SimpleDownlinkRequest(org.eclipse.leshan.core.request.SimpleDownlinkRequest) PostConstruct(javax.annotation.PostConstruct) DiscoverRequest(org.eclipse.leshan.core.request.DiscoverRequest) TbLwM2MReadCompositeRequest(org.thingsboard.server.transport.lwm2m.server.downlink.composite.TbLwM2MReadCompositeRequest) DeleteResponse(org.eclipse.leshan.core.response.DeleteResponse) ResourceModel(org.eclipse.leshan.core.model.ResourceModel) LwM2mClient(org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient) ObjectAttributes(org.thingsboard.server.common.data.device.profile.lwm2m.ObjectAttributes) LwM2mVersionedModelProvider(org.thingsboard.server.transport.lwm2m.server.LwM2mVersionedModelProvider) LwM2mResponse(org.eclipse.leshan.core.response.LwM2mResponse) TbLwM2mTransportComponent(org.thingsboard.server.queue.util.TbLwM2mTransportComponent) Function(java.util.function.Function) CreateResponse(org.eclipse.leshan.core.response.CreateResponse) ReadCompositeResponse(org.eclipse.leshan.core.response.ReadCompositeResponse) WriteAttributesResponse(org.eclipse.leshan.core.response.WriteAttributesResponse) LwM2MTransportUtil.convertMultiResourceValuesFromRpcBody(org.thingsboard.server.transport.lwm2m.utils.LwM2MTransportUtil.convertMultiResourceValuesFromRpcBody) Service(org.springframework.stereotype.Service) STEP(org.eclipse.leshan.core.attributes.Attribute.STEP) WriteRequest(org.eclipse.leshan.core.request.WriteRequest) Attribute(org.eclipse.leshan.core.attributes.Attribute) ObserveRequest(org.eclipse.leshan.core.request.ObserveRequest) LinkedList(java.util.LinkedList) CompositeDownlinkRequest(org.eclipse.leshan.core.request.CompositeDownlinkRequest) WriteAttributesRequest(org.eclipse.leshan.core.request.WriteAttributesRequest) ReadResponse(org.eclipse.leshan.core.response.ReadResponse) LwM2MTransportUtil.getVerFromPathIdVerOrId(org.thingsboard.server.transport.lwm2m.utils.LwM2MTransportUtil.getVerFromPathIdVerOrId) SingleObservation(org.eclipse.leshan.core.observation.SingleObservation) WriteResponse(org.eclipse.leshan.core.response.WriteResponse) WriteCompositeRequest(org.eclipse.leshan.core.request.WriteCompositeRequest) DiscoverResponse(org.eclipse.leshan.core.response.DiscoverResponse) LwM2mResource(org.eclipse.leshan.core.node.LwM2mResource) ReadCompositeRequest(org.eclipse.leshan.core.request.ReadCompositeRequest) LwM2mValueConverterImpl(org.thingsboard.server.transport.lwm2m.utils.LwM2mValueConverterImpl) LwM2MTransportUtil.fromVersionedIdToObjectId(org.thingsboard.server.transport.lwm2m.utils.LwM2MTransportUtil.fromVersionedIdToObjectId) InvalidRequestException(org.eclipse.leshan.core.request.exception.InvalidRequestException) LwM2m(org.eclipse.leshan.core.LwM2m) ObjectModel(org.eclipse.leshan.core.model.ObjectModel) LwM2mObjectInstance(org.eclipse.leshan.core.node.LwM2mObjectInstance) ObjectModel(org.eclipse.leshan.core.model.ObjectModel) AttributeSet(org.eclipse.leshan.core.attributes.AttributeSet) Set(java.util.Set) CreateRequest(org.eclipse.leshan.core.request.CreateRequest) LwM2mPath(org.eclipse.leshan.core.node.LwM2mPath) ContentFormat(org.eclipse.leshan.core.request.ContentFormat) Collection(java.util.Collection) LwM2mResource(org.eclipse.leshan.core.node.LwM2mResource)

Example 4 with LwM2mClient

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");
    }
}
Also used : ArrayList(java.util.ArrayList) TransportProtos(org.thingsboard.server.gen.transport.TransportProtos) LwM2mClient(org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient)

Example 5 with LwM2mClient

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;
    }
}
Also used : RedisClusterConnection(org.springframework.data.redis.connection.RedisClusterConnection) ArrayList(java.util.ArrayList) ScanOptions(org.springframework.data.redis.core.ScanOptions) Cursor(org.springframework.data.redis.core.Cursor) LwM2mClient(org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient) HashSet(java.util.HashSet)

Aggregations

LwM2mClient (org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient)13 LwM2mResource (org.eclipse.leshan.core.node.LwM2mResource)6 ResourceModel (org.eclipse.leshan.core.model.ResourceModel)4 LwM2MClientStateException (org.thingsboard.server.transport.lwm2m.server.client.LwM2MClientStateException)4 ArrayList (java.util.ArrayList)3 UUID (java.util.UUID)3 ObjectModel (org.eclipse.leshan.core.model.ObjectModel)3 LwM2mObject (org.eclipse.leshan.core.node.LwM2mObject)3 LwM2mObjectInstance (org.eclipse.leshan.core.node.LwM2mObjectInstance)3 Gson (com.google.gson.Gson)2 GsonBuilder (com.google.gson.GsonBuilder)2 JsonElement (com.google.gson.JsonElement)2 JsonObject (com.google.gson.JsonObject)2 Collection (java.util.Collection)2 HashSet (java.util.HashSet)2 List (java.util.List)2 Map (java.util.Map)2 Set (java.util.Set)2 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)2 CountDownLatch (java.util.concurrent.CountDownLatch)2