Create actionpoint to rpc

Hi I have rpc as below:

module: o-ran-supervision
  rpcs:
    +---x supervision-watchdog-reset
       +---w input
       |  +---w supervision-notification-interval?   
       |  +---w guard-timer-overhead?                
       +--ro output
          +--ro next-update-at? 

I would like to create actionpoint on supervision-watchdog-reset.
I have created annotation file like :

   module o-ran-supervision-ann {
    yang-version 1.1;
    namespace "urn:ietf:params:xml:ns:yang:o-ran-supervision:1.0";
     prefix o-ran-supervision-ann;
     import o-ran-supervision {
    prefix super;
  }
  import tailf-common {
    prefix tailf;
  }
tailf:annotate "/super:supervision-watchdog-reset" {
tailf:actionpoint cb_supervision;
      }
}

Build procedure:

$CONFD_DIR/bin/confdc  -c -o o-ran-wg4-features.fxs o-ran-wg4-features.yang
$CONFD_DIR/bin/confdc --annotate o-ran-supervision-ann.yang -c --no-features -o o-ran-supervision.fxs o-ran-supervision.yang
$CONFD_DIR/bin/confdc --emit-h o-ran-supervision.h o-ran-supervision.fxs
cc -c -o call-home.o call-home.c -Wall -g -I$CONFD_DIR/include
cc -o call-home call-home.o $CONFD_DIR/lib/libconfd.a -lpthread -lm

But while running it is failing while calling confd_register_done API
Console Log:

/home/biswajit/ConfD/install//bin/confd -c confd.conf --addloadpath /home/biswajit/ConfD/install//etc/confd --ignore-initial-validation

PATH=/sbin:/usr/sbin:$PATH ./call-home 
TRACE Connected (maapi) to ConfD
TRACE MAAPI_LOAD_ALL_NS
TRACE MAAPI_LOAD_MNS_MAPS
TRACE MAAPI_LOAD_HASH_DB
TRACE Connected (dp) to ConfD
TRACE Received daemon id 0
TRACE Connected (dp) to ConfD
TRACE Picked up old user session: 12 for user:system ctx:system
TRACE Picked up old user session: 11 for user:system ctx:system
TRACE Picked up old user session: 10 for user:system ctx:system
TRACE Picked up old user session: 1 for user:system ctx:system
DEBUG Not allowed after confd_register_done()
Failed to complete registration 
make: *** [Makefile:60: start] Error 1

Sample code:

    static int init_action(struct confd_user_info *uinfo)
    {
    int ret = CONFD_OK;

    printf("init_action called\n");
    confd_action_set_fd(uinfo, workersock);
    return ret;
    }

    static int abort_action(struct confd_user_info *uinfo) {
    fprintf(stderr, "Aborting outstanding action\n");
    /* We need to clean  up the worker socket by replying */
    confd_action_delayed_reply_error(uinfo, "aborted");
    return CONFD_OK;
     }
    static int do_action(struct confd_user_info *uinfo,
                     struct xml_tag *name,
                     confd_hkeypath_t *kp,
                     confd_tag_value_t *params,
                     int n)
      {
    int i;
    char buf[BUFSIZ];

    printf("do_action called\n");

    for (i = 0; i < n; i++) {
        confd_pp_value(buf, sizeof(buf), CONFD_GET_TAG_VALUE(&params[i]));
        printf("param %2d: %9u:%-9u, %s\n", i, CONFD_GET_TAG_NS(&params[i]),
               CONFD_GET_TAG_TAG(&params[i]), buf);
        }
     }

    int main(int argc, char *argv[])
    {
     struct sockaddr_in addr;
       int debuglevel = CONFD_TRACE;
       //struct confd_trans_cbs trans;
       //struct confd_data_cbs data;
       struct confd_action_cbs acb;

      /* Initialize confd library */

       confd_init("dataprovider", stderr, debuglevel);

      addr.sin_addr.s_addr = inet_addr("127.0.0.1");
       addr.sin_family = AF_INET;
       addr.sin_port = htons(CONFD_PORT);

       if (confd_load_schemas((struct sockaddr*)&addr,
                         sizeof (struct sockaddr_in)) != CONFD_OK)
    confd_fatal("Failed to load schemas from confd\n");

     if ((dctx = confd_init_daemon("callhome")) == NULL)
         confd_fatal("Failed to initialize daemon\n");

      /* Create and connect the control and worker sockets */

      if ((ctlsock = socket(PF_INET, SOCK_STREAM, 0)) < 0 )
        confd_fatal("Failed to open ctlsocket\n");
       if (confd_connect(dctx, ctlsock, CONTROL_SOCKET, (struct sockaddr*)&addr,
                    sizeof (struct sockaddr_in)) < 0)
      confd_fatal("Failed to confd_connect() to confd \n");

      if ((workersock = socket(PF_INET, SOCK_STREAM, 0)) < 0 )
       confd_fatal("Failed to open workersocket\n");
       if (confd_connect(dctx, workersock, WORKER_SOCKET,(struct sockaddr*)&addr,
                    sizeof (struct sockaddr_in)) < 0)
        confd_fatal("Failed to confd_connect() to confd \n");

       //init_db();
        /* Register callbacks */
     memset(&acb, 0, sizeof(acb));
     acb.init = init_action;
     acb.action = do_action;
     acb.abort = abort_action;
     strcpy(acb.actionpoint, "cb_supervision");
       if (confd_register_action_cbs(dctx, &acb) != CONFD_OK)
         fail("Couldn't register action callbacks");
       if (confd_register_done(dctx) != CONFD_OK)
        fail("Couldn't complete callback registration");


       if (confd_register_done(dctx) != CONFD_OK)
           confd_fatal("Failed to complete registration \n");

       while(1) {
          struct pollfd set[2];
         int ret;

        set[0].fd = ctlsock;
       set[0].events = POLLIN;
       set[0].revents = 0;

       set[1].fd = workersock;
       set[1].events = POLLIN;
       set[1].revents = 0;

        if (poll(set, sizeof(set)/sizeof(set[0]), -1) < 0) {
         perror("Poll failed:");
         continue;
         }

       /* Check for I/O */
        if (set[0].revents & POLLIN) {
         if ((ret = confd_fd_ready(dctx, ctlsock)) == CONFD_EOF) {
              confd_fatal("Control socket closed\n");
           } else if (ret == CONFD_ERR && confd_errno != CONFD_ERR_EXTERNAL) {
              confd_fatal("Error on control socket request: %s (%d): %s\n",
                    confd_strerror(confd_errno), confd_errno, confd_lasterr());
           }
         }
             if (set[1].revents & POLLIN) {
            if ((ret = confd_fd_ready(dctx, workersock)) == CONFD_EOF) {
                 confd_fatal("Worker socket closed\n");
           } else if (ret == CONFD_ERR && confd_errno != CONFD_ERR_EXTERNAL) {
              confd_fatal("Error on worker socket request: %s (%d): %s\n",
                    confd_strerror(confd_errno), confd_errno, confd_lasterr());
                }
            }
        }
     }

If you can figure out the root cause then it will be really helpful for me.

Regards,
Biswajit

It looks like from the code you included you are calling confd_register_done() twice. I think the second time you call this, this will cause the return “Not allowed after confd_register_done()”