[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/test/41-0050/NOTE.md b/agent/test/41-0050/NOTE.md
new file mode 100644
index 0000000..5d1add7
--- /dev/null
+++ b/agent/test/41-0050/NOTE.md
@@ -0,0 +1,2 @@
+# Binary file format
+Confirms to SFF-8472 specification for SFP+ modules.
diff --git a/agent/test/41-0050/eeprom b/agent/test/41-0050/eeprom
new file mode 100644
index 0000000..7c461db
--- /dev/null
+++ b/agent/test/41-0050/eeprom
Binary files differ
diff --git a/agent/test/47-0050/NOTE.md b/agent/test/47-0050/NOTE.md
new file mode 100644
index 0000000..cd12da8
--- /dev/null
+++ b/agent/test/47-0050/NOTE.md
@@ -0,0 +1,2 @@
+# Binary file format
+Confirms to SFF-8436 specification for XFP modules.
diff --git a/agent/test/47-0050/sfp_eeprom b/agent/test/47-0050/sfp_eeprom
new file mode 100644
index 0000000..d69a119
--- /dev/null
+++ b/agent/test/47-0050/sfp_eeprom
Binary files differ
diff --git a/agent/test/Makefile b/agent/test/Makefile
index 5897ad3..94e0829 100644
--- a/agent/test/Makefile
+++ b/agent/test/Makefile
@@ -122,7 +122,7 @@
 	make -C $(OPENOLT_PROTOS_DIR) clean
 
 # openolt
-OPENOLT_SRCS = $(wildcard ../src/*.cc) ../common/server.cc $(wildcard ../device/$(OPENOLTDEVICE)/*.cc) src/bal_stub.cc
+OPENOLT_SRCS = $(wildcard ../src/*.cc) ../common/server.cc ../device/device.cc $(wildcard ../device/$(OPENOLTDEVICE)/*.cc) src/bal_stub.cc
 OPENOLT_OBJS = $(OPENOLT_SRCS:.cc=.o)
 $(OPENOLT_LIB): $(OPENOLT_OBJS)
 	mkdir -p lib
@@ -134,6 +134,8 @@
 	$(CXX) $(CXXFLAGS) $(CXXFLAGSDEVICE) -I../common -I./inc -I../src -c $< -o $@
 src/%.o: src/%.cc
 	$(CXX) $(CXXFLAGS) $(CXXFLAGSDEVICE) -I../common -I./inc -I../src -c $< -o $@
+../device/%.o: ../device/%.cc
+	$(CXX) $(CXXFLAGS) $(CXXFLAGSDEVICE) -I../common -I./inc -I../src -c $< -o $@
 ../device/$(OPENOLTDEVICE)/%.o: ../device/$(OPENOLTDEVICE)/%.cc
 	$(CXX) $(CXXFLAGS) $(CXXFLAGSDEVICE) -I../common -I./inc -I../src -c $< -o $@
 
@@ -141,4 +143,4 @@
 	./test_openolt --gtest_output="xml:./test_openolt_report_xunit.xml"
 
 clean:
-	rm -f src/*.o lib/*.a ../src/*.o ../common/*.o ./test_openolt  ./test_openolt_report_xunit.xml
+	rm -f src/*.o lib/*.a ../src/*.o ../common/*.o ../device/device.o ./test_openolt  ./test_openolt_report_xunit.xml
diff --git a/agent/test/inc/bal_mocker.h b/agent/test/inc/bal_mocker.h
index 8a8a9fa..81d6c19 100644
--- a/agent/test/inc/bal_mocker.h
+++ b/agent/test/inc/bal_mocker.h
@@ -27,13 +27,7 @@
 #include "bcmos_errno.h"
 #include "bcmolt_system_types_typedefs.h"
 #include "bcmolt_msg.h"
-
-/** Host subsystem initialization parameters */
-typedef struct bcmolt_host_init_parms
-{
-    int dummy;
-} bcmolt_host_init_parms;
-
+#include "bcmolt_host_api.h"
 }
 
 class BalMocker : public CMockMocker<BalMocker>
diff --git a/agent/test/src/bal_mocker.cc b/agent/test/src/bal_mocker.cc
index 72ef1d2..5a2d7f1 100644
--- a/agent/test/src/bal_mocker.cc
+++ b/agent/test/src/bal_mocker.cc
@@ -16,7 +16,7 @@
 
 #include "bal_mocker.h"
 extern "C" {
-CMOCK_MOCK_FUNCTION1(BalMocker, bcmolt_host_init, bcmos_errno(bcmolt_host_init_parms*));
+CMOCK_MOCK_FUNCTION1(BalMocker, bcmolt_host_init, bcmos_errno(const bcmolt_host_init_parms*));
 CMOCK_MOCK_FUNCTION2(BalMocker, bcmolt_cfg_get, bcmos_errno(bcmolt_oltid, bcmolt_cfg*));
 CMOCK_MOCK_FUNCTION2(BalMocker, bcmolt_oper_submit, bcmos_errno(bcmolt_oltid, bcmolt_oper*));
 CMOCK_MOCK_FUNCTION2(BalMocker, bcmolt_cfg_set, bcmos_errno(bcmolt_oltid, bcmolt_cfg*));
diff --git a/agent/test/src/test_core.cc b/agent/test/src/test_core.cc
index 75a26ad..dd8265e 100644
--- a/agent/test/src/test_core.cc
+++ b/agent/test/src/test_core.cc
@@ -18,6 +18,7 @@
 #include "bal_mocker.h"
 #include "core.h"
 #include "core_data.h"
+#include "core_utils.h"
 #include "server.h"
 #include <future>
 #include <fstream>
@@ -3956,3 +3957,73 @@
     ASSERT_EQ(rxtx_power_raw.first.second, 0x5C82);  // 23682
     ASSERT_STREQ(trx_eeprom_reader2.get_node_path(), "/sys/bus/i2c/devices/41-0050/eeprom");
 }
+
+////////////////////////////////////////////////////////////////////////////
+// For testing SFP eeprom read and decode capabilities
+////////////////////////////////////////////////////////////////////////////
+
+class TestEEPROMReadDecode : public Test {
+    protected:
+        virtual void SetUp() {
+        }
+        virtual void TearDown() {
+        }
+
+};
+
+// This test reads and decodes EEPROM data confirming to SFP8436 specification.
+// The XFP used on ASFVOLT16 OLTs confirm to this specification.
+TEST_F(TestEEPROMReadDecode, TestSFF8436Decode) {
+    bool res;
+    res = ponTrx.read_eeprom_data_for_sfp(0);
+    ASSERT_TRUE(res);
+    res = ponTrx.decode_eeprom_data(0);
+    ASSERT_TRUE(res);
+    trx_data* t = ponTrx.get_trx_data(0);
+    ASSERT_NE(t, NULL);
+    ASSERT_EQ(t->sfp_index, 0);
+    ASSERT_STREQ(t->vendor_name.c_str(), "Hisense         ");
+    ASSERT_STREQ(t->vendor_part_no.c_str(), "LTH7226-PC+     ");
+    ASSERT_STREQ(t->vendor_rev.c_str(), "01");
+    ASSERT_EQ(t->p_data[0].wavelength, 1577);
+
+}
+
+TEST_F(TestEEPROMReadDecode, TestHexToAsciiSuccess) {
+    std::string vn_ascii("SUPERXON LTD.   ");
+    std::string oui_ascii("");
+    std::string pn_ascii("SOGP4321-PSGB   ");
+    std::string rev_ascii("10");
+    pair<string, bool> res;
+    unsigned char vn_hex[EEPROM_VENDOR_NAME_LENGTH] = {0x53, 0x55, 0x50, 0x45, 0x52, 0x58, 0x4F, 0x4E,
+                                                       0x20, 0x4C, 0x54, 0x44, 0x2E, 0x20, 0x20, 0x20};
+    unsigned char oui_hex[EEPROM_VENDOR_OUI_LENGTH] = {0x00, 0x00, 0x00};
+    unsigned char pn_hex[EEPROM_VENDOR_PART_NUMBER_LENGTH] = {0x53, 0x4F, 0x47, 0x50, 0x34, 0x33, 0x32, 0x31,
+                                                              0x2D, 0x50, 0x53, 0x47, 0x42, 0x20, 0x20, 0x20};
+    unsigned char rev_hex[EEPROM_VENDOR_REVISION_LENGTH] = {0x31, 0x30};
+    res = hex_to_ascii_string(vn_hex, EEPROM_VENDOR_NAME_LENGTH);
+    ASSERT_TRUE(res.second);
+    ASSERT_STREQ(res.first.c_str(), vn_ascii.c_str());
+
+    res = hex_to_ascii_string(oui_hex, EEPROM_VENDOR_OUI_LENGTH);
+    ASSERT_TRUE(res.second);
+    ASSERT_STREQ(res.first.c_str(), oui_ascii.c_str());
+
+    res = hex_to_ascii_string(pn_hex, EEPROM_VENDOR_PART_NUMBER_LENGTH);
+    ASSERT_TRUE(res.second);
+    ASSERT_STREQ(res.first.c_str(), pn_ascii.c_str());
+
+    res = hex_to_ascii_string(rev_hex, EEPROM_VENDOR_REVISION_LENGTH);
+    ASSERT_TRUE(res.second);
+    ASSERT_STREQ(res.first.c_str(), rev_ascii.c_str());
+
+}
+
+TEST_F(TestEEPROMReadDecode, TestHexToUintSuccess) {
+    uint32_t wl_uint = 1490;
+    pair<uint32_t, bool> res;
+    unsigned char vn_hex[EEPROM_DOWNSTREAM_WAVELENGTH_LENGTH] = {0x05, 0xD2};
+    res = hex_to_uinteger(vn_hex, EEPROM_DOWNSTREAM_WAVELENGTH_LENGTH);
+    ASSERT_TRUE(res.second);
+    ASSERT_EQ(res.first, wl_uint);
+}
\ No newline at end of file