First version of asfvolt16 device driver code

Change-Id: I806c2eaeebc7f8df7073c8264a7fdc6011b0d103
diff --git a/device_simulator/Makefile.am b/device_simulator/Makefile.am
index e8e1899..e1fa850 100644
--- a/device_simulator/Makefile.am
+++ b/device_simulator/Makefile.am
@@ -1,13 +1,13 @@
-bin_PROGRAMS = bal_server
+bin_PROGRAMS = voltha_bal_driver
 
-.PHONY = 
+.PHONY = brcm_lib
 
 HOSTPROG=yes
 
-DEFS += -DBAL_STUB
+DEFS += -UBAL_STUB
 
-bal_server_SOURCES = \
-    bal_server.c \
+voltha_bal_driver_SOURCES = \
+    voltha_bal_driver.c \
     bal_stub.c \
     grpc-c.h \
     bal_errno.grpc-c.h bal_indications.grpc-c.h bal_model_types.grpc-c.h \
@@ -46,16 +46,34 @@
     -lz \
     -lpthread
 
-EXTRA_bal_server_DEPENDENCIES=
+EXTRA_voltha_bal_driver_DEPENDENCIES=$(EDGECORE_DRIV_LIB) $(BRCM_BAL_LIB)
 
-LIBS = -lrt -lm
+EDGECORE = /home/asfvolt/shared/OpenNetworkLinux/EdgeCore/driver-app
+BRCM_PATH = /home/asfvolt/shared/OpenNetworkLinux/bal_src_release_2.4.3.6/bal_release
+EDGECORE_DRIV_LIB=./libEdgecoreDriver.a
+BRCM_BAL_LIB=./libbal_api_dist.so
+
+LIBS = $(EDGECORE_DRIV_LIB) $(BRCM_BAL_LIB) -lrt -lm
 
 AM_CFLAGS = \
     -I. \
     -I${srcdir}/../lib/h/ \
     -I${srcdir}/../third_party/protobuf-c \
-    -I${srcdir}/../third_party/grpc/include 
+    -I${srcdir}/../third_party/grpc/include \
+    -I${EDGECORE}/.
 
-clean_all: clean
+$(BRCM_BAL_LIB):
+	@cp $(BRCM_PATH)/build/core/lib/libbal_api_dist.so .
 
-all:bal_server$(EXEEXT)
+$(EDGECORE_DRIV_LIB):
+	@cd $(EDGECORE);make 
+	@cp $(EDGECORE)/libEdgecoreDriver.a .
+
+edgecore_lib_clean:
+	@cd $(EDGECORE);make clean
+	@rm -f libEdgecoreDriver.a
+
+clean_all: edgecore_lib_clean clean
+
+all:voltha_bal_driver$(EXEEXT)
+
diff --git a/device_simulator/README.md b/device_simulator/README.md
index 770ab96..7d2a1fd 100644
--- a/device_simulator/README.md
+++ b/device_simulator/README.md
@@ -1,6 +1,6 @@
 GRPC_C DEVICE SIMULATOR
 
- This is a executable(bal_server), which will recevie asfvolt16 adapter grpc-c messages and call respective device stub.
+ This is a executable(voltha_bal_driver), which will recevie asfvolt16 adapter grpc-c messages and call respective device stub.
  It will send recevied responses/asynchronous indications from Device stub to Adapter.
 
 GETTING STARTED
@@ -43,7 +43,7 @@
      Patch 2:
      Apply patch in service.c.patch and client.c.patch 
      - cp Makefile.am grpc-c/examples/
-     - cp bal_server.c grpc-c/examples/
+     - cp voltha_bal_driver.c grpc-c/examples/
      - cp bal_stub.c grpc-c/examples/
      - cp bal_stub.h grpc-c/examples/
          - Note: Update voltha adaptor IP in bal_stub.c
@@ -59,14 +59,17 @@
 To autogenerate code from proto files:
      - make autogen
        
-Build bal_server:
+Build voltha_bal_driver:
      - Note: Remove "-O2" from Makefile
      - make clean_all;make 
 
-The ultimate executable bal_server can be found under ~/grpc-c/build/examples/.libs/
+The ultimate executable voltha_bal_driver can be found under ~/grpc-c/build/examples/.libs/
 
 USAGE:
-    ./bal_server "serverIP:port"
+    ./voltha_bal_driver "serverIP:port1" -C "serverIP:port2" -A "serverIP:port3"
+    ./bal_core_dist -C "serverIP:port2" -A "serverIP:port3"
+
+NOTE: bal_core_dist is a broadcom executable
 
 CONTRIBUTING
      <TBD>
