nRF Cloud

The nRF Cloud library enables applications to connect to Nordic Semiconductor’s nRF Cloud. It abstracts and hides the details of the transport and the encoding scheme that is used for the payload and provides a simplified API interface for sending data from supported sensor types to the cloud. The current implementation supports the following technologies:

  • GPS and FLIP sensor data

  • TLS secured MQTT as the communication protocol

  • JSON as the data format

Initializing

Before using any other APIs of the module, the application must call nrf_cloud_init(). If this API fails, the application must not use any APIs of the module.

Note

Initialize the module before starting any timers, sensor drivers, or communication on the link.

Connecting

The application can use nrf_cloud_connect() to connect to the cloud. This API triggers a series of events and actions in the system. If the API fails, the application must retry to connect. If the CONFIG_NRF_CLOUD_CONNECTION_POLL_THREAD Kconfig option is enabled, an nRF Cloud library thread monitors the connection socket. When CONFIG_NRF_CLOUD_CONNECTION_POLL_THREAD is enabled, an additional event, NRF_CLOUD_EVT_TRANSPORT_CONNECTING, is sent to the application. The status field of nrf_cloud_evt contains the connection status that is defined by nrf_cloud_connect_result. The event NRF_CLOUD_EVT_TRANSPORT_DISCONNECTED also contains additional information in the status field that is defined by nrf_cloud_disconnect_status. See Connecting to the Cloud for additional information on CONFIG_NRF_CLOUD_CONNECTION_POLL_THREAD. When the poll thread option is used directly with the nRF Cloud library, the enumeration values are prefixed with NRF.

First, the library tries to establish the transport for communicating with the cloud. This procedure involves a TLS handshake that might take up to three seconds. The API blocks for the duration of the handshake.

The cloud uses the certificates of the device for authentication. See Updating the nRF Cloud certificate and the Modem key management library for more information on modem credentials. The certificates are generated using the device ID and PIN or HWID. The device ID is also the MQTT client ID. There are multiple configuration options for the device or client ID. See Configuration options for device ID for more information.

As the next step, the API subscribes to an MQTT topic to start receiving user association requests from the cloud.

Every time nRF Cloud starts a communication session with a device, it verifies whether the device is uniquely associated with a user. If not, the user association procedure is triggered. When adding the device to an nRF Cloud account, the user must provide the correct device ID and PIN (for Thingy:91 and custom hardware) or HWID (for nRF9160 DK) to nRF Cloud.

The following message sequence chart shows the flow of events and the expected application responses to each event during the user association procedure:

msc {
hscale = "1.3";
Module,Application;
Module<<Application      [label="nrf_cloud_connect() returns successfully"];
Module>>Application      [label="NRF_CLOUD_EVT_TRANSPORT_CONNECTED"];
Module>>Application      [label="NRF_CLOUD_EVT_USER_ASSOCIATION_REQUEST"];
 ---                     [label="Add the device to nRF Cloud account"];
Module>>Application      [label="NRF_CLOUD_EVT_USER_ASSOCIATED"];
Module<<Application      [label="nrf_cloud_disconnect() returns successfully"];
Module>>Application      [label="NRF_CLOUD_EVT_TRANSPORT_DISCONNECTED"];
Module<<Application      [label="nrf_cloud_connect() returns successfully"];
Module>>Application      [label="NRF_CLOUD_EVT_TRANSPORT_CONNECTED"];
Module>>Application      [label="NRF_CLOUD_EVT_USER_ASSOCIATED"];
Module>>Application      [label="NRF_CLOUD_EVT_READY"];
}

The chart shows the sequence of successful user association of an unassociated device.

Note

Currently, nRF Cloud requires that communication is re-established to update the device’s permission to send user data. The application must disconnect using nrf_cloud_disconnect() and then reconnect using nrf_cloud_connect().

When the device is successfully associated with a user on the cloud, subsequent connections to the cloud (also across power cycles) occur in the following sequence:

msc {
hscale = "1.3";
Module,Application;
Module<<Application      [label="nrf_cloud_connect() returns successfully"];
Module>>Application      [label="NRF_CLOUD_EVT_TRANSPORT_CONNECTED"];
Module>>Application      [label="NRF_CLOUD_EVT_USER_ASSOCIATED"];
Module>>Application      [label="NRF_CLOUD_EVT_READY"];
}

