Commit graph

91 commits

Author SHA1 Message Date
Michael Scott
ed3ea06f88 net: lwm2m: fix observer attribute update logic
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>
2018-06-07 12:27:46 -05:00
Michael Scott
a957107d50 net: lwm2m: lower priority of engine thread
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>
2018-06-07 11:51:51 -05:00
Michael Scott
4c58ffb5ab net: lwm2m: dont release reply for duplicate block transfer
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>
2018-05-25 17:19:34 -04:00
Michael Scott
a021034327 net: lwm2m: honor CONFIG_LWM2M_LOCAL_PORT when starting client
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>
2018-05-18 09:28:28 +03:00
Michael Scott
0d67f6a78d net: lwm2m: introduce FLAG_OPTIONAL to denote optional resources
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>
2018-05-16 10:56:07 +03:00
Michael Scott
0db9af5a28 net: lwm2m: return error from lwm2m_engine_get_* functions
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>
2018-05-16 10:56:07 +03:00
Michael Scott
ad13866ffd net: lwm2m: remove "used" from observe_node
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>
2018-05-11 16:38:49 +03:00
Michael Scott
6ef46e3f31 net: lwm2m: remove attr_list from obj, obj_inst and res_inst structs
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>
2018-05-11 16:38:49 +03:00
Michael Scott
573c1f777e net: lwm2m: improve return errors from update_attrs()
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>
2018-05-11 16:38:49 +03:00
Michael Scott
bc7a5d3a6c net: lwm2m: relocate/memory align notification_attrs struct
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>
2018-05-11 16:38:49 +03:00
Michael Scott
2027c10a9f net: lwm2m: remove "path" from object and resource instances
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>
2018-05-11 16:38:49 +03:00
Leandro Pereira
7359c5b10b net: lwm2m: Do not use snprintk() to get debugging token
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>
2018-05-10 14:17:35 -07:00
Michael Scott
f80c52d668 net: lwm2m: introduce LWM2M_HAS_PERM macro
Standardize permission checks via the LWM2M_HAS_PERM macro.

Signed-off-by: Michael Scott <michael@opensourcefoundries.com>
2018-05-04 09:45:35 +03:00
Michael Scott
cf55b70b4c net: lwm2m: fix error code in read and write handlers
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>
2018-05-04 09:45:35 +03:00
Michael Scott
44c9b79a49 net: lwm2m: clear lwm2m_obj_path obj in string_to_path
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>
2018-05-04 09:45:35 +03:00
Michael Scott
3e16be3c3c net: lwm2m: refactor engine_get_obj to be more useful
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>
2018-05-04 09:45:35 +03:00
Michael Scott
c1e180b6ee net: lwm2m: return NOT_FOUND for unused multi-value resources
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>
2018-02-08 09:48:45 +02:00
Robert Chou
228bf05af6 net: lwm2m: update internal API select_writer() and select_reader()
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>
2018-02-07 22:12:48 -05:00
Robert Chou
54d7207e09 net: lwm2m: check content-format and respond with error if not support
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>
2018-02-05 09:05:00 +02:00
Michael Scott
afb9830441 net: lwm2m: fix retransmit_request() pending process / packet send
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>
2018-01-31 12:20:41 +02:00
Michael Scott
db09596b1d net: lwm2m: correct packet pending process in lwm2m_send_message()
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>
2018-01-31 12:20:41 +02:00
Robert Chou
6fbd86113d net: lwm2m: fix reporting attributes with negative fraction
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>
2018-01-29 23:30:44 -05:00
Robert Chou
b7af740f3a net: lwm2m: update observe_node when attributes are written or cleared
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>
2018-01-12 20:57:34 -05:00
Robert Chou
2281f6fd7d net: lwm2m: get attributes from obj/obj_inst/res for observe_node
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>
2018-01-12 20:57:34 -05:00
Robert Chou
b0e7a039ee net: lwm2m: report attributes on discover op
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>
2018-01-12 20:57:34 -05:00
Robert Chou
09fcd83b98 net: lwm2m: add write-attribute WRITE support
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>
2018-01-12 20:57:34 -05:00
Robert Chou
33030721c4 net: lwm2m: increase packet reference to avoid packet being freed
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>
2018-01-11 09:18:10 +02:00
Michael Scott
6ddbd56853 net: lwm2m: add support for DTLS
- 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>
2017-12-15 16:46:48 -05:00
Robert Chou
685db067d5 net: lwm2m: separate write operation from write-attributes op
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>
2017-12-12 09:26:31 -05:00
Robert Chou
e237ae7d35 net: lwm2m: reduce code size of coap_options_to_path()
Signed-off-by: Robert Chou <robert.ch.chou@acer.com>
2017-12-12 09:26:31 -05:00
Robert Chou
dfbe275c64 net: lwm2m: discover op does not depend on input format type
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>
2017-12-12 09:25:59 -05:00
Robert Chou
3062e76858 net: lwm2m: correct lwm2m discover operation behavior
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>
2017-12-12 09:25:59 -05:00
Robert Chou
7929aaf307 net: lwm2m: remove unused options variable
Remove it for we are not using it after calling the
coap_packet_parse().