diff --git a/device_simulator/bal_server.c b/device_simulator/bal_server.c
deleted file mode 100644
index 9d6402f..0000000
--- a/device_simulator/bal_server.c
+++ /dev/null
@@ -1,343 +0,0 @@
-/*
- * Copyright (c) 2016, Juniper Networks, Inc.
- * All rights reserved.
- */
-
-#include <signal.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <sys/time.h>
-#include "bal_msg_type.grpc-c.h"
-#include "bal_osmsg.grpc-c.h"
-#include "bal_model_ids.grpc-c.h"
-#include "bal_obj.grpc-c.h"
-#include "bal_model_types.grpc-c.h"
-#include "bal_errno.grpc-c.h"
-#include "bal.grpc-c.h"
-
-#ifdef BAL_STUB
-#include "bal_stub.h"
-#endif
-
-static grpc_c_server_t *test_server;
-
-static void sigint_handler (int x) { 
-	grpc_c_server_destroy(test_server);
-	exit(0);
-}
-
-/*
- * This functions gets invoked whenever bal RPC gets called
- */
-void bal__bal_cfg_get_cb(grpc_c_context_t *context)
-{
-	BalCfg *get_cfg;
-
-	/*
-	 * Read incoming message into get_cfg
-	 */
-	if (context->gcc_payload) {
-		context->gcc_stream->read(context, (void **)&get_cfg, 0);
-	}
-
-}
-
-/*
- * This functions gets invoked whenever bal RPC gets called
- */
-void bal__bal_cfg_set_cb(grpc_c_context_t *context)
-{
-	BalCfg *set_cfg;
-	BalErr bal_err;
-
-	/*
-	 * Read incoming message into set_cfg
-	 */
-	if (context->gcc_payload) {
-		context->gcc_stream->read(context, (void **)&set_cfg, 0);
-	}
-
-	/*
-	 * send it to BAL
-	 */
-
-	bal_err__init(&bal_err);
-
-	bal_err.err= 0;
-
-	/*
-	 * Write reply back to the client
-	 */
-	if (!context->gcc_stream->write(context, &bal_err, 0)) {
-	} else {
-		printf("Failed to write\n");
-		exit(1);
-	}
-
-	grpc_c_status_t status;
-	status.gcs_code = 0;
-
-	/*
-	 * Finish response for RPC
-	 */
-	if (context->gcc_stream->finish(context, &status)) {
-		printf("Failed to write status\n");
-		exit(1);
-	}
-
-#ifdef BAL_STUB
-	pthread_mutex_lock(&lock);
-
-	struct QNode *temp = newNode(set_cfg->hdr->obj_type, 
-			BAL_ERRNO__BAL_ERR_OK, 
-			set_cfg->device_id);
-
-	if(set_cfg->hdr->has_obj_type)
-	{
-
-		switch(set_cfg->hdr->obj_type)
-		{
-			case BAL_OBJ_ID__BAL_OBJ_ID_ACCESS_TERMINAL:
-				{
-					printf("\n***************************************************\n");  
-					printf("Received Access Terminal Configuration msg\n");
-					printf("***************************************************\n");  
-				}
-				break;
-			case BAL_OBJ_ID__BAL_OBJ_ID_INTERFACE:
-				{
-					printf("\n***************************************************\n");  
-					printf("Received PON Interface Configuration msg\n");
-					printf("***************************************************\n");  
-					temp->intf_id = set_cfg->interface->key->intf_id;
-					printf("Pon ID = %d\n", temp->intf_id);
-				}
-				break;
-			case BAL_OBJ_ID__BAL_OBJ_ID_SUBSCRIBER_TERMINAL:
-				{
-					printf("\n*****************************************************\n");  
-					printf("Received ONU Activation msg\n");
-					printf("*****************************************************\n");  
-					temp->intf_id = set_cfg->terminal->key->intf_id;
-					temp->onu_id = set_cfg->terminal->key->sub_term_id;
-				}
-				break;
-                        case BAL_OBJ_ID__BAL_OBJ_ID_PACKET:
-                                {
-                                   switch(set_cfg->packet->key->packet_send_dest->type)
-                                   {
-					case BAL_DEST_TYPE__BAL_DEST_TYPE_ITU_OMCI_CHANNEL:
-				        {
-						printf("\n*****************************************************\n");  
-						printf("Received OMCI msg\n");
-						printf("*****************************************************\n");  
-						temp->intf_id = set_cfg->terminal->key->intf_id;
-						temp->onu_id = set_cfg->terminal->key->sub_term_id;
-					}
-					break;
-					default:
-					{
-						("\n*****************************************************\n");  
-						printf("Dest type invalid\n");
-						printf("*****************************************************\n");  
-					}
-					break;
-				   }
-                                }
-                                break;
-			default:
-				{
-				("\n*****************************************************\n");  
-				printf("Received Invalid msg\n");
-				printf("*****************************************************\n");  
-				}
-				break;
-		}
-		enQueue(set_cfg->hdr->obj_type, temp);
-	}
-	else
-	{
-		printf("BALSTUB:Cfg Set recevied without object type");
-	}
-	pthread_mutex_unlock(&lock);
-	sleep(2);   
-	pthread_cond_signal(&cv);
-	if(BAL_OBJ_ID__BAL_OBJ_ID_INTERFACE == set_cfg->hdr->obj_type)
-	{
-		sleep(5); 
-		struct QNode *temp1 = newNode(BAL_OBJ_ID__BAL_OBJ_ID_SUBSCRIBER_TERMINAL, 
-				BAL_ERRNO__BAL_ERR_OK, 
-				set_cfg->device_id);
-		temp1->intf_id = set_cfg->interface->key->intf_id;
-		temp1->onu_id = 65535;
-		printf("sending _onu_discovery_indiaction\n");
-		enQueue(BAL_OBJ_ID__BAL_OBJ_ID_SUBSCRIBER_TERMINAL, temp1); 
-		pthread_cond_signal(&cv);
-	}
-#endif
-}
-
-
-/*
- * This functions gets invoked whenever bal clear RPC gets called
- */
-void bal__bal_cfg_clear_cb(grpc_c_context_t *context)
-{
-	BalKey *clear_key;
-
-	/*
-	 * Read incoming message into clear_key 
-	 */
-	if (context->gcc_payload) {
-		context->gcc_stream->read(context, (void **)&clear_key, 0);
-	}
-
-}
-
-
-/*
- * This functions gets invoked whenever bal Init RPC gets called
- */
-void bal__bal_api_init_cb(grpc_c_context_t *context)
-{
-	BalInit *bal_init;
-	BalErr bal_err;
-
-	/*
-	 * Read incoming message into set_cfg
-	 */
-	if (context->gcc_payload) {
-		context->gcc_stream->read(context, (void **)&bal_init, 0);
-	}
-
-	/*
-	 * send it to BAL
-	 */
-
-
-	("\n*****************************************************\n");  
-	printf("Received API Init msg\n");
-	printf("*****************************************************\n");  
-
-	bal_err__init(&bal_err);
-
-	bal_err.err= 0;
-
-	/*
-	 * Write reply back to the client
-	 */
-	if (!context->gcc_stream->write(context, &bal_err, 0)) {
-	} else {
-		printf("Failed to write\n");
-		exit(1);
-	}
-
-	grpc_c_status_t status;
-	status.gcs_code = 0;
-
-	/*
-	 * Finish response for RPC
-	 */
-	if (context->gcc_stream->finish(context, &status)) {
-		printf("Failed to write status\n");
-		exit(1);
-	}
-
-}
-
-
-/*
- * This functions gets invoked whenever bal finish RPC gets called
- */
-void bal__bal_api_finish_cb(grpc_c_context_t *context)
-{
-#if 0
-	void *finish_init;
-
-	/*
-	 * Read incoming message into set_cfg
-	 */
-	if (context->gcc_payload) {
-		context->gcc_stream->read(context, (void **)&finish_init);
-	}
-#endif
-}
-
-
-/*
- * This functions gets invoked whenever bal finish RPC gets called
- */
-void bal_ind__bal_ind_info_cb(grpc_c_context_t *context)
-{
-#if 0
-	void *finish_init;
-
-	/*
-	 * Read incoming message into set_cfg
-	 */
-	if (context->gcc_payload) {
-		context->gcc_stream->read(context, (void **)&finish_init);
-	}
-#endif
-}
-
-
-/*
- * Takes socket path as argument
- */
-int main (int argc, char **argv) 
-{
-	int i = 0;
-	grpc_c_server_t *server = NULL;
-
-	printf("*************\n");
-	printf("BAL STUB\n");
-	printf("*************\n");
-	if (argc < 2) {
-		fprintf(stderr, "Missing socket path argument\n");
-		exit(1);
-	}
-
-	signal(SIGINT, sigint_handler);
-	/*
-	 * Initialize grpc-c library to be used with vanilla gRPC
-	 */
-	grpc_c_init(GRPC_THREADS, NULL);
-
-	/*
-	 * Create server object
-	 */
-	test_server = grpc_c_server_create(argv[1]);
-
-	if (test_server == NULL) {
-		printf("Failed to create server\n");
-		exit(1);
-	}
-
-	/*
-	 * Initialize greeter service
-	 */
-	printf("\nCreating a test server\n");
-	bal__service_init(test_server);
-
-	/*
-	 * Start server
-	 */
-	grpc_c_server_start(test_server);
-
-#ifdef BAL_STUB
-	printf("\nCreating a stub thread\n");
-	create_stub_thread();
-#else
-	grpc_c_client_t *client = grpc_c_client_init("172.24.150.114:60001", "bal_client", NULL);
-#endif
-
-	/*
-	 * Blocks server to wait to completion
-	 */
-	grpc_c_server_wait(test_server);
-
-	/* code added for example Makefile to compile grpc-c along with edgecore driver */
-	bal__service_init(server);
-
-}
diff --git a/device_simulator/bal_stub.c b/device_simulator/bal_stub.c
index 4b61bd5..522c56a 100644
--- a/device_simulator/bal_stub.c
+++ b/device_simulator/bal_stub.c
@@ -13,6 +13,7 @@
 ** See the License for the specific language governing permissions and
 ** limitations under the License.
 */
