Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to set ald-port list for o-ran-ald-port in operational datastore in sysrepo #1693

Open
piyush897 opened this issue Jan 16, 2025 · 3 comments
Labels
is:question Issue is actually a question.

Comments

@piyush897
Copy link

Hi Michal

I am attempting to set the O-RAN ALD-Port data in the operational datastore for the ALD-Port list; however, the fields are not being correctly populated in the operational datastore.

o-ran-ald-port yang:

module o-ran-ald-port {
  yang-version 1.1;
  namespace "urn:o-ran:ald-port:1.0";
  prefix "o-ran-ald-port";

  organization "O-RAN Alliance";

  contact
    "www.o-ran.org";

  description
    "This module defines the input state and output configuration for
    the Antenna Line Device capability.

    Copyright 2021 the O-RAN Alliance.

    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS'
    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
    ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
    LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
    CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
    SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
    INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
    CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
    ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    POSSIBILITY OF SUCH DAMAGE.

    Redistribution and use in source and binary forms, with or without
    modification, are permitted provided that the following conditions are met:

    * Redistributions of source code must retain the above copyright notice,
    this list of conditions and the above disclaimer.
    * Redistributions in binary form must reproduce the above copyright notice,
    this list of conditions and the above disclaimer in the documentation
    and/or other materials provided with the distribution.
    * Neither the Members of the O-RAN Alliance nor the names of its
    contributors may be used to endorse or promote products derived from
    this software without specific prior written permission.";

  revision "2021-03-22" {
    description
      "version 1.2.0

      1) typographical corrections in descriptions.";

    reference "ORAN-WG4.M.0-v01.00";
  }

  revision "2019-07-03" {
    description
      "version 1.1.0

      1) backward compatible changes to introduce groupings.";

    reference "ORAN-WG4.M.0-v01.00";
  }

  revision "2019-02-04" {
    description
      "version 1.0.0

      1) imported model from xRAN
      2) changed namespace and reference from xran to o-ran";

    reference "ORAN-WG4.M.0-v01.00";
  }


  feature OVERCURRENT-SUPPORTED {
    description
      "This feature indicates that the equipment supports the over-current notification
      capability.";
  }

// Groupings

  grouping aldport-group {
    description "a port grouping ";
    leaf over-current-supported {
      type boolean;
      config false;
      description
        "Set to TRUE when the equipment supports overcurrent notifications";
    }

    list ald-port {
      key "name";

      config false;

      description
        "Leaf nodes describing ALD Port";
      leaf name {
        type string {
          length "1..255";
        }
        description
          "A name that is unique that identifies a ald port instance.
          This name may be used in fault management to refer to a fault source
          or affected object";
      }

      leaf port-id {
        type uint8;
            config false;
            mandatory true;

            description
          "A number which identifies an ALD Port.
          The number of the Physical ALD port connector in the module.
          If the module supports 2 ALD Port connectors, use 0 and 1.";
      }

      leaf dc-control-support{
        type boolean;
        config false;
            mandatory true;

            description
          "It is shown that on/off in the DC power supply is possible.
          In case of False, power supply is always on.";
      }

      leaf dc-enabled-status {
        when "../dc-control-support = 'true'";
        type boolean;
        default false;
        description
          "Status of DC voltage enabled on antenna line.
          Valid only in case dc-control-support is true.";
      }

      leaf supported-connector{
        type enumeration {
              enum ANTENNA_CONNECTOR {
                description
                    "This ald port is related to antenna connector";
              }
              enum RS485_PORT {
                description
                    "This ald port is related to RS485 port";
              }
            }
        config false;
            mandatory true;

            description
          "Informs about the connectors of Module which ALDs are connected to.
          This value is depending on HW design.";
      }
    }

    list ald-port-dc-control {
      key "name";

      description
        "Container needed to manage DC on ALD ports";

      leaf name {
        type leafref {
          path "/ald-ports-io/ald-port/name";
          require-instance false;
        }
        mandatory true;

        description
          "Name derived from unmodifiable list ald-port";
      }

      leaf dc-enabled{
        type boolean;

        description
          "If dc-control-support is true case, this leaf is effective.
          If dc-control-support is not true this leaf makes no action
          In case of true, the power supply shall be turned on.";
      }
    }
  }

  grouping overcurrent-group {
    description "overcurrent group";
    container overload-condition {
      description
        "Container used in notification";

      leaf-list overloaded-ports {
        type leafref {
          path "/ald-ports-io/ald-port/name";
        }
        description
          "List of overloaded ports";
      }
    }
  }

  grouping dc-enabled-group {
    description "dc enabled group";
    list ald-port {
      key name;
      description
        "list of ald-ports that has its dc-enabled-status changed";
      leaf name{
        type leafref {
          path "/ald-ports-io/ald-port/name";
        }
        description "Name of port which has changed";
      }
      leaf dc-enabled-status{
        type leafref {
          path "/ald-ports-io/ald-port/dc-enabled-status";
        }
        description "New staus of dc-enabled-status";
      }
    }
  }

