Class: WemoDevice::SSDP

Inherits:
Object
  • Object
show all
Defined in:
lib/wemo_device/ssdp.rb

Defined Under Namespace

Classes: Response

Constant Summary collapse

MULTICAST_HOST =
"239.255.255.250".freeze
MULTICAST_PORT =
1900.freeze

Instance Method Summary collapse

Instance Method Details

#lookup(search_target, timeout) ⇒ Object



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/wemo_device/ssdp.rb', line 44

def lookup(search_target, timeout)
  UDPSocket.open do |socket|
    # `sendto(2)` should automatically `bind(2)`.
    socket.send(m_search_message(search_target), 0, MULTICAST_HOST, MULTICAST_PORT)

    responses = []
    begin
      Timeout.timeout(timeout) do
        loop do
          # `recv(2)` may discard excess bytes for message based sockets such as `SOCK_DGRAM`
          # when a message is too long and not fir in the given length and `MSG_PEEK` is not set.
          # Thus, the entire message shall be read in a single operation.
          payload, (_, port, host, _) = socket.recvfrom(4096)
          responses << Response.new(host, port, payload)
        end
      end
    rescue Timeout::Error
    end

    responses
  end
end

#m_search_message(search_target) ⇒ Object



67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/wemo_device/ssdp.rb', line 67

def m_search_message(search_target)
  [
    "M-SEARCH * HTTP/1.1",
    "Content-Length: 0",
    "ST: #{search_target}",
    # Device responses should be delayed a random duration between 0 and this many seconds
    # to balance load for the control point when it processes responses.
    "MX: 2",
    "MAN: \"ssdp:discover\"",
    "HOST: #{MULTICAST_HOST}:#{MULTICAST_PORT}",
    "",
    ""
  ].join("\r\n")
end