Global Callbacks APIs

Each Global callback type has its own callback API function prototype, and each callback has its own register and unregister functions that need to be used.

The following Global Callbacks are described in this section:

Global Callbacks Constraints

In the context of implementing global callbacks, there are several key constraints and limitations designed to streamline the callback infrastructure and ensure efficient system operation.

Understanding these limitations is crucial for developers to effectively implement and utilize global callbacks within their systems.

  • Single Global Callback Allowance: The system allows the registration of a single global callback. This policy simplifies the callback management, ensuring that there's a singular, centralized process for handling operations globally.

  • No Key Parameters: There will be no key parameter provided to any Global callback; the Global callback handles this internally if necessary.

  • No auto-generation: The code for Global callbacks is NOT generated automatically by yangdump-pro.

  • No Add Edit API: It is only supported in Set Hook Callbacks

Global Callbacks Design Principles

Global callbacks introduce an unified approach to handling operations across different object types within a YANG model.

This mechanism ensures that there is always a fallback or default handler available for operations, guaranteeing that no operation request goes unhandled. The Global callback serves as a catch-all, ensuring that even if specific handling logic hasn't been defined for every possible object in the YANG model, the system can still process operation in a consistent manner.

The SIL or SIL-SA code architecture must be modified to accommodate Global callbacks. This code is not automatically generated; it must be manually integrated to activate Global callbacks.

It is important to note that once Global callbacks are incorporated into any part of the SIL or SIL-SA code, they will be triggered for all nodes lacking specific callbacks of their own.

Global callbacks can be enabled using the yp-system, providing an alternative to embedding them directly within the SIL or SIL-SA code of any specific module.

Global EDIT Callbacks

Note

SIL version of callback is available starting in version 23.10T-8. SIL-SA version of callback is available starting in version 23.10T-11.

When a Global EDIT2 or EDIT3 callback is set up, it acts as a comprehensive handler for edit operations across the system. This Global EDIT callback is specifically designed to come into play when there are no EDIT callbacks defined for a particular data node. Essentially, if an edit operation is initiated and the system does not find a dedicated edit callback registered for the targeted object, it automatically defers to the Global EDIT callback for processing.

By having a single callback function that can act on behalf of unspecified objects during edit operations, developers can ensure that their system remains adaptable and efficient, even as the complexity of the YANG model or the number of managed objects increases. This system design reflects a thoughtful approach to scalability and manageability within network management and configuration systems.

The --sil-skip-global-edit-validate and --sil-skip-global-edit-apply CLI parameters, when set to 'true', prevent the server from invoking the Global EDIT callback during the Validate or Apply phases. This provides precise control over which phases invoke global callbacks, allowing for more targeted management of configuration changes.

Global EDIT Invocation Scenarios

It is essential to understand the conditions under which Global callback is activated during EDIT operations. This understanding ensures that the system operates efficiently, accurately executing operations.

Here is an overview of the scenarios that trigger Global EDIT callback:

  • Global Callback as Default: If there is only Global EDIT callback and no other specific EDIT callbacks set up, the system will use the Global EDIT callback for any edit operations, serving as a reliable fallback mechanism.

  • Global Callback with In-Transaction Callbacks: If there are no EDIT callbacks but In-Transaction and Global EDIT callback are present, the system defaults to using Global EDIT callback for edits, alongside In-Transaction callbacks activities.

  • Global Callback vs. Remote: The system prefers remote EDIT callbacks over Global EDIT callback for edit operations when both are available.

  • Global Callback in Absence of Remote Edits: When remote In-Transaction callbacks are set up without any EDIT callbacks, and Global callback is also in place, the system utilizes global callback for edit operations, alongside remote In-Transaction callbacks activities.

  • SIL vs SIL-SA Global Callback: The system must have only one or another. There cannot be SIL and SIL-SA Global Callbacks.

These scenarios outline how the system decides which callbacks to use under different configurations. It is all about ensuring that edits and transactions are handled as efficiently as possible, with Global callbacks serving as a reliable catch-all when more specific or remote options are not available or appropriate.

Global EDIT2 Callback Function

The Global EDIT2 callback uses the EDIT2 Callback Function template function.

Global EDIT3 Callback Function

The Global EDIT3 callback uses the EDIT3 Callback Function template function.

