I'm trying to emulate LwM2M client nodes with node.js coap package. I have LwM2M server running and listening to port 5555
at my Raspberry Pi 3.
Currently all I've achieved is sending an UDP packet to lo
(loopback) interface. (However it's encapsulated inside another UDP packet which has source and destination of 00:00:00:00:00:00, but that doesn't matter to me right now).
const coap = require('../') // Script is located inside package examples directory
const endpointClientName = 'someSensor'
const lifetime = '600'
const version = '1.0'
const binding = 'UQ'
let bodyString = '?ep=' + endpointClientName + '<=' + lifetime + '&lwm2m=' + version + '&b=' + binding;
let responseBody = '';
let options = {
host : 'fd72:cafe:face:0:fade:deaf:1234:5678',
port : 5555,
pathname : "/rd",
method : 'POST',
confirmable : 'true',
options : {
'Accept' : 'application/json'
}
};
let request = coap.request(options);
request.on('response', function (response) {
response.on('data', function () {
responseBody += response.payload.toString();
});
response.on('end', function () {
if (response.code == '2.01') {
console.log('[coap] device registered.');
var obj = JSON.parse(responseBody);
console.log('[coap] responseBody', obj);
} else {
console.log('[coap] coap response.code=' + response.code);
}
});
});
request.write(bodyString);
request.end();
code above produces UDP packet which contains data:
Data (50 bytes)
Data: 44021dff8ea487ebb272646132ff3f65703d736f6d655365...
[Length: 50]
data below pasted from wireshark as hex dump
0000 44 02 1d ff 8e a4 87 eb b2 72 64 61 32 ff 3f 65
0010 70 3d 73 6f 6d 65 53 65 6e 73 6f 72 26 6c 74 3d
0020 36 30 30 26 6c 77 6d 32 6d 3d 31 2e 30 26 62 3d
0030 55 51
However I'm expecting Wireshark to show packet as CoAP packet, which would contain segments separated into several parts:
Opt Name: #1: Uri-Path: rd
Opt Name: #2: Uri-Query: ep=someSensor
Opt Name: #3: Uri-Query: lt=600
Opt Name: #4: Uri-Query: lwm2m=1.0
Opt Name: #5: Uri-Query: b=UQ
What am I doing wrong? Perhaps I'm setting wrong options? I've noticed that some send request to address coap://localhost:port/path
, however I've failed to achieve better results by using other ways.
The whole problem was that options like lifetime
and lwm2m
version were in packet body, however it has to be described in query
:
query: Query string. Defaults to ''. Should not include the path, e.g.
'a=b&c=d'
also after registering device, response is not in json format, also all information is not in response body, but in response options:
message.options
All the CoAP options, as parsed by CoAP-packet.
All the options are in binary format, except for
'Content-Format'
,'Accept'
and'ETag'
. SeeregisterOption()
to know how to register more.See the spec for all the possible options.
With that said, problem is solved by slightly modifying the code:
const coap = require('../') // Script is located inside package examples directory
const serverAddress = 'fd72:cafe:face:0:fade:deaf:1234:5678'
const serverPort = 5555
const endpointClientName = 'someSensor'
const lifetime = '600'
const version = '1.0'
const binding = 'UQ'
const uriQuery = 'ep=' + endpointClientName + '<=' + lifetime + '&lwm2m=' + version + '&b=' + binding;
const clientResources = '/1/0'
let options = {
host : serverAddress,
port : serverPort,
pathname : "/rd",
method : 'POST',
confirmable : 'true',
query : uriQuery,
};
let request = coap.request(options);
request.on('response', function (response) {
console.log('[coap] coap response.code = ' + response.code);
console.log('[coap] coap response.options = ' + response.options);
});
request.write(clientResources);
request.end();