+
 #ifdef BAL_STUB
 #include <stdlib.h>
 #include <stdio.h>
@@ -28,237 +29,298 @@
 #include "bal_indications.grpc-c.h"
 #include "bal.grpc-c.h"
 
+char *voltha_ip_and_port = NULL;
+
 void *stub_thread(void *v) 
 {
-	int status;
-	grpc_c_client_t *client = grpc_c_client_init("172.24.150.167:60001", "bal_client", NULL);
-	pthread_mutex_lock(&lock);
-	pthread_cond_wait(&cv, &lock);
-	while(NULL != shared_queue->front)
-	{
-		BalObjId prevObjType;
-		char vendor_id[20];
-		char vendor_specific[20];
-		struct QNode *front = deQueue(shared_queue);
-		/* prepare and send rpc response */
-		BalIndications balIndCfg;
-		memset(&balIndCfg, 0, sizeof(BalIndications));
-		bal_indications__init(&balIndCfg);
-		balIndCfg.has_objtype = 1;
-		balIndCfg.objtype = front->obj_type;
-		balIndCfg.device_id = front->device_id;
-		printf("Device Id = %s\n", front->device_id);
-		switch(front->obj_type)
-		{
-			case BAL_OBJ_ID__BAL_OBJ_ID_ACCESS_TERMINAL:
-				{
-					printf("***************************************************\n");
-					printf("Successful Indication sent for ACCESS_TERMINAL\n");
-					printf("***************************************************\n");
-					balIndCfg.u_case = BAL_INDICATIONS__U_ACCESS_TERM_IND;
-					prevObjType = front->obj_type;
-				}
-				break;
-			case BAL_OBJ_ID__BAL_OBJ_ID_INTERFACE:
-				{
-					printf("***************************************************\n");
-					printf("Successful Indication sent for PON INTERFACE UP\n");
-					printf("***************************************************\n");
-					balIndCfg.u_case = BAL_INDICATIONS__U_INTERFACE_IND;
-					prevObjType = front->obj_type;
-				}
-				break;
-			case BAL_OBJ_ID__BAL_OBJ_ID_SUBSCRIBER_TERMINAL:
-				{
-					BalSubscriberTerminalKey subTermKey;
-					memset(&subTermKey, 0, sizeof(BalSubscriberTerminalKey));
-					bal_subscriber_terminal_key__init(&subTermKey);
+   int status;
+   pthread_mutex_lock(&lock);
+   pthread_cond_wait(&cv, &lock);
+   while(NULL != shared_queue->front)
+   {
+      BalErr *output;
+      BalObjId prevObjType;
+      char vendor_id[20];
+      char vendor_specific[20];
+      struct QNode *front = deQueue(shared_queue);
+      /* prepare and send rpc response */
+      BalIndications balIndCfg;
+      memset(&balIndCfg, 0, sizeof(BalIndications));
+      bal_indications__init(&balIndCfg);
+      balIndCfg.has_objtype = 1;
+      balIndCfg.objtype = front->obj_type;
+      balIndCfg.device_id = front->device_id;
+      printf("Device Id = %s\n", front->device_id);
+      switch(front->obj_type)
+      {
+         case BAL_OBJ_ID__BAL_OBJ_ID_ACCESS_TERMINAL:
+            {
+               printf("***************************************************\n");
+               printf("Successful Indication sent for ACCESS_TERMINAL\n");
+               printf("***************************************************\n");
+               balIndCfg.u_case = BAL_INDICATIONS__U_ACCESS_TERM_IND;
+               prevObjType = front->obj_type;
+               BalAccessTerminalKey accTermKey;
+               memset(&accTermKey, 0, sizeof(BalAccessTerminalKey));
+               bal_access_terminal_key__init(&accTermKey);
+               accTermKey.has_access_term_id = 1;
+               accTermKey.access_term_id = 1;
+               
+               BalAccessTerminalIndData data;
+               memset(&data, 0, sizeof(BalAccessTerminalIndData));
+               bal_access_terminal_ind_data__init(&data);
+               data.has_admin_state = 1;
+               data.admin_state = BAL_STATE__BAL_STATE_UP;
 
-					BalSerialNumber serial_number;
-					memset(&serial_number, 0, sizeof(BalSerialNumber));
-					bal_serial_number__init(&serial_number);
+               BalAccessTerminalInd access_term_ind;
+               memset(&access_term_ind, 0, sizeof(BalAccessTerminalInd));
+               bal_access_terminal_ind__init(&access_term_ind);
+               access_term_ind.data = &data;
+               access_term_ind.key = &accTermKey;
+               balIndCfg.access_term_ind = &access_term_ind;
+               status = bal_ind__bal_acc_term_ind(client, NULL, &balIndCfg, &output, NULL, 0);
+            }
+            break;
+         case BAL_OBJ_ID__BAL_OBJ_ID_INTERFACE:
+            {
+               printf("***************************************************\n");
+               printf("Successful Indication sent for PON INTERFACE UP\n");
+               printf("***************************************************\n");
+               balIndCfg.u_case = BAL_INDICATIONS__U_INTERFACE_IND;
+               prevObjType = front->obj_type;
+               status = bal_ind__bal_iface_ind(client, NULL, &balIndCfg, &output, NULL, 0);
+            }
+            break;
+         case BAL_OBJ_ID__BAL_OBJ_ID_SUBSCRIBER_TERMINAL:
+            {
+               BalSubscriberTerminalKey subTermKey;
+               memset(&subTermKey, 0, sizeof(BalSubscriberTerminalKey));
+               bal_subscriber_terminal_key__init(&subTermKey);
 
-					char vendor_id[20];
-					memset(&vendor_id, 0, 20);
-					strcpy(vendor_id,"4252434D");
-					char vendor_specific[20];
-					memset(&vendor_specific, 0, 20);
-					strcpy(vendor_specific,"12345678");
+               BalSerialNumber serial_number;
+               memset(&serial_number, 0, sizeof(BalSerialNumber));
+               bal_serial_number__init(&serial_number);
 
-					if(BAL_OBJ_ID__BAL_OBJ_ID_INTERFACE == prevObjType)
-					{
-						balIndCfg.u_case = BAL_INDICATIONS__U_TERMINAL_DISC;
-						BalSubscriberTerminalSubTermDisc terminal_disc;
-						memset(&terminal_disc, 0, sizeof(BalSubscriberTerminalSubTermDisc));
-						bal_subscriber_terminal_sub_term_disc__init(&terminal_disc);
-						balIndCfg.terminal_disc = &terminal_disc;
+/*
+               char vendor_id[20];
+               memset(&vendor_id, 0, 20);
+               strcpy(vendor_id,"4252434D");
+               char vendor_specific[20];
+               memset(&vendor_specific, 0, 20);
+               strcpy(vendor_specific,"12345678");
 
-						balIndCfg.terminal_disc->key = &subTermKey;
-						balIndCfg.terminal_disc->key->has_sub_term_id = 1;
-						balIndCfg.terminal_disc->key->sub_term_id = front->onu_id;
-						balIndCfg.terminal_disc->key->has_intf_id = 1;
-						balIndCfg.terminal_disc->key->intf_id = front->intf_id;
+               if(BAL_OBJ_ID__BAL_OBJ_ID_INTERFACE == prevObjType)
+               {
+                  balIndCfg.u_case = BAL_INDICATIONS__U_TERMINAL_DISC;
+                  BalSubscriberTerminalSubTermDisc terminal_disc;
+                  memset(&terminal_disc, 0, sizeof(BalSubscriberTerminalSubTermDisc));
+                  bal_subscriber_terminal_sub_term_disc__init(&terminal_disc);
+                  balIndCfg.terminal_disc = &terminal_disc;
 
-						BalSubscriberTerminalSubTermDiscData subTermCfgData;
-						memset(&subTermCfgData, 0, sizeof(BalSubscriberTerminalSubTermDiscData));
-						bal_subscriber_terminal_sub_term_disc_data__init(&subTermCfgData);
-						balIndCfg.terminal_disc->data = &subTermCfgData;
-						balIndCfg.terminal_disc->data->serial_number = &serial_number;
-						balIndCfg.terminal_disc->data->serial_number->vendor_id = vendor_id;
-						printf("\n***************************************************\n");
-						printf("Sending ONU discovery message\n");
-						printf("***************************************************\n");
-					}
-					else
-					{
-						balIndCfg.u_case = BAL_INDICATIONS__U_TERMINAL_IND;
-						BalSubscriberTerminalInd terminal_ind;
-						memset(&terminal_ind, 0, sizeof(BalSubscriberTerminalInd));
-						bal_subscriber_terminal_ind__init(&terminal_ind);
-						balIndCfg.terminal_ind = &terminal_ind;
+                  balIndCfg.terminal_disc->key = &subTermKey;
+                  balIndCfg.terminal_disc->key->has_sub_term_id = 1;
+                  balIndCfg.terminal_disc->key->sub_term_id = front->onu_id;
+                  balIndCfg.terminal_disc->key->has_intf_id = 1;
+                  balIndCfg.terminal_disc->key->intf_id = front->intf_id;
 
-						balIndCfg.terminal_ind->key = &subTermKey;
-						balIndCfg.terminal_ind->key->has_sub_term_id = 1;
-						balIndCfg.terminal_ind->key->sub_term_id = front->onu_id;
-						balIndCfg.terminal_ind->key->has_intf_id = 1;
-						balIndCfg.terminal_ind->key->intf_id = front->intf_id;
+                  BalSubscriberTerminalSubTermDiscData subTermCfgData;
+                  memset(&subTermCfgData, 0, sizeof(BalSubscriberTerminalSubTermDiscData));
+                  bal_subscriber_terminal_sub_term_disc_data__init(&subTermCfgData);
+                  balIndCfg.terminal_disc->data = &subTermCfgData;
+                  balIndCfg.terminal_disc->data->serial_number = &serial_number;
+                  balIndCfg.terminal_disc->data->serial_number->vendor_id = vendor_id;
+                  printf("\n***************************************************\n");
+                  printf("Sending ONU discovery message\n");
+                  printf("***************************************************\n");
+                  status = bal_ind__bal_subs_term_discovery_ind(client, NULL, &balIndCfg, &output, NULL, 0);
+               }
+               else
+               {
+*/
+                  balIndCfg.u_case = BAL_INDICATIONS__U_TERMINAL_DISC;
+                  balIndCfg.has_sub_group = 1;
+                  balIndCfg.sub_group = BAL_SUBSCRIBER_TERMINAL_AUTO_ID__BAL_SUBSCRIBER_TERMINAL_AUTO_ID_SUB_TERM_DISC;
+                  BalSubscriberTerminalSubTermDisc terminal_disc;
+                  memset(&terminal_disc, 0, sizeof(BalSubscriberTerminalSubTermDisc));
+                  bal_subscriber_terminal_sub_term_disc__init(&terminal_disc);
+                  balIndCfg.terminal_disc = &terminal_disc;
 
-						BalSubscriberTerminalIndData subTermCfgData;
-						memset(&subTermCfgData, 0, sizeof(BalSubscriberTerminalIndData));
-						bal_subscriber_terminal_ind_data__init(&subTermCfgData);
-						balIndCfg.terminal_ind->data = &subTermCfgData;
-						balIndCfg.terminal_ind->data->has_admin_state = 1;
-						balIndCfg.terminal_ind->data->admin_state = BAL_STATE__BAL_STATE_UP;
-						balIndCfg.terminal_ind->data->has_oper_status = 1;
-						balIndCfg.terminal_ind->data->oper_status = BAL_STATUS__BAL_STATUS_UP;
-						balIndCfg.terminal_ind->data->serial_number = &serial_number;
-						balIndCfg.terminal_ind->data->serial_number->vendor_id = vendor_id;
-						balIndCfg.terminal_ind->data->serial_number->vendor_specific = vendor_specific;
-						printf("***************************************************\n");
-						printf("ONU Activation Successful\n");
-						printf("***************************************************\n");
-					}
-					prevObjType = front->obj_type;
-				}
-				break;
-			case BAL_OBJ_ID__BAL_OBJ_ID_PACKET:
-				{
-					balIndCfg.u_case = BAL_INDICATIONS__U_BAL_OMCI_RESP;
-                                        BalPacketItuOmciChannelRx balomciresp;
-			                memset(&balomciresp, 0, sizeof(BalPacketItuOmciChannelRx));
-                                        bal_packet_itu_omci_channel_rx__init(&balomciresp);
+                  balIndCfg.terminal_disc->key = &subTermKey;
+                  balIndCfg.terminal_disc->key->has_sub_term_id = 1;
+                  balIndCfg.terminal_disc->key->sub_term_id = front->onu_id;
+                  balIndCfg.terminal_disc->key->has_intf_id = 1;
+                  balIndCfg.terminal_disc->key->intf_id = front->intf_id;
+
+                  BalSubscriberTerminalSubTermDiscData subTermDiscCfgData;
+                  memset(&subTermDiscCfgData, 0, sizeof(BalSubscriberTerminalSubTermDiscData));
+                  bal_subscriber_terminal_sub_term_disc_data__init(&subTermDiscCfgData);
+                  balIndCfg.terminal_disc->data = &subTermDiscCfgData;
+                  balIndCfg.terminal_disc->data->serial_number = &serial_number;
+                  balIndCfg.terminal_disc->data->serial_number->vendor_id = front->vendor_id;
+                  balIndCfg.terminal_disc->data->serial_number->vendor_specific = front->vendor_specific;
+                  printf("\n***************************************************\n");
+                  printf("Sending ONU discovery message\n");
+                  printf("***************************************************\n");
+                  status = bal_ind__bal_subs_term_discovery_ind(client, NULL, &balIndCfg, &output, NULL, 0);
+
+
+                  balIndCfg.u_case = BAL_INDICATIONS__U_TERMINAL_IND;
+                  balIndCfg.has_sub_group = 1;
+                  balIndCfg.sub_group = BAL_SUBSCRIBER_TERMINAL_AUTO_ID__BAL_SUBSCRIBER_TERMINAL_AUTO_ID_IND;
+                  BalSubscriberTerminalInd terminal_ind;
+                  memset(&terminal_ind, 0, sizeof(BalSubscriberTerminalInd));
+                  bal_subscriber_terminal_ind__init(&terminal_ind);
+                  balIndCfg.terminal_ind = &terminal_ind;
+
+                  balIndCfg.terminal_ind->key = &subTermKey;
+                  balIndCfg.terminal_ind->key->has_sub_term_id = 1;
+                  balIndCfg.terminal_ind->key->sub_term_id = front->onu_id;
+                  balIndCfg.terminal_ind->key->has_intf_id = 1;
+                  balIndCfg.terminal_ind->key->intf_id = front->intf_id;
+
+                  BalSubscriberTerminalIndData subTermCfgData;
+                  memset(&subTermCfgData, 0, sizeof(BalSubscriberTerminalIndData));
+                  bal_subscriber_terminal_ind_data__init(&subTermCfgData);
+                  balIndCfg.terminal_ind->data = &subTermCfgData;
+                  balIndCfg.terminal_ind->data->has_admin_state = 1;
+                  balIndCfg.terminal_ind->data->admin_state = BAL_STATE__BAL_STATE_UP;
+                  balIndCfg.terminal_ind->data->has_oper_status = 1;
+                  balIndCfg.terminal_ind->data->oper_status = BAL_STATUS__BAL_STATUS_UP;
+                  balIndCfg.terminal_ind->data->serial_number = &serial_number;
+                  balIndCfg.terminal_ind->data->serial_number->vendor_id = front->vendor_id;
+                  balIndCfg.terminal_ind->data->serial_number->vendor_specific = front->vendor_specific;
+                  printf("***************************************************\n");
+                  printf("ONU Activation Successful %s\n", balIndCfg.terminal_ind->data->serial_number->vendor_specific);
+                  printf("***************************************************\n");
+                  status = bal_ind__bal_subs_term_ind(client, NULL, &balIndCfg, &output, NULL, 0);
+/*
+               }
+*/
+               prevObjType = front->obj_type;
+            }
+            break;
+         case BAL_OBJ_ID__BAL_OBJ_ID_PACKET:
+            {
+               balIndCfg.u_case = BAL_INDICATIONS__U_BAL_OMCI_RESP;
+               BalPacketItuOmciChannelRx balomciresp;
+               memset(&balomciresp, 0, sizeof(BalPacketItuOmciChannelRx));
+               bal_packet_itu_omci_channel_rx__init(&balomciresp);
                                               
-                                        BalPacketKey balomcirespkey;
-			                memset(&balomcirespkey, 0, sizeof(BalPacketKey));
-                                        bal_packet_key__init(&balomcirespkey); 
-                                        balomciresp.key = &balomcirespkey;
+               BalPacketKey balomcirespkey;
+               memset(&balomcirespkey, 0, sizeof(BalPacketKey));
+               bal_packet_key__init(&balomcirespkey); 
+               balomciresp.key = &balomcirespkey;
 
-                                        BalDest balomcirespkeydest;
-			                memset(&balomcirespkeydest, 0, sizeof(BalDest));
-                                        bal_dest__init(&balomcirespkeydest);
-                                        balomciresp.key->packet_send_dest = &balomcirespkeydest;
-                                        balomciresp.key->packet_send_dest->has_type = 1;
-                                        balomciresp.key->packet_send_dest->type = BAL_DEST_TYPE__BAL_DEST_TYPE_ITU_OMCI_CHANNEL;
-                                        balomciresp.key->packet_send_dest->u_case = BAL_DEST__U_ITU_OMCI_CHANNEL;
-                                
-                                        BalItuOmciChannel itu_omci_channel;
-			                memset(&itu_omci_channel, 0, sizeof(BalItuOmciChannel));
-                                        bal_itu_omci_channel__init(&itu_omci_channel);
-                                        balomciresp.key->packet_send_dest->itu_omci_channel = &itu_omci_channel;
-                                        balomciresp.key->packet_send_dest->itu_omci_channel->has_sub_term_id = 1;
-                                        balomciresp.key->packet_send_dest->itu_omci_channel->sub_term_id = front->onu_id;
-                                        balomciresp.key->packet_send_dest->itu_omci_channel->has_int_id = 1;
-                                        balomciresp.key->packet_send_dest->itu_omci_channel->int_id = front->intf_id;
-				}
-				break;
-			default:
-				{
-					balIndCfg.u_case = BAL_INDICATIONS__U__NOT_SET;
-					prevObjType = front->obj_type;
-				}
-				break;
-		}
-		BalErr *output;
-		status = bal_ind__bal_ind_info(client, NULL, &balIndCfg, &output, NULL, 0);
-		free(front);
-		pthread_mutex_unlock(&lock);
-		pthread_mutex_lock(&lock);
-		pthread_cond_wait(&cv, &lock);
-	}
-	return NULL;
+               BalDest balomcirespkeydest;
+               memset(&balomcirespkeydest, 0, sizeof(BalDest));
+	       bal_dest__init(&balomcirespkeydest);
+	       balomciresp.key->packet_send_dest = &balomcirespkeydest;
+	       balomciresp.key->packet_send_dest->has_type = 1;
+	       balomciresp.key->packet_send_dest->type = BAL_DEST_TYPE__BAL_DEST_TYPE_ITU_OMCI_CHANNEL;
+	       balomciresp.key->packet_send_dest->u_case = BAL_DEST__U_ITU_OMCI_CHANNEL;
+
+	       BalItuOmciChannel itu_omci_channel;
+	       memset(&itu_omci_channel, 0, sizeof(BalItuOmciChannel));
+	       bal_itu_omci_channel__init(&itu_omci_channel);
+	       balomciresp.key->packet_send_dest->itu_omci_channel = &itu_omci_channel;
+	       balomciresp.key->packet_send_dest->itu_omci_channel->has_sub_term_id = 1;
+	       balomciresp.key->packet_send_dest->itu_omci_channel->sub_term_id = front->onu_id;
+	       balomciresp.key->packet_send_dest->itu_omci_channel->has_intf_id = 1;
+	       balomciresp.key->packet_send_dest->itu_omci_channel->intf_id = front->intf_id;
+	       status = bal_ind__bal_pkt_omci_channel_rx_ind(client, NULL, &balIndCfg, &output, NULL, 0);
+            }
+            break;
+         default:
+            {
+               balIndCfg.u_case = BAL_INDICATIONS__U__NOT_SET;
+               prevObjType = front->obj_type;
+            }
+            break;
+      }
+      free(front);
+      pthread_mutex_unlock(&lock);
+      pthread_mutex_lock(&lock);
+      pthread_cond_wait(&cv, &lock);
+   }
+   return NULL;
 }
 
 void create_stub_thread() 
 {
-	pthread_t threadId = 0;
+   pthread_t threadId = 0;
 
-	/* create shared queue */
-	shared_queue = createQueue();
+   /* create shared queue */
+   shared_queue = createQueue();
 
-	pthread_create(&threadId, NULL, stub_thread, NULL);      
+   pthread_create(&threadId, NULL, stub_thread, NULL);      
 
 }
 
 /* A utility function to create an empty queue */
 bal_queue *createQueue()
 {
-	shared_queue = (struct Queue*)malloc(sizeof(struct Queue));
-	shared_queue->front = shared_queue->rear = NULL;
-	return shared_queue;
+   shared_queue = (struct Queue*)malloc(sizeof(struct Queue));
+   shared_queue->front = shared_queue->rear = NULL;
+   return shared_queue;
 }
 
 /* A utility function to create a new linked list node */
 struct QNode* newNode(int objKey, int status, char *device_id)
 {
-	struct QNode *temp = (struct QNode*)malloc(sizeof(struct QNode));
-	temp->obj_type = objKey;
-	temp->status = status;
-	if(device_id != NULL)
-	{
-		memset(temp->device_id, 0, BAL_DEVICE_STR_LEN);
-		memcpy(temp->device_id, device_id, strlen(device_id));
-	}
-	temp->next = NULL;
-	return temp; 
+   struct QNode *temp = (struct QNode*)malloc(sizeof(struct QNode));
+   temp->obj_type = objKey;
+   temp->status = status;
+   if(device_id != NULL)
+   {
+      memset(temp->device_id, 0, BAL_DEVICE_STR_LEN);
+      memcpy(temp->device_id, device_id, strlen(device_id));
+   }
+   temp->next = NULL;
+   return temp; 
 }
 
 /* The function to add data to shared_queue - Add end of the queue */
 void enQueue(int objKey, struct QNode *temp)
 {
-	/* Create a new LL node */
+   /* Create a new LL node */
 
-	/* If queue is empty, then new node is front and rear both */
-	if (shared_queue->rear == NULL)
-	{
-		shared_queue->front = shared_queue->rear = temp;
-		return;
-	}
+   /* If queue is empty, then new node is front and rear both */
+   if (shared_queue->rear == NULL)
+   {
+      shared_queue->front = shared_queue->rear = temp;
+      return;
+   }
 
-	/* Add the new node at the end of queue and change rear */
-	shared_queue->rear->next = temp;
-	shared_queue->rear = temp;
+   /* Add the new node at the end of queue and change rear */
+   shared_queue->rear->next = temp;
+   shared_queue->rear = temp;
 }
 
 /* Function to remove data from shared_queue - FIFO */
 struct QNode *deQueue()
 {
-	/* If queue is empty, return NULL */
-	if (shared_queue->front == NULL)
-	{
-		return NULL;
-	}
+   /* If queue is empty, return NULL */
+   if (shared_queue->front == NULL)
+   {
+      return NULL;
+   }
 
-	/* Store previous front and move front one node ahead */
-	struct QNode *temp = shared_queue->front;
-	shared_queue->front = shared_queue->front->next;
+   /* Store previous front and move front one node ahead */
+   struct QNode *temp = shared_queue->front;
+   shared_queue->front = shared_queue->front->next;
 
-	/* If front becomes NULL, then change rear also as NULL */
-	if (shared_queue->front == NULL)
-	{
-		shared_queue->rear = NULL;
-	}
+   /* If front becomes NULL, then change rear also as NULL */
+   if (shared_queue->front == NULL)
+   {
+      shared_queue->rear = NULL;
+   }
 
-	return temp;
+   return temp;
+}
+
+void stub_bal_init(BalInit *bal_init)
+{
+    client = grpc_c_client_init(bal_init->voltha_adapter_ip_port, "bal_client", NULL);
 }
 
 #endif
