From e44becfa2377819eeddb566077ac29aa8728d219 Mon Sep 17 00:00:00 2001 From: Christopher Vagnetoft Date: Thu, 16 Feb 2017 17:40:02 +0100 Subject: [PATCH] Added upnp-discover cli tool --- bin/upnp-discover | 206 +++++++++++++++++++++++++++++++++++++++++++ composer.json | 5 +- src/SSDP/Device.php | 40 +++++++++ src/SSDP/Service.php | 25 ++++++ 4 files changed, 275 insertions(+), 1 deletion(-) create mode 100755 bin/upnp-discover diff --git a/bin/upnp-discover b/bin/upnp-discover new file mode 100755 index 0000000..94ec321 --- /dev/null +++ b/bin/upnp-discover @@ -0,0 +1,206 @@ +#!/usr/bin/env php + + 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 +]; + +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; +} + +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) { + foreach ($discovery as $device) { + printf(" %s: %s (%s) %s [%s]\n", + $device->getFriendlyName(), + $device->getModelName(), + $device->getManufacturer(), + $device->getDeviceType(), + $device->getIp() + ); + foreach ($device->getServices() as $service) { + printf(" + %s\n", $service->getServiceType()); + } + } + +} \ No newline at end of file diff --git a/composer.json b/composer.json index 345a62d..c60d7b9 100644 --- a/composer.json +++ b/composer.json @@ -13,5 +13,8 @@ "psr-4": { "NoccyLabs\\UPnP\\": "src/" } - } + }, + "bin": [ + "bin/upnp-discover" + ] } \ No newline at end of file diff --git a/src/SSDP/Device.php b/src/SSDP/Device.php index ece205c..dc05740 100644 --- a/src/SSDP/Device.php +++ b/src/SSDP/Device.php @@ -93,6 +93,46 @@ class Device return $this->ip; } + public function getDevices() + { + return $this->devices; + } + + public function getServices() + { + return $this->services; + } + + public function getFriendlyName() + { + return $this->friendlyName; + } + + public function getDeviceType() + { + return $this->deviceType; + } + + public function getManufacturer() + { + return $this->manufacturer; + } + + public function getModelName() + { + return $this->modelName; + } + + public function getModelDescription() + { + return $this->modelDescription; + } + + public function getUrl() + { + return $this->specUrl; + } + public function __toString() { diff --git a/src/SSDP/Service.php b/src/SSDP/Service.php index 0a7f3a7..b90fa9b 100644 --- a/src/SSDP/Service.php +++ b/src/SSDP/Service.php @@ -35,6 +35,31 @@ class Service } + public function getServiceType() + { + return $this->serviceType; + } + + public function getServiceId() + { + return $this->serviceId; + } + + public function getScpdUrl() + { + return $this->scpdUrl; + } + + public function getControlUrl() + { + return $this->controlUrl; + } + + public function getEventSubUrl() + { + return $this->eventSubUrl; + } + public function __toString() { return sprintf("Service: %s [%s]\nControl URL: %s\nEventSub URL: %s\nSCPD URL: %s\n",