Global EDIT Callback Initialization and Cleanup

SIL and SIL-SA callback initialization and cleanup functions are identical.

The Global EDIT2 callback function is hooked into the server with the agt_glob_register_edit2 function, described below.

status_t agt_glob_register_edit2(agt_cb_fn_t cbfn)

Register a Global EDIT2 callback.

This function registers a Global EDIT2 callback that will be called if there are no any other EDIT2 or EDIT3 callbacks registered to the current target object.

Parameters:

cbfn -- address of EDIT2 callback function to use

Returns:

the status of operation

The Global EDIT3 callback function is hooked into the server with the agt_glob_register_edit3 function, described below.

status_t agt_glob_register_edit3(agt_edit3_fn_t cbfn)

Register a Global EDIT3 callback.

This function registers a Global EDIT3 callback that will be called if there are no any other EDIT3 or EDIT2 callbacks registered to the current target object.

Parameters:

cbfn -- address of EDIT3 callback function to use

Returns:

the status of operation

The registration is done during the Initialization Phase 1 before the startup configuration is loaded into the running configuration database and before running configurations are loaded.

static status_t interfaces_init (void)
{
    /* Use one or another; NOT both */
    status_t res =
        agt_glob_register_edit3(edit3_callback_example);

    status_t res =
        agt_glob_register_edit2(edit2_callback_example);

    return res;
}

Use the agt_glob_unregister_edit function to unregister Global EDIT callbacks.

static void interfaces_cleanup (void)
{
    agt_glob_unregister_edit();
    return;
}

The unregister function needs to be called just once for All Global EDIT callbacks. It will unregister Global EDIT2 and EDIT3 callbacks. However, if it is called multiple times, it will not produce errors.

Global EDIT Callback Example

This example demonstrates the effective use of the Global EDIT3 callback in real-world scenarios. It highlights the callback's ability to seamlessly handle modifications across various nodes associated with a particular YANG module.

This example is suitable for SIL and SIL-SA versions.


/*
 * @brief Edit database object callback (agt_edit3_fn_t)\n
 *
 * @param editcb Edit Control Block that contains
 * EDIT3 callback information
 *
 * @return return status for the phase.
 */
status_t
    sample_global_edit3 (agt_editcb_t *editcb)
{
    status_t res = NO_ERR;

    /* Callback information available in the callback */
    ses_cb_t *scb = editcb->scb;
    rpc_msg_t *msg = editcb->msg;
    agt_cbtyp_t cbtyp = editcb->cbtyp;
    op_editop_t editop = editcb->editop;

    /* Node related information available in the callback */
    val_value_t *newval = editcb->newval;
    val_value_t *curval = editcb->curval;
    val_value_t *update = editcb->update;
    obj_template_t *obj = editcb->obj;
    const xmlChar *modname = editcb->modname;

    /* Transaction information available in the callback */
    agt_cfg_transaction_t *txcb = editcb->txcb;
    boolean isvalidate = editcb->isvalidate;
    boolean isrunning = editcb->isrunning;
    const xmlChar *user_id = editcb->user_id;
    const xmlChar *client_addr = editcb->client_addr;
    const xmlChar *target = editcb->target;
    const xmlChar *txid_str = editcb->txid_str;
    const xmlChar *instance_id = editcb->instance_id;

    val_value_t *errorval = (curval) ? curval : newval;

    /* Invoke callbacks only for specific nodes from a
     * specific module. Skip callback for any nodes
     * that are not from 'sample' YANG module
     */
    if (xml_strcmp(modname, (const xmlChar *)"sample")) {
        if (LOGDEBUG) {
            log_debug("\n Skipping callback for module '%s'",
                      modname);
        }

        return res;
    } else {
        if (LOGDEBUG) {
            log_debug("\n (%s) Enter GLOBAL EDIT-3 callback"
                      "\n ------PHASE:%s;EDITOP:%s"
                      "\n ------Instance ID:%s\n",
                      errorval ? VAL_NAME(errorval) : NCX_NT_NONE,
                      agt_cbtype_name(cbtyp),
                      op_editop_name(editop),
                      instance_id);
        }
    }

    switch (cbtyp) {
    case AGT_CB_VALIDATE:
        /* description-stmt validation here */
        break;
    case AGT_CB_APPLY:
        /* database manipulation are performed by the server here */
        break;
    case AGT_CB_COMMIT:
        /* device instrumentation done here */
        if (op_editop_is_delete(editop)) {
            /* Delete all data from the device */

        } else {
            /* Use update value to update your device data
             *
             * The technique here is to replace the existing data
             * with this composite Update value.
             */

        }
        break;
    case AGT_CB_ROLLBACK:
        /* undo device instrumentation done in Apply Phase */
        break;
    default:
        FLAG_INT_ERROR;
        res = ERR_INTERNAL_VAL;
    }
    return res;

} /* sample_global_edit3 */

