Class: SiriProxy::Connection
- Inherits:
-
EventMachine::Connection
- Object
- EventMachine::Connection
- SiriProxy::Connection
- Includes:
- EventMachine::Protocols::LineText2
- Defined in:
- lib/siriproxy/connection.rb
Defined Under Namespace
Instance Attribute Summary collapse
-
#consumed_ace ⇒ Object
Returns the value of attribute consumed_ace.
-
#input_buffer ⇒ Object
Returns the value of attribute input_buffer.
-
#last_ref_id ⇒ Object
Returns the value of attribute last_ref_id.
-
#name ⇒ Object
Returns the value of attribute name.
-
#other_connection ⇒ Object
Returns the value of attribute other_connection.
-
#output_buffer ⇒ Object
Returns the value of attribute output_buffer.
-
#plugin_manager ⇒ Object
Returns the value of attribute plugin_manager.
-
#processed_headers ⇒ Object
Returns the value of attribute processed_headers.
-
#ssled ⇒ Object
Returns the value of attribute ssled.
-
#unzip_stream ⇒ Object
Returns the value of attribute unzip_stream.
-
#unzipped_input ⇒ Object
Returns the value of attribute unzipped_input.
-
#unzipped_output ⇒ Object
Returns the value of attribute unzipped_output.
-
#zip_stream ⇒ Object
Returns the value of attribute zip_stream.
Instance Method Summary collapse
- #flush_output_buffer ⇒ Object
- #flush_unzipped_output ⇒ Object
- #has_next_object? ⇒ Boolean
-
#initialize ⇒ Connection
constructor
A new instance of Connection.
- #inject_object_to_output_stream(object) ⇒ Object
- #parse_object(object_data) ⇒ Object
- #post_init ⇒ Object
- #prep_received_object(object) ⇒ Object
- #process_compressed_data ⇒ Object
- #read_next_object_from_unzipped ⇒ Object
- #receive_binary_data(data) ⇒ Object
-
#receive_line(line) ⇒ Object
Process header.
-
#received_object(object) ⇒ Object
Stub – override in subclass.
- #ssl_handshake_completed ⇒ Object
Constructor Details
#initialize ⇒ Connection
Returns a new instance of Connection.
14 15 16 17 18 19 20 21 22 23 24 |
# File 'lib/siriproxy/connection.rb', line 14 def initialize super self.processed_headers = false self.output_buffer = "" self.input_buffer = "" self.unzipped_input = "" self.unzipped_output = "" self.unzip_stream = Zlib::Inflate.new self.zip_stream = Zlib::Deflate.new self.consumed_ace = false end |
Instance Attribute Details
#consumed_ace ⇒ Object
Returns the value of attribute consumed_ace.
7 8 9 |
# File 'lib/siriproxy/connection.rb', line 7 def consumed_ace @consumed_ace end |
#input_buffer ⇒ Object
Returns the value of attribute input_buffer.
7 8 9 |
# File 'lib/siriproxy/connection.rb', line 7 def input_buffer @input_buffer end |
#last_ref_id ⇒ Object
Returns the value of attribute last_ref_id.
7 8 9 |
# File 'lib/siriproxy/connection.rb', line 7 def last_ref_id @last_ref_id end |
#name ⇒ Object
Returns the value of attribute name.
7 8 9 |
# File 'lib/siriproxy/connection.rb', line 7 def name @name end |
#other_connection ⇒ Object
Returns the value of attribute other_connection.
7 8 9 |
# File 'lib/siriproxy/connection.rb', line 7 def other_connection @other_connection end |
#output_buffer ⇒ Object
Returns the value of attribute output_buffer.
7 8 9 |
# File 'lib/siriproxy/connection.rb', line 7 def output_buffer @output_buffer end |
#plugin_manager ⇒ Object
Returns the value of attribute plugin_manager.
7 8 9 |
# File 'lib/siriproxy/connection.rb', line 7 def plugin_manager @plugin_manager end |
#processed_headers ⇒ Object
Returns the value of attribute processed_headers.
7 8 9 |
# File 'lib/siriproxy/connection.rb', line 7 def processed_headers @processed_headers end |
#ssled ⇒ Object
Returns the value of attribute ssled.
7 8 9 |
# File 'lib/siriproxy/connection.rb', line 7 def ssled @ssled end |
#unzip_stream ⇒ Object
Returns the value of attribute unzip_stream.
7 8 9 |
# File 'lib/siriproxy/connection.rb', line 7 def unzip_stream @unzip_stream end |
#unzipped_input ⇒ Object
Returns the value of attribute unzipped_input.
7 8 9 |
# File 'lib/siriproxy/connection.rb', line 7 def unzipped_input @unzipped_input end |
#unzipped_output ⇒ Object
Returns the value of attribute unzipped_output.
7 8 9 |
# File 'lib/siriproxy/connection.rb', line 7 def unzipped_output @unzipped_output end |
#zip_stream ⇒ Object
Returns the value of attribute zip_stream.
7 8 9 |
# File 'lib/siriproxy/connection.rb', line 7 def zip_stream @zip_stream end |
Instance Method Details
#flush_output_buffer ⇒ Object
69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/siriproxy/connection.rb', line 69 def flush_output_buffer return if output_buffer.empty? if other_connection.ssled puts "[Debug - #{self.name}] Forwarding #{self.output_buffer.length} bytes of data to #{other_connection.name}" if $LOG_LEVEL > 5 #puts self.output_buffer.to_hex if $LOG_LEVEL > 5 other_connection.send_data(output_buffer) self.output_buffer = "" else puts "[Debug - #{self.name}] Buffering some data for later (#{self.output_buffer.length} bytes buffered)" if $LOG_LEVEL > 5 #puts self.output_buffer.to_hex if $LOG_LEVEL > 5 end end |
#flush_unzipped_output ⇒ Object
169 170 171 172 173 174 175 |
# File 'lib/siriproxy/connection.rb', line 169 def flush_unzipped_output self.zip_stream << self.unzipped_output self.unzipped_output = "" self.output_buffer << zip_stream.flush flush_output_buffer() end |
#has_next_object? ⇒ Boolean
101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
# File 'lib/siriproxy/connection.rb', line 101 def has_next_object? return false if unzipped_input.empty? #empty unpacked = unzipped_input[0...5].unpack('H*').first return true if(unpacked.match(/^0[34]/)) #Ping or pong return true if(unpacked.match(/^ff/)) #clear context if unpacked.match(/^[0-9][15-9]/) puts "ROGUE PACKET!!! WHAT IS IT?! TELL US!!! IN IRC!! COPY THE STUFF FROM BELOW" puts unpacked.to_hex end objectLength = unpacked.match(/^0200(.{6})/)[1].to_i(16) return ((objectLength + 5) < unzipped_input.length) #determine if the length of the next object (plus its prefix) is less than the input buffer end |
#inject_object_to_output_stream(object) ⇒ Object
148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 |
# File 'lib/siriproxy/connection.rb', line 148 def inject_object_to_output_stream(object) if object["refId"] != nil && !object["refId"].empty? @block_rest_of_session = false if @block_rest_of_session && self.last_ref_id != object["refId"] #new session self.last_ref_id = object["refId"] end puts "[Info - Forwarding object to #{self.other_connection.name}] #{object["class"]}" if $LOG_LEVEL > 1 object_data = object.to_plist(:plist_format => CFPropertyList::List::FORMAT_BINARY) #Recalculate the size in case the object gets modified. If new size is 0, then remove the object from the stream entirely obj_len = object_data.length if(obj_len > 0) prefix = [(0x0200000000 + obj_len).to_s(16).rjust(10, '0')].pack('H*') self.unzipped_output << prefix + object_data end flush_unzipped_output() end |
#parse_object(object_data) ⇒ Object
141 142 143 144 145 146 |
# File 'lib/siriproxy/connection.rb', line 141 def parse_object(object_data) plist = CFPropertyList::List.new(:data => object_data) object = CFPropertyList.native_types(plist.value) object end |
#post_init ⇒ Object
26 27 28 |
# File 'lib/siriproxy/connection.rb', line 26 def post_init self.ssled = false end |
#prep_received_object(object) ⇒ Object
177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 |
# File 'lib/siriproxy/connection.rb', line 177 def prep_received_object(object) #workaround for #143 if object["class"] == "FinishSpeech" or object["class"] == "SpeechRecognized" @block_rest_of_session = false end if object["refId"] == self.last_ref_id && @block_rest_of_session puts "[Info - Dropping Object from Guzzoni] #{object["class"]}" if $LOG_LEVEL > 1 pp object if $LOG_LEVEL > 3 return nil end puts "[Info - #{self.name}] Received Object: #{object["class"]}" if $LOG_LEVEL == 1 puts "[Info - #{self.name}] Received Object: #{object["class"]} (group: #{object["group"]})" if $LOG_LEVEL == 2 puts "[Info - #{self.name}] Received Object: #{object["class"]} (group: #{object["group"]}, ref_id: #{object["refId"]}, ace_id: #{object["aceId"]})" if $LOG_LEVEL > 2 pp object if $LOG_LEVEL > 3 #keeping this for filters new_obj = received_object(object) if new_obj == nil puts "[Info - Dropping Object from #{self.name}] #{object["class"]}" if $LOG_LEVEL > 1 pp object if $LOG_LEVEL > 3 return nil end #block the rest of the session if a plugin claims ownership speech = SiriProxy::Interpret.speech_recognized(object) if speech != nil inject_object_to_output_stream(object) block_rest_of_session if plugin_manager.process(speech) return nil end #object = new_obj if ((new_obj = SiriProxy::Interpret.unknown_intent(object, self, plugin_manager.method(:unknown_command))) != false) #object = new_obj if ((new_obj = SiriProxy::Interpret.speech_recognized(object, self, plugin_manager.method(:speech_recognized))) != false) object end |
#process_compressed_data ⇒ Object
83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
# File 'lib/siriproxy/connection.rb', line 83 def process_compressed_data self.unzipped_input << unzip_stream.inflate(self.input_buffer) self.input_buffer = "" puts "========UNZIPPED DATA (from #{self.name} =========" if $LOG_LEVEL > 5 puts unzipped_input.to_hex if $LOG_LEVEL > 5 puts "==================================================" if $LOG_LEVEL > 5 while(self.has_next_object?) object = read_next_object_from_unzipped() if(object != nil) #will be nil if the next object is a ping/pong new_object = prep_received_object(object) #give the world a chance to mess with folks inject_object_to_output_stream(new_object) if new_object != nil #might be nil if "the world" decides to rid us of the object end end end |
#read_next_object_from_unzipped ⇒ Object
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 |
# File 'lib/siriproxy/connection.rb', line 116 def read_next_object_from_unzipped unpacked = unzipped_input[0...5].unpack('H*').first info = unpacked.match(/^(..)(.{8})$/) if(info[1] == "03" || info[1] == "04" || info[1] == "ff") #Ping or pong -- just get these out of the way (and log them for good measure) object = unzipped_input[0...5] self.unzipped_output << object type = (info[1] == "03") ? "Ping" : ((info[1] == "04") ? "Pong" : "Clear Context") puts "[#{type} - #{self.name}] (#{info[2].to_i(16)})" if $LOG_LEVEL > 3 self.unzipped_input = unzipped_input[5..-1] flush_unzipped_output() return nil end object_size = info[2].to_i(16) prefix = unzipped_input[0...5] object_data = unzipped_input[5...object_size+5] self.unzipped_input = unzipped_input[object_size+5..-1] parse_object(object_data) end |
#receive_binary_data(data) ⇒ Object
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/siriproxy/connection.rb', line 48 def receive_binary_data(data) self.input_buffer << data ##Consume the "0xAACCEE02" data at the start of the stream if necessary (by forwarding it to the output buffer) if(self.consumed_ace == false) self.output_buffer << input_buffer[0..3] self.input_buffer = input_buffer[4..-1] self.consumed_ace = true; end begin process_compressed_data() flush_output_buffer() rescue puts "[Info - #{self.name}] Got invalid data (non-ACE protocol?), terminating the connection." self.close_connection end end |
#receive_line(line) ⇒ Object
Process header
36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/siriproxy/connection.rb', line 36 def receive_line(line) #Process header puts "[Header - #{self.name}] #{line}" if $LOG_LEVEL > 2 if(line == "") #empty line indicates end of headers puts "[Debug - #{self.name}] Found end of headers" if $LOG_LEVEL > 3 set_binary_mode self.processed_headers = true end self.output_buffer << (line + "\x0d\x0a") #Restore the CR-LF to the end of the line flush_output_buffer() end |
#received_object(object) ⇒ Object
Stub – override in subclass
218 219 220 221 |
# File 'lib/siriproxy/connection.rb', line 218 def received_object(object) object end |
#ssl_handshake_completed ⇒ Object
30 31 32 33 34 |
# File 'lib/siriproxy/connection.rb', line 30 def ssl_handshake_completed self.ssled = true puts "[Info - #{self.name}] SSL completed for #{self.name}" if $LOG_LEVEL > 1 end |