integrate tcp server and the runner/agent

runner can send the callback server info to the agent

Change-Id: I3f6216c1323097c0665da018f0301915ac39ca6c
diff --git a/agents/hal/RequestHandler.cpp b/agents/hal/RequestHandler.cpp
index fadc181..84851c0 100644
--- a/agents/hal/RequestHandler.cpp
+++ b/agents/hal/RequestHandler.cpp
@@ -78,6 +78,17 @@
 }
 
 
+AndroidSystemControlResponseMessage* AgentRequestHandler::SetHostInfo(
+    const int callback_port) {
+  cout << "[runner->agent] command " << __FUNCTION__ << endl;
+  callback_port_ = callback_port;
+  AndroidSystemControlResponseMessage* response_msg =
+      new AndroidSystemControlResponseMessage();
+  response_msg->set_response_code(SUCCESS);
+  return response_msg;
+}
+
+
 AndroidSystemControlResponseMessage* AgentRequestHandler::CheckStubService(
     const string& service_name) {
   cout << "[runner->agent] command " << __FUNCTION__ << endl;
@@ -216,7 +227,6 @@
   if (!client.get()) return NULL;
 
   const char* result = client->Call(call_payload);
-  //if (result) cout << "Call: " << result << endl;
 
   AndroidSystemControlResponseMessage* response_msg =
       new AndroidSystemControlResponseMessage();
@@ -284,22 +294,19 @@
       buffer[len] = '\0';
 
       AndroidSystemControlCommandMessage command_msg;
-      //for (int i = 0; i < len; i++) {
-      //  cout << int(buffer[i]) << " ";
-      //}
-      //cout << endl;
       if (!command_msg.ParseFromString(string(buffer))) {
         cerr << "can't parse the cmd" << endl;
         return -1;
       }
-      //cout << "[runner->agent] command type " << command_msg.command_type()
-      //    << endl;
 
       AndroidSystemControlResponseMessage* response_msg = NULL;
       switch (command_msg.command_type()) {
         case LIST_HALS:
           response_msg = ListHals(command_msg.paths());
           break;
+        case SET_HOST_INFO:
+          response_msg = SetHostInfo(command_msg.callback_port());
+          break;
         case CHECK_STUB_SERVICE:
           response_msg = CheckStubService(command_msg.service_name());
           break;
diff --git a/agents/hal/RequestHandler.h b/agents/hal/RequestHandler.h
index 8a9f174..acee747 100644
--- a/agents/hal/RequestHandler.h
+++ b/agents/hal/RequestHandler.h
@@ -45,6 +45,9 @@
   AndroidSystemControlResponseMessage* ListHals(
       const ::google::protobuf::RepeatedPtrField< ::std::string>& base_paths);
 
+  // for the SET_HOST_INFO command.
+  AndroidSystemControlResponseMessage* SetHostInfo(const int callback_port);
+
   // for the CHECK_STUB_SERVICE command
   AndroidSystemControlResponseMessage* CheckStubService(
       const string& service_name);
@@ -68,6 +71,8 @@
  protected:
   // the currently opened, connected service name.
   string service_name_;
+  // the port number of a host-side callback server.
+  int callback_port_;
 };
 
 }  // namespace vts
