|
18 | 18 |
|
19 | 19 | import java.net.SocketException; |
20 | 20 | import java.net.UnknownHostException; |
| 21 | +import java.nio.charset.StandardCharsets; |
21 | 22 | import java.util.LinkedHashMap; |
22 | 23 | import java.util.List; |
23 | 24 | import java.util.Locale; |
|
33 | 34 | import org.eclipse.californium.core.coap.OptionNumberRegistry; |
34 | 35 | import org.eclipse.californium.core.coap.Request; |
35 | 36 | import org.eclipse.californium.core.coap.Response; |
| 37 | +import org.eclipse.californium.core.coap.option.OpaqueOption; |
36 | 38 | import org.eclipse.californium.core.network.Endpoint; |
37 | 39 | import org.eclipse.jdt.annotation.NonNullByDefault; |
38 | 40 | import org.eclipse.jdt.annotation.Nullable; |
@@ -155,6 +157,27 @@ public boolean isStarted() { |
155 | 157 | return statusClient != null; |
156 | 158 | } |
157 | 159 |
|
| 160 | + private byte[] readOptionBytes(Option option) { |
| 161 | + try { |
| 162 | + return option.encode(); |
| 163 | + } catch (RuntimeException e) { |
| 164 | + logger.debug("{}: Failed to encode option value", thingName, e); |
| 165 | + return EMPTY_BYTE; |
| 166 | + } |
| 167 | + } |
| 168 | + |
| 169 | + private String readStringOption(Option option) { |
| 170 | + return new String(readOptionBytes(option), StandardCharsets.UTF_8); |
| 171 | + } |
| 172 | + |
| 173 | + private int readIntegerOption(Option option) { |
| 174 | + int value = 0; |
| 175 | + for (byte b : readOptionBytes(option)) { |
| 176 | + value = (value << 8) | (b & 0xFF); |
| 177 | + } |
| 178 | + return value; |
| 179 | + } |
| 180 | + |
158 | 181 | /** |
159 | 182 | * Process an inbound Response (or mapped Request): decode CoAP options. handle discovery result or status updates |
160 | 183 | * |
@@ -182,7 +205,7 @@ public void processResponse(@Nullable Response response) { |
182 | 205 | // We can't identify device by IP, so we need to check the CoAP header's Global Device ID |
183 | 206 | for (Option opt : options) { |
184 | 207 | if (opt.getNumber() == COIOT_OPTION_GLOBAL_DEVID) { |
185 | | - String devid = opt.getStringValue(); |
| 208 | + String devid = readStringOption(opt); |
186 | 209 | if (devid.contains("#") && profile.device.mac != null) { |
187 | 210 | // Format: <device type>#<mac address>#<coap version> |
188 | 211 | String macid = substringBetween(devid, "#", "#"); |
@@ -226,14 +249,14 @@ public void processResponse(@Nullable Response response) { |
226 | 249 | for (Option opt : options) { |
227 | 250 | switch (opt.getNumber()) { |
228 | 251 | case OptionNumberRegistry.URI_PATH: |
229 | | - uri = COLOIT_URI_BASE + opt.getStringValue(); |
| 252 | + uri = COLOIT_URI_BASE + readStringOption(opt); |
230 | 253 | break; |
231 | 254 | case OptionNumberRegistry.URI_HOST: // ignore |
232 | 255 | break; |
233 | 256 | case OptionNumberRegistry.CONTENT_FORMAT: // ignore |
234 | 257 | break; |
235 | 258 | case COIOT_OPTION_GLOBAL_DEVID: |
236 | | - devId = opt.getStringValue(); |
| 259 | + devId = readStringOption(opt); |
237 | 260 | String sVersion = substringAfterLast(devId, "#"); |
238 | 261 | int iVersion; |
239 | 262 | try { |
@@ -267,7 +290,7 @@ public void processResponse(@Nullable Response response) { |
267 | 290 | case COIOT_OPTION_STATUS_VALIDITY: |
268 | 291 | break; |
269 | 292 | case COIOT_OPTION_STATUS_SERIAL: |
270 | | - serial = opt.getIntegerValue(); |
| 293 | + serial = readIntegerOption(opt); |
271 | 294 | break; |
272 | 295 | default: |
273 | 296 | logger.debug("{} ({}): CoAP option {} with value {} skipped", thingName, devId, opt.getNumber(), |
|
0 commit comments