// Top Level Container

  container ald-ports-io {
    description
      "ALD port information.
       ALD port of the equipment that can be used to connect External Equipment (Antenna Line Devices).
       Communication uses AISG over HDLC.
       Physical connection depends on connector type offered by the port (RS-485 or antenna line)
       Note: Single instance of ALD Port can point to more than one antenna line devices.";

    uses aldport-group;
  }

  notification overcurrent-report {
    if-feature OVERCURRENT-SUPPORTED;

    description
      "The equipment is able to report overcurrent condition about Port.
      This function is depending on HW design.
      The notification depend on power consumption which connected ALD devices and module.";

    uses overcurrent-group;
  }

  notification dc-enabled-status-change {
    description
      "The equipment is able to report the change of 'dc-enabled-status' of the ald-port.
      This is applicable when the leaf 'dc-control-support' of the ald-pot is 'TRUE'.";

    uses dc-enabled-group;
  }
}
const ly_ctx *context = sr_acquire_context(sr_session_get_connection(session));
   if (!context)
   {
       syslog(LOG_ERR, "O-RAN-ALD-PORT: failed to acquire context");
       return SR_ERR_INTERNAL;
   }

   // ALD port parameters (hardcoded values)
   const vector<std::tuple<string, uint8_t, bool, bool, string>> aldPorts = {
       {"Port-1", 0, true, true, "RS485_PORT"}
       };

   // Loop over the ALD ports and create the necessary nodes
   for (const auto &port : aldPorts)
   {
       string name = std::get<0>(port);
       uint8_t portId = std::get<1>(port);
       bool dcControlSupport = std::get<2>(port);
       bool dcEnabledStatus = std::get<3>(port);
       string connectorType = std::get<4>(port);

       // XPath for ald-port
       string xpath = "/o-ran-ald-port:ald-ports-io/ald-port[name='" + name + "']";
       
       syslog(LOG_DEBUG)<<__func__<<"::"<<__LINE__<<" --> ALD-PORT NODE SETTING ENTRY";
       // Create the ald-port node
       if (LY_SUCCESS != lyd_new_path(NULL, context, xpath.c_str(), NULL, 0, parent))
       {
           syslog(LOG_ERR) << "O-RAN-ALD-PORT: cannot create 'ald-port' node";
           return SR_ERR_INTERNAL;
       }

       // Ensure the parent is valid
       if (*parent == NULL)
       {
           syslog(LOG_ERR, "ALD PORT Parent node is NULL");
           return SR_ERR_INTERNAL;
       }

       // Create 'port-id' leaf
       char portIdStr[10];
       sprintf(portIdStr, "%u", portId);
       xpath = "/o-ran-ald-port:ald-ports-io/ald-port[name='" + name + "']/port-id";
       if (LY_SUCCESS != lyd_new_path(*parent, NULL, xpath.c_str(), portIdStr, 0, NULL))
       {
           syslog(LOG_ERR, "O-RAN-ALD-PORT: cannot create 'port-id' leaf");
           return SR_ERR_INTERNAL;
       }

       // Create 'dc-control-support' leaf
       xpath = "/o-ran-ald-port:ald-ports-io/ald-port[name='" + name + "']/dc-control-support";
       if (LY_SUCCESS != lyd_new_path(*parent, NULL, xpath.c_str(), dcControlSupport ? "true" : "false", 0, NULL))
       {
           syslog(LOG_ERR, "O-RAN-ALD-PORT: cannot create 'dc-control-support' leaf");
           return SR_ERR_INTERNAL;
       }

       // Create 'dc-enabled-status' leaf (only if dc-control-support is true)
       if (dcControlSupport)
       {
           xpath = "/o-ran-ald-port:ald-ports-io/ald-port[name='" + name + "']/dc-enabled-status";
           if (LY_SUCCESS != lyd_new_path(*parent, NULL, xpath.c_str(), dcEnabledStatus ? "true" : "false", 0, NULL))
           {
               syslog(LOG_ERR, "O-RAN-ALD-PORT: cannot create 'dc-enabled-status' leaf");
               return SR_ERR_INTERNAL;
           }
       }

       // Create 'supported-connector' leaf
       xpath = "/o-ran-ald-port:ald-ports-io/ald-port[name='" + name + "']/supported-connector";
       if (LY_SUCCESS != lyd_new_path(*parent, NULL, xpath.c_str(), connectorType.c_str(), 0, NULL))
       {
           syslog(LOG_ERR, "O-RAN-ALD-PORT: cannot create 'supported-connector' leaf");
           return SR_ERR_INTERNAL;
       }
       syslog(LOG_DEBUG)<<__Func__<<"::"<<__LINE<<" --> ALD-PORT NODE SETTING EXIT";
   }
   // handling the "ald-port-dc-control" part
   string dcControlName = "Port-1";
   string xpath = "/o-ran-ald-port:ald-ports-io/ald-port-dc-control[name='" + dcControlName + "']";
   if (LY_SUCCESS != lyd_new_path(NULL, context, xpath.c_str(), NULL, 0, parent))
   {
       syslog(LOG_ERR, "O-RAN-ALD-PORT: cannot create 'ald-port-dc-control' node");
       return SR_ERR_INTERNAL;
   }

   xpath = "/o-ran-ald-port:ald-ports-io/ald-port-dc-control[name='" + dcControlName + "']/dc-enabled";
   if (LY_SUCCESS != lyd_new_path(*parent, NULL, xpath.c_str(), "true", 0, NULL))
   {
       syslog(LOG_ERR, "O-RAN-ALD-PORT: cannot create 'dc-enabled' leaf");
       return SR_ERR_INTERNAL;
   }

