VOL-2596 : Measure optical distance between OLT and ONU
Change-Id: Ib13d85fe47a800348f82a5d76a90d97d98b20e1e
diff --git a/agent/src/core_api_handler.cc b/agent/src/core_api_handler.cc
index 9a22497..9975c36 100644
--- a/agent/src/core_api_handler.cc
+++ b/agent/src/core_api_handler.cc
@@ -2868,4 +2868,73 @@
OPENOLT_LOG(INFO, openolt_log_id, "Group %d has been deleted successfully.\n", group_id);
return Status::OK;
-}
\ No newline at end of file
+}
+
+Status GetLogicalOnuDistanceZero_(uint32_t intf_id, openolt::OnuLogicalDistance* response) {
+ bcmos_errno err = BCM_ERR_OK;
+ uint32_t mld = 0;
+ double LD0;
+
+ err = getOnuMaxLogicalDistance(intf_id, &mld);
+ if (err != BCM_ERR_OK) {
+ return bcm_to_grpc_err(err, "Failed to retrieve ONU maximum logical distance");
+ }
+
+ LD0 = LOGICAL_DISTANCE(mld*1000, MINIMUM_ONU_RESPONSE_RANGING_TIME, ONU_BIT_TRANSMISSION_DELAY);
+ OPENOLT_LOG(INFO, openolt_log_id, "The ONU logical distance zero is %f, (PON %d)\n", LD0, intf_id);
+ response->set_intf_id(intf_id);
+ response->set_logical_onu_distance_zero(LD0);
+
+ return Status::OK;
+}
+
+Status GetLogicalOnuDistance_(uint32_t intf_id, uint32_t onu_id, openolt::OnuLogicalDistance* response) {
+ bcmos_errno err = BCM_ERR_OK;
+ bcmolt_itu_onu_params itu = {};
+ bcmolt_onu_cfg onu_cfg;
+ bcmolt_onu_key onu_key = {};
+ uint32_t mld = 0;
+ double LDi;
+
+ onu_key.pon_ni = intf_id;
+ onu_key.onu_id = onu_id;
+
+ err = getOnuMaxLogicalDistance(intf_id, &mld);
+ if (err != BCM_ERR_OK) {
+ return bcm_to_grpc_err(err, "Failed to retrieve ONU maximum logical distance");
+ }
+
+ /* Initialize the API struct. */
+ BCMOLT_CFG_INIT(&onu_cfg, onu, onu_key);
+ BCMOLT_FIELD_SET_PRESENT(&onu_cfg.data, onu_cfg_data, onu_state);
+ BCMOLT_FIELD_SET_PRESENT(&itu, itu_onu_params, ranging_time);
+ BCMOLT_FIELD_SET(&onu_cfg.data, onu_cfg_data, itu, itu);
+ #ifdef TEST_MODE
+ // It is impossible to mock the setting of onu_cfg.data.onu_state because
+ // the actual bcmolt_cfg_get passes the address of onu_cfg.hdr and we cannot
+ // set the onu_cfg.data.onu_state. So a new stub function is created and address
+ // of onu_cfg is passed. This is one-of case where we need to add test specific
+ // code in production code.
+ err = bcmolt_cfg_get__onu_state_stub(dev_id, &onu_cfg);
+ #else
+ /* Call API function. */
+ err = bcmolt_cfg_get(dev_id, &onu_cfg.hdr);
+ #endif
+ if (err != BCM_ERR_OK) {
+ OPENOLT_LOG(ERROR, openolt_log_id, "Failed to retrieve ONU ranging time for PON %d/ONU id %d, err = %s (%d)\n", intf_id, onu_id, bcmos_strerror(err), err);
+ return bcm_to_grpc_err(err, "Failed to retrieve ONU ranging time");
+ }
+
+ if (onu_cfg.data.onu_state != BCMOLT_ONU_STATE_ACTIVE) {
+ OPENOLT_LOG(ERROR, openolt_log_id, "ONU is not yet activated (PON %d, ONU id %d)\n", intf_id, onu_id);
+ return bcm_to_grpc_err(BCM_ERR_PARM, "ONU is not yet activated\n");
+ }
+
+ LDi = LOGICAL_DISTANCE(mld*1000, onu_cfg.data.itu.ranging_time, ONU_BIT_TRANSMISSION_DELAY);
+ OPENOLT_LOG(INFO, openolt_log_id, "The ONU logical distance is %f, (PON %d, ONU id %d)\n", LDi, intf_id, onu_id);
+ response->set_intf_id(intf_id);
+ response->set_onu_id(onu_id);
+ response->set_logical_onu_distance(LDi);
+
+ return Status::OK;
+}
diff --git a/agent/src/core_utils.cc b/agent/src/core_utils.cc
index 1412000..9a59487 100644
--- a/agent/src/core_utils.cc
+++ b/agent/src/core_utils.cc
@@ -1295,3 +1295,39 @@
freeifaddrs(interfaces);
return ipAddress;
}
+
+bcmos_errno getOnuMaxLogicalDistance(uint32_t intf_id, uint32_t *mld) {
+ bcmos_errno err = BCM_ERR_OK;
+ bcmolt_pon_distance pon_distance = {};
+ bcmolt_pon_interface_cfg pon_cfg; /* declare main API struct */
+ bcmolt_pon_interface_key key = {}; /* declare key */
+
+ key.pon_ni = intf_id;
+
+ if (!state.is_activated()) {
+ OPENOLT_LOG(ERROR, openolt_log_id, "ONU maximum logical distance is not available since OLT is not activated yet\n");
+ return BCM_ERR_STATE;
+ }
+
+ /* Initialize the API struct. */
+ BCMOLT_CFG_INIT(&pon_cfg, pon_interface, key);
+ BCMOLT_FIELD_SET_PRESENT(&pon_distance, pon_distance, max_log_distance);
+ BCMOLT_FIELD_SET(&pon_cfg.data, pon_interface_cfg_data, pon_distance, pon_distance);
+ #ifdef TEST_MODE
+ // It is impossible to mock the setting of pon_cfg.data.state because
+ // the actual bcmolt_cfg_get passes the address of pon_cfg.hdr and we cannot
+ // set the pon_cfg.data.state. So a new stub function is created and address
+ // of pon_cfg is passed. This is one-of case where we need to add test specific
+ // code in production code.
+ err = bcmolt_cfg_get__pon_intf_stub(dev_id, &pon_cfg);
+ #else
+ err = bcmolt_cfg_get(dev_id, &pon_cfg.hdr);
+ #endif
+ if (err != BCM_ERR_OK) {
+ OPENOLT_LOG(ERROR, openolt_log_id, "Failed to retrieve ONU maximum logical distance for PON %d, err = %s (%d)\n", intf_id, bcmos_strerror(err), err);
+ return err;
+ }
+ *mld = pon_distance.max_log_distance;
+
+ return BCM_ERR_OK;
+}
diff --git a/agent/src/core_utils.h b/agent/src/core_utils.h
index 5f64e47..5de6753 100644
--- a/agent/src/core_utils.h
+++ b/agent/src/core_utils.h
@@ -101,4 +101,5 @@
Status check_bal_ready();
Status check_connection();
std::string get_ip_address(const char* nw_intf);
+bcmos_errno getOnuMaxLogicalDistance(uint32_t intf_id, uint32_t *mld);
#endif // OPENOLT_CORE_UTILS_H_