Signed-off-by: Robert Chou <robert.ch.chou@acer.com>
2017-12-12 09:25:59 -05:00
Robert Chou
b678895a6d net: lwm2m: POST with <obj>/<obj instance> is a WRITE op
Per LwM2M specification V1_0_1-20170704-A, table 25.

Signed-off-by: Robert Chou <robert.ch.chou@acer.com>
2017-11-21 09:28:12 -05:00
Robert Chou
9dcbbdb3e2 net: lwm2m: fix sending packet w/o token setup when error
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>
2017-11-16 10:21:14 +02:00
Robert Chou
3ad6719fbf net: lwm2m: response to peer with correct error code when write fail
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>
2017-11-06 20:49:59 +02:00
Robert Chou
d36b3251fa net: lwm2m: check engine context before accessing it
Signed-off-by: Robert Chou <robert.ch.chou@acer.com>
2017-11-06 20:49:31 +02:00
Robert Chou
44995e2de0 net: lwm2m: replace coap_next_block() w/ coap_update_from_block()
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>
2017-11-02 10:02:45 +02:00
Robert Chou
a37f049e6d net: lwm2m: break the opaque write loop early when fail
As title, check the return value from the write callback and break if
an error is returned

Signed-off-by: Robert Chou <robert.ch.chou@acer.com>
2017-11-02 10:01:40 +02:00
Michael Scott
353be4cd58 net: lwm2m: propagate errors from post_write callbacks
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>
2017-10-31 09:41:27 +02:00
Michael Scott
febcf5317b net: lwm2m: fix OPAQUE handling in LwM2M engine
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>
2017-10-31 09:41:27 +02:00
Michael Scott
f32815a8d5 net: lwm2m: expose lwm2m_engine_get_resource() for lwm2m subsys
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>
2017-10-31 09:41:27 +02:00
Michael Scott
7fa099b67e net: lwm2m: remove unused len var from lwm2m_engine_get()
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>
2017-10-31 09:41:27 +02:00
Michael Scott
dd95dbcd9e net: lwm2m: introduce getter/setter for OPAQUE data
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>
2017-10-31 09:41:27 +02:00
Michael Scott
b37a005d68 net: lwm2m: add multi fragment support to LwM2M library
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>
2017-10-31 09:41:27 +02:00
Michael Scott
dd364efc58 net: lwm2m: share BUF_ALLOC_TIMEOUT setting w/ other lwm2m components
Signed-off-by: Michael Scott <michael.scott@linaro.org>
2017-10-31 09:41:27 +02:00
Robert Chou
be825dca1e net: lwm2m: handle format application/octet-stream w/ plain_text
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>
2017-10-31 09:32:07 +02:00
Michael Scott
a4ab36bcbd net: lwm2m: add periodic service registration to engine
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>
2017-10-26 09:29:42 +03:00
Michael Scott
022d805cc2 net: lwm2m: replace instances of s*printf with snprintk
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>
2017-10-26 09:23:19 +03:00
Michael Scott
ebe3660308 net: lwm2m: fix Leshan discover OP
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>
2017-10-26 09:20:40 +03:00