Notification string is "%"

Hello All,

A particular notification CONFD_SET_STR is setting the string as “%” am not sure why. The log level(developer LOG level set to trace) also did not give me any specific information about it.

The string before the notification CONFD_SET_STR seems fine.
" Radar channels 124 140 120 116 at time Wed Mar 8 11:09:31 2017 detected "

Its a very wierd behavior. I am not sure the scenario when the notification becomes “%”. Sometimes the notification is seen, sometimes it just displays “%”.

Best regards

Hi,

I assume you are sending a NETCONF notification here.
If so, you want to send a tag value array, so you want to use CONFD_SET_TAG_STR().

Tried sending a large string through a modified examples.confd/netconf_notifications example. Worked nicely.

Could there be a formatting error in your notification application code?

Yes, It is CONFD_SET_TAG_STR. Sorry for the typo.

I populate the string using
std::string message = “Radar channels " + channel_list_ + " at time " + event_time_ + " detected”;

The channel_list is a list of channels, and may vary after every notification. ex: 124 100 128 or 128 108 112 132 116 136 140 100 124.

I am using string arithmatic to populate this channels list.

Hello,

as the ConfD lib does not use std:string in its interface, how do you fill the actual tagged value to be used/sent?

best regards,
jozef

In addition to @josephm 's question:

CONFD_SET_TAG_STR(my_tv_array[0], myprefix_mytagname, mystring);

Did you allocate the my_tv_array properly? Are you providing the correct prefix+tag from your header file, i.e. myprefix_mytagname? Is the formatting of mystring indeed correct?

You can check the contents of the tag value array, here my_tv_array[], before sending it:

Deleted: see correct way in post below

No, you can’t set the value as C_STR and expect to get it back as C_BUF, they are different confd_value_t types even though they are both used to repsent the ‘string’ YANG type. Basically libconfd will always create C_BUF values, C_STR is a convenience for the programmer.

I fill using CONFD_SET_TAG_STR(&p_vals_[i], wireless_summary, message.c_str()); i++;

Thanks for catching that @per

The ConfD 6.3.1 UG Chapter 11.2.1 Example is a better way that actually works.

@poornima11: what is your output if you run this before sending your notification?:

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

I will check it out. All I see in the notification is “%”. On the contrary, I do see the notification sometimes. But sometimes I just see “%”.

Thank you all. I took your inputs and solved the issue.
I used a c_buf to copy the c_str and further used to SET into CONFD_SET_TAG_STR.

But Why was the notification seen sometimes when I used c_str?

Best regards,
Poornima.M

Perhaps the memory was freed and overwritten before the notification had actually been sent?
See confd_lib_types(3) man page and look for C_BUF and C_STR for more info.

If you can give us some YANG snippet and code so that we can recreate your issue, we might be able to figure out what happened.

Well, the requirement from the libconfd library is only that the memory is valid for the duration of the confd_notification_send() call - and the library dosn’t free the data passed to the function, nor does it even care where it lives (heap/stack/constant/global).

ITYM confd_types(3) - but I’m not sure the discussion about memory management there is relevant, it’s about how memory for strings must be allocated by the library when reading via MAAPI or CDB API, and the application thus is responsible for releasing that memory with confd_free_value().

In the case of confd_notification_send(), it is entirely up to the application to manage the memory for the tag-value array - allocating before the call if needed, freeing after the call if allocated.

+1

Sorry for the delay,

Here is the yang snippet.

grouping notification_mandatory_g {
   leaf mac-address {
       type leafref {
           path "/wireless:managed-ap/wireless:database/wireless:mac-address";
       }
       mandatory true;
   }
   leaf triggered_by {
      type wireless:triggered_by_e;
      mandatory true;
   }
   leaf severity {
        type wireless:severity_level_e;
        mandatory true;
   }
   leaf message {
      type string;
   }
   leaf summary {
        type string {
            length "1..128";
        }
   }
}

notification ap_radar_events {
    uses notification_mandatory_g;
}

Here is the application code where I am sending the notification.

confd_tag_value_t* confd_ap_radar_notification::get_event_data(int* num_values)
{
    if(!p_vals_)
    {
        p_vals_ = (confd_tag_value_t *) malloc( sizeof(confd_tag_value_t) * 7);
        int i = 0;
        CONFD_SET_TAG_XMLBEGIN(&p_vals_[i], wireless_ap_radar_events, wireless__ns);  i++;
   
        CONFD_SET_TAG_STR(&p_vals_[i], wireless_mac_address, ap_mac_.c_str());      i++;
        CONFD_SET_TAG_ENUM_VALUE(&p_vals_[i], wireless_triggered_by, wireless_SYSTEM); i++;
        CONFD_SET_TAG_ENUM_VALUE(&p_vals_[i], wireless_severity, wireless_INFO); i++;
        CONFD_SET_TAG_STR(&p_vals_[i],wireless_message, ""); i++;
   
        /* Cannot use C_STR to set to CONFD. So usinf buffer */
        std::string message = "Radar channels " + channel_list_ + " at time " + event_time_ + " detected";
        char *buf = new char[128];
        strcpy((char *)buf,message.c_str());
   
        CONFD_SET_TAG_STR(&p_vals_[i], wireless_summary, buf);i++;
        CONFD_SET_TAG_XMLEND(&p_vals_[i], wireless_ap_radar_events, wireless__ns);  i++;
        num_vals_ = i;
        if(buf)
            delete(buf);
    }
    *num_values = num_vals_;
   
    return p_vals_;
}

Initialising p_vals_ to null in the constructor. I still see the “%” in the string.

Best regards,
Poornima.M

When I tried to get the output using confd_pp_value,

param 0: 1086638362:1787442149, ap_radar_events
param 1: 0:2110689796, “34:ba:75:00:09:60”
param 2: 0:532094435, enum<1>
param 3: 0:483607279, enum<6>
param 4: 0:1674281495, “”
param 5: 0:738895761, “Radar channels 124,112,116 at time Thu Mar 30 17:12:40 2017 detected”
param 6: 1086638362:1787442149, ap_radar_events

param 0: 1086638362:933688870, ap_change_radar_events
param 1: 0:2110689796, “34:ba:75:00:09:60”
param 2: 0:532094435, enum<1>
param 3: 0:483607279, enum<6>
param 4: 0:1674281495, “”
param 5: 0:738895761, “Changed channel to 128 at time Thu Mar 30 17:12:41 2017 due to Radar Detection.”
param 6: 1086638362:933688870, ap_change_radar_events

But when I see on the cli,

cli# show notification stream managed_ap_events last 2
notification
eventTime 2017-03-30T11:42:41.073027+00:00
ap_radar_events
mac-address 34:ba:75:00:09:60
triggered_by SYSTEM
severity INFO
message
summary Radar channels 124,112,116 at time Thu Mar 30 17:12:40 2017 detected
!
!
notification
eventTime 2017-03-30T11:42:42.088267+00:00
ap_change_radar_events
mac-address 34:ba:75:00:09:60
triggered_by SYSTEM
severity INFO
message
summary ���
!
!

:frowning:

As I wrote:

This requirement is clearly not fulfilled by your code:

CONFD_SET_TAG_STR() just stores a pointer to your dynamically allocated buffer in the tag-value array. You need to ensure that the buffer remains valid until you have called confd_notification_send(), and since you delete it here before returning the array (which is eventually used for the confd_notification_send() call by some higher-up function), you obviously aren’t doing that.

1 Like