nRF Cloud CoAP

This library is an enhancement to the nRF Cloud library. It enables applications to communicate with nRF Cloud using the nRF Cloud CoAP service. This service uses UDP network packets, encrypted using DTLS, containing compact data encoded using CBOR. This service is lighter weight than MQTT or REST and consumes less power on the device and uses less data bandwidth.

Overview

This library provides an API for CoAP-based applications to send requests to and receive responses from nRF Cloud. Like the REST API for nRF Cloud, CoAP is client-driven. The server cannot initiate transfers to the device. Instead, the device must periodically poll for relevant information.

Polling functions

The following functions poll for externally created information:

The nrf_cloud_coap_shadow_get() function returns 0 whether there is a delta or not. Set the delta parameter to true to request the delta. The underlying CoAP result code 2.05 and an empty payload indicate that there is no delta. If there is a pending delta, the function returns result code 2.05 and a payload in JSON format. When the delta parameter is set to false, the whole current delta state section is returned and it can be quite large.

If there is a pending job, the nrf_cloud_coap_fota_job_get() function returns 0 and updates the job structure. If there is no pending job, the function returns -ENOMSG.

Supported features

This library supports the following nRF Cloud services:

Requirements

You must first preprovision the device on nRF Cloud as follows:

  1. Use the device_credentials_installer.py and nrf_cloud_provision.py scripts.

  2. Specify the --coap option to device_credentials_installer.py to have the proper root CA certificates installed in the device.

Call the nrf_cloud_coap_init() function once to initialize the library. Connect the device to LTE before calling the nrf_cloud_coap_connect() function.

Configuration

Configure the CONFIG_NRF_CLOUD_COAP option to enable or disable the use of this library.

Additionally, the following Kconfig options are available:

Finally, configure these recommended additional options:

Usage

To use this library, complete the following steps:

  1. Include the nrf_cloud_coap.h file.

  2. Call the nrf_cloud_coap_init() function once to initialize the library.

  3. Connect the device to an LTE network.

  4. Call the nrf_cloud_coap_connect() function to connect to nRF Cloud and obtain authorization to access services.

  5. Once your device is successfully connected to nRF Cloud, call any of the other functions declared in the header file to access services.

  6. Disconnect from LTE when your device does not need cloud services for a long period (for example, most of a day).

  7. Call the nrf_cloud_coap_disconnect() function to close the network socket, which frees resources in the modem.

Samples using the library

The following nRF Connect SDK samples use this library:

Limitations

For CoAP-based applications, communications will not be as reliable for all nRF Cloud services as when using MQTT or REST. This is a fundamental aspect of the way CoAP works over UDP compared to TCP.

The loss of the LTE connection or closing of the network socket will result in loss of the session information for DTLS inside the modem. The device must first call nrf_cloud_coap_disconnect(), and then nrf_cloud_coap_connect() once the LTE connection has been restored. This will result in a new full handshake of the DTLS connection and the need to re-establish authentication with the server.

Due to the same limitations in the modem, a call to nrf_cloud_coap_disconnect() followed by a subsequent call to nrf_cloud_coap_connect() will require a full DTLS handshake and reauthentication. This is true whether or not the LTE connection is intact.

References

Dependencies

This library uses the following nRF Connect SDK library:

It uses the following Zephyr libraries:

API documentation

Header file: include/net/nrf_cloud_coap.h
Source files: subsys/net/lib/nrf_cloud/src/nrf_cloud_coap.c
group nrf_cloud_coap

Functions

int nrf_cloud_coap_init(void)

Initialize nRF Cloud CoAP library.

Returns:

0 if initialization was successful, otherwise, a negative error number.

int nrf_cloud_coap_connect(const char *const app_ver)

Connect to and obtain authorization to access the nRF Cloud CoAP server.

This function must return 0 indicating success so that the other functions below, other than nrf_cloud_coap_disconnect(), will not immediately return an error when called.

Parameters:
  • app_ver – Version to report to the shadow; can be NULL.

Returns:

0 if authorized successfully, otherwise, a negative error number.

int nrf_cloud_coap_pause(void)

Pause CoAP connection.

