#!/usr/bin/env python
usage = """
Get info for all Trimble receivers on a subnet.  Example usage:
  ./ipScan.py 10.1.133.*
"""
import multiprocessing
import argparse
import requests
import xmltodict


http_timeout = 1
def get_upnp( ip ):
    try:
        r = requests.get( "http://%s/upnp.xml"%ip, timeout=http_timeout )
    except:
        return
    try:
        d = xmltodict.parse(r.text)
        print (ip, d['root']['device']['friendlyName'])
        return
    except:
        pass
    try:
        r = requests.get( f"http://{ip}/xml/dynamic/merge.xml?sysData=", timeout=http_timeout )
        if r.status_code==401:
            if not 'WWW-Authenticate' in r.headers:
                return # Not coreBuild
            if not 'Trimble' in r.headers['WWW-Authenticate']:
                return # Not coreBuild
            print( ip, "(TRMB, but upnp is off and unknown password)")
            return
        r.raise_for_status()
    except:
        return # Not coreBuild
    try:
        d = xmltodict.parse(r.text)
        print (ip,'(upnp off)',
               d['data']['sysData']['RXName'],
               d['data']['sysData']['serial'],
               d['data']['sysData']['ownerString1'])
    except:
        print( ip, "(TRMB unit, but upnp is off and merge.xml failed parsing),r.text")
        return

def main(prefix):
    min_addr = 1
    # Avoid the Gateway 10.1.148.1
    if prefix == '10.1.148':
        min_addr = 2
    all_ip = [prefix+'.%d'%n for n in range(min_addr,256)]
    pool = multiprocessing.Pool()
    d = pool.map( get_upnp, all_ip )

if __name__ == "__main__":
    parser = argparse.ArgumentParser(description=usage,
                                     formatter_class=argparse.RawDescriptionHelpFormatter)
    parser.add_argument("pattern", help="IP pattern, e.g. 10.1.149.*")
    parser.add_argument("--timeout", type=int, default=1, help="HTTP request timeout in seconds")
    args = parser.parse_args()
    http_timeout = args.timeout
    print("Timeout set to %d [s]"%http_timeout)
    if args.pattern.endswith('.*') and len(args.pattern.split('.'))==4:
        main(args.pattern[:-2])
    else:
        print(usage)