After receiving NRF_CLOUD_EVT_READY, the application can start sending sensor data to the cloud.

Configuration options for device ID

Firmware over-the-air (FOTA) updates

The nRF Cloud library supports FOTA updates for your nRF9160-based device. When the library is included by the application, the CONFIG_NRF_CLOUD_FOTA option is enabled by default, and the FOTA functionality is made available to the application.

For FOTA updates to work, the device must provide the information about the supported FOTA types to nRF Cloud. The device passes this information by writing a fota_v2 field containing an array of FOTA types into the serviceInfo field in the device’s shadow. nrf_cloud_service_info_json_encode() can be used to generate the proper JSON data to enable FOTA. Additionally, nrf_cloud_shadow_device_status_update() can be used to generate the JSON data and perform the shadow update.

Following are the three supported FOTA types:

  • APP

  • MODEM

  • BOOT

For example, a device that supports all the FOTA types writes the following data into the device shadow:

{
"state": {
   "reported": {
      "device": {
         "serviceInfo": {
            "fota_v2": [
            "APP",
            "MODEM",
            "BOOT"
            ]
}}}}}

You can initiate FOTA updates through nRF Cloud or by using the nRF Cloud Device API. When the device receives the NRF_CLOUD_EVT_FOTA_DONE event, the application must perform any necessary cleanup, as a reboot will be initiated to complete the update. The message payload of the NRF_CLOUD_EVT_FOTA_DONE event contains the nrf_cloud_fota_type value. If the value equals NRF_CLOUD_FOTA_MODEM, the application can optionally avoid a reboot by performing reinitialization of the modem and calling the nrf_cloud_modem_fota_completed() function.

Sending sensor data

The library offers two APIs, nrf_cloud_sensor_data_send() and nrf_cloud_sensor_data_stream() (lowest QoS), for sending sensor data to the cloud.

To view sensor data on nRF Cloud, the device must first inform the cloud what types of sensor data to display. The device passes this information by writing a ui field, containing an array of sensor types, into the serviceInfo field in the device’s shadow. nrf_cloud_service_info_json_encode() can be used to generate the proper JSON data to enable FOTA. Additionally, nrf_cloud_shadow_device_status_update() can be used to generate the JSON data and perform the shadow update.

Following are the supported UI types on nRF Cloud:

  • GPS

  • FLIP

  • TEMP

  • HUMIDITY

  • AIR_PRESS

  • RSRP

Using Cloud API with nRF Cloud library

You can use this library in conjunction with Cloud API. The following sections describe the various stages in the process of connection to nRF Cloud.

Initialization

To use a defined Cloud API backend, a binding must be obtained using the Cloud API function cloud_get_binding(), to which you can pass the name of the desired backend. The nRF Cloud library defines the Cloud API backend as NRF_CLOUD via the CLOUD_BACKEND_DEFINE macro.

The backend must be initialized using the cloud_init() function, with the binding, and a function pointer to user-defined Cloud API event handler as parameters. If cloud_init() returns success, the backend is ready for use. The return values for a failure scenario of the cloud_init() function are described below for the nRF Cloud backend:

  • -EACCES - Invalid state. Already initialized.

  • -EINVAL - Invalid event handler provided.

  • -ENOMEM - Error building MQTT topics. The given client ID of the device could be too long.

Note

If CONFIG_NRF_CLOUD_PROVISION_CERTIFICATES is enabled, error values could be different or have different error descriptions.

Connecting to the Cloud

The nRF Cloud library offers two ways to handle backend connections when the cloud_connect() function is called. If you enable the CONFIG_NRF_CLOUD_CONNECTION_POLL_THREAD Kconfig option, a cloud backend thread monitors the connection socket. If you disable the option, the user application must monitor the socket.

The dual functionalities of the cloud_connect() function in the two scenarios are described below:

Connected to the Cloud