This function temporarily pauses the nRF Cloud CoAP connection so that another DTLS socket can be opened and used. Once the new socket is no longer needed, close it and use nrf_cloud_coap_resume() to resume using CoAP. Do not call nrf_cloud_coap_disconnect() nor shut down the LTE connection, or the requisite data for the socket will be discarded in the modem, and the connection cannot be resumed. In that case, call nrf_cloud_coap_connect(), which results in a full DTLS handshake.

Return values:
  • -EACCES – if DTLS CID was not active or the connection was not authenticated.

  • -EAGAIN – if an error occurred while saving the connection; it is still usable.

  • -EINVAL – if the operation could not be performed.

  • -ENOMEM – if too many connections are already saved (four).

  • 0 – If successful.

int nrf_cloud_coap_resume(void)

Resume CoAP connection.

This function restores a previous connection for use.

Return values:
  • -EACCES – if the connection was not previously paused.

  • -EAGAIN – if an error occurred while loading the connection.

  • -EINVAL – if the operation could not be performed.

  • 0 – If successful.

int nrf_cloud_coap_disconnect(void)

Disconnect the nRF Cloud CoAP connection.

This does not teardown the thread in coap_client, as there is no way to do so. The thread’s call to poll(sock) will fail, resulting in an error message. This is expected. Call nrf_cloud_coap_connect() to re-establish the connection, and the thread in coap_client will resume.

Returns:

0 if the socket was closed successfully, or a negative error number.

int nrf_cloud_coap_agnss_data_get(struct nrf_cloud_rest_agnss_request const *const request, struct nrf_cloud_rest_agnss_result *result)

Request nRF Cloud CoAP Assisted GNSS (A-GNSS) data.

Parameters:
  • request[in] Data to be provided in API call.

  • result[inout] Structure pointing to caller-provided buffer in which to store A-GNSS data.

Return values:
  • -EINVAL – will be returned, and an error message printed, if invalid parameters are given.

  • -ENOENT – will be returned if there was no A-GNSS data requested for the specified request type.

  • -ENOBUFS – will be returned, and an error message printed, if there is not enough buffer space to store retrieved A-GNSS data.

  • 0 – If successful.

int nrf_cloud_coap_pgps_url_get(struct nrf_cloud_rest_pgps_request const *const request, struct nrf_cloud_pgps_result *file_location)

Request URL for nRF Cloud Predicted GPS (P-GPS) data.

After a successful call to this function, pass the file_location to nrf_cloud_pgps_update(), which then downloads and processes the file’s binary P-GPS data.

Parameters:
  • request[in] Data to be provided in API call.

  • file_location[inout] Structure that will contain the host and path to the prediction file.

Return values:

0 – If successful. Otherwise, a (negative) error code is returned.

int nrf_cloud_coap_sensor_send(const char *app_id, double value, int64_t ts_ms)

Send a sensor value to nRF Cloud.

The CoAP message is sent as a non-confirmable CoAP message.

Parameters:
  • app_id[in] The app_id identifying the type of data. See the values in nrf_cloud_defs.h that begin with NRF_CLOUD_JSON_APPID_. You may also use custom names.

  • value[in] Sensor reading.

  • ts_ms[in] Timestamp the data was measured, or NRF_CLOUD_NO_TIMESTAMP.

Return values:

0 – If successful. Otherwise, a (negative) error code is returned.

int nrf_cloud_coap_message_send(const char *app_id, const char *message, bool json, int64_t ts_ms)

Send a message string to nRF Cloud.

The CoAP message is sent as a non-confirmable CoAP message.

Parameters:
  • app_id[in] The app_id identifying the type of data. See the values in nrf_cloud_defs.h that begin with NRF_CLOUD_JSON_APPID_. You may also use custom names.

  • message[in] The string to send.

  • json[in] Set true if the data should be sent in JSON format, otherwise CBOR.

  • ts_ms[in] Timestamp the data was measured, or NRF_CLOUD_NO_TIMESTAMP.

Return values:

0 – If successful. Otherwise, a (negative) error code is returned.

int nrf_cloud_coap_json_message_send(const char *message)

Send a preencoded JSON message to nRF Cloud.

The CoAP message is sent as a non-confirmable CoAP message.

Parameters:
  • message[in] The string to send.

Return values:

0 – If successful. Otherwise, a (negative) error code is returned.

int nrf_cloud_coap_location_send(const struct nrf_cloud_gnss_data *const gnss)

Send the device location in the nrf_cloud_gnss_data PVT field to nRF Cloud.

