The server supports RPC operations defined in any YANG module, and the code can be contained in a SIL library.

There are 3 simple steps for returning data in an RPC operation:

  1. Create a val_value_t node for each data node to be returned
  2. Add data to the rpc_dataQ in the repsonse message
  3. Set the data type in the response message


    dlq_enque(msgindentval, &msg->rpc_dataQ);
    msg->rpc_data_type = RPC_DATA_YANG;



Consider this simple RPC operation <get-my-session> from yuma-mysession.yang:


  grouping session-params {
    uses appcmn:IndentParm;
      
    leaf linesize {
      description
        "The desired maximum number of characters printed
         per line.  The server may exceed this number.
         It is only a suggestion, not a hard limit.";
      type uint32 { range "40 .. 1024"; }
      default 72;
    }
    leaf with-defaults {
      description
        "The desired maximum number of characters printed
         per line.  The server may exceed this number.
         It is only a suggestion, not a hard limit.";
      type wd:with-defaults-mode;
    }
    leaf message-indent {
      type int8 {
        range "-1 .. 9";
      }
      default -1;
      description
        "The number of spaces to indent for each level of
         output in a protocol message, e.g. NETCONF request.
         The value zero means no indent, just line feeds.
         The value -1 means no indent and no line feeds either.";
    }
  }

  rpc get-my-session {
    description
      "Get the customization settings for this session";
    output {
      uses session-params;
    }
  }        

  rpc set-my-session {
    description
      "Set the customization settings for this session.
       This is like a merge operation.  Only the values that
       are present will be used to overwrite the existing
       settings.";
    input {
      uses session-params;
    }
  }        



Since there are no input parameters for the <get-my-session> operation, there is no need for an RPC validate callback. The RPC invoke callback is needed. The source code from netconf/src/agt/agt_ses.c is shown below:


/********************************************************************
* FUNCTION get_my_session_invoke
*
* get-my-session : invoke params callback
*
* INPUTS:
*    see rpc/agt_rpc.h
* RETURNS:
*    status
*********************************************************************/
static status_t
    get_my_session_invoke (ses_cb_t *scb,
                           rpc_msg_t *msg,
                           xml_node_t *methnode)
{
    (void)methnode;

    xmlChar numbuff[NCX_MAX_NUMLEN];

    /* indent */
    snprintf((char *)numbuff, sizeof(numbuff), "%d", scb->indent);
    val_value_t *indentval =
        val_make_string(mysesmod->nsid, NCX_EL_INDENT, numbuff);
    if (indentval == NULL) {
        return ERR_INTERNAL_MEM;
    }

    /* linesize */
    snprintf((char *)numbuff, sizeof(numbuff), "%u", scb->linesize);
    val_value_t *linesizeval =
        val_make_string(mysesmod->nsid, NCX_EL_LINESIZE, numbuff);
    if (linesizeval == NULL) {
        val_free_value(indentval);
        return ERR_INTERNAL_MEM;
    }

    /* with-defaults */
    val_value_t *withdefval =
        val_make_string(mysesmod->nsid,
                        NCX_EL_WITH_DEFAULTS,
                        ncx_get_withdefaults_string(scb->withdef));
    if (withdefval == NULL) {
        val_free_value(indentval);
        val_free_value(linesizeval);
        return ERR_INTERNAL_MEM;
    }

    /* message-indent */
    snprintf((char *)numbuff, sizeof(numbuff), "%d", scb->msg_indent);
    val_value_t *msgindentval =
        val_make_string(mysesmod->nsid, NCX_EL_MESSAGE_INDENT, numbuff);
    if (msgindentval == NULL) {
        val_free_value(indentval);
        val_free_value(linesizeval);
        val_free_value(withdefval);
        return ERR_INTERNAL_MEM;
    }

    dlq_enque(indentval, &msg->rpc_dataQ);
    dlq_enque(linesizeval, &msg->rpc_dataQ);
    dlq_enque(withdefval, &msg->rpc_dataQ);
    dlq_enque(msgindentval, &msg->rpc_dataQ);

    msg->rpc_data_type = RPC_DATA_YANG;
    return NO_ERR;

} /* get_my_session_invoke */