[VOL-3239] Fix MAC address reported to adapter when
Edgecore OLT is running in In-band mode.
-The openolt-agent report the MAC address of the interface on which the GRPC server is listening on.

Change-Id: Iee44d8247c7b86b312d6e289ab0607af6bf57c5d
diff --git a/agent/Makefile.in b/agent/Makefile.in
index c2587d8..e699a70 100644
--- a/agent/Makefile.in
+++ b/agent/Makefile.in
@@ -95,6 +95,7 @@
 CPPFLAGS += -DVERSION=\"$(VERSION)\" -DBAL_VER=\"$(BAL_VER)\" -DLABEL_VCS_URL=\"$(LABEL_VCS_URL)\" \
             -DLABEL_VCS_REF=\"$(LABEL_VCS_REF)\" -DLABEL_BUILD_DATE=\"$(LABEL_BUILD_DATE)\" \
             -DLABEL_COMMIT_DATE=\"$(LABEL_COMMIT_DATE)\" -DFLOW_CHECKER
+CPPFLAGS += -I./
 CXXFLAGS += -std=c++11 -fpermissive -Wno-literal-suffix
 LDFLAGS += @LDFLAGS@
 LDFLAGS += `pkg-config --libs protobuf grpc++ grpc` -ldl -lgpr
diff --git a/agent/common/main.cc b/agent/common/main.cc
index 4ebe2b8..b00b9b5 100644
--- a/agent/common/main.cc
+++ b/agent/common/main.cc
@@ -19,6 +19,7 @@
 
 #include "server.h"
 #include "core.h"
+#include "src/core_data.h"
 
 using namespace std;
 
@@ -137,6 +138,13 @@
     }
     else
         pushOltOperInd(0, "nni", "up");
+
+    for (int i = 1; i < argc; ++i) {
+       if(strcmp(argv[i-1], "--interface") == 0 || (strcmp(argv[i-1], "--intf") == 0)) {
+          grpc_server_interface_name = argv[i];
+          break;
+       }
+    }
     RunServer(argc, argv);
 
     return 0;
diff --git a/agent/src/core_api_handler.cc b/agent/src/core_api_handler.cc
index 9975c36..147582c 100644
--- a/agent/src/core_api_handler.cc
+++ b/agent/src/core_api_handler.cc
@@ -217,8 +217,23 @@
 
     char device_id[OPENOLT_FIELD_LEN];
     memset(device_id, '\0', OPENOLT_FIELD_LEN);
-    openolt_read_sysinfo("MAC", device_id);
-    OPENOLT_LOG(INFO, openolt_log_id, "Fetched device mac address %s\n", device_id);
+
+    if (grpc_server_interface_name != NULL) {
+       if (get_intf_mac(grpc_server_interface_name, device_id, sizeof(device_id)) != NULL)
+       {
+           OPENOLT_LOG(INFO, openolt_log_id, "Fetched mac address %s of an interface %s\n", device_id, grpc_server_interface_name);
+       }
+       else
+       {
+           OPENOLT_LOG(ERROR, openolt_log_id, "Mac address of an interface %s is NULL\n", grpc_server_interface_name);
+       }
+    }
+    else
+    {
+       openolt_read_sysinfo("MAC", device_id);
+       OPENOLT_LOG(INFO, openolt_log_id, "Fetched device mac address %s\n", device_id);
+    }
+
     device_info->set_device_id(device_id);
 
     // Legacy, device-wide ranges. To be deprecated when adapter
diff --git a/agent/src/core_data.cc b/agent/src/core_data.cc
index ec292e3..4f2be6d 100644
--- a/agent/src/core_data.cc
+++ b/agent/src/core_data.cc
@@ -178,3 +178,5 @@
 
 // Lock used to gaurd critical section during various API handling at the core_api_handler
 bcmos_fastlock data_lock;
+
+char* grpc_server_interface_name = NULL;
diff --git a/agent/src/core_data.h b/agent/src/core_data.h
index d44ed52..d0761c5 100644
--- a/agent/src/core_data.h
+++ b/agent/src/core_data.h
@@ -249,5 +249,7 @@
 
 extern bcmos_fastlock data_lock;
 
-
+// Interface name on which grpc server is running on
+// and this can be used to get the mac adress based on interface name.
+extern char* grpc_server_interface_name;
 #endif // OPENOLT_CORE_DATA_H_
diff --git a/agent/src/core_utils.cc b/agent/src/core_utils.cc
index 9a59487..98ef6a2 100644
--- a/agent/src/core_utils.cc
+++ b/agent/src/core_utils.cc
@@ -1331,3 +1331,41 @@
 
     return BCM_ERR_OK;
 }
+
+/**
+* Gets mac address based on interface name.
+*
+* @param intf_name interface name
+* @param mac_address  mac address field
+* @param max_size_of_mac_address max sixe of the mac_address
+* @return mac_address value in case of success or return NULL in case of failure.
+*/
+
+char* get_intf_mac(const char* intf_name, char* mac_address,  unsigned int max_size_of_mac_address){
+    int fd;
+    struct ifreq ifr;
+    char *mac;
+
+    fd = socket(AF_INET, SOCK_DGRAM, 0);
+    if ( fd == -1) {
+        OPENOLT_LOG(ERROR, openolt_log_id, "failed to get mac, could not create file descriptor");
+        return NULL;
+    }
+
+    ifr.ifr_addr.sa_family = AF_INET;
+    strncpy((char *)ifr.ifr_name , (const char *)intf_name , IFNAMSIZ-1);
+    if( ioctl(fd, SIOCGIFHWADDR, &ifr) == -1)
+    {
+        OPENOLT_LOG(ERROR, openolt_log_id, "failed to get mac, ioctl failed and returned err");
+        close(fd);
+        return NULL;
+    }
+
+    close(fd);
+    mac = (char *)ifr.ifr_hwaddr.sa_data;
+
+    // formatted mac address
+    snprintf(mac_address, max_size_of_mac_address, (const char *)"%.2x:%.2x:%.2x:%.2x:%.2x:%.2x", (unsigned char)mac[0], (unsigned char)mac[1], (unsigned char)mac[2], (unsigned char)mac[3], (unsigned char)mac[4], (unsigned char)mac[5]);
+
+    return mac_address;
+}
diff --git a/agent/src/core_utils.h b/agent/src/core_utils.h
index 5de6753..4a4d73f 100644
--- a/agent/src/core_utils.h
+++ b/agent/src/core_utils.h
@@ -19,6 +19,8 @@
 #include <unistd.h>
 #include <ifaddrs.h>
 #include <arpa/inet.h>
+#include <sys/ioctl.h>
+#include <net/if.h>
 
 #include "core.h"
 #include "core_data.h"
@@ -102,4 +104,5 @@
 Status check_connection();
 std::string get_ip_address(const char* nw_intf);
 bcmos_errno getOnuMaxLogicalDistance(uint32_t intf_id, uint32_t *mld);
+char* get_intf_mac(const char* intf_name, char* mac_address, unsigned int max_size_of_mac_address);
 #endif // OPENOLT_CORE_UTILS_H_