From 62771ab3aba45ff4f71a3b7eb959cc0b5e93df53 Mon Sep 17 00:00:00 2001 From: Mike Kovacevic Date: Thu, 10 May 2018 15:12:11 -0400 Subject: [PATCH 01/22] Rebase for PR --- lib/sippy_cup/scenario.rb | 394 +++++++++++++++++++++++++++----- spec/sippy_cup/scenario_spec.rb | 100 +++++++- 2 files changed, 436 insertions(+), 58 deletions(-) diff --git a/lib/sippy_cup/scenario.rb b/lib/sippy_cup/scenario.rb index c590e35..aaf98da 100644 --- a/lib/sippy_cup/scenario.rb +++ b/lib/sippy_cup/scenario.rb @@ -83,7 +83,8 @@ def self.from_manifest(manifest, options = {}) # @option options [String, Numeric] :source_port The source port to bind SIPp to (defaults to 8836). # @option options [String] :destination The target system at which to direct traffic. # @option options [String] :advertise_address The IP address to advertise in SIP and SDP if different from the bind IP (defaults to the bind IP). - # @option options [String] :from_user The SIP user from which traffic should appear. + # @option options [String] :from_user The SIP user from which traffic should appear. Overwrites user in :from if passed. + # @option options [String] :from The SIP user / address from which traffic should appear. # @option options [String] :to_user The SIP user to send requests to. Alias for `:to` and deprecated in favour of the same. # @option options [String] :to The SIP user / address to send requests to. # @option options [Integer] :media_port The RTCP (media) port to bind to locally. @@ -145,6 +146,21 @@ def build(steps) end end + def options(opts = {}) + msg = <<-MSG +OPTIONS sip:[remote_ip] SIP/2.0 +Via: SIP/2.0/[transport] #{@adv_ip}:[local_port];branch=[branch] +From: ;tag=[call_number] +To: +Call-ID: [call_id] +CSeq: [cseq] OPTIONS +Max-Forwards: 100 +User-Agent: #{USER_AGENT} +Content-Length: 0 +MSG + send msg, opts + end + # # Send an invite message # @@ -156,27 +172,32 @@ def invite(opts = {}) opts[:retrans] ||= 500 # FIXME: The DTMF mapping (101) is hard-coded. It would be better if we could # get this from the DTMF payload generator - from_addr = "#{@from_user}@#{@adv_ip}:[local_port]" + from_domain = @from_domain || @adv_ip + from_addr = "#{@from_user}@#{from_domain || @adv_ip + ":[local_port]"}" + max_forwards = opts[:max_forwards] || 100 + user_agent = opts[:user_agent].present? ? opts[:user_agent]: USER_AGENT msg = <<-MSG INVITE sip:#{to_addr} SIP/2.0 -Via: SIP/2.0/[transport] #{@adv_ip}:[local_port];branch=[branch] -From: "#{@from_user}" ;tag=[call_number] -To: +Via: SIP/2.0/[transport] #{@adv_ip}:[local_port];rport;branch=[branch] +From: sip:#{from_addr};tag=[call_number] +To: sip:#{to_addr} Call-ID: [call_id] CSeq: [cseq] INVITE -Contact: -Max-Forwards: 100 -User-Agent: #{USER_AGENT} +Contact: +Max-Forwards: #{max_forwards} +User-Agent: #{user_agent} Content-Type: application/sdp Content-Length: [len] -#{opts.has_key?(:headers) ? opts.delete(:headers).sub(/\n*\Z/, "\n") : ''} +#{opts.has_key?(:headers) ? opts.delete(:headers).map { |header| header.sub(/\n*\Z/, "\n") }.join : ''} v=0 o=user1 53655765 2353687637 IN IP[local_ip_type] #{@adv_ip} s=- c=IN IP[media_ip_type] [media_ip] t=0 0 m=audio [media_port] RTP/AVP 0 101 +a=rtcp-mux +a=sendrecv a=rtpmap:0 PCMU/8000 a=rtpmap:101 telephone-event/8000 a=fmtp:101 0-15 @@ -201,6 +222,26 @@ def invite(opts = {}) @reference_variables += %w(remote_addr local_addr call_addr) end + def subscribe(opts = {}) + msg = <<-MSG +SUBSCRIBE sip:#{@from_user}@#{@adv_ip} SIP/2.0 +Via: SIP/2.0/[transport] #{@adv_ip}:[local_port];branch=[branch] +From: ;tag=[call_number] +To: +Contact: +Call-ID: [call_id] +CSeq: [cseq] SUBSCRIBE +Expires: 300 +Accept: application/simple-message-summary +Allow: SUBSCRIBE, NOTIFY, INVITE, ACK, CANCEL, BYE, REFER, INFO, OPTIONS, MESSAGE +User-Agent: #{USER_AGENT} +Event: message-summary +Max-Forwards: 10 +Content-Length: 0 +MSG + send msg, opts + end + # # Send a REGISTER message with the specified credentials # @@ -215,16 +256,30 @@ def invite(opts = {}) # s.register 'frank' # def register(user, password = nil, opts = {}) + user_agent = opts[:user_agent].present? ? opts[:user_agent] : USER_AGENT send_opts = opts.dup send_opts[:retrans] ||= DEFAULT_RETRANS user, domain = parse_user user - if password - send register_message(domain, user), send_opts + + if password || opts[:auth_keyword] + send register_message(domain, user, user_agent), send_opts + + # Handle 200 OK + receive_ok opts.merge(optional: true, next: 2) + recv opts.merge(response: 401, auth: true, optional: false) - send register_auth(domain, user, password), send_opts - receive_ok opts.merge(optional: false) + + if opts[:auth_keyword].present? + send register_auth_parameterized(domain, user, opts[:auth_keyword]), send_opts + else + send register_auth(domain, user, password), send_opts + end + + receive_ok opts.merge(optional: false) unless opts[:skip_receive_ok] + + label 2 else - send register_message(domain, user), send_opts + send register_message(domain, user, user_agent), send_opts end end @@ -233,19 +288,19 @@ def register(user, password = nil, opts = {}) # # @param [Hash] opts A set of options containing SIPp element attributes # - def receive_invite(opts = {}) + def receive_invite(opts = { compact_header: false }) recv(opts.merge(request: 'INVITE', rrs: true)) do |recv| action = doc.create_element('action') do |action| action << doc.create_element('ereg') do |ereg| - ereg['regexp'] = '.*;tag=([^;]*)' + ereg['regexp'] = '.*.*;tag=([^;]*)' ereg['search_in'] = 'hdr' - ereg['header'] = 'From:' + ereg['header'] = opts[:compact_header] ? 'f:' : 'From:' ereg['assign_to'] = 'dummy,remote_addr,remote_tag' end action << doc.create_element('ereg') do |ereg| ereg['regexp'] = '' ereg['search_in'] = 'hdr' - ereg['header'] = 'To:' + ereg['header'] = opts[:compact_header] ? 't:' : 'To:' ereg['assign_to'] = 'dummy,local_addr' end action << doc.create_element('assignstr') do |assignstr| @@ -269,9 +324,10 @@ def send_trying(opts = {}) msg = <<-MSG SIP/2.0 100 Trying +[last_Record-Route:] [last_Via:] -From: ;tag=[$remote_tag] -To: ;tag=[call_number] +[last_From:] +[last_To:];tag=[call_number] [last_Call-ID:] [last_CSeq:] Server: #{USER_AGENT} @@ -291,9 +347,10 @@ def send_ringing(opts = {}) msg = <<-MSG SIP/2.0 180 Ringing +[last_Record-Route:] [last_Via:] -From: ;tag=[$remote_tag] -To: ;tag=[call_number] +[last_From:] +[last_To:];tag=[call_number] [last_Call-ID:] [last_CSeq:] Server: #{USER_AGENT} @@ -313,16 +370,15 @@ def send_answer(opts = {}) opts[:retrans] ||= DEFAULT_RETRANS msg = <<-MSG -SIP/2.0 200 Ok +SIP/2.0 200 OK +[last_Record-Route:] [last_Via:] -From: ;tag=[$remote_tag] -To: ;tag=[call_number] +[last_From:] +[last_To:];tag=[call_number] [last_Call-ID:] [last_CSeq:] -Server: #{USER_AGENT} -Contact: +Contact: Content-Type: application/sdp -[routes] Content-Length: [len] v=0 @@ -330,10 +386,14 @@ def send_answer(opts = {}) s=- c=IN IP[media_ip_type] [media_ip] t=0 0 -m=audio [media_port] RTP/AVP 0 +m=audio [media_port] RTP/AVP 0 8 101 a=rtpmap:0 PCMU/8000 +a=rtpmap:8 PCMA/8000 +a=rtpmap:101 telephone-event/8000 +a=fmtp:101 0-16 +a=rtcp-mux MSG - start_media + # start_media send msg, opts end @@ -347,10 +407,55 @@ def answer(opts = {}) receive_ack opts end + def send_cancel(opts = {}) + msg = <<-MSG + +CANCEL sip:#{to_addr} SIP/2.0 +[last_Via:] +From: +To: ;tag=[call_number] +[last_Call-ID:] +CSeq: [cseq] CANCEL +#{opts.has_key?(:headers) ? opts.delete(:headers).sub(/\n*\Z/, "\n") : ''} +Server: #{USER_AGENT} +Content-Length: 0 + MSG + send msg, opts + end + def receive_ack(opts = {}) recv opts.merge request: 'ACK' end + + # + # Send SIP INFO and expect 200 OK + # + # @param [Hash] opts A set of options to modify the message parameters + # + # + def send_info(opts = {}) + msg = <<-BODY + +INFO sip:#{@from_user}@#{@adv_ip} SIP/2.0 +Via: SIP/2.0/[transport] #{@adv_ip}:[local_port];branch=[branch] +From: ;tag=[call_number] +To: +Contact: +Call-ID: [call_id] +CSeq: [cseq] INFO +Accept: application/simple-message-summary +User-Agent: #{USER_AGENT} +Event: message-summary +Max-Forwards: 10 +Content-Length: 0 +Content-Type: application/test + + BODY + send msg, opts + recv response: 200 + end + # # Sets an expectation for a SIP 100 message from the remote party # @@ -391,7 +496,7 @@ def receive_progress(opts = {}) # @param [Hash] opts A set of options to modify the expectation # @option opts [true, false] :optional Whether or not receipt of the message is optional. Defaults to false. # - def receive_answer(opts = {}) + def receive_answer(opts = { compact_header: false }) options = { rrs: true, # Record Record Set: Make the Route headers available via [routes] later rtd: true # Response Time Duration: Record the response time @@ -402,7 +507,7 @@ def receive_answer(opts = {}) action << doc.create_element('ereg') do |ereg| ereg['regexp'] = '.*;tag=([^;]*)' ereg['search_in'] = 'hdr' - ereg['header'] = 'To:' + ereg['header'] = opts[:compact_header] ? 't:' : 'To:' ereg['assign_to'] = 'dummy,remote_addr,remote_tag' end end @@ -422,6 +527,77 @@ def receive_ok(opts = {}, &block) end alias :receive_200 :receive_ok + def receive_too_many_hops(opts = {}, &block) + recv({ response: 483 }.merge(opts), &block) + end + alias :receive_483 :receive_too_many_hops + + def receive_temp_unavailable(opts = {}, &block) + recv({ response: 480 }.merge(opts), &block) + + ack_msg = <<-BODY + +ACK sip:[service]@#{@to_domain} SIP/2.0 +Via: SIP/2.0/[transport] #{@adv_ip}:[local_port];branch=[branch-7] +From: "#{@from_user}" ;tag=[call_number] +To: [peer_tag_param] +Call-ID: [call_id] +CSeq: [cseq] ACK +Max-Forwards: 100 +Content-Length: 0 +[routes] + + BODY + + send ack_msg, {} + end + alias :receive_480 :receive_temp_unavailable + + + def receive_userbusy(opts = {}, &block) + recv({ response: 486 }.merge(opts), &block) + + ack_msg = <<-BODY + +ACK sip:[service]@#{@to_domain} SIP/2.0 +Via: SIP/2.0/[transport] #{@adv_ip}:[local_port];branch=[branch-7] +From: "#{@from_user}" ;tag=[call_number] +To: [peer_tag_param] +Call-ID: [call_id] +CSeq: [cseq] ACK +Max-Forwards: 100 +Content-Length: 0 +[routes] + + BODY + + send ack_msg, {} + end + alias :receive_486 :receive_userbusy + + + def receive_request_terminated(opts = {}, &block) + recv({ response: 487 }.merge(opts), &block) + + ack_msg = <<-BODY + +ACK sip:[service]@#{@to_domain} SIP/2.0 +Via: SIP/2.0/[transport] #{@adv_ip}:[local_port];branch=[branch-7] +From: "#{@from_user}" ;tag=[call_number] +To: [peer_tag_param] +Call-ID: [call_id] +CSeq: [cseq] ACK +Max-Forwards: 100 +Content-Length: 0 +[routes] + + BODY + + send ack_msg, {} + end + alias :receive_487 :receive_request_terminated + + # # Convenience method to wait for an answer from the called party # @@ -447,21 +623,71 @@ def ack_answer(opts = {}) msg = <<-BODY ACK [next_url] SIP/2.0 -Via: SIP/2.0/[transport] #{@adv_ip}:[local_port];branch=[branch] -From: "#{@from_user}" ;tag=[call_number] -To: [peer_tag_param] -Call-ID: [call_id] +[last_Via:] +[routes] +[last_From:] +[last_To:] +[last_Call-ID:] CSeq: [cseq] ACK -Contact: +Contact: sip:#{@from_user}@#{@adv_ip}:[local_port] Max-Forwards: 100 User-Agent: #{USER_AGENT} Content-Length: 0 -[routes] + BODY send msg, opts start_media end + def auth_required(opts = {}) + recv(response: opts[:status_code] || 401, auth:true) + end + alias :receive_401 :auth_required + + def proxy_auth_required(opts = {}) + recv(response: opts[:status_code] || 407, rrs: true, auth: true) + + ack_msg = <<-BODY + +ACK sip:#{@to_addr} SIP/2.0 +[last_Via:] +[routes] +[last_From:] +[last_To:] +[last_Call-ID:] +CSeq: [cseq] ACK +Subject: Proxy Auth Acknowledged +Max-Forwards: 70 +Content-Length: 0 + + BODY + + send ack_msg, {} + end + alias :receive_407 :proxy_auth_required + + def receive_forbidden(opts = {}) + recv(response: opts[:status_code] || 403) + + ack_msg = <<-BODY + +ACK sip:#{@to_addr} SIP/2.0 +[last_Via:] +[routes] +[last_From:] +[last_To:] +[last_Call-ID:] +CSeq: [cseq] ACK +Subject: 403 Forbidden Acknowledged +Max-Forwards: 70 +Content-Length: 0 + + BODY + + send ack_msg, {} + end + alias :receive_403 :receive_forbidden + # # Insert a pause into the scenario and its media of the specified duration # @@ -495,24 +721,24 @@ def send_digits(digits) @media << "dtmf:#{digit}" @media << "silence:#{delay}" when :info - info = <<-INFO + info = <<-BODY INFO [next_url] SIP/2.0 -Via: SIP/2.0/[transport] #{@adv_ip}:[local_port];branch=[branch] -From: "#{@from_user}" ;tag=[call_number] -To: [peer_tag_param] -Call-ID: [call_id] +[last_Via:] +[routes] +[last_From:] +[last_To:] +[last_Call-ID:] CSeq: [cseq] INFO Contact: Max-Forwards: 100 User-Agent: #{USER_AGENT} -[routes] Content-Length: [len] Content-Type: application/dtmf-relay Signal=#{digit} Duration=#{delay} - INFO + BODY send info recv response: 200 pause delay @@ -561,17 +787,39 @@ def receive_message(regexp = nil) def send_bye(opts = {}) msg = <<-MSG -BYE sip:[$call_addr] SIP/2.0 -Via: SIP/2.0/[transport] #{@adv_ip}:[local_port];branch=[branch] -From: ;tag=[call_number] -To: ;tag=[$remote_tag] -Contact: -Call-ID: [call_id] +BYE [next_url] SIP/2.0 +[last_Via:] +[routes] +To: "#{@from_user}" [peer_tag_param] +From: "#{@to_user}" ;tag=[call_number] +[last_Call-ID:] CSeq: [cseq] BYE Max-Forwards: 100 User-Agent: #{USER_AGENT} Content-Length: 0 + MSG + send msg, opts + end + + # + # Send a BYE message using destination of previous messages Contact Header + # + # @param [Hash] opts A set of options to modify the message parameters + # + def send_bye_using_contact(opts = {}) + msg = <<-MSG + +BYE [next_url] SIP/2.0 +Via: SIP/2.0/[transport] #{@adv_ip}:[local_port];rport;branch=[branch] [routes] +To: "#{@from_user}" [from_tag_param] +From: "#{@to_user}" [to_tag_param] +[last_Call-ID:] +Contact: +Max-Forwards: 100 +CSeq: [cseq] BYE +User-Agent: #{USER_AGENT} +Content-Length: 0 MSG send msg, opts end @@ -602,8 +850,8 @@ def okay(opts = {}) Contact: Max-Forwards: 100 User-Agent: #{USER_AGENT} -Content-Length: 0 [routes] +Content-Length: 0 ACK send msg, opts end @@ -625,7 +873,10 @@ def wait_for_hangup(opts = {}) # @param [Hash] opts A set of options containing SIPp element attributes - will be passed to both the and elements # def hangup(opts = {}) - send_bye opts + # Use contact is an option to make the bye use the value from the contact header for RURI + # As opposed to using the standard $call_addr variable set previously + use_contact = opts.delete(:use_contact) + use_contact ? send_bye_using_contact(opts) : send_bye(opts) receive_ok opts end @@ -779,11 +1030,16 @@ def parse_args(args) @dtmf_mode = :rfc2833 end - @from_user = args[:from_user] || "sipp" + if args[:from] + @from_user, @from_domain = args[:from].to_s.split('@') + else + @from_user = args[:from_user] || "sipp" + end args[:to] ||= args[:to_user] if args.has_key?(:to_user) if args[:to] @to_user, @to_domain = args[:to].to_s.split('@') + @to_addr = args[:to] end @to_domain ||= "[remote_ip]" end @@ -793,7 +1049,7 @@ def compile_media @media.compile! end - def register_message(domain, user) + def register_message(domain, user, user_agent) <<-BODY REGISTER sip:#{domain} SIP/2.0 @@ -805,7 +1061,7 @@ def register_message(domain, user) Contact: Max-Forwards: 10 Expires: 120 -User-Agent: #{USER_AGENT} +User-Agent: #{user_agent} Content-Length: 0 BODY end @@ -828,6 +1084,24 @@ def register_auth(domain, user, password) AUTH end + def register_auth_parameterized(domain, user, auth_keyword) + <<-AUTH + +REGISTER sip:#{domain} SIP/2.0 +Via: SIP/2.0/[transport] #{@adv_ip}:[local_port];branch=[branch] +From: ;tag=[call_number] +To: +Call-ID: [call_id] +CSeq: [cseq] REGISTER +Contact: +Max-Forwards: 20 +Expires: 3600 +[#{auth_keyword}] +User-Agent: #{USER_AGENT} +Content-Length: 0 + AUTH + end + def start_media @media = Media.new '127.0.0.255', 55555, '127.255.255.255', 44444 nop = doc.create_element('nop') { |nop| @@ -873,6 +1147,14 @@ def optional_recv(opts) recv opts end + def label(id) + label = Nokogiri::XML::Node.new 'label', doc + label['id'] = id + + yield recv if block_given? + scenario_node << label + end + def handle_response(code, opts) optional_recv opts.merge(response: code) end diff --git a/spec/sippy_cup/scenario_spec.rb b/spec/sippy_cup/scenario_spec.rb index 1f7a2ea..ec7d335 100644 --- a/spec/sippy_cup/scenario_spec.rb +++ b/spec/sippy_cup/scenario_spec.rb @@ -26,6 +26,15 @@ expect(subject.to_xml).to match(%r{}) end + describe '#options' do + it "sends an OPTIONS message" do + subject.options + + expect(subject.to_xml).to match(%r{}) + expect(subject.to_xml).to match(%r{OPTIONS}) + end + end + describe '#invite' do it "sends an INVITE message" do subject.invite @@ -52,12 +61,12 @@ context "with extra headers specified" do it "adds the headers to the end of the message" do - subject.invite headers: "Foo: \nBar: " + subject.invite headers: ["Foo: ", "Bar: "] expect(subject.to_xml).to match(%r{Foo: \nBar: }) end it "only has one blank line between headers and SDP" do - subject.invite headers: "Foo: \n\n\n" + subject.invite headers: ["Foo: \n\n\n"] expect(subject.to_xml).to match(%r{Foo: \n\nv=0}) end end @@ -119,6 +128,15 @@ expect(subject.to_xml).to match(%r{INVITE sip:\[service\]@\[remote_ip\]:\[remote_port\]}) end end + + context "when a Max-Forward option is specified" do + it "sets the Max-Forward header properly" do + max_forwards = rand(100) + subject.invite(max_forwards: max_forwards) + expect(subject.to_xml).to match(%r{INVITE}) + expect(subject.to_xml).to match(%r{Max-Forwards: #{max_forwards}}) + end + end end describe "#register" do @@ -177,6 +195,13 @@ expect(subject.to_xml).to match(%r{\[authentication username=frank password=abc123\]}) end end + + context "when a auth_keyword option is provided" do + it "adds parameterized authentication data to the REGISTER message" do + subject.register 'frank', nil, { auth_keyword: 'field0' } + expect(subject.to_xml).to match(%r{\[field0\]}) + end + end end describe '#receive_trying' do @@ -279,6 +304,22 @@ end end + describe '#receive_too_many_hops' do + it "expects a 483" do + subject.receive_too_many_hops + + expect(scenario.to_xml).to match(%q{}) + end + end + + describe '#receive_483' do + it "expects a 483" do + subject.receive_too_many_hops + + expect(scenario.to_xml).to match(%q{}) + end + end + describe '#ack_answer' do it "sends an ACK message" do subject.ack_answer @@ -313,6 +354,45 @@ end end + describe '#proxy_auth_required' do + it "expects a 407 by default" do + subject.proxy_auth_required + + expect(subject.to_xml).to match(%r{}) + end + + it "can override the expected status code via options" do + status_code = 401 + subject.proxy_auth_required(status_code: status_code) + + expect(subject.to_xml).to match(%r{}) + end + + it "sends an ACK" do + subject.proxy_auth_required + + xml = subject.to_xml + expect(xml).to match(%r{}) + expect(xml).to match(%r{ACK}) + end + + it "can also be called via :receive_407" do + expect(subject.method(:receive_407)).to eq(subject.method(:proxy_auth_required)) + end + end + + describe '#receive forbidden' do + it "expects a 403 forbidden response" do + subject.receive_forbidden + + expect(scenario.to_xml).to match(%r{}) + end + + it "can also be called via :receive_403" do + expect(subject.method(:receive_403)).to eq(subject.method(:receive_forbidden)) + end + end + describe '#wait_for_answer' do it "tells SIPp to optionally receive a SIP 100, 180 and 183 by default, while requiring a 200" do scenario.wait_for_answer @@ -415,6 +495,22 @@ end end + describe '#hangup' do + it 'calls send_bye and receive_ok by default' do + opts = { foo: 'bar' } + expect(subject).to receive(:send_bye).with(opts) + expect(subject).to receive(:receive_ok).with(opts) + subject.hangup opts + end + + it 'calls send_by_using_contact and receive_ok when passed a use_contact option' do + opts = { foo: 'bar', use_contact: true } + expect(subject).to receive(:send_bye_using_contact).with({ foo: 'bar' }) + expect(subject).to receive(:receive_ok).with({ foo: 'bar' }) + subject.hangup opts + end + end + describe '#call_length_repartition' do it 'create a partition table' do subject.call_length_repartition('1', '10', '2') From 1f215799856d02ececd266ba9a57ff7d00d6c1a1 Mon Sep 17 00:00:00 2001 From: Karn Saheb Date: Fri, 10 Jul 2020 13:40:21 -0400 Subject: [PATCH 02/22] Use remote_ip and port for BYE --- lib/sippy_cup/scenario.rb | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/lib/sippy_cup/scenario.rb b/lib/sippy_cup/scenario.rb index aaf98da..e26a169 100644 --- a/lib/sippy_cup/scenario.rb +++ b/lib/sippy_cup/scenario.rb @@ -116,6 +116,11 @@ def initialize(name, args = {}, &block) @errors = [] @adv_ip = args[:advertise_address] || "[local_ip]" + + # Configure values that will be used for the scope of this scenario + @to_uri = args[:to_uri] + @from_uri = args[:from_uri] + instance_eval &block if block_given? end @@ -785,16 +790,20 @@ def receive_message(regexp = nil) # @param [Hash] opts A set of options to modify the message parameters # def send_bye(opts = {}) + + use_contact = opts.delete(:use_contact) + msg = <<-MSG BYE [next_url] SIP/2.0 -[last_Via:] +Via: SIP/2.0/[transport] #{@adv_ip}:[local_port];rport;branch=[branch] [routes] To: "#{@from_user}" [peer_tag_param] From: "#{@to_user}" ;tag=[call_number] [last_Call-ID:] CSeq: [cseq] BYE Max-Forwards: 100 +#{use_contact ? "Contact: " : ""} User-Agent: #{USER_AGENT} Content-Length: 0 MSG @@ -812,7 +821,7 @@ def send_bye_using_contact(opts = {}) BYE [next_url] SIP/2.0 Via: SIP/2.0/[transport] #{@adv_ip}:[local_port];rport;branch=[branch] [routes] -To: "#{@from_user}" [from_tag_param] +To: "#{@from_user}" [from_tag_param] From: "#{@to_user}" [to_tag_param] [last_Call-ID:] Contact: @@ -875,8 +884,7 @@ def wait_for_hangup(opts = {}) def hangup(opts = {}) # Use contact is an option to make the bye use the value from the contact header for RURI # As opposed to using the standard $call_addr variable set previously - use_contact = opts.delete(:use_contact) - use_contact ? send_bye_using_contact(opts) : send_bye(opts) + send_bye(opts) receive_ok opts end From d25e39edf5315e37cf8b955c70161ac0fbd6f374 Mon Sep 17 00:00:00 2001 From: Karn Saheb Date: Fri, 10 Jul 2020 14:03:28 -0400 Subject: [PATCH 03/22] Use remote_addr and tag --- lib/sippy_cup/scenario.rb | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/sippy_cup/scenario.rb b/lib/sippy_cup/scenario.rb index e26a169..82863f5 100644 --- a/lib/sippy_cup/scenario.rb +++ b/lib/sippy_cup/scenario.rb @@ -510,9 +510,9 @@ def receive_answer(opts = { compact_header: false }) receive_200(options.merge(opts)) do |recv| recv << doc.create_element('action') do |action| action << doc.create_element('ereg') do |ereg| - ereg['regexp'] = '.*;tag=([^;]*)' + ereg['regexp'] = '.*.*;tag=([^;]*)' ereg['search_in'] = 'hdr' - ereg['header'] = opts[:compact_header] ? 't:' : 'To:' + ereg['header'] = opts[:compact_header] ? 'f:' : 'From:' ereg['assign_to'] = 'dummy,remote_addr,remote_tag' end end @@ -798,7 +798,7 @@ def send_bye(opts = {}) BYE [next_url] SIP/2.0 Via: SIP/2.0/[transport] #{@adv_ip}:[local_port];rport;branch=[branch] [routes] -To: "#{@from_user}" [peer_tag_param] +To: "#{@from_user}" ;tag=[$remote_tag] From: "#{@to_user}" ;tag=[call_number] [last_Call-ID:] CSeq: [cseq] BYE @@ -821,8 +821,8 @@ def send_bye_using_contact(opts = {}) BYE [next_url] SIP/2.0 Via: SIP/2.0/[transport] #{@adv_ip}:[local_port];rport;branch=[branch] [routes] -To: "#{@from_user}" [from_tag_param] -From: "#{@to_user}" [to_tag_param] +To: "#{@from_user}" ;tag=[$remote_tag] +From: "#{@to_user}" ;tag=[call_number] [last_Call-ID:] Contact: Max-Forwards: 100 From 3790ae70f75b7cf05359c552de7869050401e46f Mon Sep 17 00:00:00 2001 From: Karn Saheb Date: Fri, 10 Jul 2020 14:52:39 -0400 Subject: [PATCH 04/22] Address outbound/inbound BYE --- lib/sippy_cup/scenario.rb | 82 +++++++++++++++++++-------------- spec/sippy_cup/scenario_spec.rb | 4 +- 2 files changed, 50 insertions(+), 36 deletions(-) diff --git a/lib/sippy_cup/scenario.rb b/lib/sippy_cup/scenario.rb index 82863f5..04f3dea 100644 --- a/lib/sippy_cup/scenario.rb +++ b/lib/sippy_cup/scenario.rb @@ -16,6 +16,8 @@ class Scenario MSEC = 1_000 DEFAULT_RETRANS = 500 + SIP_URI_HEADER_MATCH = '.*?.*;tag=([^;]*)' + # # Build a scenario based on either a manifest string or a file handle. Manifests are supplied in YAML format. # All manifest keys can be overridden by passing in a Hash of corresponding values. @@ -297,17 +299,31 @@ def receive_invite(opts = { compact_header: false }) recv(opts.merge(request: 'INVITE', rrs: true)) do |recv| action = doc.create_element('action') do |action| action << doc.create_element('ereg') do |ereg| - ereg['regexp'] = '.*.*;tag=([^;]*)' + ereg['regexp'] = SIP_URI_HEADER_MATCH + ereg['search_in'] = 'hdr' + ereg['header'] = 'f:' + ereg['assign_to'] = 'dummy,remote_addr,remote_tag' + end + action << doc.create_element('ereg') do |ereg| + ereg['regexp'] = SIP_URI_HEADER_MATCH ereg['search_in'] = 'hdr' - ereg['header'] = opts[:compact_header] ? 'f:' : 'From:' + ereg['header'] = 'From:' ereg['assign_to'] = 'dummy,remote_addr,remote_tag' end + + action << doc.create_element('ereg') do |ereg| + ereg['regexp'] = '?' + ereg['search_in'] = 'hdr' + ereg['header'] = 't:' + ereg['assign_to'] = 'dummy,local_addr' + end action << doc.create_element('ereg') do |ereg| - ereg['regexp'] = '' + ereg['regexp'] = '?' ereg['search_in'] = 'hdr' - ereg['header'] = opts[:compact_header] ? 't:' : 'To:' + ereg['header'] = 'To:' ereg['assign_to'] = 'dummy,local_addr' end + action << doc.create_element('assignstr') do |assignstr| assignstr['assign_to'] = "call_addr" assignstr['value'] = "[$local_addr]" @@ -507,18 +523,39 @@ def receive_answer(opts = { compact_header: false }) rtd: true # Response Time Duration: Record the response time } + @direction = "outbound" + receive_200(options.merge(opts)) do |recv| recv << doc.create_element('action') do |action| action << doc.create_element('ereg') do |ereg| - ereg['regexp'] = '.*.*;tag=([^;]*)' + ereg['regexp'] = SIP_URI_HEADER_MATCH ereg['search_in'] = 'hdr' - ereg['header'] = opts[:compact_header] ? 'f:' : 'From:' + ereg['header'] = 't:' ereg['assign_to'] = 'dummy,remote_addr,remote_tag' end + action << doc.create_element('ereg') do |ereg| + ereg['regexp'] = SIP_URI_HEADER_MATCH + ereg['search_in'] = 'hdr' + ereg['header'] = 'To:' + ereg['assign_to'] = 'dummy,remote_addr,remote_tag' + end + + action << doc.create_element('ereg') do |ereg| + ereg['regexp'] = SIP_URI_HEADER_MATCH + ereg['search_in'] = 'hdr' + ereg['header'] = 'f:' + ereg['assign_to'] = 'dummy,local_addr,local_tag' + end + action << doc.create_element('ereg') do |ereg| + ereg['regexp'] = SIP_URI_HEADER_MATCH + ereg['search_in'] = 'hdr' + ereg['header'] = 'From:' + ereg['assign_to'] = 'dummy,local_addr,local_tag' + end end end # These variables will only be used if we initiate a hangup - @reference_variables += %w(dummy remote_addr remote_tag) + @reference_variables += %w(dummy remote_addr remote_tag local_addr local_tag) end # @@ -796,10 +833,10 @@ def send_bye(opts = {}) msg = <<-MSG BYE [next_url] SIP/2.0 -Via: SIP/2.0/[transport] #{@adv_ip}:[local_port];rport;branch=[branch] -[routes] -To: "#{@from_user}" ;tag=[$remote_tag] -From: "#{@to_user}" ;tag=[call_number] +[last_Record-Route:] +[last_Via:] +#{@direction == "outbound" ? "To:" : "From:" } sip:[$remote_addr];tag=[$remote_tag] +#{@direction == "outbound" ? "From:" : "To:" } sip:[$local_addr];tag=[call_number] [last_Call-ID:] CSeq: [cseq] BYE Max-Forwards: 100 @@ -810,29 +847,6 @@ def send_bye(opts = {}) send msg, opts end - # - # Send a BYE message using destination of previous messages Contact Header - # - # @param [Hash] opts A set of options to modify the message parameters - # - def send_bye_using_contact(opts = {}) - msg = <<-MSG - -BYE [next_url] SIP/2.0 -Via: SIP/2.0/[transport] #{@adv_ip}:[local_port];rport;branch=[branch] -[routes] -To: "#{@from_user}" ;tag=[$remote_tag] -From: "#{@to_user}" ;tag=[call_number] -[last_Call-ID:] -Contact: -Max-Forwards: 100 -CSeq: [cseq] BYE -User-Agent: #{USER_AGENT} -Content-Length: 0 - MSG - send msg, opts - end - # # Expect to receive a BYE message # diff --git a/spec/sippy_cup/scenario_spec.rb b/spec/sippy_cup/scenario_spec.rb index ec7d335..0dd0178 100644 --- a/spec/sippy_cup/scenario_spec.rb +++ b/spec/sippy_cup/scenario_spec.rb @@ -503,9 +503,9 @@ subject.hangup opts end - it 'calls send_by_using_contact and receive_ok when passed a use_contact option' do + it 'calls send_bye and receive_ok when passed a use_contact option' do opts = { foo: 'bar', use_contact: true } - expect(subject).to receive(:send_bye_using_contact).with({ foo: 'bar' }) + expect(subject).to receive(:send_bye).with({ foo: 'bar' }) expect(subject).to receive(:receive_ok).with({ foo: 'bar' }) subject.hangup opts end From d4113c5faf1c9a7bf672b98ba9dfb75990475813 Mon Sep 17 00:00:00 2001 From: Karn Saheb Date: Fri, 10 Jul 2020 16:22:53 -0400 Subject: [PATCH 05/22] Revert to routes --- lib/sippy_cup/scenario.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/sippy_cup/scenario.rb b/lib/sippy_cup/scenario.rb index 04f3dea..1d5d7a5 100644 --- a/lib/sippy_cup/scenario.rb +++ b/lib/sippy_cup/scenario.rb @@ -833,8 +833,8 @@ def send_bye(opts = {}) msg = <<-MSG BYE [next_url] SIP/2.0 -[last_Record-Route:] -[last_Via:] +Via: SIP/2.0/[transport] #{@adv_ip}:[local_port];rport;branch=[branch] +[routes] #{@direction == "outbound" ? "To:" : "From:" } sip:[$remote_addr];tag=[$remote_tag] #{@direction == "outbound" ? "From:" : "To:" } sip:[$local_addr];tag=[call_number] [last_Call-ID:] From 5fad4c4d0d588962c90799bbfcc0ba0eb59b5f14 Mon Sep 17 00:00:00 2001 From: Karn Saheb Date: Fri, 10 Jul 2020 16:25:01 -0400 Subject: [PATCH 06/22] Use last_via --- lib/sippy_cup/scenario.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/sippy_cup/scenario.rb b/lib/sippy_cup/scenario.rb index 1d5d7a5..15274a9 100644 --- a/lib/sippy_cup/scenario.rb +++ b/lib/sippy_cup/scenario.rb @@ -833,7 +833,7 @@ def send_bye(opts = {}) msg = <<-MSG BYE [next_url] SIP/2.0 -Via: SIP/2.0/[transport] #{@adv_ip}:[local_port];rport;branch=[branch] +[last_Via:] [routes] #{@direction == "outbound" ? "To:" : "From:" } sip:[$remote_addr];tag=[$remote_tag] #{@direction == "outbound" ? "From:" : "To:" } sip:[$local_addr];tag=[call_number] From 1bcafe7499a879165b57ed862bb872c3d58061b9 Mon Sep 17 00:00:00 2001 From: Karn Saheb Date: Fri, 10 Jul 2020 16:28:17 -0400 Subject: [PATCH 07/22] Annotate with direction --- lib/sippy_cup/scenario.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/sippy_cup/scenario.rb b/lib/sippy_cup/scenario.rb index 15274a9..466cdf3 100644 --- a/lib/sippy_cup/scenario.rb +++ b/lib/sippy_cup/scenario.rb @@ -842,6 +842,7 @@ def send_bye(opts = {}) Max-Forwards: 100 #{use_contact ? "Contact: " : ""} User-Agent: #{USER_AGENT} +Subject: #{@direction} Content-Length: 0 MSG send msg, opts From 3ac08e59c869390ed1abc8a47cb2085e6ed38006 Mon Sep 17 00:00:00 2001 From: Karn Saheb Date: Fri, 10 Jul 2020 16:31:30 -0400 Subject: [PATCH 08/22] Use via again --- lib/sippy_cup/scenario.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/sippy_cup/scenario.rb b/lib/sippy_cup/scenario.rb index 466cdf3..8563953 100644 --- a/lib/sippy_cup/scenario.rb +++ b/lib/sippy_cup/scenario.rb @@ -833,7 +833,7 @@ def send_bye(opts = {}) msg = <<-MSG BYE [next_url] SIP/2.0 -[last_Via:] +Via: SIP/2.0/[transport] #{@adv_ip}:[local_port];branch=[branch] [routes] #{@direction == "outbound" ? "To:" : "From:" } sip:[$remote_addr];tag=[$remote_tag] #{@direction == "outbound" ? "From:" : "To:" } sip:[$local_addr];tag=[call_number] @@ -842,7 +842,7 @@ def send_bye(opts = {}) Max-Forwards: 100 #{use_contact ? "Contact: " : ""} User-Agent: #{USER_AGENT} -Subject: #{@direction} +Subject: dir=#{@direction} Content-Length: 0 MSG send msg, opts From 63bab7dcee84efc3628ed8f75795fb976c768b81 Mon Sep 17 00:00:00 2001 From: Karn Saheb Date: Fri, 10 Jul 2020 16:35:24 -0400 Subject: [PATCH 09/22] Annotate with inbound --- lib/sippy_cup/scenario.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/sippy_cup/scenario.rb b/lib/sippy_cup/scenario.rb index 8563953..77115fd 100644 --- a/lib/sippy_cup/scenario.rb +++ b/lib/sippy_cup/scenario.rb @@ -389,6 +389,9 @@ def send_ringing(opts = {}) # def send_answer(opts = {}) opts[:retrans] ||= DEFAULT_RETRANS + + @direction = "inbound" + msg = <<-MSG SIP/2.0 200 OK From a18a01ed3837b8cda96362ecb8c5b3baefe1ad6e Mon Sep 17 00:00:00 2001 From: Karn Saheb Date: Fri, 10 Jul 2020 16:36:36 -0400 Subject: [PATCH 10/22] Fix direction --- lib/sippy_cup/scenario.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/sippy_cup/scenario.rb b/lib/sippy_cup/scenario.rb index 77115fd..8ad8e2e 100644 --- a/lib/sippy_cup/scenario.rb +++ b/lib/sippy_cup/scenario.rb @@ -838,8 +838,8 @@ def send_bye(opts = {}) BYE [next_url] SIP/2.0 Via: SIP/2.0/[transport] #{@adv_ip}:[local_port];branch=[branch] [routes] -#{@direction == "outbound" ? "To:" : "From:" } sip:[$remote_addr];tag=[$remote_tag] -#{@direction == "outbound" ? "From:" : "To:" } sip:[$local_addr];tag=[call_number] +#{@direction == "inbound" ? "To:" : "From:" } sip:[$remote_addr];tag=[$remote_tag] +#{@direction == "inbound" ? "From:" : "To:" } sip:[$local_addr];tag=[call_number] [last_Call-ID:] CSeq: [cseq] BYE Max-Forwards: 100 From 4b2a377b0b22994a1927a913f226b9f218de7b5e Mon Sep 17 00:00:00 2001 From: Karn Saheb Date: Fri, 10 Jul 2020 16:40:25 -0400 Subject: [PATCH 11/22] Use last-via again --- lib/sippy_cup/scenario.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/sippy_cup/scenario.rb b/lib/sippy_cup/scenario.rb index 8ad8e2e..c3b1e4a 100644 --- a/lib/sippy_cup/scenario.rb +++ b/lib/sippy_cup/scenario.rb @@ -836,7 +836,7 @@ def send_bye(opts = {}) msg = <<-MSG BYE [next_url] SIP/2.0 -Via: SIP/2.0/[transport] #{@adv_ip}:[local_port];branch=[branch] +[last_Via:] [routes] #{@direction == "inbound" ? "To:" : "From:" } sip:[$remote_addr];tag=[$remote_tag] #{@direction == "inbound" ? "From:" : "To:" } sip:[$local_addr];tag=[call_number] From 535ad7617e7eb1a5d4212a6c3dfd150b60e18dd0 Mon Sep 17 00:00:00 2001 From: Karn Saheb Date: Fri, 10 Jul 2020 16:50:29 -0400 Subject: [PATCH 12/22] Revert to via --- lib/sippy_cup/scenario.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/sippy_cup/scenario.rb b/lib/sippy_cup/scenario.rb index c3b1e4a..3e686be 100644 --- a/lib/sippy_cup/scenario.rb +++ b/lib/sippy_cup/scenario.rb @@ -836,7 +836,7 @@ def send_bye(opts = {}) msg = <<-MSG BYE [next_url] SIP/2.0 -[last_Via:] +Via: SIP/2.0/[transport] #{@adv_ip}:[local_port];rport;branch=[branch] [routes] #{@direction == "inbound" ? "To:" : "From:" } sip:[$remote_addr];tag=[$remote_tag] #{@direction == "inbound" ? "From:" : "To:" } sip:[$local_addr];tag=[call_number] From 5f14452e2342079ae72e3cadaf64498fe7889886 Mon Sep 17 00:00:00 2001 From: Karn Saheb Date: Fri, 10 Jul 2020 17:02:48 -0400 Subject: [PATCH 13/22] Tweak header parsing --- lib/sippy_cup/scenario.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/sippy_cup/scenario.rb b/lib/sippy_cup/scenario.rb index 3e686be..fd9ade0 100644 --- a/lib/sippy_cup/scenario.rb +++ b/lib/sippy_cup/scenario.rb @@ -16,7 +16,7 @@ class Scenario MSEC = 1_000 DEFAULT_RETRANS = 500 - SIP_URI_HEADER_MATCH = '.*?.*;tag=([^;]*)' + SIP_URI_HEADER_MATCH = '.*;]*)>?.*;tag=([^;]*)' # # Build a scenario based on either a manifest string or a file handle. Manifests are supplied in YAML format. @@ -844,7 +844,6 @@ def send_bye(opts = {}) CSeq: [cseq] BYE Max-Forwards: 100 #{use_contact ? "Contact: " : ""} -User-Agent: #{USER_AGENT} Subject: dir=#{@direction} Content-Length: 0 MSG From 3472815fec783676fe2adf255c7b43a209ed245d Mon Sep 17 00:00:00 2001 From: Karn Saheb Date: Fri, 10 Jul 2020 17:04:52 -0400 Subject: [PATCH 14/22] Tweak header parsing 2 --- lib/sippy_cup/scenario.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/sippy_cup/scenario.rb b/lib/sippy_cup/scenario.rb index fd9ade0..9acb998 100644 --- a/lib/sippy_cup/scenario.rb +++ b/lib/sippy_cup/scenario.rb @@ -312,13 +312,13 @@ def receive_invite(opts = { compact_header: false }) end action << doc.create_element('ereg') do |ereg| - ereg['regexp'] = '?' + ereg['regexp'] = ';]*)>?' ereg['search_in'] = 'hdr' ereg['header'] = 't:' ereg['assign_to'] = 'dummy,local_addr' end action << doc.create_element('ereg') do |ereg| - ereg['regexp'] = '?' + ereg['regexp'] = ';]*)>?' ereg['search_in'] = 'hdr' ereg['header'] = 'To:' ereg['assign_to'] = 'dummy,local_addr' From 0c277f47d091693c92353cc749b7dcf5157bba53 Mon Sep 17 00:00:00 2001 From: Karn Saheb Date: Fri, 10 Jul 2020 17:05:46 -0400 Subject: [PATCH 15/22] Working BYE From 924f91673aa51f4994823e8c24e22edb8290ec97 Mon Sep 17 00:00:00 2001 From: Karn Saheb Date: Wed, 15 Jul 2020 15:06:20 -0400 Subject: [PATCH 16/22] Set to/from correctly in bye --- lib/sippy_cup/scenario.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/sippy_cup/scenario.rb b/lib/sippy_cup/scenario.rb index 9acb998..c18f047 100644 --- a/lib/sippy_cup/scenario.rb +++ b/lib/sippy_cup/scenario.rb @@ -838,8 +838,8 @@ def send_bye(opts = {}) BYE [next_url] SIP/2.0 Via: SIP/2.0/[transport] #{@adv_ip}:[local_port];rport;branch=[branch] [routes] -#{@direction == "inbound" ? "To:" : "From:" } sip:[$remote_addr];tag=[$remote_tag] -#{@direction == "inbound" ? "From:" : "To:" } sip:[$local_addr];tag=[call_number] +To: sip:[$remote_addr];tag=[$remote_tag] +From: sip:[$local_addr];tag=[call_number] [last_Call-ID:] CSeq: [cseq] BYE Max-Forwards: 100 From af088775e94c0c0532153d19a34ad595b637617b Mon Sep 17 00:00:00 2001 From: Karn Saheb Date: Wed, 15 Jul 2020 15:18:01 -0400 Subject: [PATCH 17/22] Fix user busy --- lib/sippy_cup/scenario.rb | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/sippy_cup/scenario.rb b/lib/sippy_cup/scenario.rb index c18f047..6aa2653 100644 --- a/lib/sippy_cup/scenario.rb +++ b/lib/sippy_cup/scenario.rb @@ -604,15 +604,15 @@ def receive_userbusy(opts = {}, &block) ack_msg = <<-BODY -ACK sip:[service]@#{@to_domain} SIP/2.0 -Via: SIP/2.0/[transport] #{@adv_ip}:[local_port];branch=[branch-7] -From: "#{@from_user}" ;tag=[call_number] -To: [peer_tag_param] -Call-ID: [call_id] +ACK [next_url] SIP/2.0 +[last_Via:] +[routes] +[last_From:] +[last_To:] +[last_Call-ID:] CSeq: [cseq] ACK Max-Forwards: 100 Content-Length: 0 -[routes] BODY From fe0cc4ea53e6f8cb5be75ead6abf8cf1e8923864 Mon Sep 17 00:00:00 2001 From: Karn Saheb Date: Wed, 15 Jul 2020 15:22:50 -0400 Subject: [PATCH 18/22] Fix RURI --- lib/sippy_cup/scenario.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/sippy_cup/scenario.rb b/lib/sippy_cup/scenario.rb index 6aa2653..a634bf2 100644 --- a/lib/sippy_cup/scenario.rb +++ b/lib/sippy_cup/scenario.rb @@ -604,8 +604,8 @@ def receive_userbusy(opts = {}, &block) ack_msg = <<-BODY -ACK [next_url] SIP/2.0 -[last_Via:] +ACK sip:#{to_addr} SIP/2.0 +Via: SIP/2.0/[transport] #{@adv_ip}:[local_port];rport;branch=[branch] [routes] [last_From:] [last_To:] From 09afd902cee9048f767f1e077e3113fa13036547 Mon Sep 17 00:00:00 2001 From: Karn Saheb Date: Wed, 15 Jul 2020 15:24:38 -0400 Subject: [PATCH 19/22] Fix RURI --- lib/sippy_cup/scenario.rb | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/sippy_cup/scenario.rb b/lib/sippy_cup/scenario.rb index a634bf2..6175ffb 100644 --- a/lib/sippy_cup/scenario.rb +++ b/lib/sippy_cup/scenario.rb @@ -604,14 +604,15 @@ def receive_userbusy(opts = {}, &block) ack_msg = <<-BODY -ACK sip:#{to_addr} SIP/2.0 -Via: SIP/2.0/[transport] #{@adv_ip}:[local_port];rport;branch=[branch] +ACK sip:#{@to_addr} SIP/2.0 +[last_Via:] [routes] [last_From:] [last_To:] [last_Call-ID:] CSeq: [cseq] ACK -Max-Forwards: 100 +Subject: User Busy Acknowledged +Max-Forwards: 70 Content-Length: 0 BODY From fc77bc498c7c754ef215a7e822220a67a98d5ed9 Mon Sep 17 00:00:00 2001 From: Karn Saheb Date: Wed, 15 Jul 2020 15:26:37 -0400 Subject: [PATCH 20/22] Fix request terminated --- lib/sippy_cup/scenario.rb | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/lib/sippy_cup/scenario.rb b/lib/sippy_cup/scenario.rb index 6175ffb..8d7278c 100644 --- a/lib/sippy_cup/scenario.rb +++ b/lib/sippy_cup/scenario.rb @@ -627,15 +627,16 @@ def receive_request_terminated(opts = {}, &block) ack_msg = <<-BODY -ACK sip:[service]@#{@to_domain} SIP/2.0 -Via: SIP/2.0/[transport] #{@adv_ip}:[local_port];branch=[branch-7] -From: "#{@from_user}" ;tag=[call_number] -To: [peer_tag_param] -Call-ID: [call_id] +ACK sip:#{@to_addr} SIP/2.0 +[last_Via:] +[routes] +[last_From:] +[last_To:] +[last_Call-ID:] CSeq: [cseq] ACK -Max-Forwards: 100 +Subject: Request Terminated Acknowledged +Max-Forwards: 70 Content-Length: 0 -[routes] BODY From 0ba795dadb5b35cc47808f86f6e7a34e04be5b18 Mon Sep 17 00:00:00 2001 From: "mala.sankara" Date: Thu, 6 Aug 2020 12:05:39 -0400 Subject: [PATCH 21/22] Adding 400 failure --- lib/sippy_cup/scenario.rb | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/sippy_cup/scenario.rb b/lib/sippy_cup/scenario.rb index 8d7278c..0ca9232 100644 --- a/lib/sippy_cup/scenario.rb +++ b/lib/sippy_cup/scenario.rb @@ -686,6 +686,11 @@ def ack_answer(opts = {}) start_media end + def content_body_failure(opts = {}) + recv(response: opts[:status_code] || 400, auth:true) + end + alias :receive_400 :content_body_failure + def auth_required(opts = {}) recv(response: opts[:status_code] || 401, auth:true) end From a03d20f6b3839b8a900720de83a67fe49a4b555e Mon Sep 17 00:00:00 2001 From: "mala.sankara" Date: Thu, 6 Aug 2020 16:45:49 -0400 Subject: [PATCH 22/22] Parameterizing sendrecv --- lib/sippy_cup/scenario.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/sippy_cup/scenario.rb b/lib/sippy_cup/scenario.rb index 0ca9232..ac4d26f 100644 --- a/lib/sippy_cup/scenario.rb +++ b/lib/sippy_cup/scenario.rb @@ -12,6 +12,7 @@ module SippyCup # class Scenario USER_AGENT = "SIPp/sippy_cup" + UNHOLD= "sendrecv" VALID_DTMF = %w{0 1 2 3 4 5 6 7 8 9 0 * # A B C D}.freeze MSEC = 1_000 DEFAULT_RETRANS = 500 @@ -183,6 +184,7 @@ def invite(opts = {}) from_addr = "#{@from_user}@#{from_domain || @adv_ip + ":[local_port]"}" max_forwards = opts[:max_forwards] || 100 user_agent = opts[:user_agent].present? ? opts[:user_agent]: USER_AGENT + hold = opts[:hold].present? ? opts[:hold]: UNHOLD msg = <<-MSG INVITE sip:#{to_addr} SIP/2.0 @@ -204,7 +206,7 @@ def invite(opts = {}) t=0 0 m=audio [media_port] RTP/AVP 0 101 a=rtcp-mux -a=sendrecv +a=#{hold} a=rtpmap:0 PCMU/8000 a=rtpmap:101 telephone-event/8000 a=fmtp:101 0-15