When the device connects to the cloud successfully, the Cloud API dispatches a CLOUD_EVT_CONNECTED event. If the device is not associated with an nRF Cloud account, a CLOUD_EVT_PAIR_REQUEST event is generated. The device must wait until it is added to an account, which is indicated by the CLOUD_EVT_PAIR_DONE event. If a device pair request is received, the device must disconnect and reconnect after receiving the CLOUD_EVT_PAIR_DONE event. This is necessary because the updated policy of the cloud becomes effective only on a new connection. Following the CLOUD_EVT_PAIR_DONE event, the Cloud API sends a CLOUD_EVT_READY event to indicate that the cloud is ready to receive data from the device.

Disconnection from the Cloud

The user application can generate a disconnect request with the cloud_disconnect() function. A successful disconnection is indicated by the CLOUD_EVT_DISCONNECTED event. The err field in the event message is set to CLOUD_DISCONNECT_USER_REQUEST. If an unexpected disconnect event is received, the err field contains the cause. If CONFIG_NRF_CLOUD_CONNECTION_POLL_THREAD is not enabled, the only cause of disconnection is CLOUD_DISCONNECT_MISC. The user application must use the connection socket to determine a reason.

The following events can cause disconnection if the backend thread is monitoring the socket:

Location services

nRF Cloud offers location services that allow you to obtain the location of your device. The following enhancements to this library can be used to interact with nRF Cloud Location Services:

API documentation

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

Defines

IS_VALID_USER_TAG(tag)
NRF_CLOUD_SETTINGS_NAME
NRF_CLOUD_FOTA_VER
NRF_CLOUD_FOTA_VER_STR
NRF_CLOUD_STAGE_ID_MAX_LEN
NRF_CLOUD_TENANT_ID_MAX_LEN
NRF_CLOUD_CLIENT_ID_MAX_LEN

Typedefs

typedef void (*nrf_cloud_event_handler_t)(const struct nrf_cloud_evt *evt)

Event handler registered with the module to handle asynchronous events from the module.

Parameters
  • evt[in] The event and any associated parameters.

Enums

enum nrf_cloud_evt_type

Asynchronous nRF Cloud events notified by the module.

Values:

enumerator NRF_CLOUD_EVT_TRANSPORT_CONNECTED

The transport to the nRF Cloud is established.

enumerator NRF_CLOUD_EVT_TRANSPORT_CONNECTING

In the process of connecting to nRF Cloud.

enumerator NRF_CLOUD_EVT_USER_ASSOCIATION_REQUEST

There was a request from nRF Cloud to associate the device with a user on the nRF Cloud.

enumerator NRF_CLOUD_EVT_USER_ASSOCIATED

The device is successfully associated with a user.

enumerator NRF_CLOUD_EVT_READY

The device can now start sending sensor data to the cloud.

enumerator NRF_CLOUD_EVT_RX_DATA

The device received data from the cloud.

enumerator NRF_CLOUD_EVT_SENSOR_DATA_ACK

The data sent to the cloud was acknowledged.

enumerator NRF_CLOUD_EVT_TRANSPORT_DISCONNECTED

The transport was disconnected.

enumerator NRF_CLOUD_EVT_FOTA_DONE

The device should be restarted to apply a firmware upgrade

enumerator NRF_CLOUD_EVT_ERROR

There was an error communicating with the cloud.

enum nrf_cloud_disconnect_status

@ nRF Cloud disconnect status.

Values:

enumerator NRF_CLOUD_DISCONNECT_USER_REQUEST
enumerator NRF_CLOUD_DISCONNECT_CLOSED_BY_REMOTE
enumerator NRF_CLOUD_DISCONNECT_INVALID_REQUEST
enumerator NRF_CLOUD_DISCONNECT_MISC
enumerator NRF_CLOUD_DISCONNECT_COUNT
enum nrf_cloud_connect_result

@ nRF Cloud connect result.

Values:

