php-upnp/bin/upnp-discover
2017-03-31 16:45:52 +02:00

258 lines
6.6 KiB
PHP
Executable File

#!/usr/bin/env php
<?php
//
// Discover UPnP Devices on the network.
// Use this tool for testing when developing using noccylabs/upnp or similar.
//
// (c) 2017, NoccyLabs.info
// Licensed under GNU GPL v3 or later.
//
foreach ([
__DIR__."/../../autoload.php",
__DIR__."/../vendor/autoload.php"
] as $autoload) {
if (file_exists($autoload)) {
require_once $autoload; break;
}
}
use NoccyLabs\UPnP\SSDP\Device;
use NoccyLabs\UPnP\SSDP\Discovery;
use NoccyLabs\UPnP\SSDP\SearchTarget;
$opt_short = "hARd:s:u:D:lj";
$opt_long = [
"help", // -h
"all", // -A
"root", // -R
"device:", // -d:
"service:", // -s:
"uuid:", // -u:
"domain:", // -D:
"long", // -l
"json", // -j
];
$help = <<<EOH
upnp-discover - Discover UPnP devices on the local network
Usage: upnp-discover [options]
Options:
-h, --help Show this help
-A, --all Find all devices on the LAN
-R, --root Find all root devices on the LAN
-d, --device Find by device type and version
-s, --service Find by service type and version
-D, --domain Combine with -d or -s to search for specific vendor domains.
-u, --uuid Find by UUID
-l, --long Include all info in output
-j, --json Output JSON
Examples:
Find all devices:
--all
Find root devices:
--root
Find by UUID:
--uuid <uuid>
Find core UPnP devices or services:
--device InternetGatewayDevice:2
--service Layer3Forwarding:1
Find vendored devices or services:
--device dialreceiver:1 --domain dial-multiscreen-org
--service dial:1 --domain dial-multiscreen-org
EOH;
function show_help() {
echo $GLOBALS['help'];
}
$opts = (object)[
'help'=>null,
'all'=>null,
'root'=>null,
'device'=>null,
'service'=>null,
'domain'=>null,
'uuid'=>null,
'long'=>null,
'json'=>null
];
foreach (getopt($opt_short, $opt_long) as $opt=>$value) switch ($opt) {
case 'help':
case 'h':
$opts->help = true; break;
case 'all':
case 'A':
$opts->all = true; break;
case 'root':
case 'R':
$opts->root = true; break;
case 'device':
case 'd':
$opts->device = $value; break;
case 'service':
case 's':
$opts->service = $value; break;
case 'domain':
case 'd':
$opts->domain = $value; break;
case 'uuid':
case 'u':
$opts->uuid = $vaue; break;
case 'long':
case 'l':
$opts->long = true; break;
case 'json':
case 'j':
$opts->json = true; break;
}
if ($opts->device && $opts->service) {
echo "You can't specify --device and --service at the same time\n";
exit(1);
}
if ($opts->domain && (!($opts->service || $opts->device))) {
echo "You need to provide --service or --device when using --domain\n";
exit(1);
} elseif ($opts->domain) {
if ($opts->device) {
discover_device($opts->device, $opts->domain);
} else {
discover_service($opts->service, $opts->domain);
}
exit(0);
} elseif ($opts->device) {
discover_device($opts->device, $opts->domain);
exit(0);
} elseif ($opts->service) {
discover_service($opts->service, $opts->domain);
exit(0);
}
if ($opts->uuid && ($opts->service || $opts->device || $opts->all || $opts->root)) {
echo "You can't combine --uuid with the other search types\n";
exit(1);
} elseif ($opts->uuid) {
discover_uuid($opts->uuid);
exit(0);
}
if ($opts->all && $opts->root) {
echo "You can't specify --all and --root at the same time\n";
exit(1);
} elseif ($opts->all) {
discover_all();
exit(0);
} elseif ($opts->root) {
discover_root();
exit(0);
}
show_help();
exit(0);
// ---- discovery functions ---------------------------------------------------
function discover_uuid($uuid) {
echo "Discovering uuid {$uuid}...\n";
}
function discover_device($device, $domain=null) {
echo "Discovering devices for {$device}...\n";
$discovery = new Discovery();
list ($device,$version)=explode(":",$device);
if ($domain) {
$target = SearchTarget::URN_DEVICE($domain,$device,$version);
} else {
$target = SearchTarget::URN_SCHEMA_DEVICE($device,$version);
}
$discovery->discover($target);
show_results($discovery);
}
function discover_service($service, $domain=null) {
echo "Discovering services for {$service}...\n";
$discovery = new Discovery();
list ($service,$version)=explode(":",$service);
if ($domain) {
$target = SearchTarget::URN_SERVICE($domain,$service,$version);
} else {
$target = SearchTarget::URN_SCHEMA_SERVICE($service,$version);
}
$discovery->discover($target);
show_results($discovery);
}
function discover_all() {
echo "Discovering all devices...\n";
$discovery = new Discovery();
$discovery->discover(SearchTarget::ALL);
show_results($discovery);
}
function discover_root() {
echo "Discovering root devices...\n";
$discovery = new Discovery();
$discovery->discover(SearchTarget::ROOT_DEVICE);
show_results($discovery);
}
function show_results(Discovery $discovery) {
global $opts;
if ($opts->long) {
show_results_long($discovery);
} elseif ($opts->json) {
show_results_json($discovery);
} else {
show_results_short($discovery);
}
}
function show_results_short(Discovery $discovery) {
foreach ($discovery as $device) {
printf(" * \e[94m%s: %s \e[1m%s\e[21m (%s) [%s]\e[0m\n",
$device->getFriendlyName(),
$device->getManufacturer(),
$device->getModelName(),
$device->getDeviceType(),
$device->getIp()
);
}
}
function show_results_long(Discovery $discovery) {
foreach ($discovery as $device) {
show_device_long($device);
}
}
function show_device_long(Device $device, $level=0) {
$indent = str_repeat(" ",$level);
printf("{$indent} * \e[92m%s\e[94m: %s \e[1m%s\e[21m (\e[34m%s\e[94m) [%s]\e[0m\n",
$device->getFriendlyName(),
$device->getManufacturer(),
$device->getModelName(),
$device->getDeviceType(),
$device->getIp()
);
printf("{$indent} \e[32m%s\e[0m\n", $device->getUrl());
foreach ($device->getServices() as $service) {
printf("{$indent} + \e[36m%s\e[0m\n{$indent} \e[32m%s\e[0m\n", $service->getServiceType(), $service->getUrl());
}
foreach ($device->getDevices() as $subdevice) {
show_device_long($subdevice, $level+1);
}
}
function show_results_json(Discovery $discovery) {
echo json_encode($discovery->jsonSerialize())."\n";
}