diff --git a/images/angler/32/libvts_common.so b/images/angler/32/libvts_common.so
index ea10630..ff78ec0 100755
--- a/images/angler/32/libvts_common.so
+++ b/images/angler/32/libvts_common.so
Binary files differ
diff --git a/images/angler/32/libvts_multidevice_proto.so b/images/angler/32/libvts_multidevice_proto.so
index cfbfee3..a9f057c 100755
--- a/images/angler/32/libvts_multidevice_proto.so
+++ b/images/angler/32/libvts_multidevice_proto.so
Binary files differ
diff --git a/images/angler/64/libvts_common.so b/images/angler/64/libvts_common.so
index 7dd1d4e..4a0623e 100755
--- a/images/angler/64/libvts_common.so
+++ b/images/angler/64/libvts_common.so
Binary files differ
diff --git a/images/angler/64/libvts_multidevice_proto.so b/images/angler/64/libvts_multidevice_proto.so
index c064dd4..be75a34 100755
--- a/images/angler/64/libvts_multidevice_proto.so
+++ b/images/angler/64/libvts_multidevice_proto.so
Binary files differ
diff --git a/images/angler/64/vts_hal_agent b/images/angler/64/vts_hal_agent
index 7a8421d..30799a0 100755
--- a/images/angler/64/vts_hal_agent
+++ b/images/angler/64/vts_hal_agent
Binary files differ
diff --git a/images/bullhead/32/libvts_common.so b/images/bullhead/32/libvts_common.so
index 6aa1ee6..9643ee8 100755
--- a/images/bullhead/32/libvts_common.so
+++ b/images/bullhead/32/libvts_common.so
Binary files differ
diff --git a/images/bullhead/32/libvts_multidevice_proto.so b/images/bullhead/32/libvts_multidevice_proto.so
index eb300ab..8de2556 100755
--- a/images/bullhead/32/libvts_multidevice_proto.so
+++ b/images/bullhead/32/libvts_multidevice_proto.so
Binary files differ
diff --git a/images/bullhead/64/libvts_common.so b/images/bullhead/64/libvts_common.so
index fd13c8c..ddf4e7b 100755
--- a/images/bullhead/64/libvts_common.so
+++ b/images/bullhead/64/libvts_common.so
Binary files differ
diff --git a/images/bullhead/64/libvts_multidevice_proto.so b/images/bullhead/64/libvts_multidevice_proto.so
index 5d0c371..89d1547 100755
--- a/images/bullhead/64/libvts_multidevice_proto.so
+++ b/images/bullhead/64/libvts_multidevice_proto.so
Binary files differ
diff --git a/images/bullhead/64/vts_hal_agent b/images/bullhead/64/vts_hal_agent
index 6479ff5..c2902b6 100755
--- a/images/bullhead/64/vts_hal_agent
+++ b/images/bullhead/64/vts_hal_agent
Binary files differ
diff --git a/runners/host/proto/AndroidSystemControlMessage.proto b/runners/host/proto/AndroidSystemControlMessage.proto
index c87738b..100d4db 100644
--- a/runners/host/proto/AndroidSystemControlMessage.proto
+++ b/runners/host/proto/AndroidSystemControlMessage.proto
@@ -22,6 +22,8 @@
   UNKNOWN_COMMAND_TYPE = 0;
   // To get a list of available HAL modules.
   LIST_HALS = 1;
+  // To set the host information (e.g., callback server port).
+  SET_HOST_INFO = 2;
 
   // To check whether fuzzer's binder service is available.
   CHECK_STUB_SERVICE = 101;
@@ -53,6 +55,9 @@
   // for LIST_HALS
   repeated bytes paths = 1001;
 
+  // for SET_HOST_INFO
+  optional int32 callback_port = 1101;
+
   // for CHECK_STUB_SERVICE
   // the binder service name
   optional bytes service_name = 2001;
@@ -90,13 +95,13 @@
   // The reason.
   optional bytes reason = 1001;
 
-  // for the found componet files.
+  // for the found component files.
   repeated bytes file_names = 1002;
 
-  // for the found api spec.
+  // for the found API specification.
   optional bytes spec = 1003;
 
-  // for the api call result including result value, profiling data, and
+  // for the API call result including result value, profiling data, and
   // coverage measurement data.
   optional bytes result = 1004;
 }
