Class: Quaff::Call

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

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(cxn, cid, instance_id = nil, uri = nil, destination = nil, target_uri = nil) ⇒ Call

Returns a new instance of Call.



30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/call.rb', line 30

def initialize(cxn,
               cid,
               instance_id=nil,
               uri=nil,
               destination=nil,
               target_uri=nil)
  @cxn = cxn
  setdest(destination, recv_from_this: true) if destination
  @retrans = nil
  @t1, @t2 = 0.5, 32
  @instance_id = instance_id
  @cid = cid
  set_default_headers cid, uri, target_uri
end

Instance Attribute Details

#cidObject (readonly)

Returns the value of attribute cid.



28
29
30
# File 'lib/call.rb', line 28

def cid
  @cid
end

Instance Method Details

#assoc_with_msg(msg) ⇒ Object



243
244
245
246
# File 'lib/call.rb', line 243

def assoc_with_msg(msg)
  @last_Via = msg.all_headers("Via")
  @last_CSeq = CSeq.new(msg.header("CSeq"))
end

#create_dialog(msg) ⇒ Object



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/call.rb', line 65

def create_dialog msg
  if @in_dialog
    return
  end

  @in_dialog = true

  uri = msg.first_header("Contact")

  if /<(.*?)>/ =~ uri
    uri = $1
  end

  @sip_destination = uri

  unless msg.all_headers("Record-Route").nil?
    if msg.type == :request
      @routeset = msg.all_headers("Record-Route")
    else
      @routeset = msg.all_headers("Record-Route").reverse
    end
  end

end

#end_callObject



239
240
241
# File 'lib/call.rb', line 239

def end_call
  @cxn.mark_call_dead @cid
end

#get_new_via_hdrObject



53
54
55
# File 'lib/call.rb', line 53

def get_new_via_hdr
  "SIP/2.0/#{@cxn.transport} #{Quaff::Utils.local_ip}:#{@cxn.local_port};rport;branch=#{Quaff::Utils::new_branch}"
end

#get_next_hop(header) ⇒ Object



248
249
250
251
252
# File 'lib/call.rb', line 248

def get_next_hop header
  /<sip:(.+@)?(.+):(\d+);(.*)>/ =~ header
  sock = TCPSocket.new $2, $3
  return TCPSource.new sock
end

#recv_any_of(possible_messages) ⇒ Object

Waits until the next message comes in, and handles it if it is one of possible_messages.

possible_messages is a list of things that can be received. Elements can be:

  • a string representing the SIP method, e.g. “INVITE”

  • a number representing the SIP status code, e.g. 200

  • a two-item list, containing one of the above and a boolean

value, which indicates whether this message is dialog-creating. by default, requests are assumed to be dialog-creating and responses are not.

For example, [“INVITE”, 301, [“ACK”, false], [200, true]] is a valid value for possible_messages.



145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
# File 'lib/call.rb', line 145

def recv_any_of(possible_messages)
  begin
    msg = recv_something
  rescue Timeout::Error
    raise "#{ @uri } timed out waiting for one of these: #{possible_messages}"
  end

  found_match = false
  dialog_creating = nil
  
  possible_messages.each do
    | what, this_dialog_creating |
    type = if (what.class == String) then :request else :response end
    if this_dialog_creating.nil?
      this_dialog_creating = (type == :request)
    end

    found_match =
      if type == :request 
        msg.type == :request and what == msg.method
      else
        msg.type == :response and what.to_s == msg.status_code
      end

    if found_match
      dialog_creating = this_dialog_creating
      break
    end
  end

  unless found_match
    raise((msg.to_s || "Message is nil!"))
  end

  if msg.type == :request
    unless @has_To_tag
      @has_To_tag = true
      tospec = ToSpec.new
      tospec.parse(msg.header("To"))
      tospec.params['tag'] = generate_random_tag
      @last_To = tospec.to_s
      @last_From = msg.header("From")
    end
  else
    if @in_dialog
      @has_To_tag = true
      @last_To = msg.header("To")
    end    
  end

  if dialog_creating
    create_dialog msg
  end
  msg
end

#recv_request(method, dialog_creating = true) ⇒ Object



104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/call.rb', line 104

def recv_request(method, dialog_creating=true)
  begin
    msg = recv_something
  rescue Timeout::Error
    raise "#{ @uri } timed out waiting for #{ method }"
  end

  unless msg.type == :request \
    and Regexp.new(method) =~ msg.method
    raise((msg.to_s || "Message is nil!"))
  end

  unless @has_To_tag
    @has_To_tag = true
    tospec = ToSpec.new
    tospec.parse(msg.header("To"))
    tospec.params['tag'] = generate_random_tag
    @last_To = tospec.to_s
    @last_From = msg.header("From")
  end

  if dialog_creating
    create_dialog msg
  end
  msg
end

#recv_response(code, dialog_creating = false) ⇒ Object



201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
# File 'lib/call.rb', line 201

def recv_response(code, dialog_creating=false)
  begin
    msg = recv_something
  rescue Timeout::Error
    raise "#{ @uri } timed out waiting for #{ code }"
  end
  unless msg.type == :response \
    and Regexp.new(code) =~ msg.status_code
    raise "Expected #{ code}, got #{msg.status_code || msg}"
  end

  if dialog_creating
    create_dialog msg
  end

  if @in_dialog
    @has_To_tag = true
    @last_To = msg.header("To")
  end

  msg
end

#recv_response_and_create_dialog(code) ⇒ Object



224
225
226
# File 'lib/call.rb', line 224

def recv_response_and_create_dialog(code)
  recv_response code, true
end

#send_request(method, body = "", headers = {}) ⇒ Object



234
235
236
237
# File 'lib/call.rb', line 234

def send_request(method, body="", headers={})
  msg = build_message headers, body, :request, method
  send_something(msg, nil)
end

#send_response(code, phrase, body = "", retrans = nil, headers = {}) ⇒ Object



228
229
230
231
232
# File 'lib/call.rb', line 228

def send_response(code, phrase, body="", retrans=nil, headers={})
  method = nil
  msg = build_message headers, body, :response, method, code, phrase
  send_something(msg, retrans)
end

#set_callee(uri) ⇒ Object



57
58
59
60
61
62
63
# File 'lib/call.rb', line 57

def set_callee uri
  if /<(.*?)>/ =~ uri
    uri = $1
  end

  @sip_destination = "#{uri}"
end

#setdest(source, options = {}) ⇒ Object

Sets the Source where messages in this call should be sent to by default.

Options:

:recv_from_this - if true, also listens for any incoming
messages over this source's connection. (This is only
meaningful for connection-oriented transports.)


97
98
99
100
101
102
# File 'lib/call.rb', line 97

def setdest source, options={}
  @src = source
  if options[:recv_from_this] and source.sock
    @cxn.add_sock source.sock
  end
end

#update_branch(via_hdr = nil) ⇒ Object Also known as: new_transaction

Changes the branch parameter if the Via header, creating a new transaction



46
47
48
49
# File 'lib/call.rb', line 46

def update_branch via_hdr=nil
  via_hdr ||= get_new_via_hdr
  @last_Via = via_hdr
end