opensips-mi 0.0.11 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,5 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Opensips
2
4
  module MI
3
- VERSION = "0.0.11"
5
+ VERSION = "1.1.0"
4
6
  end
5
7
  end
data/lib/opensips/mi.rb CHANGED
@@ -1,22 +1,28 @@
1
- require 'ostruct'
2
- require 'fcntl'
3
- require 'securerandom'
4
- require 'socketry'
5
- require 'xmlrpc/client'
1
+ # frozen_string_literal: true
6
2
 
7
3
  require "opensips/mi/version"
8
- require "opensips/mi/response"
9
4
  require "opensips/mi/command"
10
5
  require "opensips/mi/transport"
11
6
 
12
7
  module Opensips
8
+ # OpenSIPS Managemen Interface core module
13
9
  module MI
14
- def self.connect(transport, params)
15
- # send to transport class
16
- Transport.const_get(transport.to_s.capitalize).init params
17
- rescue NameError
18
- raise NameError, "Unknown transport method: " << transport.to_s
10
+ class Error < StandardError; end
11
+ class ErrorHTTPReq < Error; end
12
+ class ErrorParams < Error; end
13
+ class ErrorResolveTimeout < Error; end
14
+ class ErrorSendTimeout < Error; end
15
+
16
+ def self.connect(transport_proto, params = {})
17
+ transp = case transport_proto
18
+ when :datagram then Transport::Datagram.new(params)
19
+ when :fifo then Transport::Fifo.new(params)
20
+ when :http then Transport::HTTP.new(params)
21
+ when :xmlrpc then Transport::Xmlrpc.new(params)
22
+ else
23
+ raise Error, "Unknown transport method: #{transport_proto}"
24
+ end
25
+ Command.new(transp)
19
26
  end
20
27
  end
21
28
  end
22
-
data/lib/opensips.rb CHANGED
@@ -1,4 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "opensips/mi"
2
4
 
5
+ # Ruby module to connect OpenSIPS Management Interface
6
+ # to send commands and read responses
3
7
  module Opensips
4
8
  end
@@ -0,0 +1,6 @@
1
+ module Opensips
2
+ module Mi
3
+ VERSION: String
4
+ # See the writing guide of rbs: https://github.com/ruby/rbs#guides
5
+ end
6
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: opensips-mi
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.11
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stas Kobzar
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-04-27 00:00:00.000000000 Z
11
+ date: 2023-08-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: xmlrpc
@@ -24,72 +24,16 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0.3'
27
- - !ruby/object:Gem::Dependency
28
- name: socketry
29
- requirement: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - "~>"
32
- - !ruby/object:Gem::Version
33
- version: '0.5'
34
- type: :runtime
35
- prerelease: false
36
- version_requirements: !ruby/object:Gem::Requirement
37
- requirements:
38
- - - "~>"
39
- - !ruby/object:Gem::Version
40
- version: '0.5'
41
- - !ruby/object:Gem::Dependency
42
- name: bundler
43
- requirement: !ruby/object:Gem::Requirement
44
- requirements:
45
- - - ">="
46
- - !ruby/object:Gem::Version
47
- version: '0'
48
- type: :development
49
- prerelease: false
50
- version_requirements: !ruby/object:Gem::Requirement
51
- requirements:
52
- - - ">="
53
- - !ruby/object:Gem::Version
54
- version: '0'
55
- - !ruby/object:Gem::Dependency
56
- name: rake
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - ">="
60
- - !ruby/object:Gem::Version
61
- version: '0'
62
- type: :development
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - ">="
67
- - !ruby/object:Gem::Version
68
- version: '0'
69
- - !ruby/object:Gem::Dependency
70
- name: rspec
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - ">="
74
- - !ruby/object:Gem::Version
75
- version: '0'
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - ">="
81
- - !ruby/object:Gem::Version
82
- version: '0'
83
- description: Ruby module for interacting with OpenSIPs management interface
27
+ description: Ruby module for interacting with OpenSIPs management interface. Supports
28
+ OpenSIPS v3+ MI with JSON-RPC protocol
84
29
  email:
85
30
  - staskobzar@gmail.com
86
31
  executables: []
87
32
  extensions: []
88
33
  extra_rdoc_files: []
89
34
  files:
90
- - ".gitignore"
91
- - ".rspec"
92
- - ".travis.yml"
35
+ - CODE_OF_CONDUCT.md
36
+ - CONTRIBUTING.md
93
37
  - Gemfile
94
38
  - LICENSE.txt
95
39
  - README.md
@@ -97,23 +41,23 @@ files:
97
41
  - lib/opensips.rb
98
42
  - lib/opensips/mi.rb