\ No newline at end of file
diff --git a/runners/host/proto/AndroidSystemControlMessage_pb2.py b/runners/host/proto/AndroidSystemControlMessage_pb2.py
index 2ad454f..e32b18f 100644
--- a/runners/host/proto/AndroidSystemControlMessage_pb2.py
+++ b/runners/host/proto/AndroidSystemControlMessage_pb2.py
@@ -14,7 +14,7 @@
 DESCRIPTOR = _descriptor.FileDescriptor(
   name='AndroidSystemControlMessage.proto',
   package='android.vts',
-  serialized_pb='\n!AndroidSystemControlMessage.proto\x12\x0b\x61ndroid.vts\"\x88\x02\n\"AndroidSystemControlCommandMessage\x12.\n\x0c\x63ommand_type\x18\x01 \x01(\x0e\x32\x18.android.vts.CommandType\x12\x0e\n\x05paths\x18\xe9\x07 \x03(\x0c\x12\x15\n\x0cservice_name\x18\xd1\x0f \x01(\x0c\x12\x12\n\tfile_path\x18\xb9\x17 \x01(\x0c\x12\r\n\x04\x62its\x18\xbb\x17 \x01(\x05\x12\x15\n\x0ctarget_class\x18\xbc\x17 \x01(\x05\x12\x14\n\x0btarget_type\x18\xbd\x17 \x01(\x05\x12\x17\n\x0etarget_version\x18\xbe\x17 \x01(\x05\x12\x14\n\x0bmodule_name\x18\xbf\x17 \x01(\x0c\x12\x0c\n\x03\x61rg\x18\xa1\x1f \x01(\x0c\"\x9d\x01\n#AndroidSystemControlResponseMessage\x12\x30\n\rresponse_code\x18\x01 \x01(\x0e\x32\x19.android.vts.ResponseCode\x12\x0f\n\x06reason\x18\xe9\x07 \x01(\x0c\x12\x13\n\nfile_names\x18\xea\x07 \x03(\x0c\x12\r\n\x04spec\x18\xeb\x07 \x01(\x0c\x12\x0f\n\x06result\x18\xec\x07 \x01(\x0c*\x86\x01\n\x0b\x43ommandType\x12\x18\n\x14UNKNOWN_COMMAND_TYPE\x10\x00\x12\r\n\tLIST_HALS\x10\x01\x12\x16\n\x12\x43HECK_STUB_SERVICE\x10\x65\x12\x17\n\x13LAUNCH_STUB_SERVICE\x10\x66\x12\x0e\n\tLIST_APIS\x10\xc9\x01\x12\r\n\x08\x43\x41LL_API\x10\xca\x01*@\n\x0cResponseCode\x12\x19\n\x15UNKNOWN_RESPONSE_CODE\x10\x00\x12\x0b\n\x07SUCCESS\x10\x01\x12\x08\n\x04\x46\x41IL\x10\x02')
+  serialized_pb='\n!AndroidSystemControlMessage.proto\x12\x0b\x61ndroid.vts\"\xa0\x02\n\"AndroidSystemControlCommandMessage\x12.\n\x0c\x63ommand_type\x18\x01 \x01(\x0e\x32\x18.android.vts.CommandType\x12\x0e\n\x05paths\x18\xe9\x07 \x03(\x0c\x12\x16\n\rcallback_port\x18\xcd\x08 \x01(\x05\x12\x15\n\x0cservice_name\x18\xd1\x0f \x01(\x0c\x12\x12\n\tfile_path\x18\xb9\x17 \x01(\x0c\x12\r\n\x04\x62its\x18\xbb\x17 \x01(\x05\x12\x15\n\x0ctarget_class\x18\xbc\x17 \x01(\x05\x12\x14\n\x0btarget_type\x18\xbd\x17 \x01(\x05\x12\x17\n\x0etarget_version\x18\xbe\x17 \x01(\x05\x12\x14\n\x0bmodule_name\x18\xbf\x17 \x01(\x0c\x12\x0c\n\x03\x61rg\x18\xa1\x1f \x01(\x0c\"\x9d\x01\n#AndroidSystemControlResponseMessage\x12\x30\n\rresponse_code\x18\x01 \x01(\x0e\x32\x19.android.vts.ResponseCode\x12\x0f\n\x06reason\x18\xe9\x07 \x01(\x0c\x12\x13\n\nfile_names\x18\xea\x07 \x03(\x0c\x12\r\n\x04spec\x18\xeb\x07 \x01(\x0c\x12\x0f\n\x06result\x18\xec\x07 \x01(\x0c*\x99\x01\n\x0b\x43ommandType\x12\x18\n\x14UNKNOWN_COMMAND_TYPE\x10\x00\x12\r\n\tLIST_HALS\x10\x01\x12\x11\n\rSET_HOST_INFO\x10\x02\x12\x16\n\x12\x43HECK_STUB_SERVICE\x10\x65\x12\x17\n\x13LAUNCH_STUB_SERVICE\x10\x66\x12\x0e\n\tLIST_APIS\x10\xc9\x01\x12\r\n\x08\x43\x41LL_API\x10\xca\x01*@\n\x0cResponseCode\x12\x19\n\x15UNKNOWN_RESPONSE_CODE\x10\x00\x12\x0b\n\x07SUCCESS\x10\x01\x12\x08\n\x04\x46\x41IL\x10\x02')
 
 _COMMANDTYPE = _descriptor.EnumDescriptor(
   name='CommandType',
@@ -31,26 +31,30 @@
       options=None,
       type=None),
     _descriptor.EnumValueDescriptor(
-      name='CHECK_STUB_SERVICE', index=2, number=101,
+      name='SET_HOST_INFO', index=2, number=2,
       options=None,
       type=None),
     _descriptor.EnumValueDescriptor(
-      name='LAUNCH_STUB_SERVICE', index=3, number=102,
+      name='CHECK_STUB_SERVICE', index=3, number=101,
       options=None,
       type=None),
     _descriptor.EnumValueDescriptor(
-      name='LIST_APIS', index=4, number=201,
+      name='LAUNCH_STUB_SERVICE', index=4, number=102,
       options=None,
       type=None),
     _descriptor.EnumValueDescriptor(
-      name='CALL_API', index=5, number=202,
+      name='LIST_APIS', index=5, number=201,
+      options=None,
+      type=None),
+    _descriptor.EnumValueDescriptor(
+      name='CALL_API', index=6, number=202,
       options=None,
       type=None),
   ],
   containing_type=None,
   options=None,
