Various improvements
This commit is contained in:
parent
ccc70650f2
commit
a9c1a3ccbe
@ -40,6 +40,14 @@ object to get the devices.
|
|||||||
print_r($device);
|
print_r($device);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
## Experimental Features
|
||||||
|
|
||||||
|
### DCP
|
||||||
|
|
||||||
|
The DCPs (Device Control Protocol) are used to interact with services. This
|
||||||
|
can be f.ex. managing UPnP portmapping in your router or controlling a media
|
||||||
|
player.
|
||||||
|
|
||||||
## Search targets
|
## Search targets
|
||||||
|
|
||||||
To find everything, use `ALL`:
|
To find everything, use `ALL`:
|
||||||
|
@ -10,10 +10,11 @@
|
|||||||
|
|
||||||
require_once __DIR__."/../vendor/autoload.php";
|
require_once __DIR__."/../vendor/autoload.php";
|
||||||
|
|
||||||
|
use NoccyLabs\UPnP\SSDP\Device;
|
||||||
use NoccyLabs\UPnP\SSDP\Discovery;
|
use NoccyLabs\UPnP\SSDP\Discovery;
|
||||||
use NoccyLabs\UPnP\SSDP\SearchTarget;
|
use NoccyLabs\UPnP\SSDP\SearchTarget;
|
||||||
|
|
||||||
$opt_short = "hARd:s:u:D:l";
|
$opt_short = "hARd:s:u:D:lj";
|
||||||
$opt_long = [
|
$opt_long = [
|
||||||
"help", // -h
|
"help", // -h
|
||||||
"all", // -A
|
"all", // -A
|
||||||
@ -22,7 +23,8 @@ $opt_long = [
|
|||||||
"service:", // -s:
|
"service:", // -s:
|
||||||
"uuid:", // -u:
|
"uuid:", // -u:
|
||||||
"domain:", // -D:
|
"domain:", // -D:
|
||||||
"long",
|
"long", // -l
|
||||||
|
"json", // -j
|
||||||
];
|
];
|
||||||
$help = <<<EOH
|
$help = <<<EOH
|
||||||
upnp-discover - Discover UPnP devices on the local network
|
upnp-discover - Discover UPnP devices on the local network
|
||||||
@ -39,6 +41,7 @@ Options:
|
|||||||
-D, --domain Combine with -d or -s to search for specific vendor domains.
|
-D, --domain Combine with -d or -s to search for specific vendor domains.
|
||||||
-u, --uuid Find by UUID
|
-u, --uuid Find by UUID
|
||||||
-l, --long Include all info in output
|
-l, --long Include all info in output
|
||||||
|
-j, --json Output JSON
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
|
|
||||||
@ -69,7 +72,8 @@ $opts = (object)[
|
|||||||
'service'=>null,
|
'service'=>null,
|
||||||
'domain'=>null,
|
'domain'=>null,
|
||||||
'uuid'=>null,
|
'uuid'=>null,
|
||||||
'long'=>null
|
'long'=>null,
|
||||||
|
'json'=>null
|
||||||
];
|
];
|
||||||
|
|
||||||
foreach (getopt($opt_short, $opt_long) as $opt=>$value) switch ($opt) {
|
foreach (getopt($opt_short, $opt_long) as $opt=>$value) switch ($opt) {
|
||||||
@ -97,6 +101,9 @@ foreach (getopt($opt_short, $opt_long) as $opt=>$value) switch ($opt) {
|
|||||||
case 'long':
|
case 'long':
|
||||||
case 'l':
|
case 'l':
|
||||||
$opts->long = true; break;
|
$opts->long = true; break;
|
||||||
|
case 'json':
|
||||||
|
case 'j':
|
||||||
|
$opts->json = true; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($opts->device && $opts->service) {
|
if ($opts->device && $opts->service) {
|
||||||
@ -190,17 +197,54 @@ function discover_root() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function show_results(Discovery $discovery) {
|
function show_results(Discovery $discovery) {
|
||||||
foreach ($discovery as $device) {
|
global $opts;
|
||||||
printf(" %s: %s (%s) %s [%s]\n",
|
if ($opts->long) {
|
||||||
$device->getFriendlyName(),
|
show_results_long($discovery);
|
||||||
$device->getModelName(),
|
} elseif ($opts->json) {
|
||||||
$device->getManufacturer(),
|
show_results_json($discovery);
|
||||||
$device->getDeviceType(),
|
} else {
|
||||||
$device->getIp()
|
show_results_short($discovery);
|
||||||
);
|
|
||||||
foreach ($device->getServices() as $service) {
|
|
||||||
printf(" + %s\n", $service->getServiceType());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
|
||||||
|
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->getServiceUrl());
|
||||||
|
}
|
||||||
|
foreach ($device->getDevices() as $subdevice) {
|
||||||
|
show_device_long($subdevice, $level+1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function show_results_json(Discovery $discovery) {
|
||||||
|
echo json_encode($discovery, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES)."\n";
|
||||||
|
}
|
||||||
|
22
src/DCP/AbstractDevice.php
Normal file
22
src/DCP/AbstractDevice.php
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace NoccyLabs\UPnP\DCP;
|
||||||
|
|
||||||
|
use NoccyLabs\UPnP\DCP\AbstractDevice;
|
||||||
|
use NoccyLabs\UPnP\SSDP\Device;
|
||||||
|
|
||||||
|
abstract class AbstractDevice
|
||||||
|
{
|
||||||
|
/** @var Device The device this DCP operates on */
|
||||||
|
protected $device;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param Device $device The device for the DCP
|
||||||
|
*/
|
||||||
|
public function __construct(Device $device)
|
||||||
|
{
|
||||||
|
$this->device = $device;
|
||||||
|
}
|
||||||
|
}
|
38
src/DCP/AbstractService.php
Normal file
38
src/DCP/AbstractService.php
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace NoccyLabs\UPnP\DCP;
|
||||||
|
|
||||||
|
use NoccyLabs\UPnP\DCP\AbstractService;
|
||||||
|
use NoccyLabs\UPnP\SSDP\Device;
|
||||||
|
use NoccyLabs\UPnP\SSDP\Service;
|
||||||
|
|
||||||
|
abstract class AbstractService
|
||||||
|
{
|
||||||
|
/** @var Service The service this DCP operates on */
|
||||||
|
protected $service;
|
||||||
|
/** @var Device The device this DCP operates on */
|
||||||
|
protected $device;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @param Device $device The device for the DCP
|
||||||
|
* @param Service $service The service for the DCP
|
||||||
|
*/
|
||||||
|
public function __construct(Device $device, Service $service)
|
||||||
|
{
|
||||||
|
$this->device = $device;
|
||||||
|
$this->service = $service;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function readScpdServiceDefinition($url)
|
||||||
|
{}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the schema to pass as the XML namespace when sending the SOAP request
|
||||||
|
* to the device.
|
||||||
|
*
|
||||||
|
* @return string The schema
|
||||||
|
*/
|
||||||
|
abstract protected function getSchemaUrn();
|
||||||
|
}
|
@ -17,8 +17,9 @@ namespace NoccyLabs\UPnP\SSDP;
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
use SimpleXMLElement;
|
use SimpleXMLElement;
|
||||||
|
use JsonSerializable;
|
||||||
|
|
||||||
class Device
|
class Device implements JsonSerializable
|
||||||
{
|
{
|
||||||
|
|
||||||
protected $deviceType;
|
protected $deviceType;
|
||||||
@ -86,7 +87,7 @@ class Device
|
|||||||
$services = $spec->serviceList;
|
$services = $spec->serviceList;
|
||||||
if (count($services)>0) {
|
if (count($services)>0) {
|
||||||
foreach ($services->children() as $service) {
|
foreach ($services->children() as $service) {
|
||||||
$this->services[] = new Service($service);
|
$this->services[] = new Service($this, $service);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -163,5 +164,16 @@ class Device
|
|||||||
return $info;
|
return $info;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function createServiceWrapper($type)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function jsonSerialize()
|
||||||
|
{
|
||||||
|
return get_object_vars($this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ namespace NoccyLabs\UPnP\SSDP;
|
|||||||
|
|
||||||
use IteratorAggregate;
|
use IteratorAggregate;
|
||||||
use ArrayIterator;
|
use ArrayIterator;
|
||||||
|
use JsonSerializable;
|
||||||
use NoccyLabs\UPnP\HTTPU\Endpoint;
|
use NoccyLabs\UPnP\HTTPU\Endpoint;
|
||||||
use NoccyLabs\UPnP\HTTPU\EndpointException;
|
use NoccyLabs\UPnP\HTTPU\EndpointException;
|
||||||
use NoccyLabs\UPnP\HTTPU\MSearchRequest;
|
use NoccyLabs\UPnP\HTTPU\MSearchRequest;
|
||||||
@ -14,7 +15,7 @@ use NoccyLabs\UPnP\HTTPU\MSearchResponse;
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class Discovery implements IteratorAggregate
|
class Discovery implements IteratorAggregate, JsonSerializable
|
||||||
{
|
{
|
||||||
|
|
||||||
protected $devices = [];
|
protected $devices = [];
|
||||||
@ -52,10 +53,14 @@ class Discovery implements IteratorAggregate
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
$device = Device::createFromSchema($response->getLocation(), $response->getIp());
|
$device = Device::createFromSchema($response->getLocation(), $response->getIp());
|
||||||
$this->devices[$loc] = $device;
|
if ($device) {
|
||||||
|
$this->devices[$loc] = $device;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$this->devices = array_values($this->devices);
|
||||||
|
|
||||||
return count($this->devices);
|
return count($this->devices);
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -65,5 +70,10 @@ class Discovery implements IteratorAggregate
|
|||||||
return new ArrayIterator($this->devices);
|
return new ArrayIterator($this->devices);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function jsonSerialize()
|
||||||
|
{
|
||||||
|
return $this->devices;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,10 +10,13 @@ namespace NoccyLabs\UPnP\SSDP;
|
|||||||
<eventSubURL>/evt/L3F</eventSubURL>
|
<eventSubURL>/evt/L3F</eventSubURL>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
use JsonSerializable;
|
||||||
use SimpleXMLElement;
|
use SimpleXMLElement;
|
||||||
|
|
||||||
class Service
|
class Service implements JsonSerializable
|
||||||
{
|
{
|
||||||
|
protected $device;
|
||||||
|
|
||||||
protected $serviceType;
|
protected $serviceType;
|
||||||
|
|
||||||
protected $serviceId;
|
protected $serviceId;
|
||||||
@ -24,9 +27,10 @@ class Service
|
|||||||
|
|
||||||
protected $eventSubUrl;
|
protected $eventSubUrl;
|
||||||
|
|
||||||
public function __construct(SimpleXMLElement $spec)
|
public function __construct(Device $device, SimpleXMLElement $spec)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
$this->device = $device;
|
||||||
$this->serviceType = (string)$spec->serviceType;
|
$this->serviceType = (string)$spec->serviceType;
|
||||||
$this->serviceId = (string)$spec->serviceId;
|
$this->serviceId = (string)$spec->serviceId;
|
||||||
$this->scpdUrl = (string)$spec->SCPDURL;
|
$this->scpdUrl = (string)$spec->SCPDURL;
|
||||||
@ -50,6 +54,26 @@ class Service
|
|||||||
return $this->scpdUrl;
|
return $this->scpdUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getServiceUrl()
|
||||||
|
{
|
||||||
|
if (strpos($this->scpdUrl,"://")!==false) {
|
||||||
|
return $this->scpdUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
$dev = ['user'=>null, 'pass'=>null, 'port'=>80, 'path'=>null];
|
||||||
|
$dev = array_merge($dev, parse_url($this->device->getUrl()));
|
||||||
|
$url = $this->scpdUrl;
|
||||||
|
|
||||||
|
$auth = $dev['user']?($dev['user'].":".$dev['path']):"";
|
||||||
|
$base = $dev['scheme']."://".$dev['host'].":".($dev['port']?:80);
|
||||||
|
if ($url[0]=="/") {
|
||||||
|
return $base.$url;
|
||||||
|
} else {
|
||||||
|
return $base.rtrim($dev['path'],"/")."/".$url;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public function getControlUrl()
|
public function getControlUrl()
|
||||||
{
|
{
|
||||||
return $this->controlUrl;
|
return $this->controlUrl;
|
||||||
@ -71,5 +95,10 @@ class Service
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function jsonSerialize()
|
||||||
|
{
|
||||||
|
return get_object_vars($this);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user