YANG Data Nodes
This section describes the basic design of a YANG data tree that represents instances of various object nodes that the client or the server can create.
Data Trees
A YumaPro data tree is a representation of some subset of all possible object instances that a server is maintaining within a configuration database or other structure.
Each data tree starts with a 'root' container, and any child nodes represent top-level YANG module data nodes that exist within the server.
Each configuration database maintains its own copy (and version) of the data tree. There is only one object tree, however, and all data trees use the same object tree for reference.
Not all object types have a corresponding node within a data tree. Only 'real' data nodes are present. Object nodes that are used as meta-data to organize the object tree (E.g., choice, augment) are not present. The following table lists the object types and whether each one is found in a data tree.
Object Types in the Data Tree
OBJ_TYP_ANYXML |
Yes |
OBJ_TYP_CONTAINER |
Yes |
OBJ_TYP_CONTAINER (ncx:root) |
Yes |
OBJ_TYP_LEAF |
Yes |
OBJ_TYP_LEAF_LIST |
Yes |
OBJ_TYP_LIST |
Yes |
OBJ_TYP_CHOICE |
No |
OBJ_TYP_CASE |
No |
OBJ_TYP_USES |
No |
OBJ_TYP_REFINE |
No |
OBJ_TYP_AUGMENT |
No |
OBJ_TYP_RPC |
No |
OBJ_TYP_RPCIO |
No |
OBJ_TYP_NOTIF |
No |
Child Data Nodes
The design used for the storage of child nodes has changed over time.
Old Design
New Design
The old design required the entire child list to be searched when adding a new entry.
The new design uses a queue of object headers. First the correct object header is found, then the instance of that object is found. YANG lists are now stored in an AVL tree (using libdict hb_tree).
The server will maintain the order or instances given in the <edit-config> or startup configuration. It will maintain YANG schema order so the objects will be returned in the correct order according to the YANG module.
The val_set_index_chain function MUST be called before val_add_child for a list
Sometimes server or SIL code creates data. In order to create a list, the following steps must be followed
Create the list node, e.g., with val_new_value()
Create the key leafs and add them to the parent with val_child_add
Create the list index chain with val_gen_index_chain
Add the list node to its parent with val_child_add
-
status_t val_child_add(val_value_t *child, val_value_t *parent)
Add a child value node to a parent value node.
Replaces val_add_child
- Parameters:
child -- node to store in the parent
parent -- complex value node with a child header Q
- Returns:
status; node is only added if status is NO_ERR
-
status_t val_child_add_force(val_value_t *child, val_value_t *parent)
Add a child value node to a parent value node Force add even if Tree Insersion fails.
- Parameters:
child -- node to store in the parent
parent -- complex value node with a child header Q
- Returns:
status; node is only added if status is NO_ERR
-
status_t val_child_insert(val_value_t *child, val_value_t *current, val_value_t *parent, op_insertop_t insert_op)
Insert a child value node into a parent value node before or after the specified node.
- Parameters:
child -- node to store in the parent
current -- last node that was stored in the parent (may be NULL)
parent -- complex value node with a childQ
insert_op -- insert operation enum (first, last, before, after)
- Returns:
status
Data Node Types
The 'ncx_btype_t' enumeration in ncx/ncxtypes.h
is used within
each val_value_t to quickly identify which variant of the data node
structure is being used.
ncx_btype_t
-
enum ncx_btype_t
enumeration of the built-in NCX types These types cannot be overridden and cannot be imported
Values:
-
enumerator NCX_BT_NONE
No type has been set yet.
The val_new_value() function has been called but no specific init function has been called to set the base type.
-
enumerator NCX_BT_ANY
The node is a YANG 1.0 'anyxml' node.
Type is deprecated. Use anydata instead.
When the client or server parses an 'anyxml' object, it will be converted to containers and strings.
This type should not be used directly.
WIll be converted to (or replaced by) a container
-
enumerator NCX_BT_BITS
YANG bits data type.
Uses ncx_list_t (string list) for implementation
-
enumerator NCX_BT_ENUM
YANG enumeration data type.
Uses enum name string in implementation
The 'value' number is not currently used
-
enumerator NCX_BT_EMPTY
YANG empty data type.
Uses boolean always set to true in implementation
If boolean set to false then may not mean not-present
-
enumerator NCX_BT_BOOLEAN
YANG boolean data type.
Uses boolean in implementation
-
enumerator NCX_BT_INT8
YANG int8 data type.
Uses int32 in implementation
-
enumerator NCX_BT_INT16
YANG int16 data type.
Uses int32 in implementation
-
enumerator NCX_BT_INT32
YANG int32 data type.
Uses int32 in implementation
-
enumerator NCX_BT_INT64
YANG int64 data type.
Uses int64 in implementation
-
enumerator NCX_BT_UINT8
YANG uint8 data type.
Uses int32 in implementation
-
enumerator NCX_BT_UINT16
YANG uint16 data type.
Uses int32 in implementation
-
enumerator NCX_BT_UINT32
YANG uint32 data type.
Uses int32 in implementation
-
enumerator NCX_BT_UINT64
YANG uint64 data type.
Uses uint64 in implementation
-
enumerator NCX_BT_DECIMAL64
YANG decimal64 data type.
Uses struct in implementation
-
enumerator NCX_BT_FLOAT64
Hidden double type, used just for XPath.
If the HAS_FLOAT define is false, then this type will be implemented as a string, not a double.
-
enumerator NCX_BT_STRING
YANG 'string' type.
There are also some YumaPro extensions that are used with this data type for special strings.
The server needs to know if a string contains XML prefixes or not, and there are several flavors to automatate processing of each one correctly.
-
enumerator NCX_BT_BINARY
YANG binary data type.
Uses struct in implementation
YANG uses base64 encoding for binary strings
-
enumerator NCX_BT_INSTANCE_ID
YANG instance-identifier data type.
Uses xpath:1.0 string in implementation
-
enumerator NCX_BT_UNION
YANG 'union' data type.
This is a meta-type.
When the client or server parses a value, it will resolve the union to one of the data types defined within the union.
An unresolved union will use the string type
-
enumerator NCX_BT_LEAFREF
YANG 'leafref' data type.
This is a meta-type.
The client or server will resolve this data type to the type of the actual 'pointed-at' leaf that is being referenced.
-
enumerator NCX_BT_IDREF
YANG identityref data type.
Uses struct in implementation, pointer to ncx_identity_t
YANG uses qualified-name encoding for identityref strings
The standards are not clear how to encode identityref in all protocols
-
enumerator NCX_BT_SLIST
ncx:xsdlist extension (internal, deprecated)
uses ncx_list_t, not limited to string sub-type
supports deprecated ncx:xsdlist string
-
enumerator NCX_BT_CONTAINER
YANG container node.
Used internally to give the val_value_t a data type
-
enumerator NCX_BT_CHOICE
YANG choice.
This is a meta-type and placeholder.
It does not appear in the data tree.
Not really used!
-
enumerator NCX_BT_CASE
YANG case.
This is a meta-type and placeholder.
It does not appear in the data tree.
Not really used!
-
enumerator NCX_BT_LIST
YANG list instance node.
Used internally to give the val_value_t a data type
-
enumerator NCX_BT_ANYDATA
The node is a YANG 1.1 'anydata' node.
When the client or server parses an 'anydata' object, it will be converted to containers and strings.
This type should not be used directly.
WIll be converted to (or replaced by) a container
-
enumerator NCX_BT_EXTERN
Internal 'external' data type, used in server and yangcli-pro.
It indicates that the content is actually in an external file.
Not a real type, points fo file for contents
-
enumerator NCX_BT_INTERN
Internal 'buffer' data type, used in server and yangcli-pro.
The content is actually stored verbatim in an internal buffer.
Not a real type, string buffer for contents.
-
enumerator NCX_BT_NONE
The following table describes the different enumeration values:
YumaPro Data Types (ncx_btype_t)
NCX_BT_NONE |
No type has been set yet. The val_new_value() function has been called but no specific init function has been called to set the base type. |
NCX_BT_ANY |
The node is a YANG 'anyxml' node. When the client or server parses an 'anyxml' object, it will be converted to containers and strings. This type should not be used directly. |
NCX_BT_BITS |
YANG 'bits' data type |
NCX_BT_ENUM |
YANG 'enumeration' data type |
NCX_BT_EMPTY |
YANG 'empty' data type |
NCX_BT_BOOLEAN |
YANG 'boolean' data type |
NCX_BT_INT8 |
YANG 'int8' data type |
NCX_BT_INT16 |
YANG 'int16' data type |
NCX_BT_INT32 |
YANG 'int32' data type |
NCX_BT_INT64 |
YANG 'int64' data type |
NCX_BT_UINT8 |
YANG 'uint8' data type |
NCX_BT_UINT16 |
YANG 'uint16' data type |
NCX_BT_UINT32 |
YANG 'uint32' data type |
NCX_BT_UINT64 |
YANG 'uint64' data type |
NCX_BT_DECIMAL64 |
YANG 'decimal64' data type |
NCX_BT_FLOAT64 |
Hidden double type, used just for XPath. If the HAS_FLOAT #define is false, then this type will be implemented as a string, not a double. |
NCX_BT_STRING |
YANG 'string' type. There are also some YumaPro extensions that are used with this data type for special strings. The server needs to know if a string contains XML prefixes or not, and there are several flavors to automate processing of each one correctly. |
NCX_BT_BINARY |
YANG 'binary' data type |
NCX_BT_INSTANCE_ID |
YANG 'instance-identifier' data type |
NCX_BT_UNION |
YANG 'union' data type. This is a meta-type. When the client or server parses a value, it will resolve the union to one of the data types defined within the union. |
NCX_BT_LEAFREF |
YANG 'leafref' data type. This is a meta-type. The client or server will resolve this data type to the type of the actual 'pointed-at' leaf that is being referenced. |
NCX_BT_IDREF |
YANG 'identityref' data type |
NCX_BT_SLIST |
XSD list data type (ncx:xsdlist extension) |
NCX_BT_CONTAINER |
YANG container |
NCX_BT_CHOICE |
YANG choice. This is a meta-type and placeholder. It does not appear in the data tree. |
NCX_BT_CASE |
YANG case. This is a meta-type and placeholder. It does not appear in the data tree. |
NCX_BT_LIST |
YANG list |
NCX_BT_EXTERN |
Internal 'external' data type, used in yangcli-pro. It indicates that the content is actually in an external file. |
NCX_BT_INTERN |
Internal 'buffer' data type, used in yangcli-pro. The content is actually stored verbatim in an internal buffer. |
YumaPro Data Node Edit Variables (val_editvars_t)
There is a temporary data structure which is attached to a data node
while editing operations are in progress, called "val_editvars_t".
This structure is used by the functions in agt/agt_val.c
to
manipulate the value tree nodes during an <edit-config>,
<copy-config>, <load-config>, or <commit> operation.
The SIL callback functions may wish to refer to the fields in this data structure. There is also a SIL cookie field to allow data to be transferred from one callback stage to the later stages. For example, if an edit operation caused the device instrumentation to reserve some memory, then this cookie could store that pointer.
The following typedef is used to define the val_editvars_t structure:
-
struct val_editvars_t
one set of edit-in-progress variables for one value node
Public Members
-
struct val_value_t_ *curparent
these fields are only used in modified values before they are actually added to the config database (TBD: move into struct) curparent == parent of curnode for merge
track the real parent
-
op_insertop_t insertop
YANG insert operation.
-
xmlChar *insertstr
saved value or key attr
-
struct xpath_pcb_t_ *insertxpcb
key attr for insert
-
struct val_value_t_ *insertval
back-ptr if before or after
-
val_insert_mode_t insert_mode
insert mode requested
-
uint8 silprio
2nd SIL priority for server
-
boolean operset
nc:operation here
-
void *pcookie
user pointer cookie
-
int icookie
user integer cookie
-
boolean is_move
TRUE if YPATCH MOVE operation.
-
boolean skip_sil_partial
TRUE if skip_sil_partial needed.
-
boolean deleted
TRUE if deleted from commit_deletes.
-
struct val_value_t_ *curparent
The following fields within the 'val_editvars_t' are highlighted:
val_editvars_t Fields
curparent |
A 'new' node will use this field to remember the parent of the 'current' value. This is needed to support the YANG insert operation. |
editop |
The effective edit operation for this node. |
insertop |
The YANG insert operation, if any. |
insertstr |
The YANG 'value' or 'key' attribute value string, used to support the YANG insert operation. |
insertxpcb |
XPath parser control block for the insert 'key' expression, if needed. Used to support the YANG insert operation. |
insertval |
Back pointer to the value node to insert ahead of, or behind, if needed. Used to support the 'before' and 'after' modes of the YANG insert operation. |
iskey |
TRUE if this is a key leaf. FALSE otherwise. |
operset |
TRUE if there was an nc:operation attribute found in this node; FALSE if the 'editop' is derived from its parent. |
pcookie |
SIL user pointer cookie. Not used by the server. Reserved for SIL callback code. |
icookie |
SIL user integer cookie. Not used by the server. Reserved for SIL callback code. |
val_value_t
The val_value_t data structure is used to maintain the internal representation of all NETCONF databases, non-configuration data available with the <get> operation, all RPC operation input and output parameters, and all notification contents.
Warning
Do not access fields directly! Use val.h macros or access functions in val.h and val_util.h
The following typedef is used to define a value node:
-
struct val_value_t
one value to match one type
Public Members
-
dlq_hdr_t qhdr
queue header to insert in dlq_hdr list
-
struct obj_template_t_ *obj
common fields
bptr to object def
-
typ_def_t *typdef
bptr to typdef if leaf
-
const xmlChar *name
back pointer to elname
the dname field is moved to
val_extra_t and only used when the value is constructed from dummy objects or no objects at all
-
struct val_value_t_ *parent
back-ptr to parent if any
-
struct val_child_hdr_t_ *hdr
back-ptr to own child_hdr
-
val_extra_t *val_extra
val extra fields only needed about 25% of the time
-
uint32 flags
internal status flags
-
xmlns_id_t nsid
namespace ID for this node
-
ncx_btype_t btyp
base type of this value
-
ncx_data_class_t dataclass
config or state data
-
time_t last_modified
last_modified and etag fields used for filtered retrieval and YANG-API If-Match type of conditional editing
-
ncx_etag_t etag
ETag for RESTCONF.
-
dlq_hdr_t *metaQ
YANG does not support user-defined meta-data but NCX does.
The <edit-config>, <get> and <get-config> operations use attributes in the RPC parameters, the metaQ is still used
The ncx:metadata extension allows optional attributes to be added to object nodes for anyxml, leaf, leaf-list, list, and container nodes. The config property will be inherited from the object that contains the metadata
This is used mostly for RPC input parameters and is strongly discouraged. Full edit-config support is not provided for metadata Q of val_value_t
-
val_editvars_t *editvars
value editing variables the editvars will only be malloced while edit is in progress
edit-vars from attrs
-
op_editop_t editop
needed for all edits
-
status_t res
validation result
-
dlq_hdr_t *indexQ
this field used in NCX_BT_LIST only ??? when is it ncx_filptr_t ???
Q of val_index_t or ncx_filptr_t
-
ncx_owner_id_t owner_id
set if the owners are being stored and this is a data node in the running config
-
ncx_nmda_origin_t nmda_origin
NMDA origin enum.
-
boolean extern_valonly
flag if NCX_BT_EXTERN and file is entire contents
-
boolean from_anydata
flag indicating value->obj was replaced because of the ywx:datapath attribute and the original object was anyxml.
This is needed for get-bulk processing to parse the <data> element as the parent of the list-target. Will probably be invalid if this parent node is also a list
-
union val_value_t::v_ v
-
union v_
union of all the NCX-specific sub-types note that the following invisible constructs should never show up in this struct:
Public Members
-
dlq_hdr_t child_hdrQ
complex types have a Q of val_value_t representing the child nodes with values
changed from Q of val_value_t to a Q of val_child_hdr_t
-
ncx_num_t num
Numeric data types:
-
ncx_str_t str
String data types:
-
val_idref_t idref
NCX_BT_IDREF.
-
ncx_binary_t binary
NCX_BT_BINARY.
-
ncx_list_t list
NCX_BT_BITS, NCX_BT_SLIST.
-
boolean boo
NCX_BT_EMPTY, NCX_BT_BOOLEAN.
-
ncx_enum_t enu
NCX_BT_UNION, NCX_BT_ENUM.
-
xmlChar *fname
NCX_BT_EXTERN.
-
xmlChar *intbuff
NCX_BT_INTERN.
-
dlq_hdr_t child_hdrQ
-
dlq_hdr_t qhdr
The following table highlights the fields in this data structure.
val_value_t Fields
qhdr |
Internal queue header to allow a value node to be stored in a queue. A complex node maintains a child queue of val_value_t nodes. |
obj |
Back pointer to the object template for this data node |
typdef |
Back pointer to the typedef structure if this is a leaf or leaf-list node. |
name |
Back pointer to the name string for this node |
parent |
Back pointer to the parent of this node, if any |
nsid |
Namespace ID for this node. This may not be the same as the object node namespace ID, E.g., anyxml child node contents will override the generic object namespace. |
btyp |
The ncx_btype_t base type enumeration for this node. This is the final resolved value, in the event the object type is not a final resolved base type. |
flags |
Internal flags field. Do not access directly. |
dataclass |
Internal config or non-config enumeration |
metaQ |
Queue of val_value_t structures that represent any meta-variables (XML attributes) found for this data node. For example, the NETCONF filter 'type' and 'select' attributes are defined for the <filter> element in yuma-netconf.yang. |
editvars |
Pointer to the malloced edit variables structure for this data node. This node will be freed (and NULL value) when the edit variables are not in use. |
res |
Internal validation result status for this node during editing or parsing. |
indexQ |
Queue of internal data structures used during parsing and filtering streamed output. |
val_extra |
Pointer to extra data if needed |
v |
Union of different internal fields, depending on the 'btyp' field value. |
v.childQ |
Queue of val_value_t child nodes, if this is a complex node. |
v.num |
ncx_num_t for all numeric data types |
v.str |
Malloced string value for the string data type |
v.idref |
Internal data structure for the YANG identityref data type |
v.binary |
Internal data structure for the YANG binary data type |
v.list |
Internal data structure for YANG bits and NCX xsdlist data types |
v.boo |
YANG boolean data type |
v.enu |
Internal data structure for YANG enumeration data type |
v.fname |
File name for NCX 'external' data type |
v.intbuff |
Malloced buffer for 'internal' data type |
YumaPro Data Nodes (Extra) (val_extra_t)
The val_extra_t data structure is used to maintain the fields that are internal and rarely used by the server have been moved from val_value_t to a new data structure called "val_extra_t".
The following typedef is used to define the extra data used for value node processing
-
struct val_extra_t
extra information not used very often within a val_value_t
Public Members
-
xmlChar *dname
malloced value name used rarely if obj_get_name not correct this can happen if val_value_t trees are constructed by SIL code from generic objects; This is NOT RECOMMENDED Use val_init_from_template using correct obj_template_t instead
malloced name if needed
-
void *getcb
Used by Agent only: GET1 callback for virtualval if this field is non-NULL, then the entire value node is actually a placeholder for a dynamic read-only object and all read access is done via this callback function; the real data type is getcb_fn_t *.
-
struct val_value_t_ *virtualval
if this field is non-NULL, then a malloced value struct representing the real value retrieved by val_get_virtual_value, is cached here for <get>/<get-config>
-
time_t cachetime
timestamp for virtual val timeout
-
struct xpath_pcb_t_ *xpathpcb
this field is for NCX_BT_LEAFREF NCX_BT_INSTANCE_ID, or tagged ncx:xpath value stored in v union as a string
-
plock_cb_t *plock[VAL_MAX_PLOCKS]
back-ptr to the partial locks that are held against this node
-
dlq_hdr_t *dataruleQ
back-ptr to the data access control rules that reference this node
Q of obj_xpath_ptr_t
-
xmlChar *varexpr
malloced pointer to the variable expression found if this val node is part of a data template.
The actual value in union v_ MUST be ignored if varexpr string is non-NULL!!
-
struct xpath_aio_cb_t_ *aiocb
Used by xpath_aio.c and agt_xpath.c to keep track of the parent of a top AIO val_value_ tree.
This is a backptr.
-
ncx_sm_mpid_t *mpid
malloced Moint Point ID struct if found in parsing
-
xmlChar *dname
The following table highlights the fields in this data structure:
Note: Do not access fields directly! Use val.h macros or access functions in val.h and val_util.h
val_extra_t Fields
dname |
Malloced name string if the client or server changed the name of this node, so the object node name is not being used. This is used for anyxml processing (and other things) to allow generic objects (container, string, empty, etc.) to be used to represent the contents of an 'anyxml' node. |
getcb |
Internal server callback function pointer. Used only if this is a 'virtual' node, and the actual value node contents are generated by a SIL callback function instead of being stored in the node itself. |
virtualval |
The temporary cached virtual node value, if the getcb pointer is non-NULL. |
cachetime |
The timestamp used to cache for a virtualval |
xpathpcb |
XPath parser control block, used if this value contains some sort of XPath string or instance-identifier. For example, the XML namespace ID mappings are stored, so the XML prefix map generated for the <rpc-reply> will contain and reuse the proper namespace attributes, as needed. |
plock |
Array of [1] for supporting <partial-lock> operation |
dataruleQ |
pointer to malloced queue for NACM data rule support |
varexpr |
malloced string containing variable string for replacement |
val_value_t Access Macros
There are a set of macros defined to access the fields within a val_value_t structure.
These should be used instead of accessing the fields directly. There are also functions defined as well. These macros are provided in addition to the access functions for quick access to the actual node value. These macros must only be used when the base type ('btyp') field has been properly set and known by the SIL code. Some auto-generated SIL code uses these macros.
The following table summarized the val_value_t macros that are
defined in ncx/val.h
:
VAL_OBJ(V) |
Access object template of the value |
VAL_TYPE(V) |
Access base type of the value |
VAL_HDR(V) |
Access child header pointer of the value |
VAL_TYPDEF(V) |
Access type definition of the value |
VAL_NSID(V) |
Access namespace ID value |
VAL_NAME(V) |
Access name value |
VAL_RES(V) |
Access resource enumeration value |
VAL_BOOL(V) |
Access value for NCX_BT_BOOLEAN |
VAL_EMPTY(V) |
Access value for NCX_BT_EMPTY |
VAL_DOUBLE(V) |
Access value for NCX_BT_FLOAT64 |
VAL_STRING(V) |
Access value for NCX_BT_STRING |
VAL_BINARY(V) |
Access value for NCX_BT_BINARY |
VAL_ENU(V) |
Access entire ncx_enum_t structure for NCX_BT_ENUM |
VAL_ENUM(V) |
Access enumeration integer value for NCX_BT_ENUM |
VAL_ENUM_NAME(V) |
Access enumeration name string for NCX_BT_ENUM |
VAL_FLAG(V) |
Deprecated: use VAL_BOOL instead |
VAL_LONG(V) |
Access NCX_BT_INT64 value |
VAL_INT(V) |
Access NCX_BT_INT32 value |
VAL_INT8(V) |
Access NCX_BT_INT8 value |
VAL_INT16(V) |
Access NCX_BT_INT16 value |
VAL_INT32(V) |
Access NCX_BT_INT32 value |
VAL_INT64(V) |
Access NCX_BT_INT64 value |
VAL_STR(V) |
Deprecated: use VAL_STRING instead |
VAL_INSTANCE_ID(V) |
Access NCX_BT_INSTANCE_ID value |
VAL_IDREF(V) |
Access entire val_idref_t structure for NCX_BT_IDREF |
VAL_IDREF_NSID(V) |
Access the identityref namespace ID for NCX_BT_IDREF |
VAL_IDREF_NAME(V) |
Access the identityref name string for NCX_BT_IDREF |
VAL_UINT(V) |
Access the NCX_BT_UINT32 value |
VAL_UINT8(V) |
Access the NCX_BT_UINT8 value |
VAL_UINT16(V) |
Access the NCX_BT_UINT16 value |
VAL_UINT32(V) |
Access the NCX_BT_UINT32 value |
VAL_UINT64(V) |
Access the NCX_BT_UINT64 value |
VAL_ULONG(V) |
Access the NCX_BT_UINT64 value |
VAL_DEC64(V) |
Access the ncx_dec64 structure for NCX_BT_DEC64 |
VAL_DEC64_DIGITS(V) |
Access the number of digits for NCX_BT_DEC64 |
VAL_DEC64_ZEROES(V) |
Access the number of zeros for NCX_BT_DEC64 |
VAL_LIST(V) |
Access the ncx_list_t structure for NCX_BT_LIST |
VAL_BITS |
Access the ncx_list_t structure for NCX_BT_BITS. (Same as VAL_LIST) |
val_value_t Access Functions
The file ncx/val.h
contains many API functions so that object
properties do not have to be accessed directly. In addition, the file
ncx/val_util.h
contains more (high-level) utility functions. The
following table highlights the most commonly used functions. Refer to
the H files for a complete definition of each API function.
val_value_t Access Functions
val_new_value |
Malloc a new value node with type NCX_BT_NONE. |
val_init_complex |
Initialize a malloced value node as one of the complex data types. |
val_init_virtual |
Initialize a malloced value node as a virtual node (provide a 'get' callback function). |
val_init_from_template |
Initialize a malloced value node using an object template. This is the most common form of the init function used by SIL callback functions. |
val_free_value |
Clean and free a malloced value node. |
val_set_name |
Set or replace the value node name. |
val_force_dname |
Set (or reset) the name of a value struct . Set all descendant nodes as well Force dname to be used, not object name backptr. |
val_set_qname |
Set or replace the value node namespace ID and name. |
val_string_ok |
Check if the string value is valid for the value node object type. |
val_string_ok_errinfo |
Check if the string value is valid for the value node object type, and provide the error information to use if it is not OK. |
val_binary_ok_errinfo |
Retrieve the YANG custom error info if any. Check a binary string to make sure the value is valid base64 if the value came from raw RPC XML, and if its CLI input then do validation as for binary sting . Retrieve the configured error info struct if any error. |
val_list_ok |
Check if the list value is valid for the value node object type. |
val_list_ok_errinfo |
Check if the list value is valid for the value node object type, and provide the error information to use if it is not OK. |
val_enum_ok |
Check if the enumeration value is valid for the value node object type. |
val_enum_ok_errinfo |
Check if the enumeration value is valid for the value node object type, and provide the error information to use if it is not OK. |
val_bit_ok |
Check if the bits value is valid for the value node object type. |
val_idref_ok |
Check if the identityref value is valid for the value node object type. |
val_parse_idref |
Convert a string to an internal QName string into its various parts and find the identity struct that is being referenced (if available). |
val_range_ok |
Check a number to see if it is in range or not . Could be a number or size range. |
val_range_ok_errinfo |
Check a number to see if it is in range or not . Could be a number or size range. Returns error info record on error exit. |
val_pattern_ok |
Check a string against all the patterns in a big AND expression. |
val_pattern_ok_errinfo |
Check a string against all the patterns in a big AND expression. Returns error info record on error exit. |
val_simval_ok |
Check if the smple value is valid for the value node object type. |
val_simval_ok_errinfo |
Check if the simple value is valid for the value node object type, and provide the error information to use if it is not OK. |
val_union_ok |
Check a union to make sure the string is valid. |
val_union_ok_errinfo |
Check a union to make sure the string is valid. Returns error info record on error exit. |
val_union_ok_ex |
Check a union to make sure the string is valid based on the specified typdef. |
val_union_ok_full |
Check a union to make sure the string is valid based on the specified typdef, and convert the string to an NCX internal format . Use context and root nodes to evaluate XPath for leafref and instance-identifier types. |
val_get_metaQ |
Get the meta Q header for the value. |
val_get_first_meta |
Get the first meta-variable (XML attribute value) for a value node. |
val_get_next_meta |
Get the next meta-variable (XML attribute value) for a value node. |
val_meta_empty |
Check if the metaQ is empty for the value node. |
val_find_meta |
Find the specified meta-variable in a value node. |
val_meta_match |
Return true if the corresponding attribute exists and has the same value. |
val_metadata_inst_count |
Get the number of instances of the specified attribute. |
val_dump_value |
Debug function to print the contents of any value node. |
val_dump_value_ex |
Debug function to print the contents of any value node, with extended parameters to control the output. |
val_dump_value_max |
Debug function to print the contents of any value node, with full control of the output parameters. |
val_set_string |
Set a malloced value node as a generic string value. Used instead of val_init_from_template. |
val_set_string2 |
Set a malloced value node as a specified string type. Used instead of val_init_from_template. |
val_set_binary |
Set and decode base64 value . Set an initialized val_value_t as a binary type. |
val_reset_empty |
Recast an already initialized value as an NCX_BT_EMPTY clean a value and set it to empty type used by yangcli-pro to delete leafs. |
val_set_simval |
Set a malloced value node as a specified simple type. Used instead of val_init_from_template. |
val_make_simval |
Create and set a val_value_t as a simple type same as val_set_simval, but malloc the value first. |
val_set_simval_str |
Set a malloced value node as a specified simple type. Used instead of val_init_from_template. Use a counted string value instead of a zero-terminated string value. |
val_make_string |
Create a complete malloced generic string value node. |
val_merge |
Merge source val into destination value (! MUST be same type !) . Any meta vars in source are also merged into destination . This function is not used to merge complex objects For simple types only! |
val_clone |
Clone a value node. |
val_clone2 |
Clone a specified val_value_t structure and sub-trees but not the editvars. |
val_clone_test |
Clone a value node with a 'test' callback function to prune certain descendant nodes during the clone procedure. |
val_clone_config_data |
Clone a value node but skip all the non-configuration descendant nodes. |
val_replace |
Replace a specified val_value_t structure and sub-trees. This can be destructive to the source 'val' parameter ! |
val_replace_str |
Replace a specified val_value_t structure with a string type. |
val_fast_replace_string |
Replace a specified val_value_t structure with a string type . Reuse everything -- just set the val->v.str field |
val_add_child |
Add a child value node to a parent value node. Simply makes a new last child!!! Does not check siblings!!! Relies on val_set_canonical_order To modify existing entries, use val_add_child_sorted instead!! |
val_add_child2 |
Add a child value node to a parent value node. |
val_add_child_sorted |
Add a child value node to a parent value node in the proper place |
val_insert_child |
Insert a child value node into a specific spot into a parent value node. |
val_remove_child |
Remove a child value node from its parent. |
val_swap_child |
Replace a child node within its parent with a different value node. |
val_first_child_match |
Match a child node name; Used for partial command completion in yangcli-pro. |
val_first_child_match_fast |
Get the first instance of the corresponding child node. Object pointers must be from the same tree!!! |
val_next_child_match |
Match the next child node name; Used for partial command completion in yangcli-pro. |
val_next_child_same |
Get the next instance of the corresponding child node. |
val_get_first_child |
Get the first child value node. |
val_get_next_child |
Get the next child value node. |
val_find_child |
Find a specific child value node. |
val_find_child_fast |
Find the first instance of the specified child node. |
val_find_child_obj |
Find the first instance of the specified child node . Use the object template pointer to match the object. |
val_find_child_que |
Find the first instance of the specified child node in the specified child Q. |
val_find_next_child |
Find the next occurrence of a specified child node. |
val_find_next_child_fast |
Find the next instance of the specified child node . Use the curchild->obj pointer to find next child of this type . Assumes childQ is sorted and all instances of 'curchild' are already grouped together. |
val_first_child_name |
Get the first corresponding child node instance, by name find first -- really for resolve index function. |
val_first_child_qname |
Get the first corresponding child node instance, by Qname. |
val_next_child_qname |
Get the next corresponding child node instance, by Qname. |
val_first_child_string |
Find first name value pair . Get the first corresponding child node instance, by name and by string value. Child node must be a base type of NCX_BT_STRING NCX_BT_INSTANCE_ID NCX_BT_LEAFREF |
val_get_first_terminal_child |
Get the child node only if obj_is_terminal(obj) is true. |
val_get_next_terminal_child |
Get the next child node only if obj_is_terminal(obj) is true. |
val_match_child |
Match a potential partial node name against the child node names, and return the first match found, if any. |
val_match_child_count |
Match the first instance of the specified child node . Return the total number of matches. |
val_child_cnt |
Get the number of child nodes within a parent node. |
val_child_inst_cnt |
Get the corresponding child instance count by name . Get instance count -- for instance qualifier checking. |
val_get_child_inst_id |
Get the instance ID for this child node within the parent context. |
val_liststr_count |
Get the number of strings within an NCX_BT_LIST value node. |
val_index_match |
Check if 2 value list nodes have the same set of key leaf values. |
val_compare |
Compare 2 value nodes |
val_compare_ex |
Compare 2 value nodes with extra parameters. |
val_compare_to_string |
Compare a value node to a string value instead of another value node. |
val_compare_to_string_len |
Compare a val_value_t structure value contents to a string . Provide a max-length to compare. |
val_sprintf_simval_nc |
Output the value node as a string into the specified buffer. |
val_make_sprintf_string |
Malloc a buffer and fill it with a zero-terminated string representation of the value node. |
val_resolve_scoped_name |
Find a descendant node within a value node, from a relative path expression. |
val_has_content |
Return TRUE if the value node has any content; FALSE if an empty XML element could represent its value. |
val_has_index |
Return TRUE if the value node is a list with a key statement. |
val_get_first_index |
Get the first index node for the specified list value node. |
val_get_next_index |
Get the next index node for the specified list value node. |
val_get_index_count |
Get the number of index nodes in this val. |
val_set_extern |
Set a malloced value node as an NCX_BT_EXTERN internal data type. |
val_set_intern |
Set a malloced value node as an NCX_BT_INTERN internal data type. |
val_fit_oneline |
Return TRUE if the value node should fit on 1 display line; Sometimes a guess is made instead of determining the exact value. XML namespace declarations generated during XML output can cause this function value to sometimes be wrong. |
val_create_allowed |
Return TRUE if the NETCONF create operation is allowed for the specified value node. |
val_delete_allowed |
Return TRUE if the NETCONF delete operation is allowed for the specified value node. |
val_is_config_data |
Return TRUE if the value node represents configuration data. |
val_is_virtual |
Check if the specified value is a virtual value , such that a 'get' callback function is required to access the real value contents. |
val_get_virtual_value |
Get the value for a virtual node from its 'get' callback function. |
val_is_default |
Return TRUE if the value node is set to its YANG default value. |
val_is_real |
Check if a value node is a real node or one of the abstract node types. |
val_get_parent_nsid |
Get the namespace ID for the parent value node of a specified child node. |
val_instance_count |
Get the number of occurrences of the specified child value node within a parent value node. |
val_instance_count_fast |
Count the number of instances of the specified object name in the parent value structure. This only checks the first level under the parent, not the entire subtree. |
val_instance_count_fast2 |
Count the number of instances of the specified object name in the parent value structure. This only checks the first level under the parent, not the entire subtree . Starts with the startval passed in. |
val_need_quotes |
Return TRUE if the printed string representation of a value node needs quotes (because it contains some whitespace or special characters). |
val_all_whitespace |
Check if a string is all whitespace. |
val_any_whitespace |
Check if a string has any whitespace chars. |
val_get_dirty_flag |
Check if a value node has been altered by an RPC operation, but this edit has not been finalized yet. |
val_get_nest_level |
Get the current numeric nest level of the specified value node. |
val_get_mod_name |
Get the module name for the specified value node. |
val_get_mod_prefix |
Get the module prefix string for the specified value node. |
val_get_nsid |
Get the namespace ID for the specified value node. |
val_change_nsid |
Change the namespace ID for the specified value node and all of its descendants. |
val_set_pcookie |
Set the SIL pointer cookie in the value node editvars structure. |
val_set_icookie |
Set the SIL integer cookie in the value node editvars structure. |
val_get_pcookie |
Get the SIL pointer cookie in the value node editvars structure. |
val_get_icookie |
Get the SIL integer cookie in the value node editvars structure. |
val_get_typdef |
Get the typedef structure for a leaf or leaf-list value node. |
val_move_children |
Move all the child nodes of one complex value node to another complex value node. |
val_set_canonical_order |
Re-order the descendant nodes of a value node so they are in YANG order. Does not change the relative order of system-ordered lists and leaf-lists. |
val_gen_index_chain |
Generate the internal key leaf lookup chain for a list value node.. |
val_add_defaults |
Generate the leafs that have default values. |
val_instance_check |
Check a value node against its template to see if the correct number of descendant nodes are present. |
val_get_choice_first_set |
Get the first real node that is present for a conceptual choice statement. |
val_get_choice_next_set |
Get the next real node that is present for a conceptual choice statement. |
val_choice_is_set |
Return TRUE if some real data node is present for a conceptual choice statement. |
val_get_first_key |
Get the first key record if this is a list with a key-stmt. |
val_get_last_key |
Get the last key record if this is a list with a key-stmt. |
val_get_next_key |
Get the next key record if this is a list with a key-stmt. |
val_get_prev_key |
Get the previous key record if this is a list with a key-stmt. |
val_remove_key |
Remove a key pointer because the key is invalid . Free the key pointer. |
val_new_child_val |
Create a child node during an edit operation. Used by the server. SIL code does not need to maintain the value tree. |
val_gen_instance_id |
Malloc and generate the YANG instance-identifier string for the value node. |
val_check_obj_when |
Check if an object node has any 'when' statements, and if so, evaluate the XPath condition(s) against the value tree to determine if the object should be considered present or not. |
val_check_child_conditional |
Check if a child object node has any FALSE 'if-feature' or 'when' statements. |
val_is_mandatory |
Check if the child object node is currently mandatory or optional. |
val_get_xpathpcb |
Access the XPath parser control block for this value node, if any. |
val_make_simval_obj |
Malloc and fill in a value node from an object template and a value string. |
val_set_simval_obj |
Fill in a value node from an object template and a value string. |
val_find_bit |
Check if a bits value contains the specified bit name |
val_find_bit_name |
Get the name of the bit from a bits value that corresponds to the specified bit position |
val_find_enum_name |
Get the name of the enum from an enumeration value that corresponds to the specified 'value' number |
val_sprintf_etag |
Write the Entity Tag for the value to the specified buffer. |
val_get_last_modified |
Get the last_modified field. |
val_has_children |
Determine if there are any child nodes for this val. |
val_delete_children |
Check if the value is a complex type and if so then delete all child nodes. |
val_clean_value |
Clean a static val_value_t structure. |
val_get_yang_typename |
Get the YANG type name for this value node if there is one. |
val_is_value_set |
Check if a value has been set by a client . It has to be initialized and not set by default to return true. |
val_idref_derived_from |
Check the specified valnode is derived from the specified identity. |
val_get_sil_priority |
Get the secondary SIL priority; zero if not found. |
val_has_conditional_value |
YANG 1.1: Check the value that must be properly set to see if it is conditional on any if-feature-stmts. |
val_convert_leafref |
Convert a value of type NCX_BT_LEAFREF to the value that the final leafref is pointing at. |
Data Tree Handling Examples
YANG data trees are instances of YANG schema nodes. There are various API functions that can be used to manipulate a desired Data node. They differ widely the operation that you need to perform. This section contains simple examples that will illustrate how to manage different YANG node types.
Include Files For Data Nodes
The following H files need to be included in a C file to use APIs to access data nodes.
H File |
Description |
---|---|
agt.h |
Core agent utilities and agt_profile |
agt_util.h |
Agent utility functions |
cfg.h |
Configuration datastore utilities |
ncx.h |
YANG module utilities |
ncxconst.h |
Global constants |
ncxtypes.h |
Module and other code data structures |
obj.h |
YANG object template APIs |
val.h |
Main val_value_t access functions |
val_child.h |
Child access functions |
val_util.h |
Additional val_value_t access functions |
These files are (and others) are automatically included in auto-generated SIL and SIL-SA code.
If using in another file, remember to include all YumaPro H files after procdefs.h.
The libxml2 file
xmlstring.h
is usually included before all YumaPro files.All YumaPro headers are self-compiling, so it is OK to include them in alphabetical order (after procdefs.h)
For example:
#include <xmlstring.h>
#include "procdefs.h"
#include "agt.h"
#include "agt_util.h"
#include "cfg.h"
#include "ncx.h"
#include "ncxconst.h"
#include "ncxtypes.h"
#include "obj.h"
#include "val.h"
#include "val_child.h"
#include "val_util.h"
Creating and Deleting Data Nodes
Many APIs in this section return a malloced structure representing a YANG data node. The val_value_t typedef is used for this purpose.
New Value Node
-
val_value_t *val_new_value(void)
Malloc and initialize the fields in a val_value_t.
- Returns:
pointer to the malloced and initialized struct or NULL if an error
/* create an uninitialized value node */
val_value_t *val = val_new_value();
if (val == NULL) {
return ERR_INTERNAL_MEM;
}
Initialize a Value Node
-
void val_init_from_template(val_value_t *val, struct obj_template_t_ *obj)
Initialize a value node from its object template.
This is the normal init function to call MUST CALL val_new_value FIRST
- Parameters:
val -- pointer to the initialized value struct to bind
obj -- object template to use
/* initialize a value node */
val_init_from_template(val, obj);
Free a Value Node
-
void val_free_value(val_value_t *val)
Scrub the memory in a val_value_t by freeing all the sub-fields and then freeing the entire struct itself.
The struct must be removed from any queue it is in before this function is called.
- Parameters:
val -- val_value_t to delete
/* clean and free a value node and all its descendants */
val_free_value(val);
Leaf Examples
The following examples show how to construct a simple leaf data node. These APIs can all be used for a leaf-list value as well.
String Value With Leaf Object Template
The most common and generic API function to construct the data node from a string value. The val_make_simval_obj API requires the child object template.
-
val_value_t *val_make_simval_obj(obj_template_t *obj, const xmlChar *valstr, status_t *res)
Create and set a val_value_t as a simple type from an object template instead of individual fields Calls val_make_simval with the object settings.
This API is the preferred method to create a leaf in SIL or SIL-SA code. This will use correct settings from the object template
- Parameters:
obj -- object template to use
valstr -- simple value encoded as a string
res -- [out] address of return status
*res return status
- Returns:
pointer to malloced and filled in val_value_t struct NULL if some error
obj_template_t *leafobj =
obj_find_child(parentobj, modname, objname);
if (leafobj == NULL) {
/* report an error or do not try to generate the leaf */
return ERR_NCX_DEF_NOT_FOUND;
}
/* construct a leaf val_vale tree regardless of its type */
status_t res = NO_ERR;
val_value_t *any_type_leaf =
val_make_simval_obj(leafobj, (const xmlChar *)"8", &res);
String Value With Parent Object Template
The "agt_make_leaf" family of API functions look up the child object and make the child leaf in one step.
-
val_value_t *agt_make_leaf(obj_template_t *parentobj, const xmlChar *leafname, const xmlChar *leafstrval, status_t *res)
make a string val_value_t struct for a specified leaf or leaf-list
This is a main API for SIL and SIL-SA code to construct return data for GET2 callbacks.
See also
- Parameters:
parentobj -- parent object to find child leaf object
leafname -- name of leaf to find (namespace hardwired)
leafstrval -- string version of value to set for leaf
res -- [out] address of return status; *res=return status
- Returns:
malloced value struct or NULL if some error
/* construct any type leaf using string representation */
status_t res = NO_ERR;
val_value_t *string_leaf =
agt_make_leaf(parentobj,
leafname,
(const xmlChar *)"example value",
&res);
There are additional APIs that allow a leaf to be created from an internal data type other than a string, such as a numeric type.
Integer Types
In order to construct a data node with integer types, the following API function can be used:
-
val_value_t *agt_make_int_leaf(obj_template_t *parentobj, const xmlChar *leafname, int32 leafval, status_t *res)
make an int32 val_value_t struct for a specified leaf or leaf-list
This is a main API for SIL and SIL-SA code to construct return data for GET2 callbacks.
See also
agt_make_int_leaf2
- Parameters:
parentobj -- parent object to find child leaf object
leafname -- name of leaf to find (namespace hardwired)
leafval -- integer number value for leaf
res -- [out] address of return status; *res return status
- Returns:
malloced value struct or NULL if some error
/* construct a uint32 type leaf */
status_t res = NO_ERR;
val_value_t *string_leaf =
agt_make_uint_leaf(parentobj,
leafname,
(uint32)32,
&res);
-
val_value_t *agt_make_uint_leaf(obj_template_t *parentobj, const xmlChar *leafname, uint32 leafval, status_t *res)
make a uint32 val_value_t struct for a specified leaf or leaf-list
This is a main API for SIL and SIL-SA code to construct return data for GET2 callbacks.
See also
agt_make_uint_leaf2
- Parameters:
parentobj -- parent object to find child leaf object
leafname -- name of leaf to find (namespace hardwired)
leafval -- number value for leaf
res -- [out] address of return status; *res=return status
- Returns:
malloced value struct or NULL if some error
/* construct a uint32 type leaf */
status_t res = NO_ERR;
val_value_t *value =
agt_make_int_leaf(parentobj,
leafname,
(int32)32,
&res);
-
val_value_t *agt_make_uint64_leaf(obj_template_t *parentobj, const xmlChar *leafname, uint64 leafval, status_t *res)
make a uint64 val_value_t struct for a specified leaf or leaf-list
This is a main API for SIL and SIL-SA code to construct return data for GET2 callbacks.
See also
agt_make_uint64_leaf2
- Parameters:
parentobj -- parent object to find child leaf object
leafname -- name of leaf to find (namespace hardwired)
leafval -- uint64 number value for leaf
res -- [out] address of return status; *res return status
- Returns:
malloced value struct or NULL if some error
/* construct a uint64 type leaf */
status_t res = NO_ERR;
val_value_t *value =
agt_make_uint64_leaf(parentobj,
leafname,
(uint64)64,
&res);
-
val_value_t *agt_make_int64_leaf(obj_template_t *parentobj, const xmlChar *leafname, int64 leafval, status_t *res)
make an int64 val_value_t struct for a specified leaf or leaf-list
This is a main API for SIL and SIL-SA code to construct return data for GET2 callbacks.
See also
agt_make_int64_leaf2
- Parameters:
parentobj -- parent object to find child leaf object
leafname -- name of leaf to find (namespace hardwired)
leafval -- int64 number value for leaf
res -- [out] address of return status; *res return status
- Returns:
malloced value struct or NULL if some error
/* construct a int64 type leaf */
status_t res = NO_ERR;
val_value_t *value =
agt_make_int64_leaf(parentobj,
leafname,
(int64)64,
&res);
Boolean Type
In order to construct a data node with boolean type, the following API function can be used.
-
val_value_t *agt_make_boolean_leaf(obj_template_t *parentobj, const xmlChar *modname, const xmlChar *leafname, boolean boolval, status_t *res)
make a val_value_t struct for a specified leaf or leaf-list (NCX_BT_BOOL)
- Parameters:
parentobj -- parent object to find child leaf object
modname -- name of module defining leaf (may be NULL to pick parent)
leafname -- name of leaf to find (namespace hardwired)
boolval -- boolean value for leaf
res -- [out] address of return status; *res return status
- Returns:
malloced value struct or NULL if some error
/* construct a boolean type leaf */
status_t res = NO_ERR;
val_value_t *string_leaf =
agt_make_boolean_leaf(parentobj,
modname,
leafname,
boolval,
&res);
Empty Type
In order to construct a data node with empty type, the following API function can be used.
-
val_value_t *agt_make_empty_leaf(obj_template_t *parentobj, const xmlChar *modname, const xmlChar *leafname, boolean boolval, status_t *res)
make a val_value_t struct for a specified leaf or leaf-list (NCX_BT_EMPTY)
- Parameters:
parentobj -- parent object to find child leaf object
modname -- name of module defining leaf (may be NULL to pick parent)
leafname -- name of leaf to find (namespace hardwired)
boolval -- ignored boolean value for leaf
res -- [out] address of return status; *res return status
- Returns:
malloced value struct or NULL if some error
/* construct a boolean type leaf */
status_t res = NO_ERR;
val_value_t *string_leaf =
agt_make_empty_leaf(parentobj,
modname,
leafname,
boolval,
&res);
Bits Type
The easiest way to create a leaf or leaf-list with the YANG bits data type is to create a string somehow with the bit values that should be set. This example uses the leaf object template and the 'val_make_simval_obj' API.
#include "val_util.h"
#include "status.h"
status_t res = NO_ERR;
val_value_t *retval =
val_make_simval_obj(leafobj,
(const xmlChar *)"bit1 bit3 bit5",
&res);
if ((retval != NULL) && (res == NO_ERR)) {
/* retval is malloced and valid, ready to use */
// ...
} else {
// res should be some error only if retval is also NULL
}
It is also possible to construct a bits leaf or leaf-list from the 'ncx_bits_t' which is really 'ncx_list_t'.
First the ncx_list_t is constructed or referenced from within another val_value_t or other data structure.
Next the agt_make_bits_leaf API is used with the parent object not the child leaf object.
-
val_value_t *agt_make_bits_leaf(obj_template_t *parentobj, const xmlChar *modname, const xmlChar *leafname, const ncx_list_t *listval, status_t *res)
make a val_value_t struct for a specified leaf or leaf-list (NCX_BT_BITS or NCX_BT_SLIST)
- Parameters:
parentobj -- parent object to find child leaf object
modname -- name of module defining leaf (may be NULL to pick parent)
leafname -- name of leaf to find (namespace hardwired)
listval -- bits value for leaf
res -- [out] address of return status; *res return status
- Returns:
malloced value struct or NULL if some error
#include "agt_util.h"
#include "ncx_list.h"
#include "status.h"
/* construct a bits leaf from another bits leaf */
status_t res = NO_ERR;
const ncx_list_t *bits = &(VAL_BITS(anotherleafval));
val_value_t *string_leaf =
agt_make_bits_leaf(parentobj,
modname,
leafname,
bits,
&res);
To check if any bit is set in a val_value_t using the bits type, refer to the following code example for a server CLI parameter:
/* Process --log-backtrace-stream */
val = val_find_child_fast(parentval, nsid, NCX_EL_LOGBT_STREAM);
if (val && val->res == NO_ERR) {
ncx_list_t *bits = &VAL_BITS(val);
if (ncx_string_in_list((const xmlChar *)"logfile", bits)) {
log_set_backtrace_logfile();
}
if (ncx_string_in_list((const xmlChar *)"stderr", bits)) {
log_set_backtrace_stderr();
}
if (ncx_string_in_list((const xmlChar *)"stdout", bits)) {
log_set_backtrace_stdout();
}
if (ncx_string_in_list((const xmlChar *)"syslog", bits)) {
log_set_backtrace_syslog();
}
if (ncx_string_in_list((const xmlChar *)"vendor", bits)) {
log_set_backtrace_vendor();
}
}
Identityref Type
The 'identityref' data type in YANG is used to select a specific YANG identity for its value, which must match the identityref 'base' statements in the identityref type.
module foo {
// ...
prefix f;
identity idbase;
identity val1 {
base idbase;
}
identity val2 {
base idbase;
}
identity val2 {
base idbase;
}
leaf idref1 {
type identityref {
// values val1, val2, val3 allowed
base idbase;
}
}
}
The 'val_idref_t' struct is used to define a reference to an identity.
-
struct val_idref_t
one QName for the NCX_BT_IDREF value
An identityref leaf can be created in 2 steps with these APIs:
Create a val_idref_t struct
Invoke the agt_make_idref_leaf API function
-
val_value_t *agt_make_idref_leaf(obj_template_t *parentobj, const xmlChar *leafname, const val_idref_t *leafval, status_t *res)
make an identityref val_value_t struct for a specified leaf or leaf-list
This is a main API for SIL and SIL-SA code to construct return data for GET2 callbacks.
See also
agt_make_idref_leaf2
- Parameters:
parentobj -- parent object to find child leaf object
leafname -- name of leaf to find (namespace hardwired)
leafval -- identityref value for leaf
res -- [out] address of return status; *res return status
- Returns:
malloced value struct or NULL if some error
The following example shows how this API might be used to set the leaf 'idref1' to the identity 'val2':
#include "agt_util.h"
#include "status.h"
#include "val.h"
#include "xmlns.h"
val_idref_t idref = {0};
xmlChar buff[] = "val2";
idref.nsid = xmlns_find_ns_by_module((const xmlChar *)"foo");
idref.name = buff;
status_t res = NO_ERR;
val_value_t *newval =
agt_make_idref_leaf(parentobj,
(const xmlChar *)"idref1",
&idref,
&res);
if ((newval != NULL) && (res == NO_ERR)) {
// valid leaf OK to use; must be freed with val_free_value
} else {
// error status and NULL return value expected
}
Leaf-list Examples
The following examples show how to construct a simple leaf-list data node.
These nodes are constructed the same way as regular leaf nodes. The only difference is that the "val_child_add" APIs allow multiple instances to be created, instead of just one.
The following example code shows how to construct 3 leaf-list siblings using the same API functions as for leaf node:
/* construct 3 leaf-list entries */
status_t res = NO_ERR;
val_value_t *leaflist_value1 =
val_make_simval_obj(leaflist_obj, (const xmlChar *)"53", &res);
if (!leaflist_value) {
return res;
}
val_value_t *leaflist_value2 =
val_make_simval_obj(leaflist_obj, (const xmlChar *)"30", &res);
if (!leaflist_value2) {
return res;
}
val_value_t *leaflist_value3 =
val_make_simval_obj(leaflist_obj, (const xmlChar *)"80", &res);
if (!leaflist_value3) {
return res;
}
Alternatively, the following example can be used in order to construct multiple leaf-list entries of int32 type node and add them to the existent container parent:
status_t res = NO_ERR;
int32 value = 0;
for (value = 10; (value <= 15) && (res==NO_ERR); value++) {
val_value_t *leaflist_value =
agt_make_int_leaf(parentobj,
leaflistname,
value,
&res);
if (!leaflist_value) {
return res;
}
/* add a new leaf-list entry into target container */
res = val_child_add(leaflist_value, container_value);
if (res != NO_ERR) {
val_free_value(leaflist_value);
}
}
As a result, all the leaf-list entries will be added to the parent container.
Adding Child Leafy Nodes
YANG data trees are usually constructed top-down. The parent is created and then children are created and added to the new parent. This procedure can be done in a nested fashion, to create any data tree.
The following APIs should be used to add leaf or leaf-list nodes to a parent in one step. These simplified APIs replace the older 2 step APIs that first create a child node and then use val_child_add to add the child to its parent.
API Function |
Description |
---|---|
agt_add_leafy |
Add any data node using a string value |
agt_add_uint_leafy |
Add a numeric data node using a uint32 value |
agt_add_int_leafy |
Add a numeric data node using a int32 value |
agt_add_uint64_leafy |
Add a numeric data node using a uint64 value |
agt_add_int64_leafy |
Add a numeric data node using a int64 value |
agt_add_boolean_leafy |
Add a boolean data node using a boolean value |
agt_add_idref_leafy |
Add an identityref data node using a val_idref_t value |
agt_add_bits_leafy |
Add a bits data node using a ncx_list_t value |
Example:
The previous leaf-list example can be simplified using the agt_add_int_leafy API.
-
status_t agt_add_int_leafy(val_value_t *parentval, const xmlChar *modname, const xmlChar *leafname, int32 leafval)
make a child node from a int32 and add to parent.
Add a simple child to a container or list
Combines agt_make_int_leaf2 and val_child_add
Can be used for leaf or leaf-list
- Parameters:
parentval -- parent value node to get new child
modname -- name of module defining leaf (may be NULL to pick parent)
leafname -- name of leaf to find (namespace hardwired)
leafval -- number value for leaf
- Returns:
status
status_t res = NO_ERR;
int32 value = 0;
for (value = 10; value <= 15 && res==NO_ERR; value++) {
res = agt_add_bits_leafy(container_value,
NULL, // modname
leaflistname,
value);
if (res != NO_ERR) {
// handle error, nothing to clean up here
}
}
Container Examples
The following examples shows how to construct a container data node.
The container nodes can be constructed different ways depending whether it is a top level container or not. If the container is not a top level container, the following code can be used:
/* get the container obj template */
obj_template_t *cont_obj =
obj_find_child(parentobj, modname, objname);
if (!cont_obj) {
return ERR_NCX_DEF_NOT_FOUND;
}
/* make a container value */
val_value_t *cont_value = val_new_value();
if (!cont_value) {
return ERR_INTERNAL_MEM;
}
val_init_from_template(cont_value, cont_obj);
The following example shows how multiple leaf-list entries can be added to the parent container:
status_t res = NO_ERR;
int32 value = 0;
for (value = 10; value <= 15 && res==NO_ERR; value++) {
val_value_t *leaflist_value =
agt_make_int_leaf(parentobj,
leaflistname,
value,
&res);
if (!leaflist_value) {
return res;
}
/* add a new leaf-list entry to parent container */
res = val_child_add(leaflist_value, cont_value);
if (res != NO_ERR) {
val_free_value(leaflist_value);
return res;
}
}
List Example
The following example shows how to construct a list data node. Refer to the Child Data Nodes section for details on this procedure.
static val_value_t *
create_list_entry (obj_template_t *parentobj,
int32 key,
status_t *res)
{
/* get the obj template for the list obj */
obj_template_t *list_obj =
obj_find_child(parentobj,
(const xmlChar *)"my-module",
(const xmlChar *)"my-list");
if (!list_obj) {
*res = ERR_NCX_DEF_NOT_FOUND;
return NULL;
}
/* make the list node */
val_value_t *list_value = val_new_value();
if (!list_value) {
*res = ERR_INTERNAL_MEM;
return NULL;
}
val_init_from_template(list_value, list_obj);
/* add key leaf entry */
*res = agt_add_int_leafy(list_obj, NULL, keyname, key);
if (*res != NO_ERR) {
val_free_value(list_value);
return NULL;
}
/* add an extra leaf entry */
*res = agt_add_uint_leafy(list_obj,
NULL, // modname
(const xmlChar *)"my-other-leaf",
(uint32)32);
if (*res != NO_ERR) {
val_free_value(list_value);
return NULL;
}
/* generate the internal index Q chain */
*res = val_gen_index_chain(list_obj, list_value);
if (*res != NO_ERR) {
val_free_value(list_value);
return NULL;
}
return list_value;
}
In the next example, 5 list entries are created and added to the parent
container contvalue
.
/* malloc and construct list values and add to container parent */
status_t res = NO_ERR;
int32 key = 0;
for (key = 10; key <= 15; key++) {
val_value_t *list_value =
create_list_entry(container_obj, key, &res);
if (!list_value) {
return res;
}
/* add a new list entry into target container */
res = val_child_add(list_value, contvalue);
if (res != NO_ERR) {
val_free_value(list_value);
return res;
}
}