-  serialized_start=478,
-  serialized_end=612,
+  serialized_start=502,
+  serialized_end=655,
 )
 
 CommandType = enum_type_wrapper.EnumTypeWrapper(_COMMANDTYPE)
@@ -75,13 +79,14 @@
   ],
   containing_type=None,
   options=None,
-  serialized_start=614,
-  serialized_end=678,
+  serialized_start=657,
+  serialized_end=721,
 )
 
 ResponseCode = enum_type_wrapper.EnumTypeWrapper(_RESPONSECODE)
 UNKNOWN_COMMAND_TYPE = 0
 LIST_HALS = 1
+SET_HOST_INFO = 2
 CHECK_STUB_SERVICE = 101
 LAUNCH_STUB_SERVICE = 102
 LIST_APIS = 201
@@ -114,56 +119,63 @@
       is_extension=False, extension_scope=None,
       options=None),
     _descriptor.FieldDescriptor(
-      name='service_name', full_name='android.vts.AndroidSystemControlCommandMessage.service_name', index=2,
+      name='callback_port', full_name='android.vts.AndroidSystemControlCommandMessage.callback_port', index=2,
+      number=1101, type=5, cpp_type=1, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      options=None),
+    _descriptor.FieldDescriptor(
+      name='service_name', full_name='android.vts.AndroidSystemControlCommandMessage.service_name', index=3,
       number=2001, type=12, cpp_type=9, label=1,
       has_default_value=False, default_value="",
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       options=None),
     _descriptor.FieldDescriptor(
-      name='file_path', full_name='android.vts.AndroidSystemControlCommandMessage.file_path', index=3,
+      name='file_path', full_name='android.vts.AndroidSystemControlCommandMessage.file_path', index=4,
       number=3001, type=12, cpp_type=9, label=1,
       has_default_value=False, default_value="",
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       options=None),
     _descriptor.FieldDescriptor(
-      name='bits', full_name='android.vts.AndroidSystemControlCommandMessage.bits', index=4,
+      name='bits', full_name='android.vts.AndroidSystemControlCommandMessage.bits', index=5,
       number=3003, type=5, cpp_type=1, label=1,
       has_default_value=False, default_value=0,
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       options=None),
     _descriptor.FieldDescriptor(
-      name='target_class', full_name='android.vts.AndroidSystemControlCommandMessage.target_class', index=5,
+      name='target_class', full_name='android.vts.AndroidSystemControlCommandMessage.target_class', index=6,
       number=3004, type=5, cpp_type=1, label=1,
       has_default_value=False, default_value=0,
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       options=None),
     _descriptor.FieldDescriptor(
-      name='target_type', full_name='android.vts.AndroidSystemControlCommandMessage.target_type', index=6,
+      name='target_type', full_name='android.vts.AndroidSystemControlCommandMessage.target_type', index=7,
       number=3005, type=5, cpp_type=1, label=1,
       has_default_value=False, default_value=0,
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       options=None),
     _descriptor.FieldDescriptor(
-      name='target_version', full_name='android.vts.AndroidSystemControlCommandMessage.target_version', index=7,
+      name='target_version', full_name='android.vts.AndroidSystemControlCommandMessage.target_version', index=8,
       number=3006, type=5, cpp_type=1, label=1,
       has_default_value=False, default_value=0,
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       options=None),
     _descriptor.FieldDescriptor(
-      name='module_name', full_name='android.vts.AndroidSystemControlCommandMessage.module_name', index=8,
+      name='module_name', full_name='android.vts.AndroidSystemControlCommandMessage.module_name', index=9,
       number=3007, type=12, cpp_type=9, label=1,
       has_default_value=False, default_value="",
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       options=None),
     _descriptor.FieldDescriptor(
-      name='arg', full_name='android.vts.AndroidSystemControlCommandMessage.arg', index=9,
+      name='arg', full_name='android.vts.AndroidSystemControlCommandMessage.arg', index=10,
       number=4001, type=12, cpp_type=9, label=1,
       has_default_value=False, default_value="",
       message_type=None, enum_type=None, containing_type=None,
@@ -179,7 +191,7 @@
   is_extendable=False,
   extension_ranges=[],
   serialized_start=51,
-  serialized_end=315,
+  serialized_end=339,
 )
 
 
@@ -234,8 +246,8 @@
   options=None,
   is_extendable=False,
   extension_ranges=[],
-  serialized_start=318,
-  serialized_end=475,
+  serialized_start=342,
+  serialized_end=499,
 )
 
 _ANDROIDSYSTEMCONTROLCOMMANDMESSAGE.fields_by_name['command_type'].enum_type = _COMMANDTYPE
