[VOL-4676]:
Initial Framework for reading SFP capabilities by reading the EEPROM data.
Use the detected SFP data to derive the MAC and PON system mode.
Make the SFP EEPROM read mode configurable per platform through the
DYNAMIC_PON_TRX_SUPPORT '#define' defined in the platform vendor.h file.

Change-Id: I07d7763371d2f804a1e93ca38646b1a30198f8ee
diff --git a/agent/src/core_api_handler.cc b/agent/src/core_api_handler.cc
index a833077..5b7bb74 100644
--- a/agent/src/core_api_handler.cc
+++ b/agent/src/core_api_handler.cc
@@ -403,12 +403,12 @@
                 BCMOLT_CFG_INIT(&dev_cfg, device, dev_key);
                 BCMOLT_MSG_FIELD_GET(&dev_cfg, system_mode);
 
-		/* FIXME: Single Phoenix BAL patch is prepared for all three variants of Radisys OLT
-		 * in which BCM_MAX_DEVS_PER_LINE_CARD macro need to be redefined as 1 incase of
-		 * "rlt-1600g-w" and "rlt-1600x-w", till then this workaround is required.*/
+		        /* FIXME: Single Phoenix BAL patch is prepared for all three variants of Radisys OLT
+		        * in which BCM_MAX_DEVS_PER_LINE_CARD macro need to be redefined as 1 incase of
+		        * "rlt-1600g-w" and "rlt-1600x-w", till then this workaround is required.*/
                 if (dev == 1 && (MODEL_ID == "rlt-1600g-w" || MODEL_ID == "rlt-1600x-w")) {
-		    continue;
-		}
+                    continue;
+                }
 
                 err = bcmolt_cfg_get(dev_id, &dev_cfg.hdr);
                 if (err == BCM_ERR_NOT_CONNECTED) {
@@ -416,18 +416,27 @@
                     bcmolt_device_connect oper;
                     BCMOLT_OPER_INIT(&oper, device, connect, key);
 
-		    /* BAL saves current state into dram_tune soc file and when dev_mgmt_daemon restarts
-		     * it retains config from soc file. If openolt agent try to connect device without
-		     * device reset device initialization fails hence doing device reset here. */
+		            /* BAL saves current state into dram_tune soc file and when dev_mgmt_daemon restarts
+		            * it retains config from soc file. If openolt agent try to connect device without
+		            * device reset device initialization fails hence doing device reset here. */
                     reset_pon_device(dev);
-
+                    bcmolt_system_mode sm;
+                    #ifdef DYNAMIC_PON_TRX_SUPPORT
+                    auto sm_res = ponTrx.get_mac_system_mode(dev, ponTrx.get_sfp_presence_data());
+                    if (!sm_res.second) {
+                        OPENOLT_LOG(ERROR, openolt_log_id, "could not read mac system mode. dev_id = %d\n", dev);
+                        continue;
+                    }
+                    sm = sm_res.first;
+                    #else
+                    sm = DEFAULT_MAC_SYSTEM_MODE;
+                    #endif
+                    BCMOLT_MSG_FIELD_SET (&oper, system_mode, sm);
                     if (MODEL_ID == "asfvolt16") {
                         BCMOLT_MSG_FIELD_SET(&oper, inni_config.mode, BCMOLT_INNI_MODE_ALL_10_G_XFI);
-                        BCMOLT_MSG_FIELD_SET (&oper, system_mode, BCMOLT_SYSTEM_MODE_XGS__2_X);
                     } else if (MODEL_ID == "asgvolt64") {
                         BCMOLT_MSG_FIELD_SET(&oper, inni_config.mode, BCMOLT_INNI_MODE_ALL_10_G_XFI);
                         BCMOLT_MSG_FIELD_SET(&oper, inni_config.mux, BCMOLT_INNI_MUX_FOUR_TO_ONE);
-                        BCMOLT_MSG_FIELD_SET (&oper, system_mode, BCMOLT_SYSTEM_MODE_GPON__16_X);
                     } else if (MODEL_ID == "rlt-3200g-w" || MODEL_ID == "rlt-1600g-w") {
                         BCMOLT_MSG_FIELD_SET(&oper, inni_config.mux, BCMOLT_INNI_MUX_NONE);
                         if(dev == 1) {
@@ -435,23 +444,14 @@
                         }
                         BCMOLT_MSG_FIELD_SET (&oper, ras_ddr_mode, BCMOLT_RAS_DDR_USAGE_MODE_TWO_DDRS);
                         BCMOLT_MSG_FIELD_SET(&oper, inni_config.mode, BCMOLT_INNI_MODE_ALL_10_G_XFI);
-                        BCMOLT_MSG_FIELD_SET (&oper, system_mode, BCMOLT_SYSTEM_MODE_GPON__16_X);
                     } else if (MODEL_ID == "rlt-1600x-w") {
                         BCMOLT_MSG_FIELD_SET(&oper, inni_config.mux, BCMOLT_INNI_MUX_NONE);
                         BCMOLT_MSG_FIELD_SET (&oper, ras_ddr_mode, BCMOLT_RAS_DDR_USAGE_MODE_TWO_DDRS);
                         BCMOLT_MSG_FIELD_SET(&oper, inni_config.mode, BCMOLT_INNI_MODE_ALL_10_G_XFI);
-                        /* By default setting device mode to GPON for rlt 1600x.
-                           In future device mode can be configured to XGSPON || GPON by reading
-                           device mode configuration from a static configuration file*/
-                        BCMOLT_MSG_FIELD_SET (&oper, system_mode, BCMOLT_SYSTEM_MODE_GPON__16_X);
                     } else if (MODEL_ID == "sda3016ss") {
                         BCMOLT_MSG_FIELD_SET(&oper, inni_config.mode, BCMOLT_INNI_MODE_ALL_12_P_5_G);
                         BCMOLT_MSG_FIELD_SET(&oper, inni_config.mux, BCMOLT_INNI_MUX_TWO_TO_ONE);
 						BCMOLT_MSG_FIELD_SET (&oper, ras_ddr_mode, BCMOLT_RAS_DDR_USAGE_MODE_TWO_DDRS);
-                        BCMOLT_MSG_FIELD_SET (&oper, system_mode, BCMOLT_SYSTEM_MODE_XGS__8_X_GPON__8_X_WDMA);
-                        /* By default setting device mode to XGSPON/GPON combo for sda3016ss.
-                           And it can also be configured to Any-PON (XGSPON || GPON) */
-
                     }
                     err = bcmolt_oper_submit(dev_id, &oper.hdr);
                     if (err) {
@@ -942,6 +942,9 @@
         BCMOLT_MSG_FIELD_SET(&interface_obj, itu.gpon.power_level.mode, BCMOLT_PON_POWER_LEVEL_MODE_DEFAULT);
     }
 
+    // TODO: Currently the PON Type is set automatically when the MAC System Mode is set. But it could be explicitely set here again.
+    // The data for the PON type is availabe in the PonTrx object (check trx_data)
+
     //Enable AES Encryption
     BCMOLT_MSG_FIELD_SET(&interface_obj, itu.onu_activation.key_exchange, BCMOLT_CONTROL_STATE_ENABLE);
     BCMOLT_MSG_FIELD_SET(&interface_obj, itu.onu_activation.authentication, BCMOLT_CONTROL_STATE_ENABLE);
diff --git a/agent/src/core_data.cc b/agent/src/core_data.cc
index bd83e81..da9c733 100644
--- a/agent/src/core_data.cc
+++ b/agent/src/core_data.cc
@@ -231,3 +231,6 @@
 // Read Rx optical power
 std::map<onu_rssi_compltd_key, Queue<onu_rssi_complete_result>*> onu_rssi_compltd_map;
 bcmos_fastlock onu_rssi_wait_lock;
+
+// PonTrx class object
+PonTrx ponTrx;
diff --git a/agent/src/core_utils.cc b/agent/src/core_utils.cc
index af3f7ad..dafc68c 100644
--- a/agent/src/core_utils.cc
+++ b/agent/src/core_utils.cc
@@ -1979,3 +1979,27 @@
         return false;
     }
 }