The code used to set the values in the callback through sr_oper_get_subscribe is provided above, but the output I am receiving is as shown below, which does not align with the expected results. Additionally, in this scenario, we are unable to create the nodes or set the data. Notably, no internal syslog errors are being generated, but the entry and exit logs are appearing as observed in the logs.


<ald-ports-io xmlns="urn:o-ran:ald-port:1.0">
                         <ald-port>
                                       <name>Port-1</name>
                                       <dc-enabled-status>true</dc-enabled-status>
                         </ald-port>
                         <ald-port-dc-control>
			                 <name>Port-1</name>
			                 <dc-enabled-status>true</dc-enabled-status>
                         </ald-port-dc-control>
</ald-ports-io>

ald-port logs

expected result should be as follows:

<ald-ports-io xmlns="urn:o-ran:ald-port:1.0">
 <name>Port-1</name>
                        <ald-port>
                                        <name>Port-1</name>
					<port-id>0</port-id>
					<dc-control-support>true</dc-control-support>
					<dc-enabled-status>true</dc-enabled-status>
					<supported-connector>ANTENNA_CONNECTOR</supported-connector>
			</ald-port>
			<ald-port-dc-control>
			                 <name>Port-1</name>
			                 <dc-enabled-status>true</dc-enabled-status>
			</ald-port-dc-control>		
</ald-ports-io>

Could you please suggest the possible reasons for the error scenario encountered here and how it can be resolved?

@michalvasko
Copy link
Member

The core of the problem is that the lists are config false meaning their key values do not uniquely identify any instances, so for every child a new list instance is created. Try something like

xpath = "/o-ran-ald-port:ald-ports-io/ald-port[1]/name";
xpath = "/o-ran-ald-port:ald-ports-io/ald-port[1]/port-id";
xpath = "/o-ran-ald-port:ald-ports-io/ald-port[1]/dc-control-support";

then for 2, and so on.

@michalvasko michalvasko added the is:question Issue is actually a question. label Jan 16, 2025
@piyush897
Copy link
Author

Hi @michalvasko
As per your last suggestion , we observed that xml was not getting created. Later we tried with the following code part and following are the observations.