diff --git a/runners/host/tcp_client/vts_tcp_client.py b/runners/host/tcp_client/vts_tcp_client.py
index 4a5ee9f..7d38439 100755
--- a/runners/host/tcp_client/vts_tcp_client.py
+++ b/runners/host/tcp_client/vts_tcp_client.py
@@ -29,6 +29,7 @@
 TARGET_PORT = os.environ.get("TARGET_PORT", 5001)
 _SOCKET_CONN_TIMEOUT_SECS = 60
 COMMAND_TYPE_NAME = {1: "LIST_HALS",
+                     2: "SET_HOST_INFO",
                      101: "CHECK_STUB_SERVICE",
                      102: "LAUNCH_STUB_SERVICE",
                      201: "LIST_APIS",
@@ -53,15 +54,22 @@
         self.channel = None
         self._mode = mode
 
-    def Connect(self, ip=TARGET_IP, port=TARGET_PORT):
+    def Connect(self, ip=TARGET_IP, port=TARGET_PORT,
+                callback_port=None):
         """Connects to a target device.
 
         Args:
-            ip: string, the IP adress of a target device.
-            port: integer, the TCP port.
+            ip: string, the IP address of a target device.
+            port: int, the TCP port which can be used to connect to
+                  a target device.
+            callback_port: int, the TCP port number of a host-side callback
+                           server.
+
+        Returns:
+            True if success, False otherwise
 
         Raises:
-            Exception when the connection fails.
+            socket.error when the connection fails.
         """
         try:
             # TODO: This assumption is incorrect. Need to fix.
@@ -81,6 +89,14 @@
             raise
         self.channel = self.connection.makefile(mode="brw")
 
+        if callback_port is not None:
+            self.SendCommand(SysMsg_pb2.SET_HOST_INFO,
+                             callback_port=callback_port)
+            resp = self.RecvResponse()
+            if (resp.response_code != SysMsg_pb2.SUCCESS):
+                return False
+        return True
+
     def Disconnect(self):
         """Disconnects from the target device.
 
@@ -159,13 +175,14 @@
                     target_version=None,
                     module_name=None,
                     service_name=None,
+                    callback_port=None,
                     arg=None):
         """Sends a command.
 
         Args:
             command_type: integer, the command type.
-            target_name: string, the target name.
-            paths: a list of strings.
+            each of the other args are to fill in a field in
+            AndroidSystemControlCommandMessage.
         """
         if not self.channel:
             raise VtsTcpError("channel is None, unable to send command.")
@@ -174,6 +191,8 @@
         command_msg.command_type = command_type
         logging.info("sending a command (type %s)",
                      COMMAND_TYPE_NAME[command_type])
+        if command_type == 202:
+            logging.info("target API: %s", arg)
 
         if target_class is not None:
             command_msg.target_class = target_class
@@ -199,6 +218,9 @@
         if bits is not None:
             command_msg.bits = bits
 
+        if callback_port is not None:
+            command_msg.callback_port = callback_port
+
         if arg is not None:
             command_msg.arg = arg
 
@@ -214,7 +236,7 @@
         try:
             header = self.channel.readline()
             len = int(header.strip("\n"))
-            logging.debug("resp %d bytes", len)
+            logging.info("resp %d bytes", len)
             data = self.channel.read(len)
             response_msg = SysMsg_pb2.AndroidSystemControlResponseMessage()
             response_msg.ParseFromString(data)
diff --git a/runners/host/tcp_server/Android.mk b/runners/host/tcp_server/Android.mk
index a858ed0..cfce96a 100644
--- a/runners/host/tcp_server/Android.mk
+++ b/runners/host/tcp_server/Android.mk
@@ -12,7 +12,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-the_py_script = tcp_server_test.py
+the_py_script = vts_tcp_server_test.py
 PRIVATE_PY_SCRIPT := $(the_py_script)
 
 default:
diff --git a/runners/host/tcp_server/__init__.py b/runners/host/tcp_server/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/runners/host/tcp_server/__init__.py
diff --git a/runners/host/tcp_server/tcp_server.py b/runners/host/tcp_server/vts_tcp_server.py
similarity index 94%
rename from runners/host/tcp_server/tcp_server.py
rename to runners/host/tcp_server/vts_tcp_server.py
index 673740a..2292f8e 100644
--- a/runners/host/tcp_server/tcp_server.py
+++ b/runners/host/tcp_server/vts_tcp_server.py
@@ -58,7 +58,7 @@
         self.request.sendall(response)  # send the response back to client
 
 
-class ThreadedTCPServer(object):
+class VtsTcpServer(object):
     """This class creates TCPServer in separate thread.
 
     Attributes:
@@ -90,7 +90,6 @@
             None or callback_func is None; else returns True after inserting
             the key-func_id and value-callback_func.
         """
-
         if func_id is None or func_id in _functions or callback_func is None:
             return False
         else:
@@ -108,7 +107,6 @@
             Returns false if func_id is not present in the dictionary -
                 _functions, else return True after removing it from dict.
         """
-
         if func_id is None or func_id not in _functions:
             return False
         else:
@@ -123,6 +121,9 @@
                   is zero, in which case a free port will be chosen
                   automatically.
 
+        Returns:
+            IP Address, port number
+
         Raises:
             TcpServerCreationError: Error occurred while starting server.
         """
@@ -134,21 +135,21 @@
 
             # Start a thread with the server -- that thread will then start one
             # more thread for each request
-            server_thread = threading.Thread(target = self._server.serve_forever)
+            server_thread = threading.Thread(target=self._server.serve_forever)
 
             # Exit the server thread when the main thread terminates
             server_thread.daemon = True
             server_thread.start()
-            logging.info('Server loop running in thread: %s', server_thread.name)
+            logging.info('TcpServer %s started (%s:%s)',
+                         server_thread.name, self._IP_address, self._port_used)
 
+            return self._IP_address, self._port_used
         except (RuntimeError, IOError, socket_error) as e:
             logging.exception(e)
             raise TcpServerCreationError('TcpServerCreationError occurred.')
 
     def Stop(self):
         """This function calls stop server to stop the server instance."""
-
-        # stop the server instance
         self._server.shutdown
         self._server.server_close()
 
diff --git a/runners/host/tcp_server/tcp_server_test.py b/runners/host/tcp_server/vts_tcp_server_test.py
similarity index 76%
rename from runners/host/tcp_server/tcp_server_test.py
rename to runners/host/tcp_server/vts_tcp_server_test.py
index fd80294..02b24d3 100644
--- a/runners/host/tcp_server/tcp_server_test.py
+++ b/runners/host/tcp_server/vts_tcp_server_test.py
@@ -15,7 +15,7 @@
 # limitations under the License.
 
 import socket
-from tcp_server import ThreadedTCPServer
+from vts_tcp_server import VtsTcpServer
 import unittest
 import logging
 import errno
@@ -35,24 +35,24 @@
     correct error when we try to connect to server from a wrong port.
 
     Attributes:
-        _thread_tcp_server: an instance of ThreadedTCPServer that is used to
+        _thread_tcp_server: an instance of VtsTcpServer that is used to
                             start and stop the TCP server.
     """
     _thread_tcp_server = None
 
     def setUp(self):
-        """This function initiates starting the server in ThreadedTCPServer."""
+        """This function initiates starting the server in VtsTcpServer."""
 
-        self._thread_tcp_server = ThreadedTCPServer()
+        self._thread_tcp_server = VtsTcpServer()
         self._thread_tcp_server.Start()  # To start the server
 
     def tearDown(self):
         """To initiate shutdown of the server.
 
-        This function calls the tcp_server.ThreadedTCPServer.Stop which
+        This function calls the tcp_server.VtsTcpServer.Stop which
         shutdowns the server.
         """
-        self._thread_tcp_server.Stop()  # calls tcp_server.ThreadedTCPServer.Stop
+        self._thread_tcp_server.Stop()  # calls tcp_server.VtsTcpServer.Stop
 
     def DoErrorCase(self):
         """Unit test for Error case.
@@ -87,47 +87,47 @@
             sock.close()
 
     def ConnectToServer(self, func_id):
-      """This function creates a connection to TCP server and sends/receives
-          message.
+        """This function creates a connection to TCP server and sends/receives
+            message.
 
-      Args:
-          func_id: This is the unique key corresponding to a function and also
-              the data that we send to the server.
+        Args:
+            func_id: This is the unique key corresponding to a function and also
+                the data that we send to the server.
 
-      Returns:
-          received: String corresponding to the message that's received from
-              the server.
+        Returns:
+            received: String corresponding to the message that's received from
+                the server.
 
-      Raises:
-          TcpServerConnectionError: Exception occurred while stopping server.
-      """
-      data = func_id
-      received = ""
+        Raises:
+            TcpServerConnectionError: Exception occurred while stopping server.
+        """
+        data = func_id
+        received = ""
 
-      # Create a socket (SOCK_STREAM means a TCP socket)
-      sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-      sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
-      host = self._thread_tcp_server.GetIPAddress()
-      port = self._thread_tcp_server.GetPortUsed()
-      logging.info('Sending Request to host: %s ,using port: %s ', host, port)
+        # Create a socket (SOCK_STREAM means a TCP socket)
+        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+        sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+        host = self._thread_tcp_server.GetIPAddress()
+        port = self._thread_tcp_server.GetPortUsed()
+        logging.info('Sending Request to host: %s ,using port: %s ', host, port)
 
-      try:
-          # Connect to server and send data
-          sock.connect((host, port))
-          sock.sendall(data + "\n")
+        try:
+            # Connect to server and send data
+            sock.connect((host, port))
+            sock.sendall(data + "\n")
 
-          # Receive data from the server and shut down
-          received = sock.recv(1024)
-          logging.info('Request sent')
-      except socket_error as e:
-          logging.error(e)
-          raise TcpServerConnectionError('Exception occurred.')
-      finally:
-          sock.close()
-      logging.info('Sent : %s', data)
-      logging.info('Received : %s', received)
+            # Receive data from the server and shut down
+            received = sock.recv(1024)
+            logging.info('Request sent')
+        except socket_error as e:
+            logging.error(e)
+            raise TcpServerConnectionError('Exception occurred.')
+        finally:
+            sock.close()
+        logging.info('Sent : %s', data)
+        logging.info('Received : %s', received)
 
-      return received
+        return received
 
     def test_DoErrorCase(self):
         """ Unit test for error cases."""
@@ -223,4 +223,3 @@
 if __name__ == '__main__':
     # Test the code
     unittest.main()
-
diff --git a/sysfuzzer/common/fuzz_tester/FuzzerBase.cpp b/sysfuzzer/common/fuzz_tester/FuzzerBase.cpp
index a8cbe30..39acabe 100644
--- a/sysfuzzer/common/fuzz_tester/FuzzerBase.cpp
+++ b/sysfuzzer/common/fuzz_tester/FuzzerBase.cpp
@@ -370,7 +370,7 @@
     }
     DIR* srcdir = opendir(product_path);
     if (!srcdir) {
-      cerr << "couln't open " << product_path << endl;
+      cerr << __func__ << " couln't open " << product_path << endl;
       return;
     }
 
@@ -405,7 +405,7 @@
     }
     srcdir = opendir(module_basepath);
     if (!srcdir) {
-      cerr << "couln't open " << module_basepath << endl;
+      cerr << __func__ << " couln't open " << module_basepath << endl;
       return;
     }
 
@@ -463,7 +463,7 @@
   }
   DIR* srcdir = opendir(gcov_output_basepath_);
   if (!srcdir) {
-    cerr << "couln't open " << gcov_output_basepath_ << endl;
+    cerr << __func__ << " couln't open " << gcov_output_basepath_ << endl;
     return NULL;
   }
 
diff --git a/sysfuzzer/common/specification_parser/SpecificationBuilder.cpp b/sysfuzzer/common/specification_parser/SpecificationBuilder.cpp
index 3ef916f..59c39f0 100644
--- a/sysfuzzer/common/specification_parser/SpecificationBuilder.cpp
+++ b/sysfuzzer/common/specification_parser/SpecificationBuilder.cpp
@@ -232,9 +232,10 @@
 
   void* result;
   func_fuzzer->FunctionCallBegin();
-  cout << __func__ << " Call Function " << func_msg->name() << endl;
+  cout << __func__ << " Call Function " << func_msg->name() << " parent_path("
+      << func_msg->parent_path() << ")" << endl;
   if (!func_fuzzer->Fuzz(func_msg, &result, agent_port_)) {
-    cout << __func__ << " function not found - todo handle more explicitly" << endl;
+    cerr << __func__ << " function not found - todo handle more explicitly" << endl;
     return *(new string("error"));
   }
   cout << __func__ << ": called" << endl;
diff --git a/testcases/host/sample/SampleCameraTest.py b/testcases/host/sample/SampleCameraTest.py
index 8fc7440..52eb3d7 100644
--- a/testcases/host/sample/SampleCameraTest.py
+++ b/testcases/host/sample/SampleCameraTest.py
@@ -32,11 +32,11 @@
                                          target_basepaths=["/data/local/tmp/32/hal"],
                                          bits=32)
 
-    def testCameraOpenFirst(self):
+    def TestCameraOpenFirst(self):
         """A simple testcase which just calls an open function."""
         self.dut.hal.camera.common.methods.open()  # note args are skipped
 
-    def testCameraInit(self):
+    def TestCameraInit(self):
         """A simple testcase which just calls an init function."""
         self.dut.hal.camera.init()  # expect an exception? (can be undefined)
 
@@ -56,6 +56,9 @@
         def torch_mode_status_change():
             logging.info("torch_mode_status_change")
 
+        my_callback = self.dut.hal.camera.camera_module_callbacks_t(
+            camera_device_status_change, torch_mode_status_change)
+        self.dut.hal.camera.set_callbacks(my_callback)
         self.dut.hal.camera.common.methods.open()  # note args are skipped
 
 
diff --git a/utils/python/mirror/hal_mirror.py b/utils/python/mirror/hal_mirror.py
index c01e2fa..d60cc66 100644
--- a/utils/python/mirror/hal_mirror.py
+++ b/utils/python/mirror/hal_mirror.py
@@ -22,6 +22,7 @@
 from vts.runners.host import errors
 from vts.runners.host.proto import InterfaceSpecificationMessage_pb2 as IfaceSpecMsg
 from vts.runners.host.tcp_client import vts_tcp_client
+from vts.runners.host.tcp_server import vts_tcp_server
 from vts.utils.python.mirror import mirror_object
 
 COMPONENT_CLASS_DICT = {"hal_conventional": 1,
@@ -45,16 +46,20 @@
     This class holds and manages the life cycle of multiple mirror objects that
     map to different HAL components.
 
-    One can use this class to create and des
+    One can use this class to create and destroy a HAL mirror object.
 
     Attributes:
-        hal_level_mirrors: dict, key is HAL handler name, value is HAL
-                           mirror object.
-        host_port: int, the port number on the host side to use.
+        _hal_level_mirrors: dict, key is HAL handler name, value is HAL
+                            mirror object.
+        _host_port: int, the port number on the host side to use.
+        _callback_server: the instance of a callback server.
+        _callback_port: int, the port number of a host-side callback server.
     """
     def __init__(self, host_port):
         self._hal_level_mirrors = {}
         self._host_port = host_port
+        self._callback_server = None
+        self._callback_port = 0
 
     def __del__(self):
         for hal_mirror_name in self._hal_level_mirrors:
@@ -147,7 +152,10 @@
         if bits not in [32, 64]:
             raise error.ComponentLoadingError("Invalid value for bits: %s" % bits)
         client = vts_tcp_client.VtsTcpClient()
-        client.Connect(port=self._host_port)
+        callback_server = vts_tcp_server.VtsTcpServer()
+        _, self._callback_port = callback_server.Start()
+        client.Connect(port=self._host_port,
+                       callback_port=self._callback_port)
         if not handler_name:
             handler_name = target_type
         service_name = "vts_binder_%s" % handler_name
@@ -200,7 +208,8 @@
         text_format.Merge(found_api_spec, if_spec_msg)
 
         # Instantiate a MirrorObject and return it.
-        hal_mirror = mirror_object.MirrorObject(client, if_spec_msg)
+        hal_mirror = mirror_object.MirrorObject(client, if_spec_msg,
+                                                callback_server)
         self._hal_level_mirrors[handler_name] = hal_mirror
 
     def __getattr__(self, name):
diff --git a/utils/python/mirror/mirror_object.py b/utils/python/mirror/mirror_object.py
index f4f26e0..df8b7d2 100644
--- a/utils/python/mirror/mirror_object.py
+++ b/utils/python/mirror/mirror_object.py
@@ -26,9 +26,12 @@
 # a dict containing the IDs of the registered function pointers.
 _function_pointer_id_dict = {}
 
+
 class MirrorObjectError(Exception):
+    """Raised when there is a general error in manipulating a mirror object."""
     pass
 
+
 class MirrorObject(object):
     """The class that mirrors objects on the native side.
 
@@ -39,12 +42,14 @@
         _client: the TCP client instance.
         _if_spec_msg: the interface specification message of a host object to
                       mirror.
+        _callback_server: the instance of a callback server.
         _parent_path: the name of a sub struct this object mirrors.
     """
 
-    def __init__(self, client, msg, parent_path=None):
+    def __init__(self, client, msg, callback_server, parent_path=None):
         self._client = client
         self._if_spec_msg = msg
+        self._callback_server = callback_server
         self._parent_path = parent_path
 
     def GetFunctionPointerID(self, function_pointer):
@@ -56,7 +61,9 @@
             if not max_num or key > max_num:
                 max_num = key
         _function_pointer_id_dict[max_num + 1] = function_pointer
-        return str(max_num + 1)
+        id = str(max_num + 1)
+        self._callback_server.RegisterCallback(id, function_pointer)
+        return id
 
     def OpenConventionalHal(self, module_name=None):
         """Opens the target conventional HAL component.
@@ -322,7 +329,9 @@
                 parent_name = "%s.%s" % (self._parent_path, api_name)
             else:
                 parent_name = api_name
-            return MirrorObject(self._client, struct_msg, parent_name)
+            return MirrorObject(self._client, struct_msg,
+                                self._callback_server,
+                                parent_path=parent_name)
 
         # handle attributes.
         fuzz = False