VOL-2854: Add command line option to specify interface name in openolt on which gRPC server will run
          - OLT management interface or inband interface can be given as command line input and gRPC
            server will listen on given interface's IP address
          - If no interface name given gRPC server will listen on "0.0.0.0:9191"

Change-Id: I506fabf7ae81bf4d4ed8f6199107801daff62941
diff --git a/README.md b/README.md
index cb01501..8f51881 100644
--- a/README.md
+++ b/README.md
@@ -7,7 +7,7 @@
 through the [OpenOLT
 adapter](https://github.com/opencord/voltha/tree/master/voltha/adapters/openolt).
 
-OpenOLT agent uses Broadcom's BAL (Broadband Access Layer) software for
+OpenOLT agent uses Broadcom's BAL (Broadband Adaptation Layer) software for
 interfacing with the Maple/Qumran chipsets in OLTs such as the Edgecore/Accton
 ASXvOLT16.
 
@@ -131,11 +131,19 @@
 
 ```shell
 cd /broadcom
-./openolt
+./openolt --interface <interface-name> (or)
+./openolt --intf <interface-name>
 ```
 
-> **NOTE**: the two executables will remain open in the terminals, unless they
-> are put in background.
+> **NOTE**:
+
+* In the commands above, you should specify OLT management interface name or
+  inband interface name if OLT is used in inband mode. Openolt gRPC server
+  will start listening on given interface's IP address. If no interface
+  specified gRPC server will listen on "0.0.0.0:9191" which will accpet
+  requests from any of the interfaces present in OLT.
+* The two executables will remain open in the terminals, unless they are put
+  in background.
 
 ### Connect from VOLTHA
 
@@ -148,9 +156,10 @@
 
 ### Additional notes
 
-* *9191* is the TCP port that the *OpenOLT* agent uses for its gRPC channel
-* In the commands above, you can either use the loopback IP address (127.0.0.1)
-  or substitute all its occurrences with the management IP of your OLT
+* *9191* is the TCP port that the *OpenOLT* agent uses for its gRPC channel.
+* In the commands above, you should use OLT inband interface IP address if OLT
+  is used in inband mode, otherwise substitute all its occurrences with the
+  management IP of your OLT.
 
 ## Build OpenOLT
 
diff --git a/VERSION b/VERSION
index 197c4d5..005119b 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-2.4.0
+2.4.1
diff --git a/agent/common/core.h b/agent/common/core.h
index f73051e..31e10ed 100644
--- a/agent/common/core.h
+++ b/agent/common/core.h
@@ -238,6 +238,7 @@
 void stats_collection();
 Status check_connection();
 Status check_bal_ready();
+std::string get_ip_address(const char* nw_intf);
 
 // Stubbed defntions of bcmolt_cfg_get required for unit-test
 #ifdef TEST_MODE
diff --git a/agent/common/main.cc b/agent/common/main.cc
index 49d1175..4ebe2b8 100644
--- a/agent/common/main.cc
+++ b/agent/common/main.cc
@@ -137,7 +137,7 @@
     }
     else
         pushOltOperInd(0, "nni", "up");
-    RunServer();
+    RunServer(argc, argv);
 
     return 0;
 }
diff --git a/agent/common/server.cc b/agent/common/server.cc
index e33938b..13017a7 100644
--- a/agent/common/server.cc
+++ b/agent/common/server.cc
@@ -309,23 +309,32 @@
     };
 };
 