Global GET2 Callback

Note

SIL version of callback is available starting in version 23.10T-8. SIL-SA version of callback is available starting in version 23.10T-11. AIO support for SIL and SIL-SA is available starting in version 24.10-2.

The Global GET2 callback mechanism is a crucial part of the system's data retrieval infrastructure, designed to ensure a consistent and efficient approach to fetching data across various objects within a YANG model.

In instances where a specific GET2 callback has not been registered for a given object, the system will automatically revert to using the Global GET2 callback. This ensures that all GET2 requests are handled efficiently, without leaving any object without a corresponding callback mechanism.

Global GET2 Invocation Scenarios

The activation criteria for Global GET callbacks are critical for ensuring seamless data retrieval across the system.

This section delineates the specific scenarios under which Global GET callback is triggered, reflecting the system's strategic approach to handling GET requests efficiently and effectively.

  • Global Callback as Default: In the absence of any GET callbacks for a specific node, Global GET callback are automatically invoked for this node. This scenario establishes Global GET callback as a universal solution for handling data retrieval operations, ensuring that GET requests are addressed even without specific callback configurations.

  • Global Callback vs. GET1: When GET1 callback is configured for a node, Global GET callback is not activated for this node.

  • Global Callback vs. Remote: The system prefers remote GET callback over Global GET callback for a specific node when both are available.

  • Global Callback vs. NMDA: When NMDA is enabled and a <get-data> request targets the operational datastore, the system's response varies based on the configuration of GET callbacks:

    • If GET callback dedicated to a specific configurational data is present, GET callback is invoked.

    • If GET callback dedicated to a specific configurational data is NOT present, Global GET callback is invoked.

  • SIL vs SIL-SA Global Callback: The system must have only one or another. There cannot be SIL and SIL-SA Global Callbacks.

These scenarios outline how the system decides which callbacks to use under different configurations. By understanding these activation criteria, system developers and administrators can better anticipate the system's behavior in response to GET requests, ensuring efficient and accurate data handling.

Global All In One GET2 Callback

AIO support for SIL and SIL-SA is available starting in version 24.10-2.

In order to enable AIO, YANG extension must be specified for the top AIO node.

Refer for more details on how to setup AIO nodes here All In One GET2 Callback.

The entire subtree would be expected in one retrieval in one callback invocation. That’s if there AIO enabled node for a container, any complex nodes within this container will not have any extra callback invocations, they will be handled by the top AIO container callback during this Global callback invocation.

Global GET2 Callback Function

The Global GET2 callback uses the GET2 Callback Function template function.

Global GET2 Callback Initialization and Cleanup

SIL and SIL-SA callback initialization and cleanup functions are identical.

The Global GET2 callback is registered through a dedicated function, which should be called during the system Phase 1 initialization.

status_t agt_glob_register_get(getcb_fn2_t cbfn)

Register a Global GET2 callback.

This function registers a Global GET2 callback that will be called if there are no any other GET2 callbacks registered to the current target object.

Parameters:

cbfn -- address of GET2 callback function to use

Returns:

the status of operation

This registration is crucial for setting up the global handling mechanism for GET2 callbacks before the system starts processing any data retrieval requests.

Example init1 function:

static status_t init_interfaces (void)
{
    // ...

    res = agt_glob_register_get(sample_global_get2);
    if (res != NO_ERR) {
        return res;
    }

    // ...

} /* init_interfaces */

Use the agt_glob_unregister_get function to unregister Global GET callback.

static void interfaces_cleanup (void)
{
    agt_glob_unregister_get();
    return;
}

The unregister function needs to be called to unregister Global GET callback. If it is called multiple times, it will not produce errors.

Global GET2 Callback Example

