12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#!/usr/bin/env python
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)# Copyright (c) 2013 The Chromium Authors. All rights reserved.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)# Use of this source code is governed by a BSD-style license that can be
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)# found in the LICENSE file.
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)"""Command line tool for forwarding ports from a device to the host.
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Allows an Android device to connect to services running on the host machine,
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)i.e., "adb forward" in reverse. Requires |host_forwarder| and |device_forwarder|
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)to be built.
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)"""
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import optparse
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import sys
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import time
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)from pylib import android_commands, constants, forwarder
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)from pylib.utils import run_tests_helper
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)def main(argv):
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  parser = optparse.OptionParser(usage='Usage: %prog [options] device_port '
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 'host_port [device_port_2 host_port_2] ...',
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 description=__doc__)
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  parser.add_option('-v',
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    '--verbose',
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    dest='verbose_count',
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    default=0,
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    action='count',
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    help='Verbose level (multiple times for more)')
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  parser.add_option('--device',
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    help='Serial number of device we should use.')
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  parser.add_option('--debug', action='store_const', const='Debug',
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    dest='build_type', default='Release',
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                    help='Use Debug build of host tools instead of Release.')
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  options, args = parser.parse_args(argv)
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  run_tests_helper.SetLogLevel(options.verbose_count)
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if len(args) < 2 or not len(args) % 2:
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    parser.error('Need even number of port pairs')
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    sys.exit(1)
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  try:
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    port_pairs = map(int, args[1:])
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    port_pairs = zip(port_pairs[::2], port_pairs[1::2])
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  except ValueError:
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    parser.error('Bad port number')
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    sys.exit(1)
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  adb = android_commands.AndroidCommands(options.device)
5358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  constants.SetBuildType(options.build_type)
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  try:
5558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    forwarder.Forwarder.Map(port_pairs, adb)
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    while True:
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      time.sleep(60)
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  except KeyboardInterrupt:
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    sys.exit(0)
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  finally:
61a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    forwarder.Forwarder.UnmapAllDevicePorts(adb)
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)if __name__ == '__main__':
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  main(sys.argv)
65