The CoAP message is sent as a non-confirmable CoAP message. Only NRF_CLOUD_GNSS_TYPE_PVT is supported.

Parameters:
  • gnss[in] A pointer to an nrf_cloud_gnss_data struct indicating the device location, usually as determined by the GNSS unit.

Return values:

0 – If successful. Otherwise, a (negative) error code is returned.

int nrf_cloud_coap_location_get(struct nrf_cloud_rest_location_request const *const request, struct nrf_cloud_location_result *const result)

Request device location from nRF Cloud.

At least one of cell_info or wifi_info must be provided within the request.

Parameters:
  • request[in] Data to be provided in API call.

  • result[inout] Location information.

Returns:

0 if the request succeeded, a positive value indicating a CoAP result code, or a negative error number.

int nrf_cloud_coap_fota_job_get(struct nrf_cloud_fota_job_info *const job)

Request current nRF Cloud FOTA job info for the specified device.

Parameters:
  • job[out] Parsed job info. If no job exists, type will be set to invalid. If a job exists, user must call nrf_cloud_coap_fota_job_free to free the memory allocated by this function.

Returns:

0 if the request succeeded, a positive value indicating a CoAP result code, or a negative error number.

void nrf_cloud_coap_fota_job_free(struct nrf_cloud_fota_job_info *const job)

Free memory allocated by nrf_cloud_coap_current_fota_job_get().

Parameters:
  • job[inout] Job info to be freed.

int nrf_cloud_coap_fota_job_update(const char *const job_id, const enum nrf_cloud_fota_status status, const char *const details)

Update the status of the specified nRF Cloud FOTA job.

Parameters:
  • job_id[in] Null-terminated FOTA job identifier.

  • status[in] Status of the FOTA job.

  • details[in] Null-terminated string containing details of the job, such as an error description.

Returns:

0 if the request succeeded, a positive value indicating a CoAP result code, or a negative error number.

int nrf_cloud_coap_shadow_get(char *buf, size_t buf_len, bool delta)

Query the device’s shadow delta.

If there is no delta, the return value will be 0 and the length of the string stored in buf will be 0.

Parameters:
  • buf[inout] Pointer to memory in which to receive the delta.

  • buf_len[in] Size of buffer.

  • delta[in] True to request only changes in the shadow, if any; otherwise, all of desired part.

Returns:

0 if the request succeeded, a positive value indicating a CoAP result code, or a negative error number.

int nrf_cloud_coap_shadow_state_update(const char *const shadow_json)

Update the device’s “state” in the shadow via the UpdateDeviceState endpoint.

Parameters:
  • shadow_json[in] Null-terminated JSON string to be written to the device’s shadow.

Returns:

0 if the request succeeded, a positive value indicating a CoAP result code, or a negative error number.

int nrf_cloud_coap_shadow_device_status_update(const struct nrf_cloud_device_status *const dev_status)

Update the device status in the shadow.

Parameters:
  • dev_status[in] Device status to be encoded.

Returns:

0 if the request succeeded, a positive value indicating a CoAP result code, or a negative error number.

int nrf_cloud_coap_shadow_service_info_update(const struct nrf_cloud_svc_info *const svc_inf)

Update the device’s “serviceInfo” in the shadow.

Parameters:
  • svc_inf[in] Service info items to be updated in the shadow.

Returns:

0 if the request succeeded, a positive value indicating a CoAP result code, or a negative error number.

int nrf_cloud_coap_shadow_delta_process(const struct nrf_cloud_data *in_data)

Process any elements of the shadow relevant to this library.

One such element is the control section, which specifies the log level and turns alerts on and off.

Parameters:
  • in_data[in] A pointer to a structure with the length and a pointer to the delta received.

Returns:

0 if the request succeeded, a positive value indicating a CoAP result code, or a negative error number.

int nrf_cloud_coap_obj_send(struct nrf_cloud_obj *const obj)

Send an nRF Cloud object.

This only supports sending of the CoAP CBOR or JSON type or a pre-encoded CBOR buffer.

Parameters:
  • obj[in] An nRF Cloud object. Will be encoded first if obj->enc_src is NRF_CLOUD_ENC_SRC_NONE.

Returns:

0 if the request succeeded, a positive value indicating a CoAP result code, or a negative error number.