This example demonstrates the effective use of the Global GET2 callback in real-world scenarios. It highlights the callback's ability to seamlessly handle retrieval across various nodes associated with a particular YANG module.

This example is suitable for SIL and SIL-SA versions.

/* GET2 TEST
 *
 * see ncx/getcb.h (getcb_fn2_t)
 */
static status_t
    sample_global_get2 (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);
    }
    status_t res = NO_ERR;

    obj_template_t *obj = GETCB_GET2_OBJ(get2cb);
    const xmlChar *modname = obj_get_mod_name(obj);

    /* Invoke callbacks only for specific nodes from a
     * specific module. Skip callback for any nodes
     * that are not from 'sample' YANG module
     */
    if (xml_strcmp(modname, (const xmlChar *)"sample")) {
        if (LOGDEBUG) {
            log_debug("\n Skipping callback for module '%s'",
                      modname);
        }

        return res;
    } else {
        /* Handle the retrieval */
        getcb_dump_get2cb(get2cb);
    }

    return res;

}  /* sample_global_get2 */

Global RPC Callback

Note

SIL version of callback is available starting in version 23.10T-8. SIL-SA version of callback is available starting in version 23.10T-11.

When a Global RPC callback is implemented, it serves as a universal handler for RPC operations throughout the system. This setup is particularly crucial when a specific RPC callback is not defined for a given data node. In such cases, if an RPC operation is initiated and no dedicated RPC callback is found for the targeted object, the system will default to the Global RPC callback for processing.

Global RPC Invocation Scenarios

Understanding the conditions under which Global RPC callbacks are triggered is essential for ensuring that the system operates efficiently and performs operations accurately.

Here is an outline of the scenarios that activate Global RPC callbacks:

  • Global RPC Callback as Default: If only Global RPC callback is set up and no other specific RPC callbacks exist, the system will utilize this Global RPC callback for any RPC operations, acting as a reliable fallback mechanism.

  • Global RPC Callback vs. Remote Callback: The system prefers a remote RPC callback over a Global RPC callback for RPC operations when both are available.

  • SIL vs SIL-SA Global Callback: The system must have only one or another. There cannot be SIL and SIL-SA Global Callbacks.

Global RPC Callback Function

The Global RPC callback uses the RPC Callback Template template function.

Global RPC Callback Initialization

SIL and SIL-SA callback initialization and cleanup functions are identical.

Global RPC callbacks are integrated into the server through specific registration functions, which are called during the system's Initialization Phase 1 before loading the startup configuration into the running configuration database.

The 'agt_glob_register_rpc' function in agt/agt_glob.h is used to provide a callback function for a specific callback phase. The same function can be used for multiple phases if desired.

status_t agt_glob_register_rpc(agt_rpc_phase_t phase, agt_rpc_method_t cbfn)

add callback for 1 phase of RPC processing

This function registers a Global RPC callback that will be called if there are no any other RPC callbacks registered to the current RPC target object.

Parameters:
  • phase -- RPC server callback phase for this callback

    • AGT_PH_VALIDATE(0): validate phase

    • AGT_PH_INVOKE(1): invoke phase

    • AGT_PH_POST_REPLY(2): post-reply phase

  • cbfn -- pointer to callback function to register

Returns:

status of the operation

Example Registration Code:

res =
   agt_glob_register_rpc(AGT_RPC_PH_VALIDATE,
                         global_rpc_validate);
if (res != NO_ERR) {
   return res;
}

res =
   agt_glob_register_rpc(AGT_RPC_PH_INVOKE,
                         global_rpc_invoke);
if (res != NO_ERR) {
   return res;
}

Global RPC Callback Cleanup

The 'agt_glob_unregister_rpc' function in agt/agt_glob.h is used to cleanup a callback function for all callback phases.

void agt_glob_unregister_rpc(void)

Unregister Global RPC callbacks.

This function unregisters Global RPC callbacks. All methods

To unregister Global RPC callbacks, use the appropriate function which needs to be called only once for all callback phases.

agt_glob_unregister_rpc();

Global RPC Validate Callback Example

This example shows the effective implementation of the Global RPC Validate callback in a real-world scenario. It illustrates how the callback seamlessly manages RPC operations across different nodes related to a specific YANG module.

This example is suitable for SIL and SIL-SA versions.

