Class: Frisky::SSDP::BroadcastSearcher

Inherits:
EventMachine::Connection
  • Object
show all
Includes:
EventMachine::Deferrable, NetworkConstants, LogSwitch
Defined in:
lib/frisky/ssdp/broadcast_searcher.rb

Constant Summary

Constants included from NetworkConstants

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

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(search_target, response_wait_time, ttl = TTL) ⇒ BroadcastSearcher

Returns a new instance of BroadcastSearcher.



23
24
25
26
27
28
29
30
31
32
# File 'lib/frisky/ssdp/broadcast_searcher.rb', line 23

def initialize(search_target, response_wait_time, ttl=TTL)
  @ttl = ttl
  @discovery_responses = []
  @alive_notifications = []
  @byebye_notifications = []

  setup_broadcast_socket

  @search = m_search(search_target, response_wait_time)
end

Instance Attribute Details

#available_responsesObject (readonly)

Returns the value of attribute available_responses.



20
21
22
# File 'lib/frisky/ssdp/broadcast_searcher.rb', line 20

def available_responses
  @available_responses
end

#byebye_responsesObject (readonly)

Returns the value of attribute byebye_responses.



21
22
23
# File 'lib/frisky/ssdp/broadcast_searcher.rb', line 21

def byebye_responses
  @byebye_responses
end

#discovery_responsesArray (readonly)

Returns The list of responses from the current discovery request.

Returns:

  • (Array)

    The list of responses from the current discovery request.



18
19
20
# File 'lib/frisky/ssdp/broadcast_searcher.rb', line 18

def discovery_responses
  @discovery_responses
end

Instance Method Details

#m_search(search_target, response_wait_time) ⇒ Object



40
41
42
43
44
45
46
47
48
49
# File 'lib/frisky/ssdp/broadcast_searcher.rb', line 40

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

#parse(data) ⇒ Hash

Converts the headers to a set of key-value pairs.

Parameters:

  • data (String)

    The data to convert.

Returns:

  • (Hash)

    The converted data. Returns an empty Hash if it didn’t know how to parse.



85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/frisky/ssdp/broadcast_searcher.rb', line 85

def parse(data)
  new_data = {}

  unless data =~ /\n/
    log 'Received response as a single-line String.  Discarding.'
    log "Bad response looked like:\n#{data}"
    return new_data
  end

  data.each_line do |line|
    line =~ /(\S*):(.*)/

    unless $1.nil?
      key = $1
      value = $2
      key = key.gsub('-', '_').downcase.to_sym
      new_data[key] = value.strip
    end
  end

  new_data
end

#peer_infoArray<String,Fixnum>

Gets the IP and port from the peer that just sent data.

Returns:

  • (Array<String,Fixnum>)

    The IP and port.



54
55
56
57
58
59
60
# File 'lib/frisky/ssdp/broadcast_searcher.rb', line 54

def peer_info
  peer_bytes = get_peername[2, 6].unpack('nC4')
  port = peer_bytes.first.to_i
  ip = peer_bytes[1, 4].join('.')

  [ip, port]
end

#post_initObject



34
35
36
37
38
# File 'lib/frisky/ssdp/broadcast_searcher.rb', line 34

def post_init
  if send_datagram(@search, BROADCAST_IP, MULTICAST_PORT) > 0
    log "Sent broadcast datagram search:\n#{@search}"
  end
end

#receive_data(response) ⇒ Object



62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/frisky/ssdp/broadcast_searcher.rb', line 62

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

  if parsed_response.has_key? :nts
    if parsed_response[:nts] == 'ssdp:alive'
      @alive_notifications << parsed_response
    elsif parsed_response[:nts] == 'ssdp:bye-bye'
      @byebye_notifications << parsed_response
    else
      raise "Unknown NTS value: #{parsed_response[:nts]}"
    end
  else
    @discovery_responses << parsed_response
  end
end

#setup_broadcast_socketObject

Sets Socket options to allow for brodcasting.



109
110
111
# File 'lib/frisky/ssdp/broadcast_searcher.rb', line 109

def setup_broadcast_socket
  set_sock_opt(Socket::SOL_SOCKET, Socket::SO_BROADCAST, true)
end