def __init_socket_port(self): NUM_RETRIES = 100 RETRY_WAIT_TIME_SEC = 0.05 # Bind a socket to use as mutex lock socket_lock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) for i in range(NUM_RETRIES): try: socket_lock.bind((ItsSession.IPADDR, ItsSession.LOCK_PORT)) break except socket.error: if i == NUM_RETRIES - 1: raise its.error.Error(self.device_id, "acquiring socket lock timed out") else: time.sleep(RETRY_WAIT_TIME_SEC) # Check if a port is already assigned to the device. command = "adb forward --list" proc = subprocess.Popen(command.split(), stdout=subprocess.PIPE) output, error = proc.communicate() port = None used_ports = [] for line in output.split(os.linesep): # each line should be formatted as: # "<device_id> tcp:<host_port> tcp:<remote_port>" forward_info = line.split() if len(forward_info) >= 3 and \ len(forward_info[1]) > 4 and forward_info[1][:4] == "tcp:" and \ len(forward_info[2]) > 4 and forward_info[2][:4] == "tcp:": local_p = int(forward_info[1][4:]) remote_p = int(forward_info[2][4:]) if forward_info[0] == self.device_id and \ remote_p == ItsSession.REMOTE_PORT: port = local_p break; else: used_ports.append(local_p) # Find the first available port if no port is assigned to the device. if port is None: for p in range(ItsSession.CLIENT_PORT_START, ItsSession.CLIENT_PORT_START + ItsSession.MAX_NUM_PORTS): if p not in used_ports: # Try to run "adb forward" with the port command = "%s forward tcp:%d tcp:%d" % \ (self.adb, p, self.REMOTE_PORT) proc = subprocess.Popen(command.split(), stdout=subprocess.PIPE, stderr=subprocess.PIPE) output, error = proc.communicate() # Check if there is no error if error is None or error.find("error") < 0: port = p break if port is None: raise its.error.Error(self.device_id, " cannot find an available " + "port") # Release the socket as mutex unlock socket_lock.close() # Connect to the socket self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.sock.connect((self.IPADDR, port)) self.sock.settimeout(self.SOCK_TIMEOUT)