Class: Frisky::SSDP::Searcher

Inherits:
MulticastConnection show all
Includes:
LogSwitch
Defined in:
lib/frisky/ssdp/searcher.rb

Overview

A subclass of an EventMachine::Connection, this handles doing M-SEARCHes.

Search types:

ssdp:all
upnp:rootdevice
uuid:[device-uuid]
urn:schemas-upnp-org:device:[deviceType-version]
urn:schemas-upnp-org:service:[serviceType-version]
urn:[custom-schema]:device:[deviceType-version]
urn:[custom-schema]:service:[serviceType-version]

Constant Summary collapse

DEFAULT_RESPONSE_WAIT_TIME =
5
DEFAULT_M_SEARCH_COUNT =
2

Constants included from NetworkConstants

NetworkConstants::BROADCAST_IP, NetworkConstants::MULTICAST_IP, NetworkConstants::MULTICAST_PORT, NetworkConstants::TTL

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods inherited from MulticastConnection

#parse, #peer_info, #set_membership, #set_multicast_ttl, #set_ttl, #setup_multicast_socket, #switch_multicast_loop

Constructor Details

#initialize(search_target, options = {}) ⇒ Searcher

Returns a new instance of Searcher.

Parameters:

  • search_target (String)
  • options (Hash) (defaults to: {})

Options Hash (options):

  • response_wait_time (Fixnum)
  • ttl (Fixnum)
  • m_search_count (Fixnum)

    The number of times to send the M-SEARCH. UPnP 1.0 suggests to send the request more than once.



32
33
34
35
36
37
38
39
40
# File 'lib/frisky/ssdp/searcher.rb', line 32

def initialize(search_target, options = {})
  options[:ttl] ||= TTL
  options[:response_wait_time] ||= DEFAULT_RESPONSE_WAIT_TIME
  @m_search_count = options[:m_search_count] ||= DEFAULT_M_SEARCH_COUNT

  @search = m_search(search_target, options[:response_wait_time])

  super options[:ttl]
end

Instance Attribute Details

#discovery_responsesEventMachine::Channel (readonly)

Returns Provides subscribers with responses from their search request.

Returns:

  • (EventMachine::Channel)

    Provides subscribers with responses from their search request.



24
25
26
# File 'lib/frisky/ssdp/searcher.rb', line 24

def discovery_responses
  @discovery_responses
end

Instance Method Details

#m_search(search_target, response_wait_time) ⇒ Object

Builds the M-SEARCH request string.

Parameters:

  • search_target (String)
  • response_wait_time (Fixnum)


76
77
78
79
80
81
82
83
84
85
# File 'lib/frisky/ssdp/searcher.rb', line 76

def m_search(search_target, response_wait_time)
  <<-MSEARCH
M-SEARCH * HTTP/1.1\r
HOST: #{MULTICAST_IP}:#{MULTICAST_PORT}\r
MAN: "ssdp:discover"\r
MX: #{response_wait_time}\r
ST: #{search_target}\r
\r
  MSEARCH
end

#post_initObject

Sends the M-SEARCH that was built during init. Logs what was sent if the send was successful.



64
65
66
67
68
69
70
# File 'lib/frisky/ssdp/searcher.rb', line 64

def post_init
  @m_search_count.times do
    if send_datagram(@search, MULTICAST_IP, MULTICAST_PORT) > 0
      log "Sent datagram search:\n#{@search}"
    end
  end
end

#receive_data(response) ⇒ Object

This is the callback called by EventMachine when it receives data on the socket that’s been opened for this connection. In this case, the method parses the SSDP responses/notifications into Hashes and adds them to the appropriate EventMachine::Channel (provided as accessor methods). This effectively means that in each Channel, you get a Hash that represents the headers for each response/notification that comes in on the socket.

Parameters:

  • response (String)

    The data received on this connection’s socket.



50
51
52
53
54
55
56
57
58
59
60
# File 'lib/frisky/ssdp/searcher.rb', line 50

def receive_data(response)
  ip, port = peer_info
  log "Response from #{ip}:#{port}:\n#{response}\n"
  parsed_response = parse(response)

  return if parsed_response.has_key? :nts
  return if parsed_response[:man] &&
    parsed_response[:man] =~ /ssdp:discover/

  @discovery_responses << parsed_response
end