=title Extensible IOC Database Links

The extensible link mechanism allows new kinds of record links to be created,
using JSON for the link address syntax.
The IOC continues to support the older link types that do not use JSON to
specify their link addresses.

The following additional link types are available in this release:

=over

=item * L<Constant|/"Constant Link const">

=item * L<Calc|/"Calculation Link calc">

=item * L<dbState|/"dbState Link state">

=item * L<Debug|/"Debug Link debug">

=item * L<Trace|/"Trace Link trace">

=back

=head2 Using JSON Links

When setting a record link field to a JSON link address, the link specification
must appear inside a pair of braces C< {} > expressed as a JSON5 (L<JavaScript
Object Notation|https://spec.json5.org/>) object, which allows link parameters
to be defined as needed by the particular link type. When link fields are set in
an IOC database file, the field value may take advantage of the JSON5 syntax to
reduce the number of double-quote characters required.


=head2 Link Type Reference

=cut


link(const, lnkConstIf)

=head3 Constant Link C<"const">

Constant links are input links that provide literal values at link initialization
time, but do not return any data when their C<getValue()> routine is called.
Most record types support the use of constant links on their input links by
calling C<recGblInitConstantLink()> at record initialization, which results in
the constant value being loaded into the target field at that time.

Note that for most record types (the C<printf> and C<calcout> records are the
main exceptions) it is pointless to set an input link to a constant link at
runtime since the link initialization that loads the field value usually only
happens when a record is initialized. A constant link that is embedded inside
another input link type such as a calculation link should be OK though since the
link initialization will take place when the record's field gets set.

=head4 Parameters

A const link takes a parameter which may be an integer, double or string, or an
array of those types. If an array contains both integers and double values the
integers will be promoted to doubles. Mixing strings and numbers in an array
results in an error.

=head4 Examples

 {const: 3.14159265358979}
 {const: "Pi"}
 {const: [1, 2.718281828459, 3.14159265358979]}
 {const: ["One", "e", "Pi"]}
 {const:[Inf, -Inf]})

The newer JSON5 syntax supports Infinity values when parsing numbers, so it is
no longer necessary to quote these in a string, although that still works:

 field(INP, {const:"Inf"})

=cut


link(calc, lnkCalcIf)

=head3 Calculation Link C<"calc">

A calculation link is an input link that can evaluate mathematical expressions
on scalar (double-precision floating-point) values obtained from up to 21 child
input links, and returns a double-precision floating-point result. The
expression is evaluated by the EPICS Calc engine, and the result is returned as
the value of the link.

Since 7.0.10 the number of inputs has been increased from 12 to 21.

Two additional expressions may also be provided and are evaluated to determine
whether the record owning the link should be placed in alarm state. In both
cases the result of the main calculation is available to these expressions as
C<VAL> (attempts to assign to C<VAL> inside either expression will have no
lasting effect). If the C<major> expression evaluates to a non-zero value the
record will be placed in C<LINK/MAJOR> alarm. If not and the C<minor> expression
evaluates to non-zero the record will be placed in C<LINK/MINOR> alarm state.

A calculation link can also be an output link, with the scalar output value
being converted to a double and provided to the expression as C<VAL>. Up to 21
additional input links can also be read and provided to the expression as above.
The result of the calculation is forwarded to a child output link specified in
the link's C<out> parameter.

For an output link the main expression is actually optional; if not provided the
converted value will be forwarded to the output link unchanged. The two alarm
expressions may still be used to put the output link into alarm state as
described above.

=head4 Parameters

The link address is a JSON map with the following keys:

=over

=item expr

The primary expression to be evaluated, given as a string.
This is optional for output links, required for input links.

=item major

An optional expression that returns non-zero to raise a major alarm.

=item minor

An optional expression that returns non-zero to raise a minor alarm.

=item args

A JSON list of up to 24 input arguments for the expression, which are assigned
to the inputs C<A>, C<B>, C<C>, ... C<U>. Each input argument may be either a
numeric literal or an embedded JSON link inside C<{}> braces. A C<pva> link
could provide values from another record in this or other IOCs if built in, but
the built-in non-JSON CA or DB link types are not supported. The same input
values are provided to the two alarm expressions as to the primary expression.

=item out

A JSON link inside C<{}> braces which specifies the destination of C<putValue>
operations after any expressions have been evaluated.
This key is required for output links, not used by input links.

=item units

An optional string specifying the engineering units for the result of the
expression. Equivalent to the C<EGU> field of a record.

=item prec

An optional integer specifying the numeric precision with which the calculation
result should be displayed. Equivalent to the C<PREC> field of a record.

=item time

An optional string containing a single upper or lower-case letter C<A> ... C<U>
which must correspond to an input provided in the C<args> parameter. When the
record containing such a link has C<TSEL> set to -2 (epicsTimeEventDeviceTime)
the record's timestamp field C<TIME> will be read from the indicated input link
atomically with the value of the input argument.

=back

=head4 Example

 {calc: {expr:"A*B", args:[{pva:"record"}, 1.5], prec:3}}

=cut


link(state, lnkStateIf)

=head3 dbState Link C<"state">

A dbState link is one that gets or puts a boolean value from/to a named global
flag as implemented by the dbState facility in C<dbstate.h>. The link type can
invert the sense of the dbState flag during the get or put if desired.

The value of the named flag is read or written at the time of the link I/O
operation. When reading a flag, the value returned by the link will be zero or
one converted to the requested data type. When writing to a flag the boolean
value of the data written is determined in the originating data type. All
strings are regarded as true other than C<""> and C<"0"> which are both false.

A link can be configured to invert the sense of the flag data by putting an
exclamation mark C<!> before the first character of the flag's name in the link
address.

These dbState flags can be accessed from the IOC Shell with various dbState
commands, and are also used by the C<"sync"> Channel-Access server-side filter
mechanism.

=head4 Parameters

The link takes a single parameter which must be a string, providing the name of
the dbState object, with an optional leading C<!> character to indicate that the
flag's value should be inverted. The dbState object will be created when the
link is initialized if it doesn't already exist.

=head4 Examples

 {state:"redBeam"}
 {state:"!simEnable"}

=cut


link(debug, lnkDebugIf)
variable(lnkDebug_debug, int)

=head3 Debug Link C<"debug">

The debug link type exists to enable debugging of other link types; it provides
no functionality itself other than to turn on the debug flag for the child link
that is its only parameter and pass all link operations down to that link.

=head4 Example

 {debug:{state:"redBeam"}}

=cut


link(trace, lnkTraceIf)

=head3 Trace Link C<"trace">

The trace link type is a relative of the debug link type that also traces the
operation of its child link. At creation it turns on the debug flag of its child
link, then it prints the method arguments and return values of all link
operations before / after passing control down to the child link.

=head4 Example

 {trace:{state:"redBeam"}}

=cut