/*
 * @brief Validation phase callback for Global RPC\n
 *
 * All YANG constraints have passed at this point.
 * Add description-stmt checks in this function.
 *
 * @param scb session invoking the RPC operation.
 * @param msg message in progress for this <rpc> request.
 * The msg->rpc_input value node contains the input (if any).
 * It is a container matching the rpc/input node for the YANG rpc.
 * @param methnode XML node for the operation, which can be used
 * in error reporting (or ignored).
 * @return return status for the phase.
 *  - An error in validate phase will cancel invoke phase
 *  - An rpc-error will be added if an error is returned and
 * the msg error Q is empty
 */
static status_t
    global_rpc_validate (ses_cb_t *scb,
                         rpc_msg_t *msg,
                         xml_node_t *methnode)
{
    status_t res = NO_ERR;

    /* YANG module found for this node */
    const xmlChar *modname = methnode->module;

    /* qualified name of element */
    const xmlChar *qname = methnode->qname;

    /* element name without any prefix */
    const xmlChar *elname = methnode->elname;

    /* Invoke Global RPC callbacks only for module with a name sample */
    if (xml_strcmp(modname, (const xmlChar *)"sample")) {
        if (LOGDEBUG) {
            log_debug("\n Skipping VALIDATE callback for module '%s'",
                      modname);
        }

        return res;
    } else {
        if (LOGDEBUG) {
            log_debug("\n\nEnter GLOBAL RPC VALIDATE callback"
                      "\n modname=%s"
                      "\n RPC Qualified Name=%s"
                      "\n RPC Name=%s",
                      modname,
                      qname ? qname : NCX_NT_NONE,
                      elname ? elname : NCX_NT_NONE);
        }
    }

    /* Check RPC input to ensure it is required */
    val_value_t *inputval = agt_get_rpc_input(msg);
    if (inputval == NULL) {
        return ERR_NCX_OPERATION_FAILED;
    }

    /* Assign an error value in case any errors occur */
    val_value_t *errorval = NULL;


    /* Handle Input parameter here */


    if (res != NO_ERR) {
        agt_record_error(scb,
                         &msg->mhdr,
                         NCX_LAYER_OPERATION,
                         res,
                         methnode,
                         (errorval) ? NCX_NT_VAL : NCX_NT_NONE,
                         errorval,
                         (errorval) ? NCX_NT_VAL : NCX_NT_NONE,
                         errorval);
    }
    return res;

} /* global_rpc_validate */

Refer for more details on how to interact with input parameters here RPC Validate Callback Function

Global RPC Invoke Callback Example

This example shows the effective implementation of the Global RPC Invoke callback in a real-world scenario. It illustrates how the callback seamlessly manages RPC operations across different nodes related to a specific YANG module.

This example is suitable for SIL and SIL-SA versions.

/*
 * @brief Invocation phase callback for GLOBAL RPC\n
 *
 * Validation callback has passed at this point.
 * Call device instrumentation code in this function.
 *
 * @param scb session invoking the RPC operation.
 * @param msg message in progress for this <rpc> request.
 * The msg->rpc_input value node contains the input (if any).
 * It is a container matching the rpc/input node for the YANG rpc.
 * @param methnode XML node for the operation, which can be used
 * in error reporting (or ignored).
 * @return return status for the phase.
 *  - An error in validate phase will cancel invoke phase
 *  - An rpc-error will be added if an error is returned and
 * the msg error Q is empty
 */
static status_t
    global_rpc_invoke (ses_cb_t *scb,
                       rpc_msg_t *msg,
                       xml_node_t *methnode)
{
    status_t res = NO_ERR;

    /* YANG module found for this node */
    const xmlChar *modname = methnode->module;

    /* qualified name of element */
    const xmlChar *qname = methnode->qname;

    /* element name without any prefix */
    const xmlChar *elname = methnode->elname;

    /* Invoke Global RPC callbacks only for module with a name sample */
    if (xml_strcmp(modname, (const xmlChar *)"sample")) {
        if (LOGDEBUG) {
            log_debug("\n Skipping INVOKE callback for module '%s'",
                      modname);
        }

        return res;
    } else {
        if (LOGDEBUG) {
            log_debug("\n\nEnter GLOBAL RPC INVOKE callback"
                      "\n modname=%s"
                      "\n RPC Qualified Name=%s"
                      "\n RPC Name=%s",
                      modname,
                      qname ? qname : NCX_NT_NONE,
                      elname ? elname : NCX_NT_NONE);
        }
    }

    /* Check RPC input to ensure it is required */
    val_value_t *inputval = agt_get_rpc_input(msg);
    if (inputval == NULL) {
        return ERR_NCX_OPERATION_FAILED;
    }

    /* remove the next line if scb is used */
    (void)scb;

    /* invoke your device instrumentation code here */

    obj_template_t *outputobj = agt_get_rpc_output_obj(msg);
    if (outputobj == NULL) {
        return ERR_NCX_OPERATION_FAILED;
    }

    /* Handle Output parameters here */

    return res;

} /* global_rpc_invoke */