enumerator NRF_CLOUD_CONNECT_RES_SUCCESS
enumerator NRF_CLOUD_CONNECT_RES_ERR_NOT_INITD
enumerator NRF_CLOUD_CONNECT_RES_ERR_INVALID_PARAM
enumerator NRF_CLOUD_CONNECT_RES_ERR_NETWORK
enumerator NRF_CLOUD_CONNECT_RES_ERR_BACKEND
enumerator NRF_CLOUD_CONNECT_RES_ERR_MISC
enumerator NRF_CLOUD_CONNECT_RES_ERR_NO_MEM
enumerator NRF_CLOUD_CONNECT_RES_ERR_PRV_KEY
enumerator NRF_CLOUD_CONNECT_RES_ERR_CERT
enumerator NRF_CLOUD_CONNECT_RES_ERR_CERT_MISC
enumerator NRF_CLOUD_CONNECT_RES_ERR_TIMEOUT_NO_DATA
enumerator NRF_CLOUD_CONNECT_RES_ERR_ALREADY_CONNECTED
enum nrf_cloud_sensor

Sensor types supported by the nRF Cloud.

Values:

enumerator NRF_CLOUD_SENSOR_GPS

The GPS sensor on the device.

enumerator NRF_CLOUD_SENSOR_FLIP

The FLIP movement sensor on the device.

enumerator NRF_CLOUD_SENSOR_BUTTON

The Button press sensor on the device.

enumerator NRF_CLOUD_SENSOR_TEMP

The TEMP sensor on the device.

enumerator NRF_CLOUD_SENSOR_HUMID

The Humidity sensor on the device.

enumerator NRF_CLOUD_SENSOR_AIR_PRESS

The Air Pressure sensor on the device.

enumerator NRF_CLOUD_SENSOR_AIR_QUAL

The Air Quality sensor on the device.

The RSPR data obtained from the modem.

enumerator NRF_CLOUD_DEVICE_INFO

The descriptive DEVICE data indicating its status.

enumerator NRF_CLOUD_SENSOR_LIGHT

The light sensor on the device.

enum nrf_cloud_topic_type

Topic types supported by nRF Cloud.

Values:

enumerator NRF_CLOUD_TOPIC_STATE

Endpoint used to update the cloud-side device shadow state .

enumerator NRF_CLOUD_TOPIC_MESSAGE

Endpoint used to directly message the nRF Cloud Web UI.

enum nrf_cloud_fota_status

FOTA status reported to nRF Cloud.

Values:

enumerator NRF_CLOUD_FOTA_QUEUED
enumerator NRF_CLOUD_FOTA_IN_PROGRESS
enumerator NRF_CLOUD_FOTA_FAILED
enumerator NRF_CLOUD_FOTA_SUCCEEDED
enumerator NRF_CLOUD_FOTA_TIMED_OUT
enumerator NRF_CLOUD_FOTA_CANCELED
enumerator NRF_CLOUD_FOTA_REJECTED
enumerator NRF_CLOUD_FOTA_DOWNLOADING
enum nrf_cloud_fota_type

FOTA update type.

Values:

enumerator NRF_CLOUD_FOTA_TYPE__FIRST
enumerator NRF_CLOUD_FOTA_APPLICATION

Application update.

enumerator NRF_CLOUD_FOTA_MODEM

Modem update.

enumerator NRF_CLOUD_FOTA_BOOTLOADER

Bootloader update.

enumerator NRF_CLOUD_FOTA_TYPE__INVALID
enum nrf_cloud_shadow_info

How the info sections are handled when encoding shadow data.

Values:

enumerator NRF_CLOUD_INFO_NO_CHANGE

Data will not be modified

enumerator NRF_CLOUD_INFO_SET

Data will be set/updated

enumerator NRF_CLOUD_INFO_CLEAR

Data section will be cleared

Functions

int nrf_cloud_init(const struct nrf_cloud_init_param *param)

Initialize the module.

Warning

This API must be called prior to using nRF Cloud and it must return successfully.

Parameters
  • param[in] Initialization parameters.

Returns

  • 0 – If successful.

  • -EACCES – Already initialized or nrf_cloud_uninit is in progress. Otherwise, a (negative) error code is returned.

int nrf_cloud_uninit(void)

Uninitialize nRF Cloud; disconnects cloud connection and cleans up allocated memory.

Note

If nRF Cloud FOTA is enabled and a FOTA job is active uninit will not be performed.

Returns

  • 0 – If successful.

  • -EBUSY – If a FOTA job is in progress. Otherwise, a (negative) error code is returned.

int nrf_cloud_connect(const struct nrf_cloud_connect_param *param)

Connect to the cloud.