-void RunServer() {
-  OpenoltService service;
-  std::string server_address(serverPort);
-  ServerBuilder builder;
+void RunServer(int argc, char** argv) {
+    std::string ipAddress = "0.0.0.0";
 
-  builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
-  builder.RegisterService(&service);
+    for (int i = 1; i < argc; ++i) {
+        if(strcmp(argv[i-1], "--interface") == 0 || (strcmp(argv[i-1], "--intf") == 0)) {
+            ipAddress = get_ip_address(argv[i]);
+            break;
+        }
+    }
 
-  std::unique_ptr<Server> server(builder.BuildAndStart());
+    serverPort = ipAddress.append(":9191").c_str();
+    OpenoltService service;
+    std::string server_address(serverPort);
+    ServerBuilder builder;
 
-  time_t now;
-  time(&now);
-  signature = (int)now;
+    builder.AddListeningPort(server_address, grpc::InsecureServerCredentials());
+    builder.RegisterService(&service);
 
-  std::cout << "Server listening on " << server_address
-  << ", connection signature : " << signature << std::endl;
+    std::unique_ptr<Server> server(builder.BuildAndStart());
 
+    time_t now;
+    time(&now);
+    signature = (int)now;
 
-  server->Wait();
+    std::cout << "Server listening on " << server_address
+    << ", connection signature : " << signature << std::endl;
+
+    server->Wait();
 }
diff --git a/agent/common/server.h b/agent/common/server.h
index 2238287..f196fa3 100644
--- a/agent/common/server.h
+++ b/agent/common/server.h
@@ -17,6 +17,6 @@
 #ifndef OPENOLT_SERVER_H_
 #define OPENOLT_SERVER_H_
 
-void RunServer();
+void RunServer(int argc, char** argv);
 
 #endif
diff --git a/agent/scripts/init.d/openolt b/agent/scripts/init.d/openolt
index 585109d..ef80b24 100755
--- a/agent/scripts/init.d/openolt
+++ b/agent/scripts/init.d/openolt
@@ -19,6 +19,12 @@
 USER="root"
 GROUP="root"
 
+# If OLT is used in inband mode, inband interface name will be copied
+# to /etc/default/openolt file. Here inband interface is passed as argument
+# while running openolt service
+[ -r /etc/default/openolt ] && . /etc/default/openolt
+[ -z "gRPC_interface" ] || APPARGS="--interface $gRPC_interface"
+
 # Include functions 
 set -e
 . /lib/lsb/init-functions
diff --git a/agent/src/core_utils.cc b/agent/src/core_utils.cc
index 32de09d..6570c2f 100644
--- a/agent/src/core_utils.cc
+++ b/agent/src/core_utils.cc
@@ -1267,3 +1267,28 @@
     return Status::OK;
 }
 
+std::string get_ip_address(const char* nw_intf){
+    std::string ipAddress = "0.0.0.0";
+    struct ifaddrs *interfaces = NULL;
+    struct ifaddrs *temp_addr = NULL;
+    int success = 0;
+   /* retrieve the current interfaces - returns 0 on success */
+    success = getifaddrs(&interfaces);
+    if (success == 0) {
+        /* Loop through linked list of interfaces */
+        temp_addr = interfaces;
+        while(temp_addr != NULL) {
+            if(temp_addr->ifa_addr->sa_family == AF_INET) {
+                /* Check if interface given present in OLT, if yes return its IP Address */
+                if(strcmp(temp_addr->ifa_name, nw_intf) == 0){
+                    ipAddress=inet_ntoa(((struct sockaddr_in*)temp_addr->ifa_addr)->sin_addr);
+                    break;
+                }
+            }
+            temp_addr = temp_addr->ifa_next;
+        }
+    }
+    /* Free memory */
+    freeifaddrs(interfaces);
+    return ipAddress;
+}
diff --git a/agent/src/core_utils.h b/agent/src/core_utils.h
index ad48474..b686867 100644
--- a/agent/src/core_utils.h
+++ b/agent/src/core_utils.h
@@ -17,6 +17,8 @@
 #define OPENOLT_CORE_UTILS_H_
 #include <string>
 #include <unistd.h>
+#include <ifaddrs.h>
+#include <arpa/inet.h>
 
 #include "core.h"
 #include "core_data.h"
@@ -98,6 +100,5 @@
 Status handle_acl_rule_cleanup(int16_t acl_id, int32_t gemport_id, int32_t intf_id, const std::string flow_type);
 Status check_bal_ready();
 Status check_connection();
+std::string get_ip_address(const char* nw_intf);
 #endif // OPENOLT_CORE_UTILS_H_
-
-