Refer for more details on how to interact with input/output parameters here RPC Invoke Callback Function

Global Action Callback

Note

SIL version of callback is available starting in version 23.10T-8. SIL-SA version of callback is available starting in version 23.10T-11.

When a Global Action callback is implemented, it serves as a universal handler for Action operations throughout the system.

Refer for more details about Action Callbacks here Action Callbacks.

Global Action Invocation Scenarios

Understanding the conditions under which Global Action callbacks are triggered is essential for ensuring that the system operates efficiently and performs operations accurately.

Here is an outline of the scenarios that activate Global Action callbacks:

  • Global Action Callback as Default: If only a Global Action callback is set up and no other specific Action callbacks exist, the system will utilize this Global Action callback for any Action operations, acting as a reliable fallback mechanism.

  • Global Action Callback vs. Remote Callback: The system prefers remote Action callbacks over Global Action callbacks for Action operations when both are available.

  • SIL vs SIL-SA Global Callback: The system must have only one or another. There cannot be SIL and SIL-SA Global Callbacks.

Global Action Callback Function

The Global Action callback uses the Action Callback Template template function.

Global Action Callback Initialization

SIL and SIL-SA callback initialization and cleanup functions are identical.

Global Action callbacks are integrated into the server through specific registration functions, which are called during the system's Initialization Phase 1 before loading the startup configuration into the running configuration database.

Refer to Action Callback Initialization for more details on initialization.

The 'agt_glob_register_action' function in agt/agt_glob.h is used to provide a callback function for a specific callback phase. The same function can be used for multiple phases if desired.

status_t agt_glob_register_action(agt_rpc_phase_t phase, agt_action_cb_t action_cb)

add callback for 1 phase of Global Action processing

Parameters:
  • phase -- action server callback phase for this callback

    • AGT_PH_VALIDATE(0): validate phase

    • AGT_PH_INVOKE(1): invoke phase

    • AGT_PH_POST_REPLY(2): post-reply phase

  • action_cb -- pointer to callback function to register

Returns:

status of the operation

Example Registration Code:

res =
   agt_glob_register_action(AGT_RPC_PH_VALIDATE,
                            global_action_validate);
if (res != NO_ERR) {
   return res;
}

res =
   agt_glob_register_action(AGT_RPC_PH_INVOKE,
                            global_action_invoke);
if (res != NO_ERR) {
   return res;
}

Global Action Callback Cleanup

The 'agt_glob_unregister_action' function in agt/agt_glob.h is used to cleanup a callback function for all callback phases.

void agt_glob_unregister_action(void)

remove all Global callbacks for all phases of action processing

To unregister Global Action callbacks, use the appropriate function which needs to be called only once for all callback phases.

agt_glob_unregister_action();

Global Action Validate Callback Example

This example shows the effective implementation of the Global Action Validate callback in a real-world scenario. It illustrates how the callback seamlessly manages Action operations across different nodes related to a specific YANG module.

This example is suitable for SIL and SIL-SA versions.

/*
 * @brief YANG 1.1 global action validate callback. (agt_action_cb_t)\n
 *
 * @param scb session invoking the "<action>" RPC
 * @param msg message in progress for this "<rpc>" request
 * @param methnode XML node for the operation, which can be used
 * in error reporting (or ignored).
 * @param actionval the nested 'action-method-name' node that was parsed
 * within the topval subtree, in the RPC "<action>" request.
 * This is used to help derive the list keys.
 * @return return status for the phase.
 *  - An error in validate phase will cancel invoke phase
 *  - An rpc-error will be added if an error is returned and
 * the msg error Q is empty
 */
