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]"
      msg = <<-MSG

INVITE sip:#{to_addr} SIP/2.0
Via: SIP/2.0/[transport] #{@adv_ip}:[local_port];branch=[branch]
From: "#{@from_user}" <sip:#{from_addr}>;tag=[call_number]
To: <sip:#{to_addr}>
Call-ID: [call_id]
CSeq: [cseq] INVITE
Contact: <sip:#{from_addr};transport=[transport]>
Max-Forwards: 100
User-Agent: #{USER_AGENT}
Content-Type: application/sdp
Content-Length: [len]
#{opts.has_key?(:headers) ? opts.delete(:headers).sub(/\n*\Z/, "\n") : ''}
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=rtpmap:0 PCMU/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-15
      MSG
      send msg, opts do |send|
        send << doc.create_element('action') do |action|
          action << doc.create_element('assignstr') do |assignstr|
            assignstr['assign_to'] = "remote_addr"
            assignstr['value']     = to_addr
          end
          action << doc.create_element('assignstr') do |assignstr|
            assignstr['assign_to'] = "local_addr"
            assignstr['value']     = from_addr
          end
          action << doc.create_element('assignstr') do |assignstr|
            assignstr['assign_to'] = "call_addr"
            assignstr['value']     = to_addr
          end
        end
      end
      # These variables will only be used if we initiate a hangup
      @reference_variables += %w(remote_addr local_addr call_addr)
    end
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]"
      msg = <<-MSG

INVITE sip:#{to_addr} SIP/2.0
Via: SIP/2.0/[transport] #{@adv_ip}:[local_port];branch=[branch]
From: "#{@from_user}" <sip:#{from_addr}>;tag=[call_number]
To: <sip:#{to_addr}>
Call-ID: [call_id]
CSeq: [cseq] INVITE
Contact: <sip:#{from_addr};transport=[transport]>
Max-Forwards: 100
User-Agent: #{USER_AGENT}
Content-Type: application/sdp
Content-Length: [len]
#{opts.has_key?(:headers) ? opts.delete(:headers).sub(/\n*\Z/, "\n") : ''}
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=rtpmap:0 PCMU/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-15
      MSG
      send msg, opts do |send|
        send << doc.create_element('action') do |action|
          action << doc.create_element('assignstr') do |assignstr|
            assignstr['assign_to'] = "remote_addr"
            assignstr['value']     = to_addr
          end
          action << doc.create_element('assignstr') do |assignstr|
            assignstr['assign_to'] = "local_addr"
            assignstr['value']     = from_addr
          end
          action << doc.create_element('assignstr') do |assignstr|
            assignstr['assign_to'] = "call_addr"
            assignstr['value']     = to_addr
          end
        end
      end
      # These variables will only be used if we initiate a hangup
      @reference_variables += %w(remote_addr local_addr call_addr)
    end
Send an invite message

 @param [Hash] opts A set of options to modify the message
 @option opts [Integer] :retrans
 @option opts [String] :headers Extra headers to place into the INVITE