Commit 5f8a9e9f679f7f333a10bbabd51b22d519207144
Committed by
GitHub
1 parent
c350fb7a
Lwm2m rpc (#4473)
* Lwm2m: RPC_terminal * Lwm2m: RPC_terminal del two file * Lwm2m: RPC_terminal add test observe * Lwm2m: RPC_terminal add test delete
Showing
13 changed files
with
723 additions
and
378 deletions
@@ -35,7 +35,7 @@ import org.thingsboard.server.transport.lwm2m.secure.LwM2mCredentialsSecurityInf | @@ -35,7 +35,7 @@ import org.thingsboard.server.transport.lwm2m.secure.LwM2mCredentialsSecurityInf | ||
35 | import org.thingsboard.server.transport.lwm2m.secure.ReadResultSecurityStore; | 35 | import org.thingsboard.server.transport.lwm2m.secure.ReadResultSecurityStore; |
36 | import org.thingsboard.server.transport.lwm2m.server.LwM2mSessionMsgListener; | 36 | import org.thingsboard.server.transport.lwm2m.server.LwM2mSessionMsgListener; |
37 | import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportContextServer; | 37 | import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportContextServer; |
38 | -import org.thingsboard.server.transport.lwm2m.utils.TypeServer; | 38 | +import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler; |
39 | 39 | ||
40 | import java.io.IOException; | 40 | import java.io.IOException; |
41 | import java.security.GeneralSecurityException; | 41 | import java.security.GeneralSecurityException; |
@@ -69,7 +69,7 @@ public class LwM2MBootstrapSecurityStore implements BootstrapSecurityStore { | @@ -69,7 +69,7 @@ public class LwM2MBootstrapSecurityStore implements BootstrapSecurityStore { | ||
69 | 69 | ||
70 | @Override | 70 | @Override |
71 | public List<SecurityInfo> getAllByEndpoint(String endPoint) { | 71 | public List<SecurityInfo> getAllByEndpoint(String endPoint) { |
72 | - ReadResultSecurityStore store = lwM2MCredentialsSecurityInfoValidator.createAndValidateCredentialsSecurityInfo(endPoint, TypeServer.BOOTSTRAP); | 72 | + ReadResultSecurityStore store = lwM2MCredentialsSecurityInfoValidator.createAndValidateCredentialsSecurityInfo(endPoint, LwM2mTransportHandler.LwM2mTypeServer.BOOTSTRAP); |
73 | if (store.getBootstrapJsonCredential() != null && store.getSecurityMode() < LwM2MSecurityMode.DEFAULT_MODE.code) { | 73 | if (store.getBootstrapJsonCredential() != null && store.getSecurityMode() < LwM2MSecurityMode.DEFAULT_MODE.code) { |
74 | /** add value to store from BootstrapJson */ | 74 | /** add value to store from BootstrapJson */ |
75 | this.setBootstrapConfigScurityInfo(store); | 75 | this.setBootstrapConfigScurityInfo(store); |
@@ -93,7 +93,7 @@ public class LwM2MBootstrapSecurityStore implements BootstrapSecurityStore { | @@ -93,7 +93,7 @@ public class LwM2MBootstrapSecurityStore implements BootstrapSecurityStore { | ||
93 | 93 | ||
94 | @Override | 94 | @Override |
95 | public SecurityInfo getByIdentity(String identity) { | 95 | public SecurityInfo getByIdentity(String identity) { |
96 | - ReadResultSecurityStore store = lwM2MCredentialsSecurityInfoValidator.createAndValidateCredentialsSecurityInfo(identity, TypeServer.BOOTSTRAP); | 96 | + ReadResultSecurityStore store = lwM2MCredentialsSecurityInfoValidator.createAndValidateCredentialsSecurityInfo(identity, LwM2mTransportHandler.LwM2mTypeServer.BOOTSTRAP); |
97 | if (store.getBootstrapJsonCredential() != null && store.getSecurityMode() < LwM2MSecurityMode.DEFAULT_MODE.code) { | 97 | if (store.getBootstrapJsonCredential() != null && store.getSecurityMode() < LwM2MSecurityMode.DEFAULT_MODE.code) { |
98 | /** add value to store from BootstrapJson */ | 98 | /** add value to store from BootstrapJson */ |
99 | this.setBootstrapConfigScurityInfo(store); | 99 | this.setBootstrapConfigScurityInfo(store); |
@@ -28,7 +28,6 @@ import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceLwM2MC | @@ -28,7 +28,6 @@ import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceLwM2MC | ||
28 | import org.thingsboard.server.queue.util.TbLwM2mTransportComponent; | 28 | import org.thingsboard.server.queue.util.TbLwM2mTransportComponent; |
29 | import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportContextServer; | 29 | import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportContextServer; |
30 | import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler; | 30 | import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler; |
31 | -import org.thingsboard.server.transport.lwm2m.utils.TypeServer; | ||
32 | 31 | ||
33 | import java.io.IOException; | 32 | import java.io.IOException; |
34 | import java.security.GeneralSecurityException; | 33 | import java.security.GeneralSecurityException; |
@@ -59,7 +58,7 @@ public class LwM2mCredentialsSecurityInfoValidator { | @@ -59,7 +58,7 @@ public class LwM2mCredentialsSecurityInfoValidator { | ||
59 | * @param keyValue - | 58 | * @param keyValue - |
60 | * @return ValidateDeviceCredentialsResponseMsg and SecurityInfo | 59 | * @return ValidateDeviceCredentialsResponseMsg and SecurityInfo |
61 | */ | 60 | */ |
62 | - public ReadResultSecurityStore createAndValidateCredentialsSecurityInfo(String endpoint, TypeServer keyValue) { | 61 | + public ReadResultSecurityStore createAndValidateCredentialsSecurityInfo(String endpoint, LwM2mTransportHandler.LwM2mTypeServer keyValue) { |
63 | CountDownLatch latch = new CountDownLatch(1); | 62 | CountDownLatch latch = new CountDownLatch(1); |
64 | final ReadResultSecurityStore[] resultSecurityStore = new ReadResultSecurityStore[1]; | 63 | final ReadResultSecurityStore[] resultSecurityStore = new ReadResultSecurityStore[1]; |
65 | contextS.getTransportService().process(ValidateDeviceLwM2MCredentialsRequestMsg.newBuilder().setCredentialsId(endpoint).build(), | 64 | contextS.getTransportService().process(ValidateDeviceLwM2MCredentialsRequestMsg.newBuilder().setCredentialsId(endpoint).build(), |
@@ -96,7 +95,7 @@ public class LwM2mCredentialsSecurityInfoValidator { | @@ -96,7 +95,7 @@ public class LwM2mCredentialsSecurityInfoValidator { | ||
96 | * @param keyValue - | 95 | * @param keyValue - |
97 | * @return SecurityInfo | 96 | * @return SecurityInfo |
98 | */ | 97 | */ |
99 | - private ReadResultSecurityStore createSecurityInfo(String endPoint, String jsonStr, TypeServer keyValue) { | 98 | + private ReadResultSecurityStore createSecurityInfo(String endPoint, String jsonStr, LwM2mTransportHandler.LwM2mTypeServer keyValue) { |
100 | ReadResultSecurityStore result = new ReadResultSecurityStore(); | 99 | ReadResultSecurityStore result = new ReadResultSecurityStore(); |
101 | JsonObject objectMsg = LwM2mTransportHandler.validateJson(jsonStr); | 100 | JsonObject objectMsg = LwM2mTransportHandler.validateJson(jsonStr); |
102 | if (objectMsg != null && !objectMsg.isJsonNull()) { | 101 | if (objectMsg != null && !objectMsg.isJsonNull()) { |
@@ -109,7 +108,7 @@ public class LwM2mCredentialsSecurityInfoValidator { | @@ -109,7 +108,7 @@ public class LwM2mCredentialsSecurityInfoValidator { | ||
109 | && objectMsg.get("client").getAsJsonObject().get("endpoint").isJsonPrimitive()) ? objectMsg.get("client").getAsJsonObject().get("endpoint").getAsString() : null; | 108 | && objectMsg.get("client").getAsJsonObject().get("endpoint").isJsonPrimitive()) ? objectMsg.get("client").getAsJsonObject().get("endpoint").getAsString() : null; |
110 | endPoint = (endPointPsk == null || endPointPsk.isEmpty()) ? endPoint : endPointPsk; | 109 | endPoint = (endPointPsk == null || endPointPsk.isEmpty()) ? endPoint : endPointPsk; |
111 | if (object != null && !object.isJsonNull()) { | 110 | if (object != null && !object.isJsonNull()) { |
112 | - if (keyValue.equals(TypeServer.BOOTSTRAP)) { | 111 | + if (keyValue.equals(LwM2mTransportHandler.LwM2mTypeServer.BOOTSTRAP)) { |
113 | result.setBootstrapJsonCredential(object); | 112 | result.setBootstrapJsonCredential(object); |
114 | result.setEndPoint(endPoint); | 113 | result.setEndPoint(endPoint); |
115 | result.setSecurityMode(LwM2MSecurityMode.fromSecurityMode(object.get("bootstrapServer").getAsJsonObject().get("securityMode").getAsString().toLowerCase()).code); | 114 | result.setSecurityMode(LwM2MSecurityMode.fromSecurityMode(object.get("bootstrapServer").getAsJsonObject().get("securityMode").getAsString().toLowerCase()).code); |
@@ -92,7 +92,8 @@ public class LwM2mServerListener { | @@ -92,7 +92,8 @@ public class LwM2mServerListener { | ||
92 | public void onResponse(Observation observation, Registration registration, ObserveResponse response) { | 92 | public void onResponse(Observation observation, Registration registration, ObserveResponse response) { |
93 | if (registration != null) { | 93 | if (registration != null) { |
94 | try { | 94 | try { |
95 | - service.onObservationResponse(registration, convertPathFromObjectIdToIdVer(observation.getPath().toString(), registration), response); | 95 | + service.onObservationResponse(registration, convertPathFromObjectIdToIdVer(observation.getPath().toString(), |
96 | + registration), response, null); | ||
96 | } catch (Exception e) { | 97 | } catch (Exception e) { |
97 | log.error("[{}] onResponse", e.toString()); | 98 | log.error("[{}] onResponse", e.toString()); |
98 | 99 |
@@ -75,7 +75,7 @@ public class LwM2mSessionMsgListener implements GenericFutureListener<Future<? s | @@ -75,7 +75,7 @@ public class LwM2mSessionMsgListener implements GenericFutureListener<Future<? s | ||
75 | 75 | ||
76 | @Override | 76 | @Override |
77 | public void onToDeviceRpcRequest(ToDeviceRpcRequestMsg toDeviceRequest) { | 77 | public void onToDeviceRpcRequest(ToDeviceRpcRequestMsg toDeviceRequest) { |
78 | - this.service.onToDeviceRpcRequest(toDeviceRequest); | 78 | + this.service.onToDeviceRpcRequest(toDeviceRequest,this.sessionInfo); |
79 | } | 79 | } |
80 | 80 | ||
81 | @Override | 81 | @Override |
@@ -16,9 +16,13 @@ | @@ -16,9 +16,13 @@ | ||
16 | package org.thingsboard.server.transport.lwm2m.server; | 16 | package org.thingsboard.server.transport.lwm2m.server; |
17 | 17 | ||
18 | import com.fasterxml.jackson.databind.ObjectMapper; | 18 | import com.fasterxml.jackson.databind.ObjectMapper; |
19 | +import com.google.common.collect.Sets; | ||
20 | +import com.google.gson.Gson; | ||
21 | +import com.google.gson.JsonArray; | ||
19 | import com.google.gson.JsonObject; | 22 | import com.google.gson.JsonObject; |
20 | import com.google.gson.JsonParser; | 23 | import com.google.gson.JsonParser; |
21 | import com.google.gson.JsonSyntaxException; | 24 | import com.google.gson.JsonSyntaxException; |
25 | +import com.google.gson.reflect.TypeToken; | ||
22 | import lombok.extern.slf4j.Slf4j; | 26 | import lombok.extern.slf4j.Slf4j; |
23 | import org.apache.commons.lang3.StringUtils; | 27 | import org.apache.commons.lang3.StringUtils; |
24 | import org.eclipse.californium.core.network.config.NetworkConfig; | 28 | import org.eclipse.californium.core.network.config.NetworkConfig; |
@@ -26,7 +30,12 @@ import org.eclipse.leshan.core.attributes.Attribute; | @@ -26,7 +30,12 @@ import org.eclipse.leshan.core.attributes.Attribute; | ||
26 | import org.eclipse.leshan.core.attributes.AttributeSet; | 30 | import org.eclipse.leshan.core.attributes.AttributeSet; |
27 | import org.eclipse.leshan.core.model.ObjectModel; | 31 | import org.eclipse.leshan.core.model.ObjectModel; |
28 | import org.eclipse.leshan.core.model.ResourceModel; | 32 | import org.eclipse.leshan.core.model.ResourceModel; |
33 | +import org.eclipse.leshan.core.node.LwM2mMultipleResource; | ||
34 | +import org.eclipse.leshan.core.node.LwM2mNode; | ||
35 | +import org.eclipse.leshan.core.node.LwM2mObject; | ||
36 | +import org.eclipse.leshan.core.node.LwM2mObjectInstance; | ||
29 | import org.eclipse.leshan.core.node.LwM2mPath; | 37 | import org.eclipse.leshan.core.node.LwM2mPath; |
38 | +import org.eclipse.leshan.core.node.LwM2mSingleResource; | ||
30 | import org.eclipse.leshan.core.node.codec.CodecException; | 39 | import org.eclipse.leshan.core.node.codec.CodecException; |
31 | import org.eclipse.leshan.core.request.DownlinkRequest; | 40 | import org.eclipse.leshan.core.request.DownlinkRequest; |
32 | import org.eclipse.leshan.core.request.WriteAttributesRequest; | 41 | import org.eclipse.leshan.core.request.WriteAttributesRequest; |
@@ -50,6 +59,7 @@ import java.util.LinkedList; | @@ -50,6 +59,7 @@ import java.util.LinkedList; | ||
50 | import java.util.List; | 59 | import java.util.List; |
51 | import java.util.Map; | 60 | import java.util.Map; |
52 | import java.util.Optional; | 61 | import java.util.Optional; |
62 | +import java.util.Set; | ||
53 | import java.util.concurrent.ConcurrentHashMap; | 63 | import java.util.concurrent.ConcurrentHashMap; |
54 | 64 | ||
55 | import static org.eclipse.leshan.core.attributes.Attribute.DIMENSION; | 65 | import static org.eclipse.leshan.core.attributes.Attribute.DIMENSION; |
@@ -62,8 +72,8 @@ import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPA | @@ -62,8 +72,8 @@ import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPA | ||
62 | @Slf4j | 72 | @Slf4j |
63 | public class LwM2mTransportHandler { | 73 | public class LwM2mTransportHandler { |
64 | 74 | ||
65 | - public static final String BASE_DEVICE_API_TOPIC = "v1/devices/me"; | ||
66 | - | 75 | + // public static final String BASE_DEVICE_API_TOPIC = "v1/devices/me"; |
76 | + public static final String TRANSPORT_DEFAULT_LWM2M_VERSION = "1.0"; | ||
67 | public static final String CLIENT_LWM2M_SETTINGS = "clientLwM2mSettings"; | 77 | public static final String CLIENT_LWM2M_SETTINGS = "clientLwM2mSettings"; |
68 | public static final String BOOTSTRAP = "bootstrap"; | 78 | public static final String BOOTSTRAP = "bootstrap"; |
69 | public static final String SERVERS = "servers"; | 79 | public static final String SERVERS = "servers"; |
@@ -73,21 +83,21 @@ public class LwM2mTransportHandler { | @@ -73,21 +83,21 @@ public class LwM2mTransportHandler { | ||
73 | public static final String ATTRIBUTE = "attribute"; | 83 | public static final String ATTRIBUTE = "attribute"; |
74 | public static final String TELEMETRY = "telemetry"; | 84 | public static final String TELEMETRY = "telemetry"; |
75 | public static final String KEY_NAME = "keyName"; | 85 | public static final String KEY_NAME = "keyName"; |
76 | - public static final String OBSERVE = "observe"; | 86 | + public static final String OBSERVE_LWM2M = "observe"; |
77 | public static final String ATTRIBUTE_LWM2M = "attributeLwm2m"; | 87 | public static final String ATTRIBUTE_LWM2M = "attributeLwm2m"; |
78 | - public static final String RESOURCE_VALUE = "resValue"; | ||
79 | - public static final String RESOURCE_TYPE = "resType"; | 88 | +// public static final String RESOURCE_VALUE = "resValue"; |
89 | +// public static final String RESOURCE_TYPE = "resType"; | ||
80 | 90 | ||
81 | private static final String REQUEST = "/request"; | 91 | private static final String REQUEST = "/request"; |
82 | - private static final String RESPONSE = "/response"; | 92 | + // private static final String RESPONSE = "/response"; |
83 | private static final String ATTRIBUTES = "/" + ATTRIBUTE; | 93 | private static final String ATTRIBUTES = "/" + ATTRIBUTE; |
84 | public static final String TELEMETRIES = "/" + TELEMETRY; | 94 | public static final String TELEMETRIES = "/" + TELEMETRY; |
85 | - public static final String ATTRIBUTES_RESPONSE = ATTRIBUTES + RESPONSE; | 95 | + // public static final String ATTRIBUTES_RESPONSE = ATTRIBUTES + RESPONSE; |
86 | public static final String ATTRIBUTES_REQUEST = ATTRIBUTES + REQUEST; | 96 | public static final String ATTRIBUTES_REQUEST = ATTRIBUTES + REQUEST; |
87 | - public static final String DEVICE_ATTRIBUTES_RESPONSE = ATTRIBUTES_RESPONSE + "/"; | 97 | + // public static final String DEVICE_ATTRIBUTES_RESPONSE = ATTRIBUTES_RESPONSE + "/"; |
88 | public static final String DEVICE_ATTRIBUTES_REQUEST = ATTRIBUTES_REQUEST + "/"; | 98 | public static final String DEVICE_ATTRIBUTES_REQUEST = ATTRIBUTES_REQUEST + "/"; |
89 | - public static final String DEVICE_ATTRIBUTES_TOPIC = BASE_DEVICE_API_TOPIC + ATTRIBUTES; | ||
90 | - public static final String DEVICE_TELEMETRY_TOPIC = BASE_DEVICE_API_TOPIC + TELEMETRIES; | 99 | +// public static final String DEVICE_ATTRIBUTES_TOPIC = BASE_DEVICE_API_TOPIC + ATTRIBUTES; |
100 | +// public static final String DEVICE_TELEMETRY_TOPIC = BASE_DEVICE_API_TOPIC + TELEMETRIES; | ||
91 | 101 | ||
92 | public static final long DEFAULT_TIMEOUT = 2 * 60 * 1000L; // 2min in ms | 102 | public static final long DEFAULT_TIMEOUT = 2 * 60 * 1000L; // 2min in ms |
93 | 103 | ||
@@ -95,30 +105,86 @@ public class LwM2mTransportHandler { | @@ -95,30 +105,86 @@ public class LwM2mTransportHandler { | ||
95 | public static final String LOG_LW2M_INFO = "info"; | 105 | public static final String LOG_LW2M_INFO = "info"; |
96 | public static final String LOG_LW2M_ERROR = "error"; | 106 | public static final String LOG_LW2M_ERROR = "error"; |
97 | public static final String LOG_LW2M_WARN = "warn"; | 107 | public static final String LOG_LW2M_WARN = "warn"; |
108 | + public static final String LOG_LW2M_VALUE = "value"; | ||
98 | 109 | ||
99 | public static final int LWM2M_STRATEGY_1 = 1; | 110 | public static final int LWM2M_STRATEGY_1 = 1; |
100 | public static final int LWM2M_STRATEGY_2 = 2; | 111 | public static final int LWM2M_STRATEGY_2 = 2; |
101 | 112 | ||
102 | public static final String CLIENT_NOT_AUTHORIZED = "Client not authorized"; | 113 | public static final String CLIENT_NOT_AUTHORIZED = "Client not authorized"; |
103 | 114 | ||
104 | - public static final String GET_TYPE_OPER_READ = "read"; | ||
105 | - public static final String GET_TYPE_OPER_DISCOVER = "discover"; | ||
106 | - public static final String GET_TYPE_OPER_OBSERVE = "observe"; | ||
107 | - public static final String POST_TYPE_OPER_OBSERVE_CANCEL = "observeCancel"; | ||
108 | - public static final String POST_TYPE_OPER_EXECUTE = "execute"; | ||
109 | - /** | ||
110 | - * Replaces the Object Instance or the Resource(s) with the new value provided in the “Write” operation. (see | ||
111 | - * section 5.3.3 of the LW M2M spec). | ||
112 | - * if all resources are to be replaced | ||
113 | - */ | ||
114 | - public static final String POST_TYPE_OPER_WRITE_REPLACE = "replace"; | 115 | + public enum LwM2mTypeServer { |
116 | + BOOTSTRAP(0, "bootstrap"), | ||
117 | + CLIENT(1, "client"); | ||
118 | + | ||
119 | + public int code; | ||
120 | + public String type; | ||
121 | + | ||
122 | + LwM2mTypeServer(int code, String type) { | ||
123 | + this.code = code; | ||
124 | + this.type = type; | ||
125 | + } | ||
126 | + | ||
127 | + public static LwM2mTypeServer fromLwM2mTypeServer(String type) { | ||
128 | + for (LwM2mTypeServer sm : LwM2mTypeServer.values()) { | ||
129 | + if (sm.type.equals(type)) { | ||
130 | + return sm; | ||
131 | + } | ||
132 | + } | ||
133 | + throw new IllegalArgumentException(String.format("Unsupported typeServer type : %d", type)); | ||
134 | + } | ||
135 | + } | ||
136 | + | ||
115 | /** | 137 | /** |
116 | - * Adds or updates Resources provided in the new value and leaves other existing Resources unchanged. (see section | ||
117 | - * 5.3.3 of the LW M2M spec). | ||
118 | - * if this is a partial update request | 138 | + * Define the behavior of a write request. |
119 | */ | 139 | */ |
120 | - public static final String PUT_TYPE_OPER_WRITE_UPDATE = "update"; | ||
121 | - public static final String PUT_TYPE_OPER_WRITE_ATTRIBUTES = "wright-attributes"; | 140 | + public enum LwM2mTypeOper { |
141 | + /** | ||
142 | + * GET | ||
143 | + */ | ||
144 | + READ(0, "Read"), | ||
145 | + DISCOVER(1, "Discover"), | ||
146 | + OBSERVE_READ_ALL(2, "ObserveReadAll"), | ||
147 | + /** | ||
148 | + * POST | ||
149 | + */ | ||
150 | + OBSERVE(3, "Observe"), | ||
151 | + OBSERVE_CANCEL(4, "ObserveCancel"), | ||
152 | + EXECUTE(5, "Execute"), | ||
153 | + /** | ||
154 | + * Replaces the Object Instance or the Resource(s) with the new value provided in the “Write” operation. (see | ||
155 | + * section 5.3.3 of the LW M2M spec). | ||
156 | + * if all resources are to be replaced | ||
157 | + */ | ||
158 | + WRITE_REPLACE(6, "WriteReplace"), | ||
159 | + /** | ||
160 | + * PUT | ||
161 | + */ | ||
162 | + /** | ||
163 | + * Adds or updates Resources provided in the new value and leaves other existing Resources unchanged. (see section | ||
164 | + * 5.3.3 of the LW M2M spec). | ||
165 | + * if this is a partial update request | ||
166 | + */ | ||
167 | + WRITE_UPDATE(7, "WriteUpdate"), | ||
168 | + WRITE_ATTRIBUTES(8, "WriteAttributes"), | ||
169 | + DELETE(9, "Delete"); | ||
170 | + | ||
171 | + public int code; | ||
172 | + public String type; | ||
173 | + | ||
174 | + LwM2mTypeOper(int code, String type) { | ||
175 | + this.code = code; | ||
176 | + this.type = type; | ||
177 | + } | ||
178 | + | ||
179 | + public static LwM2mTypeOper fromLwLwM2mTypeOper(String type) { | ||
180 | + for (LwM2mTypeOper to : LwM2mTypeOper.values()) { | ||
181 | + if (to.type.equals(type)) { | ||
182 | + return to; | ||
183 | + } | ||
184 | + } | ||
185 | + throw new IllegalArgumentException(String.format("Unsupported typeOper type : %d", type)); | ||
186 | + } | ||
187 | + } | ||
122 | 188 | ||
123 | public static final String EVENT_AWAKE = "AWAKE"; | 189 | public static final String EVENT_AWAKE = "AWAKE"; |
124 | public static final String SERVICE_CHANNEL = "SERVICE"; | 190 | public static final String SERVICE_CHANNEL = "SERVICE"; |
@@ -156,19 +222,20 @@ public class LwM2mTransportHandler { | @@ -156,19 +222,20 @@ public class LwM2mTransportHandler { | ||
156 | throw new CodecException("Invalid value type for resource %s, type %s", resourcePath, type); | 222 | throw new CodecException("Invalid value type for resource %s, type %s", resourcePath, type); |
157 | } | 223 | } |
158 | } | 224 | } |
159 | -// | ||
160 | -// public static LwM2mNode getLvM2mNodeToObject(LwM2mNode content) { | ||
161 | -// if (content instanceof LwM2mObject) { | ||
162 | -// return (LwM2mObject) content; | ||
163 | -// } else if (content instanceof LwM2mObjectInstance) { | ||
164 | -// return (LwM2mObjectInstance) content; | ||
165 | -// } else if (content instanceof LwM2mSingleResource) { | ||
166 | -// return (LwM2mSingleResource) content; | ||
167 | -// } else if (content instanceof LwM2mMultipleResource) { | ||
168 | -// return (LwM2mMultipleResource) content; | ||
169 | -// } | ||
170 | -// return null; | ||
171 | -// } | 225 | + |
226 | + public static LwM2mNode getLvM2mNodeToObject(LwM2mNode content) { | ||
227 | + if (content instanceof LwM2mObject) { | ||
228 | + return (LwM2mObject) content; | ||
229 | + } else if (content instanceof LwM2mObjectInstance) { | ||
230 | + return (LwM2mObjectInstance) content; | ||
231 | + } else if (content instanceof LwM2mSingleResource) { | ||
232 | + return (LwM2mSingleResource) content; | ||
233 | + } else if (content instanceof LwM2mMultipleResource) { | ||
234 | + return (LwM2mMultipleResource) content; | ||
235 | + } | ||
236 | + return null; | ||
237 | + } | ||
238 | + | ||
172 | 239 | ||
173 | public static LwM2mClientProfile getNewProfileParameters(JsonObject profilesConfigData, TenantId tenantId) { | 240 | public static LwM2mClientProfile getNewProfileParameters(JsonObject profilesConfigData, TenantId tenantId) { |
174 | LwM2mClientProfile lwM2MClientProfile = new LwM2mClientProfile(); | 241 | LwM2mClientProfile lwM2MClientProfile = new LwM2mClientProfile(); |
@@ -177,7 +244,7 @@ public class LwM2mTransportHandler { | @@ -177,7 +244,7 @@ public class LwM2mTransportHandler { | ||
177 | lwM2MClientProfile.setPostKeyNameProfile(profilesConfigData.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().get(KEY_NAME).getAsJsonObject()); | 244 | lwM2MClientProfile.setPostKeyNameProfile(profilesConfigData.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().get(KEY_NAME).getAsJsonObject()); |
178 | lwM2MClientProfile.setPostAttributeProfile(profilesConfigData.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().get(ATTRIBUTE).getAsJsonArray()); | 245 | lwM2MClientProfile.setPostAttributeProfile(profilesConfigData.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().get(ATTRIBUTE).getAsJsonArray()); |
179 | lwM2MClientProfile.setPostTelemetryProfile(profilesConfigData.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().get(TELEMETRY).getAsJsonArray()); | 246 | lwM2MClientProfile.setPostTelemetryProfile(profilesConfigData.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().get(TELEMETRY).getAsJsonArray()); |
180 | - lwM2MClientProfile.setPostObserveProfile(profilesConfigData.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().get(OBSERVE).getAsJsonArray()); | 247 | + lwM2MClientProfile.setPostObserveProfile(profilesConfigData.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().get(OBSERVE_LWM2M).getAsJsonArray()); |
181 | lwM2MClientProfile.setPostAttributeLwm2mProfile(profilesConfigData.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().get(ATTRIBUTE_LWM2M).getAsJsonObject()); | 248 | lwM2MClientProfile.setPostAttributeLwm2mProfile(profilesConfigData.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().get(ATTRIBUTE_LWM2M).getAsJsonObject()); |
182 | return lwM2MClientProfile; | 249 | return lwM2MClientProfile; |
183 | } | 250 | } |
@@ -198,8 +265,8 @@ public class LwM2mTransportHandler { | @@ -198,8 +265,8 @@ public class LwM2mTransportHandler { | ||
198 | * "telemetry":["/1/0/1","/2/0/1","/6/0/1"], | 265 | * "telemetry":["/1/0/1","/2/0/1","/6/0/1"], |
199 | * "observe":["/2/0","/2/0/0","/4/0/2"]} | 266 | * "observe":["/2/0","/2/0/0","/4/0/2"]} |
200 | * "attributeLwm2m": {"/3_1.0": {"ver": "currentTimeTest11"}, | 267 | * "attributeLwm2m": {"/3_1.0": {"ver": "currentTimeTest11"}, |
201 | - * "/3_1.0/0": {"gt": 17}, | ||
202 | - * "/3_1.0/0/9": {"pmax": 45}, "/3_1.2": {ver": "3_1.2"}} | 268 | + * "/3_1.0/0": {"gt": 17}, |
269 | + * "/3_1.0/0/9": {"pmax": 45}, "/3_1.2": {ver": "3_1.2"}} | ||
203 | */ | 270 | */ |
204 | public static LwM2mClientProfile getLwM2MClientProfileFromThingsboard(DeviceProfile deviceProfile) { | 271 | public static LwM2mClientProfile getLwM2MClientProfileFromThingsboard(DeviceProfile deviceProfile) { |
205 | if (deviceProfile != null && ((Lwm2mDeviceProfileTransportConfiguration) deviceProfile.getProfileData().getTransportConfiguration()).getProperties().size() > 0) { | 272 | if (deviceProfile != null && ((Lwm2mDeviceProfileTransportConfiguration) deviceProfile.getProfileData().getTransportConfiguration()).getProperties().size() > 0) { |
@@ -254,9 +321,9 @@ public class LwM2mTransportHandler { | @@ -254,9 +321,9 @@ public class LwM2mTransportHandler { | ||
254 | objectMsg.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().has(TELEMETRY) && | 321 | objectMsg.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().has(TELEMETRY) && |
255 | !objectMsg.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().get(TELEMETRY).isJsonNull() && | 322 | !objectMsg.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().get(TELEMETRY).isJsonNull() && |
256 | objectMsg.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().get(TELEMETRY).isJsonArray() && | 323 | objectMsg.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().get(TELEMETRY).isJsonArray() && |
257 | - objectMsg.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().has(OBSERVE) && | ||
258 | - !objectMsg.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().get(OBSERVE).isJsonNull() && | ||
259 | - objectMsg.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().get(OBSERVE).isJsonArray() && | 324 | + objectMsg.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().has(OBSERVE_LWM2M) && |
325 | + !objectMsg.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().get(OBSERVE_LWM2M).isJsonNull() && | ||
326 | + objectMsg.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().get(OBSERVE_LWM2M).isJsonArray() && | ||
260 | objectMsg.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().has(ATTRIBUTE_LWM2M) && | 327 | objectMsg.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().has(ATTRIBUTE_LWM2M) && |
261 | !objectMsg.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().get(ATTRIBUTE_LWM2M).isJsonNull() && | 328 | !objectMsg.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().get(ATTRIBUTE_LWM2M).isJsonNull() && |
262 | objectMsg.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().get(ATTRIBUTE_LWM2M).isJsonObject()); | 329 | objectMsg.get(OBSERVE_ATTRIBUTE_TELEMETRY).getAsJsonObject().get(ATTRIBUTE_LWM2M).isJsonObject()); |
@@ -341,8 +408,7 @@ public class LwM2mTransportHandler { | @@ -341,8 +408,7 @@ public class LwM2mTransportHandler { | ||
341 | if (keyArray.length > 1 && keyArray[1].split(LWM2M_SEPARATOR_KEY).length == 2) { | 408 | if (keyArray.length > 1 && keyArray[1].split(LWM2M_SEPARATOR_KEY).length == 2) { |
342 | keyArray[1] = keyArray[1].split(LWM2M_SEPARATOR_KEY)[0]; | 409 | keyArray[1] = keyArray[1].split(LWM2M_SEPARATOR_KEY)[0]; |
343 | return StringUtils.join(keyArray, LWM2M_SEPARATOR_PATH); | 410 | return StringUtils.join(keyArray, LWM2M_SEPARATOR_PATH); |
344 | - } | ||
345 | - else { | 411 | + } else { |
346 | return pathIdVer; | 412 | return pathIdVer; |
347 | } | 413 | } |
348 | } catch (Exception e) { | 414 | } catch (Exception e) { |
@@ -350,6 +416,37 @@ public class LwM2mTransportHandler { | @@ -350,6 +416,37 @@ public class LwM2mTransportHandler { | ||
350 | } | 416 | } |
351 | } | 417 | } |
352 | 418 | ||
419 | + /** | ||
420 | + * @param path - pathId or pathIdVer | ||
421 | + * @return | ||
422 | + */ | ||
423 | + public static String getVerFromPathIdVerOrId(String path) { | ||
424 | + try { | ||
425 | + String[] keyArray = path.split(LWM2M_SEPARATOR_PATH); | ||
426 | + if (keyArray.length > 1) { | ||
427 | + String[] keyArrayVer = keyArray[1].split(LWM2M_SEPARATOR_KEY); | ||
428 | + return keyArrayVer.length == 2 ? keyArrayVer[1] : null; | ||
429 | + } | ||
430 | + } catch (Exception e) { | ||
431 | + return null; | ||
432 | + } | ||
433 | + return null; | ||
434 | + } | ||
435 | + | ||
436 | + public static String validPathIdVer(String pathIdVer, Registration registration) throws IllegalArgumentException { | ||
437 | + if (pathIdVer.indexOf(LWM2M_SEPARATOR_PATH) < 0) { | ||
438 | + throw new IllegalArgumentException(String.format("Error:")); | ||
439 | + } else { | ||
440 | + String[] keyArray = pathIdVer.split(LWM2M_SEPARATOR_PATH); | ||
441 | + if (keyArray.length > 1 && keyArray[1].split(LWM2M_SEPARATOR_KEY).length == 2) { | ||
442 | + return pathIdVer; | ||
443 | + } else { | ||
444 | + LwM2mPath pathObjId = new LwM2mPath(pathIdVer); | ||
445 | + return convertPathFromObjectIdToIdVer(pathIdVer, registration); | ||
446 | + } | ||
447 | + } | ||
448 | + } | ||
449 | + | ||
353 | public static String convertPathFromObjectIdToIdVer(String path, Registration registration) { | 450 | public static String convertPathFromObjectIdToIdVer(String path, Registration registration) { |
354 | String ver = registration.getSupportedObject().get(new LwM2mPath(path).getObjectId()); | 451 | String ver = registration.getSupportedObject().get(new LwM2mPath(path).getObjectId()); |
355 | try { | 452 | try { |
@@ -357,8 +454,7 @@ public class LwM2mTransportHandler { | @@ -357,8 +454,7 @@ public class LwM2mTransportHandler { | ||
357 | if (keyArray.length > 1) { | 454 | if (keyArray.length > 1) { |
358 | keyArray[1] = keyArray[1] + LWM2M_SEPARATOR_KEY + ver; | 455 | keyArray[1] = keyArray[1] + LWM2M_SEPARATOR_KEY + ver; |
359 | return StringUtils.join(keyArray, LWM2M_SEPARATOR_PATH); | 456 | return StringUtils.join(keyArray, LWM2M_SEPARATOR_PATH); |
360 | - } | ||
361 | - else { | 457 | + } else { |
362 | return path; | 458 | return path; |
363 | } | 459 | } |
364 | } catch (Exception e) { | 460 | } catch (Exception e) { |
@@ -397,13 +493,13 @@ public class LwM2mTransportHandler { | @@ -397,13 +493,13 @@ public class LwM2mTransportHandler { | ||
397 | * when: | 493 | * when: |
398 | * a.old value is 17 and new value is 24 due to lt condition | 494 | * a.old value is 17 and new value is 24 due to lt condition |
399 | * b.old value is 75 and new value is 90 due to both gt and step conditions | 495 | * b.old value is 75 and new value is 90 due to both gt and step conditions |
400 | - * String uriQueries = "pmin=10&pmax=60"; | ||
401 | - * AttributeSet attributes = AttributeSet.parse(uriQueries); | ||
402 | - * WriteAttributesRequest request = new WriteAttributesRequest(target, attributes); | ||
403 | - * Attribute gt = new Attribute(GREATER_THAN, Double.valueOf("45")); | ||
404 | - * Attribute st = new Attribute(LESSER_THAN, Double.valueOf("10")); | ||
405 | - * Attribute pmax = new Attribute(MAXIMUM_PERIOD, "60"); | ||
406 | - * Attribute [] attrs = {gt, st}; | 496 | + * String uriQueries = "pmin=10&pmax=60"; |
497 | + * AttributeSet attributes = AttributeSet.parse(uriQueries); | ||
498 | + * WriteAttributesRequest request = new WriteAttributesRequest(target, attributes); | ||
499 | + * Attribute gt = new Attribute(GREATER_THAN, Double.valueOf("45")); | ||
500 | + * Attribute st = new Attribute(LESSER_THAN, Double.valueOf("10")); | ||
501 | + * Attribute pmax = new Attribute(MAXIMUM_PERIOD, "60"); | ||
502 | + * Attribute [] attrs = {gt, st}; | ||
407 | */ | 503 | */ |
408 | public static DownlinkRequest createWriteAttributeRequest(String target, Object params) { | 504 | public static DownlinkRequest createWriteAttributeRequest(String target, Object params) { |
409 | AttributeSet attrSet = new AttributeSet(createWriteAttributes(params)); | 505 | AttributeSet attrSet = new AttributeSet(createWriteAttributes(params)); |
@@ -423,4 +519,12 @@ public class LwM2mTransportHandler { | @@ -423,4 +519,12 @@ public class LwM2mTransportHandler { | ||
423 | }); | 519 | }); |
424 | return (Attribute[]) attributeLists.toArray(Attribute[]::new); | 520 | return (Attribute[]) attributeLists.toArray(Attribute[]::new); |
425 | } | 521 | } |
522 | + | ||
523 | + | ||
524 | + public static Set<String> convertJsonArrayToSet(JsonArray jsonArray) { | ||
525 | + List<String> attributeListOld = new Gson().fromJson(jsonArray, new TypeToken<List<String>>() { | ||
526 | + }.getType()); | ||
527 | + return Sets.newConcurrentHashSet(attributeListOld); | ||
528 | + } | ||
529 | + | ||
426 | } | 530 | } |
@@ -15,6 +15,7 @@ | @@ -15,6 +15,7 @@ | ||
15 | */ | 15 | */ |
16 | package org.thingsboard.server.transport.lwm2m.server; | 16 | package org.thingsboard.server.transport.lwm2m.server; |
17 | 17 | ||
18 | +import lombok.SneakyThrows; | ||
18 | import lombok.extern.slf4j.Slf4j; | 19 | import lombok.extern.slf4j.Slf4j; |
19 | import org.eclipse.californium.core.coap.CoAP; | 20 | import org.eclipse.californium.core.coap.CoAP; |
20 | import org.eclipse.californium.core.coap.Response; | 21 | import org.eclipse.californium.core.coap.Response; |
@@ -24,8 +25,8 @@ import org.eclipse.leshan.core.node.LwM2mPath; | @@ -24,8 +25,8 @@ import org.eclipse.leshan.core.node.LwM2mPath; | ||
24 | import org.eclipse.leshan.core.node.LwM2mSingleResource; | 25 | import org.eclipse.leshan.core.node.LwM2mSingleResource; |
25 | import org.eclipse.leshan.core.node.ObjectLink; | 26 | import org.eclipse.leshan.core.node.ObjectLink; |
26 | import org.eclipse.leshan.core.observation.Observation; | 27 | import org.eclipse.leshan.core.observation.Observation; |
27 | -import org.eclipse.leshan.core.request.CancelObservationRequest; | ||
28 | import org.eclipse.leshan.core.request.ContentFormat; | 28 | import org.eclipse.leshan.core.request.ContentFormat; |
29 | +import org.eclipse.leshan.core.request.DeleteRequest; | ||
29 | import org.eclipse.leshan.core.request.DiscoverRequest; | 30 | import org.eclipse.leshan.core.request.DiscoverRequest; |
30 | import org.eclipse.leshan.core.request.DownlinkRequest; | 31 | import org.eclipse.leshan.core.request.DownlinkRequest; |
31 | import org.eclipse.leshan.core.request.ExecuteRequest; | 32 | import org.eclipse.leshan.core.request.ExecuteRequest; |
@@ -47,27 +48,31 @@ import org.eclipse.leshan.core.util.NamedThreadFactory; | @@ -47,27 +48,31 @@ import org.eclipse.leshan.core.util.NamedThreadFactory; | ||
47 | import org.eclipse.leshan.server.californium.LeshanServer; | 48 | import org.eclipse.leshan.server.californium.LeshanServer; |
48 | import org.eclipse.leshan.server.registration.Registration; | 49 | import org.eclipse.leshan.server.registration.Registration; |
49 | import org.springframework.stereotype.Service; | 50 | import org.springframework.stereotype.Service; |
51 | +import org.thingsboard.server.common.transport.TransportService; | ||
50 | import org.thingsboard.server.queue.util.TbLwM2mTransportComponent; | 52 | import org.thingsboard.server.queue.util.TbLwM2mTransportComponent; |
51 | import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient; | 53 | import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient; |
52 | import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientContext; | 54 | import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientContext; |
55 | +import org.thingsboard.server.transport.lwm2m.server.client.Lwm2mClientRpcRequest; | ||
53 | import org.thingsboard.server.transport.lwm2m.utils.LwM2mValueConverterImpl; | 56 | import org.thingsboard.server.transport.lwm2m.utils.LwM2mValueConverterImpl; |
54 | 57 | ||
55 | import javax.annotation.PostConstruct; | 58 | import javax.annotation.PostConstruct; |
59 | +import java.util.Arrays; | ||
56 | import java.util.Date; | 60 | import java.util.Date; |
61 | +import java.util.Set; | ||
57 | import java.util.concurrent.ExecutorService; | 62 | import java.util.concurrent.ExecutorService; |
58 | import java.util.concurrent.Executors; | 63 | import java.util.concurrent.Executors; |
64 | +import java.util.stream.Collectors; | ||
59 | 65 | ||
66 | +import static org.eclipse.californium.core.coap.CoAP.ResponseCode.CONTENT; | ||
67 | +import static org.eclipse.leshan.core.ResponseCode.BAD_REQUEST; | ||
68 | +import static org.eclipse.leshan.core.ResponseCode.NOT_FOUND; | ||
60 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.DEFAULT_TIMEOUT; | 69 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.DEFAULT_TIMEOUT; |
61 | -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.GET_TYPE_OPER_DISCOVER; | ||
62 | -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.GET_TYPE_OPER_OBSERVE; | ||
63 | -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.GET_TYPE_OPER_READ; | ||
64 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LOG_LW2M_ERROR; | 70 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LOG_LW2M_ERROR; |
65 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LOG_LW2M_INFO; | 71 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LOG_LW2M_INFO; |
66 | -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.POST_TYPE_OPER_EXECUTE; | ||
67 | -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.POST_TYPE_OPER_OBSERVE_CANCEL; | ||
68 | -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.POST_TYPE_OPER_WRITE_REPLACE; | ||
69 | -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.PUT_TYPE_OPER_WRITE_ATTRIBUTES; | ||
70 | -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.PUT_TYPE_OPER_WRITE_UPDATE; | 72 | +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LOG_LW2M_VALUE; |
73 | +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LwM2mTypeOper; | ||
74 | +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LwM2mTypeOper.OBSERVE_CANCEL; | ||
75 | +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LwM2mTypeOper.OBSERVE_READ_ALL; | ||
71 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.RESPONSE_CHANNEL; | 76 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.RESPONSE_CHANNEL; |
72 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.convertPathFromIdVerToObjectId; | 77 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.convertPathFromIdVerToObjectId; |
73 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.convertPathFromObjectIdToIdVer; | 78 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.convertPathFromObjectIdToIdVer; |
@@ -79,7 +84,7 @@ import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandle | @@ -79,7 +84,7 @@ import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandle | ||
79 | public class LwM2mTransportRequest { | 84 | public class LwM2mTransportRequest { |
80 | private ExecutorService executorResponse; | 85 | private ExecutorService executorResponse; |
81 | 86 | ||
82 | - private LwM2mValueConverterImpl converter; | 87 | + public LwM2mValueConverterImpl converter; |
83 | 88 | ||
84 | private final LwM2mTransportContextServer lwM2mTransportContextServer; | 89 | private final LwM2mTransportContextServer lwM2mTransportContextServer; |
85 | 90 | ||
@@ -89,11 +94,16 @@ public class LwM2mTransportRequest { | @@ -89,11 +94,16 @@ public class LwM2mTransportRequest { | ||
89 | 94 | ||
90 | private final LwM2mTransportServiceImpl serviceImpl; | 95 | private final LwM2mTransportServiceImpl serviceImpl; |
91 | 96 | ||
92 | - public LwM2mTransportRequest(LwM2mTransportContextServer lwM2mTransportContextServer, LwM2mClientContext lwM2mClientContext, LeshanServer leshanServer, LwM2mTransportServiceImpl serviceImpl) { | 97 | + private final TransportService transportService; |
98 | + | ||
99 | + public LwM2mTransportRequest(LwM2mTransportContextServer lwM2mTransportContextServer, | ||
100 | + LwM2mClientContext lwM2mClientContext, LeshanServer leshanServer, | ||
101 | + LwM2mTransportServiceImpl serviceImpl, TransportService transportService) { | ||
93 | this.lwM2mTransportContextServer = lwM2mTransportContextServer; | 102 | this.lwM2mTransportContextServer = lwM2mTransportContextServer; |
94 | this.lwM2mClientContext = lwM2mClientContext; | 103 | this.lwM2mClientContext = lwM2mClientContext; |
95 | this.leshanServer = leshanServer; | 104 | this.leshanServer = leshanServer; |
96 | this.serviceImpl = serviceImpl; | 105 | this.serviceImpl = serviceImpl; |
106 | + this.transportService = transportService; | ||
97 | } | 107 | } |
98 | 108 | ||
99 | @PostConstruct | 109 | @PostConstruct |
@@ -106,108 +116,155 @@ public class LwM2mTransportRequest { | @@ -106,108 +116,155 @@ public class LwM2mTransportRequest { | ||
106 | /** | 116 | /** |
107 | * Device management and service enablement, including Read, Write, Execute, Discover, Create, Delete and Write-Attributes | 117 | * Device management and service enablement, including Read, Write, Execute, Discover, Create, Delete and Write-Attributes |
108 | * | 118 | * |
109 | - * @param registration - | ||
110 | - * @param targetIdVer - | ||
111 | - * @param typeOper - | ||
112 | - * @param contentFormatParam - | ||
113 | - * @param observation - | 119 | + * @param registration - |
120 | + * @param targetIdVer - | ||
121 | + * @param typeOper - | ||
122 | + * @param contentFormatName - | ||
114 | */ | 123 | */ |
115 | - public void sendAllRequest(Registration registration, String targetIdVer, String typeOper, | ||
116 | - String contentFormatParam, Observation observation, Object params, long timeoutInMs) { | ||
117 | - String target = convertPathFromIdVerToObjectId(targetIdVer); | ||
118 | - LwM2mPath resultIds = new LwM2mPath(target); | ||
119 | - if (registration != null && resultIds.getObjectId() >= 0) { | 124 | + @SneakyThrows |
125 | + public void sendAllRequest(Registration registration, String targetIdVer, LwM2mTypeOper typeOper, | ||
126 | + String contentFormatName, Object params, long timeoutInMs, Lwm2mClientRpcRequest rpcRequest) { | ||
127 | + try { | ||
128 | + | ||
129 | + String target = convertPathFromIdVerToObjectId(targetIdVer); | ||
120 | DownlinkRequest request = null; | 130 | DownlinkRequest request = null; |
121 | - ContentFormat contentFormat = contentFormatParam != null ? ContentFormat.fromName(contentFormatParam.toUpperCase()) : null; | ||
122 | - LwM2mClient lwM2MClient = lwM2mClientContext.getLwM2mClientWithReg(registration, null); | ||
123 | - ResourceModel resource = null; | ||
124 | - timeoutInMs = timeoutInMs > 0 ? timeoutInMs : DEFAULT_TIMEOUT; | ||
125 | - switch (typeOper) { | ||
126 | - case GET_TYPE_OPER_READ: | ||
127 | - request = new ReadRequest(contentFormat, target); | ||
128 | - break; | ||
129 | - case GET_TYPE_OPER_DISCOVER: | ||
130 | - request = new DiscoverRequest(target); | ||
131 | - break; | ||
132 | - case GET_TYPE_OPER_OBSERVE: | ||
133 | - if (resultIds.isResource()) { | ||
134 | - request = new ObserveRequest(resultIds.getObjectId(), resultIds.getObjectInstanceId(), resultIds.getResourceId()); | ||
135 | - } else if (resultIds.isObjectInstance()) { | ||
136 | - request = new ObserveRequest(resultIds.getObjectId(), resultIds.getObjectInstanceId()); | ||
137 | - } else if (resultIds.getObjectId() >= 0) { | ||
138 | - request = new ObserveRequest(resultIds.getObjectId()); | ||
139 | - } | ||
140 | - break; | ||
141 | - case POST_TYPE_OPER_OBSERVE_CANCEL: | ||
142 | - request = new CancelObservationRequest(observation); | ||
143 | - break; | ||
144 | - case POST_TYPE_OPER_EXECUTE: | ||
145 | - resource = lwM2MClient.getResourceModel(targetIdVer); | ||
146 | - if (params != null && resource != null && !resource.multiple) { | ||
147 | - request = new ExecuteRequest(target, (String) this.converter.convertValue(params, resource.type, ResourceModel.Type.STRING, resultIds)); | ||
148 | - } else { | ||
149 | - request = new ExecuteRequest(target); | ||
150 | - } | ||
151 | - break; | ||
152 | - case POST_TYPE_OPER_WRITE_REPLACE: | ||
153 | - // Request to write a <b>String Single-Instance Resource</b> using the TLV content format. | ||
154 | - resource = lwM2MClient.getResourceModel(targetIdVer); | ||
155 | - if (resource != null && contentFormat != null) { | 131 | + ContentFormat contentFormat = contentFormatName != null ? ContentFormat.fromName(contentFormatName.toUpperCase()) : ContentFormat.DEFAULT; |
132 | + LwM2mClient lwM2MClient = this.lwM2mClientContext.getLwM2mClientWithReg(registration, null); | ||
133 | + LwM2mPath resultIds = target != null ? new LwM2mPath(target) : null; | ||
134 | + if (!OBSERVE_READ_ALL.name().equals(typeOper.name()) && resultIds != null && registration != null && resultIds.getObjectId() >= 0 && | ||
135 | + lwM2MClient != null) { | ||
136 | + if (lwM2MClient.isValidObjectVersion(targetIdVer)) { | ||
137 | + timeoutInMs = timeoutInMs > 0 ? timeoutInMs : DEFAULT_TIMEOUT; | ||
138 | + ResourceModel resourceModel = null; | ||
139 | + switch (typeOper) { | ||
140 | + case READ: | ||
141 | + request = new ReadRequest(contentFormat, target); | ||
142 | + break; | ||
143 | + case DISCOVER: | ||
144 | + request = new DiscoverRequest(target); | ||
145 | + break; | ||
146 | + case OBSERVE: | ||
147 | + if (resultIds.isResource()) { | ||
148 | + request = new ObserveRequest(resultIds.getObjectId(), resultIds.getObjectInstanceId(), resultIds.getResourceId()); | ||
149 | + } else if (resultIds.isObjectInstance()) { | ||
150 | + request = new ObserveRequest(resultIds.getObjectId(), resultIds.getObjectInstanceId()); | ||
151 | + } else if (resultIds.getObjectId() >= 0) { | ||
152 | + request = new ObserveRequest(resultIds.getObjectId()); | ||
153 | + } | ||
154 | + break; | ||
155 | + case OBSERVE_CANCEL: | ||
156 | + /** | ||
157 | + * lwM2MTransportRequest.sendAllRequest(lwServer, registration, path, POST_TYPE_OPER_OBSERVE_CANCEL, null, null, null, null, context.getTimeout()); | ||
158 | + * At server side this will not remove the observation from the observation store, to do it you need to use | ||
159 | + * {@code ObservationService#cancelObservation()} | ||
160 | + */ | ||
161 | + leshanServer.getObservationService().cancelObservations(registration, target); | ||
162 | + break; | ||
163 | + case EXECUTE: | ||
164 | + resourceModel = lwM2MClient.getResourceModel(targetIdVer, this.lwM2mTransportContextServer.getLwM2MTransportConfigServer() | ||
165 | + .getModelProvider()); | ||
166 | + if (params != null && !resourceModel.multiple) { | ||
167 | + request = new ExecuteRequest(target, (String) this.converter.convertValue(params, resourceModel.type, ResourceModel.Type.STRING, resultIds)); | ||
168 | + } else { | ||
169 | + request = new ExecuteRequest(target); | ||
170 | + } | ||
171 | + break; | ||
172 | + case WRITE_REPLACE: | ||
173 | + // Request to write a <b>String Single-Instance Resource</b> using the TLV content format. | ||
174 | +// resource = lwM2MClient.getResourceModel(targetIdVer); | ||
156 | // if (contentFormat.equals(ContentFormat.TLV) && !resource.multiple) { | 175 | // if (contentFormat.equals(ContentFormat.TLV) && !resource.multiple) { |
157 | - if (contentFormat.equals(ContentFormat.TLV)) { | ||
158 | - request = this.getWriteRequestSingleResource(null, resultIds.getObjectId(), resultIds.getObjectInstanceId(), resultIds.getResourceId(), params, resource.type, registration); | ||
159 | - } | ||
160 | - // Mode.REPLACE && Request to write a <b>String Single-Instance Resource</b> using the given content format (TEXT, TLV, JSON) | 176 | + resourceModel = lwM2MClient.getResourceModel(targetIdVer, this.lwM2mTransportContextServer.getLwM2MTransportConfigServer() |
177 | + .getModelProvider()); | ||
178 | + if (contentFormat.equals(ContentFormat.TLV)) { | ||
179 | + request = this.getWriteRequestSingleResource(null, resultIds.getObjectId(), | ||
180 | + resultIds.getObjectInstanceId(), resultIds.getResourceId(), params, resourceModel.type, | ||
181 | + registration, rpcRequest); | ||
182 | + } | ||
183 | + // Mode.REPLACE && Request to write a <b>String Single-Instance Resource</b> using the given content format (TEXT, TLV, JSON) | ||
161 | // else if (!contentFormat.equals(ContentFormat.TLV) && !resource.multiple) { | 184 | // else if (!contentFormat.equals(ContentFormat.TLV) && !resource.multiple) { |
162 | - else if (!contentFormat.equals(ContentFormat.TLV)) { | ||
163 | - request = this.getWriteRequestSingleResource(contentFormat, resultIds.getObjectId(), resultIds.getObjectInstanceId(), resultIds.getResourceId(), params, resource.type, registration); | ||
164 | - } | ||
165 | - } | ||
166 | - break; | ||
167 | - case PUT_TYPE_OPER_WRITE_UPDATE: | ||
168 | - if (resultIds.getResourceId() >= 0) { | ||
169 | -// ResourceModel resourceModel = leshanServer.getModelProvider().getObjectModel(registration).getObjectModel(resultIds.getObjectId()).resources.get(resultIds.getResourceId()); | ||
170 | -// ResourceModel.Type typeRes = resourceModel.type; | ||
171 | - LwM2mNode node = LwM2mSingleResource.newStringResource(resultIds.getResourceId(), (String) this.converter.convertValue(params, resource.type, ResourceModel.Type.STRING, resultIds)); | ||
172 | - request = new WriteRequest(WriteRequest.Mode.UPDATE, contentFormat, target, node); | 185 | + else if (!contentFormat.equals(ContentFormat.TLV)) { |
186 | + request = this.getWriteRequestSingleResource(contentFormat, resultIds.getObjectId(), | ||
187 | + resultIds.getObjectInstanceId(), resultIds.getResourceId(), params, resourceModel.type, | ||
188 | + registration, rpcRequest); | ||
189 | + } | ||
190 | + break; | ||
191 | + case WRITE_UPDATE: | ||
192 | +// LwM2mNode node = null; | ||
193 | +// if (resultIds.isObjectInstance()) { | ||
194 | +// node = new LwM2mObjectInstance(resultIds.getObjectInstanceId(), lwM2MClient. | ||
195 | +// getNewResourcesForInstance(targetIdVer, this.lwM2mTransportContextServer.getLwM2MTransportConfigServer().getModelProvider(), | ||
196 | +// this.converter)); | ||
197 | +// request = new WriteRequest(WriteRequest.Mode.UPDATE, contentFormat, target, node); | ||
198 | +// } else if (resultIds.getObjectId() >= 0) { | ||
199 | +// request = new ObserveRequest(resultIds.getObjectId()); | ||
200 | +// } | ||
201 | + break; | ||
202 | + case WRITE_ATTRIBUTES: | ||
203 | + request = createWriteAttributeRequest(target, params); | ||
204 | + break; | ||
205 | + case DELETE: | ||
206 | + request = new DeleteRequest(target); | ||
207 | + break; | ||
173 | } | 208 | } |
174 | - break; | ||
175 | - case PUT_TYPE_OPER_WRITE_ATTRIBUTES: | ||
176 | - request = createWriteAttributeRequest(target, params); | ||
177 | - break; | ||
178 | - } | ||
179 | 209 | ||
180 | - if (request != null) { | ||
181 | - try { | ||
182 | - this.sendRequest(registration, lwM2MClient, request, timeoutInMs); | ||
183 | - } catch (ClientSleepingException e) { | ||
184 | - DownlinkRequest finalRequest = request; | ||
185 | - long finalTimeoutInMs = timeoutInMs; | ||
186 | - lwM2MClient.getQueuedRequests().add(() -> sendRequest(registration, lwM2MClient, finalRequest, finalTimeoutInMs)); | ||
187 | - } catch (Exception e) { | ||
188 | - log.error("[{}] [{}] [{}] Failed to send downlink.", registration.getEndpoint(), targetIdVer, typeOper, e); | 210 | + if (request != null) { |
211 | + try { | ||
212 | + this.sendRequest(registration, lwM2MClient, request, timeoutInMs, rpcRequest); | ||
213 | + } catch (ClientSleepingException e) { | ||
214 | + DownlinkRequest finalRequest = request; | ||
215 | + long finalTimeoutInMs = timeoutInMs; | ||
216 | + lwM2MClient.getQueuedRequests().add(() -> sendRequest(registration, lwM2MClient, finalRequest, finalTimeoutInMs, rpcRequest)); | ||
217 | + } catch (Exception e) { | ||
218 | + log.error("[{}] [{}] [{}] Failed to send downlink.", registration.getEndpoint(), targetIdVer, typeOper, e); | ||
219 | + } | ||
220 | + } else if (OBSERVE_CANCEL == typeOper && rpcRequest != null) { | ||
221 | + rpcRequest.setInfoMsg(null); | ||
222 | + serviceImpl.sentRpcRequest(rpcRequest, CONTENT.name(), null, null); | ||
223 | + } else { | ||
224 | + log.error("[{}], [{}] - [{}] error SendRequest", registration.getEndpoint(), typeOper, targetIdVer); | ||
225 | + if (rpcRequest != null) { | ||
226 | + String errorMsg = resourceModel == null ? String.format("Path %s not found in object version", targetIdVer) : "SendRequest - null"; | ||
227 | + serviceImpl.sentRpcRequest(rpcRequest, NOT_FOUND.getName(), errorMsg, LOG_LW2M_ERROR); | ||
228 | + } | ||
229 | + } | ||
230 | + } else if (rpcRequest != null) { | ||
231 | + String errorMsg = String.format("Path %s not found in object version", targetIdVer); | ||
232 | + serviceImpl.sentRpcRequest(rpcRequest, NOT_FOUND.getName(), errorMsg, LOG_LW2M_ERROR); | ||
233 | + } | ||
234 | + } else if (OBSERVE_READ_ALL.name().equals(typeOper.name())) { | ||
235 | + Set<Observation> observations = leshanServer.getObservationService().getObservations(registration); | ||
236 | + Set<String> observationPaths = observations.stream().map(observation -> observation.getPath().toString()).collect(Collectors.toUnmodifiableSet()); | ||
237 | + String msg = String.format("%s: type operation %s observation paths - %s", LOG_LW2M_INFO, | ||
238 | + OBSERVE_READ_ALL.type, observationPaths); | ||
239 | + serviceImpl.sendLogsToThingsboard(msg, registration); | ||
240 | + log.info("[{}], [{}]", registration.getEndpoint(), msg); | ||
241 | + if (rpcRequest != null) { | ||
242 | + String valueMsg = String.format("Observation paths - %s", observationPaths); | ||
243 | + serviceImpl.sentRpcRequest(rpcRequest, CONTENT.name(), valueMsg, LOG_LW2M_VALUE); | ||
189 | } | 244 | } |
190 | - } else { | ||
191 | - log.error("[{}], [{}] - [{}] error SendRequest", registration.getEndpoint(), typeOper, targetIdVer); | ||
192 | } | 245 | } |
246 | + } catch (Exception e) { | ||
247 | + String msg = String.format("%s: type operation %s %s", LOG_LW2M_ERROR, | ||
248 | + typeOper.name(), e.getMessage()); | ||
249 | + serviceImpl.sendLogsToThingsboard(msg, registration); | ||
250 | + throw new Exception(e); | ||
193 | } | 251 | } |
194 | } | 252 | } |
195 | 253 | ||
196 | /** | 254 | /** |
197 | - * | ||
198 | * @param registration - | 255 | * @param registration - |
199 | - * @param request - | ||
200 | - * @param timeoutInMs - | 256 | + * @param request - |
257 | + * @param timeoutInMs - | ||
201 | */ | 258 | */ |
202 | 259 | ||
203 | @SuppressWarnings("unchecked") | 260 | @SuppressWarnings("unchecked") |
204 | - private void sendRequest(Registration registration, LwM2mClient lwM2MClient, DownlinkRequest request, long timeoutInMs) { | 261 | + private void sendRequest(Registration registration, LwM2mClient lwM2MClient, DownlinkRequest request, long timeoutInMs, Lwm2mClientRpcRequest rpcRequest) { |
205 | leshanServer.send(registration, request, timeoutInMs, (ResponseCallback<?>) response -> { | 262 | leshanServer.send(registration, request, timeoutInMs, (ResponseCallback<?>) response -> { |
206 | if (!lwM2MClient.isInit()) { | 263 | if (!lwM2MClient.isInit()) { |
207 | lwM2MClient.initValue(this.serviceImpl, convertPathFromObjectIdToIdVer(request.getPath().toString(), registration)); | 264 | lwM2MClient.initValue(this.serviceImpl, convertPathFromObjectIdToIdVer(request.getPath().toString(), registration)); |
208 | } | 265 | } |
209 | if (CoAP.ResponseCode.isSuccess(((Response) response.getCoapResponse()).getCode())) { | 266 | if (CoAP.ResponseCode.isSuccess(((Response) response.getCoapResponse()).getCode())) { |
210 | - this.handleResponse(registration, request.getPath().toString(), response, request); | 267 | + this.handleResponse(registration, request.getPath().toString(), response, request, rpcRequest); |
211 | if (request instanceof WriteRequest && ((WriteRequest) request).isReplaceRequest()) { | 268 | if (request instanceof WriteRequest && ((WriteRequest) request).isReplaceRequest()) { |
212 | LwM2mNode node = ((WriteRequest) request).getNode(); | 269 | LwM2mNode node = ((WriteRequest) request).getNode(); |
213 | Object value = this.converter.convertValue(((LwM2mSingleResource) node).getValue(), | 270 | Object value = this.converter.convertValue(((LwM2mSingleResource) node).getValue(), |
@@ -216,48 +273,64 @@ public class LwM2mTransportRequest { | @@ -216,48 +273,64 @@ public class LwM2mTransportRequest { | ||
216 | LOG_LW2M_INFO, ((Response) response.getCoapResponse()).getCode(), response.getCode().getCode(), | 273 | LOG_LW2M_INFO, ((Response) response.getCoapResponse()).getCode(), response.getCode().getCode(), |
217 | response.getCode().getName(), request.getPath().toString(), value); | 274 | response.getCode().getName(), request.getPath().toString(), value); |
218 | serviceImpl.sendLogsToThingsboard(msg, registration); | 275 | serviceImpl.sendLogsToThingsboard(msg, registration); |
219 | - log.debug("[{}] [{}] - [{}] [{}] Update SendRequest[{}]", registration.getEndpoint(), | 276 | + log.info("[{}] [{}] - [{}] [{}] Update SendRequest[{}]", registration.getEndpoint(), |
220 | ((Response) response.getCoapResponse()).getCode(), response.getCode(), | 277 | ((Response) response.getCoapResponse()).getCode(), response.getCode(), |
221 | request.getPath().toString(), value); | 278 | request.getPath().toString(), value); |
279 | + serviceImpl.sentRpcRequest(rpcRequest, response.getCode().getName(), null, LOG_LW2M_INFO); | ||
222 | } | 280 | } |
223 | } else { | 281 | } else { |
224 | String msg = String.format("%s: sendRequest: CoapCode - %s Lwm2m code - %d name - %s Resource path - %s SendRequest to Client", LOG_LW2M_ERROR, | 282 | String msg = String.format("%s: sendRequest: CoapCode - %s Lwm2m code - %d name - %s Resource path - %s SendRequest to Client", LOG_LW2M_ERROR, |
225 | ((Response) response.getCoapResponse()).getCode(), response.getCode().getCode(), response.getCode().getName(), request.getPath().toString()); | 283 | ((Response) response.getCoapResponse()).getCode(), response.getCode().getCode(), response.getCode().getName(), request.getPath().toString()); |
226 | serviceImpl.sendLogsToThingsboard(msg, registration); | 284 | serviceImpl.sendLogsToThingsboard(msg, registration); |
227 | log.error("[{}], [{}] - [{}] [{}] error SendRequest", registration.getEndpoint(), ((Response) response.getCoapResponse()).getCode(), response.getCode(), request.getPath().toString()); | 285 | log.error("[{}], [{}] - [{}] [{}] error SendRequest", registration.getEndpoint(), ((Response) response.getCoapResponse()).getCode(), response.getCode(), request.getPath().toString()); |
286 | + if (rpcRequest != null) { | ||
287 | + serviceImpl.sentRpcRequest(rpcRequest, response.getCode().getName(), response.getErrorMessage(), LOG_LW2M_ERROR); | ||
288 | + } | ||
228 | } | 289 | } |
229 | }, e -> { | 290 | }, e -> { |
230 | if (!lwM2MClient.isInit()) { | 291 | if (!lwM2MClient.isInit()) { |
231 | lwM2MClient.initValue(this.serviceImpl, convertPathFromObjectIdToIdVer(request.getPath().toString(), registration)); | 292 | lwM2MClient.initValue(this.serviceImpl, convertPathFromObjectIdToIdVer(request.getPath().toString(), registration)); |
232 | } | 293 | } |
233 | String msg = String.format("%s: sendRequest: Resource path - %s msg error - %s SendRequest to Client", | 294 | String msg = String.format("%s: sendRequest: Resource path - %s msg error - %s SendRequest to Client", |
234 | - LOG_LW2M_ERROR, request.getPath().toString(), e.toString()); | 295 | + LOG_LW2M_ERROR, request.getPath().toString(), e.getMessage()); |
235 | serviceImpl.sendLogsToThingsboard(msg, registration); | 296 | serviceImpl.sendLogsToThingsboard(msg, registration); |
236 | log.error("[{}] - [{}] error SendRequest", request.getPath().toString(), e.toString()); | 297 | log.error("[{}] - [{}] error SendRequest", request.getPath().toString(), e.toString()); |
298 | + if (rpcRequest != null) { | ||
299 | + serviceImpl.sentRpcRequest(rpcRequest, CoAP.CodeClass.ERROR_RESPONSE.name(), e.getMessage(), LOG_LW2M_ERROR); | ||
300 | + } | ||
237 | }); | 301 | }); |
238 | 302 | ||
239 | } | 303 | } |
240 | 304 | ||
241 | - private WriteRequest getWriteRequestSingleResource(ContentFormat contentFormat, Integer objectId, Integer instanceId, Integer resourceId, Object value, ResourceModel.Type type, Registration registration) { | 305 | + private WriteRequest getWriteRequestSingleResource(ContentFormat contentFormat, Integer objectId, Integer instanceId, |
306 | + Integer resourceId, Object value, ResourceModel.Type type, | ||
307 | + Registration registration, Lwm2mClientRpcRequest rpcRequest) { | ||
242 | try { | 308 | try { |
243 | - switch (type) { | ||
244 | - case STRING: // String | ||
245 | - return (contentFormat == null) ? new WriteRequest(objectId, instanceId, resourceId, value.toString()) : new WriteRequest(contentFormat, objectId, instanceId, resourceId, value.toString()); | ||
246 | - case INTEGER: // Long | ||
247 | - final long valueInt = Integer.toUnsignedLong(Integer.parseInt(value.toString())); | ||
248 | - return (contentFormat == null) ? new WriteRequest(objectId, instanceId, resourceId, valueInt) : new WriteRequest(contentFormat, objectId, instanceId, resourceId, valueInt); | ||
249 | - case OBJLNK: // ObjectLink | ||
250 | - return (contentFormat == null) ? new WriteRequest(objectId, instanceId, resourceId, ObjectLink.fromPath(value.toString())) : new WriteRequest(contentFormat, objectId, instanceId, resourceId, ObjectLink.fromPath(value.toString())); | ||
251 | - case BOOLEAN: // Boolean | ||
252 | - return (contentFormat == null) ? new WriteRequest(objectId, instanceId, resourceId, Boolean.parseBoolean(value.toString())) : new WriteRequest(contentFormat, objectId, instanceId, resourceId, Boolean.parseBoolean(value.toString())); | ||
253 | - case FLOAT: // Double | ||
254 | - return (contentFormat == null) ? new WriteRequest(objectId, instanceId, resourceId, Double.parseDouble(value.toString())) : new WriteRequest(contentFormat, objectId, instanceId, resourceId, Double.parseDouble(value.toString())); | ||
255 | - case TIME: // Date | ||
256 | - Date date = new Date(Long.decode(value.toString())); | ||
257 | - return (contentFormat == null) ? new WriteRequest(objectId, instanceId, resourceId, date) : new WriteRequest(contentFormat, objectId, instanceId, resourceId, date); | ||
258 | - case OPAQUE: // byte[] value, base64 | ||
259 | - return (contentFormat == null) ? new WriteRequest(objectId, instanceId, resourceId, Hex.decodeHex(value.toString().toCharArray())) : new WriteRequest(contentFormat, objectId, instanceId, resourceId, Hex.decodeHex(value.toString().toCharArray())); | ||
260 | - default: | 309 | + if (type != null) { |
310 | + switch (type) { | ||
311 | + case STRING: // String | ||
312 | + return (contentFormat == null) ? new WriteRequest(objectId, instanceId, resourceId, value.toString()) : new WriteRequest(contentFormat, objectId, instanceId, resourceId, value.toString()); | ||
313 | + case INTEGER: // Long | ||
314 | + final long valueInt = Integer.toUnsignedLong(Integer.parseInt(value.toString())); | ||
315 | + return (contentFormat == null) ? new WriteRequest(objectId, instanceId, resourceId, valueInt) : new WriteRequest(contentFormat, objectId, instanceId, resourceId, valueInt); | ||
316 | + case OBJLNK: // ObjectLink | ||
317 | + return (contentFormat == null) ? new WriteRequest(objectId, instanceId, resourceId, ObjectLink.fromPath(value.toString())) : new WriteRequest(contentFormat, objectId, instanceId, resourceId, ObjectLink.fromPath(value.toString())); | ||
318 | + case BOOLEAN: // Boolean | ||
319 | + return (contentFormat == null) ? new WriteRequest(objectId, instanceId, resourceId, Boolean.parseBoolean(value.toString())) : new WriteRequest(contentFormat, objectId, instanceId, resourceId, Boolean.parseBoolean(value.toString())); | ||
320 | + case FLOAT: // Double | ||
321 | + return (contentFormat == null) ? new WriteRequest(objectId, instanceId, resourceId, Double.parseDouble(value.toString())) : new WriteRequest(contentFormat, objectId, instanceId, resourceId, Double.parseDouble(value.toString())); | ||
322 | + case TIME: // Date | ||
323 | + Date date = new Date(Long.decode(value.toString())); | ||
324 | + return (contentFormat == null) ? new WriteRequest(objectId, instanceId, resourceId, date) : new WriteRequest(contentFormat, objectId, instanceId, resourceId, date); | ||
325 | + case OPAQUE: // byte[] value, base64 | ||
326 | + return (contentFormat == null) ? new WriteRequest(objectId, instanceId, resourceId, Hex.decodeHex(value.toString().toCharArray())) : new WriteRequest(contentFormat, objectId, instanceId, resourceId, Hex.decodeHex(value.toString().toCharArray())); | ||
327 | + default: | ||
328 | + } | ||
329 | + } | ||
330 | + if (rpcRequest != null) { | ||
331 | + String patn = "/" + objectId + "/" + instanceId + "/" + resourceId; | ||
332 | + String errorMsg = String.format("Bad ResourceModel Operations (E): Resource path - %s ResourceModel type - %s", patn, type); | ||
333 | + rpcRequest.setErrorMsg(errorMsg); | ||
261 | } | 334 | } |
262 | return null; | 335 | return null; |
263 | } catch (NumberFormatException e) { | 336 | } catch (NumberFormatException e) { |
@@ -266,14 +339,19 @@ public class LwM2mTransportRequest { | @@ -266,14 +339,19 @@ public class LwM2mTransportRequest { | ||
266 | patn, type, value, e.toString()); | 339 | patn, type, value, e.toString()); |
267 | serviceImpl.sendLogsToThingsboard(msg, registration); | 340 | serviceImpl.sendLogsToThingsboard(msg, registration); |
268 | log.error("Path: [{}] type: [{}] value: [{}] errorMsg: [{}]]", patn, type, value, e.toString()); | 341 | log.error("Path: [{}] type: [{}] value: [{}] errorMsg: [{}]]", patn, type, value, e.toString()); |
342 | + if (rpcRequest != null) { | ||
343 | + String errorMsg = String.format("NumberFormatException: Resource path - %s type - %s value - %s", patn, type, value); | ||
344 | + serviceImpl.sentRpcRequest(rpcRequest, BAD_REQUEST.getName(), errorMsg, LOG_LW2M_ERROR); | ||
345 | + } | ||
269 | return null; | 346 | return null; |
270 | } | 347 | } |
271 | } | 348 | } |
272 | 349 | ||
273 | - private void handleResponse(Registration registration, final String path, LwM2mResponse response, DownlinkRequest request) { | 350 | + private void handleResponse(Registration registration, final String path, LwM2mResponse response, |
351 | + DownlinkRequest request, Lwm2mClientRpcRequest rpcRequest) { | ||
274 | executorResponse.submit(() -> { | 352 | executorResponse.submit(() -> { |
275 | try { | 353 | try { |
276 | - sendResponse(registration, path, response, request); | 354 | + this.sendResponse(registration, path, response, request, rpcRequest); |
277 | } catch (Exception e) { | 355 | } catch (Exception e) { |
278 | log.error("[{}] endpoint [{}] path [{}] Exception Unable to after send response.", registration.getEndpoint(), path, e); | 356 | log.error("[{}] endpoint [{}] path [{}] Exception Unable to after send response.", registration.getEndpoint(), path, e); |
279 | } | 357 | } |
@@ -282,20 +360,30 @@ public class LwM2mTransportRequest { | @@ -282,20 +360,30 @@ public class LwM2mTransportRequest { | ||
282 | 360 | ||
283 | /** | 361 | /** |
284 | * processing a response from a client | 362 | * processing a response from a client |
363 | + * | ||
285 | * @param registration - | 364 | * @param registration - |
286 | - * @param path - | ||
287 | - * @param response - | 365 | + * @param path - |
366 | + * @param response - | ||
288 | */ | 367 | */ |
289 | - private void sendResponse(Registration registration, String path, LwM2mResponse response, DownlinkRequest request) { | 368 | + private void sendResponse(Registration registration, String path, LwM2mResponse response, |
369 | + DownlinkRequest request, Lwm2mClientRpcRequest rpcRequest) { | ||
290 | String pathIdVer = convertPathFromObjectIdToIdVer(path, registration); | 370 | String pathIdVer = convertPathFromObjectIdToIdVer(path, registration); |
291 | if (response instanceof ReadResponse) { | 371 | if (response instanceof ReadResponse) { |
292 | - serviceImpl.onObservationResponse(registration, pathIdVer, (ReadResponse) response); | 372 | + serviceImpl.onObservationResponse(registration, pathIdVer, (ReadResponse) response, rpcRequest); |
293 | } else if (response instanceof CancelObservationResponse) { | 373 | } else if (response instanceof CancelObservationResponse) { |
294 | log.info("[{}] Path [{}] CancelObservationResponse 3_Send", pathIdVer, response); | 374 | log.info("[{}] Path [{}] CancelObservationResponse 3_Send", pathIdVer, response); |
375 | + | ||
295 | } else if (response instanceof DeleteResponse) { | 376 | } else if (response instanceof DeleteResponse) { |
296 | log.info("[{}] Path [{}] DeleteResponse 5_Send", pathIdVer, response); | 377 | log.info("[{}] Path [{}] DeleteResponse 5_Send", pathIdVer, response); |
297 | } else if (response instanceof DiscoverResponse) { | 378 | } else if (response instanceof DiscoverResponse) { |
298 | - log.info("[{}] Path [{}] DiscoverResponse 6_Send", pathIdVer, response); | 379 | + log.info("[{}] [{}] - [{}] [{}] Discovery value: [{}]", registration.getEndpoint(), |
380 | + ((Response) response.getCoapResponse()).getCode(), response.getCode(), | ||
381 | + request.getPath().toString(), ((DiscoverResponse) response).getObjectLinks()); | ||
382 | + if (rpcRequest != null) { | ||
383 | + String discoveryMsg = String.format("%s", | ||
384 | + Arrays.stream(((DiscoverResponse) response).getObjectLinks()).collect(Collectors.toSet())); | ||
385 | + serviceImpl.sentRpcRequest(rpcRequest, response.getCode().getName(), discoveryMsg, LOG_LW2M_VALUE); | ||
386 | + } | ||
299 | } else if (response instanceof ExecuteResponse) { | 387 | } else if (response instanceof ExecuteResponse) { |
300 | log.info("[{}] Path [{}] ExecuteResponse 7_Send", pathIdVer, response); | 388 | log.info("[{}] Path [{}] ExecuteResponse 7_Send", pathIdVer, response); |
301 | } else if (response instanceof WriteAttributesResponse) { | 389 | } else if (response instanceof WriteAttributesResponse) { |
@@ -304,5 +392,11 @@ public class LwM2mTransportRequest { | @@ -304,5 +392,11 @@ public class LwM2mTransportRequest { | ||
304 | log.info("[{}] Path [{}] WriteAttributesResponse 9_Send", pathIdVer, response); | 392 | log.info("[{}] Path [{}] WriteAttributesResponse 9_Send", pathIdVer, response); |
305 | serviceImpl.onWriteResponseOk(registration, pathIdVer, (WriteRequest) request); | 393 | serviceImpl.onWriteResponseOk(registration, pathIdVer, (WriteRequest) request); |
306 | } | 394 | } |
395 | + if (rpcRequest != null && (response instanceof ExecuteResponse | ||
396 | + || response instanceof WriteAttributesResponse | ||
397 | + || response instanceof DeleteResponse)) { | ||
398 | + rpcRequest.setInfoMsg(null); | ||
399 | + serviceImpl.sentRpcRequest(rpcRequest, response.getCode().getName(), null, null); | ||
400 | + } | ||
307 | } | 401 | } |
308 | } | 402 | } |
@@ -21,6 +21,7 @@ import org.eclipse.leshan.server.registration.Registration; | @@ -21,6 +21,7 @@ import org.eclipse.leshan.server.registration.Registration; | ||
21 | import org.thingsboard.server.common.data.Device; | 21 | import org.thingsboard.server.common.data.Device; |
22 | import org.thingsboard.server.common.data.DeviceProfile; | 22 | import org.thingsboard.server.common.data.DeviceProfile; |
23 | import org.thingsboard.server.gen.transport.TransportProtos; | 23 | import org.thingsboard.server.gen.transport.TransportProtos; |
24 | +import org.thingsboard.server.transport.lwm2m.server.client.Lwm2mClientRpcRequest; | ||
24 | 25 | ||
25 | import java.util.Collection; | 26 | import java.util.Collection; |
26 | import java.util.Optional; | 27 | import java.util.Optional; |
@@ -37,9 +38,7 @@ public interface LwM2mTransportService { | @@ -37,9 +38,7 @@ public interface LwM2mTransportService { | ||
37 | 38 | ||
38 | void setCancelObservations(Registration registration); | 39 | void setCancelObservations(Registration registration); |
39 | 40 | ||
40 | - void setCancelObservationRecourse(Registration registration, String path); | ||
41 | - | ||
42 | - void onObservationResponse(Registration registration, String path, ReadResponse response); | 41 | + void onObservationResponse(Registration registration, String path, ReadResponse response, Lwm2mClientRpcRequest rpcRequest); |
43 | 42 | ||
44 | void onAttributeUpdate(TransportProtos.AttributeUpdateNotificationMsg msg, TransportProtos.SessionInfoProto sessionInfo); | 43 | void onAttributeUpdate(TransportProtos.AttributeUpdateNotificationMsg msg, TransportProtos.SessionInfoProto sessionInfo); |
45 | 44 | ||
@@ -51,7 +50,9 @@ public interface LwM2mTransportService { | @@ -51,7 +50,9 @@ public interface LwM2mTransportService { | ||
51 | 50 | ||
52 | void onResourceDelete(Optional<TransportProtos.ResourceDeleteMsg> resourceDeleteMsgOpt); | 51 | void onResourceDelete(Optional<TransportProtos.ResourceDeleteMsg> resourceDeleteMsgOpt); |
53 | 52 | ||
54 | - void onToDeviceRpcRequest(TransportProtos.ToDeviceRpcRequestMsg toDeviceRequest); | 53 | + void onToDeviceRpcRequest(TransportProtos.ToDeviceRpcRequestMsg toDeviceRequest, TransportProtos.SessionInfoProto sessionInfo); |
54 | + | ||
55 | + void onToDeviceRpcResponse(TransportProtos.ToDeviceRpcResponseMsg toDeviceRpcResponse, TransportProtos.SessionInfoProto sessionInfo); | ||
55 | 56 | ||
56 | void onToServerRpcResponse(TransportProtos.ToServerRpcResponseMsg toServerResponse); | 57 | void onToServerRpcResponse(TransportProtos.ToServerRpcResponseMsg toServerResponse); |
57 | 58 |
@@ -16,7 +16,6 @@ | @@ -16,7 +16,6 @@ | ||
16 | package org.thingsboard.server.transport.lwm2m.server; | 16 | package org.thingsboard.server.transport.lwm2m.server; |
17 | 17 | ||
18 | import com.fasterxml.jackson.core.type.TypeReference; | 18 | import com.fasterxml.jackson.core.type.TypeReference; |
19 | -import com.google.common.collect.Sets; | ||
20 | import com.google.gson.Gson; | 19 | import com.google.gson.Gson; |
21 | import com.google.gson.GsonBuilder; | 20 | import com.google.gson.GsonBuilder; |
22 | import com.google.gson.JsonArray; | 21 | import com.google.gson.JsonArray; |
@@ -52,6 +51,7 @@ import org.thingsboard.server.queue.util.TbLwM2mTransportComponent; | @@ -52,6 +51,7 @@ import org.thingsboard.server.queue.util.TbLwM2mTransportComponent; | ||
52 | import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient; | 51 | import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClient; |
53 | import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientContext; | 52 | import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientContext; |
54 | import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientProfile; | 53 | import org.thingsboard.server.transport.lwm2m.server.client.LwM2mClientProfile; |
54 | +import org.thingsboard.server.transport.lwm2m.server.client.Lwm2mClientRpcRequest; | ||
55 | import org.thingsboard.server.transport.lwm2m.server.client.ResultsAddKeyValueProto; | 55 | import org.thingsboard.server.transport.lwm2m.server.client.ResultsAddKeyValueProto; |
56 | import org.thingsboard.server.transport.lwm2m.server.client.ResultsAnalyzerParameters; | 56 | import org.thingsboard.server.transport.lwm2m.server.client.ResultsAnalyzerParameters; |
57 | import org.thingsboard.server.transport.lwm2m.utils.LwM2mValueConverterImpl; | 57 | import org.thingsboard.server.transport.lwm2m.utils.LwM2mValueConverterImpl; |
@@ -74,21 +74,29 @@ import java.util.concurrent.Executors; | @@ -74,21 +74,29 @@ import java.util.concurrent.Executors; | ||
74 | import java.util.concurrent.TimeUnit; | 74 | import java.util.concurrent.TimeUnit; |
75 | import java.util.stream.Collectors; | 75 | import java.util.stream.Collectors; |
76 | 76 | ||
77 | +import static org.eclipse.californium.core.coap.CoAP.ResponseCode.BAD_REQUEST; | ||
77 | import static org.eclipse.leshan.core.attributes.Attribute.OBJECT_VERSION; | 78 | import static org.eclipse.leshan.core.attributes.Attribute.OBJECT_VERSION; |
78 | import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPARATOR_PATH; | 79 | import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPARATOR_PATH; |
79 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.CLIENT_NOT_AUTHORIZED; | 80 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.CLIENT_NOT_AUTHORIZED; |
80 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.DEVICE_ATTRIBUTES_REQUEST; | 81 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.DEVICE_ATTRIBUTES_REQUEST; |
81 | -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.GET_TYPE_OPER_DISCOVER; | ||
82 | -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.GET_TYPE_OPER_OBSERVE; | ||
83 | -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.GET_TYPE_OPER_READ; | ||
84 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LOG_LW2M_ERROR; | 82 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LOG_LW2M_ERROR; |
85 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LOG_LW2M_INFO; | 83 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LOG_LW2M_INFO; |
84 | +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LOG_LW2M_VALUE; | ||
86 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LWM2M_STRATEGY_2; | 85 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LWM2M_STRATEGY_2; |
87 | -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.POST_TYPE_OPER_EXECUTE; | ||
88 | -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.POST_TYPE_OPER_WRITE_REPLACE; | ||
89 | -import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.PUT_TYPE_OPER_WRITE_ATTRIBUTES; | 86 | +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LwM2mTypeOper; |
87 | +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LwM2mTypeOper.DISCOVER; | ||
88 | +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LwM2mTypeOper.EXECUTE; | ||
89 | +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LwM2mTypeOper.OBSERVE; | ||
90 | +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LwM2mTypeOper.OBSERVE_CANCEL; | ||
91 | +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LwM2mTypeOper.OBSERVE_READ_ALL; | ||
92 | +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LwM2mTypeOper.READ; | ||
93 | +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LwM2mTypeOper.WRITE_ATTRIBUTES; | ||
94 | +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LwM2mTypeOper.WRITE_REPLACE; | ||
95 | +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LwM2mTypeOper.WRITE_UPDATE; | ||
90 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.SERVICE_CHANNEL; | 96 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.SERVICE_CHANNEL; |
97 | +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.convertJsonArrayToSet; | ||
91 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.convertPathFromIdVerToObjectId; | 98 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.convertPathFromIdVerToObjectId; |
99 | +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.convertPathFromObjectIdToIdVer; | ||
92 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.getAckCallback; | 100 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.getAckCallback; |
93 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.validateObjectVerFromKey; | 101 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.validateObjectVerFromKey; |
94 | 102 | ||
@@ -257,21 +265,13 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | @@ -257,21 +265,13 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | ||
257 | public void setCancelObservations(Registration registration) { | 265 | public void setCancelObservations(Registration registration) { |
258 | if (registration != null) { | 266 | if (registration != null) { |
259 | Set<Observation> observations = leshanServer.getObservationService().getObservations(registration); | 267 | Set<Observation> observations = leshanServer.getObservationService().getObservations(registration); |
260 | - observations.forEach(observation -> this.setCancelObservationRecourse(registration, observation.getPath().toString())); | 268 | + observations.forEach(observation -> lwM2mTransportRequest.sendAllRequest(registration, |
269 | + convertPathFromObjectIdToIdVer(observation.getPath().toString(), registration), OBSERVE_CANCEL, | ||
270 | + null, null, this.lwM2mTransportContextServer.getLwM2MTransportConfigServer().getTimeout(), null)); | ||
261 | } | 271 | } |
262 | } | 272 | } |
263 | 273 | ||
264 | /** | 274 | /** |
265 | - * lwM2MTransportRequest.sendAllRequest(lwServer, registration, path, POST_TYPE_OPER_OBSERVE_CANCEL, null, null, null, null, context.getTimeout()); | ||
266 | - * At server side this will not remove the observation from the observation store, to do it you need to use | ||
267 | - * {@code ObservationService#cancelObservation()} | ||
268 | - */ | ||
269 | - @Override | ||
270 | - public void setCancelObservationRecourse(Registration registration, String path) { | ||
271 | - leshanServer.getObservationService().cancelObservations(registration, path); | ||
272 | - } | ||
273 | - | ||
274 | - /** | ||
275 | * Sending observe value to thingsboard from ObservationListener.onResponse: object, instance, SingleResource or MultipleResource | 275 | * Sending observe value to thingsboard from ObservationListener.onResponse: object, instance, SingleResource or MultipleResource |
276 | * | 276 | * |
277 | * @param registration - Registration LwM2M Client | 277 | * @param registration - Registration LwM2M Client |
@@ -279,7 +279,7 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | @@ -279,7 +279,7 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | ||
279 | * @param response - observe | 279 | * @param response - observe |
280 | */ | 280 | */ |
281 | @Override | 281 | @Override |
282 | - public void onObservationResponse(Registration registration, String path, ReadResponse response) { | 282 | + public void onObservationResponse(Registration registration, String path, ReadResponse response, Lwm2mClientRpcRequest rpcRequest) { |
283 | if (response.getContent() != null) { | 283 | if (response.getContent() != null) { |
284 | if (response.getContent() instanceof LwM2mObject) { | 284 | if (response.getContent() instanceof LwM2mObject) { |
285 | LwM2mObject lwM2mObject = (LwM2mObject) response.getContent(); | 285 | LwM2mObject lwM2mObject = (LwM2mObject) response.getContent(); |
@@ -289,6 +289,13 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | @@ -289,6 +289,13 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | ||
289 | this.updateObjectInstanceResourceValue(registration, lwM2mObjectInstance, path); | 289 | this.updateObjectInstanceResourceValue(registration, lwM2mObjectInstance, path); |
290 | } else if (response.getContent() instanceof LwM2mResource) { | 290 | } else if (response.getContent() instanceof LwM2mResource) { |
291 | LwM2mResource lwM2mResource = (LwM2mResource) response.getContent(); | 291 | LwM2mResource lwM2mResource = (LwM2mResource) response.getContent(); |
292 | + if (rpcRequest != null) { | ||
293 | + Object valueResp = lwM2mResource.isMultiInstances() ? lwM2mResource.getValues() : lwM2mResource.getValue(); | ||
294 | + Object value = this.converter.convertValue(valueResp, lwM2mResource.getType(), ResourceModel.Type.STRING, | ||
295 | + new LwM2mPath(convertPathFromIdVerToObjectId(path))); | ||
296 | + rpcRequest.setValueMsg(String.format("%s", value)); | ||
297 | + this.sentRpcRequest(rpcRequest, response.getCode().getName(), (String) value, LOG_LW2M_VALUE); | ||
298 | + } | ||
292 | this.updateResourcesValue(registration, lwM2mResource, path); | 299 | this.updateResourcesValue(registration, lwM2mResource, path); |
293 | } | 300 | } |
294 | } | 301 | } |
@@ -307,11 +314,12 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | @@ -307,11 +314,12 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | ||
307 | if (msg.getSharedUpdatedCount() > 0) { | 314 | if (msg.getSharedUpdatedCount() > 0) { |
308 | msg.getSharedUpdatedList().forEach(tsKvProto -> { | 315 | msg.getSharedUpdatedList().forEach(tsKvProto -> { |
309 | String pathName = tsKvProto.getKv().getKey(); | 316 | String pathName = tsKvProto.getKv().getKey(); |
310 | - String pathIdVer = this.validatePathIntoProfile(sessionInfo, pathName); | 317 | + String pathIdVer = this.getPresentPathIntoProfile(sessionInfo, pathName); |
311 | Object valueNew = this.lwM2mTransportContextServer.getValueFromKvProto(tsKvProto.getKv()); | 318 | Object valueNew = this.lwM2mTransportContextServer.getValueFromKvProto(tsKvProto.getKv()); |
312 | LwM2mClient lwM2MClient = lwM2mClientContext.getLwM2mClient(new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB())); | 319 | LwM2mClient lwM2MClient = lwM2mClientContext.getLwM2mClient(new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB())); |
313 | if (pathIdVer != null) { | 320 | if (pathIdVer != null) { |
314 | - ResourceModel resourceModel = lwM2MClient.getResourceModel(pathIdVer); | 321 | + ResourceModel resourceModel = lwM2MClient.getResourceModel(pathIdVer, this.lwM2mTransportContextServer.getLwM2MTransportConfigServer() |
322 | + .getModelProvider()); | ||
315 | if (resourceModel != null && resourceModel.operations.isWritable()) { | 323 | if (resourceModel != null && resourceModel.operations.isWritable()) { |
316 | this.updateResourcesValueToClient(lwM2MClient, this.getResourceValueFormatKv(lwM2MClient, pathIdVer), valueNew, pathIdVer); | 324 | this.updateResourcesValueToClient(lwM2MClient, this.getResourceValueFormatKv(lwM2MClient, pathIdVer), valueNew, pathIdVer); |
317 | } else { | 325 | } else { |
@@ -380,8 +388,124 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | @@ -380,8 +388,124 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | ||
380 | lwM2mClientContext.getLwM2mClients().values().stream().forEach(e -> e.deleteResources(pathIdVer, this.lwM2mTransportContextServer.getLwM2MTransportConfigServer().getModelProvider())); | 388 | lwM2mClientContext.getLwM2mClients().values().stream().forEach(e -> e.deleteResources(pathIdVer, this.lwM2mTransportContextServer.getLwM2MTransportConfigServer().getModelProvider())); |
381 | } | 389 | } |
382 | 390 | ||
383 | - public void onToDeviceRpcRequest(TransportProtos.ToDeviceRpcRequestMsg toDeviceRequest) { | ||
384 | - log.info("[{}] toDeviceRpcRequest", toDeviceRequest); | 391 | + @Override |
392 | + public void onToDeviceRpcRequest(TransportProtos.ToDeviceRpcRequestMsg toDeviceRequest, SessionInfoProto sessionInfo) { | ||
393 | + Lwm2mClientRpcRequest lwm2mClientRpcRequest = null; | ||
394 | + try { | ||
395 | + log.info("[{}] toDeviceRpcRequest", toDeviceRequest); | ||
396 | + Registration registration = lwM2mClientContext.getLwM2mClient(new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB())).getRegistration(); | ||
397 | + lwm2mClientRpcRequest = this.getDeviceRpcRequest(toDeviceRequest, sessionInfo, registration); | ||
398 | + if (lwm2mClientRpcRequest != null && lwm2mClientRpcRequest.getErrorMsg() != null) { | ||
399 | + lwm2mClientRpcRequest.setResponseCode(BAD_REQUEST.name()); | ||
400 | + this.onToDeviceRpcResponse(lwm2mClientRpcRequest.getDeviceRpcResponseResultMsg(), sessionInfo); | ||
401 | + } else { | ||
402 | + lwM2mTransportRequest.sendAllRequest(registration, lwm2mClientRpcRequest.getTargetIdVer(), lwm2mClientRpcRequest.getTypeOper(), lwm2mClientRpcRequest.getContentFormatName(), | ||
403 | + lwm2mClientRpcRequest.getValue() == null ? lwm2mClientRpcRequest.getParams() : lwm2mClientRpcRequest.getValue(), | ||
404 | + this.lwM2mTransportContextServer.getLwM2MTransportConfigServer().getTimeout(), lwm2mClientRpcRequest); | ||
405 | + } | ||
406 | + } catch (Exception e) { | ||
407 | + if (lwm2mClientRpcRequest == null) { | ||
408 | + lwm2mClientRpcRequest = new Lwm2mClientRpcRequest(); | ||
409 | + } | ||
410 | + lwm2mClientRpcRequest.setResponseCode(BAD_REQUEST.name()); | ||
411 | + if (lwm2mClientRpcRequest.getErrorMsg() == null) { | ||
412 | + lwm2mClientRpcRequest.setErrorMsg(e.getMessage()); | ||
413 | + } | ||
414 | + this.onToDeviceRpcResponse(lwm2mClientRpcRequest.getDeviceRpcResponseResultMsg(), sessionInfo); | ||
415 | + } | ||
416 | + } | ||
417 | + | ||
418 | + /** | ||
419 | + * @param toDeviceRequest - | ||
420 | + * @param sessionInfo - | ||
421 | + * @param registration - | ||
422 | + * @return | ||
423 | + * @throws IllegalArgumentException | ||
424 | + */ | ||
425 | + private Lwm2mClientRpcRequest getDeviceRpcRequest(TransportProtos.ToDeviceRpcRequestMsg toDeviceRequest, | ||
426 | + SessionInfoProto sessionInfo, Registration registration) throws IllegalArgumentException { | ||
427 | + Lwm2mClientRpcRequest lwm2mClientRpcRequest = new Lwm2mClientRpcRequest(); | ||
428 | + try { | ||
429 | + lwm2mClientRpcRequest.setRequestId(toDeviceRequest.getRequestId()); | ||
430 | + lwm2mClientRpcRequest.setSessionInfo(sessionInfo); | ||
431 | + lwm2mClientRpcRequest.setValidTypeOper(toDeviceRequest.getMethodName()); | ||
432 | + JsonObject rpcRequest = LwM2mTransportHandler.validateJson(toDeviceRequest.getParams()); | ||
433 | + if (rpcRequest != null) { | ||
434 | + if (rpcRequest.has(lwm2mClientRpcRequest.keyNameKey)) { | ||
435 | + String targetIdVer = this.getPresentPathIntoProfile(sessionInfo, | ||
436 | + rpcRequest.get(lwm2mClientRpcRequest.keyNameKey).getAsString()); | ||
437 | + if (targetIdVer != null) { | ||
438 | + lwm2mClientRpcRequest.setTargetIdVer(targetIdVer); | ||
439 | + lwm2mClientRpcRequest.setInfoMsg(String.format("Changed by: key - %s, pathIdVer - %s", | ||
440 | + rpcRequest.get(lwm2mClientRpcRequest.keyNameKey).getAsString(), targetIdVer)); | ||
441 | + } | ||
442 | + } | ||
443 | + if (lwm2mClientRpcRequest.getTargetIdVer() == null) { | ||
444 | + lwm2mClientRpcRequest.setValidTargetIdVerKey(rpcRequest, registration); | ||
445 | + } | ||
446 | + if (rpcRequest.has(lwm2mClientRpcRequest.contentFormatNameKey)) { | ||
447 | + lwm2mClientRpcRequest.setValidContentFormatName(rpcRequest); | ||
448 | + } | ||
449 | + if (rpcRequest.has(lwm2mClientRpcRequest.timeoutInMsKey) && rpcRequest.get(lwm2mClientRpcRequest.timeoutInMsKey).getAsLong() > 0) { | ||
450 | + lwm2mClientRpcRequest.setTimeoutInMs(rpcRequest.get(lwm2mClientRpcRequest.timeoutInMsKey).getAsLong()); | ||
451 | + } | ||
452 | + if (rpcRequest.has(lwm2mClientRpcRequest.valueKey)) { | ||
453 | + lwm2mClientRpcRequest.setValue(rpcRequest.get(lwm2mClientRpcRequest.valueKey).getAsString()); | ||
454 | + } | ||
455 | + if (rpcRequest.has(lwm2mClientRpcRequest.paramsKey) && rpcRequest.get(lwm2mClientRpcRequest.paramsKey).isJsonObject()) { | ||
456 | + lwm2mClientRpcRequest.setParams(new Gson().fromJson(rpcRequest.get(lwm2mClientRpcRequest.paramsKey) | ||
457 | + .getAsJsonObject().toString(), new TypeToken<ConcurrentHashMap<String, Object>>() { | ||
458 | + }.getType())); | ||
459 | + } | ||
460 | + lwm2mClientRpcRequest.setSessionInfo(sessionInfo); | ||
461 | + if (OBSERVE_READ_ALL != lwm2mClientRpcRequest.getTypeOper() && lwm2mClientRpcRequest.getTargetIdVer() == null) { | ||
462 | + lwm2mClientRpcRequest.setErrorMsg(lwm2mClientRpcRequest.targetIdVerKey + " and " + | ||
463 | + lwm2mClientRpcRequest.keyNameKey + " is null or bad format"); | ||
464 | + } | ||
465 | + else if ((EXECUTE == lwm2mClientRpcRequest.getTypeOper() | ||
466 | + || WRITE_REPLACE == lwm2mClientRpcRequest.getTypeOper()) | ||
467 | + && lwm2mClientRpcRequest.getTargetIdVer() !=null | ||
468 | + && !(new LwM2mPath(convertPathFromIdVerToObjectId(lwm2mClientRpcRequest.getTargetIdVer())).isResource() | ||
469 | + || new LwM2mPath(convertPathFromIdVerToObjectId(lwm2mClientRpcRequest.getTargetIdVer())).isResourceInstance())) { | ||
470 | + lwm2mClientRpcRequest.setErrorMsg("Invalid parameter " + lwm2mClientRpcRequest.targetIdVerKey | ||
471 | + + ". Only Resource or ResourceInstance can be this operation"); | ||
472 | + } | ||
473 | + else if (WRITE_UPDATE == lwm2mClientRpcRequest.getTypeOper()){ | ||
474 | + lwm2mClientRpcRequest.setErrorMsg("Procedures In Development..."); | ||
475 | + } | ||
476 | + } else { | ||
477 | + lwm2mClientRpcRequest.setErrorMsg("Params of request is bad Json format."); | ||
478 | + } | ||
479 | + } catch (Exception e) { | ||
480 | + throw new IllegalArgumentException(lwm2mClientRpcRequest.getErrorMsg()); | ||
481 | + } | ||
482 | + return lwm2mClientRpcRequest; | ||
483 | + } | ||
484 | + | ||
485 | + public void sentRpcRequest (Lwm2mClientRpcRequest rpcRequest, String requestCode, String msg, String typeMsg) { | ||
486 | + rpcRequest.setResponseCode(requestCode); | ||
487 | + if (LOG_LW2M_ERROR.equals(typeMsg)) { | ||
488 | + rpcRequest.setInfoMsg(null); | ||
489 | + rpcRequest.setValueMsg(null); | ||
490 | + if (rpcRequest.getErrorMsg() == null) { | ||
491 | + msg = msg.isEmpty() ? null : msg; | ||
492 | + rpcRequest.setErrorMsg(msg); | ||
493 | + } | ||
494 | + } else if (LOG_LW2M_INFO.equals(typeMsg)) { | ||
495 | + if (rpcRequest.getInfoMsg() == null) { | ||
496 | + rpcRequest.setInfoMsg(msg); | ||
497 | + } | ||
498 | + } else if (LOG_LW2M_VALUE.equals(typeMsg)) { | ||
499 | + if (rpcRequest.getValueMsg() == null) { | ||
500 | + rpcRequest.setValueMsg(msg); | ||
501 | + } | ||
502 | + } | ||
503 | + this.onToDeviceRpcResponse(rpcRequest.getDeviceRpcResponseResultMsg(), rpcRequest.getSessionInfo()); | ||
504 | + } | ||
505 | + | ||
506 | + @Override | ||
507 | + public void onToDeviceRpcResponse(TransportProtos.ToDeviceRpcResponseMsg toDeviceResponse, SessionInfoProto sessionInfo) { | ||
508 | + transportService.process(sessionInfo, toDeviceResponse, null); | ||
385 | } | 509 | } |
386 | 510 | ||
387 | public void onToServerRpcResponse(TransportProtos.ToServerRpcResponseMsg toServerResponse) { | 511 | public void onToServerRpcResponse(TransportProtos.ToServerRpcResponseMsg toServerResponse) { |
@@ -395,8 +519,8 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | @@ -395,8 +519,8 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | ||
395 | */ | 519 | */ |
396 | @Override | 520 | @Override |
397 | public void doTrigger(Registration registration, String path) { | 521 | public void doTrigger(Registration registration, String path) { |
398 | - lwM2mTransportRequest.sendAllRequest(registration, path, POST_TYPE_OPER_EXECUTE, | ||
399 | - ContentFormat.TLV.getName(), null, null, this.lwM2mTransportContextServer.getLwM2MTransportConfigServer().getTimeout()); | 522 | + lwM2mTransportRequest.sendAllRequest(registration, path, EXECUTE, |
523 | + ContentFormat.TLV.getName(), null, this.lwM2mTransportContextServer.getLwM2MTransportConfigServer().getTimeout(), null); | ||
400 | } | 524 | } |
401 | 525 | ||
402 | /** | 526 | /** |
@@ -486,14 +610,14 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | @@ -486,14 +610,14 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | ||
486 | if (LWM2M_STRATEGY_2 == LwM2mTransportHandler.getClientOnlyObserveAfterConnect(lwM2MClientProfile)) { | 610 | if (LWM2M_STRATEGY_2 == LwM2mTransportHandler.getClientOnlyObserveAfterConnect(lwM2MClientProfile)) { |
487 | // #2 | 611 | // #2 |
488 | lwM2MClient.getPendingRequests().addAll(clientObjects); | 612 | lwM2MClient.getPendingRequests().addAll(clientObjects); |
489 | - clientObjects.forEach(path -> lwM2mTransportRequest.sendAllRequest(registration, path, GET_TYPE_OPER_READ, ContentFormat.TLV.getName(), | ||
490 | - null, null, this.lwM2mTransportContextServer.getLwM2MTransportConfigServer().getTimeout())); | 613 | + clientObjects.forEach(path -> lwM2mTransportRequest.sendAllRequest(registration, path, READ, ContentFormat.TLV.getName(), |
614 | + null, this.lwM2mTransportContextServer.getLwM2MTransportConfigServer().getTimeout(), null)); | ||
491 | } | 615 | } |
492 | // #1 | 616 | // #1 |
493 | - this.initReadAttrTelemetryObserveToClient(registration, lwM2MClient, GET_TYPE_OPER_READ, clientObjects); | ||
494 | - this.initReadAttrTelemetryObserveToClient(registration, lwM2MClient, GET_TYPE_OPER_OBSERVE, clientObjects); | ||
495 | - this.initReadAttrTelemetryObserveToClient(registration, lwM2MClient, PUT_TYPE_OPER_WRITE_ATTRIBUTES, clientObjects); | ||
496 | - this.initReadAttrTelemetryObserveToClient(registration, lwM2MClient, GET_TYPE_OPER_DISCOVER, clientObjects); | 617 | + this.initReadAttrTelemetryObserveToClient(registration, lwM2MClient, READ, clientObjects); |
618 | + this.initReadAttrTelemetryObserveToClient(registration, lwM2MClient, OBSERVE, clientObjects); | ||
619 | + this.initReadAttrTelemetryObserveToClient(registration, lwM2MClient, WRITE_ATTRIBUTES, clientObjects); | ||
620 | + this.initReadAttrTelemetryObserveToClient(registration, lwM2MClient, DISCOVER, clientObjects); | ||
497 | } | 621 | } |
498 | } | 622 | } |
499 | 623 | ||
@@ -534,7 +658,8 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | @@ -534,7 +658,8 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | ||
534 | */ | 658 | */ |
535 | private void updateResourcesValue(Registration registration, LwM2mResource lwM2mResource, String path) { | 659 | private void updateResourcesValue(Registration registration, LwM2mResource lwM2mResource, String path) { |
536 | LwM2mClient lwM2MClient = lwM2mClientContext.getLwM2mClientWithReg(registration, null); | 660 | LwM2mClient lwM2MClient = lwM2mClientContext.getLwM2mClientWithReg(registration, null); |
537 | - if (lwM2MClient.saveResourceValue(path, lwM2mResource, this.lwM2mTransportContextServer.getLwM2MTransportConfigServer().getModelProvider())) { | 661 | + if (lwM2MClient.saveResourceValue(path, lwM2mResource, this.lwM2mTransportContextServer.getLwM2MTransportConfigServer() |
662 | + .getModelProvider())) { | ||
538 | Set<String> paths = new HashSet<>(); | 663 | Set<String> paths = new HashSet<>(); |
539 | paths.add(path); | 664 | paths.add(path); |
540 | this.updateAttrTelemetry(registration, paths); | 665 | this.updateAttrTelemetry(registration, paths); |
@@ -570,64 +695,30 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | @@ -570,64 +695,30 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | ||
570 | } | 695 | } |
571 | 696 | ||
572 | /** | 697 | /** |
573 | - * @param clientProfile - | ||
574 | - * @param path - | ||
575 | - * @return true if path isPresent in postAttributeProfile | ||
576 | - */ | ||
577 | - private boolean validatePathInAttrProfile(LwM2mClientProfile clientProfile, String path) { | ||
578 | - try { | ||
579 | - List<String> attributesSet = new Gson().fromJson(clientProfile.getPostAttributeProfile(), | ||
580 | - new TypeToken<List<String>>() { | ||
581 | - }.getType()); | ||
582 | - return attributesSet.stream().anyMatch(p -> p.equals(path)); | ||
583 | - } catch (Exception e) { | ||
584 | - log.error("Fail Validate Path [{}] ClientProfile.Attribute", path, e); | ||
585 | - return false; | ||
586 | - } | ||
587 | - } | ||
588 | - | ||
589 | - /** | ||
590 | - * @param clientProfile - | ||
591 | - * @param path - | ||
592 | - * @return true if path isPresent in postAttributeProfile | ||
593 | - */ | ||
594 | - private boolean validatePathInTelemetryProfile(LwM2mClientProfile clientProfile, String path) { | ||
595 | - try { | ||
596 | - List<String> telemetriesSet = new Gson().fromJson(clientProfile.getPostTelemetryProfile(), new TypeToken<List<String>>() { | ||
597 | - }.getType()); | ||
598 | - return telemetriesSet.stream().anyMatch(p -> p.equals(path)); | ||
599 | - } catch (Exception e) { | ||
600 | - log.error("Fail Validate Path [{}] ClientProfile.Telemetry", path, e); | ||
601 | - return false; | ||
602 | - } | ||
603 | - } | ||
604 | - | ||
605 | - /** | ||
606 | * Start observe/read: Attr/Telemetry | 698 | * Start observe/read: Attr/Telemetry |
607 | * #1 - Analyze: path in resource profile == client resource | 699 | * #1 - Analyze: path in resource profile == client resource |
608 | * | 700 | * |
609 | * @param registration - | 701 | * @param registration - |
610 | */ | 702 | */ |
611 | private void initReadAttrTelemetryObserveToClient(Registration registration, LwM2mClient lwM2MClient, | 703 | private void initReadAttrTelemetryObserveToClient(Registration registration, LwM2mClient lwM2MClient, |
612 | - String typeOper, Set<String> clientObjects) { | 704 | + LwM2mTypeOper typeOper, Set<String> clientObjects) { |
613 | LwM2mClientProfile lwM2MClientProfile = lwM2mClientContext.getProfile(registration); | 705 | LwM2mClientProfile lwM2MClientProfile = lwM2mClientContext.getProfile(registration); |
614 | Set<String> result = null; | 706 | Set<String> result = null; |
615 | ConcurrentHashMap<String, Object> params = null; | 707 | ConcurrentHashMap<String, Object> params = null; |
616 | - if (GET_TYPE_OPER_READ.equals(typeOper)) { | 708 | + if (READ.equals(typeOper)) { |
617 | result = JacksonUtil.fromString(lwM2MClientProfile.getPostAttributeProfile().toString(), | 709 | result = JacksonUtil.fromString(lwM2MClientProfile.getPostAttributeProfile().toString(), |
618 | new TypeReference<>() { | 710 | new TypeReference<>() { |
619 | }); | 711 | }); |
620 | result.addAll(JacksonUtil.fromString(lwM2MClientProfile.getPostTelemetryProfile().toString(), | 712 | result.addAll(JacksonUtil.fromString(lwM2MClientProfile.getPostTelemetryProfile().toString(), |
621 | new TypeReference<>() { | 713 | new TypeReference<>() { |
622 | })); | 714 | })); |
623 | - } else if (GET_TYPE_OPER_OBSERVE.equals(typeOper)) { | 715 | + } else if (OBSERVE.equals(typeOper)) { |
624 | result = JacksonUtil.fromString(lwM2MClientProfile.getPostObserveProfile().toString(), | 716 | result = JacksonUtil.fromString(lwM2MClientProfile.getPostObserveProfile().toString(), |
625 | new TypeReference<>() { | 717 | new TypeReference<>() { |
626 | }); | 718 | }); |
627 | - } else if (GET_TYPE_OPER_DISCOVER.equals(typeOper)) { | 719 | + } else if (DISCOVER.equals(typeOper)) { |
628 | result = this.getPathForWriteAttributes(lwM2MClientProfile.getPostAttributeLwm2mProfile()).keySet(); | 720 | result = this.getPathForWriteAttributes(lwM2MClientProfile.getPostAttributeLwm2mProfile()).keySet(); |
629 | - ; | ||
630 | - } else if (PUT_TYPE_OPER_WRITE_ATTRIBUTES.equals(typeOper)) { | 721 | + } else if (WRITE_ATTRIBUTES.equals(typeOper)) { |
631 | params = this.getPathForWriteAttributes(lwM2MClientProfile.getPostAttributeLwm2mProfile()); | 722 | params = this.getPathForWriteAttributes(lwM2MClientProfile.getPostAttributeLwm2mProfile()); |
632 | result = params.keySet(); | 723 | result = params.keySet(); |
633 | } | 724 | } |
@@ -644,8 +735,8 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | @@ -644,8 +735,8 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | ||
644 | lwM2MClient.getPendingRequests().addAll(pathSend); | 735 | lwM2MClient.getPendingRequests().addAll(pathSend); |
645 | ConcurrentHashMap<String, Object> finalParams = params; | 736 | ConcurrentHashMap<String, Object> finalParams = params; |
646 | pathSend.forEach(target -> lwM2mTransportRequest.sendAllRequest(registration, target, typeOper, ContentFormat.TLV.getName(), | 737 | pathSend.forEach(target -> lwM2mTransportRequest.sendAllRequest(registration, target, typeOper, ContentFormat.TLV.getName(), |
647 | - null, finalParams != null ? finalParams.get(target) : null, this.lwM2mTransportContextServer.getLwM2MTransportConfigServer().getTimeout())); | ||
648 | - if (GET_TYPE_OPER_OBSERVE.equals(typeOper)) { | 738 | + finalParams != null ? finalParams.get(target) : null, this.lwM2mTransportContextServer.getLwM2MTransportConfigServer().getTimeout(), null)); |
739 | + if (OBSERVE.equals(typeOper)) { | ||
649 | lwM2MClient.initValue(this, null); | 740 | lwM2MClient.initValue(this, null); |
650 | } | 741 | } |
651 | } | 742 | } |
@@ -718,11 +809,6 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | @@ -718,11 +809,6 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | ||
718 | return null; | 809 | return null; |
719 | } | 810 | } |
720 | 811 | ||
721 | -// public TransportProtos.KeyValueProto getKvToThingsboard(String pathIdVer, Registration registration) { | ||
722 | -// ResultsResourceValue resultsResourceValue = getResultsResourceValue(pathIdVer, registration); | ||
723 | -// return resultsResourceValue != null ? this.lwM2mTransportContextServer.getKvAttrTelemetryToThingsboard(resultsResourceValue) : null; | ||
724 | -// } | ||
725 | - | ||
726 | private TransportProtos.KeyValueProto getKvToThingsboard(String pathIdVer, Registration registration) { | 812 | private TransportProtos.KeyValueProto getKvToThingsboard(String pathIdVer, Registration registration) { |
727 | LwM2mClient lwM2MClient = this.lwM2mClientContext.getLwM2mClientWithReg(null, registration.getId()); | 813 | LwM2mClient lwM2MClient = this.lwM2mClientContext.getLwM2mClientWithReg(null, registration.getId()); |
728 | JsonObject names = lwM2mClientContext.getProfiles().get(lwM2MClient.getProfileId()).getPostKeyNameProfile(); | 814 | JsonObject names = lwM2mClientContext.getProfiles().get(lwM2MClient.getProfileId()).getPostKeyNameProfile(); |
@@ -828,18 +914,18 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | @@ -828,18 +914,18 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | ||
828 | if (lwM2mClientContext.addUpdateProfileParameters(deviceProfile)) { | 914 | if (lwM2mClientContext.addUpdateProfileParameters(deviceProfile)) { |
829 | // #1 | 915 | // #1 |
830 | JsonArray attributeOld = lwM2MClientProfileOld.getPostAttributeProfile(); | 916 | JsonArray attributeOld = lwM2MClientProfileOld.getPostAttributeProfile(); |
831 | - Set<String> attributeSetOld = this.convertJsonArrayToSet(attributeOld); | 917 | + Set<String> attributeSetOld = convertJsonArrayToSet(attributeOld); |
832 | JsonArray telemetryOld = lwM2MClientProfileOld.getPostTelemetryProfile(); | 918 | JsonArray telemetryOld = lwM2MClientProfileOld.getPostTelemetryProfile(); |
833 | - Set<String> telemetrySetOld = this.convertJsonArrayToSet(telemetryOld); | 919 | + Set<String> telemetrySetOld = convertJsonArrayToSet(telemetryOld); |
834 | JsonArray observeOld = lwM2MClientProfileOld.getPostObserveProfile(); | 920 | JsonArray observeOld = lwM2MClientProfileOld.getPostObserveProfile(); |
835 | JsonObject keyNameOld = lwM2MClientProfileOld.getPostKeyNameProfile(); | 921 | JsonObject keyNameOld = lwM2MClientProfileOld.getPostKeyNameProfile(); |
836 | JsonObject attributeLwm2mOld = lwM2MClientProfileOld.getPostAttributeLwm2mProfile(); | 922 | JsonObject attributeLwm2mOld = lwM2MClientProfileOld.getPostAttributeLwm2mProfile(); |
837 | 923 | ||
838 | LwM2mClientProfile lwM2MClientProfileNew = lwM2mClientContext.getProfiles().get(deviceProfile.getUuidId()); | 924 | LwM2mClientProfile lwM2MClientProfileNew = lwM2mClientContext.getProfiles().get(deviceProfile.getUuidId()); |
839 | JsonArray attributeNew = lwM2MClientProfileNew.getPostAttributeProfile(); | 925 | JsonArray attributeNew = lwM2MClientProfileNew.getPostAttributeProfile(); |
840 | - Set<String> attributeSetNew = this.convertJsonArrayToSet(attributeNew); | 926 | + Set<String> attributeSetNew = convertJsonArrayToSet(attributeNew); |
841 | JsonArray telemetryNew = lwM2MClientProfileNew.getPostTelemetryProfile(); | 927 | JsonArray telemetryNew = lwM2MClientProfileNew.getPostTelemetryProfile(); |
842 | - Set<String> telemetrySetNew = this.convertJsonArrayToSet(telemetryNew); | 928 | + Set<String> telemetrySetNew = convertJsonArrayToSet(telemetryNew); |
843 | JsonArray observeNew = lwM2MClientProfileNew.getPostObserveProfile(); | 929 | JsonArray observeNew = lwM2MClientProfileNew.getPostObserveProfile(); |
844 | JsonObject keyNameNew = lwM2MClientProfileNew.getPostKeyNameProfile(); | 930 | JsonObject keyNameNew = lwM2MClientProfileNew.getPostKeyNameProfile(); |
845 | JsonObject attributeLwm2mNew = lwM2MClientProfileNew.getPostAttributeLwm2mProfile(); | 931 | JsonObject attributeLwm2mNew = lwM2MClientProfileNew.getPostAttributeLwm2mProfile(); |
@@ -882,7 +968,7 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | @@ -882,7 +968,7 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | ||
882 | // update value in Resources | 968 | // update value in Resources |
883 | registrationIds.forEach(registrationId -> { | 969 | registrationIds.forEach(registrationId -> { |
884 | Registration registration = lwM2mClientContext.getRegistration(registrationId); | 970 | Registration registration = lwM2mClientContext.getRegistration(registrationId); |
885 | - this.readResourceValueObserve(registration, sendAttrToThingsboard.getPathPostParametersAdd(), GET_TYPE_OPER_READ); | 971 | + this.readResourceValueObserve(registration, sendAttrToThingsboard.getPathPostParametersAdd(), READ); |
886 | // send attr/telemetry to tingsboard for new path | 972 | // send attr/telemetry to tingsboard for new path |
887 | this.updateAttrTelemetry(registration, sendAttrToThingsboard.getPathPostParametersAdd()); | 973 | this.updateAttrTelemetry(registration, sendAttrToThingsboard.getPathPostParametersAdd()); |
888 | }); | 974 | }); |
@@ -911,7 +997,7 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | @@ -911,7 +997,7 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | ||
911 | registrationIds.forEach(registrationId -> { | 997 | registrationIds.forEach(registrationId -> { |
912 | Registration registration = lwM2mClientContext.getRegistration(registrationId); | 998 | Registration registration = lwM2mClientContext.getRegistration(registrationId); |
913 | if (postObserveAnalyzer.getPathPostParametersAdd().size() > 0) { | 999 | if (postObserveAnalyzer.getPathPostParametersAdd().size() > 0) { |
914 | - this.readResourceValueObserve(registration, postObserveAnalyzer.getPathPostParametersAdd(), GET_TYPE_OPER_OBSERVE); | 1000 | + this.readResourceValueObserve(registration, postObserveAnalyzer.getPathPostParametersAdd(), OBSERVE); |
915 | } | 1001 | } |
916 | // 5.3 del | 1002 | // 5.3 del |
917 | // send Request cancel observe to Client | 1003 | // send Request cancel observe to Client |
@@ -923,12 +1009,6 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | @@ -923,12 +1009,6 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | ||
923 | } | 1009 | } |
924 | } | 1010 | } |
925 | 1011 | ||
926 | - private Set<String> convertJsonArrayToSet(JsonArray jsonArray) { | ||
927 | - List<String> attributeListOld = new Gson().fromJson(jsonArray, new TypeToken<List<String>>() { | ||
928 | - }.getType()); | ||
929 | - return Sets.newConcurrentHashSet(attributeListOld); | ||
930 | - } | ||
931 | - | ||
932 | /** | 1012 | /** |
933 | * Compare old list with new list after change AttrTelemetryObserve in config Profile | 1013 | * Compare old list with new list after change AttrTelemetryObserve in config Profile |
934 | * | 1014 | * |
@@ -962,16 +1042,16 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | @@ -962,16 +1042,16 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | ||
962 | * @param registration - Registration LwM2M Client | 1042 | * @param registration - Registration LwM2M Client |
963 | * @param targets - path Resources == [ "/2/0/0", "/2/0/1"] | 1043 | * @param targets - path Resources == [ "/2/0/0", "/2/0/1"] |
964 | */ | 1044 | */ |
965 | - private void readResourceValueObserve(Registration registration, Set<String> targets, String typeOper) { | 1045 | + private void readResourceValueObserve(Registration registration, Set<String> targets, LwM2mTypeOper typeOper) { |
966 | targets.forEach(target -> { | 1046 | targets.forEach(target -> { |
967 | LwM2mPath pathIds = new LwM2mPath(convertPathFromIdVerToObjectId(target)); | 1047 | LwM2mPath pathIds = new LwM2mPath(convertPathFromIdVerToObjectId(target)); |
968 | if (pathIds.isResource()) { | 1048 | if (pathIds.isResource()) { |
969 | - if (GET_TYPE_OPER_READ.equals(typeOper)) { | 1049 | + if (READ.equals(typeOper)) { |
970 | lwM2mTransportRequest.sendAllRequest(registration, target, typeOper, | 1050 | lwM2mTransportRequest.sendAllRequest(registration, target, typeOper, |
971 | - ContentFormat.TLV.getName(), null, null, this.lwM2mTransportContextServer.getLwM2MTransportConfigServer().getTimeout()); | ||
972 | - } else if (GET_TYPE_OPER_OBSERVE.equals(typeOper)) { | 1051 | + ContentFormat.TLV.getName(), null, this.lwM2mTransportContextServer.getLwM2MTransportConfigServer().getTimeout(), null); |
1052 | + } else if (OBSERVE.equals(typeOper)) { | ||
973 | lwM2mTransportRequest.sendAllRequest(registration, target, typeOper, | 1053 | lwM2mTransportRequest.sendAllRequest(registration, target, typeOper, |
974 | - null, null, null, this.lwM2mTransportContextServer.getLwM2MTransportConfigServer().getTimeout()); | 1054 | + null, null, this.lwM2mTransportContextServer.getLwM2MTransportConfigServer().getTimeout(), null); |
975 | } | 1055 | } |
976 | } | 1056 | } |
977 | }); | 1057 | }); |
@@ -1026,8 +1106,8 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | @@ -1026,8 +1106,8 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | ||
1026 | .collect(Collectors.toUnmodifiableSet()); | 1106 | .collect(Collectors.toUnmodifiableSet()); |
1027 | if (!pathSend.isEmpty()) { | 1107 | if (!pathSend.isEmpty()) { |
1028 | ConcurrentHashMap<String, Object> finalParams = lwm2mAttributesNew; | 1108 | ConcurrentHashMap<String, Object> finalParams = lwm2mAttributesNew; |
1029 | - pathSend.forEach(target -> lwM2mTransportRequest.sendAllRequest(registration, target, PUT_TYPE_OPER_WRITE_ATTRIBUTES, ContentFormat.TLV.getName(), | ||
1030 | - null, finalParams.get(target), this.lwM2mTransportContextServer.getLwM2MTransportConfigServer().getTimeout())); | 1109 | + pathSend.forEach(target -> lwM2mTransportRequest.sendAllRequest(registration, target, WRITE_ATTRIBUTES, ContentFormat.TLV.getName(), |
1110 | + finalParams.get(target), this.lwM2mTransportContextServer.getLwM2MTransportConfigServer().getTimeout(), null)); | ||
1031 | } | 1111 | } |
1032 | }); | 1112 | }); |
1033 | } | 1113 | } |
@@ -1043,8 +1123,8 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | @@ -1043,8 +1123,8 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | ||
1043 | Map<String, Object> params = (Map<String, Object>) lwm2mAttributesOld.get(target); | 1123 | Map<String, Object> params = (Map<String, Object>) lwm2mAttributesOld.get(target); |
1044 | params.clear(); | 1124 | params.clear(); |
1045 | params.put(OBJECT_VERSION, ""); | 1125 | params.put(OBJECT_VERSION, ""); |
1046 | - lwM2mTransportRequest.sendAllRequest(registration, target, PUT_TYPE_OPER_WRITE_ATTRIBUTES, ContentFormat.TLV.getName(), | ||
1047 | - null, params, this.lwM2mTransportContextServer.getLwM2MTransportConfigServer().getTimeout()); | 1126 | + lwM2mTransportRequest.sendAllRequest(registration, target, WRITE_ATTRIBUTES, ContentFormat.TLV.getName(), |
1127 | + params, this.lwM2mTransportContextServer.getLwM2MTransportConfigServer().getTimeout(), null); | ||
1048 | }); | 1128 | }); |
1049 | } | 1129 | } |
1050 | }); | 1130 | }); |
@@ -1054,9 +1134,10 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | @@ -1054,9 +1134,10 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | ||
1054 | 1134 | ||
1055 | private void cancelObserveIsValue(Registration registration, Set<String> paramAnallyzer) { | 1135 | private void cancelObserveIsValue(Registration registration, Set<String> paramAnallyzer) { |
1056 | LwM2mClient lwM2MClient = lwM2mClientContext.getLwM2mClientWithReg(registration, null); | 1136 | LwM2mClient lwM2MClient = lwM2mClientContext.getLwM2mClientWithReg(registration, null); |
1057 | - paramAnallyzer.forEach(p -> { | ||
1058 | - if (this.getResourceValueFromLwM2MClient(lwM2MClient, p) != null) { | ||
1059 | - this.setCancelObservationRecourse(registration, convertPathFromIdVerToObjectId(p)); | 1137 | + paramAnallyzer.forEach(pathIdVer -> { |
1138 | + if (this.getResourceValueFromLwM2MClient(lwM2MClient, pathIdVer) != null) { | ||
1139 | + lwM2mTransportRequest.sendAllRequest(registration, pathIdVer, OBSERVE_CANCEL, null, | ||
1140 | + null, this.lwM2mTransportContextServer.getLwM2MTransportConfigServer().getTimeout(), null); | ||
1060 | } | 1141 | } |
1061 | } | 1142 | } |
1062 | ); | 1143 | ); |
@@ -1064,8 +1145,9 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | @@ -1064,8 +1145,9 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | ||
1064 | 1145 | ||
1065 | private void updateResourcesValueToClient(LwM2mClient lwM2MClient, Object valueOld, Object valueNew, String path) { | 1146 | private void updateResourcesValueToClient(LwM2mClient lwM2MClient, Object valueOld, Object valueNew, String path) { |
1066 | if (valueNew != null && (valueOld == null || !valueNew.toString().equals(valueOld.toString()))) { | 1147 | if (valueNew != null && (valueOld == null || !valueNew.toString().equals(valueOld.toString()))) { |
1067 | - lwM2mTransportRequest.sendAllRequest(lwM2MClient.getRegistration(), path, POST_TYPE_OPER_WRITE_REPLACE, | ||
1068 | - ContentFormat.TLV.getName(), null, valueNew, this.lwM2mTransportContextServer.getLwM2MTransportConfigServer().getTimeout()); | 1148 | + lwM2mTransportRequest.sendAllRequest(lwM2MClient.getRegistration(), path, WRITE_REPLACE, |
1149 | + ContentFormat.TLV.getName(), valueNew, | ||
1150 | + this.lwM2mTransportContextServer.getLwM2MTransportConfigServer().getTimeout(), null); | ||
1069 | } else { | 1151 | } else { |
1070 | log.error("Failed update resource [{}] [{}]", path, valueNew); | 1152 | log.error("Failed update resource [{}] [{}]", path, valueNew); |
1071 | String logMsg = String.format("%s: Failed update resource path - %s value - %s. Value is not changed or bad", | 1153 | String logMsg = String.format("%s: Failed update resource path - %s value - %s. Value is not changed or bad", |
@@ -1084,19 +1166,6 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | @@ -1084,19 +1166,6 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | ||
1084 | } | 1166 | } |
1085 | 1167 | ||
1086 | /** | 1168 | /** |
1087 | - * Get path to resource from profile equal keyName or from ModelObject equal name | ||
1088 | - * Only for resource: isWritable && isPresent as attribute in profile -> LwM2MClientProfile (format: CamelCase) | ||
1089 | - * | ||
1090 | - * @param sessionInfo - | ||
1091 | - * @param name - | ||
1092 | - * @return path if path isPresent in postProfile | ||
1093 | - */ | ||
1094 | - private String validatePathIntoProfile(TransportProtos.SessionInfoProto sessionInfo, String name) { | ||
1095 | - String pathIdVer = this.getPresentPathIntoProfile(sessionInfo, name); | ||
1096 | - return !pathIdVer.isEmpty() ? pathIdVer : null; | ||
1097 | - } | ||
1098 | - | ||
1099 | - /** | ||
1100 | * Get path to resource from profile equal keyName | 1169 | * Get path to resource from profile equal keyName |
1101 | * | 1170 | * |
1102 | * @param sessionInfo - | 1171 | * @param sessionInfo - |
@@ -1108,7 +1177,7 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | @@ -1108,7 +1177,7 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | ||
1108 | LwM2mClient lwM2mClient = lwM2mClientContext.getLwM2MClient(sessionInfo); | 1177 | LwM2mClient lwM2mClient = lwM2mClientContext.getLwM2MClient(sessionInfo); |
1109 | return profile.getPostKeyNameProfile().getAsJsonObject().entrySet().stream() | 1178 | return profile.getPostKeyNameProfile().getAsJsonObject().entrySet().stream() |
1110 | .filter(e -> e.getValue().getAsString().equals(name) && validateResourceInModel(lwM2mClient, e.getKey(), false)).findFirst().map(Map.Entry::getKey) | 1179 | .filter(e -> e.getValue().getAsString().equals(name) && validateResourceInModel(lwM2mClient, e.getKey(), false)).findFirst().map(Map.Entry::getKey) |
1111 | - .orElse(""); | 1180 | + .orElse(null); |
1112 | } | 1181 | } |
1113 | 1182 | ||
1114 | /** | 1183 | /** |
@@ -1140,7 +1209,7 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | @@ -1140,7 +1209,7 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | ||
1140 | public void updateAttriuteFromThingsboard(List<TransportProtos.TsKvProto> tsKvProtos, TransportProtos.SessionInfoProto sessionInfo) { | 1209 | public void updateAttriuteFromThingsboard(List<TransportProtos.TsKvProto> tsKvProtos, TransportProtos.SessionInfoProto sessionInfo) { |
1141 | LwM2mClient lwM2MClient = lwM2mClientContext.getLwM2MClient(sessionInfo); | 1210 | LwM2mClient lwM2MClient = lwM2mClientContext.getLwM2MClient(sessionInfo); |
1142 | tsKvProtos.forEach(tsKvProto -> { | 1211 | tsKvProtos.forEach(tsKvProto -> { |
1143 | - String pathIdVer = this.validatePathIntoProfile(sessionInfo, tsKvProto.getKv().getKey()); | 1212 | + String pathIdVer = this.getPresentPathIntoProfile(sessionInfo, tsKvProto.getKv().getKey()); |
1144 | if (pathIdVer != null) { | 1213 | if (pathIdVer != null) { |
1145 | // #1.1 | 1214 | // #1.1 |
1146 | if (lwM2MClient.getDelayedRequests().containsKey(pathIdVer) && tsKvProto.getTs() > lwM2MClient.getDelayedRequests().get(pathIdVer).getTs()) { | 1215 | if (lwM2MClient.getDelayedRequests().containsKey(pathIdVer) && tsKvProto.getTs() > lwM2MClient.getDelayedRequests().get(pathIdVer).getTs()) { |
@@ -1276,7 +1345,8 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | @@ -1276,7 +1345,8 @@ public class LwM2mTransportServiceImpl implements LwM2mTransportService { | ||
1276 | } | 1345 | } |
1277 | 1346 | ||
1278 | private boolean validateResourceInModel(LwM2mClient lwM2mClient, String pathIdVer, boolean isWritableNotOptional) { | 1347 | private boolean validateResourceInModel(LwM2mClient lwM2mClient, String pathIdVer, boolean isWritableNotOptional) { |
1279 | - ResourceModel resourceModel = lwM2mClient.getResourceModel(pathIdVer); | 1348 | + ResourceModel resourceModel = lwM2mClient.getResourceModel(pathIdVer, this.lwM2mTransportContextServer.getLwM2MTransportConfigServer() |
1349 | + .getModelProvider()); | ||
1280 | Integer objectId = new LwM2mPath(convertPathFromIdVerToObjectId(pathIdVer)).getObjectId(); | 1350 | Integer objectId = new LwM2mPath(convertPathFromIdVerToObjectId(pathIdVer)).getObjectId(); |
1281 | String objectVer = validateObjectVerFromKey(pathIdVer); | 1351 | String objectVer = validateObjectVerFromKey(pathIdVer); |
1282 | return resourceModel != null && (isWritableNotOptional ? | 1352 | return resourceModel != null && (isWritableNotOptional ? |
@@ -20,6 +20,7 @@ import lombok.extern.slf4j.Slf4j; | @@ -20,6 +20,7 @@ import lombok.extern.slf4j.Slf4j; | ||
20 | import org.eclipse.leshan.core.model.ResourceModel; | 20 | import org.eclipse.leshan.core.model.ResourceModel; |
21 | import org.eclipse.leshan.core.node.LwM2mPath; | 21 | import org.eclipse.leshan.core.node.LwM2mPath; |
22 | import org.eclipse.leshan.core.node.LwM2mResource; | 22 | import org.eclipse.leshan.core.node.LwM2mResource; |
23 | +import org.eclipse.leshan.core.node.LwM2mSingleResource; | ||
23 | import org.eclipse.leshan.server.model.LwM2mModelProvider; | 24 | import org.eclipse.leshan.server.model.LwM2mModelProvider; |
24 | import org.eclipse.leshan.server.registration.Registration; | 25 | import org.eclipse.leshan.server.registration.Registration; |
25 | import org.eclipse.leshan.server.security.SecurityInfo; | 26 | import org.eclipse.leshan.server.security.SecurityInfo; |
@@ -27,7 +28,9 @@ import org.thingsboard.server.gen.transport.TransportProtos; | @@ -27,7 +28,9 @@ import org.thingsboard.server.gen.transport.TransportProtos; | ||
27 | import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceCredentialsResponseMsg; | 28 | import org.thingsboard.server.gen.transport.TransportProtos.ValidateDeviceCredentialsResponseMsg; |
28 | import org.thingsboard.server.transport.lwm2m.server.LwM2mQueuedRequest; | 29 | import org.thingsboard.server.transport.lwm2m.server.LwM2mQueuedRequest; |
29 | import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportServiceImpl; | 30 | import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportServiceImpl; |
31 | +import org.thingsboard.server.transport.lwm2m.utils.LwM2mValueConverterImpl; | ||
30 | 32 | ||
33 | +import java.util.Collection; | ||
31 | import java.util.List; | 34 | import java.util.List; |
32 | import java.util.Map; | 35 | import java.util.Map; |
33 | import java.util.Queue; | 36 | import java.util.Queue; |
@@ -39,7 +42,9 @@ import java.util.concurrent.CopyOnWriteArrayList; | @@ -39,7 +42,9 @@ import java.util.concurrent.CopyOnWriteArrayList; | ||
39 | import java.util.stream.Collectors; | 42 | import java.util.stream.Collectors; |
40 | 43 | ||
41 | import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPARATOR_PATH; | 44 | import static org.thingsboard.server.common.data.lwm2m.LwM2mConstants.LWM2M_SEPARATOR_PATH; |
45 | +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.TRANSPORT_DEFAULT_LWM2M_VERSION; | ||
42 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.convertPathFromIdVerToObjectId; | 46 | import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.convertPathFromIdVerToObjectId; |
47 | +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.getVerFromPathIdVerOrId; | ||
43 | 48 | ||
44 | @Slf4j | 49 | @Slf4j |
45 | @Data | 50 | @Data |
@@ -94,12 +99,33 @@ public class LwM2mClient implements Cloneable { | @@ -94,12 +99,33 @@ public class LwM2mClient implements Cloneable { | ||
94 | } | 99 | } |
95 | } | 100 | } |
96 | 101 | ||
97 | - public ResourceModel getResourceModel(String pathRez) { | ||
98 | - if (this.getResources().get(pathRez) != null) { | ||
99 | - return this.getResources().get(pathRez).getResourceModel(); | ||
100 | - } else { | ||
101 | - return null; | ||
102 | - } | 102 | + public ResourceModel getResourceModel(String pathRez, LwM2mModelProvider modelProvider) { |
103 | + LwM2mPath pathIds = new LwM2mPath(convertPathFromIdVerToObjectId(pathRez)); | ||
104 | + String verSupportedObject = registration.getSupportedObject().get(pathIds.getObjectId()); | ||
105 | + String verRez = getVerFromPathIdVerOrId(pathRez); | ||
106 | + return (verRez == null || verSupportedObject.equals(verRez)) ? modelProvider.getObjectModel(registration) | ||
107 | + .getResourceModel(pathIds.getObjectId(), pathIds.getResourceId()) : null; | ||
108 | + } | ||
109 | + | ||
110 | + public Collection<LwM2mResource> getNewResourcesForInstance(String pathRezIdVer, LwM2mModelProvider modelProvider, | ||
111 | + LwM2mValueConverterImpl converter) { | ||
112 | + LwM2mPath pathIds = new LwM2mPath(convertPathFromIdVerToObjectId(pathRezIdVer)); | ||
113 | + String verSupportedObject = registration.getSupportedObject().get(pathIds.getObjectId()); | ||
114 | + String verRez = getVerFromPathIdVerOrId(pathRezIdVer); | ||
115 | + Collection<LwM2mResource> resources = ConcurrentHashMap.newKeySet(); | ||
116 | + Map<Integer, ResourceModel> resourceModels = modelProvider.getObjectModel(registration) | ||
117 | + .getObjectModel(pathIds.getObjectId()).resources; | ||
118 | + resourceModels.forEach((k, resourceModel) -> { | ||
119 | + resources.add(LwM2mSingleResource.newResource(k, converter.convertValue("0", ResourceModel.Type.STRING, resourceModel.type, pathIds), resourceModel.type)); | ||
120 | + }); | ||
121 | + return resources; | ||
122 | + } | ||
123 | + | ||
124 | + public boolean isValidObjectVersion (String path) { | ||
125 | + LwM2mPath pathIds = new LwM2mPath(convertPathFromIdVerToObjectId(path)); | ||
126 | + String verSupportedObject = registration.getSupportedObject().get(pathIds.getObjectId()); | ||
127 | + String verRez = getVerFromPathIdVerOrId(path); | ||
128 | + return verRez == null ? TRANSPORT_DEFAULT_LWM2M_VERSION.equals(verSupportedObject) : verRez.equals(verSupportedObject); | ||
103 | } | 129 | } |
104 | 130 | ||
105 | /** | 131 | /** |
@@ -26,7 +26,6 @@ import org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode; | @@ -26,7 +26,6 @@ import org.thingsboard.server.transport.lwm2m.secure.LwM2MSecurityMode; | ||
26 | import org.thingsboard.server.transport.lwm2m.secure.LwM2mCredentialsSecurityInfoValidator; | 26 | import org.thingsboard.server.transport.lwm2m.secure.LwM2mCredentialsSecurityInfoValidator; |
27 | import org.thingsboard.server.transport.lwm2m.secure.ReadResultSecurityStore; | 27 | import org.thingsboard.server.transport.lwm2m.secure.ReadResultSecurityStore; |
28 | import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler; | 28 | import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler; |
29 | -import org.thingsboard.server.transport.lwm2m.utils.TypeServer; | ||
30 | 29 | ||
31 | import java.util.Arrays; | 30 | import java.util.Arrays; |
32 | import java.util.Map; | 31 | import java.util.Map; |
@@ -119,7 +118,7 @@ public class LwM2mClientContextImpl implements LwM2mClientContext { | @@ -119,7 +118,7 @@ public class LwM2mClientContextImpl implements LwM2mClientContext { | ||
119 | */ | 118 | */ |
120 | @Override | 119 | @Override |
121 | public LwM2mClient addLwM2mClientToSession(String identity) { | 120 | public LwM2mClient addLwM2mClientToSession(String identity) { |
122 | - ReadResultSecurityStore store = lwM2MCredentialsSecurityInfoValidator.createAndValidateCredentialsSecurityInfo(identity, TypeServer.CLIENT); | 121 | + ReadResultSecurityStore store = lwM2MCredentialsSecurityInfoValidator.createAndValidateCredentialsSecurityInfo(identity, LwM2mTransportHandler.LwM2mTypeServer.CLIENT); |
123 | if (store.getSecurityMode() < LwM2MSecurityMode.DEFAULT_MODE.code) { | 122 | if (store.getSecurityMode() < LwM2MSecurityMode.DEFAULT_MODE.code) { |
124 | UUID profileUuid = (store.getDeviceProfile() != null && addUpdateProfileParameters(store.getDeviceProfile())) ? store.getDeviceProfile().getUuidId() : null; | 123 | UUID profileUuid = (store.getDeviceProfile() != null && addUpdateProfileParameters(store.getDeviceProfile())) ? store.getDeviceProfile().getUuidId() : null; |
125 | LwM2mClient client; | 124 | LwM2mClient client; |
1 | +/** | ||
2 | + * Copyright © 2016-2021 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.transport.lwm2m.server.client; | ||
17 | + | ||
18 | +import com.google.gson.JsonObject; | ||
19 | +import lombok.Data; | ||
20 | +import org.eclipse.leshan.core.request.ContentFormat; | ||
21 | +import org.eclipse.leshan.server.registration.Registration; | ||
22 | +import org.thingsboard.server.gen.transport.TransportProtos; | ||
23 | +import org.thingsboard.server.gen.transport.TransportProtos.SessionInfoProto; | ||
24 | +import org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.LwM2mTypeOper; | ||
25 | + | ||
26 | +import java.util.concurrent.ConcurrentHashMap; | ||
27 | + | ||
28 | +import static org.thingsboard.server.transport.lwm2m.server.LwM2mTransportHandler.validPathIdVer; | ||
29 | + | ||
30 | +@Data | ||
31 | +public class Lwm2mClientRpcRequest { | ||
32 | + public final String targetIdVerKey = "targetIdVer"; | ||
33 | + public final String keyNameKey = "key"; | ||
34 | + public final String typeOperKey = "typeOper"; | ||
35 | + public final String contentFormatNameKey = "contentFormatName"; | ||
36 | + public final String valueKey = "value"; | ||
37 | + public final String infoKey = "info"; | ||
38 | + public final String paramsKey = "params"; | ||
39 | + public final String timeoutInMsKey = "timeOutInMs"; | ||
40 | + public final String resultKey = "result"; | ||
41 | + public final String errorKey = "error"; | ||
42 | + public final String methodKey = "methodName"; | ||
43 | + | ||
44 | + private LwM2mTypeOper typeOper; | ||
45 | + private String targetIdVer; | ||
46 | + private String contentFormatName; | ||
47 | + private long timeoutInMs; | ||
48 | + private Object value; | ||
49 | + private ConcurrentHashMap<String, Object> params; | ||
50 | + private SessionInfoProto sessionInfo; | ||
51 | + private int requestId; | ||
52 | + private String errorMsg; | ||
53 | + private String valueMsg; | ||
54 | + private String infoMsg; | ||
55 | + private String responseCode; | ||
56 | + | ||
57 | + public void setValidTypeOper (String typeOper){ | ||
58 | + try { | ||
59 | + this.typeOper = LwM2mTypeOper.fromLwLwM2mTypeOper(typeOper); | ||
60 | + } catch (Exception e) { | ||
61 | + this.errorMsg = this.methodKey + " - " + typeOper + " is not valid."; | ||
62 | + } | ||
63 | + } | ||
64 | + public void setValidContentFormatName (JsonObject rpcRequest){ | ||
65 | + try { | ||
66 | + if (ContentFormat.fromName(rpcRequest.get(this.contentFormatNameKey).getAsString()) != null) { | ||
67 | + this.contentFormatName = rpcRequest.get(this.contentFormatNameKey).getAsString(); | ||
68 | + } | ||
69 | + else { | ||
70 | + this.errorMsg = this.contentFormatNameKey + " - " + rpcRequest.get(this.contentFormatNameKey).getAsString() + " is not valid."; | ||
71 | + } | ||
72 | + } catch (Exception e) { | ||
73 | + this.errorMsg = this.contentFormatNameKey + " - " + rpcRequest.get(this.contentFormatNameKey).getAsString() + " is not valid."; | ||
74 | + } | ||
75 | + } | ||
76 | + | ||
77 | + public void setValidTargetIdVerKey (JsonObject rpcRequest, Registration registration){ | ||
78 | + if (rpcRequest.has(this.targetIdVerKey)) { | ||
79 | + String targetIdVerStr = rpcRequest.get(targetIdVerKey).getAsString(); | ||
80 | + // targetIdVer without ver - ok | ||
81 | + try { | ||
82 | + // targetIdVer with/without ver - ok | ||
83 | + this.targetIdVer = validPathIdVer(targetIdVerStr, registration); | ||
84 | + if (this.targetIdVer != null){ | ||
85 | + this.infoMsg = String.format("Changed by: pathIdVer - %s", this.targetIdVer); | ||
86 | + } | ||
87 | + } catch (Exception e) { | ||
88 | + if (this.targetIdVer == null) { | ||
89 | + this.errorMsg = this.targetIdVerKey + " - " + targetIdVerStr + " is not valid."; | ||
90 | + } | ||
91 | + } | ||
92 | + } | ||
93 | + } | ||
94 | + | ||
95 | + public TransportProtos.ToDeviceRpcResponseMsg getDeviceRpcResponseResultMsg() { | ||
96 | + JsonObject payloadResp = new JsonObject(); | ||
97 | + payloadResp.addProperty(this.resultKey, this.responseCode); | ||
98 | + if (this.errorMsg != null) { | ||
99 | + payloadResp.addProperty(this.errorKey, this.errorMsg); | ||
100 | + } | ||
101 | + else if (this.valueMsg != null) { | ||
102 | + payloadResp.addProperty(this.valueKey, this.valueMsg); | ||
103 | + } | ||
104 | + else if (this.infoMsg != null) { | ||
105 | + payloadResp.addProperty(this.infoKey, this.infoMsg); | ||
106 | + } | ||
107 | + return TransportProtos.ToDeviceRpcResponseMsg.newBuilder() | ||
108 | + .setPayload(payloadResp.getAsJsonObject().toString()) | ||
109 | + .setRequestId(this.requestId) | ||
110 | + .build(); | ||
111 | + } | ||
112 | +} |
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/ResultsResourceValue.java
deleted
100644 → 0
1 | -/** | ||
2 | - * Copyright © 2016-2021 The Thingsboard Authors | ||
3 | - * | ||
4 | - * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | - * you may not use this file except in compliance with the License. | ||
6 | - * You may obtain a copy of the License at | ||
7 | - * | ||
8 | - * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | - * | ||
10 | - * Unless required by applicable law or agreed to in writing, software | ||
11 | - * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | - * See the License for the specific language governing permissions and | ||
14 | - * limitations under the License. | ||
15 | - */ | ||
16 | -package org.thingsboard.server.transport.lwm2m.server.client; | ||
17 | - | ||
18 | -import lombok.Data; | ||
19 | -import org.thingsboard.server.common.data.kv.DataType; | ||
20 | - | ||
21 | -@Data | ||
22 | -public class ResultsResourceValue { | ||
23 | - DataType dataType; | ||
24 | - Object value; | ||
25 | - String resourceName; | ||
26 | - | ||
27 | - public ResultsResourceValue (DataType dataType, Object value, String resourceName) { | ||
28 | - this.dataType = dataType; | ||
29 | - this.value = value; | ||
30 | - this.resourceName = resourceName; | ||
31 | - } | ||
32 | -} |
common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/utils/TypeServer.java
deleted
100644 → 0
1 | -/** | ||
2 | - * Copyright © 2016-2021 The Thingsboard Authors | ||
3 | - * | ||
4 | - * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | - * you may not use this file except in compliance with the License. | ||
6 | - * You may obtain a copy of the License at | ||
7 | - * | ||
8 | - * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | - * | ||
10 | - * Unless required by applicable law or agreed to in writing, software | ||
11 | - * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | - * See the License for the specific language governing permissions and | ||
14 | - * limitations under the License. | ||
15 | - */ | ||
16 | -package org.thingsboard.server.transport.lwm2m.utils; | ||
17 | - | ||
18 | -public enum TypeServer { | ||
19 | - BOOTSTRAP(0, "bootstrap"), | ||
20 | - CLIENT(1, "client"); | ||
21 | - | ||
22 | - public int code; | ||
23 | - public String type; | ||
24 | - | ||
25 | - TypeServer(int code, String type) { | ||
26 | - this.code = code; | ||
27 | - this.type = type; | ||
28 | - } | ||
29 | -} |