This example shows the build steps and run-time message flows for a custom RPC operation.



Example YANG Module

module myrpc {
  namespace "http://www.netconfcentral.org/ns/yang/myrpc";
  prefix "m";

  revision "2020-02-04";

  rpc myrpc {
    description "Example RPC returns <ok>";
    input {
      leaf parm1 {
        type string;
        description "example input parameter";
      }
    }
  }
}


1) Generate the SIL-SA Library


  • Copy the YANG module myrpc.yang to a directory where the client and server can find it, like $HOME/modules/ directory
  • Make sure the SDK tools are properly installed
  • Use the make_sil_sa_dir script to generate the 'myrpc' source tree


> make_sil_sa_dir myrpc

Example:

andy@andy-i7-dev:~/X$ make_sil_sa_dir myrpc
modparms = 

Add --sil-get2 because --sil-sa present (GET1 not supported)
*** /home/andy/modules/myrpc.yang
*** 0 Errors, 0 Warnings


Add --sil-get2 because --sil-sa present (GET1 not supported)
*** /home/andy/modules/myrpc.yang
*** 0 Errors, 0 Warnings

andy@andy-i7-dev:~/X$ 


2) Build and Install the SIL-SA Library


  • The stub code generated by yangdump-sdk supports the new RPC operation without any modification.
  • The empty stub code does not implement the RPC in the system. You have to add this code.
  • There are some C compiler warnings generated in the stub code because the variables are not used yet. You should fill in the stub code and these warnings should go away.
  • Verify the SIL-SA library is installed in the /usr/lib/yumapro directory
  • Note that the library name contains the string "_sa". This prevents netconfd-pro from loading the library and enables sil-sa-app to load the library instead.


> cd myrpc
> make
> sudo make install
> ls -l /usr/lib/yumapro/libmyrpc_sa.so

Example:

andy@andy-i7-dev:~/X$ cd myrpc/
andy@andy-i7-dev:~/X/myrpc$ make
for dir in src; do\
  cd $dir && make && cd ..;\
        done
make[1]: Entering directory '/home/andy/X/myrpc/src'
Makefile:322: dependencies: No such file or directory
cc -MM -MG -MT ../bin/myrpc.o \
-Wall -Wcomment   -I. -I/usr/include/yumapro/platform -I/usr/include/yumapro/ncx -I/usr/include/yumapro/agt -I/usr/include/yumapro/sil-sa -I/usr/include/yumapro/ycontrol -I/usr/include -I/usr/include/libxml2 -I/usr/include/libxml2/libxml \
  -c myrpc.c > myrpc.D
cc -O2 -DDEBUG=1 -DLINUX=1 -DGCC=1 -DHAS_FLOAT=1 -Wall -Wno-long-long -Wformat-y2k -Winit-self -Wswitch-default -Wextra -Wundef -Wshadow -Wpointer-arith -Wwrite-strings -Wbad-function-cast -Wcast-qual -Waggregate-return -Wstrict-prototypes -Wold-style-definition -Wmissing-prototypes -Wmissing-declarations -Winvalid-pch -Wredundant-decls -Wnested-externs -Winline -std=gnu99 -Werror=incompatible-pointer-types -fPIC   \
        -I. -I/usr/include/yumapro/platform -I/usr/include/yumapro/ncx -I/usr/include/yumapro/agt -I/usr/include/yumapro/sil-sa -I/usr/include/yumapro/ycontrol -I/usr/include -I/usr/include/libxml2 -I/usr/include/libxml2/libxml   -c -o ../bin/myrpc.o myrpc.c
myrpc.c: In function ‘y_myrpc_myrpc_validate’:
myrpc.c:110:20: warning: variable ‘v_parm1’ set but not used [-Wunused-but-set-variable]
     const xmlChar *v_parm1;
                    ^~~~~~~
myrpc.c: In function ‘y_myrpc_myrpc_invoke’:
myrpc.c:165:20: warning: variable ‘v_parm1’ set but not used [-Wunused-but-set-variable]
     const xmlChar *v_parm1;
                    ^~~~~~~
cc -O2 -DDEBUG=1 -DLINUX=1 -DGCC=1 -DHAS_FLOAT=1 -Wall -Wno-long-long -Wformat-y2k -Winit-self -Wswitch-default -Wextra -Wundef -Wshadow -Wpointer-arith -Wwrite-strings -Wbad-function-cast -Wcast-qual -Waggregate-return -Wstrict-prototypes -Wold-style-definition -Wmissing-prototypes -Wmissing-declarations -Winvalid-pch -Wredundant-decls -Wnested-externs -Winline -std=gnu99 -Werror=incompatible-pointer-types -fPIC   -shared -rdynamic -Wl,-soname,libmyrpc.so -o ../lib/libmyrpc.so ../bin/myrpc.o
make[1]: Leaving directory '/home/andy/X/myrpc/src'
andy@andy-i7-dev:~/X/myrpc$ sudo make install
for dir in src; do\
          cd $dir && make install && cd ..;\
        done
make[1]: Entering directory '/home/andy/X/myrpc/src'
mkdir -p /usr/lib/yumapro
install ../lib/libmyrpc.so \
        /usr/lib/yumapro/libmyrpc_sa.so
make[1]: Leaving directory '/home/andy/X/myrpc/src'
andy@andy-i7-dev:~/X/myrpc$ sudo make install
for dir in src; do\
          cd $dir && make install && cd ..;\
        done
