/upnp/find.php

https://gitlab.com/x33n/ampache · PHP · 140 lines · 52 code · 23 blank · 65 comment · 4 complexity · 9da78d75f0a9ab95adca930c4c5c95b1 MD5 · raw file

  1. <?php
  2. error_reporting( E_ALL );
  3. ini_set('display_errors', 1);
  4. class UPnPFind
  5. {
  6. /**
  7. * Find devices by UPnP multicast message and stores them to cache
  8. *
  9. * @return array Parsed device list
  10. */
  11. public static function findDevices()
  12. {
  13. $discover = self::discover(10);
  14. return($discover); //!!
  15. /*
  16. $devices = array();
  17. flush();
  18. foreach ($discover as $response) {
  19. $device = new Device();
  20. if ($device->initByDiscoveryReponse($response)) {
  21. $device->saveToCache();
  22. try {
  23. $client = $device->getClient('ConnectionManager');
  24. $protocolInfo = $client->call('GetProtocolInfo');
  25. $sink = $protocolInfo['Sink'];
  26. $tmp = explode(',', $sink);
  27. $protocols = array();
  28. foreach ($tmp as $protocol) {
  29. $t = explode(':', $protocol);
  30. if ($t[0] == 'http-get') {
  31. $protocols[] = $t[2];
  32. }
  33. }
  34. } catch (UPnPException $upnpe) {
  35. $protocols = array();
  36. }
  37. $device->protocolInfo = $protocols;
  38. $cache[$device->getId()] = array(
  39. 'name' => $device->getName(),
  40. 'services' => $device->getServices(),
  41. 'icons' => $device->getIcons(),
  42. 'protocols' => $device->getProtocolInfo()
  43. );
  44. }
  45. }
  46. return $cache;
  47. */
  48. }
  49. /**
  50. * Performs a standardized UPnP multicast request to 239.255.255.250:1900
  51. * and listens $timeout seconds for responses
  52. *
  53. * Thanks to artheus (https://github.com/artheus/PHP-UPnP/blob/master/phpupnp.class.php)
  54. *
  55. * @param int $timeout Timeout to wait for responses
  56. *
  57. * @return array Response
  58. */
  59. private static function discover($timeout = 2)
  60. {
  61. $msg = 'M-SEARCH * HTTP/1.1' . "\r\n";
  62. $msg .= 'HOST: 239.255.255.250:1900' . "\r\n";
  63. $msg .= 'MAN: "ssdp:discover"' . "\r\n";
  64. $msg .= "MX: 3\r\n";
  65. $msg .= "ST: upnp:rootdevice\r\n";
  66. $msg .= '' . "\r\n";
  67. $socket = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
  68. socket_set_option($socket, SOL_SOCKET, SO_BROADCAST, 1);
  69. socket_sendto($socket, $msg, strlen($msg), 0, '239.255.255.250', 1900);
  70. socket_set_option($socket, SOL_SOCKET, SO_RCVTIMEO, array('sec' => $timeout, 'usec' => 0));
  71. $response = array();
  72. do {
  73. $buf = null;
  74. @socket_recvfrom($socket, $buf, 1024, MSG_WAITALL, $from, $port);
  75. if (!is_null($buf))
  76. $response[] = self::discoveryReponse2Array($buf);
  77. } while (!is_null($buf));
  78. //socket_close($socket);
  79. return $response;
  80. }
  81. /**
  82. * Transforms discovery response string to key/value array
  83. *
  84. * @param string $res discovery response
  85. *
  86. * @return \stdObj
  87. */
  88. private static function discoveryReponse2Array($res)
  89. {
  90. $result = array();
  91. $lines = explode("\n", trim($res));
  92. if (trim($lines[0]) == 'HTTP/1.1 200 OK') {
  93. array_shift($lines);
  94. }
  95. foreach ($lines as $line) {
  96. $tmp = explode(':', trim($line));
  97. $key = strtoupper(array_shift($tmp));
  98. $value = (count($tmp) > 0 ? trim(join(':', $tmp)) : null);
  99. $result[$key] = $value;
  100. }
  101. return (Object)$result;
  102. }
  103. }
  104. $devices = UPnPFind::findDevices();
  105. ?>
  106. <pre>
  107. <?php print_r($devices); ?>
  108. </pre>