In any stage of connecting to the cloud, an NRF_CLOUD_EVT_ERROR might be received. If it is received before NRF_CLOUD_EVT_TRANSPORT_CONNECTED, the application may repeat the call to nrf_cloud_connect to try again.

Parameters
  • param[in] Parameters to be used for the connection.

Returns

Connect – result defined by enum nrf_cloud_connect_result.

int nrf_cloud_sensor_data_send(const struct nrf_cloud_sensor_data *param)

Send sensor data reliably.

This API should only be called after receiving an NRF_CLOUD_EVT_READY event. If the API succeeds, you can expect the NRF_CLOUD_EVT_SENSOR_DATA_ACK event for data sent with a valid tag value.

Parameters
  • param[in] Sensor data; the data pointed to by param->data.ptr must be a string.

Returns

  • 0 – If successful.

  • -EACCES – Cloud connection is not established; wait for NRF_CLOUD_EVT_READY. Otherwise, a (negative) error code is returned.

int nrf_cloud_shadow_update(const struct nrf_cloud_sensor_data *param)

Update the device shadow with sensor data.

Parameters
  • param[in] Sensor data; the data pointed to by param->data.ptr must be a valid JSON string.

Returns

  • 0 – If successful.

  • -EACCES – Cloud connection is not established; wait for NRF_CLOUD_EVT_READY. Otherwise, a (negative) error code is returned.

int nrf_cloud_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 successful.

  • -EACCES – Cloud connection is not established; wait for NRF_CLOUD_EVT_READY. Otherwise, a (negative) error code is returned.

int nrf_cloud_sensor_data_stream(const struct nrf_cloud_sensor_data *param)

Stream sensor data. Uses lowest QoS; no acknowledgment,.

This API should only be called after receiving an NRF_CLOUD_EVT_READY event.

Parameters
  • param[in] Sensor data; tag value is ignored.

Returns

  • 0 – If successful.

  • -EACCES – Cloud connection is not established; wait for NRF_CLOUD_EVT_READY. Otherwise, a (negative) error code is returned.

int nrf_cloud_send(const struct nrf_cloud_tx_data *msg)

Send data to nRF Cloud.

This API is used to send pre-encoded data to nRF Cloud.

Parameters
  • msg[in] Pointer to a structure containting data and topic information.

Returns

  • 0 – If successful.

  • -EACCES – Cloud connection is not established; wait for NRF_CLOUD_EVT_READY. Otherwise, a (negative) error code is returned.

int nrf_cloud_disconnect(void)

Disconnect from the cloud.

This API may be called any time after receiving the NRF_CLOUD_EVT_TRANSPORT_CONNECTED event. If the API succeeds, you can expect the NRF_CLOUD_EVT_TRANSPORT_DISCONNECTED event.

Returns

void nrf_cloud_process(void)

Function that must be called periodically to keep the module functional.

int nrf_cloud_modem_fota_completed(const bool fota_success)

The application has handled re-init after a modem FOTA update and the LTE link has been re-established. This function must be called in order to complete the modem update.

Parameters
  • fota_success[in] true if modem update was successful, false otherwise.

Returns

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

int nrf_cloud_service_info_json_encode(const struct nrf_cloud_svc_info *const svc_inf, cJSON *const svc_inf_obj)

Add service info into the provided cJSON object.

Parameters
  • svc_inf[in] Service info to add.

  • svc_inf_obj[inout] cJSON object to which service info will be added.

Returns

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

int nrf_cloud_modem_info_json_encode(const struct nrf_cloud_modem_info *const mod_inf, cJSON *const mod_inf_obj)

Add modem info into the provided cJSON object.

Note

To add modem info, CONFIG_MODEM_INFO must be enabled.

Parameters
  • mod_inf[in] Modem info to add.

  • mod_inf_obj[inout] cJSON object to which modem info will be added.

Returns

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

int nrf_cloud_client_id_get(char *id_buf, int id_len)

Function to retrieve the current device ID.

Parameters
  • id_buf[inout] Buffer to receive the device ID.

  • id_len[in] Size of buffer (NRF_CLOUD_CLIENT_ID_MAX_LEN).

Returns

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

int nrf_cloud_tenant_id_get(char *id_buf, int id_len)

