4.1. Initialize Anjay client

4.1.1. Project structure

Create the following directory layout for your client project:

example/
  ├── CMakeLists.txt
  └── src/
      └── main.c

Note

All code found in this tutorial is available under examples/tutorial/BC* in Anjay source directory. Each tutorial project follows the same project directory layout.

4.1.2. Configure the build system

Create a CMakeLists.txt file in the root of your project directory with the following content:

cmake_minimum_required(VERSION 3.16)
project(anjay-bc-initialization C)

set(CMAKE_C_STANDARD 99)
set(CMAKE_C_EXTENSIONS OFF)

add_compile_options(-Wall -Wextra)

find_package(anjay REQUIRED)

add_executable(${PROJECT_NAME} src/main.c)
target_link_libraries(${PROJECT_NAME} PRIVATE anjay)

This file configures the CMake build system to compile your client and link it with the Anjay library.

4.1.3. Implement the Hello World client

Create a main.c file in the src/ directory with the following content:

#include <anjay/anjay.h>
#include <avsystem/commons/avs_log.h>

int main(int argc, char *argv[]) {
    if (argc != 2) {
        avs_log(tutorial, ERROR, "usage: %s ENDPOINT_NAME", argv[0]);
        return -1;
    }

    const anjay_configuration_t CONFIG = {
        .endpoint_name = argv[1],
        .in_buffer_size = 4000,
        .out_buffer_size = 4000,
        .msg_cache_size = 4000
    };

    anjay_t *anjay = anjay_new(&CONFIG);
    if (!anjay) {
        avs_log(tutorial, ERROR, "Could not create Anjay object");
        return -1;
    }

    anjay_event_loop_run(anjay, avs_time_duration_from_scalar(1, AVS_TIME_S));

    anjay_delete(anjay);
    return 0;
}

Note

Complete code of this example can be found in examples/tutorial/BC-Initialization subdirectory of main Anjay project repository.

Code explanation:

Note

We recommend you to look at the doxygen generated API documentation if something isn’t immediately clear to you.

First, we call the anjay_new() function that initializes the client. It needs to be passed an anjay_configuration_t structure that contains basic runtime configuration of the client.

The example code above configures the basic values that are most essential:

  • endpoint_name sets the Endpoint Client Name - see Clients and servers.

  • in_buffer_size and out_buffer_size control sizes of the buffers used for network communication.

  • msg_cache_size sets the size of the message cache - this is not strictly necessary for the client to work, but it is used to internally cache responses so that retransmitted packets are properly handled as duplicates. The bigger this buffer, the older packets the library will be able to detect as retransmissions.

After initializing the library, anjay_event_loop_run() is called. This function doesn’t return unless there is a fatal error, instead acting as the main loop of the LwM2M client.

In more complicated applications, this function would typically be run in a dedicated thread, while other threads would perform tasks not directly related to LwM2M and communicate with the LwM2M thread when necessary.

Important

If you intend to run Anjay event loop in a dedicated thread, please make sure that the code is properly synchronized. The WITH_THREAD_SAFETY and WITH_SCHEDULER_THREAD_SAFE compile-time configuration options may be helpful in achieving this goal.

The second argument specifies the maximum time for which the loop is allowed to wait for incoming events in a single iteration - 1 second in this example. The shorter the time, the more responsive the loop will be in handling asynchronous requests (e.g. jobs scheduled from another threads), but the average CPU usage level of the main loop may be higher.

In case the event loop finishes, anjay_delete() - a function that cleans up all resources used by the client - is called.

4.1.4. Build and run the client

In your project directory, build the client:

$ cmake . && make

If the build succeeds, you can run the client. Provide an endpoint name as an argument. When the communication with the server takes place later in the project this will be a name that the client uses to identify itself to the server. Please look into the brief description of LwM2M for details on recommended formats of the endpoint name.

At this point, you can use the local hostname to simulate an endpoint name:

$ ./anjay-bc-initialization urn:dev:os:$(hostname)

Important

Project will not be configured successfully until you install Anjay library, see Compiling client applications for details how to do it.

You will see only some logs and the application will appear to freeze - that’s because without any server configuration, there are no tasks to do. However, if you do not see “Could not create Anjay object” there, then Anjay was properly initialized.

The connection to the LwM2M Server will be described in the next steps.