import grpc
import logging
import os
import select
import signal
import socket
import subprocess
import sys
import threading
import time
if os.path.split(os.path.dirname(__file__))[1] != 'plugin':
sys.path.append(
os.path.join(os.path.abspath(os.path.dirname(__file__)), 'plugin'))
from plugin_constants import PLUGIN_PROTOS_PATH, PLUGIN_SERVICE_ADDRESS, PLUGIN_PROXY_SERVICE_PORT, REMOTE_PLUGIN_PROXY_PORT
from test_plugin_client import TestPluginClient
sys.path.append(PLUGIN_PROTOS_PATH)
import test_plugin_service_pb2
import test_plugin_service_pb2_grpc
LOGGER = logging.getLogger(__name__)
class PluginServiceProxyWrapper:
def __init__(self, plugin_service_address, plugin_proxy_service_port,
remote_proxy_port):
""" Wrapper for ptroxy service that handles usbmuxd requests/response
Args:
plugin_service_address: address for the plugin service in
test_plugin_service.py.
plugin_proxy_service_port: port for the proxy service
remote_proxy_port: port for the proxy service on the test app side.
"""
self.plugin_service_address = plugin_service_address
self.plugin_proxy_service_port = plugin_proxy_service_port
self.remote_proxy_port = remote_proxy_port
self.proxy_process_stop_flag = threading.Event()
self.plugin_service_proxy = self.PluginServiceProxy(
plugin_service_address, plugin_proxy_service_port,
self.proxy_process_stop_flag)
self.iproxy_process = None
self.proxy_process = None
def start(self):
self.iproxy_process = self.start_iproxy()
self.proxy_process = threading.Thread(
target=self.plugin_service_proxy.start)
self.proxy_process.start()
def tear_down(self):
LOGGER.info('terminating proxy process...')
if self.proxy_process != None:
self.proxy_process_stop_flag.set()
self.proxy_process.join()
self.proxy_process_stop_flag.clear()
LOGGER.info('terminating iproxy process...')
if self.iproxy_process != None:
os.kill(self.iproxy_process.pid, signal.SIGTERM)
def reset(self):
if self.proxy_process != None:
self.proxy_process_stop_flag.set()
self.proxy_process.join()
self.proxy_process_stop_flag.clear()
self.proxy_process = threading.Thread(
target=self.plugin_service_proxy.start)
self.proxy_process.start()
def start_iproxy(self):
cmd = ['iproxy', self.plugin_proxy_service_port, self.remote_proxy_port]
process = subprocess.Popen(cmd)
time.sleep(2)
return process
class PluginServiceProxy:
def __init__(self, plugin_service_address, plugin_proxy_service_port,
stop_flag):
""" Proxy service that handles usbmuxd requests/response.
The service is responsible for forwarding data received from usbmuxd
to plugin service. It also forwards data received from plugin service
back to the remote usbmuxd proxy on the test app side.
Args:
plugin_service_address: address for the plugin service in
test_plugin_service.py.
plugin_proxy_service_port: port for the proxy service.
stop_flag: since the service will be continuously running in the
background to handle requests async. We need a thread flag to
stop the service process.
"""
self.plugin_client = TestPluginClient(plugin_service_address)
self.plugin_proxy_service_port = plugin_proxy_service_port
self.stop_flag = stop_flag
def start(self):
sock = None
try:
LOGGER.info(
'Attemping to establish connection with remote proxy service...')
received = ""
while received == "" and not self.stop_flag.is_set():
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(('localhost', int(self.plugin_proxy_service_port)))
try:
sock.sendall(bytes("hello world" + "\n", "utf-8"))
received = str(sock.recv(1024), "utf-8")
except ConnectionResetError as e:
LOGGER.error(
'unable to connect to remote device server, retrying...', e)
sock.close()
sock = None
time.sleep(3)
LOGGER.info(
'Connection with remote proxy service is successfully established!')
while not self.stop_flag.is_set():
self.receiveRequests()
self.forwardRequests()
except Exception as e:
LOGGER.error('Proxy service unexpectedly exited due to error ', e)
finally:
if sock != None:
sock.close()
def receiveRequests(self):
return
def forwardRequests(self):
return
if __name__ == '__main__':
server = PluginServiceProxyWrapper(PLUGIN_SERVICE_ADDRESS,
PLUGIN_PROXY_SERVICE_PORT,
REMOTE_PLUGIN_PROXY_PORT)
server.start()