99
43
  - lib/opensips/mi/command.rb
100
- - lib/opensips/mi/response.rb
101
44
  - lib/opensips/mi/transport.rb
45
+ - lib/opensips/mi/transport/abstract.rb
102
46
  - lib/opensips/mi/transport/datagram.rb
103
47
  - lib/opensips/mi/transport/fifo.rb
48
+ - lib/opensips/mi/transport/http.rb
104
49
  - lib/opensips/mi/transport/xmlrpc.rb
105
50
  - lib/opensips/mi/version.rb
106
- - opensips-mi.gemspec
107
- - spec/command_spec.rb
108
- - spec/fixtures/dlg_list
109
- - spec/fixtures/ul_dump
110
- - spec/response_spec.rb
111
- - spec/spec_helper.rb
112
- - spec/transport_spec.rb
113
- homepage: http://github.com/staskobzar/opensips-mi
51
+ - sig/opensips/mi.rbs
52
+ homepage: https://github.com/staskobzar/opensips-mi
114
53
  licenses:
115
54
  - MIT
116
- metadata: {}
55
+ metadata:
56
+ allowed_push_host: https://rubygems.org
57
+ homepage_uri: https://github.com/staskobzar/opensips-mi
58
+ source_code_uri: https://github.com/staskobzar/opensips-mi
59
+ changelog_uri: https://github.com/staskobzar/opensips-mi/releases
60
+ github_repo: https://github.com/staskobzar/opensips-mi.git
117
61
  post_install_message:
118
62
  rdoc_options: []
119
63
  require_paths:
@@ -122,21 +66,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
122
66
  requirements:
123
67
  - - ">="
124
68
  - !ruby/object:Gem::Version
125
- version: '0'
69
+ version: 3.0.0
126
70
  required_rubygems_version: !ruby/object:Gem::Requirement
127
71
  requirements:
128
72
  - - ">="
129
73
  - !ruby/object:Gem::Version
130
74
  version: '0'
131
75
  requirements: []
132
- rubygems_version: 3.0.3
76
+ rubygems_version: 3.4.18
133
77
  signing_key:
134
78
  specification_version: 4
