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_onboard.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

The functions in this library can return either positive or negative return values.

Negative values are standard device-side errors defined in errno.h. These indicate a failure to send the request to the cloud for various reasons, such as the device is not connected to the cloud or the request contains invalid parameters.

Positive values are cloud-side errors (CoAP result codes). These indicate the cloud received the request but rejected it. This can occur either because of the request itself or because of a cloud-side error. See the specific result code for details. These are defined in zephyr/net/coap.h.

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, an error number. Negative values are device-side errors defined in errno.h. Positive values are cloud-side errors (CoAP result codes) defined in zephyr/net/coap.h.

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.

Returns:

0 If successful. Positive values are cloud-side errors (CoAP result codes) defined in zephyr/net/coap.h.

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.

Returns:

0 If successful, nonzero if failed. Negative values are device-side errors defined in errno.h. Positive values are cloud-side errors (CoAP result codes) defined in zephyr/net/coap.h.

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

Send a sensor value to nRF Cloud.

The sensor message is sent either as a non-confirmable or confirmable CoAP message. Use non-confirmable when sending low priority information for which some data loss is acceptable.

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

  • value[in] Sensor reading.

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

  • confirmable[in] Select whether to use a CON or NON CoAP transfer.

Returns:

0 If successful, nonzero if failed. Negative values are device-side errors defined in errno.h. Positive values are cloud-side errors (CoAP result codes) defined in zephyr/net/coap.h.

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

Send a message to nRF Cloud.

The JSON or CBOR message is sent either as a non-confirmable or confirmable CoAP message. Use non-confirmable when sending low priority information for which some data loss is acceptable.

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.

  • confirmable[in] Select whether to use a CON or NON CoAP transfer.

Returns:

0 If successful, nonzero if failed. Negative values are device-side errors defined in errno.h. Positive values are cloud-side errors (CoAP result codes) defined in zephyr/net/coap.h.

int nrf_cloud_coap_json_message_send(const char *message, bool bulk, bool confirmable)

Send a preencoded JSON message to nRF Cloud.

The JSON message is sent either as a non-confirmable or confirmable CoAP message. Use non-confirmable when sending low priority information for which some data loss is acceptable.

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

  • bulk[in] Set true if message is an array of JSON messages to be sent to the bulk topic.

  • confirmable[in] Select whether to use a CON or NON CoAP transfer.

Returns:

0 If successful, nonzero if failed. Negative values are device-side errors defined in errno.h. Positive values are cloud-side errors (CoAP result codes) defined in zephyr/net/coap.h.

int nrf_cloud_coap_location_send(const struct nrf_cloud_gnss_data *const gnss, bool confirmable)

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

The location message is sent as either a non-confirmable or 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.

  • confirmable[in] Select whether to use a CON or NON CoAP transfer.

Returns:

0 If successful, nonzero if failed. Negative values are device-side errors defined in errno.h. Positive values are cloud-side errors (CoAP result codes) defined in zephyr/net/coap.h.

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 successful, nonzero if failed. Negative values are device-side errors defined in errno.h. Positive values are cloud-side errors (CoAP result codes) defined in zephyr/net/coap.h.

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 successful, nonzero if failed. Negative values are device-side errors defined in errno.h. Positive values are cloud-side errors (CoAP result codes) defined in zephyr/net/coap.h.

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 successful, nonzero if failed. Negative values are device-side errors defined in errno.h. Positive values are cloud-side errors (CoAP result codes) defined in zephyr/net/coap.h.

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 successful, nonzero if failed. Negative values are device-side errors defined in errno.h. Positive values are cloud-side errors (CoAP result codes) defined in zephyr/net/coap.h.

int nrf_cloud_coap_shadow_state_update(const char *const shadow_json)

Update the device’s “reported state” in the shadow through the state/update CoAP resource. This is used both to report the current state of the device as well as to accept settings changes received in a shadow delta.

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

Returns:

0 If successful, nonzero if failed. Negative values are device-side errors defined in errno.h. Positive values are cloud-side errors (CoAP result codes) defined in zephyr/net/coap.h.

int nrf_cloud_coap_shadow_desired_update(const char *const shadow_json)

Update the device’s “desired state” in the shadow through the state/desired CoAP resource. Normally, this is only used to silence a shadow delta that is incompatible with the device, by overwriting the invalid desired values with the reported values.

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

Returns:

0 If successful, nonzero if failed. Negative values are device-side errors defined in errno.h. Positive values are cloud-side errors (CoAP result codes) defined in zephyr/net/coap.h.

int nrf_cloud_coap_shadow_device_status_update(const struct nrf_cloud_device_status *const dev_status)

Update the device status in the shadow’s reported state section.

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

Returns:

0 If successful, nonzero if failed. Negative values are device-side errors defined in errno.h. Positive values are cloud-side errors (CoAP result codes) defined in zephyr/net/coap.h.

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 successful, nonzero if failed. Negative values are device-side errors defined in errno.h. Positive values are cloud-side errors (CoAP result codes) defined in zephyr/net/coap.h.

int nrf_cloud_coap_shadow_delta_process(const struct nrf_cloud_data *in_data, struct nrf_cloud_obj *const delta_out)

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.

If application-specific delta data exists, it will be provided in delta_out.

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

  • delta_out[out] A pointer to a structure that contains application-specific delta data.

Return values:
  • -ENOMSG – Error decoding input data.

  • 0 – Success, no application-specific delta data.

  • 1 – Success, application-specific delta data exists. Caller is responsible for the memory in delta_out; free with nrf_cloud_obj_free.

int nrf_cloud_coap_bytes_send(uint8_t *buf, size_t buf_len, bool confirmable)

Send raw bytes to nRF Cloud.

Parameters:
  • buf[in] buffer with binary string.

  • buf_len[in] length of buf in bytes.

  • confirmable[in] Select whether to use a CON or NON CoAP transfer.

Returns:

0 If successful, nonzero if failed. Negative values are device-side errors defined in errno.h. Positive values are cloud-side errors (CoAP result codes) defined in zephyr/net/coap.h.

int nrf_cloud_coap_obj_send(struct nrf_cloud_obj *const obj, bool confirmable)

Send an nRF Cloud object.

This only supports sending of the CoAP CBOR or JSON type objects or a pre-encoded CBOR buffer. If the object is actually an array of JSON objects, it will be sent to the d2c/bulk topic, otherwise all other documents are sent to the d2c topic. See the nrf_cloud_obj_bulk_init() function.

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

  • confirmable[in] Select whether to use a CON or NON CoAP transfer.

Returns:

0 If successful, nonzero if failed. Negative values are device-side errors defined in errno.h. Positive values are cloud-side errors (CoAP result codes) defined in zephyr/net/coap.h.