Bootstrap discovery was not implemented properly in the LwM2M engine.
Although, there were some indications in the source code that it is
implemented, it was not done according to spec (and actually broken).
Given that Bootstrap Discovery procedure differs a lot from the regular
Device Management Discovery (different permissions, different
information returned), it's easier to implement it as a separate
function (`bootstrap_discovery()`) instead of making the existing
`do_discovery_op()` function even more complicated.
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
The LwM2M firmware pull object no longer uses the system workqueue
to execute firmware_transfer(), but directly executes it itself.
Previously, the workqueue would be blocked because firmware_transfer()
indirectly calls a blocking connect(). This would lead to problems
with e.g. modem drivers that use UART to interface with the modem
hardware, as some UART drivers use the workqueue.
Fixes#31053.
Signed-off-by: Maik Vermeulen <maik.vermeulen@innotractor.com>
A dedicated LwM2M execute callback type has been implemented which
supports execute arguments. The lwm2m engine, lwm2m_client sample and
lwm2m objects have been updated accordingly. Also the API change has
been documented, and the lwm2m engine reference has been updated.
Fixes#30551.
Signed-off-by: Maik Vermeulen <maik.vermeulen@innotractor.com>
Previously, lwm2m_engine set would check against the max_data_len
parameter of the ressource, but didn't take into consideration the
(possibly changed) max_data_len returned by the pre_write callback.
Fixes#30541
Signed-off-by: Henning Fleddermann <henning.fleddermann@grandcentrix.net>
The message should only be returned if the requested pending/reply
pointer is not NULL. Otherwise it could get an incorrect match (for
instance if specific pending pointer is searched for and reply is NULL
the function could return any message that doesn't expect a reply (and
thus has its reply pointer set to NULL).
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
LwM2M engine by default sends piggybacked responses for requests after
all callbacks are executed. This approach however isn't good enough if
the application callback executes some lenghty operations (for instance
during FW update). Delaying the ACK may result in unnecessary
retransmissions.
This commits adds an API function which allows to send an early empty
ACK from the application callback. This prevents further retransmissions
from the server side. After all callbacks are executed, the LwM2M engine
will send the response as a separate CON message.
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
Verify if block tranfer is used and not an initial block when skipping
directly to data processing during FW update in PUSH mode.
This fixes a bug, which caused TLV not to be processed when the FW
object was updated as a whole, and actual resource number was encoded in
a TLV (for instance when writing FW Update URI).
Fixes#30135
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
Rework the bootstrap DELETE operation, to support deletion of multiple
resources.
Current implementation had several oversimplifications, making it not
spec-compliant:
* DELETE `/` removed only Security object instances (!= 0)
* DELETE `/x` was handled as DELETE `/x/0`, therefore not removing all
of the object instances.
Since the above is only supported during bootstrap and not regular
Device management, this functionality was implemented in the
`bootstrap_delete` function, which now will be called for all DELETE
operations initiated during bootstrap. The regular LwM2M DELETE handler
will only be called during regular Device management, as it has more
strict limitations on what can be deleted.
Additionally, handle empty URI Path option as `/`, therefore indicating
deletion of all resources.
Fixes#29964
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
If networking pre-emptive thread priorities are enabled,
then use the proper macro to enable them.
Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
Add a simple backoff mechanism between consecutive registration attempts
in case of registration failures. Finally, notify the application in
case the registration failed several times.
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
Refactor the boostrap regstration procedure, by splitting the message
creation and sending into a separate function, in similar manner as
it's done with regular registration.
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
Currently, when socket errors occur during receive, the LwM2M engine
restarts the state machine and registers again to the server. While this
works in simple use case (only RD client socket open), it's not a valid
approach when more sockets are open (FW update socket).
Fix this by introducing socket fault callback, which is registered by
the LwM2M engine users. This way, a proper socket owner is notified on
error and can pertake appropriate action.
For RD socket errors the behaviour remains the same - the state machine
is reset and the client registers again to the server. For FW update
socket, handle the error by reopening the socket and retransmitting the
last request. This allows to resume the download from the point the
error occured, w/o a need to start from scratch.
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
According to LwM2M specfication v1.0.2, par. 5.3.2, the LwM2M client
MUST send an “Update” operation to the LwM2M Server whenever the
lifetime parameter of the Server object changes the server). The same
applies for the object instances created/deleted. The changes in objects
seem to already be handled, but the lifetime was not.
Additionally, the "Update" message shall only contain these parameters
which changed since the last update (including objects). As it's
straightforward to determine if the liftime changed but it's not easy
to tell if there were updates in the object instances, add an
additional parameter to the engine_trigger_update() function, indicating
that new object information shall be sent in the "Update" message.
Eventually add a proper error checking in `sm_send_registration` as the
function is reworked anyway.
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
The memset on firmware_ctx during PULL FW update initialization will
set the socket descriptor to a valid value of 0. This leads to an error
if parsing of the URI provided by the server fails, and the firware_ctx
is closed - the socket with a descriptor 0 will be accidently closed.
Fix this by invalidating the socket FD after the memset on
initialization.
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
It shouldn't be optional to handle separate response, as it's a
mandatory requirement according to the RFC7252:
"The protocol leaves the decision whether to
piggyback a response or not (i.e., send a separate response) to
the server. The client MUST be prepared to receive either."
Therefore, remove the flag as separate responses are handled now
properly.
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
Separate response handling implemented in the engine was faulty. The
separate response was not acknowledged by the client, resulting in
spurious retransmissions from the server side.
Also, the pending CON message was retransmitted by the client even after
it was acknowledged by an empty ACK, but the respnse haven't arrived
yet. Fix this by adding a new `acknowledged` flag to the `lwm2m_message`
structure. Once acknowledged, the flag is set and the confirmable
message is no longer retransmitted. We keep the message on the pending
list in order to timeout properly in case separate response does not
arrive in time.
Finally, prevent the reply callback from being called twice in case
the response is transmitted separately from ACk. The callback should
only be called on the actual reply, not the empty ACK.
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
So far this function existed as a static function in LwM2M PULL FOTA
module. Since such functionality will be needed in other places, make it
an internal API function.
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
Some LWM2M backends/servers, such as emxq, expect the sequence numbers
to begin on 0.
This change is in line with how other lwm2m clients, such as Anjay and
Wakama, starts the notification sequence.
Signed-off-by: Viktor Sjölind <viktor.sjolind@endian.se>
Prior to this commit, the LwM2M stack would TLV-encode integers
depending on their internal storage size. An integer with value 5 stored
in an int8_t would be encoded with length 1, but an integer stored in an
int32_t would be encoded as "00 00 00 05" with length 4.
This commit checks if the value is castable to a smaller int and encodes
it as such if so. This is cascading, so even a 64 bit integer with value
5 will be encoded with length 1.
Note that this does not seem to be required by the specification, but
this is how Anjay and the other LwM2M stack seem to do it.
Signed-off-by: Benjamin Lindqvist <benjamin.lindqvist@endian.se>
Improve token handling by removing special meaning of tokenlen == 0,
which allows to handle server requests w/o a token (so far such
requests would cause the lwm2m engine to autogenerate token in the
response).
In order to autogenerate token during message initialization, use
special symbol `LWM2M_MSG_TOKEN_GENERATE_NEW`. If no token is wished to
be used, simply set the tokenlen to 0.
Additionally, fix an issue with token autogeneration, where invalid
token len was used (0 instead of 8).
Fixes#28299
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
LwM2M engine did not set response code for the Bootstrap-finish message,
hence it replied with the code copied from the request which is not
correct. Fix this by setting correct code for the Bootstrap-finish
reply.
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
So far, `LWM2M_RD_CLIENT_EVENT_BOOTSTRAP_TRANSFER_COMPLETE` event was
reported before the final ACK for the Bootstrap Finish was sent from the
client side. This could cause delays in the ACK sending, in case the
application wanted for instance to store the received data in flash.
Fix this, by reporting the
`LWM2M_RD_CLIENT_EVENT_BOOTSTRAP_TRANSFER_COMPLETE` event on the next
state tansition (before the actual registration starts).
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
"Public Key or Identity" resource is of opaque data type, therefore it's
not correct to assume it will be a NULL terminated string (the existing
servers, for instance Leshan, does not include NULL terminator). Use the
actual size associated with the resource instead.
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
So far, the resource instance structure kept only the information about
the buffer length provided to the resource (in the `data_len` field).
While this approach might be enough for integer resources, where the
actual data size is fixed, it did not work for opaque resources. It is
impossible to determine the actual opaque resource length after it's
been written into.
Fix this, by replacing the current `data_len` field of the
`lwm2m_engine_res_inst` with `max_data_len`, indicating the buffer
size, and making the `data_len` field to hold the actual data size of
the resource.
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
Currently, after `CONFIG_LWM2M_RD_CLIENT_SUPPORT_BOOTSTRAP` is enabled,
the LwM2M engine will initiate bootstrap procedure on each run. This
approach limits the flexibility of the application, as it's not always
necessary to go over the bootstrap procedure (for instance, the
application may decide to store the security object obtained during the
bootstrap in flash, and restore it on boot).
Fix this by introducing an additional `flags` parameter to the
`lwm2m_rd_client_start()` function, which provides information whether
to run bootstrap in the current session or not.
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
So far, the LwM2M state machine started in the `ENGINE_INIT` state,
which made it exectue the registration/bootstrap registration even when
`lwm2m_rd_client_start()` was not called. With a new `ENGINE_IDLE`
state, the state machine can wait for the application to actually start
the client before proceeding. It also makes sense to stay in the
ENGINE_IDLE state after successfull deregistration, until the
application restarts the client.
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
This commit fixes PUSH FOTA when opaque content-format is used.
This consists of the following fixes:
* Moved `struct block_context` to a private header, so that it can be a
part of `struct lwm2m_input_context`. This allows content decoders to
make use of the block context data.
* Removed faulty `get_length_left` function from the plain text
decoder, and replace it with coap_packet_get_payload() to obtain the
actual payload size.
* Introduce `struct lwm2m_opaque_context` as a part of block context,
which allows to keep track of opaque data download progress.
* Simplify `lwm2m_write_handler_opaque()` function. It will now only
make calls to `engine_get_opaque` - it's the decoder responsibility
to update the opaque context according to it's content format (for
instance TLV decoder should only update it with the actual opaque
data size, not the whole TLV).
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
support longer name like urn:dev:ops:{OUI}-{ProductClass}-{SerialNumber}
or urn:imei-msisdn:###############-###############
Signed-off-by: Pascal Brogle <pascal.brogle@husqvarnagroup.com>
Change so that the caller of lwm2m_init_message is
responsible for generating a message id and remove message id generation
from lwm2m_init_message. Prevents generating a new id when the caller's
intent is to init a message with id 0.
Fixes#28283
Signed-off-by: Pascal Brogle <pascal.brogle@husqvarnagroup.com>
message id 0 and token 0 have special semantics in the lwm2m engine,
they are used to request generation of new id, mark them as such.
Signed-off-by: Pascal Brogle <pascal.brogle@husqvarnagroup.com>
The default string representing Sensor Type resource in Generic IPSO
object would not fit into the predefined buffer. Increase the buffer
size and add extra BUILD_ASSERT to detect this situation.
Coverity ID: 214225
Fixes#28164
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
Fix for a problem in current lwm2m firmware object implementation.
Transfer should not begin when an empty string is received.
Signed-off-by: Marin Jurjevic <marin.jurjevic@hotmail.com>
Now that device_api attribute is unmodified at runtime, as well as all
the other attributes, it is possible to switch all device driver
instance to be constant.
A coccinelle rule is used for this:
@r_const_dev_1
disable optional_qualifier
@
@@
-struct device *
+const struct device *
@r_const_dev_2
disable optional_qualifier
@
@@
-struct device * const
+const struct device *
Fixes#27399
Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
-Wimplicit-fallthrough=2 requires a fallthrough comment or a compiler
to tells gcc that this happens intentionally.
Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
The LwM2M server might modify the lifetime value while the device is
registered, hence it's needed to obtain the value directly from the
Server object instance, before each Register Update.
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
A proper way to match a Security object instance with a Server object
instance is via Short Server ID resource. Both coupled object instances
should carry the same value of this resource in order to me considered
matched.
This was not implemented in the LwM2M library and it was incorrectly
assumed that the Security object instance index corresponds to the
Server object instance index. While such apporach works is simple
scenario, it might yield incorrect results when bootstrap is used.
Fix this, by verifyng the Short Server ID resource in the Secuirty
instance used, and finding a matching Server instance. The server object
instance is stored for future use in the engine.
Additionally, remove an extra Server object instance that was created
when the bootstrap procedure was used. Since the boostrap Security
object instance does not have the corresponding Server object, it's
enough to have a single Server instance.
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
Currently, functions for poll sock_fds array management are buggy, in
case there is another socket open (for instance the socket for firmware
update download), it could get overwritten, if the LwM2M socket was
closed and re-opened in a meantime (e. g. on registration timeout).
Fix this, by appending new entries to the sock_fds in continuous manner.
In case of removal, the deleted entry is overwritten by the last one,
and the last one is cleared.
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
During FW update, the application expects a consecutive data stream.
Therefore retransmitted blocks shall not be forwarded to the
application, but ignored. In case blocks are received out of order,
return an error and do not handle this block.
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
When FW update in PUSH mode is used, the firmware is encapsulated in the
TLV as an opaque data, according to the LMWM2M satandard, and then
sliced into blocks and transferred block by block in several
transactions. Therefore, the TLV header is only present in the initial
message.
Current implementation did not handle this case well, reporting errors
on consecutive blocks, therefore making the FW update in PUSH mode
broken.
This commit fixes this issue with following changes:
* The TLV is only assumed to be present in the initial block, while
consecutive blocks will be processed directly into the appropriate
handler,
* 32-bit variables shall be used whenever dealing with the opaque data
length, since the firmware size can easily exceed the 16-bit range,
* Additional information, required for the FW block transfer to work
properly were added to the block context structure,
* The application shall only be notified of the actual data length, and
not the total block size (the total TLV size including header).
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
Remove the `sm_bootstrap_reg_done` function, which produced duplicated
logs. The bootstrap registration done event is already logged on state
transition. Additionally, in case bootstrap procedure took longer time,
the duplicated log message was printed on each `lwm2m_rd_client_service`
call (500 miliseconds by default).
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
The security object instance used should be cleared on engine reset,
otherwise we might end up using invalid object instance for the
registration (i. e. if the engine was restarted during the bootstrap
procedure due to socket errors, the registration attempt will use
bootstrap security object instead of finding a proper one).
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
During the bootstrap procedure, when Boostrap Finish was received, the
response message was not initialized properly, resulting in a socket
error (NULL pointer porovided) and the response not being sent.
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
`addrlen` parameter is updated on each `recvfrom` call, indicating the
actual address length returned. In case both, IPv4 and IPv6 are used on
different sockets (i. e. on regular LWM2M socket and FOTA socket), the
returned address length will differ.
In case `from_addr_len` is not reinitialized on each iteration, the
value stored in the `from_addr_len` variable will eventually indicate
the smaller IPv4 address size, therefore resulting in a failure in a
consecutive call on an IPv6 socket.
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
Although LwM2M engine uses cooperative threads, the internal `send()`
implementation might trigger context switch when it calls a kernel
function, therefore resulting in `send()` call being entered from both
the LwM2M thread and the retransmit work.
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
The context should only clear messages it owns, not all of them. Since
both context (LwM2M and FOTA) share common message pool, they might
interrupt their operation otherwise (i. e. cancel retransmissions).
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
The FOTA socket was not closed when download finished or an error
occured.
Additionally, fix the socket fd verification (it was assumed 0 is not a
valid fd which is not correct).
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
In case unsopported TLV type or malformed packet is received, the
`do_write_op_tlv` function will end up in an infinite loop. Prevent that
by returning an error code in case it does not recognize TLV type.
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
Allow to configure, how long before registration timeout should the
Registration Update be sent. The fixed 6 seconds used so far, might
not be enough in slower networks (like NB-IoT), resulting in frequent
re-registrations at LWM2M level.
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
This should be boolean according to specification. It makes difference
when JSON encoding is used.
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
So far socket errors reported by poll/recvfrom were ignored, which could
lead to an unexpected behavior when socket was left in an undefined
state.
Fix this, by requesting a re-registration in the LWM2M state machine,
which will close the faulty socket and open a new one. Note, that simply
closing and re-opening a socket in the lwm2m engine would not work,
since this would silently invalidate any open observations on the
lwm2m server side (due to port number change). Triggering a fresh
registration will notify the server to update its observations.
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
On OT network with poor coverage, very often request/observe packets
doesn't get it's ACK and consumes from pendings/replies/message stacks.
In such cases when LWM2M engine tries to recover by resetting its state,
it fails because of lack of free messages.
Signed-off-by: Kiril Petrov <retfie@gmail.com>
In networks with high latencies (like NB-IoT), it's quite common to
recieve duplicated response. It's not an error condition, a correct way
to handle it is to simply ignore the duplicate. Lower the log level for
this event, not to disturb users.
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
The retaransmission logic was not correct in the lwm2m_engine, and could
lead to faulty behavior in case multiple messages were pending for
retransmission in the queue.
1. Since there is a singe delayed work item for entire retransmission
queue, `coap_pending_next_to_expire` should be called before
scheduling next timeout, to identify which message is going to expire
next (and when). Currently, the engine always set next timeout, based
on timeout from the message being currently re-transmitted.
2. In case the message was re-transmitted several times, and is removed
from the retansmission queue due to a timeout, next retransmission
should be scheduled, in case there are other messages on the queue.
3. Verify the timeout of the earliest message to expire in the
retransmission handler. In case messages from the beginning of the
queue were removed, we might need to schedule the retransmission
again, instead of sending message rightaway.
4. `lwm2m_send_message` is not handling retransmissions anyway, so
there's no need to check send attempts. Instead, verify
retransmission work item is already pending, and update its timeout
if needed.
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
The LwM2M stack would previously ignore all OPAQUE resources when
reading them. This meant that it was impossible to read them, even if
there was a custom read callback.
Signed-off-by: Göran Weinholt <goran.weinholt@endian.se>
During registration, first thing LWM2M does is trying to close a socket
indicated by sock_fd stored in its context. In case it is not
initialized to some invalid value (-1 in this case), LWM2M may close an
ambigous socket.
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
Cell ID resource was not initialized properly in the Connectivity
Monitoring object, making it unusable from the application.
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
This change is to allow access to the firmware block context in order to
give the firmware update callback implementation an indication of when
to reset the flash context. Additionally, it allows for a validity check
between the total expected size downloaded and the actual size
downloaded. A simple implementation can check if the block context's
current downloaded blocks is equal to the expected block size in order
to determine if the flash context needs to be reset. This approach
seemed the simplest, and knowing the firmware block context can have
other purposes. This has been tested by accessing the block context
during the update in the block received callback and confirming that the
callback had information regarding the current downloaded bytes.
Fixes#16122
Signed-off-by: Kyle Sun <yaomon18@yahoo.com>
The function calculates the number of octets put, but does not return
it. Call sites check for non-zero values suggesting this is a bug.
See https://habr.com/en/company/pvs-studio/blog/495284/ fragment 12.
Signed-off-by: Peter Bigot <peter.bigot@nordicsemi.no>
Use the size of the target buffer as the maximum length when
formatting with snprintf.
See https://habr.com/en/company/pvs-studio/blog/495284/ fragment 3.
Signed-off-by: Peter Bigot <peter.bigot@nordicsemi.no>
According to LWM2M specification, when Queue Mode is used, the LWM2M
client should keep the reciever on for specified time after sending A
CoAP message. This commit adds a new LWM2M event,
`LWM2M_RD_CLIENT_EVENT_QUEUE_MODE_RX_OFF`, to facilitate the process by
notifying the application when it's safe to turn the receiver off.
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
Add Kconfig option to enable Queue Mode binding. With this option
enabled, the LWM2M client will register with `UQ` binding, instead of
`U`.
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
I think people might be reading differences into 'if' and 'depends on'
that aren't there, like maybe 'if' being needed to "hide" a symbol,
while 'depends on' just adds a dependency.
There are no differences between 'if' and 'depends on'. 'if' is just a
shorthand for 'depends on'. They work the same when it comes to creating
implicit menus too.
The way symbols get "hidden" is through their dependencies not being
satisfied ('if'/'depends on' get copied up as a dependency on the
prompt).
Since 'if' and 'depends on' are the same, an 'if' with just a single
symbol in it can be replaced with a 'depends on'. IMO, it's best to
avoid 'if' there as a style choice too, because it confuses people into
thinking there's deep Kconfig magic going on that requires 'if'.
Going for 'depends on' can also remove some nested 'if's, which
generates nicer symbol information and docs, because nested 'if's really
are so simple/dumb that they just add the dependencies from both 'if's
to all symbols within.
Replace a bunch of single-symbol 'if's with 'depends on' to despam the
Kconfig files a bit and make it clearer how things work. Also do some
other minor related dependency refactoring.
The replacement isn't complete. Will fix up the rest later. Splitting it
a bit to make it more manageable.
(Everything above is true for choices, menus, and comments as well.)
Detected by tweaking the Kconfiglib parsing code. It's impossible to
detect after parsing, because 'if' turns into 'depends on'.
Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
Based on work by Michael Scott.
Add a new Kconfig knob, CONFIG_LWM2M_IPSO_TIMESTAMP_EXTENSIONS. This
defaults to n. When enabled, various IPSO objects will by default have
the timestamp resource (5518) added to their representations. This can
be turned off on a per-object basis.
The idea of adding timestamp resources was originally suggested by
Hannes Tschofenig on this OMA page:
https://github.com/OpenMobileAlliance/OMA_LwM2M_for_Developers/issues/429
Signed-off-by: Michael Scott <mike@foundries.io>
Signed-off-by: Martí Bolívar <marti.bolivar@nordicsemi.no>
Use this short header style in all Kconfig files:
# <description>
# <copyright>
# <license>
...
Also change all <description>s from
# Kconfig[.extension] - Foo-related options
to just
# Foo-related options
It's clear enough that it's about Kconfig.
The <description> cleanup was done with this command, along with some
manual cleanup (big letter at the start, etc.)
git ls-files '*Kconfig*' | \
xargs sed -i -E '1 s/#\s*Kconfig[\w.-]*\s*-\s*/# /'
Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
Clean up space errors and use a consistent style throughout the Kconfig
files. This makes reading the Kconfig files more distraction-free, helps
with grepping, and encourages the same style getting copied around
everywhere (meaning another pass hopefully won't be needed).
Go for the most common style:
- Indent properties with a single tab, including for choices.
Properties on choices work exactly the same syntactically as
properties on symbols, so not sure how the no-indentation thing
happened.
- Indent help texts with a tab followed by two spaces
- Put a space between 'config' and the symbol name, not a tab. This
also helps when grepping for definitions.
- Do '# A comment' instead of '#A comment'
I tweaked Kconfiglib a bit to find most of the stuff.
Some help texts were reflowed to 79 columns with 'gq' in Vim as well,
though not all, because I was afraid I'd accidentally mess up
formatting.
Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
LWM2M_FIRMWARE_UPDATE_PULL_LOCAL_PORT is unused since commit 54c10c04e5
("net: lwm2m: use security data for connections").
Found with a script.
Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
Unused since commit d1cb39e7ce ("net: lwm2m: migrate LwM2M library to
BSD-sockets API").
Found with a script.
Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
With `CONFIG_NET_NATIVE`, offloaded drivers can specify capabilites with
`NET_IPV4/6` configs, so there is no longer need to handle socket
offloading separately.
Also, initialize hints structure with zeros, as according to man pages
unused fields should be set to 0:
`All the other fields in the structure pointed to by hints must contain
either 0 or a NULL pointer, as appropriate.`
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
Add new config option `LWM2M_DNS_SUPPORT` to the LWM2M library, instead
of relying on `DNS_RESOLVER` which is only compatible with native
network stack. This allows to use DNS with offloaded interfaces
seamlessly.
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
Cast a %lld argument to long long int. This is causing warnings on
recent GNU Arm Embedded toolchains, which fail the build with
-Werror=format=.
Signed-off-by: Marti Bolivar <marti.bolivar@nordicsemi.no>
Add new RD Client API of lwm2m_rd_client_stop() for this
Fix issues of de-register and event reporting in RD Client
Signed-off-by: Jun Qing Zou <jun.qing.zou@nordicsemi.no>
The LwM2M implementation for DNS resolving has checks which
configure hints based on whether IPv4 or IPv6 are enabled.
Neither of them need enabled if using NET_SOCKETS_OFFLOAD,
which then causes an error to be returned to due to
"hints.ai_family" not being set.
Also the offload API need to know when to free the allocated
"struct addrinfo" instead of calling free() generically,
thus let's use the freeaddrinfo() API for sockets which will
call into the offload API if needed.
Fixes: https://github.com/zephyrproject-rtos/zephyr/issues/18765
Signed-off-by: Jun Qing Zou <jun.qing.zou@nordicsemi.no>
When the firmware_pull mechansim sends the callback to notify the
sample of a new firmware block, the user supplied buffer can be
smaller than the CoAP BLOCK_SIZE setting. To handle this case,
we loop through the payload and fill the user supplied buffer with
smaller chunks.
Unfortunately, the last_block calculation is done outside this loop
which causes several callbacks (while in this loop) to have
last_block true. Let's fix this by adding a small check to make
sure we're at the end of the current payload block before notifying
the user of a last_block.
Fixes: https://github.com/zephyrproject-rtos/zephyr/issues/16158
Signed-off-by: Michael Scott <mike@foundries.io>
When val1 is 0, we need to handle a negative val2 value so that we
generate correct TLV value.
Example: val1 = 0, val2 = -500000 is equivalent to -0.5 decimal.
Currently we generate: 0.5 (losing the sign).
Fixes: https://github.com/zephyrproject-rtos/zephyr/issues/16154
Signed-off-by: Michael Scott <mike@foundries.io>
Current JSON formatting for float32/64 is broken in a similar way as
plain text. Let's use the newly fixed logic for plain text to
generate the float32/64 values in the JSON string.
Fixes: https://github.com/zephyrproject-rtos/zephyr/issues/16154
Signed-off-by: Michael Scott <mike@foundries.io>
We can use the plain text float32/64 formatter for JSON as well, so
let's expose the put_float32/64 functions.
Signed-off-by: Michael Scott <mike@foundries.io>
Formatting a float32/64 value for plain text is broken.
Example for 32bit: val1=0 and val2=500000 is equivalent to 0.5
Current formatter was using %d.%d (%lld.%lld for 64bit) so
exported value was 0.500000 (or 0.5)
To fix this, for val2 use a zero-padded formatter for the maximum
length of each bit length (6 for 32bit and 9 for 64bit), and then
remove the zero characters at the end of the string.
Notes re: handling of val1/val2 signs:
- eliminate potential negative sign when converting val2 to avoid:
a value like: 0.-5
- use negative val2 when val1 is 0 to fix small negative handling
such as -0.5
Fixes: https://github.com/zephyrproject-rtos/zephyr/issues/16154
Signed-off-by: Michael Scott <mike@foundries.io>
When the bootstrap support was added, it looks like I somehow missed
the handling block in the engine.
Let's add it now to fix boostrap support.
Fixes: https://github.com/zephyrproject-rtos/zephyr/issues/18080
Signed-off-by: Michael Scott <mike@foundries.io>
- LWM2M_SECURITY_INSTANCE_COUNT wasn't following the standard of
having the unconditional default in the last position
- LWM2M_SERVER_INSTANCE_COUNT needs another instance when
bootstrap is enabled.
Signed-off-by: Michael Scott <mike@foundries.io>
LwM2M boostrap support is enabled via the config option:
LWM2M_RD_CLIENT_SUPPORT_BOOTSTRAP. If enabled, this config sets
the default # of server and security instances. However, this is
not working correctly because LWM2M_RD_CLIENT_SUPPORT_BOOTSTRAP
is defined below it's uses in the Kconfig file.
Let's move the RD_CLIENT configs higher in the Kconfig to fix this
behavior.
Signed-off-by: Michael Scott <mike@foundries.io>
When checking for total IP address counts, don't check
CONFIG_NET_IF_MAX_IPV6_COUNT twice. This was a typo for
CONFIG_NET_IF_MAX_IPV4_COUNT.
This was reported by IRC user: retfie
Signed-off-by: Michael Scott <mike@foundries.io>
Several problems with memset usage in the LwM2M subsystem were
identified:
- Every single object that can have multiple instances is using
memset to initialize static resource data during init. This data
will already be set to 0 because it is static, so the memset
statements are unneeded.
- Instead of using memset during object init which is only called
one time during kernel startup, let's add a memset to the
object create function to ensure the resource data is cleared out.
It could have been used prior and then released via a DELETE op.
- the IPSO Timer object was setting a lot of data structure members
to 0 in the create function. Let's do 1 memset on the entire
structure and then only the non-zero values afterward.
Signed-off-by: Michael Scott <mike@foundries.io>
When presenting errors in lwm2m_engine_set() let's include the related
LwM2M path for easier debugging.
Signed-off-by: Michael Scott <mike@foundries.io>
This core LwM2M Object enables monitoring of parameters related to
network connectivity.
This is only the basic object structure. More work will be needed
to set the various resources based on connectivity.
Signed-off-by: Michael Scott <mike@foundries.io>
This Object is used to report the state of a momentary action push
button control and to count the number of times the control has
been operated since the last observation.
Signed-off-by: Michael Scott <mike@foundries.io>
LwM2M allows for multiple instance resources such the power source
resources in the device object. These types of resources have
always been very hard to work with, and frankly were poorly
implemented.
This led to other issues where it was very hard to have
non-sequential resource instances, and each resource of this type
needed special getter / setter methods such as:
lwm2m_device_add_pwrsrc()
lwm2m_device_set_pwrsrc_voltage_mv()
Going forward, as more LwM2M objects are implemented this just
doesn't scale well.
To fix this:
- split the resource instance data out from the resource data.
This includes the data pointer information and resource
instance id.
- add resource id and resource instance id to the event callback
functions so user's can see in more detail what resources and
resource instances are being handled.
- allow generic functions like lwm2m_engine_get_*() and
lwm2m_engine_set_*() to access resource instance data.
- adjust object resource initialization macros to map resource
instances to resources at the time of object instance
creation.
- fix up the lwm2m_client as a reflection of all of these changes.
Signed-off-by: Michael Scott <mike@foundries.io>
Due to work combining data into the lwm2m_message structure, we no
longer need to pass the lwm2m_engine_obj parameter between
formatters and most of the operation handlers.
So, let's remove it.
Signed-off-by: Michael Scott <mike@foundries.io>
The multi_max_count is no longer used and can be removed from the
obj_field structure if we change all of the OBJ_FIELD() macros to
use OBJ_FIELD_DATA() instead.
Technically, OBJ_FIELD() and OBJ_FIELD_DATA() are now the same, but
we're keeping them both for the time being. In the future, more
fields may be added to the obj_field structure and we can use the
OBJ_FIELD() macro again if that's the case.
Signed-off-by: Michael Scott <mike@foundries.io>
- Several of the functions use "path" as the parameter name for the
string-based LwM2M path. Let's clarify by using "pathstr".
- Recent updates to the LwM2M engine now support resource instances
when parsing the LwM2M path. Let's update descriptions accordingly.
Signed-off-by: Michael Scott <mike@foundries.io>
Per IPSO Light Control definition from the OMA LwM2M registry:
http://www.openmobilealliance.org/tech/profiles/lwm2m/3311.xml
There is an optional "Application Type" string resource (5750) in the
Light Control object. This was missed in the initial implementation.
NOTE: sample will assign reference if needed.
Signed-off-by: Michael Scott <mike@foundries.io>
We are pre-allocating a storage variable for the application type
resource in the IPSO Timer object. This is an optional resource
which won't always be set by samples.
Let's leave out the pre-allocated variable and let the sample set
this reference if needed (it's optional).
Signed-off-by: Michael Scott <mike@foundries.io>
Server records contain the default PMIN and PMAX settings for how
often we can send observe notifications. We are currently using
arbitrary defaults which cannot be changed when compiled or
during runtime.
Let's add Kconfig settings for the default settings to use and
also lookup the current values in the active server record when
an observe is added.
The actual PMIN/PMAX values can still be set via WRITE_ATTRIBUTE
operation.
Signed-off-by: Michael Scott <mike@foundries.io>
Currently the retransmit_work is not cancelled when closing a context,
making it operate on an invalid context.
LwM2M RD client also closes the context and initializes it again when
registration with the server fails, overwriting the active timeout and
breaking the timeout dlist.
Signed-off-by: Pieterjan Camerlynck <pieterjan.camerlynck@gmail.com>
Current implementation of LwM2M engine doesn't allow users a way
of overriding TLS credential load with custom function. This
would be needed by an offloaded TLS stack where we don't want
to use standard Zephyr functions.
Let's add a load_credential function pointer to the LwM2M client
context which will be called when it's available.
Fixes: https://github.com/zephyrproject-rtos/zephyr/issues/17408
Signed-off-by: Michael Scott <mike@foundries.io>
When performing OTA using the LwM2M subsys, several logging errors
regarding log_strdup were noted. Let's fix these.
Signed-off-by: Michael Scott <mike@foundries.io>
If a sample wants to use the Zephyr implementation of mbedtls, it
enables CONFIG_MBEDTLS and sets any needed Zephyr-specific mbedtls
options.
Currently, the LwM2M subsystem selects MBEDTLS automatically when
LWM2M_DTLS_SUPPORT is enabled. Let's remove this and let the
LwM2M client sample enable mbedtls and it's options.
This mimics the behavior of several other network-related samples
and removes conflicts when selecting alternate implementations of
MBEDTLS.
Fixes: https://github.com/zephyrproject-rtos/zephyr/issues/17399
Signed-off-by: Michael Scott <mike@foundries.io>
CONFIG_NET_IPV* checks are not needed in lwm2m_parse_peerinfo().
The functions used are always available. Worse, having these checks
forces the need to enable CONFIG_NET_IPV4 or IPV6 when it's not really
needed (LwM2M could be using an offloaded IP stack).
Fixes: https://github.com/zephyrproject-rtos/zephyr/issues/17401
Signed-off-by: Michael Scott <mike@foundries.io>
CONFIG_NET_IPV* checks are not needed in lwm2m_sprint_ip_addr(). The
functions used are always available. Worse, having these checks
forces the need to enable CONFIG_NET_IPV4 or IPV6 when it's not really
needed (LwM2M could be using an offloaded IP stack).
NOTE: Also fixes an issue where a NULL is returned when the IP address
is unknown. This usually ends up with a crash/abort in the logging
code.
Fixes: https://github.com/zephyrproject-rtos/zephyr/issues/17401
Signed-off-by: Michael Scott <mike@foundries.io>
This fixes the issue where observations are automatically reported using
the minimum period instead of the maximum. This causes notifications to
be sent more frequently than configured when the resource does not
change.
Signed-off-by: Pieterjan Camerlynck <pieterjan.camerlynck@gmail.com>
move misc/util.h to sys/util.h and
create a shim for backward-compatibility.
No functional changes to the headers.
A warning in the shim can be controlled with CONFIG_COMPAT_INCLUDES.
Related to #16539
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
move misc/printk.h to sys/printk.h and
create a shim for backward-compatibility.
No functional changes to the headers.
A warning in the shim can be controlled with CONFIG_COMPAT_INCLUDES.
Related to #16539
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
move misc/byteorder.h to sys/byteorder.h and
create a shim for backward-compatibility.
No functional changes to the headers.
A warning in the shim can be controlled with CONFIG_COMPAT_INCLUDES.
Related to #16539
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
Found a few annoying typos and figured I better run script and
fix anything it can find, here are the results...
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
Due to commit a211afb0 ("logging: Add option to detect missed
transient string duplication"), the logs for LwM2M subsystem
is now spamming missing log_strdup() calls.
Let's add log_strdup() where needed.
Signed-off-by: Michael Scott <mike@foundries.io>
Libraries that use mbedTLS have been invoking
zephyr_link_interface(mbedTLS). It is not clear what the intent of
this code has been, but it is redundant with the mbedTLS build
scripts, so it can be safely removed.
In addition to being redundant, it causes problems as it introduces an
ordering dependency, with this code mbedTLS must be declared before
users of mbedTLS are declared. Since this code is redundant, this
ordering dependency is also unnecessary.
This code is believed to have been added early on by accident and
copied through cargo-cult programming since.
Signed-off-by: Sebastian Bøe <sebastian.boe@nordicsemi.no>
This fixes an issue where if timestamp == service_due_timestamp,
we don't call the periodic service. Then the following call to
engine_next_service_timeout_ms() returns 0 because the service
is still due and lwm2m_engine_service() is called again.
This process repeats several times until the value of
k_uptime_get() changes and then the work is finally handled.
Previously, the resolution of k_uptime_get() was in ms. A recent
change to this API defaults Zephyr so that the resolution is
set via CONFIG_SYS_CLOCK_TICKS_PER_SEC (default 100).
This means the value of k_uptime_get() only changes every 10ms.
Reported-by: Github User pieterjanc
Signed-off-by: Michael Scott <mike@foundries.io>
"It's a Trap!" -- Admiral Ackbar
When moving to the BSD-socket APIs, the original thread running LwM2M
periodic services such as observes and lifetime updates, was replaced
with a re-occuring workqueue job. To save the overhead of creating a
new thread, I used the system workqueue for these jobs.
This was a mistake. If these jobs hit a semaphore or wait for some
reason, it cannot be prempted due to the priority of the system work
queue.
Let's instead add this service handling to the thread that we already
use for polling sockets. This also removes a configuration issue where
the system workqueue stack size needed to be increased. This can now
be adjusted via the LWM2M_ENGINE_STACK_SIZE knob.
Directly fixes semaphore usage in the socket-based DNS code.
This was introduced as a bugfix for non-responsive DNS server hanging
the Zephyr device forever. However, this probably fixes randomly
seeming hangs on the device.
Signed-off-by: Michael Scott <mike@foundries.io>
Update the files which contain no license information with the
'Apache-2.0' SPDX license identifier. Many source files in the tree are
missing licensing information, which makes it harder for compliance
tools to determine the correct license.
By default all files without license information are under the default
license of Zephyr, which is Apache version 2.
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
Normally, this bug wasn't apparent as the value is type-casted
to a float32/64 type. However, once we start persisting these
values they need the correct length.
Signed-off-by: Michael Scott <mike@foundries.io>
Let's avoid future compile issues with this macro when passing
in a type-casted value that isn't surrounded by parenthesis.
Signed-off-by: Michael Scott <mike@foundries.io>
Occasionally we see a stack crash in LwM2M. This may have been
due to the swap from net_app APIs to socket-based APIs.
Let's raise the default stack by 1k.
Signed-off-by: Michael Scott <mike@foundries.io>
When a context is closed to a server, we should clean up any
existing observes along with it. Otherwise these will try to fire
afterward.
Signed-off-by: Michael Scott <mike@foundries.io>
We are already in sm_do_registration(), there's no need to check
!sm_is_registered(). Either we are performing a full registration
or a registration update. In both cases, sm_send_registration()
is called.
Signed-off-by: Michael Scott <mike@foundries.io>
If an error is received during registration update, we need to reset
the status so that a full registration is performed. This was
incorrectly being set to ENGINE_REGISTRATION_SENT.
The correct status should be: ENGINE_DO_REGISTRATION
Signed-off-by: Michael Scott <mike@foundries.io>
send() returns -1 upon error and sets errno appropriately. Let's
not bother saving the return code and instead share errno back
to the user.
Signed-off-by: Michael Scott <mike@foundries.io>
subsys/net/lib/lwm2m/Kconfig.ipso is 'source'd within an 'if LWM2M', in
subsys/net/lib/lwm2m/Kconfig, so the 'depends on LWM2M' is redundant.
The 'depends on NET_IPV4' and 'depends on NET_L2_OPENTHREAD' are within
corresponding 'if's in the same file.
'if FOO' is just shorthand for adding 'depends on FOO' to each item
within the 'if'. Dependencies on menus work similarly. There are no
"conditional includes" in Kconfig, so 'if FOO' has no special meaning
around a source. Conditional includes wouldn't be possible, because an
if condition could include (directly or indirectly) forward references
to symbols not defined yet.
Tip: When adding a symbol, check its dependencies in the menuconfig
('ninja menuconfig', then / to jump to the symbol). The menuconfig also
shows how the file with the symbol got included, so if you see
duplicated dependencies, it's easy to hunt down where they come from.
Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
Found via Coverity CID 191001: Control flow issues (NO_EFFECT)
This less-than-zero comparison of an unsigned value is never true:
"put_char(out, '}') < 0U".
Let's fix this check to be less than 1 instead as it should have
been originally.
Signed-off-by: Michael Scott <mike@foundries.io>
Once the fraction value has been assigned a value, we can't move
the exponent any more.
Fixes erroneous values the binary32/64 formats.
Signed-off-by: Michael Scott <mike@foundries.io>
Errno value is only significant when `recvfrom` function indicated an
error (by returning -1). We should not depend on it's value if no error
is notified.
As the return value of `recvfrom` is already checked, misused errno
verification can simply be removed.
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
There are issues using lowercase min and max macros when compiling a C++
application with a third-party toolchain such as GNU ARM Embedded when
using some STL headers i.e. <chrono>.
This is because there are actual C++ functions called min and max
defined in some of the STL headers and these macros interfere with them.
By changing the macros to UPPERCASE, which is consistent with almost all
other pre-processor macros this naming conflict is avoided.
All files that use these macros have been updated.
Signed-off-by: Carlos Stuart <carlosstuart1970@gmail.com>
Per Coverity report, oma_tlv_put() does pointer arithmetic accessing
the data as an array of u8_t. In put_bool() we get a singleton
pointer from the evaluation of: "value != 0 ? 1 : 0" which is
passed to put_s8() which in turn passes it to oma_tlv_put().
To avoid misinterpretation, let's create a temporary s8_t variable
to pass into oma_tlv_put instead.
Fixes: https://github.com/zephyrproject-rtos/zephyr/issues/12312
Signed-off-by: Michael Scott <mike@foundries.io>
Zero is a special value in the binary32/64 format. It has all zero
bits (sign=0, exponent=0 and fraction=0).
Handle this special case explicitly instead of trying to encode
in binary format which results in an incorrect value of 0.5.
Signed-off-by: Michael Scott <mike@foundries.io>
Initial implementation of IPSO Timer object #3340
Based on: http://www.openmobilealliance.org/tech/profiles/lwm2m/3340.xml
"This IPSO object is used to time events and actions, using patterns
common to industrial timers. A POST to the trigger resource or On/Off
input state change starts the timing operation, and the timer
remaining time shows zero when the operation is complete. The
patterns supported are One-Shot (mode 1), On-Time or Interval
(mode 2), Time delay on pick-up or TDPU (tmode 3), and Time Delay
on Drop-Out or TDDO (mode 4). Mode 0 disables the timer, so the output
follows the input with no delay. A counter is provided to count
occurrences of the timer output changing from 0 to 1. Writing a value
of zero resets the counter. The Digital Input State resource reports
the state of the timer output."
NOTE: Only One-Shot Mode (mode 1) is implemented in this patch.
Signed-off-by: Michael Scott <mike@foundries.io>
During the initial work on LwM2M, the float32/64 code was
basically stubbed out. Float32 sent only whole values and
float64 was completely broken.
Let's clean up the OMA TLV formatting code by moving the float
processing code into a separate file: lwm2m_util.c.
Then using public definitions for binary32 and binary64, let's
fix the processing code to correctly fill the float32_value_t
and float64_value_t types.
Signed-off-by: Michael Scott <mike@foundries.io>
A few cases were missed where we weren't cleaning up the existing
connection correctly. This was easily missed because we try and
clean up the connection everywhere.
Instead, let's clean up any existing connection prior to starting
a new one in the do_bootstrap_reg() and do_registration()
functions.
Signed-off-by: Michael Scott <mike@foundries.io>
- Fix enum naming throughout
- Correct next_instance logic
- Move to registration server if no bootstrap server is found
- Fixes to logging
Signed-off-by: Michael Scott <mike@foundries.io>
As we are removing net_app and net_pkt based libraries and
applications, CoAP legacy based libraries and apps are moved
to socket based implementations. So removing legacy CoAP.
Signed-off-by: Ravi kumar Veeramally <ravikumar.veeramally@linux.intel.com>
Previously, the net_app layer handled DNS support as a part of
network initialization. With the move to BSD-socket APIs,
we need to add support for DNS to the LwM2M library.
Signed-off-by: Michael Scott <mike@foundries.io>
This commit resets the firmware status to IDLE after a bad
download attempt. Previously, the firmware object would stay
in an odd state and any further attempts to download firmware
would return an error.
Signed-off-by: Michael Scott <mike@foundries.io>
We can save some resources by removing the periodic service thread
and replacing it by queuing the services to the work queue.
Before (reel_board using BT + DTLS)
Memory region Used Size Region Size %age Used
FLASH: 289464 B 1 MB 27.61%
SRAM: 75620 B 256 KB 28.85%
IDT_LIST: 136 B 2 KB 6.64%
After
Memory region Used Size Region Size %age Used
FLASH: 289576 B 1 MB 27.62%
SRAM: 74596 B 256 KB 28.46%
IDT_LIST: 136 B 2 KB 6.64%
Signed-off-by: Michael Scott <mike@foundries.io>
Now that the security data can be loaded into and used from the
security / server objects, we can add support for LwM2M bootstrap.
This is a mode where initially a connection can be made to a server
which can update several LwM2M (including security and server
data) and then trigger a "bootstrap complete". Once this happens
the client will start it's connection process over but now with
the new information.
Signed-off-by: Michael Scott <mike@foundries.io>
In order to support bootstrap mode, we need to store server data
in the security / server objects. Once the connection to the
bootstrap server is made, it will clear these objects and add
new server connection data.
Signed-off-by: Michael Scott <mike@foundries.io>
For bootstrap support, we need to store connection credentials
in the security object. This way the client can start a connection
at index 0 and after bootstrapping, move to the next connection.
Let's add the needed fields and a config item to set the key length.
Signed-off-by: Michael Scott <mike@foundries.io>
Update the parsing functions for JSON used by the JSON data
formatter and enable it in the LwM2M engine.
Signed-off-by: Michael Scott <mike@foundries.io>
The JSON formatter is currently not enabled for incoming WRITE
operations. To update the code in the formatter and not litter
the input context with extra data, let's allow formatters to
store their own user data.
Signed-off-by: Michael Scott <mike@foundries.io>
net_app contexts save the remote address and we use this during
observe notifications and pending handling. If we move to another
network layer such as sockets, then the remote address becomes
harder to reference. Let's save it as a part of the client
context.
Signed-off-by: Michael Scott <mike@foundries.io>
As part of the migration from net_app APIs to socket APIs, let's
stop referencing the net_pkt fragments throughout the LwM2M library.
Establish a msg_data flat buffer inside lwm2m_message and use that
instead.
NOTE: As a part of this change we remove the COAP_NET_PKT setting.
The COAP library reverts to COAP_SOCK behavior.
This doesn't mean we use sockets in LwM2M (yet), it only means we
use the socket-compatible COAP library which parses flat buffers
instead of net_pkt fragments.
Signed-off-by: Michael Scott <mike@foundries.io>
Currently, this will select the needed configs for LwM2M and net_pkt.
During the migration to socket APIs, the net_pkt selections will change
to socket-based selects.
Signed-off-by: Michael Scott <mike@foundries.io>
The relationship between lwm2m_engine_context and lwm2m_message
has always been a tenuous one. Let's merge the 2 structures
into lwm2m_message and remove all of the extra stack variables.
This change increases SRAM usage slightly due to the
addition of the context structures to the multiple lwm2m_messages.
However, the way lwm2m_engine_context was being used off the stack
was probably creating hard to debug issues in the longterm.
Also, having all of the structures in 1 place makes sharing them
much easier later.
Signed-off-by: Michael Scott <mike@foundries.io>
Reported by Github user himanshujha199640 using coccinelle:
subsys/net/lib/lwm2m/lwm2m_obj_device.c:172:5-16:
WARNING: Unsigned expression compared with zero.
Fixes: https://github.com/zephyrproject-rtos/zephyr/issues/11135
Signed-off-by: Michael Scott <mike@foundries.io>
CONFIG_NET_CONTEXT_NET_PKT_POOL is used by Zephyr's TCP stack as
a way of keeping the original packet data when compression and
other l2 specific actions make the data unusable for retries.
LwM2M uses UDP and this option was never used.
Signed-off-by: Michael Scott <mike@foundries.io>
Remove an unnecessary local variable to store the
return value, instead return directly thereby saving
few bits of memory.
Found using Coccinelle.
Signed-off-by: Himanshu Jha <himanshujha199640@gmail.com>
Remove an unnecessary local variable to store the
return value, instead return directly thereby saving
few bits of memory.
Found using Coccinelle.
Signed-off-by: Himanshu Jha <himanshujha199640@gmail.com>
Two separate folders and Kconfig options causing confusion on
CoAP and CoAP_SOCK implementations. This patch simplifies it.
Current CoAP Kconfig option moved to COAP_NET_PKT.
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
When resending data, we need to always check pending status first.
If the pending check returns an "expired" status, avoid sending the
data to L2 network driver entirely.
This change fixes a use after free issue, where the L2 network driver
was still handling a packet that was expired out from under it when
the pending status was checked.
Signed-off-by: Michael Scott <mike@foundries.io>
During firmware transmit timeout, we rely on the pending packet data to
reconstitute the token and token length. At this point the pending
structure may be cleared out due to multiple retries. To avoid getting
a zero token, let's use the token data from the original msg structure
instead.
Signed-off-by: Michael Scott <mike@foundries.io>
We are using msg->cpkt.pkt as the net_pkt pointer in the call to
net_app_send_pkt(). Let's keep the code clean and not expose
ourselves to "out of order" issues, by also using msg->cpkt.pkt
in the error handling unref call.
Signed-off-by: Michael Scott <mike@foundries.io>
During the retransmit cycle we take ref on the outgoing packet,
only to immediately unref it. Originally, this was to make sure
the net_context handling didn't get rid of the packet when
sendto() is called. But after checking, the ref counter is never
in danger of going to 0 at this point in the code, so the
added ref handling is useless.
Signed-off-by: Michael Scott <mike@foundries.io>
Add some extra space to the color resource buffer, to allow more
exotic and application-specific color spaces.
Signed-off-by: Marti Bolivar <marti@foundries.io>
When DBG level for CONFIG_LWM2M_LOG_LEVEL is disabled, a compiler
warning is generated:
In file included from include/logging/log.h:11:0,
from subsys/net/lib/lwm2m/lwm2m_engine.c:28:
subsys/net/lib/lwm2m/lwm2m_engine.c: In function ‘engine_add_observer’:
subsys/net/lib/lwm2m/lwm2m_engine.c:558:3: warning: implicit
declaration of function ‘sprint_token’
[-Wimplicit-function-declaration]
sprint_token(token, tkl), lwm2m_sprint_ip_addr(addr));
^
Let's remove the #if guards around sprint_token() and let
the Linker remove it when not needed.
Signed-off-by: Michael Scott <mike@foundries.io>
Adding spaces around "=" when definining Kconfig template so
that is more consistent with overall style of these template
variables.
Signed-off-by: Jukka Rissanen <jukka.rissanen@linux.intel.com>
The return of memset is never checked. This patch explicitly ignore
the return to avoid MISRA-C violations.
The only directory excluded directory was ext/* since it contains
only imported code.
Signed-off-by: Flavio Ceolin <flavio.ceolin@intel.com>
For ease of maintenance, let's swap the reader/writer initialization
syntax to:
.put_begin = put_begin,
.put_end = put_end,
...
This way we only assign used fields and adding new ones later is
less error prone.
Signed-off-by: Michael Scott <mike@foundries.io>
We set "insert" to true when the value is already in the buffer, but
we need to insert a TLV to denote things like RESOURCE_INSTANCE or
OBJECT_INSTANCE. In this case, let's not re-add the value.
Signed-off-by: Michael Scott <mike@foundries.io>
Let's implement put_begin/end_oi functions in the TLV formatter
so to mark the boundry of an object instance when more than 1
object instance is returned.
Fixes https://github.com/zephyrproject-rtos/zephyr/issues/9470
Signed-off-by: Michael Scott <mike@foundries.io>
In order to re-use the put_begin_ri / put_end_ri logic, let's create
generic functions for them: put_begin_tlv and put_end_tlv
Signed-off-by: Michael Scott <mike@foundries.io>
Currently, we only save the resource id of the incoming path setting.
In the future, we will need to change other values in order to process
multi-instance READ operations.
Let's save and restore the entire path only at the beginning and end
of processing.
Signed-off-by: Michael Scott <mike@foundries.io>
Data formatters may need to process data at the beginning and end of
each object instance and/or resource. Currently, they can only add
processing at the beginning and end of resource instances.
Let's establish put_begin/end_oi (object instance) and put_begin/end_r
(resource) API functions that data formatters can use for this purpose.
Signed-off-by: Michael Scott <mike@foundries.io>
Optimize the resource processing loop to avoid extra
assignments before checking if we need to process the
actual resource.
Signed-off-by: Michael Scott <mike@foundries.io>
When reading multiple instances, the base name value should not
include an object instance id. The object instance id is added
to the individual resource name values.
Accomplish this by saving the original path level and adjusting
the (base) name where needed.
Signed-off-by: Michael Scott <mike@foundries.io>
The put_begin / put_end calls are to be used at the very beginning
and end of processing a READ op. Let's correct that logic.
Signed-off-by: Michael Scott <mike@foundries.io>
Now that formatters use their own private data to hold state,
let's remove the old member variables from lwm2m_output_context
which are now unused.
Signed-off-by: Michael Scott <mike@foundries.io>
Data formatters have various private state variables which are
currently located in the output context structure. Let's add
a place where data formatters can store a pointer to their
private data so that as we add more formatters the output
context doesn't get cluttered up.
Signed-off-by: Michael Scott <mike@foundries.io>
The plain-text format only supports READ op for a specific resource.
In all other cases return NOT_ALLOWED.
Signed-off-by: Michael Scott <mike@foundries.io>
Data formatters are becoming too complex for a simple do_read_op()
function to handle all in one place. Also, more data formatters are
going to be added for LwM2M v1.1 support in the future.
In order for data formatters to perform internal setup or deny
invalid requests (specific to the formatter's logic), let's
establish do_read_op_* functions in each formatter.
Once the internal processing is done, they can call back into the
more generic lwm2m_perform_read_op function.
Signed-off-by: Michael Scott <mike@foundries.io>
Let's correct the starting logic in do_read_op() to not assume
a default value of 0 will be present for the first object, when
reading multiple objects.
Signed-off-by: Michael Scott <mike@foundries.io>
The object instance list isn't sorted by object instance id. Let's
simplify this and fix the logic in lwm2m_next_engine_obj_inst() to make
sure that we always get the NEXT object instance by value of
obj_inst_id, not just the next object instance in the list.
NOTE: This change removes the "last" object instance pointer from the
parameters of lwm2m_next_engine_obj_inst(). Some of the logic to return
a NULL value for the end of the list has to be moved back into
do_read_op().
Signed-off-by: Michael Scott <mike@foundries.io>
Remove over-complicated match_type logic in do_read_op(). Replace
MATCH_* checks with actual path->level values.
Signed-off-by: Michael Scott <mike@foundries.io>
When processing an observe request we fail to check whether a
resource has the read permission set. Let's check and if it
doesn't return -EPERM.
NOTE: Also do diligence and return -ENOENT when an object field
cannot be found while looking for the permission.
Fixes https://github.com/zephyrproject-rtos/zephyr/issues/8286
Signed-off-by: Michael Scott <mike@foundries.io>
Due to a change in the company name, the LwM2M copyrights need
to be changed from "Open Source Foundries Limited" ->
"Foundries.io".
Signed-off-by: Michael Scott <mike@foundries.io>
Up until now, Zephyr has patched Kconfig to use the last 'default' with
a satisfied condition, instead of the first one. I'm not sure why the
patch was added (it predates Kconfiglib), but I suspect it's related to
Kconfig.defconfig files.
There are at least three problems with the patch:
1. It's inconsistent with how Kconfig works in other projects, which
might confuse newcomers.
2. Due to oversights, earlier 'range' properties are still preferred,
as well as earlier 'default' properties on choices.
In addition to being inconsistent, this makes it impossible to
override 'range' properties and choice 'default' properties if the
base definition of the symbol/choice already has 'range'/'default'
properties.
I've seen errors caused by the inconsistency, and I suspect there
are more.
3. A fork of Kconfiglib that adds the patch needs to be maintained.
Get rid of the patch and go back to standard Kconfig behavior, as
follows:
1. Include the Kconfig.defconfig files first instead of last in
Kconfig.zephyr.
2. Include boards/Kconfig and arch/<arch>/Kconfig first instead of
last in arch/Kconfig.
3. Include arch/<arch>/soc/*/Kconfig first instead of last in
arch/<arch>/Kconfig.
4. Swap a few other 'source's to preserve behavior for some scattered
symbols with multiple definitions.
Swap 'source's in some no-op cases too, where it might match the
intent.
5. Reverse the defaults on symbol definitions that have more than one
default.
Skip defaults that are mutually exclusive, e.g. where each default
has an 'if <some board>' condition. They are already safe.
6. Remove the prefer-later-defaults patch from Kconfiglib.
Testing was done with a Python script that lists all Kconfig
symbols/choices with multiple defaults, along with a whitelist of fixed
symbols. The script also verifies that there are no "unreachable"
defaults hidden by defaults without conditions
As an additional test, zephyr/.config was generated before and after the
change for several samples and checked to be identical (after sorting).
This commit includes some default-related cleanups as well:
- Simplify some symbol definitions, e.g. where a default has 'if FOO'
when the symbol already has 'depends on FOO'.
- Remove some redundant 'default ""' for string symbols. This is the
implicit default.
Piggyback fixes for swapped ranges on BT_L2CAP_RX_MTU and
BT_L2CAP_TX_MTU (caused by confusing inconsistency).
Piggyback some fixes for style nits too, e.g. unindented help texts.
Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
The LwM2M engine will cleanup the net_app_ctx if there are
errors during initialization. The clean up calls here in
RD client are duplicated.
Signed-off-by: Michael Scott <mike@foundries.io>
During transfer of object data via OMA TLV format, we can
encounter resources which are optional or not handled in base
LwM2M engine. When these resources cannot be handled let's
read past them and continue on.
Signed-off-by: Michael Scott <mike@foundries.io>
Don't use hard-coded value of 4 for passing the # of options to
coap_find_options() in handle_request(). This can easily get
out of sync.
Signed-off-by: Michael Scott <mike@foundries.io>
LwM2M engine now supports optional resources that may need to be
setup or torn down in user-based code during object instance
creation / deletion.
Let's provide callbacks that can be used for this purpose.
Signed-off-by: Michael Scott <mike@foundries.io>
Let's rename lwm2m_engine_exec_cb_t to lwm2m_engine_user_cb_t so that
future user-code callbacks can make use of the same definition.
Signed-off-by: Michael Scott <mike@foundries.io>
Bool symbols implicitly default to 'n'.
A 'default n' can make sense e.g. in a Kconfig.defconfig file, if you
want to override a 'default y' on the base definition of the symbol. It
isn't used like that on any of these symbols though.
Remove some 'default ""' properties on string symbols too.
Also make definitions more consistent by converting some
config FOO
<type>
prompt "foo"
definitions to a shorter form:
config FOO
<type> "foo"
This shorthand works for int/hex/string symbols too, not just for bool
symbols.
Signed-off-by: Ulf Magnusson <Ulf.Magnusson@nordicsemi.no>
If we use newlib the isdigit (and other similar functions) return an
error as char can possibly be viewed as signed:
usr/include/ctype.h:57:54: error: array subscript has type ‘char’ [-Werror=char-subscripts]
#define __ctype_lookup(__c) ((__ctype_ptr__+sizeof(""[__c]))[(int)(__c)])
Explicity cast to unsigned char so we deal with both this warning and
possible warning when -Wpointer-sign is enabled.
Signed-off-by: Kumar Gala <kumar.gala@linaro.org>
When the priority of the LwM2M engine was lowered, it causes an
occasional registration update to fall outside of the registration
lifetime. This shows up as the following error:
Failed with code 4.4. Retrying registration
Let's try and retry a bit earlier to account for the priority
change.
Signed-off-by: Michael Scott <michael@opensourcefoundries.com>
The ARRAY_SIZE() utility macro will actually test the parameter types,
and ensure that it is only called with arrays, and not arrays decayed
to pointers.
Changes were performed with a simple Coccinelle script.
Signed-off-by: Leandro Pereira <leandro.pereira@intel.com>
A typo in update_attrs() was setting every observer to a PMIN of 0.
This meant we could send observer data as often as the process was
called. This is out of spec as the default minimum is 10 seconds.
Signed-off-by: Michael Scott <michael@opensourcefoundries.com>
The LwM2M engine thread is used for various periodic triggers.
None of these are in a critical path that requires super sensitive
timing and the current K_PRIO_COOP(7) setting was causing the
Bluetooth RX thread to have to wait too long for certain actions
to complete.
Let's lower the priority to -1 (effectively) to eliminate these
conflicts.
Signed-off-by: Michael Scott <michael@opensourcefoundries.com>
During normal use, a CoAP packet can be resent due to network congestion
and other causes. During block transfer the LwM2M client checks to make
sure the block received is the one we expect and if not generates a
"duplicate" warning. When this happened, we were releasing the reply
handler and when the correct block was received the client would
generate a "No handler" error.
To avoid releasing the reply handler too early, let's set the coap_reply
"user_data" field to an error condition (1). Then, once the reply
processing is complete we can check the user_data field to be sure that
it's ok to release the reply handler.
Signed-off-by: Michael Scott <michael@opensourcefoundries.com>
The next error check is much more suitable to handle the error due to
the error message which lets the user know that something went wrong.
Fixes#7661.
Signed-off-by: Daniel Egger <daniel@eggers-club.de>
When designing the registration client for LwM2M, I understood
that the LwM2M Technical Specification allows for a multi-server
connection setup where the client makes several connections
to various LwM2M servers and allows each of them to manage
various aspects of the LwM2M client based on Access Controls.
However, the way I implemented it was not well thought out and
as we look forward to adding Bootstrap support, it needs a
do over.
Let's remove all of the code dedicated to handling multiple LwM2M
client connections. This will simplify and reduce the code size
of the registration client considerably.
Later, once Bootstrap support has been added, we can implement
multi-server connections in a cleaner manner.
Signed-off-by: Michael Scott <michael@opensourcefoundries.com>
This allows a user to customize the port used for downloading
firmware via the pull method of the LwM2M client. It's default
value of 0 will select a random port during initialization.
NOTE: If set, this value should not be the same port as the
LWM2M_LOCAL_PORT setting.
Signed-off-by: Michael Scott <michael@opensourcefoundries.com>
Due to a bug where LWM2M_LOCAL_PORT was not being honored, all
outgoing traffic from the LwM2M client was coming from a random
port determined during initialization.
Now that this bug bas been fixed, let's default the client to the
behavior that most users are expecting, and let new users customize
the outgoing port if needed (which should be rarely).
Signed-off-by: Michael Scott <michael@opensourcefoundries.com>
Currently, CONFIG_LWM2M_LOCAL_PORT is never used when setting up
the LwM2M client. Let's set the port of the local address using
CONFIG_LWM2M_LOCAL_PORT, so that the client can bind to it.
NOTE: A setting of 0 will use a random port.
Signed-off-by: Michael Scott <michael@opensourcefoundries.com>
Using IPSO Smart Object Guideline: "Smart Objects Starter Pack 1.0"
dated May 27, 2017, let's mark the OPTIONAL resources for an
IPSO Temperature object (Section 10. "IPSO Object: Temperature").
Signed-off-by: Michael Scott <michael@opensourcefoundries.com>
Using IPSO Smart Object Guideline: "Smart Objects Starter Pack 1.0"
dated May 27, 2017, let's mark the OPTIONAL resources for an
IPSO Light Control object (Section 16. "IPSO Object: Light Control")
Signed-off-by: Michael Scott <michael@opensourcefoundries.com>
Using OMA Technical Specification LwM2M Enabler 1.0.2 dated
Feb. 9, 2018, let's mark the OPTIONAL resources for an LwM2M
Firmware Update object (Section E.6 "LwM2M Object: Firmware
Update")
Signed-off-by: Michael Scott <michael@opensourcefoundries.com>
Using OMA Technical Specification LwM2M Enabler 1.0.2 dated
Feb. 9, 2018, let's mark the OPTIONAL resources for an LwM2M
Device object (Section E.4 "LwM2M Object: Device")
As a result, the Device object no longer configures the default
buffers for data storage of several optional resources.
The LwM2M client sample is also changed to to setup these read-only
buffers instead.
Signed-off-by: Michael Scott <michael@opensourcefoundries.com>
Using OMA Technical Specification LwM2M Enabler 1.0.2 dated
Feb. 9, 2018, let's mark the OPTIONAL resources for an LwM2M
Server object (Section E.1 "LwM2M Object: Server")
Signed-off-by: Michael Scott <michael@opensourcefoundries.com>
Using OMA Technical Specification LwM2M Enabler 1.0.2 dated
Feb. 9, 2018, let's mark the OPTIONAL resources for an LwM2M
Security object (Section E.1 "LwM2M Object: Security")
Signed-off-by: Michael Scott <michael@opensourcefoundries.com>
This patch introduces several changes to support OPTIONAL resources.
The primary indicator for this behavior is to assign FLAG_OPTIONAL
to the object field's permission flags.
These resources are not setup by the LwM2M object code. They are
left up to the user-based code for initialization via the following
functions:
lwm2m_engine_set_res_data()
lwm2m_engine_get_res_data()
When assigning const-based data as a data buffer, user-based code can
also specify the following data flag: LWM2M_RES_DATA_FLAG_RO
The FLAG_OPTIONAL flag also affects the LwM2M engine in the following
ways:
- CREATE operations won't generate an error if optional resources are
not included.
- Object instance READ operations won't complain about missing
optional resources.
- In the future, BOOTSTRAP operations can have different handling
based on optional resources.
Signed-off-by: Michael Scott <michael@opensourcefoundries.com>
In the future, we will have optional resources that may or may
not be assigned a buffer for data storage. When these resources
are queried we need to be able to return an error code if the
buffer isn't set.
Signed-off-by: Michael Scott <michael@opensourcefoundries.com>
In an effort to reduce the footprint of the LwM2M client, let's
lower the default # of observes handled by the client from 20 to
10.
This saves ~640 bytes of SRAM.
Signed-off-by: Michael Scott <michael@opensourcefoundries.com>
Remove "used" member from observe_node structure and replace by
checking the ctx for non-NULL value.
Signed-off-by: Michael Scott <michael@opensourcefoundries.com>
The slist attr_list doesn't scale well when added to the LwM2M object,
object instance and resource instance structures. The goal of a
robust LwM2M client is to let the user create MANY object instances
and these will have many resource instances each. The amount of SRAM
taken up by the attr_lists will only increase over time, regardless
of the actual # of write attribute structures reserved via the
LWM2M_NUM_ATTR config setting.
Instead, let's remove the slist from these structures and add a
reference pointer to the lwm2m_attr structure. We can use this
reference to create the one to many relationship between the objects,
object instances and resource instances for a much smaller amount of
code and SRAM resources.
The sacrifice for these savings will be a larger # of iterations when
looking up assigned write attributes and matching them to their
references. However, due to the # of write attributes current being
handled, the # of iterations during this process is very manageable.
Example flash and SRAM savings when building for nrf52_blenano2:
Before patch:
Memory region Used Size Region Size %age Used
FLASH: 139532 B 512 KB 26.61%
SRAM: 36576 B 64 KB 55.81%
IDT_LIST: 148 B 2 KB 7.23%
After patch:
Memory region Used Size Region Size %age Used
FLASH: 139284 B 512 KB 26.57%
SRAM: 36000 B 64 KB 54.93%
IDT_LIST: 148 B 2 KB 7.23%
Summary: This patch saves ~248 bytes of flash and ~576 bytes of SRAM
for the typical configuration of LwM2M client in Zephyr.
NOTE: these values will vary by architecture.
Signed-off-by: Michael Scott <michael@opensourcefoundries.com>
When any error is returned from update_attrs() in engine_add_observer()
an EINVAL is returned back to the caller. Let's return whatever error
code was generated in update_attrs() instead.
Also, add handling where previously errors were ignored.
Signed-off-by: Michael Scott <michael@opensourcefoundries.com>
For code clarity, let's move notification_attrs structure to the top
of lwm2m_engine.c. While we're at it, we can re-order it's members
for memory alignment.
NOTE: This patch does not change the current flash or SRAM usage but
further additions to the notification_attrs structure could.
Signed-off-by: Michael Scott <michael@opensourcefoundries.com>
The path member of the object instance and resource instance structures
can easily be removed to save several bytes per instance over the entire
LwM2M subsystem. So let's remove it.
Example savings when building for nrf52_blenano:
SRAM usage before patch: 37952 B
SRAM usage after patch: 36576 B
Signed-off-by: Michael Scott <michael@opensourcefoundries.com>
Let's optimize the order of the following structures to account for
memory alignment:
lwm2m_engine_obj
lwm2m_engine_res_inst
lwm2m_output_context
lwm2m_output_context
Tested building for nrf52_blenano hardware:
SRAM usage before patch: 38240 B
SRAM usage after patch: 37952 B
Signed-off-by: Michael Scott <michael@opensourcefoundries.com>
It's highly unlikely that snprintk() will return a negative value, but
that's a possibility that will make the `pos` variable be set to a
value outside the boundaries of the statically allocated `buf` array.
Also clamp writes to ensure that the statically allocated buffer won't
be overwritten with a large token length.
Fixes#7070.
Signed-off-by: Leandro Pereira <leandro.pereira@intel.com>
In the future, when bootstrap support is added, this config won't
be used. Let's remove it.
Signed-off-by: Michael Scott <michael@opensourcefoundries.com>
Now that the LWM2M_OP_* bits have been renumbered, we no longer need
a custom BIT() macro for the LwM2M code. Let's remove it and use
BIT() instead.
Signed-off-by: Michael Scott <michael@opensourcefoundries.com>
Remove unused OP flag LWM2M_OP_NONE and renumber the existing flags
so that the operations used in object permissions land in the lowest
bits, and extended operations come later.
We may eventually add more permission / data flags, so let's try and
keep them inside a 1 byte boundary (flags with bits 0 to 7).
NOTE: LWM2M_OP_DELETE is currently not checked as a permission but
it may be in the future so it is in the lower bits.
Signed-off-by: Michael Scott <michael@opensourcefoundries.com>
When a data pointer or data length is not set, the read and write
handlers should return ENOENT to generate the correct LwM2M error
code (COAP_RESPONSE_CODE_NOT_FOUND).
Signed-off-by: Michael Scott <michael@opensourcefoundries.com>
Before ever call of string_to_path(), the lwm2m_obj_path object
was being cleared via memset. Let's move the memset into
string_to_path() to remove the duplicate code.
Signed-off-by: Michael Scott <michael@opensourcefoundries.com>
Eliminate several similar code-blocks by replacing
engine_get_resource() with a more useful function called:
path_to_objs()
By supplying an lwm2m_obj_path object, it will find and set
the related values for:
struct lwm2m_engine_obj_inst
struct lwm2m_engine_obj_field
struct lwm2m_engine_res_inst
NOTE: NULLs can be supplied where the returned value is not
important.
Signed-off-by: Michael Scott <michael@opensourcefoundries.com>
The code in the LwM2M "Device" object was checking for this max
power source config value, except that it was never added as a
Kconfig option. Let's go ahead and add it so apps can set the
value appropriately.
Signed-off-by: Michael Scott <michael@opensourcefoundries.com>
When attempting to read an unused multi-value resource such as
"Available Power Sources", lwm2m client return a successful coap packet
w/o any values. This looks like a timeout to any lwm2m servers which
make sure a valid response is returned.
Let's fix this by returning the correct NOT_FOUND error code instead.
NOTE: To test this I commented out the portion of the lwm2m client
sample which initializes the LWM2M_DEVICE_PWR_SRC_TYPE_BAT_INT and
LWM2M_DEVICE_PWR_SRC_TYPE_USB values. By default, the sample will
setup dummy values to be returned by the client.
Signed-off-by: Michael Scott <michael@opensourcefoundries.com>
As per review of PR #5893, this is a follow up patch to update
select_writer() API to match the behavior of select_reader() API.
Quote from OMA-TS-LightweightM2M-V1_0_1-20170704-A. 8.2.5
"An Object Instance or Resource is Read by sending a CoAP GET to the
corresponding path. The response includes the value in the
corresponding Plain Text, Opaque, TLV or JSON format according to
the specified Content-Format (see section 6.4).The request MAY
specify an Accept option containing the preferred Content-Format
to receive. When the specified Content-Format is not supported by
the LwM2M Client, the request MUST be rejected."
Therefore, we do not attempt to assign a content-format when the
requested one is not supported. Instead, we return an error code.
0 is returned when reader or writer has been successfully selected by
select_reader() or select_writer()
Signed-off-by: Robert Chou <robert.ch.chou@acer.com>
Currently, we always set the content-format as "plain/text" when
it is unrecognized. This is wrong for it's possible that payload
is actually something else.
For example, we don't support JSON as incoming format right now.
But if I send a PUT request to /1/0/1 (server objectinstance/lifetime
resource) with value 3200 in JSON format: {"e":[{"n":"","v":3200}]}.
The client will still handle the request and respond with changed (2.04)
except the lifetime resource is updated incorrectly due to parsing
error.
Correct the behavior by not setting a default format and respond with
content-format-not-support error code (4.15)
Signed-off-by: Robert Chou <robert.ch.chou@acer.com>
During the CoAP API change, slight changes were made the ref / unref
packet pending process. Let's re-align with the coap-client sample
in how we apply the packet refs in retransmit_request() and also
replace the lwm2m_send_message() call with a direct call of
net_app_send_pkt(). This avoids a second processing of the pending
packets and keeps the ref/unref flow cleaner.
Signed-off-by: Michael Scott <michael@opensourcefoundries.com>
During the CoAP API change, the way packets were ref'd and then
unref'd in order to stop the packet sending functions from releasing
the net_pkts was changed and never updated in the LwM2M library.
Let's use coap_pending_cycle() and coap_pending_clear() to do the
ref/unref the same way as the coap-client samples in order to
match the pending process with the current CoAP APIs.
Signed-off-by: Michael Scott <michael@opensourcefoundries.com>
Fraction could be stored with negative value.
The implementation was only considering the positive value case.
Therefore, we have to modify the code to take care of the case.
To test it
======================================================================
1. launch eclipse/wakaama lwm2m server
2. launch zephyr lwm2m client and wait for registration completed
3. Issue commands from server
* attr 0 /1/0/1 -0.1 0.1
* disc 0 /1/0
Current output
----------------------------------------------------------------------
Client #0 /1/0 : 2.05 (COAP_205_CONTENT)
105 bytes received of type application/link-format:
</1/0>,</1/0/0>,</1/0/1>;gt=0.1;lt=0/00000,</1/0/2>,</1/0/3>,</1/0/4>,
</1/0/5>,</1/0/6>,</1/0/7>,</1/0/8>
Expected output
----------------------------------------------------------------------
Client #0 /1/0 : 2.05 (COAP_205_CONTENT)
102 bytes received of type application/link-format:
</1/0>,</1/0/0>,</1/0/1>;gt=0.1;lt=-0.1,</1/0/2>,</1/0/3>,</1/0/4>,
</1/0/5>,</1/0/6>,</1/0/7>,</1/0/8>
Signed-off-by: Robert Chou <robert.ch.chou@acer.com>
As title, we should update the existing observe_node when new attributes
are written from server side. Add the implementation to handle that.
Signed-off-by: Robert Chou <robert.ch.chou@acer.com>
1. Read notification attributes set by server to setup the
minimum/maximum notification period of a observation request.
2. Reordering to check observe_node duplication first
(bailout earlier)
3. Simplify remove observe_node condition checking
NOTE: attributes are inheritable, priority: res > obj_inst > obj
Reference: LwM2M spec V1_0_1-20170704-A, section 5.1
Signed-off-by: Robert Chou <robert.ch.chou@acer.com>
Since we've added storing notification attributes written by server.
We can now append these attributes as part of link-format for discover
op.
Signed-off-by: Robert Chou <robert.ch.chou@acer.com>
Implement write-attribute on obj/obj_inst/res according to LwM2M spec
20170704-A, sec 5.1.2. Support pmin/pmax/st/gt/lt parameters on WRITE
operation.
The basic idea is to add sys_slist_t to obj/obj_inst/res structure.
And attach struct lwm2m_attr to the list when attributes are written
from server side (implement lwm2m_write_attr_handler accordingly)
Signed-off-by: Robert Chou <robert.ch.chou@acer.com>
commit 2a7546fb5a ("net: lwm2m: add support for coap2coap proxy")
erroneously changed the COAP_OPTION_* used to specify the coap2coap
or coap2http proxy resource used from COAP_OPTION_URI_PATH to
COAP_OPTION_PROXY_SCHEME.
Changing it back to COAP_OPTION_URI_PATH requires us to re-order how
the coap options are appended to the packet as the coap options must
be added in the order specified by the numbers in:
https://tools.ietf.org/html/rfc7252#section-12.2
Signed-off-by: Michael Scott <michael@opensourcefoundries.com>
CoAP packet w/ confirmation flag set is required to be retransmitted
before it got the ACK message from the peer.
However, the packet is usally unreference once it's sent to the network.
Although we set the timeout as no wait when calling function
net_app_send_pkt(), it's still possible that the packet is unreferenced
before we got a chance to increase the packet reference by calling
coap_pending_cycle().
Usually, the IP stack will generate an ARP packet first and then send
out the packet. However, this is not the case when the remote is a
loopback address.
As issue #5101 described, when asking client to perform a firmware pull
on URL "coap://127.0.0.1:7783/large". The packet will be unreferenced
immediately after calling net_app_send_pkt(). Which then result in
client hang.
The solution to the issue is to increase the reference count on the
sending packet and decrease it after the process is finished.
Signed-off-by: Robert Chou <robert.ch.chou@acer.com>
Consolidate and standardize error handling throughout
lwm2m_obj_firmware_pull.c. As well as handle previously
unhandled errors returned from transfer_request().
NOTE: in general, unhandled errors will now result in
RESULT_UPDATE_FAILED. Previously, unhandled errors in
transfer_request() would result in RESULT_CONNECTION_LOST
which might or might not be over-written with another
result later.
Signed-off-by: Michael Scott <michael@opensourcefoundries.com>
Currently, LwM2M firmware download only supports coap2http proxy.
Let's add support for coap2coap proxy as well.
This was tested running Californium demo app cf-proxy on the host
machine with the following setting changed in Californum.properties:
MAX_RESOURCE_BODY_SIZE=524288
Add the following to the samples/net/lwm2m_client/prj.conf:
CONFIG_LWM2M_FIRMWARE_UPDATE_PULL_COAP_PROXY_SUPPORT=y
CONFIG_LWM2M_FIRMWARE_UPDATE_PULL_COAP_PROXY_ADDR="coap://[2001:db8::2]:5682"
Build the sample for qemu_x86 as you would normally, but now
you can use a real world coap address to pull firmware using the 5/0/1
resource. The host machine running cf-proxy will pull the remote
resource and then deliver it to the running qemu sample.
Signed-off-by: Michael Scott <michael@opensourcefoundries.com>
- Add needed settings for DTLS support to the lwm2m_ctx structure.
- Add initialization of MBEDTLS to the LwM2M lib based on the
user application settings in lwm2m_ctx.
Signed-off-by: Michael Scott <michael@opensourcefoundries.com>
The default net_context remote address is scrambled when using a
connection via DTLS. Instead let's use the dtls context remote.
Signed-off-by: Michael Scott <michael@opensourcefoundries.com>
While looping through possible lwm2m_ctx matches, we're referencing
remote before checking that the context itself is valid.
Also, reduce indentation issues.
Signed-off-by: Michael Scott <michael@opensourcefoundries.com>
Instead of building under the "app" context, let's build the
LwM2M library as a separate static library. This will be helpful
later when adding support for DTLS as w/o this configuration,
the build breaks on MBEDTLS config includes.
Signed-off-by: Michael Scott <michael@opensourcefoundries.com>
Content-format is used to determine the type of the PUT/POST
request. Therefore, it's incorrect to assign default when the
caller does not include one in the request.
Define LWM2M_FORMAT_NONE=65535 to indicate the format is missing.
The 65000~65535 is reserved for experiments and should be safe for
the purpose. Check content-type at PUT method to setup
write/write-attrs operation accordingly.
Also, add reporting write-attrs as not implemented to the caller.
Signed-off-by: Robert Chou <robert.ch.chou@acer.com>
According to LwM2M specification V1_0_1-20170704-A, table 25,
incoming request is a discover op if it is method GET with
accept format as application/link-format
Signed-off-by: Robert Chou <robert.ch.chou@acer.com>
According to LwM2M specification 20170208-A, there are two different
discover interfaces supported by the device.
(1) Bootstrap discover (sec 5.2.7.3) (To be implemented)
(2) Device management discover interface (Sec 5.4.2)
- object ID is required (i.e. root directory discover is not allowed)
- attributes should be responded accordingly when implemented
This patch correct the behavior according to the spec and summarized
as follow
(1) Still support CoAP ".well-known/core" but change to report only
first level of the URI.
(2) Respond to caller only when object ID is provided unless it's
bootstrap discover
Fixes#4941
Signed-off-by: Robert Chou <robert.ch.chou@acer.com>
Token is missing when we jump to the error and token is not yet setup.
To correct it, we grab the token from the input packet at the beginning
of the handle_request()
Signed-off-by: Robert Chou <robert.ch.chou@acer.com>
Copy/paste error was checking minimum measurements where it
should have been checking maximum measurements.
Signed-off-by: Michael Scott <michael.scott@linaro.org>
Initial values for the min/max measurements were 0 and this caused
issues with sensors maximums that weren't above 0 and minimums that
went below 0. Let's update those to MAX_INT so the first sensor
value update will set those to correct values.
When resetting the measured values, let's use the current sensor
value not 0.
Signed-off-by: Michael Scott <michael.scott@linaro.org>
Introducing CMake is an important step in a larger effort to make
Zephyr easy to use for application developers working on different
platforms with different development environment needs.
Simplified, this change retains Kconfig as-is, and replaces all
Makefiles with CMakeLists.txt. The DSL-like Make language that KBuild
offers is replaced by a set of CMake extentions. These extentions have
either provided simple one-to-one translations of KBuild features or
introduced new concepts that replace KBuild concepts.
This is a breaking change for existing test infrastructure and build
scripts that are maintained out-of-tree. But for FW itself, no porting
should be necessary.
For users that just want to continue their work with minimal
disruption the following should suffice:
Install CMake 3.8.2+
Port any out-of-tree Makefiles to CMake.
Learn the absolute minimum about the new command line interface:
$ cd samples/hello_world
$ mkdir build && cd build
$ cmake -DBOARD=nrf52_pca10040 ..
$ cd build
$ make
PR: zephyrproject-rtos#4692
docs: http://docs.zephyrproject.org/getting_started/getting_started.html
Signed-off-by: Sebastian Boe <sebastian.boe@nordicsemi.no>
Update the firmware update_result accordingly by checking return
value of the firmware data write callback registered by application.
Also, set response code according.
Signed-off-by: Robert Chou <robert.ch.chou@acer.com>
We should call coap_update_from_block() which will determine the minimum
size of the BLOCK1 SIZE between server/client and update the current
offset and total size(if available) accordingly.
Signed-off-by: Robert Chou <robert.ch.chou@acer.com>
Now that objects and samples have their return values fixed, let's
propagate them back up to the user if there's an error.
Signed-off-by: Michael Scott <michael.scott@linaro.org>
Previously, post_write and execute callbacks returned 1 when handled
and 0 for error condition. However, this wasn't detailed enough and
the engine can't propagate any sort of error back to users -- so it
doesn't even check the return values in many cases!
Let's adjust the resource callback functions of all objects and the
lwm2m_client sample to return 0 for success or a valid error code.
Signed-off-by: Michael Scott <michael.scott@linaro.org>
Now that we can access resource data in the lwm2m subsys, let's use
the user provided firmware push buffer (5/0/0) to also store the
firmware pull data.
This way the size of the firmware pull buffer is completely up to the
application.
NOTE: This patch adds a 64 byte firmware buffer to the lwm2m_client
sample for this purpose.
Signed-off-by: Michael Scott <michael.scott@linaro.org>
With the change to support multi-fragement buffers in the LwM2M subsys,
the OPAQUE data type was direct write methods were broken.
Let's fix OPAQUE handling by using the newly introduced getter methods
which can use multiple user callbacks (depending on the size of the
user provided buffer). Let's also add public methods for users to set
/ get OPAQUE data in resources for future use with DTLS key data.
Signed-off-by: Michael Scott <michael.scott@linaro.org>
The lwm2m_engine_get_resource() function needs to be made available to
other portions of the lwm2m subsys in order for firmware resource data
to be used in the future.
Signed-off-by: Michael Scott <michael.scott@linaro.org>
During conversion from the ZoAP to CoAP APIs the use for this variable
was removed, but the variable itself was left in place.
Signed-off-by: Michael Scott <michael.scott@linaro.org>
No need for 2 different defines to specify URI lengths in the source
for firmware pull method. Let's combine them.
Signed-off-by: Michael Scott <michael.scott@linaro.org>
Each content formatter should have a way of handling opaque data.
For instance TLV data will individually be able to specify a length
but plain text will take up the rest of the packet.
Signed-off-by: Michael Scott <michael.scott@linaro.org>
The existing LwM2M framework expected contiguous buffers and this
was the reason for the 384 byte buffer sizes. This was previously
a limitation of the ZoAP API. The new CoAP API doesn't have this
limitation and the LwM2M library has already been migrated to use
it.
Let's finish the process by replacing any contiguous buffer handling
with the correct net_pkt APIs to parse across multiple fragments.
Signed-off-by: Michael Scott <michael.scott@linaro.org>
application/octet-stream is used to indicate opaque payload format.
Use plain text handler to handle the opaque format.
Signed-off-by: Robert Chou <robert.ch.chou@acer.com>
When moving to the new CoAP API, I thought we would need to parse
incoming option values longer than 12 characters.
This hasn't proven to be true, so let's remove the auto-selection of
this config. If needed user can set this option later.
Signed-off-by: Michael Scott <michael.scott@linaro.org>
Remove the RD client's stack in favor of using the engine's periodic
service to trigger RD client events. This saves 5K RAM of stack based
memory.
Signed-off-by: Michael Scott <michael.scott@linaro.org>
Remove the stack from the device object and instead make use of
the periodic engine service which will trigger the device service
when it's ready.
Signed-off-by: Michael Scott <michael.scott@linaro.org>
Stacks cost a lot of RAM in Zephyr. We have 3 total stacks in
the LwM2M lib. We can remove 2 of these if add a service handler
into the main LwM2M engine. Each service can register with this
handler so that they can be called based on their own periodic
timer. The handler itself will search through these registered
services and call them when they become due otherwise sleep
until another is ready.
Signed-off-by: Michael Scott <michael.scott@linaro.org>
Let's use conservative defaults for the LwM2M library to enable
hardware with constrained resources. Users can increase where
necessary.
Signed-off-by: Michael Scott <michael.scott@linaro.org>
Let's use snprintk for simple formatting to allow for possible disabling
of printf and protect calls to sprintf from string overruns.
Signed-off-by: Michael Scott <michael.scott@linaro.org>
When using Leshan REST API to perform a discover OP on a client, only an
accept field is sent with "application/link-format". Current logic uses
the content-type to determine when a discover OP is indicated. Let's
handle this case as well.
Signed-off-by: Michael Scott <michael.scott@linaro.org>
Let's rename lwm2m_release_message() to lwm2m_reset_message()
and add a parameter to let the function know whether or not to
release the lwm2m_message resource back to the pool.
By adding the optional release parameter, we can keep the
lwm2m_message but reset the underlying net_pkt / net_buf resources.
This allows us to regenerate the net_pkt after determining
an error has occured. In this case, we don't want the previously
added net_pkt contents but we do want to maintain the message id,
token, etc.
Signed-off-by: Michael Scott <michael.scott@linaro.org>
This patch moves from the ZoAP API in subsys/net/lib/zoap to
the CoAP API in subsys/net/lib/coap which handles multiple
fragments for sending / receiving data.
NOTE: This patch moves the LwM2M library over to the CoAP APIs
but there will be a follow-up patch which re-writes the content
formatter reader / writers to use net_pkt APIs for parsing
across multiple net buffers. The current implementation assumes
all of the data will land in 1 buffer.
Samples using the library still need a fairly large NET_BUF_DATA_SIZE
setting. (Example: CONFIG_NET_BUF_DATA_SIZE=384)
Signed-off-by: Michael Scott <michael.scott@linaro.org>
Don't use names like "strlen" for parameters. Try and name buffer
parameters consistently.
NOTE: For several functions I removed "const" flag. This is
intentional and will be needed in upcoming patches.
Signed-off-by: Michael Scott <michael.scott@linaro.org>
Remove some left over TODOs and also fix a TODO where we need to return
the appropriate error code to generate a 4.05 response.
Signed-off-by: Michael Scott <michael.scott@linaro.org>
The stack of rd client is exhausted while running lwm2m client w/ IPv6
and network log global enabled. Increase the stack size to 1536 when
NET_LOG_GLOBAL is enabled.
Detail described at #4424
Signed-off-by: Robert Chou <robert.ch.chou@acer.com>
".well-known/core" is mainly used with method GET for performing the
resource discovery (RFC 6690). Since we are implementing a LwM2M client
and is not implement a resource directory which allow others to do the
resource registration (POST to .well-known/core). Only GET method is
allowed for the usage. Report 4.5 (Method Not Allowed) if other methods
are requested.
Signed-off-by: Robert Chou <robert.ch.chou@acer.com>
Modify zoap_options_to_path() to return error when URI contains
character other than digits and return 4.04 NOT FOUND to caller.
PATH such as "/1a/2/3" was treated as "/1/2/3" after parsring
which is incorrect.
Signed-off-by: Robert Chou <robert.ch.chou@acer.com>
Return 4.05 Method Not Allowed when path is empty ('/') to the
caller for it's only use by bootstrap delete. This change also avoid the
empty path being treated as request targeted at 0/0/0.
Signed-off-by: Robert Chou <robert.ch.chou@acer.com>
1) Respond NOT FOUND to caller when object doesn't exist
2) Report as internal server error when OP not handled
Signed-off-by: Robert Chou <robert.ch.chou@acer.com>
Applications may want to be notified when various events
happen in the LwM2M rd client. Let's implement an event
callback which sends: connect, disconnect and update events.
Signed-off-by: Michael Scott <michael.scott@linaro.org>
CoAP allows a proxy to be used when transferring data (CoAP-CoAP and/or
CoAP-HTTP) by creating request on a specific URI path and by using the
Proxy URI CoAP option. Create specific Kconfig options for the proxy
server address and port, until a parser gets implemented.
Code tested with Californium acting as CoAP proxy.
Signed-off-by: Ricardo Salveti <ricardo.salveti@linaro.org>
[michael.scott@linaro.org: rebased on net_app + lwm2m_message
refactoring + firmware update changes.]
Signed-off-by: Michael Scott <michael.scott@linaro.org>
During firmware download via block-wise transfer, we can see
packets occaionally get re-transmitted (normal logic in the
pending / retry functions). However, both of these packets
end up coming through the reply handler and we should ignore
any block-wise transfer that has a current value less than
where we expect to be.
NOTE: This fixes K64F ethernet transfers where we were getting
too many packets back in the handler.
Signed-off-by: Michael Scott <michael.scott@linaro.org>
UDP packets can be lost in heavy traffic. Normally we can handle this
with pending packet processing for packets which have not been responded
to with an ACK. However, due to the time it takes for firmware to
download via CoAP, an extra level of retries should be added.
The process works like this:
Normal pending packets will try to send 3 times fairly quickly.
If that fails, then the timeout callback is called for the firmware
download process. A retry counter is incremented and the timeout
callback perform a new packet send of the block-wise transfer
packet that is missing, until the retry counter hits a limit (3)
and then the transfer is aborted.
This allows for a longer "outage" to happen during firmware transfer
and the process can still succeed.
NOTE: This patch does not fix a current bug where the pending process
is not re-sending the packets correctly, it only makes the process
more stable with a better chance to work.
Signed-off-by: Michael Scott <michael.scott@linaro.org>
When a packet expires after the pending retries we call
lwm2m_release_message() to free up resources. This includes
cleanup of the pending structure which calls net_pkt_unref on
the pending packet. This would normally free up the packet
memory. However, earlier in the pending processing we add a ref
to the packet so that normal send processing doesn't free up
the memory. This meant we were leaking packet memory every
time we had an expiration due to timeout.
Let's do an unref prior to calling lwm2m_release_message() to
make sure the packet memory is freed correctly.
Signed-off-by: Michael Scott <michael.scott@linaro.org>
Previously, firmware support wasn't initializing the retransmit work
or the extra network packet pools. Let's fix that.
NOTE: While this fixes the setup of retransmit work, the actual
attempts to re-send packets which are pending is failing. Needs
another follow-up fix.
Signed-off-by: Michael Scott <michael.scott@linaro.org>
Create an internal function lwm2m_engine_context_init() which sets
the extra packet pools and initializes retransmit work internal to
the LwM2M engine.
This function will be used by firmware pull support which establishes
a new LwM2M context for downloading firmware.
Signed-off-by: Michael Scott <michael.scott@linaro.org>
In the case of a proxy server translating HTTP -> COAP (known in
the code as "separate reply"), we were leaking lwm2m_message structures.
This was due to pending objects being cleared out during the first ACK,
and no other way of finding a matching message when the follow up packet
was received. Let's add a second match for reply to make sure we can
find our matching message resources.
NOTE: This change renames find_msg_from_pending() to find_msg() and
makes it a static function as it's only used by the lwm2m_engine.
Signed-off-by: Michael Scott <michael.scott@linaro.org>
This is a useful message announcing that the RD client state machine
is starting for a particular connection. If the log level is set
low so that DBG messages are hidden, then this message goes away.
Signed-off-by: Michael Scott <michael.scott@linaro.org>
1. Add handling block1 option in handle_request(). The basic idea is
to declare structure block_context at compiled time and use "token"
as a key to pick up the on-going block cotext. It should be able to
support multiple blockwise transfer concurrently
2. Use write callback implemented in lwm2m_obj_firmware to deal w/ the
update state transition and than call the callback registered by the
application
3. move default_block_size to lwm2m_engine.c to share between
lwm2m_engine and lwm2m_obj_firmware_pull
Signed-off-by: Robert Chou <robert.ch.chou@acer.com>
[michael.scott@linaro.org: rebased on LwM2M net_app changes.]
Signed-off-by: Michael Scott <michael.scott@linaro.org>
OPAQUE resource type might/might not have data_ptr/data_len setup
depending on the implementation. This introduce an issue that when
OPAQUE resource is written from the server side, the ones w/ none
setup will not be able to get the data at post_write_cb()
Modify to setup data_ptr/data_len as incoming buffer and buffer size
Signed-off-by: Robert Chou <robert.ch.chou@acer.com>
1. Parse firmware pull URI
2. Add lwm2m_firmware_get/set_update_cb() for application to register
callback. This is because we want to check the update_state before
we pass to the application
3. Add lwm2m_firmware_get/set_update_result() and
lwm2m_firmware_get/set_update_stat() to manage the state transition
as well as the sanity check
Signed-off-by: Robert Chou <robert.ch.chou@acer.com>
[michael.scott@linaro.org: rebased on net_app framework and
lwm2m_message refactoring.]
Signed-off-by: Michael Scott <michael.scott@linaro.org>
With future patches we will need to parse URLs in the registration
client and firmware object. Enable it by default when LWM2M is
enabled.
Signed-off-by: Michael Scott <michael.scott@linaro.org>
Due to timeout checking the minimum lifetime must be 15 seconds,
and we're storing the lifetime as an unsigned short so set the
maximum to 65535.
Signed-off-by: Michael Scott <michael.scott@linaro.org>
Callbacks are setup for the following states:
- ENGINE_DO_BOOTSTRAP
- ENGINE_DO_REGISTRATION (first registration)
- ENGINE_REGISTRATION_DONE (subsequent client updates)
- ENGINE_DEREGISTER
In most cases, if a timeout occurs the registration engine goes back to
ENGINE_INIT. The exception is a timeout during client update, which
forces the state machine back to ENGINE_DO_REGISTRATION (skipping a
boostrap).
Signed-off-by: Michael Scott <michael.scott@linaro.org>
Sending an lwm2m message is too difficult. It requires pending / reply
and other structures to be configured and set by various portions of
the library. There is also no way to know if a pending message ever
encounters a timeout.
Let's fix this by simplifying the internal LwM2M engine APIs for
handling lwm2m messages:
1. A user calls lwm2m_get_message(lwm2m_ctx) which returns the first
available lwm2m message from an array of messages
(total # of messages is set via CONFIG_LWM2M_ENGINE_MAX_MESSAGES).
2. Next the user sets all of the fields in the message that are
required (type, code message id, token, etc)
3. Then the user calls lwm2m_init_message(msg). This initializes the
underlying zoap_packet, pending and reply structures.
4. Once initialized, the user creates their payload in msg->zpkt.
5. When the user is ready to send, the call lwm2m_send_message(msg).
6. And if for some reason an error occurs at any point, they can free
up the entire set of structures with: lwm2m_release_message(msg).
Included in the refactoring is a timeout_cb field which can be set in
the LwM2M messages. If a pending structure ever expires the engine
will call the timeout_cb passing in the msg structure before it's
automatically released.
Signed-off-by: Michael Scott <michael.scott@linaro.org>
Instead of using a magic reference to 8 for token length, let's
establish a define for MAX_TOKEN_LENGTH and then use it for both
variable definitions and to make sure tokens are valid. Also,
Correct the handling of a special token length value (0xFF) which
lets lwm2m_init_message() know to skip token generation. We were
using a -1 value here previously (on a u8_t variable).
Signed-off-by: Michael Scott <michael.scott@linaro.org>
This is the first part of a large refactoring of LwM2M library
message functions and will simplify observer handling later.
Signed-off-by: Michael Scott <michael.scott@linaro.org>
All throughout the LwM2M library we use sockaddr values which are
basically the same as the net_app_ctx's remote addr. There's no
reason to keep these extra sockaddr values around. The net_app
framework client won't accept incoming requests on sockaddr other
than the one we're connected to.
Signed-off-by: Michael Scott <michael.scott@linaro.org>
This is the final stage of moving the LwM2M library internals to
the net_app APIs. This means we can support DTLS and other
built-in features in the future. All of the logic for
establishing the network connection is removed from the sample
app.
Signed-off-by: Michael Scott <michael.scott@linaro.org>
In preparation for the move to net_app APIs, we will need
to pass net_app_ctx structures around to the following
functions:
lwm2m_udp_sendto()
udp_request_handler()
Let's add the parameter as net_context for now so the
transition will be smoother later.
Signed-off-by: Michael Scott <michael.scott@linaro.org>
This allows use to associate easily the replies / pending operations
with a specific network connection.
Signed-off-by: Michael Scott <michael.scott@linaro.org>
The LwM2M library does not use net_app APIs internally. To help
this effort let's establish a user facing structure "lwm2m_ctx"
(similar to http_client_ctx and mqtt_ctx) and start it off by
wrappering the net_context structure.
Future patches will add user setup options to this structure and
eventually remove the net_context structure in favor of a net_app_ctx.
Signed-off-by: Michael Scott <michael.scott@linaro.org>
Errors has been ignored when using TLV writer to create/write object
instance/resources. Modify to propagate the error back to the caller.
To reproduce the issue, try to create IPSO light control object
instances twice. Since the default instance count is 1, the second one
should be rejected and responded w/ error. But the current
implementation will respond w/ 2.04.
Signed-off-by: Robert Chou <robert.ch.chou@acer.com>
We did not check the requested object/object instance/resource exists or
not before we adding an observer. Correct it by checking the existence
first.
Signed-off-by: Robert Chou <robert.ch.chou@acer.com>
We should stop sending out notification to the peer when the
object/object instances requested to be observed is removed
Signed-off-by: Robert Chou <robert.ch.chou@acer.com>
We were using sys_slist_remove() to remove object, object instance and
observer w/o passing the previous sys_snode_t to it (NULL).
This will instruct the function to treat the node as the list head and
result in unexpected behavior after the removal.
Correct it by using sys_slist_find_and_remove() or passing the previous
node to the function.
Signed-off-by: Robert Chou <robert.ch.chou@acer.com>
When a request demands to create a new object instance, it will search
whether the request object instance exists or not. However, current
implementation does not reset the lwm2m_engine_obj_inst at the time it
is deleted. It only removes the object instance from the sys list.
Correct the behavior by resetting both object instance and resource
instances at the time it's deleted. Also, consolidate function
lwm2m_delete_handler() and lwm2m_delete_obj_inst().
To reproduce the issue, try to create light control object instance
(/3301), delete the created instance and create it again. You shall find
following error message dumped.
> [ipso_light_control] [ERR] light_control_create: Can not create
instance - already existing: 0
> [lib/lwm2m_engine] [ERR] lwm2m_create_obj_inst: unable to create obj -
3311 instance 0
Signed-off-by: Robert Chou <robert.ch.chou@acer.com>
Per LwM2M spec (7.3.2.4 Operation on Object):
"If the payload (New Value) conveys an Object Instance ID in conflict
with one already present in the LwM2M Client, the complete request
MUST be rejected and a "Bad Request" error code MUST be sent back."
Let's do that.
Signed-off-by: Michael Scott <michael.scott@linaro.org>
Per LwM2M specification 7.3.2.4, "Optional Resources MAY be conveyed
in the "New Value" parameter as well; the LwM2M Client MAY ignore the
optional resources it doesn't support."
Update TLV/JSON writer to ignore error when object fields are not
found (treated as optional resource). This will allow the resources
supported being written.
Signed-off-by: Robert Chou <robert.ch.chou@acer.com>
[michael.scott@linaro.org: re-worked patch post addition of CREATE
operation.]
Signed-off-by: Michael Scott <michael.scott@linaro.org>
Prior to this patch, a CREATE operation was handled as a WRITE operation
after the object instance was created. This becomes problematic when
handling of optional resources differs between these 2 operations.
Let's introduce an actual CREATE operation and use it later to create
these differences.
Signed-off-by: Michael Scott <michael.scott@linaro.org>
We are returning EINVAL from content format write ops when an object
field definition is not found (an optional field which is not
implemented). Instead, return ENOENT which lets the LwM2M engine
know to send ZOAP_RESPONSE_CODE_NOT_FOUND to the LwM2M server at the
end of handle_request().
NOTE: This behavior is not correct when we call the writer right after
a CREATE operation where the data is assigned to resources for the
first time. This case will be handled in a follow-up patch once we're
able to distinguish between a WRITE and a CREATE in the write op
handler.
Signed-off-by: Michael Scott <michael.scott@linaro.org>
POSIX requires struct sockaddr's field to be named "sa_family"
(not just "family"):
http://pubs.opengroup.org/onlinepubs/009696699/basedefs/sys/socket.h.html
This change allows to port POSIX apps easier (including writing
portable apps using BSD Sockets compatible API).
Signed-off-by: Paul Sokolovsky <paul.sokolovsky@linaro.org>
Per LwM2M specification 5.3.1 Register, report "ct=11543" when JSON is
supported. Also, report the resource type as rt="oma.lwm2m" when "ct="
presents.
Signed-off-by: Robert Chou <robert.ch.chou@acer.com>
Per LwM2M specification 5.3.1 Register. When object instances are
available, object ID can be ignored in registration message
Signed-off-by: Robert Chou <robert.ch.chou@acer.com>
According to LwM2M specification 5.2.7.3 Bootstrap DISOCVER,
security object is only reported to the bootstrap server.
Correct the behavior to (1) report server object to the server
(2) do not report security object at registration time
Signed-off-by: Robert Chou <robert.ch.chou@acer.com>
1. According to the specification 5.3.1, it's a MUST to specify
(1) content format: app link format (2) supported lwm2m version.
Also, we should use text/plain instead of LWM2M's (obsolete).
2. Use LWM2M_FORMAT_OMA_TLV as default accept format when accept option
is not given from the caller for TLV is a MUST have in LwM2M spec and
it can deals w/ multiple resources read
Signed-off-by: Robert Chou <robert.ch.chou@acer.com>
Save in observe_node_data so that later on we can select the correct
content format requested by the caller at the first time
Signed-off-by: Robert Chou <robert.ch.chou@acer.com>
Function do_write_op_tlv() uses in->inbuf and in->insize as a looping
condition to iterate through items in TLV payload and call
do_write_op_tlv_item() to update the value.
However, do_write_op_tlv_item() will override the value before calling
for fitting the usage of lwm2m_write_handler() function without restore
them. (lwm2m_write_handler() is also called by plain text/json writer
and is expecting in->inbuf is the start of buffer and in->insize as the
length of the buffer)
This will result in errors in do_write_op_tlv().
Signed-off-by: Robert Chou <robert.ch.chou@acer.com>
sprint_token is only used by SYS_LOG_DBG, so only build it when
CONFIG_SYS_LOG_LWM2M_LEVEL > 3.
Signed-off-by: Ricardo Salveti <ricardo.salveti@linaro.org>
Separate response can happen when handling block transfer for firmware
updates, and to avoid duplicating the lwm2m_udp_receive function, create
and additional flag to allow handling CoAP separate response messages.
This is required to avoid removing the reply callback, since a new
message (with a valid token) will be received later from the server.
Signed-off-by: Ricardo Salveti <ricardo.salveti@linaro.org>
Simplifly net_context_sendto calls and also allows to easily debug every
send/receive lwm2m call.
Signed-off-by: Ricardo Salveti <ricardo.salveti@linaro.org>
IPSO Smart Objects are a set of template objects based on the LwM2M
object framework which are designed to represent standard hardware
such as temperature and humidity sensors or light controls.
Let's add a place for these objects to live as well as an initial
temperature sensor object.
Signed-off-by: Michael Scott <michael.scott@linaro.org>
Origin: SICS-IoT / Contiki OS
URL: https://github.com/sics-iot/lwm2m-contiki/tree/lwm2m-standalone-dtls
commit: d07b0bcd77ec7e8b93787669507f3d86cfbea64a
Purpose: Introduction of LwM2M client library.
Maintained-by: Zephyr
Lightweight Machine-to-Machine (LwM2M) is a protocol stack extension
of the Constrained Application Protocol (CoAP) which uses UDP
transmission packets.
This library was based on source worked on by Joakim Eriksson,
Niclas Finne and Joel Hoglund which was adopted by Contiki and then
later revamped to work as a stand-alone library.
A VERY high level summary of the changes made:
- [ALL] sources were re-formatted to Zephyr coding standards
- [engine] The engine portion was re-written due to the heavy reliance
on ER-CoAP APIs which are not compatible to the Zephyr CoAP APIs as
well as other Zephyr specific needs.
- [engine] All LWM2M/IPSO object data is now abstracted into resource
data which stores information like the data type, length, callbacks
to help with read/write. The engine modifies this data directly (or
makes callbacks) instead of all of the logic for this living in each
object's code. (This wasn't scaling well as I was implementing
changes).
- [engine] Related to the above change, I also added a generic set of
getter/setter functions that user applications can call to change
the object data instead of having to add getter/setting methods in
each object.
- [engine] The original sources shared the engine's context structure
quite extensively causing a problem with portability. I broke up the
context into it's individual parts: LWM2M path data, input data and
output data and pass only the needed data into each set of APIs.
- [content format read/writer] sources were re-organized into single
.c/h files per content formatter.
- [content format read/writer] sources were re-written where necessary
to remove the sharing of the lwm2m engine's context and instead only
requires the path and input or output data specific to it's
function.
- [LwM2M objects] re-written using the new engine's abstractions
Signed-off-by: Michael Scott <michael.scott@linaro.org>