librevox 1.0.0 → 1.2.0
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 +4 -4
- data/README.md +6 -2
- data/lib/librevox/applications.rb +2 -6
- data/lib/librevox/command_socket.rb +21 -5
- data/lib/librevox/listener/base.rb +4 -8
- data/lib/librevox/listener/inbound.rb +4 -4
- data/lib/librevox/listener/outbound.rb +19 -18
- data/lib/librevox/protocol/connection.rb +2 -2
- data/lib/librevox/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: fadfc835daf0f70edfe72c9a1fb2fb8ff709dc649e2105b06e0e304537b4a1aa
|
|
4
|
+
data.tar.gz: 6b6d55db19a6d4d8f3079148c5e0da1af6bd3b31491dc7238967c24188579332
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ade75b396dfaf64a08de980507b3a3ad47c6b3c91d0112196eceb9cc9f787ef96e0e0423583b0bfcb50dca63ce7f7d881b8166c5d28ec8763b0be6297d62566b
|
|
7
|
+
data.tar.gz: 62950a76f942a2021f05c0594daf0dfa7c9227e50218f7f78cf485e4edda45356a893cb6eb6aeffb9042a3535429a0cecb1bcf151619017afbd6303c13ea27e3
|
data/README.md
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src=".github/banner.svg" alt="Librevox" width="100%">
|
|
3
|
+
</p>
|
|
4
|
+
|
|
1
5
|
# Librevox
|
|
2
6
|
|
|
3
7
|
A Ruby library for interacting with [FreeSWITCH](http://www.freeswitch.org) through [mod_event_socket](https://developer.signalwire.com/freeswitch/FreeSWITCH-Explained/Modules/mod_event_socket_1048924/), using async I/O.
|
|
@@ -267,12 +271,12 @@ being processed until the current application completes.
|
|
|
267
271
|
Librevox runs two fibers for each outbound connection:
|
|
268
272
|
|
|
269
273
|
- **Session fiber** (`run_session`) — runs the setup sequence and then
|
|
270
|
-
`session_initiated`. Each `
|
|
274
|
+
`session_initiated`. Each `send_message` or `application` call blocks the fiber
|
|
271
275
|
until the reply arrives.
|
|
272
276
|
- **Read fiber** (`read_loop`) — reads messages from the socket and dispatches
|
|
273
277
|
them to `Async::Queue` instances, waking the session fiber.
|
|
274
278
|
|
|
275
|
-
An `Async::Semaphore(1)` mutex on `
|
|
279
|
+
An `Async::Semaphore(1)` mutex on `send_message` ensures only one command is
|
|
276
280
|
in-flight at a time, so replies are always delivered to the correct caller.
|
|
277
281
|
This also serializes commands issued by event hooks (which run in their own
|
|
278
282
|
fibers) with the main session flow.
|
|
@@ -150,9 +150,7 @@ module Librevox
|
|
|
150
150
|
args = [min, max, tries, timeout, terminators, file, invalid_file,
|
|
151
151
|
variable, regexp].join " "
|
|
152
152
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
application "play_and_get_digits", args, params
|
|
153
|
+
application "play_and_get_digits", args, variable: variable
|
|
156
154
|
end
|
|
157
155
|
|
|
158
156
|
# Plays a sound file on the current channel.
|
|
@@ -182,9 +180,7 @@ module Librevox
|
|
|
182
180
|
arg_string = "%s %s %s %s %s %s" % [min, max, file, variable, timeout,
|
|
183
181
|
terminators]
|
|
184
182
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
application "read", arg_string, params
|
|
183
|
+
application "read", arg_string, variable: variable
|
|
188
184
|
end
|
|
189
185
|
|
|
190
186
|
# Records a message, with an optional limit on the maximum duration of the
|
|
@@ -16,16 +16,19 @@ module Librevox
|
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
def connect
|
|
19
|
-
|
|
20
|
-
stream = IO::Stream(
|
|
19
|
+
socket = TCPSocket.open(@server, @port)
|
|
20
|
+
stream = IO::Stream(socket)
|
|
21
21
|
@connection = Protocol::Connection.new(stream)
|
|
22
|
-
|
|
22
|
+
send_message "auth #{@auth}"
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def send_message(msg)
|
|
26
|
+
@connection.send_message(msg)
|
|
23
27
|
read_response
|
|
24
28
|
end
|
|
25
29
|
|
|
26
30
|
def command(*args)
|
|
27
|
-
|
|
28
|
-
read_response
|
|
31
|
+
send_message(super(*args))
|
|
29
32
|
end
|
|
30
33
|
|
|
31
34
|
def read_response
|
|
@@ -34,6 +37,19 @@ module Librevox
|
|
|
34
37
|
end
|
|
35
38
|
end
|
|
36
39
|
|
|
40
|
+
def application(uuid, app, args = nil, **params)
|
|
41
|
+
headers = params
|
|
42
|
+
.merge(
|
|
43
|
+
event_lock: true,
|
|
44
|
+
call_command: "execute",
|
|
45
|
+
execute_app_name: app,
|
|
46
|
+
execute_app_arg: args,
|
|
47
|
+
)
|
|
48
|
+
.map { |key, value| "#{key.to_s.tr('_', '-')}: #{value}" }
|
|
49
|
+
|
|
50
|
+
send_message "sendmsg #{uuid}\n#{headers.join("\n")}"
|
|
51
|
+
end
|
|
52
|
+
|
|
37
53
|
def close
|
|
38
54
|
@connection.close
|
|
39
55
|
end
|
|
@@ -6,7 +6,7 @@ require 'async/semaphore'
|
|
|
6
6
|
module Librevox
|
|
7
7
|
module Listener
|
|
8
8
|
class Base
|
|
9
|
-
def initialize(connection
|
|
9
|
+
def initialize(connection)
|
|
10
10
|
@connection = connection
|
|
11
11
|
@reply_queue = Async::Queue.new
|
|
12
12
|
@command_mutex = Async::Semaphore.new(1)
|
|
@@ -34,7 +34,7 @@ module Librevox
|
|
|
34
34
|
end
|
|
35
35
|
|
|
36
36
|
def command(*args)
|
|
37
|
-
@listener.
|
|
37
|
+
@listener.send_message(super(*args))
|
|
38
38
|
end
|
|
39
39
|
end
|
|
40
40
|
|
|
@@ -48,9 +48,9 @@ module Librevox
|
|
|
48
48
|
@command_delegate ||= CommandDelegate.new(self)
|
|
49
49
|
end
|
|
50
50
|
|
|
51
|
-
def
|
|
51
|
+
def send_message(msg)
|
|
52
52
|
@command_mutex.acquire do
|
|
53
|
-
|
|
53
|
+
@connection.send_message(msg)
|
|
54
54
|
@reply_queue.dequeue
|
|
55
55
|
end
|
|
56
56
|
end
|
|
@@ -81,10 +81,6 @@ module Librevox
|
|
|
81
81
|
def on_event(event)
|
|
82
82
|
end
|
|
83
83
|
|
|
84
|
-
def write(data)
|
|
85
|
-
@connection&.write(data)
|
|
86
|
-
end
|
|
87
|
-
|
|
88
84
|
def run_session
|
|
89
85
|
end
|
|
90
86
|
|
|
@@ -24,7 +24,7 @@ module Librevox
|
|
|
24
24
|
barrier.async { client.run }
|
|
25
25
|
end
|
|
26
26
|
|
|
27
|
-
def initialize(connection
|
|
27
|
+
def initialize(connection, args = {})
|
|
28
28
|
super(connection)
|
|
29
29
|
@auth = args[:auth] || "ClueCon"
|
|
30
30
|
end
|
|
@@ -32,15 +32,15 @@ module Librevox
|
|
|
32
32
|
def run_session
|
|
33
33
|
Librevox.logger.info "Connected."
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
send_message "auth #{@auth}"
|
|
36
36
|
|
|
37
37
|
events = self.class.subscribe_events || ['ALL']
|
|
38
|
-
|
|
38
|
+
send_message "event plain #{events.join(' ')}"
|
|
39
39
|
|
|
40
40
|
filters = self.class.subscribe_filters || {}
|
|
41
41
|
filters.each do |header, values|
|
|
42
42
|
[*values].each do |value|
|
|
43
|
-
|
|
43
|
+
send_message "filter #{header} #{value}"
|
|
44
44
|
end
|
|
45
45
|
end
|
|
46
46
|
|
|
@@ -13,23 +13,24 @@ module Librevox
|
|
|
13
13
|
barrier.async { server.run }
|
|
14
14
|
end
|
|
15
15
|
|
|
16
|
-
def application(app, args = nil, params
|
|
17
|
-
|
|
18
|
-
parts << "execute-app-arg: #{args}" if args && !args.empty?
|
|
19
|
-
parts << "event-lock: true"
|
|
16
|
+
def application(app, args = nil, **params)
|
|
17
|
+
variable_name = params.delete(:variable)
|
|
20
18
|
|
|
21
|
-
|
|
22
|
-
|
|
19
|
+
headers = params
|
|
20
|
+
.merge(
|
|
21
|
+
event_lock: true,
|
|
22
|
+
call_command: "execute",
|
|
23
|
+
execute_app_name: app,
|
|
24
|
+
execute_app_arg: args,
|
|
25
|
+
)
|
|
26
|
+
.map { |key, value| "#{key.to_s.tr('_', '-')}: #{value}" }
|
|
23
27
|
|
|
24
|
-
|
|
25
|
-
end
|
|
28
|
+
send_message "sendmsg\n#{headers.join("\n")}"
|
|
26
29
|
|
|
27
|
-
|
|
28
|
-
@
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
end
|
|
32
|
-
@app_complete_queue.dequeue # CHANNEL_EXECUTE_COMPLETE
|
|
30
|
+
response = @app_complete_queue.dequeue
|
|
31
|
+
@session = response.content
|
|
32
|
+
|
|
33
|
+
variable(variable_name) if variable_name
|
|
33
34
|
end
|
|
34
35
|
|
|
35
36
|
attr_accessor :session
|
|
@@ -38,16 +39,16 @@ module Librevox
|
|
|
38
39
|
def session_initiated
|
|
39
40
|
end
|
|
40
41
|
|
|
41
|
-
def initialize(connection
|
|
42
|
+
def initialize(connection)
|
|
42
43
|
super(connection)
|
|
43
44
|
@session = nil
|
|
44
45
|
@app_complete_queue = Async::Queue.new
|
|
45
46
|
end
|
|
46
47
|
|
|
47
48
|
def run_session
|
|
48
|
-
@session =
|
|
49
|
-
|
|
50
|
-
|
|
49
|
+
@session = send_message("connect").headers
|
|
50
|
+
send_message "myevents"
|
|
51
|
+
send_message "linger"
|
|
51
52
|
session_initiated
|
|
52
53
|
sleep # keep session alive for event hooks and child tasks
|
|
53
54
|
end
|
data/lib/librevox/version.rb
CHANGED