135
- summary: OpenSIPs management interface
136
- test_files:
137
- - spec/command_spec.rb
138
- - spec/fixtures/dlg_list
139
- - spec/fixtures/ul_dump
140
- - spec/response_spec.rb
141
- - spec/spec_helper.rb
142
- - spec/transport_spec.rb
79
+ summary: Ruby OpenSIPs management interface
80
+ test_files: []
data/.gitignore DELETED
@@ -1,30 +0,0 @@
1
- # Ignore temporary files
2
- .*swp
3
- *~
4
-
5
- *.gem
6
- *.rbc
7
- Gemfile*.lock
8
- .bundle
9
- .config
10
- .byebug_history
11
- coverage
12
- log
13
- InstalledFiles
14
- lib/bundler/man
15
- pkg
16
- rdoc
17
- spec/reports
18
- test/tmp
19
- test/version_tmp
20
- tmp
21
-
22
- # YARD artifacts
23
- .yardoc
24
- _yardoc
25
- doc/
26
-
27
- .DS_Store
28
- results.html
29
- html
30
-
data/.rspec DELETED
@@ -1 +0,0 @@
1
- --require spec_helper
data/.travis.yml DELETED
@@ -1,3 +0,0 @@
1
- language: ruby
2
- rvm:
3
- - 2.6.3
@@ -1,176 +0,0 @@
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
- @rawdata = data
26
- @result = nil
27
- end
28
-
29
- # Parse user locations records to Hash
30
- def ul_dump
31
- res = {}
32
- aor = nil
33
- contact = nil
34
-
35
- @rawdata.each do |r|
36
- next if r.start_with?("Domain")
37
- r = r.strip
38
- key, val = r.split(":: ")
39
-
40
- if key == "AOR"
41
- aor = val
42
- res[aor] = []
43
- next
44
- elsif key == "Contact"
45
- contact = {}
46
- res[aor] << contact
47
- end
48
-
49
- contact[key.gsub(?-, ?_).downcase.to_sym] = val if key
50
- end
51
-
52
- @result = res
53
- self
54
- end
55
-
56
- # returns struct
57
- def uptime
58
- res = Hash.new
59
- @rawdata.each do |r|
60
- next if /^Now::/ =~ r
61
- if /^Up since:: [^\s]+ (?'mon'[^\s]+)\s+(?'d'\d+) (?'h'\d+):(?'m'\d+):(?'s'\d+) (?'y'\d+)/ =~ r
62
- res[:since] = Time.local(y,mon,d,h,m,s)
63
- end
64
- if /^Up time:: (?'sec'\d+) / =~ r
65
- res[:uptime] = sec.to_i
66
- end
67
- end
68
- @result = OpenStruct.new res
69
- self
70
- end
71
-
72
- # returns struct
73
- def cache_fetch
74
- res = Hash.new
75
- @rawdata.each do |r|
76
- if /^(?'label'[^=]+)=\s+\[(?'value'[^\]]+)\]/ =~ r
77
- label.strip!
78
- res[label.to_sym] = value
79
- end
80
- end
81
- @result = OpenStruct.new res
82
- self
83
- end
84
-
85
- # returns Array of registered contacts
86
- def ul_show_contact
87
- result = []
88
- @rawdata.each do |r|
89
- _, contact = r.strip.split("Contact:: ")
90
- next unless contact
91
-
92
- params = contact.split(';')
93
-
94
- res = {contact: params.shift}
95
-
96
- params.each do |p|
97
- key, val = p.split('=')
98
- res[key.gsub(?-, ?_).downcase.to_sym] = val
99
- end
100
- result << res
101
- end
102
- @result = result
103
- end
104
-
105
- # returns hash of dialogs
106
- def dlg_list
107
- # parse dialogs information into array
108
- # assuming new block always starts with "dialog:: hash=..."
109
- calls, key = Hash.new, nil
110
- @rawdata.each do |l|
111
- l.strip!
112
- if l.match(/^dialog::\s+hash=(.*)$/)
113
- key = $1
114
- calls[key] = Hash.new
115
- next
116
- end
117
- # building dialog array
118
- if l.match(/^([^:]+)::\s+(.*)$/)
119
- calls[key][$1.to_sym] = $2
120
- end
121
- end
122
- @result = calls
123
- self
124
- end
125
-
126
- def dr_gw_status
127
- return self if @rawdata.empty?
128
- if /\AEnabled::\s+(?<status>yes|no)/ =~ @rawdata[0]
129
- self.class.send(:define_method, :enabled, proc{status.eql?('yes')})
130
- return self
131
- end
132
- @result = dr_gws_hash
133
- self
134
- end
135
-
136
- # returns array containing list of opensips processes
137
- def ps
138
- processes = []
139
- @rawdata.each do |l|
140
- l.slice! "Process:: "
141
- h = {}
142
-
143
- l.split(" ", 3).each do |x|
144
- key, val = x.split("=", 2)
145
- h[key.downcase.to_sym] = val
146
- end
147
-
148
- processes << OpenStruct.new(h)
149
- end
150
-
151
- @result = processes
152
- self
153
- end
154
-
155
- private
156
- def dr_gws_hash
157
- return nil if @rawdata.empty?
158
- res = {}
159
- @rawdata.map do |gw|
160
- if /\AID::\s+(?<id>[^\s]+)\s+IP=(?<ip>[^:\s]+):?(?<port>\d+)?\s+Enabled=(?<status>yes|no)/ =~ gw
161
- res[id] = {
162
- enabled: status.eql?('yes'),
163
- ipaddr: ip,
164
- port: port
165
- }
166
- end
167
- end
168
- res.empty? ? nil : res
169
- end
170
-
171
- end # END class
172
-
173
- class InvalidResponseData < Exception;end
174
- class EmptyResponseData < Exception;end
175
- end
176
- end
data/opensips-mi.gemspec DELETED
@@ -1,26 +0,0 @@
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 |spec|
7
- spec.name = "opensips-mi"
8
- spec.version = Opensips::MI::VERSION
9
- spec.licenses = ['MIT']
10
- spec.authors = ["Stas Kobzar"]
11
- spec.email = ["staskobzar@gmail.com"]
12
- spec.description = %q{Ruby module for interacting with OpenSIPs management interface}
13
- spec.summary = %q{OpenSIPs management interface}
14
- spec.homepage = "http://github.com/staskobzar/opensips-mi"
15
-
16
- spec.files = `git ls-files`.split($/).reject{|f| %r|^examples/.*|.match f}
17
- spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
- spec.require_paths = ["lib"]
19
-
20
- spec.add_dependency "xmlrpc", "~> 0.3"
21
- spec.add_dependency "socketry", "~> 0.5"
22
-
23
- spec.add_development_dependency "bundler"
24
- spec.add_development_dependency "rake"
25
- spec.add_development_dependency "rspec"
26
- end
data/spec/command_spec.rb DELETED
@@ -1,4 +0,0 @@
1
- include Opensips::MI
2
-
3
- describe Command do
4
- end
@@ -1,20 +0,0 @@
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
-
@@ -1,168 +0,0 @@
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
-