Function to retrieve the current customer tenant ID.

Parameters
  • id_buf[inout] Buffer to receive the tenant ID.

  • id_len[in] Size of buffer (NRF_CLOUD_TENANT_ID_MAX_LEN).

Returns

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

struct nrf_cloud_fota_job_info
#include <nrf_cloud.h>

Common FOTA job info.

Public Members

char *id

Null-terminated FOTA job identifier

struct nrf_cloud_data
#include <nrf_cloud.h>

Generic encapsulation for any data that is sent to the cloud.

Public Members

uint32_t len

Length of the data.

const void *ptr

Pointer to the data.

struct nrf_cloud_topic
#include <nrf_cloud.h>

MQTT topic.

Public Members

uint32_t len

Length of the topic.

const void *ptr

Pointer to the topic.

struct nrf_cloud_sensor_list
#include <nrf_cloud.h>

Sensors that are supported by the device.

Public Members

uint8_t size

Size of the list.

enum nrf_cloud_sensor *ptr

Supported sensor types.

struct nrf_cloud_connect_param
#include <nrf_cloud.h>

Connection parameters.

Public Members

const struct nrf_cloud_sensor_list *sensor

Supported sensor types. May be NULL.

struct nrf_cloud_sensor_data
#include <nrf_cloud.h>

Sensor data transmission parameters.

Public Members

enum nrf_cloud_sensor type

The sensor that is the source of the data.

struct nrf_cloud_data data

Sensor data to be transmitted.

uint16_t tag

Unique tag to identify the sent data. Can be used to match acknowledgment on the NRF_CLOUD_EVT_SENSOR_DATA_ACK event. Valid range: NCT_MSG_ID_USER_TAG_BEGIN to NCT_MSG_ID_USER_TAG_END. Any other value will suppress the NRF_CLOUD_EVT_SENSOR_DATA_ACK event.

struct nrf_cloud_evt
#include <nrf_cloud.h>

Asynchronous events received from the module.

Public Members

enum nrf_cloud_evt_type type

The event that occurred.

uint32_t status

Any status associated with the event.

struct nrf_cloud_data data

Received data.

struct nrf_cloud_topic topic

Topic on which data was received.

struct nrf_cloud_tx_data
#include <nrf_cloud.h>

Structure used to send pre-encoded data to nRF Cloud.

Public Members

struct nrf_cloud_data data

Data that is to be published.

enum nrf_cloud_topic_type topic_type

Endpoint topic type published to.

enum mqtt_qos qos

Quality of Service of the message.

struct nrf_cloud_svc_info_fota
#include <nrf_cloud.h>

Controls which values are added to the FOTA array in the “serviceInfo” shadow section.

struct nrf_cloud_svc_info_ui
#include <nrf_cloud.h>

Controls which values are added to the UI array in the “serviceInfo” shadow section.

Public Members

uint8_t temperature

Items with UI support on nRF Cloud

uint8_t air_quality

Items without UI support on nRF Cloud

struct nrf_cloud_modem_info
#include <nrf_cloud.h>

Modem info data and which sections should be encoded.

struct nrf_cloud_svc_info
#include <nrf_cloud.h>

Structure to specify which components are added to the encoded service info object.

Public Members

struct nrf_cloud_svc_info_fota *fota

Specify FOTA components to enable, set to NULL to remove the FOTA entry

struct nrf_cloud_svc_info_ui *ui

Specify UI components to enable, set to NULL to remove the UI entry

struct nrf_cloud_device_status
#include <nrf_cloud.h>

Structure to specify which components are added to the encoded device status object.

Public Members

struct nrf_cloud_modem_info *modem

Specify which modem info components to include, set to NULL to skip

struct nrf_cloud_svc_info *svc

Specify which service info components to include, set to NULL to skip

struct nrf_cloud_init_param
#include <nrf_cloud.h>

Initialization parameters for the module.

Public Members

nrf_cloud_event_handler_t event_handler

Event handler that is registered with the module.

char *client_id

NULL-terminated MQTT client ID string. Must not exceed NRF_CLOUD_CLIENT_ID_MAX_LEN. Must be set if NRF_CLOUD_CLIENT_ID_SRC_RUNTIME is enabled; otherwise, NULL.