Skip to content

gRPC API differences from C APIs

PALASH KHARE edited this page Apr 6, 2022 · 4 revisions

Signal APIs

Some C APIs accepts size of output array as an input parameter, for example nxReadSignalWaveform

nxStatus_t _NXFUNC nxReadSignalWaveform (
    nxSessionRef_t SessionRef,
    f64 Timeout,
    nxTimestamp100ns_t * StartTime,
    f64 * DeltaTime,
    f64 * ValueBuffer,
    u32 SizeOfValueBuffer,
     u32 * NumberOfValuesReturned
);

Here SizeOfValueBuffer is passed to the C API after allocating memory for the respective output arrays with that value.

In gRPC API these parameters are not present, instead these are calculated internally by the gRPC API and those are passed to the underlying C API call.

For example, the gRPC API definition for ReadSignalWaveform is

message ReadSignalWaveformRequest {
  nidevice_grpc.Session session = 1;
  oneof timeout_enum {
    TimeOut timeout = 2;
    double timeout_raw = 3;
  }
  uint32 samples_per_signal = 4;
  uint32 number_of_signals = 5;
}

Here two new parameters are added which are samples_per_signal and number_of_signals because the client already knows the number of signals in the session and samples_per_signal indicates the number of samples per signal user wants in the output array. Internally the gRPC API calculates the output array size as (samples_per_signals * number_of_signals) and allocates the output array with this value.

Similar thing is applicable to the following signal APIs

  • ReadSignalSinglePoint
  • ReadSignalXY
  • ConvertFramesToSignalSinglePoint

C APIs having void* parameters

Note: Parameters which accept size for the corresponding void* parameter are removed from the gRPC APIs. Those are calculated internally by gRPC API and provided to the underlying C API.

  • All APIs that accept or return void* have been updated in gRPC to return structured message with separate fields in message for each piece of information. For e.g. APIs that accept or return Frame object as void* instead return a FrameBuffer message which uses oneof to return frame based on interface being used for reading the frame. The FrameBuffer message looks like
        message FrameBufferRequest {
            oneof frame {
                FrameRequest can = 1;
                FrameRequest lin = 2;
                FrameRequest flex_ray = 3;
                FrameRequest j1939 = 4;
                EnetFrameRequest enet = 5;
            }
        }

Each Frame* message contains fields appropriate for specific frame.

        message FrameRequest {
            uint64 timestamp = 1;
            uint32 identifier = 2;
            oneof type_enum{
                FrameType type = 3;
                uint32 type_raw = 4;
            }
            repeated FrameFlags flags = 5;
            uint32 info = 6;
            bytes payload = 7;
        }
  • ReadState/WriteState have been modified on similar lines to return structured message instead of returning void* messages. In ReadState API where return value is u32 containing bitfields for several pieces of information, gRPC response returns contains these bitfields in separate fields of the message. For e.g. if want to read nxState_CANComm, instead of return u32 value like C API, gRPC API return below message.
    message CanCommResponse {
        CanCommState comm_state = 1;
        uint32 comm_state_raw = 2;
        uint32 transceiver_error = 3;
        uint32 sleep = 4;
        CanLastErr last_error = 5;
        uint32 last_error_raw = 6;
        uint32 transmit_error_counter = 7;
        uint32 receive_error_counter = 8;
    }
  • Get/Set APIs have also been modified on similar lines. Based on datatypes of different PropertyIDs, oneof fields are used in request/response message. For example
    message GetPropertyResponse {
        int32 status = 1;
        oneof property_value {
            uint32 u32_scalar = 2;
            bool bool_scalar = 3;
            string str = 4;
            uint64 u64_scalar = 5;
            int32 i32_scalar = 6;
            double f64_scalar = 7;
            string string_array = 8;
            U32Array u32_array = 9;
            nidevice_grpc.Session db_ref = 10;
            DbRefArray db_ref_array = 11;
            nidevice_grpc.Session dev_ref = 12;
            DeviceRefArray dev_ref_array = 13;
            InterfaceRefArray intf_ref_array = 14;
            EptRxFilterArray ept_rx_filter_array = 15;
        }
    }
  • For the void* parameters which accepts structs in C Socket APIs, the gRPC equivalent has been implemented with oneof or union types. For example
    message SockAddr {
        oneof addr {
            SockAddrIn ipv4 = 1;
            SockAddrIn6 ipv6 = 2;
        }
    }

Error reporting in Socket APIs

The nxsocket API uses a thread-local get_last_error implementation as they're primary mechanism for error reporting. Even the error code must be retrieved with nxgetlasterrornum. This does not work when split into multiple service calls. Therefore GetLastError method is made private in xnetsocket and an additional parameter for getting last error is added with each of the gRPC socket APIs. For example

message AcceptResponse {
  int32 status = 1;
  SockAddr addr = 2;
  nidevice_grpc.Session socket = 3;
  string error_message = 4;
  int32 error_num = 5;
}

Table of Contents

Internal Development

Creating and Setting Up a gRPC Server

Server Security Support

Creating a gRPC Client

gRPC Client Examples

Session Utilities API Reference

Driver Documentation

gRPC API Differences From C API

Sharing Driver Sessions Between Clients

Getting started with moniker based streaming
C API Docs
NI-DAQmx
NI-DCPOWER
NI-DIGITAL PATTERN DRIVER
NI-DMM
NI-FGEN
NI-FPGA
NI-RFmx Bluetooth
NI-RFmx NR
NI-RFmx WCDMA
NI-RFmx GSM
NI-RFmx CDMA2k
NI-RFmx Instr
NI-RFmx LTE
NI-RFmx SpecAn
NI-RFmx TD-SCDMA
NI-RFmx WLAN
NI-RFSA
NI-RFSG
NI-SCOPE
NI-SWITCH
NI-TCLK
NI-XNET
Clone this wiki locally