Consider this simplified example, that represents GET2 callback for the “leaf” and “leaf-list” nodes.


  ...

    leaf get2-leaf { 
       config false; 
       type int32; 
    } 

    leaf-list get2-leaf-list { 
       config false; 
       type int32; 
    }

  ...



NOTE:

Note that only leaf or leaf-list nodes that are top level nodes required a callback. Any other simple type nodes DOES NOT required callback and can be generated within their parent callback invocation.


The following C API code exemplifies a simple GET2 callback function for the data model, which returns the leaf value when it is requested.


/* start value for leaf /get2-leaf */ 
static int32 leaf_val = 42;

/********************************************************************
* FUNCTION  get2_leaflist_type
*
* Path: /get2-leaf
*
* INPUTS: 
*   scb == session control block making the request 
*   msg == incoming XML message header 
*   get2cb == get2 control block for this callback request
* 
* OUTPUTS: 
*   return_valQ is filled with malloced val_value_t nodes
*
* RETURNS: 
*    status: 
*      NO_ERR if executed OK and found OK 
*      ERR_NCX_NO_INSTANCE warning if no instance found
*
********************************************************************/
static status_t 
    get2_leaflist_type (ses_cb_t *scb, 
                        xml_msg_hdr_t *msg, 
                        getcb_get2_t *get2cb) 
{ 
    (void)scb; 
    (void)msg; 

    /* check the callback mode type */ 
    getcb_mode_t cbmode = GETCB_GET2_CBMODE(get2cb); 
    switch (cbmode) { 
    case GETCB_GET_VALUE: 
        break; 
    case GETCB_GETNEXT_VALUE: 
        return ERR_NCX_NO_INSTANCE; 
    default: 
        return SET_ERROR(ERR_INTERNAL_VAL); 
    } 

    /* get the real value from the system here.
     * But in this example just increment the value by 1
     */ 
    int32 retval = leaf_val++; 

    /* return the leaf in the static return_val struct */ 
    obj_template_t *obj = GETCB_GET2_OBJ(get2cb); 
    val_value_t *return_val = GETCB_GET2_RETURN_VAL(get2cb); 

    val_init_from_template(return_val, obj); 
    VAL_INT32(return_val) = retval; 

    return NO_ERR;

}  /* get2_leaflist_type */ 


In the above example, the code generates the value based on the static value that is incremented after each retrieval. An agent can generate the value based on the real device statistical data or based on the system's statistical data, etc.


NOTE:

In the example, the code demonstrates how the value can be set using val.h macros, VAL_INT32. However, it is more reliable and recommended to use val.h APIs as agt_make_leaf2, or specific API for a specific YANG type, such as agt_make_int_leaf2. Or the most generic val_make_simval_obj() that creates and set a val_value_t as a simple type from an object template instead of individual fields.


To ensure that the GET2 callback is working as expected an application can retrieve running configuration and device state information as follows:


 
 <?xml version="1.0" encoding="UTF-8"?> 
  <rpc message-id="3" 
     xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"> 
    <get> 
      <filter type="subtree"> 
        <get2-leaf xmlns="http://yumaworks.com/ns/interfaces" /> 

      </filter> 
    </get> 
  </rpc> 


The server may reply with:


     <rpc-reply message-id="101"
                xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">

        <get2-leaf xmlns="http://yumaworks.com/ns/interfaces">42</get2-leaf>
     </rpc-reply>


Now let us go through simple examples that will illustrate how to utilize the GET2 callbacks fo rthe leaf-list nodes.

The following C API code exemplifies a simple GET2 callback function for the same data model, which returns the leaf-list values when requested.


/********************************************************************
* FUNCTION  get2_leaflist_type
*
* Path: /get2-leaf-list
*
* INPUTS: 
*   scb == session control block making the request 
*   msg == incoming XML message header 
*   get2cb == get2 control block for this callback request
* 
* OUTPUTS: 
*   return_valQ is filled with malloced val_value_t nodes
*
* RETURNS: 
*    status: 
*      NO_ERR if executed OK and found OK 
*      ERR_NCX_NO_INSTANCE warning if no instance found
*
********************************************************************/
static status_t 
    get2_leaflist_type (ses_cb_t *scb, 
                        xml_msg_hdr_t *msg, 
                        getcb_get2_t *get2cb) 
{ 
    (void)scb; 
    (void)msg; 

    status_t res = NO_ERR; 

    /* check the callback mode type */ 
    getcb_mode_t cbmode = GETCB_GET2_CBMODE(get2cb); 
    switch (cbmode) { 
    case GETCB_GET_VALUE: 
        break; 
    case GETCB_GETNEXT_VALUE: 
        return ERR_NCX_NO_INSTANCE; 
    default: 
        return SET_ERROR(ERR_INTERNAL_VAL); 
    } 

    obj_template_t *obj = GETCB_GET2_OBJ(get2cb); 

    /* always return all the leaf-list instances 
     *  3 entries [53, 67, 92] 
     */ 
    val_value_t *retval = 
        val_make_simval_obj(obj, (const xmlChar *)"53", &res); 
    if (retval) { 
        getcb_add_return_val(get2cb, retval); 
    } 

    if (res == NO_ERR) { 
        retval = val_make_simval_obj(obj, (const xmlChar *)"67", &res); 
        if (retval) { 
            getcb_add_return_val(get2cb, retval); 
        } 
    } 

    if (res == NO_ERR) { 
        retval = val_make_simval_obj(obj, (const xmlChar *)"92", &res); 
        if (retval) { 
            getcb_add_return_val(get2cb, retval); 
        } 
    } 

    return res;

}  /* get2_leaflist_type */ 


In the above example, the code generates the value based on the static value that does not fluctuate after each retrieval. An agent can generate the value based on the real device statistical data or based on the system's statistical data, etc.

To ensure that the GET2 callback is working as expected an application can retrieve running configuration and device state information as follows:


 <?xml version="1.0" encoding="UTF-8"?> 
  <rpc message-id="3" 
     xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"> 
    <get> 
      <filter type="subtree"> 
        <get2-leaf-list xmlns="http://yumaworks.com/ns/interfaces" /> 

      </filter> 
    </get> 
  </rpc> 


The server may reply with:


     <rpc-reply message-id="101"
                xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">

        <get2-leaf-list xmlns="http://yumaworks.com/ns/interfaces">53</get2-leaf-list>
        <get2-leaf-list xmlns="http://yumaworks.com/ns/interfaces">67</get2-leaf-list>
        <get2-leaf-list xmlns="http://yumaworks.com/ns/interfaces">92</get2-leaf-list>
     </rpc-reply>