static status_t
    global_action_validate (ses_cb_t *scb,
                            rpc_msg_t *msg,
                            xml_node_t *methnode,
                            val_value_t *actionval)
{
    status_t res = NO_ERR;

    /* YANG module found for this node */
    const xmlChar *modname = methnode->module;

    /* qualified name of element */
    const xmlChar *qname = methnode->qname;

    /* element name without any prefix */
    const xmlChar *elname = methnode->elname;

    /* Invoke Global Action callbacks only for module with a name sample */
    if (xml_strcmp(modname, (const xmlChar *)"sample")) {
        if (LOGDEBUG) {
            log_debug("\n Skipping VALIDATE callback for module '%s'",
                      modname);
        }

        return res;
    } else {
        if (LOGDEBUG) {
            log_debug("\n\nEnter GLOBAL ACTION VALIDATE callback"
                      "\n modname=%s"
                      "\n Action Qualified Name=%s"
                      "\n Action Name=%s",
                      modname,
                      qname ? qname : NCX_NT_NONE,
                      elname ? elname : NCX_NT_NONE);
        }
    }

    /* Assign an error value in case any errors occur */
    val_value_t *errorval = NULL;


    /* Handle Action Input parameter here */
    (void)actionval;

    if (res != NO_ERR) {
        agt_record_error(scb,
                         &msg->mhdr,
                         NCX_LAYER_OPERATION,
                         res,
                         methnode,
                         (errorval) ? NCX_NT_VAL : NCX_NT_NONE,
                         errorval,
                         (errorval) ? NCX_NT_VAL : NCX_NT_NONE,
                         errorval);
    }
    return res;

} /* global_action_validate */

Refer for more details on how to interact with input parameters here Action Validate Callback Function

Global Action Invoke Callback Example

This example shows the effective implementation of the Global Action Invoke callback in a real-world scenario. It illustrates how the callback seamlessly manages Action operations across different nodes related to a specific YANG module.

This example is suitable for SIL and SIL-SA versions.

/*
 * @brief YANG 1.1 global action invoke callback. (agt_action_cb_t)\n
 *
 * @param scb session invoking the "<action>" RPC
 * @param msg message in progress for this "<rpc>" request
 * @param methnode XML node for the operation, which can be used
 * in error reporting (or ignored).
 * @param actionval the nested 'action-method-name' node that was parsed
 * within the topval subtree, in the RPC "<action>" request.
 * This is used to help derive the list keys.
 * @return return status for the phase.
 *  - An error in validate phase will cancel invoke phase
 *  - An rpc-error will be added if an error is returned and
 * the msg error Q is empty
 */
static status_t
    global_action_invoke (ses_cb_t *scb,
                          rpc_msg_t *msg,
                          xml_node_t *methnode,
                          val_value_t *actionval)
{
    status_t res = NO_ERR;

    /* YANG module found for this node */
    const xmlChar *modname = methnode->module;

    /* qualified name of element */
    const xmlChar *qname = methnode->qname;

    /* element name without any prefix */
    const xmlChar *elname = methnode->elname;

    /* Invoke Global Action callbacks only for module with a name sample */
    if (xml_strcmp(modname, (const xmlChar *)"sample")) {
        if (LOGDEBUG) {
            log_debug("\n Skipping INVOKE callback for module '%s'",
                      modname);
        }

        return res;
    } else {
        if (LOGDEBUG) {
            log_debug("\n\nEnter GLOBAL ACTION INVOKE callback"
                      "\n modname=%s"
                      "\n Action Qualified Name=%s"
                      "\n Action Name=%s",
                      modname,
                      qname ? qname : NCX_NT_NONE,
                      elname ? elname : NCX_NT_NONE);
        }
    }

    /* Handle Action Input parameter here */
    (void)actionval;

    /* remove the next line if msg is used */
    (void)msg;

    /* remove the next line if scb is used */
    (void)scb;

    /* remove the next line if methnode is used */
    (void)methnode;

    /* invoke your device instrumentation code here */

    /* Handle Output parameters here */

    return res;

} /* global_action_invoke */

Refer for more details on how to interact with input/output parameters here Action Invoke Callback Function