5.6.7. Bootstrap awareness
In this tutorial you will learn how to setup Resources writable only by the LwM2M Bootstrap Server.
5.6.7.1. Handling LwM2M Bootstrap Server
LwM2M Bootstrap Server is an unusual entity: it is allowed to modify Instances and Resources not accessible to “regular” LwM2M Servers. That is useful for setting up sensitive data that servers should not change (or even read) during normal operation of the device - DTLS keys or certificates, for example.
Whenever a LwM2M Bootstrap Server sends a Bootstrap Write request, Anjay uses
the same instance_create and resource_write handlers as for “regular”
LwM2M Server operations. The only difference is that Anjay ignores the
operations declared through the kind argument to anjay_dm_emit_res()
calls inside the list_resources handler for bootstrap requests, allowing
Bootstrap Server to do anything it wants.
If a device has to implement a Resource that must only be writable by the LwM2M Bootstrap Server, its handlers should be implemented like so:
resource_writehandler must be able to set the value of a Resource, as if it was a writable one,list_resourceshandler should pass akindargument that does not allow writing toanjay_dm_emit_res(). That will prevent Anjay from calling theresource_writehandler for this particular Resource when the request is issued by a non-bootstrap server.
5.6.7.2. Example: bootstrap-writable Resource
As an example, we will modify the Test Object from
Multi-instance writable object with fixed number of instances to prevent changing the value of Label
Resource by non-bootstrap servers:
Name  | 
Object ID  | 
Instances  | 
|---|---|---|
Test object  | 
1234  | 
Multiple  | 
Each Object Instance has two Resources:
Name  | 
Resource ID  | 
Operations  | 
Instances  | 
Mandatory  | 
Type  | 
|---|---|---|---|---|---|
Label  | 
0  | 
Read  | 
Single  | 
Mandatory  | 
String  | 
Value  | 
1  | 
Read/Write  | 
Single  | 
Mandatory  | 
Integer  | 
To achieve that, we need to update the test_list_resources handler so that
it disallows writing to Resource 0:
static int test_list_resources(anjay_t *anjay,
                               const anjay_dm_object_def_t *const *obj_ptr,
                               anjay_iid_t iid,
                               anjay_dm_resource_list_ctx_t *ctx) {
    // ...
    // only allow reading Resource 0 by LwM2M Servers
    // this will be ignored for LwM2M Bootstrap Server
    anjay_dm_emit_res(ctx, 0, ANJAY_DM_RES_R, ANJAY_DM_RES_PRESENT);
    // Value Resource can be read/written by LwM2M Servers
    anjay_dm_emit_res(ctx, 1, ANJAY_DM_RES_RW, ANJAY_DM_RES_PRESENT);
    return 0;
}
That leaves one more issue with the example project: it has a pre-configured
LwM2M Server that is not a bootstrap one. Changing it to a LwM2M Bootstrap
Server is a matter of setting bootstrap_server = true on
anjay_security_instance_t struct when initializing the Security Object:
const anjay_security_instance_t security_instance = {
    .ssid = 1,
    .bootstrap_server = true,
    .server_uri = "coap://eu.iot.avsystem.cloud:5693",
    .security_mode = ANJAY_SECURITY_NOSEC
};
It is worth noting that the LwM2M Bootstrap Server has only a Security Object instance and no Server Object instances. For that reason, the example project deliberately does not initialize any Server Object Instances.
Note
Complete code of this example can be found in examples/tutorial/AT-CustomObjects/bootstrap-awareness subdirectory of main Anjay project repository.