7.1. LwM2M testing shell
For the purpose of early testing of Anjay-based clients, we provide a simple CLI implementation of LwM2M. It is written in Python using powercmd library. You can find it in tests/integration/framework/nsh-lwm2m directory in the Anjay repository.
7.1.1. Running the server
You can start the server (from the main Anjay directory) by running ./tests/integration/framework/nsh-lwm2m/nsh_lwm2m.py with the following optional arguments:
- --help, -h
Show help.
- --ipv6, -6
Use IPv6 by default.
- --listen PORT, -l PORT
Immediately starts listening on specified CoAP port. Default UDP, can be TCP if –tcp is passed. If PORT is not specified, default one is used (5683 for CoAP, 5684 for CoAP/(D)TLS)
- --tcp, -t
Listen on TCP port
- --psk-identity IDENTITY, -i IDENTITY
PSK identity to use for DTLS connection (literal string).
- --psk-key KEY, -k KEY
PSK key to use for DTLS connection (literal string).
- --debug
Enable mbed TLS debug output.
7.1.2. Supported commands
In this section we present the commands supported by the shell, with a bunch of examples. The initial setup for most of the provided examples can be obtained by two commands, both runned from the main Anjay directory, first for setting up the server:
./bootstrap/framework/nsh-lwm2m/nsh_lwm2m.py -l 9000
and the second for setting up the client:
./output/bin/demo -e my_endpoint -u coap://127.0.0.1:9000
7.1.2.1. Handling messages
The most important group of commands are those for sending messages. Most of them just send the corresponding LwM2M message:
- bootstrap_finish
MSG_ID
TOKEN
OPTIONS
CONTENT
- changed
MSG_ID
TOKEN
LOCATION
OPTIONS
CONTENT
- coap_get
PATH
ACCEPT
MSG_ID
TOKEN
LOCATION
- content
MSG_ID
TOKEN
CONTENT
FORMAT
TYPE
OPTIONS
- continue
MSG_ID
TOKEN
TYPE
OPTIONS
- create
PATH
CONTENT
MSG_ID
TOKEN
OPTIONS
FORMAT
- created
MSG_ID
TOKEN
LOCATION
OPTIONS
- delete
PATH
MSG_ID
TOKEN
OPTIONS
- deleted
MSG_ID
TOKEN
LOCATION
OPTIONS
- deregister
PATH
MSG_ID
TOKEN
OPTIONS
- discover
PATH
MSG_ID
TOKEN
OPTIONS
- empty
- error_response
CODE
MSG_ID
TOKEN
OPTIONS
- est_coaps_simple_enroll
MSG_ID
TOKEN
URI_PATH
URI_QUERY
OPTIONS
CONTENT
- execute
PATH
CONTENT
MSG_ID
TOKEN
OPTIONS
- notify
TOKEN
CONTENT
FORMAT
CONFIRMABLE
OPTIONS
- observe
MSG_ID
TOKEN
OPTIONS
- observe_composite
PATHS
OBSERVE
ACCEPT
MSG_ID
TOKEN
OPTIONS
- read
PATH
ACCEPT
MSG_ID
TOKEN
OPTIONS
- read_composite
PATHS
ACCEPT
MSG_ID
TOKEN
OPTIONS
- request_bootstrap
ENDPOINT_NAME
PREFERRED_CONTENT_FORMAT
MSG_ID
TOKEN
URI_PATH
URI_QUERY
OPTIONS
CONTENT
- reset
MSG_ID
- send
PATH
MSG_ID
TOKEN
FORMAT
OPTIONS
CONTENT
- write
PATH
CONTENT
FORMAT
UPDATE
MSG_ID
TOKEN
OPTIONS
- write_attributes
PATH
LT
GT
ST
PMIN
PMAX
EPMIN
EPMAX
QUERY
MSG_ID
TOKEN
OPTIONS
- write_composite
CONTENT
FORMAT
MSG_ID
TOKEN
OPTIONS
Because sometimes it might be necessary to use Write message with a large block of data (e.g. when performing a firmware update) it may be handy to load the data from a file instead of writing it by hand. Nsh supports an additional command for this case:
- write_file
FNAME
PATH
FORMAT
CHUNKSIZE
TIMEOUT_S
Opens file
FNAME
and attempts to push it using BLOCK1 to the Client.
It is also possible to send a custom CoAP message/UDP datagram using Nsh:
- coap
TYPE
CODE
MSG_ID
TOKEN
OPTIONS
CONTENT
RESPOND
Send a custom CoAP message.
- udp
CONTENT
Send a custom UDP datagram.
And finally, there is a command waiting for a message sent by the client:
- recv
TIMEOUT_S
Waits for a next incoming message. If
TIMEOUT_S
is specified, the command will not wait longer thanTIMEOUT_S
if no messages are received.
Nsh provide also one more feature for handling messages.
When the user enters an empty line while the flags AUTO_UPDATE
, AUTO_REREGISTER
or AUTO_ACK
(see set command description)
are set, the server tries to handle the corresponding messages from the client,
responding them in a proper way. For example, when client sends notify
the result of entering an empty line on Nsh side should be:
[Lwm2mCmd] port: 9000, client: 127.0.0.1:47748 $
<- Register /rd?lwm2m=1.1&ep=my_endpoint<=86400: </1/1>,</2>,</3/0>,</4/0>,<...
-> Created /rd/demo
[Lwm2mCmd] port: 9000, client: 127.0.0.1:47748 $
Note
Usually there is no need for passing all of the command arguments. To see which are optional
you can use help for the considered command. In the output they are printed with ?
signs.
7.1.2.2. Working with payloads
7.1.2.2.1. Introduction
When a binary payload contains a non-printable character, it is
impossible to encode it as a plain text. To overcome this inconvenience the shell introduces a special
type: EscapedBytes
, in which you can hex-encode some of the bytes (in many cases it might be quite handy to
hex-encode just all of them): after \x
the following two characters are interpreted as hex digits encoding
one byte. Examples of the binary payloads encoded in such way can be found below, while discussing subshells.
Preparing or reading data in such format may be quite painful so Nsh has tools to make it more comfortable. To build TLV or CBOR payloads (which are binary formats), nsh exposes subshells. Each of them has its own set of commands, however, some of them are common. help, get_error and exit behave in a similar way to those known from the main shell. Other commands common for the subshells are:
- serialize
Displays the prepared structure as an encoded hex-escaped string (ready to use as EscapedBytes).
- show
Displays current element structure in a human-readable form.
7.1.2.2.2. CBOR subshell
This subshell is entered by cbor command. The only extra command supported is:
- add_resource
BASENAME
NAME
TYPE
VALUE
Adds the next entry to the existing CBOR data.
BASENAME
argument is optional and it can contain the parent path. InNAME
a path to some value-containing Resource/Resource Instance is kept.
7.1.2.2.3. TLV subshell
TLV subshell is entered by tlv command. It supports a few commands more:
- add_instance
ID
Creates an object instance with a given
ID
. It must be created as a top-level element.- add_multiple_resource
ID
Creates a Multiple Resource under the currently selected Object Instance (as a top-level element, if none is selected).
- add_resource
ID
VALUE
TYPE
Creates a Resource with a given
ID
under the currently selected Object Instance. If there is none, it is created as a top-level element.- add_resource_instance
ID
VALUE
TYPE
Creates a Resource Instance of the currently selected Multiple Resource.
- deserialize
DATA
Loads a TLV-encoded element structure for further processing. It is helpful, when we recieve data from read request from the client.
- make_multires
(RIID,VALUE),...
Builds Multiple Resource Instances from the list of pairs of
RIID
andVALUE
(of typeEscapedBytes
). The pairs need to be comma separated and no spaces are allowed.For example
(1,\x04),(5,\x02)
represents two object instances, first with ID 1 and value 4 and second with ID 5 and value 2.- remove
PATH
Removes an element to which the path points. The path consists of 1 - 3 integers, separated by
/
character.- select
PATH
Selects an Object Instance or Multiple Resource that further add_* calls will add elements into.
7.1.2.2.4. Using subshells example
Let’s suppose that we would like to encode some simple data as both CBOR ans TLV, let its structure be:
/0 (Instance)
-> /0 (Multiple Resource)
-> 0 = 2 (Resource Instance)
-> 1 = 5 (Resource Instance)
/1 (Instance)
-> /1 = 11 (Resource)
-> /3 = 1 (Resource)
To encode it as TLV, we need to enter the following commands:
add_instance 0
add_multiple_resource 0
make_multires (0,\x02),(1,\x05)
add_instance 1
add_resource 1 type=int 11
add_resource 3 type=int 1
After running these commands, the TLV data are ready, and you can see the result in human-readable form using show command:
[Lwm2mCmd/TLV] port: 9000, client: 127.0.0.1:47748 $ show
* exact: show
path value
---------------
0 instance (1 resources)
0/0 multiple resource (2 instances)
0/0/0 resource instance = b'\x02' (int: 2)
0/0/1 resource instance = b'\x05' (int: 5)
* 1 instance (2 resources)
1/1 resource = b'\x0b' (int: 11)
1/3 resource = b'\x01' (int: 1)
and when we escape the subshell with exit command, we will recieve the created data in form of EscapedBytes:
[Lwm2mCmd/TLV] port: 9000, client: 127.0.0.1:47748 $ exit
* exact: exit
exiting
\x08\x00\x08\x86\x00\x41\x00\x02\x41\x01\x05\x06\x01\xc1\x01\x0b\xc1\x03\x01
In CBOR the number of commands will be smaller, as we run them only for leaves:
add_resource 0/0/0 int 2
add_resource 0/0/1 int 5
add_resource 1/1 int 11
add_resource 1/3 int 1
which gives us the following CBOR data:
[Lwm2mCmd/CBOR] port: 9000, client: 127.0.0.1:47748 $ show
* exact: show
CBOR (4 elements):
{<SenmlLabel.NAME: 0>: '0/0/0', <SenmlLabel.VALUE: 2>: 2}
{<SenmlLabel.NAME: 0>: '0/0/1', <SenmlLabel.VALUE: 2>: 5}
{<SenmlLabel.NAME: 0>: '1/1', <SenmlLabel.VALUE: 2>: 11}
{<SenmlLabel.NAME: 0>: '1/3', <SenmlLabel.VALUE: 2>: 1}
and, in the same way as in the case of the TLV subshell, we escape the shell and recieve the encoded data:
[Lwm2mCmd/CBOR] port: 9000, client: 127.0.0.1:47748 $ exit
* exact: exit
exiting
\x84\xa2\x00\x65\x30\x2f\x30\x2f\x30\x02\x02\xa2\x00\x65\x30\x2f\x30\x2f\x31\x02\x05\xa2\x00\x63\x31\x2f\x31\x02\x0b\xa2\x00\x63\x31\x2f\x33\x02\x01
7.1.2.3. Decoding messages
Nsh supports two commands which are connected to both previously discussed topics - tools for decoding CoAP/LwM2M messages:
- coap_decode
DATA
Decodes a CoAP message and displays it in a human-readable form.
- lwm2m_decode
DATA
Decodes a LwM2M message and displays it in a human-readable form.
For example, we can decode an empty coap message (with EscapedBytes representation \x60\x00\x13\x38
):
[Lwm2mCmd] port: 9000, client: 127.0.0.1:47748 $ coap_decode \x60\x00\x13\x38
* exact: coap_decode
version: 1
type: ACKNOWLEDGEMENT
code: 0.00 (EMPTY)
msg_id: 4920
token: (length: 0)
options:
content: 0 bytes
7.1.2.4. Inspecting previous messages
Nsh supports also a bunch of tools for inspecting the results of the previous commands.
7.1.2.4.1. Message history
The first such tool is the message history which can be handled using two commands:
- details
N
Displays details of a
N
-th last message, or the last message, ifN
is not given.- reset_history
Clears command history.
To see how they work, let’s send a few messages, e.g.:
read /1/1/3/1
empty
reset
Now, we can check N-th message, sent or received, by running details N
(important note: the last message has N=1). For example, in such case running details 4
would return:
[Lwm2mCmd] port: 9000, client: 127.0.0.1:47748 $ details 4
* exact: details
*** Send ***
Read /1/1/3/1
version: 1
type: CONFIRMABLE
code: 0.01 (REQ_GET)
msg_id: 4920
token: NbwK\x18W\xc7\xcb (length: 8)
options:
option 11 (URI_PATH), content (1 bytes): 1
option 11 (URI_PATH), content (1 bytes): 1
option 11 (URI_PATH), content (1 bytes): 3
option 11 (URI_PATH), content (1 bytes): 1
content: 0 bytes
ascii-ish:
We can use also run this command without parameters, to see the last message:
[Lwm2mCmd] port: 9000, client: 127.0.0.1:47748 $ details
* exact: details
*** Send ***
Reset, msg_id = 4922
version: 1
type: RESET
code: 0.00 (EMPTY)
msg_id: 4922
token: (length: 0)
options:
content: 0 bytes
ascii-ish:
After running the reset_history command, the history will be cleared and
details (with any parameter) runned after that, returns only a warning message not found
.
7.1.2.4.2. Payload buffer
Another important tool is payload buffer. It stores the contents of the messages received by the server and can be accessed with a set of functions payload_buffer_*:
- payload_buffer_clear
Clears payload buffer.
- payload_buffer_show
Shows the payload buffer content.
- payload_buffer_show_hex
Shows the payload buffer content presented as hex.
- payload_buffer_show_tlv
Shows the payload buffer content presented as tlv.
Let’s see an example. After reading an object instance (with some human readable format, e.g. JSON):
[Lwm2mCmd] port: 9000, client: 127.0.0.1:47748 $ read /1/1 APPLICATION_LWM2M_JSON
* exact: read
-> Read /1/1: accept APPLICATION_LWM2M_JSON
<- Content (11543 (APPLICATION_LWM2M_JSON); 193 bytes)
the content of the message can be printed data using payload_buffer_show. The result should be similar to:
[Lwm2mCmd] port: 9000, client: 127.0.0.1:47748 $ payload_buffer_show
* exact: payload_buffer_show
b'{"bn":"/1/1","e":[{"n":"/0","v":1},{"n":"/1","v":86400},{"n":"/6","bv":true},{"n":"/7","sv":"U"},{"n":"/17","v":1},
{"n":"/18","v":0},{"n":"/19","v":1},{"n":"/20","v":0},{"n":"/23","bv":false}]}'
Sometimes it is quite useful to represent the data as hex-encoded bytes, what can be obtained with payload_buffer_show_hex, which for the considered JSON data looks like:
[Lwm2mCmd] port: 9000, client: 127.0.0.1:47748 $ payload_buffer_show_hex
* exact: payload_buffer_show_hex
\x7b\x22\x62\x6e\x22\x3a\x22\x2f\x31\x2f\x31\x22\x2c\x22\x65\x22\x3a\x5b\x7b\x22\x6e\x22\x3a\x22\x2f\x30\x22\x2c\x22
\x76\x22\x3a\x31\x7d\x2c\x7b\x22\x6e\x22\x3a\x22\x2f\x31\x22\x2c\x22\x76\x22\x3a\x38\x36\x34\x30\x30\x7d\x2c\x7b\x22
\x6e\x22\x3a\x22\x2f\x36\x22\x2c\x22\x62\x76\x22\x3a\x74\x72\x75\x65\x7d\x2c\x7b\x22\x6e\x22\x3a\x22\x2f\x37\x22\x2c
\x22\x73\x76\x22\x3a\x22\x55\x22\x7d\x2c\x7b\x22\x6e\x22\x3a\x22\x2f\x31\x37\x22\x2c\x22\x76\x22\x3a\x31\x7d\x2c\x7b
\x22\x6e\x22\x3a\x22\x2f\x31\x38\x22\x2c\x22\x76\x22\x3a\x30\x7d\x2c\x7b\x22\x6e\x22\x3a\x22\x2f\x31\x39\x22\x2c\x22
\x76\x22\x3a\x31\x7d\x2c\x7b\x22\x6e\x22\x3a\x22\x2f\x32\x30\x22\x2c\x22\x76\x22\x3a\x30\x7d\x2c\x7b\x22\x6e\x22\x3a
\x22\x2f\x32\x33\x22\x2c\x22\x62\x76\x22\x3a\x66\x61\x6c\x73\x65\x7d\x5d\x7d
To use the function payload_buffer_show_tlv we need some data in TLV format, so with the current payload it prints only an error:
[Lwm2mCmd] port: 9000, client: 127.0.0.1:47748 $ payload_buffer_show_tlv
* exact: payload_buffer_show_tlv
attempted to take 7217722 bytes, but only 187 available (try "get_error" for details)
Moreover, after reading the object instance with read /1/1 APPLICATION_LWM2M_TLV
, the result will be the same.
The reason of such behavior is that there is some data in payload which is not in TLV encoding.
In such case payload_buffer_clear is needed before:
payload_buffer_clear
read /1/1 APPLICATION_LWM2M_TLV
payload_buffer_show_tlv
And finally some nice, human-readable TLV representation is printed:
[Lwm2mCmd] port: 9000, client: 127.0.0.1:47748 $ payload_buffer_show_tlv
* exact: payload_buffer_show_tlv
TLV (9 elements):
resource 0 = b'\x01' (int: 1)
resource 1 = b'\x00\x01Q\x80' (int: 86400, float: 0.000000)
resource 6 = b'\x01' (int: 1)
resource 7 = b'U' (int: 85)
resource 17 = b'\x01' (int: 1)
resource 18 = b'\x00' (int: 0)
resource 19 = b'\x01' (int: 1)
resource 20 = b'\x00' (int: 0)
resource 23 = b'\x00' (int: 0)
7.1.2.4.3. Checking errors
When something was wrong with your last command Nsh will return an error. It might be helpful to get some more details and for this purpose you can use get_error command. To see how it works, let’s try the following read:
[Lwm2mCmd] port: 9000, client: 127.0.0.1:47748 $ read 0/3
* exact: read
could not send Lwm2mRead (not a valid CoAP path: 0/3) (try "get_error" for details)
Some error was returned, so get_error command can be used to see some details. A similar trace should be printed:
[Lwm2mCmd] port: 9000, client: 127.0.0.1:47748 $ get_error
* exact: get_error
Traceback (most recent call last):
File "./bootstrap/framework/nsh-lwm2m/nsh_lwm2m.py", line 862, in send_msg
self._send(cls(*args, **kwargs))
File "/home/mziobro/anjay/bootstrap/framework/nsh-lwm2m/lwm2m/messages.py", line 636, in __init__
path = Lwm2mNonemptyPath(path)
File "/home/mziobro/anjay/bootstrap/framework/nsh-lwm2m/lwm2m/path.py", line 62, in __init__
super().__init__(text)
File "/home/mziobro/anjay/bootstrap/framework/nsh-lwm2m/lwm2m/path.py", line 32, in __init__
super().__init__(text)
File "/home/mziobro/anjay/bootstrap/framework/nsh-lwm2m/lwm2m/path.py", line 13, in __init__
raise ValueError('not a valid CoAP path: %s' % (text,))
ValueError: not a valid CoAP path: 0/3
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/mziobro/anjay/bootstrap/framework/nsh-lwm2m/powercmd/powercmd/cmd.py", line 173, in default
return invoker.invoke(self, cmdline=CommandLine(cmdline))
File "/home/mziobro/anjay/bootstrap/framework/nsh-lwm2m/powercmd/powercmd/command_invoker.py", line 208, in invoke
return cmd.handler(*args, **typed_args)
File "./bootstrap/framework/nsh-lwm2m/nsh_lwm2m.py", line 864, in send_msg
raise e.__class__('could not send %s (%s)' % (cls.__name__, e))
ValueError: could not send Lwm2mRead (not a valid CoAP path: 0/3)
As we can see, the error was raised in line 13 of path.py
:
def __init__(self, text):
if not text.startswith('/'):
raise ValueError('not a valid CoAP path: %s' % (text,))
Now the issue with the path is clear - it is not started with /
character.
7.1.2.5. Dealing with connections
To this point we always used the same setting of the client and the server, with the server port given as a command line parameter. This approach is sufficient for most of cases, but Nsh supports three commands for modifying the connection in runtime:
- connect
HOST
PORT
Connects the socket to given
HOST:PORT
. Future packets will be sent to this address.- listen
PORT
PSK_IDENTITY
PSK_KEY
CA_PATH
CA_FILE
CRT_FILE
KEY_FILE
IPV6
DEBUG
CONNECTION_ID
Starts listening on given
PORT
. If any ofPSK_IDENTITY
,PSK_KEY
,CA_PATH
,CA_FILE
,CRT_FILE
orKEY_FILE
are specified, sets up a DTLS server, otherwise - raw CoAP server.- unconnect
“Unconnects” the socket from an already accepted client. The idea is that then the server will be able to receive packets from different (host, port), which may be useful for testing purposes.
7.1.2.6. Testing
We can use Nsh for running list of commands from a file, working as a kind of a primitive test case. There are two commands which can be especially helpful in such situation:
- expect
MSG_CODE
Makes the shell compare next received packet against the one configured via this command and print a message if a mismatch is detected.
MSG_CODE
can be:a string with Python code that evaluates to a correct message,
None, if no messages are expected,
ANY to disable checking (default).
Note: after receiving each message the “expected” value is set to ANY.
- sleep
TIMEOUT_S
Blocks for
TIMEOUT_S
seconds. Might be helpful when we want to be sure that the client have enough time to make some action.
7.1.2.7. Different kinds of servers
Besides a casual LwM2M server, Nsh can also serve in two different ways:
as a bootstrap LwM2M server,
for serving files over CoAP.
They are implemented with the following commands (respectively):
- bootstrap
URI
SECURITY_MODE
PSK_IDENTITY
PSK_KEY
CLIENT_CERT_PATH
CLIENT_PRIVATE_KEY_PATH
SERVER_CERT_PATH
SSID
IS_BOOTSTRAP
LIFETIME
NOTIFICATION_STORING
BINDING
IID
FINISH
TLS_CIPHERSUITES
Sets up a Security and Server instances for an LwM2M server.
In case of PreSharedKey security mode,
PSK_IDENTITY
andPSK_KEY
are literal plain text sequences to be used as DTLS identity and secret key.In case of Certificate security mode,
CLIENT_CERT_PATH
andSERVER_CERT_PATH
shall be paths to binary DER-encoded X.509 certificates, andCLIENT_PRIVATE_KEY_PATH
to binary DER-encoded PKCS#8 file, which MUST NOT be password-protected.If
IS_BOOTSTRAP
is True, only the Security object instance is configured.LIFETIME
,NOTIFICATION_STORING
andBINDING
are ignored in such case.SSID
is still set for the Security instance.Both Security and Server object instances are created with given
IID
.If
FINISH
is set to True, a Bootstrap Finish message will be sent after setting up Security/Server instances.- file_server
ROOT_DIRECTORY
PORT
PSK_IDENTITY
PSK_KEY
CA_PATH
CA_FILE
CRT_FILE
KEY_FILE
IPV6
DEBUG
Serves files from
ROOT_DIRECTORY
over CoAP(s).
As they are the most complex commands, we provide examples for both of them:
7.1.2.7.1. Bootstrapping
To show how we can use Nsh for bootstrapping, we set up the bootstrap server:
./bootstrap/framework/nsh-lwm2m/nsh_lwm2m.py -l 9000
and the second one (in some other terminal), this time on a different port and using some id and password (for the sake of simplicity the id=`user`and password=`password`):
./bootstrap/framework/nsh-lwm2m/nsh_lwm2m.py -l 9500 --psk-identity user --psk-key password
Then we run the client (important note: --bootstrap
option is necessary):
./output/bin/demo -e my_endpoint -u coap://127.0.0.1:9000 --bootstrap
At this point the client is connected to the first server and we need to provide it information sufficient for connecting the second server:
[Lwm2mCmd] port: 9000, client: 127.0.0.1:41266 $ bootstrap finish=True ssid=1 uri=coaps://127.0.0.1:9500 security_m
ode=PreSharedKey psk_identity=user psk_key=password
* exact: bootstrap
-> Write /0: APPLICATION_LWM2M_TLV, 58 bytes
<- Changed (no location path)
-> Write /1: APPLICATION_LWM2M_TLV, 18 bytes
<- Changed (no location path)
-> Bootstrap Finish /bs:
<- Changed (no location path)
Now the client is connected to the second server. As we can see in the bootstrap server log, it sent 3 messages to the client, two Writes to set the Server and Security objects and Bootstrap Finish in the end.
7.1.2.7.2. Serving files over CoAP
To see how we can use Nsh for serving files, first start it without arguments:
./bootstrap/framework/nsh-lwm2m/nsh_lwm2m.py
and then start serving files from Anjay directory:
[Lwm2mCmd] $ file_server . 9000
* exact: file_server
Serving directory /home/mziobro/anjay on port 9000...
Press CTRL-C to stop
Currently we do not have to connect, so we can run the client with any URI starting with coap://
./output/bin/demo -e my_endpoint -u coap://anything
Because the URI is invalid, we will recieve a few errors, but the client will run. Now, we use download command on the client side. Assuming that we are in the same (i.e. Anjay) directory, it will just copy one of the files (in this case, we download Makefile to Makefile_copy):
download coap://127.0.0.1:9000/Makefile Makefile_copy
7.1.2.8. Miscellaneous
There are a few commands, rather simple, which does not fit in any previous category:
- exit
Terminates the command loop. Equivalent to
Ctrl+D
.- help
Displays a description of given command or lists all available commands.
- set
AUTO_UPDATE
AUTO_REREGISTER
AUTO_ACK
AUTO_BSPACK_ERROR
Sets in which situation server sends a message to a client automatically:
AUTO_UPDATE
- when LwM2M Update is received from the client,AUTO_REREGISTER
- when LwM2M Register is received from the client,AUTO_ACK
- after any confirmable message from the client.AUTO_BSPACK_ERROR
- afterBootstrapPackRequest
is received it automatically responds withNOT FOUND
.
If some of the options are absent, their state remains unchanged.