+
+pair<string, bool> hex_to_ascii_string(unsigned char* ptr, int length) {
+    // initialize the ASCII code string as empty.
+    string ascii = "";
+    for (size_t i = 0; i < length; i ++)
+    {
+        string part = string(1,ptr[i]);
+        ascii += part;
+    }
+    return {ascii, true};
+}
+
+pair<uint32_t, bool> hex_to_uinteger(unsigned char *ptr, int length) {
+    if (length > 8) {
+        perror("invalid length of bytes for conversion to uint\n");
+        return {0, false};
+    }
+    uint32_t res = 0;
+    for (int i = 0; i < length; i++)
+    {
+        res = uint32_t(ptr[i]) * pow(2, (length - 1 - i) * 8) + res;
+    }
+    return {res, true};
+}
diff --git a/agent/src/core_utils.h b/agent/src/core_utils.h
index 344ce5e..1813a37 100644
--- a/agent/src/core_utils.h
+++ b/agent/src/core_utils.h
@@ -127,4 +127,6 @@
 bool save_to_txt_file(const std::string& file_name, const std::string& content);
 bcmos_errno get_gem_obj_state(bcmolt_interface pon_ni, bcmolt_gem_port_id id, bcmolt_activation_state *state);
 bcmos_errno get_alloc_obj_state(bcmolt_interface pon_ni, bcmolt_alloc_id id, bcmolt_activation_state *state);
+pair<string, bool> hex_to_ascii_string(unsigned char* ptr, int length);
+pair<uint32_t, bool> hex_to_uinteger(unsigned char *ptr, int length);
 #endif // OPENOLT_CORE_UTILS_H_