diff --git a/device_simulator/bal_stub.h b/device_simulator/bal_stub.h
index dda776a..61012b1 100644
--- a/device_simulator/bal_stub.h
+++ b/device_simulator/bal_stub.h
@@ -14,6 +14,15 @@
 ** limitations under the License.
 */
 
+#include "bal_msg_type.grpc-c.h"
+#include "bal_osmsg.grpc-c.h"
+#include "bal_model_ids.grpc-c.h"
+#include "bal_obj.grpc-c.h"
+#include "bal_model_types.grpc-c.h"
+#include "bal_errno.grpc-c.h"
+#include "bal_indications.grpc-c.h"
+#include "bal.grpc-c.h"
+
 /* Global definations */
 pthread_cond_t cv;
 pthread_mutex_t lock;
@@ -24,6 +33,14 @@
 #define BALSERVER        "bal_server"
 #define BAL_DEVICE_STR_LEN 20
 
+typedef struct BalCoreIpInfo
+{
+   char bal_core_arg1[4];
+   char bal_core_ip_port[24];
+   char bal_core_arg2[4];
+   char bal_shared_lib_ip_port[24];
+}balCoreIpInfo;
+
 /* A linked list (LL) node to store a queue entry */
 struct QNode
 {
@@ -32,6 +49,8 @@
 	int status;
 	int intf_id;
 	int onu_id;
+	char vendor_id[BAL_DEVICE_STR_LEN];
+	char vendor_specific[BAL_DEVICE_STR_LEN];
 	struct QNode *next;
 };
 