make[1]: Entering directory '/home/andy/X/myrpc/src'
mkdir -p /usr/lib/yumapro
install ../lib/libmyrpc.so \
        /usr/lib/yumapro/libmyrpc_sa.so
make[1]: Leaving directory '/home/andy/X/myrpc/src'
andy@andy-i7-dev:~/X/myrpc$ 
andy@andy-i7-dev:~/X/myrpc$ ls -l /usr/lib/yumapro/libmyrpc_sa.so
-rwxr-xr-x 1 root root 8336 Feb  4 10:01 /usr/lib/yumapro/libmyrpc_sa.so
andy@andy-i7-dev:~/X/myrpc$ 


3) Start the Server and sil-sa-app


  • Start the netconfd-pro server and sil-sa-app program. They can be started in any order.


> netconfd-pro --log-level=debug2 --module=myrpc

In another terminal window:

> sil-sa-app --log-level=debug2


The server and sil-sa-app process will send YControl messages back and forth.

The sil-sa-app will register with the server to handle the myrpc operation

The following example from the server log file shows this register-request message


<?xml version="1.0" encoding="UTF-8"?>
<ycontrol xmlns="http://yumaworks.com/ns/yumaworks-ycontrol">
 <message-id>2</message-id>
 <message-type>subsys-request</message-type>
 <server-id>server1</server-id>
 <subsys-id>subsys1</subsys-id>
 <service-id>sil-sa</service-id>
 <payload>
  <sil-sa xmlns="http://yumaworks.com/ns/yumaworks-sil-sa">
   <register-request>
    <register>
     <module>myrpc</module>
     <rpc-name>myrpc</rpc-name>
    </register>
   </register-request>
  </sil-sa>
 </payload>
</ycontrol>


4) Send the RPC request to the server


  • Use yangcli-pro or another client program to send an RPC request to the server 


<?xml version="1.0" encoding="UTF-8"?>
<rpc message-id="3"
 xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
 <myrpc xmlns="http://www.netconfcentral.org/ns/yang/myrpc">
  <parm1>test1</parm1>
 </myrpc>
</rpc>


5) Server sends RPC Request to the Subsystem


The server will send an <rpc-request> message to the sil-sa-app subsystem


<?xml version="1.0" encoding="UTF-8"?>
<ycontrol xmlns:ya="http://yumaworks.com/ns/yumaworks-attrs"
 xmlns="http://yumaworks.com/ns/yumaworks-ycontrol">
 <message-id>2</message-id>
 <message-type>server-request</message-type>
 <server-id>server1</server-id>
 <subsys-id>subsys1</subsys-id>
 <service-id>sil-sa</service-id>
 <payload>
  <sil-sa xmlns="http://yumaworks.com/ns/yumaworks-sil-sa">
   <rpc-request>
    <transaction-id>R2</transaction-id>
    <user-id>andy</user-id>
    <client-addr>127.0.0.1</client-addr>
    <rpc-module>myrpc</rpc-module>
    <rpc-name>myrpc</rpc-name>
    <rpc-input ya:datapath="/m:myrpc/m:input">
     <parm1 xmlns="http://www.netconfcentral.org/ns/yang/myrpc">test1</parm1>
    </rpc-input>
   </rpc-request>
  </sil-sa>
 </payload>
</ycontrol>


6) Subsystem Processes the RPC Request


The sil-sa-app will process the RPC request and invoke the validate and invoke callbacks in myrpc.c.


yc_parse: Overriding datapath obj 'rpc-input' with '/m:myrpc/m:input'
ycontrol: dispatch message to service 'sil-sa'
Start SIL validate rpc <myrpc> from module myrpc
Start SIL invoke rpc <myrpc> from module myrpc
ycontrol_msg: sending subsys-response # 2 for sil-sa
ses_msg: reused out buff 0x55ae82dab130 for s 1
ses_msg: free msg 0x55ae82dda020 for session 1
ses got send request on session 1
ses_msg: send 1.1 buff:521 for s:1


7) Subsystem Sends an RPC Response to the Server


The sil-sa-app will send an <rpc-response> message to the server


<?xml version="1.0" encoding="UTF-8"?>
<ycontrol xmlns:ya="http://yumaworks.com/ns/yumaworks-attrs"
 xmlns="http://yumaworks.com/ns/yumaworks-ycontrol">
 <message-id>2</message-id>
 <message-type>subsys-response</message-type>
 <server-id>server1</server-id>
 <subsys-id>subsys1</subsys-id>
 <service-id>sil-sa</service-id>
 <payload>
  <sil-sa xmlns="http://yumaworks.com/ns/yumaworks-sil-sa">
   <rpc-response>
    <transaction-id>R2</transaction-id>
    <rpc-ok/>
   </rpc-response>
  </sil-sa>
 </payload>
</ycontrol>


8) Server Processes the Subsystem Response and Sends Reply to Client


The server will then process this message and send an <rpc-reply> message to the client


agt_sil: adding data response 2 for subsys subsys1
agt_top: end dispatch yumaworks-ycontrol:ycontrol
ses_msg: free msg 0x5579c9a9b880 for session 3
ycontrol_mode_done for TXID 'R2'
agt_rpc: start results for 'subsys1' (ok)

agt_rpc: Got rpc-ok from subsys 'subsys1'
agt_rpc: sending ok <rpc-reply> for ses 4 msg '3'

<?xml version="1.0" encoding="UTF-8"?>
<rpc-reply message-id="3"
 xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
 <ok/>
</rpc-reply>