# Same callback is getting invoked for both get & set operation

**URL:** <https://dmap-community.ductus.global/t/same-callback-is-getting-invoked-for-both-get-set-operation/4139>\
**Category:** YANG\
**Created:** [July 11, 2022, 10:52am UTC](https://dmap-community.ductus.global/t/same-callback-is-getting-invoked-for-both-get-set-operation/4139 "2022-07-11T10:52:10Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![biswajit](https://avatars.discourse-cdn.com/v4/letter/b/e56c9b/32.png) [@biswajit](https://dmap-community.ductus.global/u/biswajit)\
**Post date:** [July 11, 2022, 10:52am UTC](https://dmap-community.ductus.global/t/same-callback-is-getting-invoked-for-both-get-set-operation/4139/1 "2022-07-11T10:52:10Z")

</div>

Hi,  
The callpoint is subscribed to rw field. When i am trying to set few fields of that then get\_elem callback is getting invoked. If its expected then is there any way when i will be trying to perform set operation, then before the db gets updated the callback will get invoked. Because currently once DB gets updated, successfully then only set\_elem callback is getting invoked.

Regards,  
Biswajit

---

<div class="post-metadata">

**Author:** ![cohult](https://yyz2.discourse-cdn.com/flex010/user_avatar/dmap-community.ductus.global/cohult/32/221_2.png) [@cohult](https://dmap-community.ductus.global/u/cohult)\
**Post date:** [July 11, 2022, 7:25pm UTC](https://dmap-community.ductus.global/t/same-callback-is-getting-invoked-for-both-get-set-operation/4139/2 "2022-07-11T19:25:57Z")

</div>

When you set something over a northbound interface, e.g. CLI, NETCONF, RESTCONF, etc. you start a transaction. ConfD will as part of the transaction read the existing data, here using get\_elem() for a few good reasons to, for example, calculate a “minimum diff” so that the set\_elem() callback will not be called for a value that is already set to the same value.

See for example ConfD UG chapter " User sessions and ConfD Transactions" and the confd\_lib\_dp(3) man page under the confd\_register\_trans\_cb() function for more details on transactions.

---

<div class="post-metadata">

**Author:** ![biswajit](https://avatars.discourse-cdn.com/v4/letter/b/e56c9b/32.png) [@biswajit](https://dmap-community.ductus.global/u/biswajit)\
**Post date:** [July 12, 2022, 12:07pm UTC](https://dmap-community.ductus.global/t/same-callback-is-getting-invoked-for-both-get-set-operation/4139/3 "2022-07-12T12:07:10Z")

</div>

Hi Conny,  
thanks a lot for you input.  
I am facing two problems now:  
1.Even if i am creating new list entry still before the set\_element call back, get\_element call back is getting invoked.  
1.As a consequence, i am not able to figure out whether the get\_element call back is getting called for “get” operation or for edit-config request.  
2.If you have answer for that, then if you can provide a method to read the data which has been passed on edit-config request then I will be able to provide the same in CONFD\_SET\_STR API.

Regards,  
Biswajit

---

<div class="post-metadata">

**Author:** ![cohult](https://yyz2.discourse-cdn.com/flex010/user_avatar/dmap-community.ductus.global/cohult/32/221_2.png) [@cohult](https://dmap-community.ductus.global/u/cohult)\
**Post date:** [July 12, 2022, 1:23pm UTC](https://dmap-community.ductus.global/t/same-callback-is-getting-invoked-for-both-get-set-operation/4139/4 "2022-07-12T13:23:54Z")

</div>

> [@biswajit](#):
>
> 1.Even if i am creating new list entry still before the set\_element call back, get\_element call back is getting invoked.  
> 1.As a consequence, i am not able to figure out whether the get\_element call back is getting called for “get” operation or for edit-config request

Not that I understand why that matters, it should not for a normal use case, but  
see confd\_trans\_ctx-\>confd\_user\_info-\>context and confd\_trans\_ctx-\>confd\_trans\_mode. Refer to the $CONFD\_DIR/include/confd\_lib.h file for details.

> [@biswajit](#):
>
> 2.If you have answer for that, then if you can provide a method to read the data which has been passed on edit-config request then I will be able to provide the same in CONFD\_SET\_STR API.

If you are not using CDB, but have a callpoint that you register callbacks to, you can accumulate the resulting change operations and derive the data from the edit\_config from them. However, I do not understand why you use a DP API callpoint if that is what you want to do?

---

<div class="post-metadata">

**Author:** ![biswajit](https://avatars.discourse-cdn.com/v4/letter/b/e56c9b/32.png) [@biswajit](https://dmap-community.ductus.global/u/biswajit)\
**Post date:** [July 13, 2022, 6:59pm UTC](https://dmap-community.ductus.global/t/same-callback-is-getting-invoked-for-both-get-set-operation/4139/5 "2022-07-13T18:59:42Z")

</div>

Hi Conny,  
we have o-ran-interface.yang which is as below:  
module: o-ran-interfaces

```
augment /if:interfaces/if:interface:
+--rw l2-mtu?             
+--rw alias-macs*         
+--rw vlan-tagging?       
+--rw class-of-service
   +--rw u-plane-marking?            
   +--rw c-plane-marking?            
   +--rw m-plane-marking?            
   +--rw s-plane-marking?            
   +--rw other-marking?              
   +--rw enhanced-uplane-markings* [up-marking-name]
      +--rw up-marking-name     
      +--rw enhanced-marking?   
augment /if:interfaces/if:interface:
+--rw base-interface?   
+--rw vlan-id?          
augment /if:interfaces/if:interface:
+--rw mac-address?      
+--rw port-reference
| +--rw port-name?     
| +--rw port-number?   
+--ro last-cleared?     

```

The flow is like : At first the client will query the interface details as below:

```
              <rpc xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" **message-id="23"** >
            <get xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
       <filter type="subtree">
       < **interfaces** xmlns=" **urn:ietf:params:xml:ns:yang:ietf-interfaces**">
          </interfaces>
           </filter>
         </get>
    </rpc>

<rpc-reply
xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="23">
<data
	xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
	<interfaces
		xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces">
		<interface>
			<name>MAC0</name>
			<type
				xmlns:ianaift="urn:ietf:params:xml:ns:yang:iana-if-type">ianaift:ethernetCsmacd
			</type>
			<enabled>true</enabled>
			<mac-address xmlns="urn:o-ran:interfaces:1.0">d4:92:34:fc:00:32
			</mac-address>
			
			<vlan-tagging
				xmlns="urn:o-ran:interfaces:1.0">true
			</vlan-tagging>
		</interface>
	</interfaces>
</data>

```

Step -2:Client will invoke a edit-config request as below:

```
 <rpc xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="24">
   <edit-config xmlns="urn:ietf:params:xml:ns:netconf:base:1.0"><target><running/></target> 
     <config><interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces">
 <interface>
    <name>cuplane0</name>
    <description>CU Plane Vlan 1</description>
   <type xmlns:ianaift="urn:ietf:params:xml:ns:yang:iana-if-type">ianaift:l2vlan</type>
   <enabled>true</enabled>
   <base-interface xmlns="urn:o-ran:interfaces:1.0">MAC0</base-interface>
   <vlan-id xmlns="urn:o-ran:interfaces:1.0">753</vlan-id>
   <mac-address xmlns="urn:o-ran:interfaces:1.0">d4:92:34:fc:00:32</mac-address>
 </interface>
</interfaces>

```

For that i have just resgistered a call point as below:

module o-ran-interfaces-ann {

```
   yang-version 1.1;
   namespace "urn:ietf:params:xml:ns:yang:o-ran-interfaces-ann:1.0";
  prefix o-ran-if-ann;
 import ietf-interfaces {
  prefix if;
}
 import tailf-common {
  prefix tailf;
}
tailf:annotate "/if:interfaces/if:interface" {
tailf:callpoint cb_op_if_interface;
  }
}

```

For the step-1 I can manage with get-elem & get-next .But when same get-element call back is getting hit for step-2 as well, then I am not able to proceed further. Because if its a get-operation i dont need to send any value for base-interface.Where as for edit-config request i have to set it which i am trying handle on same get-element call back.  
But if you have any sample application which can be used as above requirement,will be really helpful.  
Also if you can help me in accumulate the resulting change operations and derive the data  
,then it will be really helpful.  
If you have any other suggestion which can fulfil our request then it will be more helpful.

Regards,  
Biswajit

---

<div class="post-metadata">

**Author:** ![josephm](https://avatars.discourse-cdn.com/v4/letter/j/a88e57/32.png) [@josephm](https://dmap-community.ductus.global/u/josephm)\
**Post date:** [July 14, 2022, 8:31am UTC](https://dmap-community.ductus.global/t/same-callback-is-getting-invoked-for-both-get-set-operation/4139/6 "2022-07-14T08:31:10Z")

</div>

“get” callbacks can be invoked by ConfD as existence check → to see if such item is or is not present already in “database” hidden behind your callback implementation. It let’s ConfD know whether it should invoke your create/set callbacks for edit-config NETCONF operation.

I assume you normally reply with something like `confd_data_reply_value()` or similar. If requested item does not exist, just use the `confd_data_reply_not_found()` instead. ConfD will most probably subsequently invoke your set/create callbacks as it has been told (by your get callback) that this record does not exist (yet).

---

<div class="post-metadata">

**Author:** ![biswajit](https://avatars.discourse-cdn.com/v4/letter/b/e56c9b/32.png) [@biswajit](https://dmap-community.ductus.global/u/biswajit)\
**Post date:** [July 14, 2022, 11:19am UTC](https://dmap-community.ductus.global/t/same-callback-is-getting-invoked-for-both-get-set-operation/4139/7 "2022-07-14T11:19:36Z")

</div>

Hi Joseph,  
As you suggested, in get\_element callback if the interface has not been created then i am calling confd\_data\_reply\_not\_found.

```
struct interface* s = find_interface(&(kp->v[1][0]));
if (s ==NULL){
printf("NO Interface\n");
confd_data_reply_not_found(tctx);
    return CONFD_OK;
}

```

Now dont know why set\_element call back is not getting invoked.  
Log:  
TRACE CALL data get\_elem(thandle=2248,/interfaces/interface{cuplane1}/name)NO Interface  
(NOEXISTS) → CONFD\_OK  
TRACE CALL data get\_elem(thandle=2248,/interfaces/interface{cuplane1}/vlan-tagging)NO Interface  
(NOEXISTS) → CONFD\_OK  
TRACE CALL data get\_elem(thandle=2248,/interfaces/interface{cuplane1}/vlan-tagging)NO Interface  
(NOEXISTS) → CONFD\_OK  
TRACE NULL trans finish(thandle=2248)  
TRACE Close user sess 14  
 → CONFD\_OK

Can you please help why set\_element is not getting invoked even if i have provided callback for “set\_elem” also for “create”

Regards,  
Biswajit

---

<div class="post-metadata">

**Author:** ![josephm](https://avatars.discourse-cdn.com/v4/letter/j/a88e57/32.png) [@josephm](https://dmap-community.ductus.global/u/josephm)\
**Post date:** [July 14, 2022, 1:35pm UTC](https://dmap-community.ductus.global/t/same-callback-is-getting-invoked-for-both-get-set-operation/4139/8 "2022-07-14T13:35:14Z")

</div>

as with any potential problem in regard to “external application” using confd-lib, try enabling developer log in ConfD - check whether sequence of callback invocations matches the one reported by your app and if it possibly shows some extra error or info…

---

<div class="post-metadata">

**Author:** ![biswajit](https://avatars.discourse-cdn.com/v4/letter/b/e56c9b/32.png) [@biswajit](https://dmap-community.ductus.global/u/biswajit)\
**Post date:** [July 14, 2022, 5:50pm UTC](https://dmap-community.ductus.global/t/same-callback-is-getting-invoked-for-both-get-set-operation/4139/9 "2022-07-14T17:50:08Z")

</div>

Hi Joseph,  
I have already enabled developer log. But there is no message seen on devel.log & confd.log.  
The edit-config is failing as i am not able to set the node data in confd provided in rpc.

#netconf-console set.xml

```xml
    <?xml version="1.0" encoding="UTF-8"?>
    <rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="32">
     <rpc-error>
    <error-type>application</error-type>
    <error-tag>unknown-element</error-tag>
    <error-severity>error</error-severity>
    <error-path xmlns:o-ran-int="urn:o-ran:interfaces:1.0" 
    xmlns:if="urn:ietf:params:xml:ns:yang:ietf-interfaces">
      /rpc/edit-config/config/if:interfaces/if:interface[if:name='cuplane1']/o-ran-int:vlan-tagging
    </error-path>
     <error-message xml:lang="en">/interfaces/interface[name='cuplane1']/o-ran-int:vlan-tagging: the 'when' expression "if:type = 'ianaift:ethernetCsmacd'" failed</error-message>
    <error-info>
      <bad-element>vlan-tagging</bad-element>
    </error-info>
    </rpc-error>
    </rpc-reply>

```

set.xml content:

```xml
<rpc xmlns="urn:ietf:params:xml:ns:netconf:base:1.0" message-id="32">
<edit-config xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
<target><running/></target>
<config>

      <interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces">
      <interface>
      <name>cuplane</name>
      <type xmlns:ianaift="urn:ietf:params:xml:ns:yang:iana-if-type">ianaift:l2vlan</type>
      <vlan-id xmlns="urn:o-ran:interfaces:1.0">408</vlan-id>
      <mac-address xmlns="urn:o-ran:interfaces:1.0">00:1e:3e:0f:fc:1b</mac-address>
      </interface>
      </interfaces>
      </config>
      </edit-config>
      </rpc>

```

sample Code:

```auto
     struct interface {
    char name[256];
    struct in_addr ip;
    unsigned int port;
    u_int8_t mac[6];
    u_int16_t vlan;
    char baseName[256];
    };

     static struct interface running_db[256];
     static int num_interface = 0;
      static struct confd_daemon_ctx *dctx;
     static int ctlsock;
    static int workersock;

    static int s_init(struct confd_trans_ctx *tctx)
    {
      confd_trans_set_fd(tctx, workersock);
      return CONFD_OK;
    }
      static struct interface *find_interface(confd_value_t *v)
      {
          int i;
          for (i=0; i< num_interface; i++) {
              if (confd_svcmp(running_db[i].name, v) == 0){
          printf("#########Find:%d\n",i);
                  return &running_db[i];
      	}
          }
          return NULL;
      }

      static struct interface *add_interface(char *name)
      {
          int i, j;
      
          for (i=0; i < num_interface; i++) {
              if (strcmp(running_db[i].name, name) > 0) {
                  /* found the position to add at, now shuffle the */
                  /* remaining elems in the array one step */
                  for (j = num_interface; j > i; j--) {
                      running_db[j] = running_db[j-1];
                  }
                  break;
              }
          }
          num_interface++;
          memset(&running_db[i], 0, sizeof(struct interface));
          strcpy(running_db[i].name, name);
          return &running_db[i];
      }
	#if 1 
	static int hw_get_optional(struct confd_trans_ctx *tctx, confd_hkeypath_t * kp)
	{
		int tag=CONFD_GET_XMLTAG(&kp->v[0][0]);
		if (tag == ip_ipv4) {
			printf("INSIDE IPV4 ****** 8\n");
			confd_data_reply_not_found(tctx);
		//	tag = GET_NEXT_TAG;
		}
		
		else if (tag == ip_ipv6) {
			printf("INSIDE IPV6 ****** 8\n");
			confd_data_reply_not_found(tctx);
		}
		return CONFD_OK;
	}
	#endif
		static int hw_get_elem(struct confd_trans_ctx *tctx, confd_hkeypath_t * kp)
		{
			confd_value_t v;
			confd_value_t *key,*key1;
			key = &kp->v[1][0];
			struct interface* s = find_interface(&(kp->v[1][0]));
		
			if (s == NULL) {
			printf("NO Interface\n");
			confd_data_reply_not_found(tctx);
		    return CONFD_OK;
			}
		
			struct confd_identityref idref;
			int tag = CONFD_GET_XMLTAG(&kp->v[0][0]);
			// printf(" ******* ELEM TAG:%d\n",tag);
			int idx;
			char * ifname;
			idx = kp->len;
			idx = idx - 1;
			if(tag==o_ran_int_mac_address)
			{
				// printf("MAC ADDRESS ******************");
				CONFD_SET_BINARY(&v,s->mac,6);
			}
			else if(tag==if_type)
			{
				// printf("IINTERFACE TYPE\n");
				idref.ns = ianaift__ns;
				idref.id = ianaift_l2vlan;
				CONFD_SET_IDENTITYREF(&v,idref);
			}
			else if(tag==if_name)
			{
				//ifname = (char *) CONFD_GET_BUFPTR(&kp->v[1][0]);
				if (s== NULL)
				{
					// key = &kp->v[0][0];
					// printf(" ****Adding Interface******* \n");
					add_interface((char *)CONFD_GET_BUFPTR(key));
				}
				//printf("$$$KEY Name:%s\n",s->name);
				//printf(" ******* TAG:%d\n",tag);
				s = find_interface(&(kp->v[1][0]));
		
				CONFD_SET_STR(&v,s->name);
			}
			else if(tag==o_ran_int_vlan_id)
			{
				if(s->vlan!=0)
				{
					printf("vlan accepted");
					CONFD_SET_UINT16(&v,s->vlan);
				}
				else{
		
					printf("vlan not accepted");
					CONFD_SET_NOEXISTS(&v);
				}
		
			}
			else if(tag == o_ran_int_vlan_tagging)
			{
				CONFD_SET_BOOL(&v,1);
				printf("VLAN TAGGING");
		
			}
		#if 1
			else if( tag == o_ran_int_base_interface)
			{
		
				if (tctx->mode == 1)
				{
					if(strlen(s->baseName)==0) 
						CONFD_SET_NOEXISTS(&v);
				}
				else
				{
		
					//CONFD_SET_STR(&v,"cuplane");
					CONFD_SET_STR(&v,(char *)CONFD_GET_BUFPTR(key));
					//strcpy(s->baseName,(char *)CONFD_GET_BUFPTR(key));
				}
		
			}
		#endif
			else if (tag == if_discontinuity_time)
			{
				time_t t;
				struct confd_datetime dt;
				time(&t);
				time_to_dt(t, &dt);
				//getdatetime(&eventTime);
				CONFD_SET_DATETIME(&v, dt);
			}
		
			else
				CONFD_SET_NOEXISTS(&v);
		
			confd_data_reply_value(tctx, &v);
		
			return CONFD_OK;
		}

                    int hw_get_next(struct confd_trans_ctx *tctx,
                    confd_hkeypath_t * kp, long next)
                    {
            
            confd_value_t v;
            static int pos =0;
            printf(" ***** Get NEXT\n");
            switch (CONFD_GET_XMLTAG(&kp->v[0][0])) {
          
              case if_interface:
                if (next == -1) { /* first call */
                  pos = 0;
                } else {
                  pos++;// = (int)next;
                }
                if (pos == num_interface ) { /* We have reached the end of the list*/
                  confd_data_reply_next_key(tctx, NULL, -1, -1);
                  return CONFD_OK;
                }
              CONFD_SET_STR(&v, running_db[pos].name);
              confd_data_reply_next_key(tctx, &v, 1,(long)(pos+1));
              break;
              case if_higher_layer_if:
                  confd_data_reply_next_key(tctx, NULL, -1, -1);
          	break;
              case if_lower_layer_if:
                  confd_data_reply_next_key(tctx, NULL, -1, -1);
          	break;
              case ip_ipv4:
          		printf(" **********IPV4********");
          	confd_data_reply_next_key(tctx, NULL, -1, -1);
          	break;
          	  case ip_ipv6:
          
          	confd_data_reply_next_key(tctx, NULL, -1, -1);
          	break;
              default:
                return CONFD_ERR;
            }
          
            return CONFD_OK;
          
          }
          static int hw_set_elem(struct confd_trans_ctx *tctx,
                              confd_hkeypath_t *keypath,
                              confd_value_t *newval)
          {
          	printf(" ************* SET ELEMENT");
          	unsigned char *bin;
          	int len;
              confd_value_t *tag = &(keypath->v[0][0]);
              
              switch (CONFD_GET_XMLTAG(tag)){
          
              case o_ran_int_mac_address:
          	    bin=CONFD_GET_BINARY_PTR(newval);
          	    len=CONFD_GET_BINARY_SIZE(newval);
          	    printf("MAC:%x:%x:%x:%x\n",bin[0],bin[1],bin[2],bin[3],bin[4]);
          	    memcpy(s->mac,bin,len);
          
                  break;
          #if 1
              case o_ran_int_vlan_id:
            
                 s->vlan=CONFD_GET_UINT16(newval);
          	  printf("&&&&&&\nSET ELEM VLAN:%d\n",s->vlan);
          	  break;
          #if 0
              case o_ran_int_base_interface:
            
          	  printf(" ****8BASE INTERFACE******** \n");
          
                 CONFD_SET_STR(&v,"MAC0");
            break;
          #endif
             default:
          	  confd_data_reply_not_found(tctx);
              // return CONFD_ERR;
          #endif
          
          // case if_name:
          
              }
          
              return CONFD_OK;
          }

        static int hw_create(struct confd_trans_ctx *tctx,
                          confd_hkeypath_t *keypath)
        {
            confd_value_t *key = &keypath->v[0][0];
            add_interface((char *)CONFD_GET_BUFPTR(key));
            return CONFD_OK;
        }
      static struct interface *new_interface(char *name, u_int8_t *mac, u_int16_t vlan)
      {
          struct interface *sp = add_interface(name);
          strcpy(sp->mac,mac);//inet_addr(ip);
          if(vlan!=0)
      	{
          sp->vlan =vlan;// atoi(port);
      	}
          return sp;
      }
	init_db()
	{
		num_interface = 0;
		u_int8_t addr[6];
		u_int16_t vlan=0;//405;
		// u_int16_t vlan=0;//408;
		addr[0] = 0x11;
		addr[1] = 0x22;
		addr[2] = 0x33;
		addr[3] = 0x44;
		addr[4] = 0x55;
		addr[5] = 0x66;
		
		new_interface("cuplane",addr,vlan);
		
	}

        int main(int argc, char *argv[])
        {
          struct sockaddr_in addr;
          //int debuglevel = CONFD_PROTO_TRACE;
          int debuglevel = CONFD_TRACE;
          struct confd_trans_cbs trans;
          struct confd_data_cbs data;
        
          /* 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("portstatus")) == 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 */
        #if 1
          memset(&trans, 0, sizeof(trans));
          trans.init = s_init;
          if (confd_register_trans_cb(dctx, &trans) == CONFD_ERR)
            confd_fatal("Failed to register trans cb\n");
        
          memset(&data, 0, sizeof (struct confd_data_cbs));
        
          data.get_elem = hw_get_elem;
          data.get_next = hw_get_next;
          data.exists_optional=hw_get_optional;
          data.set_elem = hw_set_elem;
          data.create = hw_create;
        //data.remove = doremove;
        
          //strcpy(data.callpoint, o_ran_hw__callpointid_cb_op_component);
          strcpy(data.callpoint,if__callpointid_cb_op_if_interface);
          if (confd_register_data_cb(dctx, &data) == CONFD_ERR)
            confd_fatal("Failed to register data cb\n");
        #endif
          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());
              }
            }
          }
        }

```

---

<div class="post-metadata">

**Author:** ![josephm](https://avatars.discourse-cdn.com/v4/letter/j/a88e57/32.png) [@josephm](https://dmap-community.ductus.global/u/josephm)\
**Post date:** [July 14, 2022, 7:58pm UTC](https://dmap-community.ductus.global/t/same-callback-is-getting-invoked-for-both-get-set-operation/4139/10 "2022-07-14T19:58:55Z")

</div>

well, there’s NETCONF error, and operation is interrupted → your callbacks to modify configuration do not get invoked…

```xml
<rpc-error>
  <error-type>application</error-type>
  <error-tag>unknown-element</error-tag>
  <error-severity>error</error-severity>
  <error-path xmlns:o-ran-int="urn:o-ran:interfaces:1.0" xmlns:if="urn:ietf:params:xml:ns:yang:ietf-interfaces">
    /rpc/edit-config/config/if:interfaces/if:interface[if:name='cuplane1']/o-ran-int:vlan-tagging
  </error-path>
  <error-message xml:lang="en">/interfaces/interface[name='cuplane1']/o-ran-int:vlan-tagging: the 'when' expression "if:type = 'ianaift:ethernetCsmacd'" failed</error-message>
  <error-info>
    <bad-element>vlan-tagging</bad-element>
  </error-info>
</rpc-error>

```

You cannot do edit-config for `vlan-tagging` element with config set like you have in RPC request - such element “does not exist in schema” due to when statement condition not being met…

I assume that you have `when` statement someplace in the YANGs that conditions `vlan-tagging` element with interface `type` == `ianaift:ethernetCsmacd` (you are setting `ianaift:l2vlan` in RPC), just like error message shows…

---

<div class="post-metadata">

**Author:** ![biswajit](https://avatars.discourse-cdn.com/v4/letter/b/e56c9b/32.png) [@biswajit](https://dmap-community.ductus.global/u/biswajit)\
**Post date:** [July 14, 2022, 9:15pm UTC](https://dmap-community.ductus.global/t/same-callback-is-getting-invoked-for-both-get-set-operation/4139/11 "2022-07-14T21:15:20Z")

</div>

Hi Joseph,  
Thanks a lot for finding the mistake. Appreciate your effort in finding the root cause.

Regards,  
Biswajit

---

<div class="post-metadata">

**Author:** ![josephm](https://avatars.discourse-cdn.com/v4/letter/j/a88e57/32.png) [@josephm](https://dmap-community.ductus.global/u/josephm)\
**Post date:** [July 15, 2022, 8:21am UTC](https://dmap-community.ductus.global/t/same-callback-is-getting-invoked-for-both-get-set-operation/4139/12 "2022-07-15T08:21:41Z")

</div>

no problem, sometimes it might not be apparent how all the pieces and events connect together 🙂

---

<div class="post-metadata">

**Author:** ![khan](https://avatars.discourse-cdn.com/v4/letter/k/3ab097/32.png) [@khan](https://dmap-community.ductus.global/u/khan)\
**Post date:** [July 19, 2023, 2:37pm UTC](https://dmap-community.ductus.global/t/same-callback-is-getting-invoked-for-both-get-set-operation/4139/13 "2023-07-19T14:37:01Z")

</div>

I kind of facing similar problem or want to understand the way how get\_next() and get\_object gets invoked

I’m trying to create a list instance from CLI, and I have implemented a CLI command below

aaa authentication users username TestUser PhoneNumber 1234

upon execution of the above command, I see the below call traces, my get\_next & get\_object and create callbacks are getting called properly but i see calls to get\_next and get\_object repeatedly

daemon.debug transaction-app: TRACE CALL trans init(thandle=548,mode=“rw”,db=running) → CONFD\_OK  
daemon.debug transaction-app: TRACE CALL data get\_next(thandle=548, /aaa/authentication/users/username, -1) → CONFD\_OK  
daemon.debug transaction-app: TRACE CALL data get\_next(thandle=548, /aaa/authentication/users/username, 1) → CONFD\_OK  
daemon.debug transaction-app: TRACE CALL data get\_next(thandle=548, /aaa/authentication/users/username, 2) → CONFD\_OK  
daemon.debug transaction-app: TRACE CALL data get\_next(thandle=548, /aaa/authentication/users/username, 3) → CONFD\_OK  
daemon.debug transaction-app: TRACE CALL data get\_next(thandle=548, /aaa/authentication/users/username, 4) → CONFD\_OK

daemon.debug transaction-app: TRACE CALL data get\_next(thandle=548, /aaa/authentication/users/username, -1) → CONFD\_OK  
daemon.debug transaction-app: TRACE CALL data get\_next(thandle=548, /aaa/authentication/users/username, 1) → CONFD\_OK  
daemon.debug transaction-app: TRACE CALL data get\_next(thandle=548, /aaa/authentication/users/username, 2) → CONFD\_OK  
daemon.debug transaction-app: TRACE CALL data get\_next(thandle=548, /aaa/authentication/users/username, 3) → CONFD\_OK

daemon.debug transaction-app: TRACE CALL data get\_next(thandle=548, /aaa/authentication/users/username, 4) → CONFD\_OK

daemon.debug transaction-app: TRACE CALL data get\_object(thandle=548,/aaa/authentication/users/username{sajid}) (NOEXISTS) → CONFD\_OK

daemon.debug transaction-app: TRACE CALL data get\_object(thandle=548,/aaa/authentication/users/username{sajid}) (NOEXISTS) → CONFD\_OK  
daemon.debug transaction-app: TRACE CALL data get\_object(thandle=548,/aaa/authentication/users/username{sajid}) (NOEXISTS) → CONFD\_OK  
daemon.debug transaction-app: TRACE CALL data get\_object(thandle=548,/aaa/authentication/users/username{sajid}) (NOEXISTS) → CONFD\_OK

daemon.debug transaction-app: TRACE CALL data get\_object(thandle=548,/aaa/authentication/users/username{sajid}) (NOEXISTS) → CONFD\_OK

daemon.info confd[31311]: audit user: secadmin/13 CLI ‘aaa authentication users username sajid PhoneNumber 1234’  
daemon.debug transaction-app: TRACE CALL data get\_object(thandle=548,/aaa/authentication/users/username{sajid}) (NOEXISTS) → CONFD\_OK  
daemon.debug transaction-app: TRACE CALL data get\_object(thandle=548,/aaa/authentication/users/username{sajid}) (NOEXISTS) → CONFD\_OK  
daemon.debug transaction-app: TRACE CALL data create(thandle=548,/aaa/authentication/users/username{sajid}) → CONFD\_ACCUMULATE

My concern is why confd

1. calling get\_next() twice even though have replied full set of my list entries
2. why is it calling get\_object multiple times even the DP has replied confd\_data\_reply\_not\_found(tctx);, is it no supposed to call create immediately after getting NOEXIST from a call to get\_object()

---

<div class="post-metadata">

**Author:** ![cohult](https://yyz2.discourse-cdn.com/flex010/user_avatar/dmap-community.ductus.global/cohult/32/221_2.png) [@cohult](https://dmap-community.ductus.global/u/cohult)\
**Post date:** [July 21, 2023, 2:39pm UTC](https://dmap-community.ductus.global/t/same-callback-is-getting-invoked-for-both-get-set-operation/4139/14 "2023-07-21T14:39:54Z")

</div>

Suggest not to use the CLI if you are looking for somewhat more predictable callback invocations. The CLI is a human-to-machine interface, so ConfD must fetch data for things like tab-complete, table look-ahead, etc. Use NETCONF or RESTCONF instead.