@@ -51,3 +70,5 @@
 struct QNode* newNode(int objKey, int status, char *device_id);
 void enQueue(int objKey, struct QNode *temp);
 struct QNode *deQueue();
+grpc_c_client_t *client;
+void stub_bal_init(BalInit *bal_init);
diff --git a/device_simulator/voltha_bal_driver.c b/device_simulator/voltha_bal_driver.c
new file mode 100755
index 0000000..92c3dd5
--- /dev/null
+++ b/device_simulator/voltha_bal_driver.c
@@ -0,0 +1,505 @@
+/*
+** Copyright 2017-present Open Networking Foundation
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+
+#include <signal.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include "bal_msg_type.grpc-c.h"
+#include "bal_osmsg.grpc-c.h"
+#include "bal_model_ids.grpc-c.h"
+#include "bal_obj.grpc-c.h"
+#include "bal_model_types.grpc-c.h"
+#include "bal_errno.grpc-c.h"
+#include "bal.grpc-c.h"
+
+#ifdef BAL_STUB
+#include "bal_stub.h"
+#else
+#include "asfvolt16_driver.h"
+#endif
+
+/* Global varibles */
+balCoreIpInfo coreIpPortInfo;
+
+static grpc_c_server_t *test_server;
+
+static void sigint_handler (int x) { 
+   grpc_c_server_destroy(test_server);
+   exit(0);
+}
+
+/*
+ * This functions gets invoked whenever bal RPC gets called
+ */
+void bal__bal_cfg_get_cb(grpc_c_context_t *context)
+{
+   BalCfg *get_cfg;
+
+   /*
+    * Read incoming message into get_cfg
+    */
+   if (context->gcc_payload) {
+      context->gcc_stream->read(context, (void **)&get_cfg, 0);
+   }
+
+#ifndef BAL_STUB
+   //asfvolt16_bal_cfg_get(key, get_cfg);
+#endif
+}
+
+/*
+ * This functions gets invoked whenever bal RPC gets called
+ */
+void bal__bal_cfg_set_cb(grpc_c_context_t *context)
+{
+   BalCfg *set_cfg;
+   BalErr bal_err;
+   int ret_val = 0;
+
+   /*
+    * Read incoming message into set_cfg
+    */
+   if (context->gcc_payload) {
+      context->gcc_stream->read(context, (void **)&set_cfg, 0);
+   }
+
+   /*
+    * send it to BAL
+    */
+
+   bal_err__init(&bal_err);
+
+   bal_err.err= 0;
+
+   /*
+    * Write reply back to the client
+    */
+ 
+   ret_val = context->gcc_stream->write(context, &bal_err, 0);
+   if (ret_val != GRPC_C_WRITE_OK) {
+      if(ret_val == GRPC_C_WRITE_PENDING) {
+         printf("write is pending, sleep for 10 sec\n", ret_val);
+         sleep(10);
+      }
+      else {
+         printf("Failed to write\n", ret_val);
+         exit(1);
+      }
+   }
+
+   grpc_c_status_t status;
+   status.gcs_code = 0;
+
+   /*
+    * Finish response for RPC
+    */
+   if (context->gcc_stream->finish(context, &status)) {
+      printf("Failed to write status\n");
+      exit(1);
+   }
+
+#ifdef BAL_STUB
+   pthread_mutex_lock(&lock);
+
+   struct QNode *temp = newNode(set_cfg->hdr->obj_type, 
+         BAL_ERRNO__BAL_ERR_OK, 
+         set_cfg->device_id);
+
+/*   if(set_cfg->hdr->has_obj_type)
+   { */
+
+      switch(set_cfg->hdr->obj_type)
+      {
+         case BAL_OBJ_ID__BAL_OBJ_ID_ACCESS_TERMINAL:
+            {
+               printf("\n***************************************************\n");  
+               printf("Received Access Terminal Configuration msg\n");
+               printf("***************************************************\n");  
+            }
+            break;
+         case BAL_OBJ_ID__BAL_OBJ_ID_INTERFACE:
+            {
+               printf("\n***************************************************\n");  
+               printf("Received PON Interface Configuration msg\n");
+               printf("***************************************************\n");  
+               temp->intf_id = set_cfg->interface->key->intf_id;
+               printf("Pon ID = %d\n", temp->intf_id);
+            }
+            break;
+         case BAL_OBJ_ID__BAL_OBJ_ID_SUBSCRIBER_TERMINAL:
+            {
+          printf("\n*****************************************************\n");  
+          printf("Received ONU Activation msg\n");
+          printf("*****************************************************\n");  
+          temp->intf_id = set_cfg->terminal->key->intf_id;
+          temp->onu_id = set_cfg->terminal->key->sub_term_id;
+          memset(temp->vendor_id, 0, BAL_DEVICE_STR_LEN);
+          memcpy(temp->vendor_id, 
+                set_cfg->terminal->data->serial_number->vendor_id, 
+                strlen(set_cfg->terminal->data->serial_number->vendor_id));
+          memset(temp->vendor_specific, 0, BAL_DEVICE_STR_LEN);
+          memcpy(temp->vendor_specific, 
+                set_cfg->terminal->data->serial_number->vendor_specific, 
+                strlen(set_cfg->terminal->data->serial_number->vendor_specific));
+
+            }
+            break;
+    case BAL_OBJ_ID__BAL_OBJ_ID_PACKET:
+       {
+          switch(set_cfg->packet->key->packet_send_dest->type)
+          {
+             case BAL_DEST_TYPE__BAL_DEST_TYPE_ITU_OMCI_CHANNEL:
+                {
+                   printf("\n*****************************************************\n");  
+                   printf("Received OMCI msg\n");
+                   printf("*****************************************************\n");  
+                   temp->intf_id = set_cfg->terminal->key->intf_id;
+                   temp->onu_id = set_cfg->terminal->key->sub_term_id;
+                }
+                break;
+             default:
+                {
+                   ("\n*****************************************************\n");  
+                   printf("Dest type invalid\n");
+                   printf("*****************************************************\n");  
+                }
+                break;
+          }
+       }
+       break;
+    default:
+       {
+          ("\n*****************************************************\n");  
+          printf("Received Invalid msg\n");
+          printf("*****************************************************\n");  
+                    pthread_mutex_unlock(&lock);
+                    return;
+       }
+       break;
+      }
+      enQueue(set_cfg->hdr->obj_type, temp);
+/*
+   }
+   else
+   {
+      printf("BALSTUB:Cfg Set recevied without object type");
+   } */
+   pthread_mutex_unlock(&lock);
+   sleep(2);   
+   pthread_cond_signal(&cv);
+/*
+   if(BAL_OBJ_ID__BAL_OBJ_ID_INTERFACE == set_cfg->hdr->obj_type)
+   {
+      sleep(5); 
+      struct QNode *temp1 = newNode(BAL_OBJ_ID__BAL_OBJ_ID_SUBSCRIBER_TERMINAL, 
+            BAL_ERRNO__BAL_ERR_OK, 
+            set_cfg->device_id);
+      temp1->intf_id = set_cfg->interface->key->intf_id;
+      temp1->onu_id = 65535;
+      printf("sending _onu_discovery_indiaction\n");
+      enQueue(BAL_OBJ_ID__BAL_OBJ_ID_SUBSCRIBER_TERMINAL, temp1); 
+      pthread_cond_signal(&cv);
+   }
+*/
+#else
+   if(BAL_OBJ_ID__BAL_OBJ_ID_ACCESS_TERMINAL == set_cfg->hdr->obj_type)
+   {
+      sleep(5);//enable this if running with gdb
+   }
+   asfvolt16_bal_cfg_set(set_cfg);
+#endif
+}
+
+
+/*
+ * This functions gets invoked whenever bal clear RPC gets called
+ */
+void bal__bal_cfg_clear_cb(grpc_c_context_t *context)
+{
+   BalKey *clear_key;
+
+   /*
+    * Read incoming message into clear_key 
+    */
+   if (context->gcc_payload) {
+      context->gcc_stream->read(context, (void **)&clear_key, 0);
+   }
+
+#ifndef BAL_STUB
+   asfvolt16_bal_cfg_clear(clear_key);
+#endif
+}
+
+
+/*
+ * This functions gets invoked whenever bal Init RPC gets called
+ */
+void bal__bal_api_init_cb(grpc_c_context_t *context)
+{
+   BalInit *bal_init;
+   BalErr bal_err;
+   int ret_val;
+
+   /*
+    * Read incoming message into set_cfg
+    */
+   if (context->gcc_payload) {
+      context->gcc_stream->read(context, (void **)&bal_init, 0);
+   }
+
+   /*
+    * send it to BAL
+    */
+
+
+   ("\n*****************************************************\n");  
+   printf("Received API Init msg\n");
+   printf("*****************************************************\n");  
+
+   bal_err__init(&bal_err);
+
+   bal_err.err= 0;
+
+   /*
+    * Write reply back to the client
+    */
+   ret_val = context->gcc_stream->write(context, &bal_err, 0);
+   if (ret_val != GRPC_C_WRITE_OK) {
+      if(ret_val == GRPC_C_WRITE_PENDING) {
+         printf("write is pending, sleep for 10 sec\n", ret_val);
+         sleep(10);
+      }
+      else {
+         printf("Failed to write\n", ret_val);
+         exit(1);
+      }
+   }
+
+   grpc_c_status_t status;
+   status.gcs_code = 0;
+
+   /*
+    * Finish response for RPC
+    */
+   if (context->gcc_stream->finish(context, &status)) {
+      printf("Failed to write status\n");
+      exit(1);
+   }
+
+#ifndef BAL_STUB
+   asfvolt16_bal_init(bal_init, &coreIpPortInfo);
+#else
+   printf("\nRecevied IP Address == %s \n", bal_init->voltha_adapter_ip_port);
+   stub_bal_init(bal_init);
+#endif
+
+}
+
+
+/*
+ * This functions gets invoked whenever bal finish RPC gets called
+ */
+void bal__bal_api_finish_cb(grpc_c_context_t *context)
+{
+#if 0
+   void *finish_init;
+
+   /*
+    * Read incoming message into set_cfg
+    */
+   if (context->gcc_payload) {
+      context->gcc_stream->read(context, (void **)&finish_init);
+   }
+#endif
+}
+
+#if 0
+/*
+ * This functions gets invoked whenever bal finish RPC gets called
+ */
+void bal_ind__bal_ind_info_cb(grpc_c_context_t *context)
+{
+#if 0
+   void *finish_init;
+
+   /*
+    * Read incoming message into set_cfg
+    */
+   if (context->gcc_payload) {
+      context->gcc_stream->read(context, (void **)&finish_init);
+   }
+#endif
+}
+#endif
+
+void bal_ind__bal_acc_term_ind_cb(grpc_c_context_t *context)
+{
+}
+void bal_ind__bal_acc_term_oper_sts_cng_ind_cb(grpc_c_context_t *context)
+{
+}
+void bal_ind__bal_flow_oper_sts_cng_cb(grpc_c_context_t *context)
+{
+}
+void bal_ind__bal_flow_ind_cb(grpc_c_context_t *context)
+{
+}
+void bal_ind__bal_group_ind_cb(grpc_c_context_t *context)
+{
+}
+void bal_ind__bal_iface_oper_sts_cng_cb(grpc_c_context_t *context)
+{
+}
+void bal_ind__bal_iface_los_cb(grpc_c_context_t *context)
+{
+}
+void bal_ind__bal_iface_ind_cb(grpc_c_context_t *context)
+{
+}
+void bal_ind__bal_iface_stat_cb(grpc_c_context_t *context)
+{
+}
+void bal_ind__bal_subs_term_oper_sts_cng_cb(grpc_c_context_t *context)
+{
+}
+void bal_ind__bal_subs_term_discovery_ind_cb(grpc_c_context_t *context)
+{
+}
+void bal_ind__bal_subs_term_alarm_ind_cb(grpc_c_context_t *context)
+{
+}
+void bal_ind__bal_subs_term_dgi_ind_cb(grpc_c_context_t *context)
+{
+}
+void bal_ind__bal_subs_term_ind_cb(grpc_c_context_t *context)
+{
+}
+void bal_ind__bal_tm_queue_ind_info_cb(grpc_c_context_t *context)
+{
+}
+void bal_ind__bal_tm_sched_ind_info_cb(grpc_c_context_t *context)
+{
+}
+void bal_ind__bal_pkt_bearer_channel_rx_ind_cb(grpc_c_context_t *context)
+{
+}
+void bal_ind__bal_pkt_omci_channel_rx_ind_cb(grpc_c_context_t *context)
+{
+}
+void bal_ind__bal_pkt_ieee_oam_channel_rx_ind_cb(grpc_c_context_t *context)
+{
+}
+void bal__bal_api_heartbeat_cb(grpc_c_context_t *context)
+{
+   BalHeartbeat *bal_hb;
+   BalErr bal_err;
+
+   /*
+    * Read incoming message into set_cfg
+    */
+   printf("\nRecevied HeartBeat from Adapter\n");
+   if (context->gcc_payload) {
+	context->gcc_stream->read(context, (void **)&bal_hb, 0);
+   }
+
+   printf("Received Heart Beat msg\n");
+
+   bal_err__init(&bal_err);
+
+   bal_err.err= 0;
+
+   /*
+    * Write reply back to the client
+    */
+    if (!context->gcc_stream->write(context, &bal_err, 0)) {
+    } else {
+              printf("Failed to write\n");
+	      exit(1);
+    }
+
+    grpc_c_status_t status;
+    status.gcs_code = 0;
+
+    /*
+     * Finish response for RPC
+     */
+    if (context->gcc_stream->finish(context, &status)) {
+	printf("Failed to write status\n");
+	exit(1);
+    }
+   printf("\nSent HeartBeat Response to Adapter\n");
+}
+
+/*
+ * Takes socket path as argument
+ */
+int main (int argc, char **argv) 
+{
+   int i = 0;
+   grpc_c_server_t *server = NULL;
+
+   if (argc < 6) {
+      fprintf(stderr, "Missing socket path argument\n");
+      exit(1);
+   }
+
+   strcpy(coreIpPortInfo.bal_core_arg1, argv[2] /*, strlen(argv[2])*/);
+   strcpy(coreIpPortInfo.bal_core_ip_port, argv[3]/*, strlen(argv[3])*/);
+   strcpy(coreIpPortInfo.bal_core_arg2, argv[4]/*, strlen(argv[4])*/);
+   strcpy(coreIpPortInfo.bal_shared_lib_ip_port, argv[5]/*, strlen(argv[5])*/);
+
+   signal(SIGINT, sigint_handler);
+   /*
+    * Initialize grpc-c library to be used with vanilla gRPC
+    */
+   grpc_c_init(GRPC_THREADS, NULL);
+
+   /*
+    * Create server object
+    */
+   test_server = grpc_c_server_create(argv[1]);
+
+   if (test_server == NULL) {
+      printf("Failed to create server\n");
+      exit(1);
+   }
+
+   /*
+    * Initialize greeter service
+    */
+   printf("\nbal_voltha_app running.....\n");
+   bal__service_init(test_server);
+
+   /*
+    * Start server
+    */
+   grpc_c_server_start(test_server);
+
+#ifdef BAL_STUB
+   printf("\nCreating a stub thread\n");
+   create_stub_thread();
+#endif
+
+   /*
+    * Blocks server to wait to completion
+    */
+   grpc_c_server_wait(test_server);
+
+   /* code added for example Makefile to compile grpc-c along with edgecore driver */
+   bal__service_init(server);
+
+}