// Parent node for the entire configuration
    lyd_node *root_parent = nullptr;

    // Loop over the ALD ports and create the necessary nodes
    for (size_t i = 0; i < aldPorts.size(); ++i)
    {
        const auto &port = aldPorts[i];
        string name = std::get<0>(port);
        uint8_t portId = std::get<1>(port);
        bool dcControlSupport = std::get<2>(port);
        bool dcEnabledStatus = std::get<3>(port);
        string connectorType = std::get<4>(port);

        lyd_node *current_parent = nullptr;

        // Used 'name' as the predicate key for each ald-port
        string xpath = "/o-ran-ald-port:ald-ports-io/ald-port[name='" + name + "']";
        if (LY_SUCCESS != lyd_new_path(root_parent, context, xpath.c_str(), NULL, 0, &current_parent))
        {
            syslog(LOG_ERR, "O-RAN-ALD-PORT: cannot create 'ald-port' node for name '%s'", name.c_str());
            return SR_ERR_INTERNAL;
        }

        if (!root_parent)
        {
            root_parent = current_parent;
        }

        syslog(LOG_DEBUG)<<__func__<<"::"<<__LINE__<<" --> ALD-PORT NODE SETTING ENTRY";
        xpath = "/o-ran-ald-port:ald-ports-io/ald-port[name='" + name + "']/port-id";
        char portIdStr[10];
        sprintf(portIdStr, "%u", portId);
        if (LY_SUCCESS != lyd_new_path(current_parent, NULL, xpath.c_str(), portIdStr, 0, NULL))
        {
            syslog(LOG_ERR, "O-RAN-ALD-PORT: cannot create 'port-id' leaf");
            return SR_ERR_INTERNAL;
        }

        xpath = "/o-ran-ald-port:ald-ports-io/ald-port[name='" + name + "']/dc-control-support";
        if (LY_SUCCESS != lyd_new_path(current_parent, NULL, xpath.c_str(), dcControlSupport ? "true" : "false", 0, NULL))
        {
            syslog(LOG_ERR, "O-RAN-ALD-PORT: cannot create 'dc-control-support' leaf");
            return SR_ERR_INTERNAL;
        }

        if (dcControlSupport)
        {
            xpath = "/o-ran-ald-port:ald-ports-io/ald-port[name='" + name + "']/dc-enabled-status";
            if (LY_SUCCESS != lyd_new_path(current_parent, NULL, xpath.c_str(), dcEnabledStatus ? "true" : "false", 0, NULL))
            {
                syslog(LOG_ERR, "O-RAN-ALD-PORT: cannot create 'dc-enabled-status' leaf");
                return SR_ERR_INTERNAL;
            }
        }

        xpath = "/o-ran-ald-port:ald-ports-io/ald-port[name='" + name + "']/supported-connector";
        if (LY_SUCCESS != lyd_new_path(current_parent, NULL, xpath.c_str(), connectorType.c_str(), 0, NULL))
        {
            syslog(LOG_ERR, "O-RAN-ALD-PORT: cannot create 'supported-connector' leaf");
            return SR_ERR_INTERNAL;
        }
        syslog(LOG_DEBUG)<<__func__<<"::"<<__LINE__<<" --> ALD-PORT NODE SETTING EXIT";
    }

    // Handle "ald-port-dc-control"
    string dcControlName = "Port-1";
    string xpath = "/o-ran-ald-port:ald-ports-io/ald-port-dc-control[name='" + dcControlName + "']";
    lyd_node *dc_control_parent = nullptr;
    if (LY_SUCCESS != lyd_new_path(root_parent, context, xpath.c_str(), NULL, 0, &dc_control_parent))
    {
        syslog(LOG_ERR, "O-RAN-ALD-PORT: cannot create 'ald-port-dc-control' node");
        return SR_ERR_INTERNAL;
    }

    xpath = "/o-ran-ald-port:ald-ports-io/ald-port-dc-control[name='" + dcControlName + "']/dc-enabled";
    if (LY_SUCCESS != lyd_new_path(dc_control_parent, NULL, xpath.c_str(), "true", 0, NULL))
    {
        syslog(LOG_ERR, "O-RAN-ALD-PORT: cannot create 'dc-enabled' leaf");
        return SR_ERR_INTERNAL;
    }

 // Serialize the lyd_node* (root_parent) to XML
 lyd_print_mem(&xml_str, root_parent, LYD_XML, LYD_PRINT_SHRINK);

 int rc = sr_set_item(session, "/o-ran-ald-port:ald-ports-io", sr_value, 0);
   

I am currently receiving the entry and exit logs, and the expected serialized XML string generated is visible within these logs. However, the XML string is not being stored in the operational datastore as expected. The sysrepocfg triggered successfully, but xml is not stored in the operational datastore which we would have retrieved by this command.
For your reference, I have attached an image of the logs.
Please let me know if any further information is required to assist in resolving this issue.

sysrepocfg -d operational -v3 -f xml -m o-ran-ald-port -X
[INF] Connection 109 created.
[INF] Session 134 (user "root", CID 109) created.
[INF] Published event "operational get" "/o-ran-ald-port:ald-ports-io/ald-port" with ID 2.
[INF] Event "operational get" with ID 2 succeeded.
[INF] No datastore changes to apply

Image

Image

@michalvasko
Copy link
Member

I am not sure I understand, you are still using key values as predicates instead of the positions so it will not work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
is:question Issue is actually a question.
Projects
None yet
Development

No branches or pull requests

2 participants