opensips-mi 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +15 -0
- data/.gitignore +28 -0
- data/.travis.yml +3 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +275 -0
- data/Rakefile +20 -0
- data/lib/opensips.rb +4 -0
- data/lib/opensips/mi.rb +23 -0
- data/lib/opensips/mi/command.rb +167 -0
- data/lib/opensips/mi/response.rb +122 -0
- data/lib/opensips/mi/transport.rb +10 -0
- data/lib/opensips/mi/transport/datagram.rb +40 -0
- data/lib/opensips/mi/transport/fifo.rb +90 -0
- data/lib/opensips/mi/transport/xmlrpc.rb +43 -0
- data/lib/opensips/mi/version.rb +5 -0
- data/opensips-mi.gemspec +24 -0
- data/test/fixtures/dlg_list +20 -0
- data/test/fixtures/ul_dump +168 -0
- data/test/helper.rb +53 -0
- data/test/test_command.rb +110 -0
- data/test/test_response.rb +101 -0
- data/test/test_transport.rb +187 -0
- metadata +127 -0
@@ -0,0 +1,122 @@
|
|
1
|
+
module Opensips
|
2
|
+
module MI
|
3
|
+
class Response
|
4
|
+
attr_reader :code, :success, :message
|
5
|
+
attr_reader :rawdata # raw data array
|
6
|
+
attr_reader :result # formatted data
|
7
|
+
|
8
|
+
def initialize(data)
|
9
|
+
raise InvalidResponseData,
|
10
|
+
'Invalid parameter' unless data.is_a? Array
|
11
|
+
raise EmptyResponseData,
|
12
|
+
'Empty parameter array' if data.empty?
|
13
|
+
|
14
|
+
if /^(?<code>\d+) (?<message>.+)$/ =~ data.shift.to_s
|
15
|
+
@code = code.to_i
|
16
|
+
@message = message
|
17
|
+
else
|
18
|
+
raise InvalidResponseData,
|
19
|
+
'Invalid response parameter. Can not parse'
|
20
|
+
end
|
21
|
+
|
22
|
+
@success = (200..299).include?(@code)
|
23
|
+
|
24
|
+
# successfull responses have additional new line
|
25
|
+
data.pop if @success
|
26
|
+
@rawdata = data
|
27
|
+
@result = nil
|
28
|
+
end
|
29
|
+
|
30
|
+
# Parse user locations records to Hash
|
31
|
+
def ul_dump
|
32
|
+
return nil unless /^Domain:: location table=\d+ records=(\d+)$/ =~ @rawdata.shift
|
33
|
+
records = Hash.new
|
34
|
+
aor = ''
|
35
|
+
@rawdata.each do |r|
|
36
|
+
if /\tAOR:: (?<peer>.+)$/ =~ r
|
37
|
+
aor = peer
|
38
|
+
records[aor] = Hash.new
|
39
|
+
end
|
40
|
+
if /^\t{2,3}(?<key>[^:]+):: (?<val>.*)$/ =~ r
|
41
|
+
records[aor][key] = val if aor
|
42
|
+
end
|
43
|
+
end
|
44
|
+
@result = records
|
45
|
+
self
|
46
|
+
end
|
47
|
+
|
48
|
+
# returns struct
|
49
|
+
def uptime
|
50
|
+
res = Hash.new
|
51
|
+
@rawdata.each do |r|
|
52
|
+
next if /^Now::/ =~ r
|
53
|
+
if /^Up since:: [^\s]+ (?'mon'[^\s]+)\s+(?'d'\d+) (?'h'\d+):(?'m'\d+):(?'s'\d+) (?'y'\d+)/ =~ r
|
54
|
+
res[:since] = Time.local(y,mon,d,h,m,s)
|
55
|
+
end
|
56
|
+
if /^Up time:: (?'sec'\d+) / =~ r
|
57
|
+
res[:uptime] = sec.to_i
|
58
|
+
end
|
59
|
+
end
|
60
|
+
@result = OpenStruct.new res
|
61
|
+
self
|
62
|
+
end
|
63
|
+
|
64
|
+
# returns struct
|
65
|
+
def cache_fetch
|
66
|
+
res = Hash.new
|
67
|
+
@rawdata.each do |r|
|
68
|
+
if /^(?'label'[^=]+)=\s+\[(?'value'[^\]]+)\]/ =~ r
|
69
|
+
label.strip!
|
70
|
+
res[label.to_sym] = value
|
71
|
+
end
|
72
|
+
end
|
73
|
+
@result = OpenStruct.new res
|
74
|
+
self
|
75
|
+
end
|
76
|
+
|
77
|
+
# returns Array of registered contacts
|
78
|
+
def ul_show_contact
|
79
|
+
res = Array.new
|
80
|
+
@rawdata.each do |r|
|
81
|
+
cont = Hash.new
|
82
|
+
r.split(?;).each do |rec|
|
83
|
+
if /^Contact:: (.*)$/ =~ rec
|
84
|
+
cont[:contact] = $1
|
85
|
+
else
|
86
|
+
key,val = rec.split ?=
|
87
|
+
cont[key.to_sym] = val
|
88
|
+
end
|
89
|
+
end
|
90
|
+
res << cont
|
91
|
+
end
|
92
|
+
@result = res
|
93
|
+
self
|
94
|
+
end
|
95
|
+
|
96
|
+
# returns hash of dialogs
|
97
|
+
def dlg_list
|
98
|
+
# parse dialogs information into array
|
99
|
+
# assuming new block always starts with "dialog:: hash=..."
|
100
|
+
calls, key = Hash.new, nil
|
101
|
+
@rawdata.each do |l|
|
102
|
+
l.strip!
|
103
|
+
if l.match(/^dialog::\s+hash=(.*)$/)
|
104
|
+
key = $1
|
105
|
+
calls[key] = Hash.new
|
106
|
+
next
|
107
|
+
end
|
108
|
+
# building dialog array
|
109
|
+
if l.match(/^([^:]+)::\s+(.*)$/)
|
110
|
+
calls[key][$1.to_sym] = $2
|
111
|
+
end
|
112
|
+
end
|
113
|
+
@result = calls
|
114
|
+
self
|
115
|
+
end
|
116
|
+
|
117
|
+
end
|
118
|
+
|
119
|
+
class InvalidResponseData < Exception;end
|
120
|
+
class EmptyResponseData < Exception;end
|
121
|
+
end
|
122
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Opensips
|
2
|
+
module MI
|
3
|
+
module Transport
|
4
|
+
class Datagram < Opensips::MI::Command
|
5
|
+
RECVMAXLEN = 2**16 - 1
|
6
|
+
|
7
|
+
class << self
|
8
|
+
def init(params)
|
9
|
+
Datagram.new params
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize(params)
|
14
|
+
raise ArgumentError,
|
15
|
+
'Missing socket host' if params[:host].nil?
|
16
|
+
raise ArgumentError,
|
17
|
+
'Missing socket port' if params[:port].nil?
|
18
|
+
Socket.getaddrinfo(params[:host], nil) rescue
|
19
|
+
raise SocketError, "Invalid host #{params[:host]}"
|
20
|
+
raise SocketError,
|
21
|
+
"Invalid port #{params[:port]}" unless (1..(2**16-1)).include?(params[:port])
|
22
|
+
@sock = UDPSocket.new
|
23
|
+
@sock.connect params[:host], params[:port]
|
24
|
+
end
|
25
|
+
|
26
|
+
def command(cmd, params = [])
|
27
|
+
request = ":#{cmd}:\n"
|
28
|
+
params.each do |c|
|
29
|
+
request << "#{c}\n"
|
30
|
+
end
|
31
|
+
@sock.send request, 0
|
32
|
+
# will raise Errno::ECONNREFUSED if failed to connect
|
33
|
+
response, = @sock.recvfrom RECVMAXLEN
|
34
|
+
Opensips::MI::Response.new response.split(?\n)
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
module Opensips
|
2
|
+
module MI
|
3
|
+
module Transport
|
4
|
+
class Fifo < Opensips::MI::Command
|
5
|
+
PERMISIONS = '0666'
|
6
|
+
attr_accessor :reply_fifo # name of the reply fifo file
|
7
|
+
attr_accessor :fifo_name # OpenSIPs fifo file. See mi_fifo module
|
8
|
+
attr_accessor :reply_dir # path to directory with where the reply fif is located
|
9
|
+
|
10
|
+
class << self
|
11
|
+
def init(params)
|
12
|
+
fifo = Fifo.new params
|
13
|
+
fifo.open
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def initialize(params)
|
18
|
+
# set default values
|
19
|
+
@reply_fifo = if params[:reply_fifo].nil?
|
20
|
+
"opensips_reply_" << Digest::MD5.hexdigest(rand.to_s)[0,8]
|
21
|
+
else
|
22
|
+
@reply_fifo = params[:reply_fifo]
|
23
|
+
end
|
24
|
+
|
25
|
+
@reply_dir = if params[:reply_dir].nil?
|
26
|
+
'/tmp/'
|
27
|
+
else
|
28
|
+
params[:reply_dir]
|
29
|
+
end
|
30
|
+
raise ArgumentError,
|
31
|
+
"Fifo reply directory does not exists #{@reply_dir}" unless Dir.exists? @reply_dir
|
32
|
+
|
33
|
+
# fifo_name is required parameter
|
34
|
+
raise ArgumentError,
|
35
|
+
'Missing required parameter fifo_name' if params[:fifo_name].nil?
|
36
|
+
|
37
|
+
@fifo_name = params[:fifo_name]
|
38
|
+
raise ArgumentError,
|
39
|
+
"OpenSIPs fifo_name file does not exist: #{@fifo_name}" unless File.exists? @fifo_name
|
40
|
+
raise ArgumentError,
|
41
|
+
"File #{@fifo_name} is not pipe" unless File.pipe? @fifo_name
|
42
|
+
|
43
|
+
# set finalizing method
|
44
|
+
reply_file = File.expand_path(@reply_fifo, @reply_dir)
|
45
|
+
ObjectSpace.define_finalizer(self, proc{self.class.finalize(reply_file)})
|
46
|
+
end
|
47
|
+
|
48
|
+
def open
|
49
|
+
# create fifo file
|
50
|
+
fifo_file = File.expand_path(@reply_fifo, @reply_dir)
|
51
|
+
Kernel.system "mkfifo -m #{PERMISIONS} #{fifo_file}"
|
52
|
+
raise SystemCallError,
|
53
|
+
"Can not create reply pipe: #{fifo_file}" unless File.pipe?(fifo_file)
|
54
|
+
self
|
55
|
+
end
|
56
|
+
|
57
|
+
def command(cmd, params = [])
|
58
|
+
fd_w = IO::sysopen(@fifo_name, Fcntl::O_WRONLY)
|
59
|
+
fifo_w = IO.open(fd_w)
|
60
|
+
|
61
|
+
request = ":#{cmd}:#{@reply_fifo}\n"
|
62
|
+
params.each do |c|
|
63
|
+
request << "#{c}\n"
|
64
|
+
end
|
65
|
+
# additional new line to terminate command
|
66
|
+
request << ?\n
|
67
|
+
fifo_w.syswrite request
|
68
|
+
|
69
|
+
# read response
|
70
|
+
file = File.expand_path(File.expand_path(@reply_fifo,@reply_dir))
|
71
|
+
fd_r = IO::sysopen(file, Fcntl::O_RDONLY )
|
72
|
+
fifo_r = IO.open(fd_r)
|
73
|
+
|
74
|
+
response = Array[]
|
75
|
+
response << $_.chomp while fifo_r.gets
|
76
|
+
Opensips::MI::Response.new response
|
77
|
+
ensure
|
78
|
+
# make sure we always close files' descriptors
|
79
|
+
fifo_r.close if fifo_r
|
80
|
+
fifo_w.close if fifo_w
|
81
|
+
end
|
82
|
+
|
83
|
+
def self.finalize(reply_file)
|
84
|
+
File.unlink(reply_file) if File.exists?(reply_file)
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module Opensips
|
2
|
+
module MI
|
3
|
+
module Transport
|
4
|
+
class Xmlrpc < Opensips::MI::Command
|
5
|
+
RPCSEG = 'RPC2'
|
6
|
+
class << self
|
7
|
+
def init(params)
|
8
|
+
Xmlrpc.new params
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def initialize(params)
|
13
|
+
raise ArgumentError,
|
14
|
+
'Missing socket host' if params[:host].nil?
|
15
|
+
raise ArgumentError,
|
16
|
+
'Missing socket port' if params[:port].nil?
|
17
|
+
Socket.getaddrinfo(params[:host], nil) rescue
|
18
|
+
raise SocketError, "Invalid host #{params[:host]}"
|
19
|
+
raise SocketError,
|
20
|
+
"Invalid port #{params[:port]}" unless (1..(2**16-1)).include?(params[:port])
|
21
|
+
uri = "http://#{params[:host]}:#{params[:port]}/#{RPCSEG}"
|
22
|
+
@client = XMLRPC::Client.new_from_uri(uri, nil, 3)
|
23
|
+
rescue => e
|
24
|
+
raise e.class,
|
25
|
+
"Can not connect OpenSIPs server.\n#{e.message}"
|
26
|
+
end
|
27
|
+
|
28
|
+
def command(cmd, params = [])
|
29
|
+
response = ["200 OK"]
|
30
|
+
response += @client.call(cmd, *params).split(?\n)
|
31
|
+
response << ""
|
32
|
+
Opensips::MI::Response.new response
|
33
|
+
rescue => e
|
34
|
+
response = ["600 " << e.message]
|
35
|
+
Opensips::MI::Response.new response
|
36
|
+
end
|
37
|
+
|
38
|
+
def set_header(header);header;end
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
data/opensips-mi.gemspec
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'opensips/mi/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "opensips-mi"
|
8
|
+
gem.version = Opensips::MI::VERSION
|
9
|
+
gem.authors = ["Stas Kobzar"]
|
10
|
+
gem.email = ["stas@modulis.ca"]
|
11
|
+
gem.description = %q{Ruby module for interacting with OpenSIPs management interface}
|
12
|
+
gem.summary = %q{OpenSIPs management interface}
|
13
|
+
gem.homepage = "http://github.com/staskobzar/opensips-mi"
|
14
|
+
|
15
|
+
gem.files = `git ls-files`.split($/).reject{|f| %r|^examples/.*|.match f}
|
16
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
17
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
|
+
gem.require_paths = ["lib"]
|
19
|
+
|
20
|
+
gem.add_development_dependency('bundler', '~> 1.3')
|
21
|
+
gem.add_development_dependency('rdoc')
|
22
|
+
gem.add_development_dependency('rake')
|
23
|
+
gem.add_development_dependency('mocha')
|
24
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
200 OK
|
2
|
+
dialog:: hash=3212:2099935485
|
3
|
+
state:: 4
|
4
|
+
user_flags:: 0
|
5
|
+
timestart:: 1365817158
|
6
|
+
timeout:: 1365824358
|
7
|
+
callid:: 1854719653
|
8
|
+
from_uri:: sip:7747@voip.etsmtl.ca
|
9
|
+
to_uri:: sip:95142842020@voip.etsmtl.ca
|
10
|
+
caller_tag:: 1614235294
|
11
|
+
caller_contact:: sip:7747@10.130.8.100
|
12
|
+
callee_cseq:: 0
|
13
|
+
caller_route_set::
|
14
|
+
caller_bind_addr:: udp:10.130.8.21:5060
|
15
|
+
callee_tag:: as2e60b080
|
16
|
+
callee_contact:: sip:95142842020@10.130.8.240:5060
|
17
|
+
caller_cseq:: 20
|
18
|
+
callee_route_set::
|
19
|
+
callee_bind_addr:: udp:10.130.8.21:5060
|
20
|
+
|
@@ -0,0 +1,168 @@
|
|
1
|
+
200 OK
|
2
|
+
Domain:: location table=512 records=15
|
3
|
+
AOR:: 7962
|
4
|
+
Contact:: sip:7962@10.164.112.13 Q=
|
5
|
+
Expires:: 143
|
6
|
+
Callid:: 5e7a1e47da91c41c
|
7
|
+
Cseq:: 31401
|
8
|
+
User-agent:: Avaya IP Phone 1120E (SIP1120e.04.03.12.00)
|
9
|
+
State:: CS_SYNC
|
10
|
+
Flags:: 0
|
11
|
+
Cflag:: 0
|
12
|
+
Socket:: udp:10.130.8.21:5060
|
13
|
+
Methods:: 7551
|
14
|
+
AOR:: 7329
|
15
|
+
Contact:: sip:7329@10.132.113.171 Q=
|
16
|
+
Expires:: 95
|
17
|
+
Callid:: 504e5ee5baf3e7d8
|
18
|
+
Cseq:: 10412
|
19
|
+
User-agent:: Avaya IP Phone 1120E (SIP1120e.04.03.12.00)
|
20
|
+
State:: CS_SYNC
|
21
|
+
Flags:: 0
|
22
|
+
Cflag:: 0
|
23
|
+
Socket:: udp:10.130.8.21:5060
|
24
|
+
Methods:: 7551
|
25
|
+
AOR:: 7863
|
26
|
+
Contact:: sip:7863@10.132.113.172 Q=
|
27
|
+
Expires:: 142
|
28
|
+
Callid:: d808729f9d47ec2d
|
29
|
+
Cseq:: 28091
|
30
|
+
User-agent:: Avaya IP Phone 1120E (SIP1120e.04.03.12.00)
|
31
|
+
State:: CS_SYNC
|
32
|
+
Flags:: 0
|
33
|
+
Cflag:: 0
|
34
|
+
Socket:: udp:10.130.8.21:5060
|
35
|
+
Methods:: 7551
|
36
|
+
AOR:: 3812
|
37
|
+
Contact:: sip:3812@10.132.113.163 Q=
|
38
|
+
Expires:: 58
|
39
|
+
Callid:: a59c4a46f79d7317
|
40
|
+
Cseq:: 19050
|
41
|
+
User-agent:: Avaya IP Phone 1120E (SIP1120e.04.03.12.00)
|
42
|
+
State:: CS_SYNC
|
43
|
+
Flags:: 0
|
44
|
+
Cflag:: 0
|
45
|
+
Socket:: udp:10.130.8.21:5060
|
46
|
+
Methods:: 7551
|
47
|
+
AOR:: 3810
|
48
|
+
Contact:: sip:3810@10.132.113.166 Q=
|
49
|
+
Expires:: 87
|
50
|
+
Callid:: dd38e788e386a79d
|
51
|
+
Cseq:: 18259
|
52
|
+
User-agent:: Avaya IP Phone 1140E (SIP1140e.04.03.12.00)
|
53
|
+
State:: CS_SYNC
|
54
|
+
Flags:: 0
|
55
|
+
Cflag:: 0
|
56
|
+
Socket:: udp:10.130.8.21:5060
|
57
|
+
Methods:: 7551
|
58
|
+
AOR:: 7519
|
59
|
+
Contact:: sip:7519@10.132.113.174 Q=
|
60
|
+
Expires:: 63
|
61
|
+
Callid:: f0a2566a33a42295
|
62
|
+
Cseq:: 28149
|
63
|
+
User-agent:: Avaya IP Phone 1120E (SIP1120e.04.03.12.00)
|
64
|
+
State:: CS_SYNC
|
65
|
+
Flags:: 0
|
66
|
+
Cflag:: 0
|
67
|
+
Socket:: udp:10.130.8.21:5060
|
68
|
+
Methods:: 7551
|
69
|
+
AOR:: 7259
|
70
|
+
Contact:: sip:7259@10.164.112.18 Q=
|
71
|
+
Expires:: 32
|
72
|
+
Callid:: 7f0d07e8c1415bbc
|
73
|
+
Cseq:: 32493
|
74
|
+
User-agent:: Avaya IP Phone 1120E (SIP1120e.04.03.12.00)
|
75
|
+
State:: CS_SYNC
|
76
|
+
Flags:: 0
|
77
|
+
Cflag:: 0
|
78
|
+
Socket:: udp:10.130.8.21:5060
|
79
|
+
Methods:: 7551
|
80
|
+
AOR:: 7577
|
81
|
+
Contact:: sip:7577@10.132.113.178 Q=
|
82
|
+
Expires:: 159
|
83
|
+
Callid:: 5eca2b3d1062416b
|
84
|
+
Cseq:: 12767
|
85
|
+
User-agent:: Avaya IP Phone 1140E (SIP1140e.04.03.12.00)
|
86
|
+
State:: CS_SYNC
|
87
|
+
Flags:: 0
|
88
|
+
Cflag:: 0
|
89
|
+
Socket:: udp:10.130.8.21:5060
|
90
|
+
Methods:: 7551
|
91
|
+
AOR:: 3901
|
92
|
+
Contact:: sip:3901@10.132.113.160 Q=
|
93
|
+
Expires:: 132
|
94
|
+
Callid:: a57d709ba8c7d6d7
|
95
|
+
Cseq:: 27476
|
96
|
+
User-agent:: Avaya IP Phone 1120E (SIP1120e.04.03.12.00)
|
97
|
+
State:: CS_SYNC
|
98
|
+
Flags:: 0
|
99
|
+
Cflag:: 0
|
100
|
+
Socket:: udp:10.130.8.21:5060
|
101
|
+
Methods:: 7551
|
102
|
+
AOR:: 7806
|
103
|
+
Contact:: sip:7806@10.132.113.175 Q=
|
104
|
+
Expires:: 132
|
105
|
+
Callid:: 0fb4baf2782a89b3
|
106
|
+
Cseq:: 23944
|
107
|
+
User-agent:: Avaya IP Phone 1120E (SIP1120e.04.03.12.00)
|
108
|
+
State:: CS_SYNC
|
109
|
+
Flags:: 0
|
110
|
+
Cflag:: 0
|
111
|
+
Socket:: udp:10.130.8.21:5060
|
112
|
+
Methods:: 7551
|
113
|
+
AOR:: 7402
|
114
|
+
Contact:: sip:7402@10.132.113.168 Q=
|
115
|
+
Expires:: 47981
|
116
|
+
Callid:: ef8fa87d63302751
|
117
|
+
Cseq:: 13537
|
118
|
+
User-agent:: Avaya IP Phone 1120E (SIP1120e.04.03.12.00)
|
119
|
+
State:: CS_SYNC
|
120
|
+
Flags:: 0
|
121
|
+
Cflag:: 0
|
122
|
+
Socket:: udp:10.130.8.21:5060
|
123
|
+
Methods:: 7551
|
124
|
+
AOR:: 3822
|
125
|
+
Contact:: sip:3822@10.132.113.162 Q=
|
126
|
+
Expires:: 97
|
127
|
+
Callid:: f534f0b8d8a070e7
|
128
|
+
Cseq:: 50129
|
129
|
+
User-agent:: Avaya IP Phone 1220 (SIP12x0.04.03.12.00)
|
130
|
+
State:: CS_SYNC
|
131
|
+
Flags:: 0
|
132
|
+
Cflag:: 0
|
133
|
+
Socket:: udp:10.130.8.21:5060
|
134
|
+
Methods:: 7551
|
135
|
+
AOR:: 7641
|
136
|
+
Contact:: sip:7641@10.164.112.28 Q=
|
137
|
+
Expires:: 98
|
138
|
+
Callid:: df0f22a80302737a
|
139
|
+
Cseq:: 33571
|
140
|
+
User-agent:: Avaya IP Phone 1140E (SIP1140e.04.03.12.00)
|
141
|
+
State:: CS_SYNC
|
142
|
+
Flags:: 0
|
143
|
+
Cflag:: 0
|
144
|
+
Socket:: udp:10.130.8.21:5060
|
145
|
+
Methods:: 7551
|
146
|
+
AOR:: 7423
|
147
|
+
Contact:: sip:7423@10.164.113.25 Q=
|
148
|
+
Expires:: 109
|
149
|
+
Callid:: ab10dabda2f0f257
|
150
|
+
Cseq:: 39074
|
151
|
+
User-agent:: Avaya IP Phone 1120E (SIP1120e.04.03.12.00)
|
152
|
+
State:: CS_SYNC
|
153
|
+
Flags:: 0
|
154
|
+
Cflag:: 0
|
155
|
+
Socket:: udp:10.130.8.21:5060
|
156
|
+
Methods:: 7551
|
157
|
+
AOR:: 7747
|
158
|
+
Contact:: sip:7747@10.132.113.198 Q=
|
159
|
+
Expires:: 69
|
160
|
+
Callid:: 8c026d6f-9afd173e-c4d03305@10.132.113.198
|
161
|
+
Cseq:: 41286
|
162
|
+
User-agent:: PolycomSoundStationIP-SSIP_6000-UA/3.3.5.0247_0004f2f18103
|
163
|
+
State:: CS_SYNC
|
164
|
+
Flags:: 0
|
165
|
+
Cflag:: 0
|
166
|
+
Socket:: udp:10.130.8.21:5060
|
167
|
+
Methods:: 8063
|
168
|
+
|