sip-lab 1.24.0 → 1.27.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.
- package/package.json +3 -2
- package/prebuilds/linux-x64/sip-lab.node +0 -0
- package/runtests +80 -0
- package/samples/pcma.js +217 -0
- package/src/sip.cpp +170 -101
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sip-lab",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.27.1",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"engines": {
|
|
@@ -45,6 +45,7 @@
|
|
|
45
45
|
"DEV.md",
|
|
46
46
|
"samples",
|
|
47
47
|
"prebuilds",
|
|
48
|
-
"pocketsphinx"
|
|
48
|
+
"pocketsphinx",
|
|
49
|
+
"runtests"
|
|
49
50
|
]
|
|
50
51
|
}
|
|
Binary file
|
package/runtests
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
set -o nounset
|
|
4
|
+
|
|
5
|
+
function usage() {
|
|
6
|
+
cat <<EOF
|
|
7
|
+
Usage: $0 [-g]
|
|
8
|
+
|
|
9
|
+
Details:
|
|
10
|
+
-g : run each test inside gdb
|
|
11
|
+
EOF
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
use_gdb=0
|
|
15
|
+
|
|
16
|
+
while getopts "gh" o; do
|
|
17
|
+
case "${o}" in
|
|
18
|
+
g)
|
|
19
|
+
use_gdb=1
|
|
20
|
+
;;
|
|
21
|
+
h)
|
|
22
|
+
usage
|
|
23
|
+
exit 0
|
|
24
|
+
;;
|
|
25
|
+
*)
|
|
26
|
+
usage
|
|
27
|
+
exit 1
|
|
28
|
+
;;
|
|
29
|
+
esac
|
|
30
|
+
done
|
|
31
|
+
shift $((OPTIND-1))
|
|
32
|
+
|
|
33
|
+
successful_tests=()
|
|
34
|
+
|
|
35
|
+
function output_successful_tests() {
|
|
36
|
+
echo "Successful tests:"
|
|
37
|
+
for t in "${successful_tests[@]}"
|
|
38
|
+
do
|
|
39
|
+
echo " - $t"
|
|
40
|
+
done
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
echo
|
|
44
|
+
|
|
45
|
+
for i in $(ls samples/*.js)
|
|
46
|
+
do
|
|
47
|
+
start_time=$(date +%s.%N)
|
|
48
|
+
|
|
49
|
+
if [[ $use_gdb -eq 0 ]]
|
|
50
|
+
then
|
|
51
|
+
node $i
|
|
52
|
+
else
|
|
53
|
+
gdb -ex "handle SIGSEGV stop" -ex "run" -ex "bt" -ex "quit" --args node $i
|
|
54
|
+
fi
|
|
55
|
+
|
|
56
|
+
if [[ $? -ne 0 ]]
|
|
57
|
+
then
|
|
58
|
+
echo "$i failed"
|
|
59
|
+
echo
|
|
60
|
+
output_successful_tests
|
|
61
|
+
exit 1
|
|
62
|
+
else
|
|
63
|
+
end_time=$(date +%s.%N)
|
|
64
|
+
duration=$(echo "$end_time - $start_time" | bc)
|
|
65
|
+
formatted_duration=$(printf "%.2f seconds" $duration)
|
|
66
|
+
successful_tests+=("$i: duration=$formatted_duration")
|
|
67
|
+
|
|
68
|
+
echo
|
|
69
|
+
echo "$i failed"
|
|
70
|
+
fi
|
|
71
|
+
done
|
|
72
|
+
|
|
73
|
+
echo
|
|
74
|
+
|
|
75
|
+
echo "Success. All tests passed"
|
|
76
|
+
echo
|
|
77
|
+
output_successful_tests
|
|
78
|
+
echo
|
|
79
|
+
echo "Everything OK"
|
|
80
|
+
echo
|
package/samples/pcma.js
ADDED
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
var sip = require ('../index.js')
|
|
2
|
+
var Zeq = require('@mayama/zeq')
|
|
3
|
+
var z = new Zeq()
|
|
4
|
+
var m = require('data-matching')
|
|
5
|
+
var sip_msg = require('sip-matching')
|
|
6
|
+
var sdp = require('sdp-matching')
|
|
7
|
+
|
|
8
|
+
var assert = require('assert')
|
|
9
|
+
|
|
10
|
+
async function test() {
|
|
11
|
+
//sip.set_log_level(6)
|
|
12
|
+
sip.dtmf_aggregation_on(500)
|
|
13
|
+
|
|
14
|
+
z.trap_events(sip.event_source, 'event', (evt) => {
|
|
15
|
+
var e = evt.args[0]
|
|
16
|
+
return e
|
|
17
|
+
})
|
|
18
|
+
|
|
19
|
+
console.log(sip.start((data) => { console.log(data)} ))
|
|
20
|
+
|
|
21
|
+
t1 = sip.transport.create({address: "127.0.0.1", type: 'udp'})
|
|
22
|
+
t2 = sip.transport.create({address: "127.0.0.1", type: 'udp'})
|
|
23
|
+
|
|
24
|
+
console.log("t1", t1)
|
|
25
|
+
console.log("t2", t2)
|
|
26
|
+
|
|
27
|
+
sip.set_codecs("PCMA/8000/1:128")
|
|
28
|
+
|
|
29
|
+
flags = 0
|
|
30
|
+
|
|
31
|
+
oc = sip.call.create(t1.id, {from_uri: 'sip:alice@test.com', to_uri: `sip:bob@${t2.address}:${t2.port}`})
|
|
32
|
+
|
|
33
|
+
await z.wait([
|
|
34
|
+
{
|
|
35
|
+
event: "incoming_call",
|
|
36
|
+
call_id: m.collect("call_id"),
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
event: 'response',
|
|
40
|
+
call_id: oc.id,
|
|
41
|
+
method: 'INVITE',
|
|
42
|
+
msg: sip_msg({
|
|
43
|
+
$rs: '100',
|
|
44
|
+
$rr: 'Trying',
|
|
45
|
+
'$(hdrcnt(via))': 1,
|
|
46
|
+
'hdr_call_id': m.collect('sip_call_id'),
|
|
47
|
+
$fU: 'alice',
|
|
48
|
+
$fd: 'test.com',
|
|
49
|
+
$tU: 'bob',
|
|
50
|
+
'hdr_l': '0',
|
|
51
|
+
}),
|
|
52
|
+
},
|
|
53
|
+
], 1000)
|
|
54
|
+
|
|
55
|
+
ic = {
|
|
56
|
+
id: z.store.call_id,
|
|
57
|
+
sip_call_id: z.store.sip_call_id,
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
sip.call.respond(ic.id, {code: 200, reason: 'OK'})
|
|
61
|
+
|
|
62
|
+
await z.wait([
|
|
63
|
+
{
|
|
64
|
+
event: 'media_update',
|
|
65
|
+
call_id: oc.id,
|
|
66
|
+
status: 'ok',
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
event: 'media_update',
|
|
70
|
+
call_id: ic.id,
|
|
71
|
+
status: 'ok',
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
event: 'response',
|
|
75
|
+
call_id: oc.id,
|
|
76
|
+
method: 'INVITE',
|
|
77
|
+
msg: sip_msg({
|
|
78
|
+
$rs: '200',
|
|
79
|
+
$rr: 'OK',
|
|
80
|
+
'$(hdrcnt(VIA))': 1,
|
|
81
|
+
$fU: 'alice',
|
|
82
|
+
$fd: 'test.com',
|
|
83
|
+
$tU: 'bob',
|
|
84
|
+
'hdr_content_type': 'application/sdp',
|
|
85
|
+
$rb: '!{_}a=sendrecv',
|
|
86
|
+
}),
|
|
87
|
+
},
|
|
88
|
+
], 1000)
|
|
89
|
+
|
|
90
|
+
sip.call.reinvite(oc.id)
|
|
91
|
+
|
|
92
|
+
await z.wait([
|
|
93
|
+
{
|
|
94
|
+
event: 'reinvite',
|
|
95
|
+
call_id: ic.id
|
|
96
|
+
},
|
|
97
|
+
], 1000)
|
|
98
|
+
|
|
99
|
+
sip.call.respond(ic.id, {code: 200, reason: 'OK'})
|
|
100
|
+
|
|
101
|
+
await z.wait([
|
|
102
|
+
{
|
|
103
|
+
event: 'response',
|
|
104
|
+
call_id: oc.id,
|
|
105
|
+
method: 'INVITE',
|
|
106
|
+
msg: sip_msg({
|
|
107
|
+
$rs: '100',
|
|
108
|
+
}),
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
event: 'response',
|
|
112
|
+
call_id: oc.id,
|
|
113
|
+
method: 'INVITE',
|
|
114
|
+
msg: sip_msg({
|
|
115
|
+
$rs: '200',
|
|
116
|
+
$rr: 'OK',
|
|
117
|
+
$rb: '!{_}a=sendrecv',
|
|
118
|
+
}),
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
event: 'media_update',
|
|
122
|
+
call_id: oc.id,
|
|
123
|
+
status: 'ok',
|
|
124
|
+
},
|
|
125
|
+
{
|
|
126
|
+
event: 'media_update',
|
|
127
|
+
call_id: ic.id,
|
|
128
|
+
status: 'ok',
|
|
129
|
+
},
|
|
130
|
+
], 500)
|
|
131
|
+
|
|
132
|
+
sip.call.reinvite(oc.id, false, 0)
|
|
133
|
+
|
|
134
|
+
await z.wait([
|
|
135
|
+
{
|
|
136
|
+
event: 'reinvite',
|
|
137
|
+
call_id: ic.id
|
|
138
|
+
},
|
|
139
|
+
], 1000)
|
|
140
|
+
|
|
141
|
+
sip.call.respond(ic.id, {code: 200, reason: 'OK'})
|
|
142
|
+
|
|
143
|
+
await z.wait([
|
|
144
|
+
{
|
|
145
|
+
event: 'response',
|
|
146
|
+
call_id: oc.id,
|
|
147
|
+
method: 'INVITE',
|
|
148
|
+
msg: sip_msg({
|
|
149
|
+
$rs: '100',
|
|
150
|
+
}),
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
event: 'response',
|
|
154
|
+
call_id: oc.id,
|
|
155
|
+
method: 'INVITE',
|
|
156
|
+
msg: sip_msg({
|
|
157
|
+
$rs: '200',
|
|
158
|
+
$rr: 'OK',
|
|
159
|
+
$rb: '!{_}a=sendrecv',
|
|
160
|
+
}),
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
event: 'media_update',
|
|
164
|
+
call_id: oc.id,
|
|
165
|
+
status: 'ok',
|
|
166
|
+
},
|
|
167
|
+
{
|
|
168
|
+
event: 'media_update',
|
|
169
|
+
call_id: ic.id,
|
|
170
|
+
status: 'ok',
|
|
171
|
+
},
|
|
172
|
+
], 500)
|
|
173
|
+
|
|
174
|
+
oc_stat = sip.call.get_stream_stat(oc.id, {media_id: 0})
|
|
175
|
+
ic_stat = sip.call.get_stream_stat(ic.id, {media_id: 0})
|
|
176
|
+
|
|
177
|
+
console.log(oc_stat)
|
|
178
|
+
console.log(ic_stat)
|
|
179
|
+
|
|
180
|
+
oc_stat = JSON.parse(oc_stat)
|
|
181
|
+
ic_stat = JSON.parse(ic_stat)
|
|
182
|
+
|
|
183
|
+
assert(oc_stat.CodecInfo == 'PCMA/8000/1')
|
|
184
|
+
assert(ic_stat.CodecInfo == 'PCMA/8000/1')
|
|
185
|
+
|
|
186
|
+
sip.call.terminate(oc.id)
|
|
187
|
+
|
|
188
|
+
await z.wait([
|
|
189
|
+
{
|
|
190
|
+
event: 'call_ended',
|
|
191
|
+
call_id: oc.id,
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
event: 'call_ended',
|
|
195
|
+
call_id: ic.id,
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
event: 'response',
|
|
199
|
+
call_id: oc.id,
|
|
200
|
+
method: 'BYE',
|
|
201
|
+
msg: sip_msg({
|
|
202
|
+
$rs: '200',
|
|
203
|
+
$rr: 'OK',
|
|
204
|
+
}),
|
|
205
|
+
},
|
|
206
|
+
], 1000)
|
|
207
|
+
|
|
208
|
+
console.log("Success")
|
|
209
|
+
|
|
210
|
+
sip.stop()
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
test()
|
|
214
|
+
.catch(e => {
|
|
215
|
+
console.error(e)
|
|
216
|
+
process.exit(1)
|
|
217
|
+
})
|
package/src/sip.cpp
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#include <arpa/inet.h>
|
|
2
|
+
#include <netdb.h>
|
|
2
3
|
|
|
3
4
|
#include "sip.hpp"
|
|
4
5
|
|
|
@@ -305,8 +306,18 @@ struct Subscription {
|
|
|
305
306
|
struct ConfBridgePort {
|
|
306
307
|
unsigned slot;
|
|
307
308
|
pjmedia_port *port;
|
|
309
|
+
short connection_mode;
|
|
308
310
|
};
|
|
309
311
|
|
|
312
|
+
#define FP_DTMFDET 0
|
|
313
|
+
#define FP_WAV_PLAYER 1
|
|
314
|
+
#define FP_WAV_WRITER 2
|
|
315
|
+
#define FP_TONEGEN 3
|
|
316
|
+
#define FP_FAX 4
|
|
317
|
+
#define FP_SPEECH_SYNTH 5
|
|
318
|
+
#define FP_SPEECH_RECOG 6
|
|
319
|
+
#define MAX_FP 7
|
|
320
|
+
|
|
310
321
|
struct AudioEndpoint {
|
|
311
322
|
pjmedia_transport *med_transport;
|
|
312
323
|
pjmedia_stream *med_stream;
|
|
@@ -322,13 +333,7 @@ struct AudioEndpoint {
|
|
|
322
333
|
pjmedia_port *null_port;
|
|
323
334
|
|
|
324
335
|
ConfBridgePort stream_cbp;
|
|
325
|
-
ConfBridgePort
|
|
326
|
-
ConfBridgePort wav_writer_cbp;
|
|
327
|
-
ConfBridgePort tonegen_cbp;
|
|
328
|
-
ConfBridgePort dtmfdet_cbp;
|
|
329
|
-
ConfBridgePort fax_cbp;
|
|
330
|
-
ConfBridgePort flite_cbp;
|
|
331
|
-
ConfBridgePort pocketsphinx_cbp;
|
|
336
|
+
ConfBridgePort feature_cbps[MAX_FP];
|
|
332
337
|
};
|
|
333
338
|
|
|
334
339
|
struct VideoEndpoint {
|
|
@@ -779,7 +784,7 @@ static int find_endpoint_by_inband_dtmf_media_port(Call *call,
|
|
|
779
784
|
MediaEndpoint *me = (MediaEndpoint *)call->media[i];
|
|
780
785
|
if (ENDPOINT_TYPE_AUDIO == me->type) {
|
|
781
786
|
AudioEndpoint *ae = (AudioEndpoint *)me->endpoint.audio;
|
|
782
|
-
if (ae->
|
|
787
|
+
if (ae->feature_cbps[FP_DTMFDET].port && (pjmedia_port *)ae->feature_cbps[FP_DTMFDET].port == port) {
|
|
783
788
|
return i;
|
|
784
789
|
}
|
|
785
790
|
}
|
|
@@ -1505,8 +1510,8 @@ pjsip_transport *create_udp_transport(pjsip_endpoint *sip_endpt,
|
|
|
1505
1510
|
// pj_status_t status;
|
|
1506
1511
|
pjsip_transport *transport;
|
|
1507
1512
|
|
|
1508
|
-
int port = 5060;
|
|
1509
1513
|
for (int i = 0; i < 1000; ++i) {
|
|
1514
|
+
int port = 5060;
|
|
1510
1515
|
port += i;
|
|
1511
1516
|
transport = allocate_udp_transport(sip_endpt, ipaddr, port);
|
|
1512
1517
|
if (transport) {
|
|
@@ -1553,8 +1558,8 @@ pjsip_tpfactory *create_tcp_tpfactory(pjsip_endpoint *sip_endpt,
|
|
|
1553
1558
|
// pj_status_t status;
|
|
1554
1559
|
pjsip_tpfactory *tpfactory;
|
|
1555
1560
|
|
|
1556
|
-
int port = 6060;
|
|
1557
1561
|
for (int i = 0; i < 1000; ++i) {
|
|
1562
|
+
int port = 6060;
|
|
1558
1563
|
port += i;
|
|
1559
1564
|
tpfactory = allocate_tcp_tpfactory(sip_endpt, ipaddr, port);
|
|
1560
1565
|
if (tpfactory) {
|
|
@@ -1604,8 +1609,8 @@ pjsip_tpfactory *create_tls_tpfactory(pjsip_endpoint *sip_endpt,
|
|
|
1604
1609
|
// pj_status_t status;
|
|
1605
1610
|
pjsip_tpfactory *tpfactory;
|
|
1606
1611
|
|
|
1607
|
-
int port = 6060;
|
|
1608
1612
|
for (int i = 0; i < 1000; ++i) {
|
|
1613
|
+
int port = 6060;
|
|
1609
1614
|
port += i;
|
|
1610
1615
|
tpfactory = allocate_tls_tpfactory(sip_endpt, ipaddr, port);
|
|
1611
1616
|
if (tpfactory) {
|
|
@@ -2796,9 +2801,47 @@ bool dlg_set_transport_by_t(Transport *t, pjsip_dialog *dlg) {
|
|
|
2796
2801
|
return true;
|
|
2797
2802
|
}
|
|
2798
2803
|
|
|
2799
|
-
|
|
2804
|
+
bool is_ip_address(const char *hostname) {
|
|
2805
|
+
struct sockaddr_in sa;
|
|
2806
|
+
return inet_pton(AF_INET, hostname, &(sa.sin_addr)) != 0;
|
|
2807
|
+
}
|
|
2808
|
+
|
|
2809
|
+
void build_transport_tag(char *dest, const char *type, const char *hostname,
|
|
2800
2810
|
int port) {
|
|
2801
|
-
|
|
2811
|
+
struct addrinfo hints, * res, *p;
|
|
2812
|
+
|
|
2813
|
+
if(is_ip_address(hostname)) {
|
|
2814
|
+
sprintf(dest, "%s:%s:%d", type, hostname, port);
|
|
2815
|
+
return;
|
|
2816
|
+
}
|
|
2817
|
+
|
|
2818
|
+
memset(&hints, 0, sizeof(hints));
|
|
2819
|
+
hints.ai_family = AF_UNSPEC; // AF_INET or AF_INET6 to force version
|
|
2820
|
+
hints.ai_socktype = SOCK_STREAM;
|
|
2821
|
+
|
|
2822
|
+
// Resolve the domain name
|
|
2823
|
+
int status = getaddrinfo(hostname, NULL, &hints, &res);
|
|
2824
|
+
if (status != 0) {
|
|
2825
|
+
printf("build_transport_tag getaddrinfo: %s\n", gai_strerror(status));
|
|
2826
|
+
sprintf(dest, "%s:%s:%d", type, hostname, port);
|
|
2827
|
+
} else {
|
|
2828
|
+
for (p = res; p != NULL; p = p->ai_next) {
|
|
2829
|
+
void *addr;
|
|
2830
|
+
if (p->ai_family == AF_INET) { // IPv4
|
|
2831
|
+
struct sockaddr_in *ipv4 = (struct sockaddr_in *)p->ai_addr;
|
|
2832
|
+
addr = &(ipv4->sin_addr);
|
|
2833
|
+
} else { // IPv6
|
|
2834
|
+
struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)p->ai_addr;
|
|
2835
|
+
addr = &(ipv6->sin6_addr);
|
|
2836
|
+
}
|
|
2837
|
+
char ipstr[INET6_ADDRSTRLEN];
|
|
2838
|
+
inet_ntop(p->ai_family, addr, ipstr, sizeof(ipstr));
|
|
2839
|
+
sprintf(dest, "%s:%s:%d", type, ipstr, port);
|
|
2840
|
+
break;
|
|
2841
|
+
}
|
|
2842
|
+
}
|
|
2843
|
+
|
|
2844
|
+
freeaddrinfo(res);
|
|
2802
2845
|
}
|
|
2803
2846
|
|
|
2804
2847
|
void build_transport_tag_from_pjsip_transport(char *dest, pjsip_transport *t) {
|
|
@@ -2810,6 +2853,7 @@ void build_transport_tag_from_pjsip_transport(char *dest, pjsip_transport *t) {
|
|
|
2810
2853
|
assert(t->local_name.host.slen < 16);
|
|
2811
2854
|
strncpy(address, t->local_name.host.ptr, t->local_name.host.slen);
|
|
2812
2855
|
address[t->local_name.host.slen] = 0;
|
|
2856
|
+
printf("build_transport_tag_from_pjsip_transport address=%s\n", address);
|
|
2813
2857
|
|
|
2814
2858
|
if (t->key.type == PJSIP_TRANSPORT_UDP) {
|
|
2815
2859
|
type = "udp";
|
|
@@ -3082,7 +3126,7 @@ pj_status_t audio_endpoint_send_dtmf(Call *call, AudioEndpoint *ae,
|
|
|
3082
3126
|
tone.on_msec = ON_DURATION;
|
|
3083
3127
|
tone.off_msec = OFF_DURATION;
|
|
3084
3128
|
tone.volume = 0;
|
|
3085
|
-
status = pjmedia_tonegen_play_digits((pjmedia_port *)ae->
|
|
3129
|
+
status = pjmedia_tonegen_play_digits((pjmedia_port *)ae->feature_cbps[FP_TONEGEN].port, 1,
|
|
3086
3130
|
&tone, 0);
|
|
3087
3131
|
if (status != PJ_SUCCESS) {
|
|
3088
3132
|
set_error("pjmedia_tonegen_play_digits failed.");
|
|
@@ -3789,7 +3833,7 @@ pj_status_t audio_endpoint_start_speech_synth(Call *call, AudioEndpoint *ae, con
|
|
|
3789
3833
|
return -1;
|
|
3790
3834
|
}
|
|
3791
3835
|
|
|
3792
|
-
pjmedia_flite_port_speak(ae->
|
|
3836
|
+
pjmedia_flite_port_speak(ae->feature_cbps[FP_SPEECH_SYNTH].port, text, flags);
|
|
3793
3837
|
|
|
3794
3838
|
return PJ_SUCCESS;
|
|
3795
3839
|
}
|
|
@@ -4122,36 +4166,27 @@ out:
|
|
|
4122
4166
|
return 0;
|
|
4123
4167
|
}
|
|
4124
4168
|
|
|
4125
|
-
pj_status_t audio_endpoint_stop_speech_synth(Call *call, AudioEndpoint *ae) {
|
|
4126
|
-
return audio_endpoint_remove_port(call, ae, &ae->flite_cbp);
|
|
4127
|
-
}
|
|
4128
|
-
|
|
4129
|
-
pj_status_t audio_endpoint_stop_speech_recog(Call *call, AudioEndpoint *ae) {
|
|
4130
|
-
return audio_endpoint_remove_port(call, ae, &ae->pocketsphinx_cbp);
|
|
4131
|
-
}
|
|
4132
|
-
|
|
4133
4169
|
pj_status_t audio_endpoint_stop_play_wav(Call *call, AudioEndpoint *ae) {
|
|
4134
|
-
return audio_endpoint_remove_port(call, ae, &ae->
|
|
4170
|
+
return audio_endpoint_remove_port(call, ae, &ae->feature_cbps[FP_WAV_PLAYER]);
|
|
4135
4171
|
}
|
|
4136
4172
|
|
|
4137
4173
|
pj_status_t audio_endpoint_stop_record_wav(Call *call, AudioEndpoint *ae) {
|
|
4138
|
-
return audio_endpoint_remove_port(call, ae, &ae->
|
|
4174
|
+
return audio_endpoint_remove_port(call, ae, &ae->feature_cbps[FP_WAV_WRITER]);
|
|
4139
4175
|
}
|
|
4140
4176
|
|
|
4141
4177
|
pj_status_t audio_endpoint_stop_fax(Call *call, AudioEndpoint *ae) {
|
|
4142
|
-
return audio_endpoint_remove_port(call, ae, &ae->
|
|
4178
|
+
return audio_endpoint_remove_port(call, ae, &ae->feature_cbps[FP_FAX]);
|
|
4143
4179
|
}
|
|
4144
4180
|
|
|
4145
|
-
|
|
4146
|
-
|
|
4147
|
-
int pjw_call_stop_speech_synth(long call_id, const char *json) {
|
|
4148
|
-
return audio_endpoint_stop_op(call_id, json, audio_endpoint_stop_speech_synth);
|
|
4181
|
+
pj_status_t audio_endpoint_stop_speech_synth(Call *call, AudioEndpoint *ae) {
|
|
4182
|
+
return audio_endpoint_remove_port(call, ae, &ae->feature_cbps[FP_SPEECH_SYNTH]);
|
|
4149
4183
|
}
|
|
4150
4184
|
|
|
4151
|
-
|
|
4152
|
-
return
|
|
4185
|
+
pj_status_t audio_endpoint_stop_speech_recog(Call *call, AudioEndpoint *ae) {
|
|
4186
|
+
return audio_endpoint_remove_port(call, ae, &ae->feature_cbps[FP_SPEECH_RECOG]);
|
|
4153
4187
|
}
|
|
4154
4188
|
|
|
4189
|
+
|
|
4155
4190
|
int pjw_call_stop_play_wav(long call_id, const char *json) {
|
|
4156
4191
|
return audio_endpoint_stop_op(call_id, json, audio_endpoint_stop_play_wav);
|
|
4157
4192
|
}
|
|
@@ -4164,6 +4199,14 @@ int pjw_call_stop_fax(long call_id, const char *json) {
|
|
|
4164
4199
|
return audio_endpoint_stop_op(call_id, json, audio_endpoint_stop_fax);
|
|
4165
4200
|
}
|
|
4166
4201
|
|
|
4202
|
+
int pjw_call_stop_speech_synth(long call_id, const char *json) {
|
|
4203
|
+
return audio_endpoint_stop_op(call_id, json, audio_endpoint_stop_speech_synth);
|
|
4204
|
+
}
|
|
4205
|
+
|
|
4206
|
+
int pjw_call_stop_speech_recog(long call_id, const char *json) {
|
|
4207
|
+
return audio_endpoint_stop_op(call_id, json, audio_endpoint_stop_speech_recog);
|
|
4208
|
+
}
|
|
4209
|
+
|
|
4167
4210
|
|
|
4168
4211
|
int pjw_call_start_fax(long call_id, const char *json) {
|
|
4169
4212
|
PJW_LOCK();
|
|
@@ -4639,15 +4682,6 @@ bool start_tcp_media(Call *call, MediaEndpoint *me,
|
|
|
4639
4682
|
void close_audio_endpoint_ports_and_conf(Call *call, AudioEndpoint *ae) {
|
|
4640
4683
|
pj_status_t status;
|
|
4641
4684
|
|
|
4642
|
-
audio_endpoint_remove_port(call, ae, &ae->stream_cbp);
|
|
4643
|
-
audio_endpoint_remove_port(call, ae, &ae->wav_player_cbp);
|
|
4644
|
-
audio_endpoint_remove_port(call, ae, &ae->wav_writer_cbp);
|
|
4645
|
-
audio_endpoint_remove_port(call, ae, &ae->tonegen_cbp);
|
|
4646
|
-
audio_endpoint_remove_port(call, ae, &ae->dtmfdet_cbp);
|
|
4647
|
-
audio_endpoint_remove_port(call, ae, &ae->fax_cbp);
|
|
4648
|
-
audio_endpoint_remove_port(call, ae, &ae->flite_cbp);
|
|
4649
|
-
audio_endpoint_remove_port(call, ae, &ae->pocketsphinx_cbp);
|
|
4650
|
-
|
|
4651
4685
|
if (ae->master_port) {
|
|
4652
4686
|
status = pjmedia_master_port_stop(ae->master_port);
|
|
4653
4687
|
if(status != PJ_SUCCESS) {
|
|
@@ -4660,6 +4694,12 @@ void close_audio_endpoint_ports_and_conf(Call *call, AudioEndpoint *ae) {
|
|
|
4660
4694
|
ae->master_port = NULL;
|
|
4661
4695
|
}
|
|
4662
4696
|
|
|
4697
|
+
audio_endpoint_remove_port(call, ae, &ae->stream_cbp);
|
|
4698
|
+
|
|
4699
|
+
for(int i=0 ; i<MAX_FP ; i++) {
|
|
4700
|
+
audio_endpoint_remove_port(call, ae, &ae->feature_cbps[i]);
|
|
4701
|
+
}
|
|
4702
|
+
|
|
4663
4703
|
if (ae->conf) {
|
|
4664
4704
|
status = pjmedia_conf_destroy(ae->conf);
|
|
4665
4705
|
if(status != PJ_SUCCESS) {
|
|
@@ -4677,17 +4717,17 @@ void close_audio_endpoint_ports_and_conf(Call *call, AudioEndpoint *ae) {
|
|
|
4677
4717
|
}
|
|
4678
4718
|
}
|
|
4679
4719
|
|
|
4680
|
-
bool connect_feature_port_to_stream_port(Call *call, AudioEndpoint *ae, ConfBridgePort *cbp
|
|
4720
|
+
bool connect_feature_port_to_stream_port(Call *call, AudioEndpoint *ae, ConfBridgePort *cbp) {
|
|
4681
4721
|
pj_status_t status;
|
|
4682
4722
|
|
|
4683
|
-
if(connection_mode == CONNECTION_MODE_SOURCE || connection_mode == CONNECTION_MODE_SOURCE_AND_SINK) {
|
|
4723
|
+
if(cbp->connection_mode == CONNECTION_MODE_SOURCE || cbp->connection_mode == CONNECTION_MODE_SOURCE_AND_SINK) {
|
|
4684
4724
|
status = pjmedia_conf_connect_port(ae->conf, cbp->slot, ae->stream_cbp.slot, 0);
|
|
4685
4725
|
if (status != PJ_SUCCESS) {
|
|
4686
4726
|
set_error("pjmedia_conf_connect_port failed");
|
|
4687
4727
|
return false;
|
|
4688
4728
|
}
|
|
4689
4729
|
}
|
|
4690
|
-
if(connection_mode == CONNECTION_MODE_SINK || connection_mode == CONNECTION_MODE_SOURCE_AND_SINK) {
|
|
4730
|
+
if(cbp->connection_mode == CONNECTION_MODE_SINK || cbp->connection_mode == CONNECTION_MODE_SOURCE_AND_SINK) {
|
|
4691
4731
|
status = pjmedia_conf_connect_port(ae->conf, ae->stream_cbp.slot, cbp->slot, 0);
|
|
4692
4732
|
printf("status=%i\n" ,status);
|
|
4693
4733
|
if (status != PJ_SUCCESS) {
|
|
@@ -4711,6 +4751,19 @@ bool restart_media_stream(Call *call, MediaEndpoint *me,
|
|
|
4711
4751
|
pjmedia_port *old_port = ae->stream_cbp.port;
|
|
4712
4752
|
pjmedia_port *new_port;
|
|
4713
4753
|
|
|
4754
|
+
bool master_port_was_stopped = false;
|
|
4755
|
+
|
|
4756
|
+
if(ae->master_port) {
|
|
4757
|
+
status = pjmedia_master_port_stop(ae->master_port);
|
|
4758
|
+
if(status != PJ_SUCCESS) {
|
|
4759
|
+
make_evt_media_update(evt, sizeof(evt), call->id,
|
|
4760
|
+
"setup_failed (pjmedia_master_port_stop failed)", "");
|
|
4761
|
+
dispatch_event(evt);
|
|
4762
|
+
return false;
|
|
4763
|
+
}
|
|
4764
|
+
master_port_was_stopped = true;
|
|
4765
|
+
}
|
|
4766
|
+
|
|
4714
4767
|
status =
|
|
4715
4768
|
pjmedia_stream_info_from_sdp(&stream_info, call->inv->dlg->pool,
|
|
4716
4769
|
g_med_endpt, local_sdp, remote_sdp, idx);
|
|
@@ -4860,35 +4913,23 @@ bool restart_media_stream(Call *call, MediaEndpoint *me,
|
|
|
4860
4913
|
}
|
|
4861
4914
|
|
|
4862
4915
|
// Need to connect ports to new stream port
|
|
4863
|
-
|
|
4864
|
-
|
|
4865
|
-
|
|
4866
|
-
|
|
4867
|
-
if(ae->wav_writer_cbp.port) {
|
|
4868
|
-
if(!connect_feature_port_to_stream_port(call, ae, &ae->wav_writer_cbp, CONNECTION_MODE_SINK)) return false;
|
|
4869
|
-
}
|
|
4870
|
-
|
|
4871
|
-
if(ae->wav_player_cbp.port) {
|
|
4872
|
-
if(!connect_feature_port_to_stream_port(call, ae, &ae->wav_player_cbp, CONNECTION_MODE_SOURCE)) return false;
|
|
4873
|
-
}
|
|
4874
|
-
|
|
4875
|
-
if(ae->tonegen_cbp.port) {
|
|
4876
|
-
if(!connect_feature_port_to_stream_port(call, ae, &ae->tonegen_cbp, CONNECTION_MODE_SOURCE)) return false;
|
|
4877
|
-
}
|
|
4878
|
-
|
|
4879
|
-
if(ae->fax_cbp.port) {
|
|
4880
|
-
if(!connect_feature_port_to_stream_port(call, ae, &ae->fax_cbp, CONNECTION_MODE_SOURCE_AND_SINK)) return false;
|
|
4881
|
-
}
|
|
4882
|
-
|
|
4883
|
-
if(ae->flite_cbp.port) {
|
|
4884
|
-
if(!connect_feature_port_to_stream_port(call, ae, &ae->flite_cbp, CONNECTION_MODE_SOURCE)) return false;
|
|
4916
|
+
for(int i=0 ; i<MAX_FP ; i++) {
|
|
4917
|
+
if(ae->feature_cbps[i].port) {
|
|
4918
|
+
if(!connect_feature_port_to_stream_port(call, ae, &ae->feature_cbps[i])) return false;
|
|
4919
|
+
}
|
|
4885
4920
|
}
|
|
4921
|
+
}
|
|
4886
4922
|
|
|
4887
|
-
|
|
4888
|
-
|
|
4923
|
+
if(master_port_was_stopped) {
|
|
4924
|
+
status = pjmedia_master_port_start(ae->master_port);
|
|
4925
|
+
if(status != PJ_SUCCESS) {
|
|
4926
|
+
make_evt_media_update(evt, sizeof(evt), call->id,
|
|
4927
|
+
"setup_failed (pjmedia_master_port_start failed)", "");
|
|
4928
|
+
dispatch_event(evt);
|
|
4929
|
+
return false;
|
|
4889
4930
|
}
|
|
4890
4931
|
}
|
|
4891
|
-
|
|
4932
|
+
|
|
4892
4933
|
return true;
|
|
4893
4934
|
}
|
|
4894
4935
|
|
|
@@ -5379,7 +5420,7 @@ static pj_bool_t on_rx_request(pjsip_rx_data *rdata) {
|
|
|
5379
5420
|
|
|
5380
5421
|
long transport_id;
|
|
5381
5422
|
|
|
5382
|
-
//
|
|
5423
|
+
//printf("on_rx_request transport_tag=%s\n", tag);
|
|
5383
5424
|
|
|
5384
5425
|
TransportMap::iterator iter = g_TransportMap.find(tag);
|
|
5385
5426
|
if (iter != g_TransportMap.end()) {
|
|
@@ -5490,7 +5531,7 @@ static pj_bool_t on_rx_request(pjsip_rx_data *rdata) {
|
|
|
5490
5531
|
|
|
5491
5532
|
long transport_id;
|
|
5492
5533
|
|
|
5493
|
-
|
|
5534
|
+
printf("on_rx_request INVITE transport_tag=%s\n", tag);
|
|
5494
5535
|
|
|
5495
5536
|
TransportMap::iterator iter = g_TransportMap.find(tag);
|
|
5496
5537
|
if (iter != g_TransportMap.end()) {
|
|
@@ -6707,7 +6748,9 @@ bool prepare_tonegen(Call *call, AudioEndpoint *ae) {
|
|
|
6707
6748
|
printf("prepare_tone_gen call.id=%i\n", call->id);
|
|
6708
6749
|
pj_status_t status;
|
|
6709
6750
|
|
|
6710
|
-
|
|
6751
|
+
ConfBridgePort *fp = &ae->feature_cbps[FP_TONEGEN];
|
|
6752
|
+
|
|
6753
|
+
if(fp->port) {
|
|
6711
6754
|
printf("already prepared\n");
|
|
6712
6755
|
return true;
|
|
6713
6756
|
}
|
|
@@ -6716,24 +6759,28 @@ bool prepare_tonegen(Call *call, AudioEndpoint *ae) {
|
|
|
6716
6759
|
call->inv->pool, PJMEDIA_PIA_SRATE(&ae->stream_cbp.port->info),
|
|
6717
6760
|
PJMEDIA_PIA_CCNT(&ae->stream_cbp.port->info),
|
|
6718
6761
|
PJMEDIA_PIA_SPF(&ae->stream_cbp.port->info),
|
|
6719
|
-
PJMEDIA_PIA_BITS(&ae->stream_cbp.port->info), 0, &
|
|
6762
|
+
PJMEDIA_PIA_BITS(&ae->stream_cbp.port->info), 0, &fp->port);
|
|
6720
6763
|
if (status != PJ_SUCCESS) {
|
|
6721
6764
|
set_error("pjmedia_tonegen_create failed");
|
|
6722
6765
|
return false;
|
|
6723
6766
|
}
|
|
6724
6767
|
|
|
6725
|
-
status = pjmedia_conf_add_port(ae->conf, call->inv->pool,
|
|
6768
|
+
status = pjmedia_conf_add_port(ae->conf, call->inv->pool, fp->port, NULL, &fp->slot);
|
|
6726
6769
|
if (status != PJ_SUCCESS) {
|
|
6727
6770
|
set_error("pjmedia_conf_add_port failed");
|
|
6728
6771
|
return false;
|
|
6729
6772
|
}
|
|
6730
6773
|
|
|
6731
|
-
|
|
6774
|
+
fp->connection_mode = CONNECTION_MODE_SOURCE;
|
|
6775
|
+
|
|
6776
|
+
return connect_feature_port_to_stream_port(call, ae, fp);
|
|
6732
6777
|
}
|
|
6733
6778
|
|
|
6734
6779
|
bool prepare_wav_player(Call *call, AudioEndpoint *ae, const char *file, unsigned flags, bool end_of_file_event) {
|
|
6735
6780
|
pj_status_t status;
|
|
6736
6781
|
|
|
6782
|
+
ConfBridgePort *fp = &ae->feature_cbps[FP_WAV_PLAYER];
|
|
6783
|
+
|
|
6737
6784
|
unsigned wav_ptime;
|
|
6738
6785
|
wav_ptime = PJMEDIA_PIA_SPF(&ae->stream_cbp.port->info) * 1000 /
|
|
6739
6786
|
PJMEDIA_PIA_SRATE(&ae->stream_cbp.port->info);
|
|
@@ -6744,7 +6791,7 @@ bool prepare_wav_player(Call *call, AudioEndpoint *ae, const char *file, unsigne
|
|
|
6744
6791
|
wav_ptime,
|
|
6745
6792
|
flags,
|
|
6746
6793
|
-1, /* buf size */
|
|
6747
|
-
&
|
|
6794
|
+
&fp->port
|
|
6748
6795
|
);
|
|
6749
6796
|
|
|
6750
6797
|
if (status != PJ_SUCCESS) {
|
|
@@ -6753,71 +6800,83 @@ bool prepare_wav_player(Call *call, AudioEndpoint *ae, const char *file, unsigne
|
|
|
6753
6800
|
}
|
|
6754
6801
|
|
|
6755
6802
|
if (end_of_file_event) {
|
|
6756
|
-
status = pjmedia_wav_player_set_eof_cb2(
|
|
6803
|
+
status = pjmedia_wav_player_set_eof_cb2(fp->port, (void*)call, on_end_of_file);
|
|
6757
6804
|
if (status != PJ_SUCCESS) {
|
|
6758
6805
|
set_error("pjmedia_wav_player_set_eof_cb2 failed");
|
|
6759
6806
|
return false;
|
|
6760
6807
|
}
|
|
6761
6808
|
}
|
|
6762
6809
|
|
|
6763
|
-
status = pjmedia_conf_add_port(ae->conf, call->inv->pool,
|
|
6810
|
+
status = pjmedia_conf_add_port(ae->conf, call->inv->pool, fp->port, NULL, &fp->slot);
|
|
6764
6811
|
if (status != PJ_SUCCESS) {
|
|
6765
6812
|
set_error("pjmedia_conf_add_port failed");
|
|
6766
6813
|
return false;
|
|
6767
6814
|
}
|
|
6768
6815
|
|
|
6769
|
-
|
|
6816
|
+
fp->connection_mode = CONNECTION_MODE_SOURCE;
|
|
6817
|
+
|
|
6818
|
+
return connect_feature_port_to_stream_port(call, ae, fp);
|
|
6770
6819
|
}
|
|
6771
6820
|
|
|
6772
6821
|
bool prepare_wav_writer(Call *call, AudioEndpoint *ae, const char *file) {
|
|
6773
6822
|
pj_status_t status;
|
|
6774
6823
|
|
|
6824
|
+
ConfBridgePort *fp = &ae->feature_cbps[FP_WAV_WRITER];
|
|
6825
|
+
|
|
6775
6826
|
status = pjmedia_wav_writer_port_create(
|
|
6776
6827
|
call->inv->pool, file, PJMEDIA_PIA_SRATE(&ae->stream_cbp.port->info),
|
|
6777
6828
|
PJMEDIA_PIA_CCNT(&ae->stream_cbp.port->info), PJMEDIA_PIA_SPF(&ae->stream_cbp.port->info),
|
|
6778
6829
|
PJMEDIA_PIA_BITS(&ae->stream_cbp.port->info), PJMEDIA_FILE_WRITE_PCM, 0,
|
|
6779
|
-
(pjmedia_port **)&
|
|
6830
|
+
(pjmedia_port **)&fp->port);
|
|
6780
6831
|
if (status != PJ_SUCCESS) {
|
|
6781
6832
|
set_error("pjmedia_wav_write_port_create failed");
|
|
6782
6833
|
return false;
|
|
6783
6834
|
}
|
|
6784
6835
|
|
|
6785
|
-
status = pjmedia_conf_add_port(ae->conf, call->inv->pool,
|
|
6836
|
+
status = pjmedia_conf_add_port(ae->conf, call->inv->pool, fp->port, NULL, &fp->slot);
|
|
6786
6837
|
if (status != PJ_SUCCESS) {
|
|
6787
6838
|
set_error("pjmedia_conf_add_port failed");
|
|
6788
6839
|
return false;
|
|
6789
6840
|
}
|
|
6790
6841
|
|
|
6791
|
-
|
|
6842
|
+
fp->connection_mode = CONNECTION_MODE_SINK;
|
|
6843
|
+
|
|
6844
|
+
return connect_feature_port_to_stream_port(call, ae, fp);
|
|
6792
6845
|
}
|
|
6793
6846
|
|
|
6794
6847
|
bool prepare_dtmfdet(Call *call, AudioEndpoint *ae) {
|
|
6795
6848
|
pj_status_t status;
|
|
6849
|
+
|
|
6850
|
+
ConfBridgePort *fp = &ae->feature_cbps[FP_DTMFDET];
|
|
6851
|
+
|
|
6796
6852
|
status = pjmedia_dtmfdet_create(
|
|
6797
6853
|
call->inv->pool,
|
|
6798
6854
|
PJMEDIA_PIA_SRATE(&ae->stream_cbp.port->info),
|
|
6799
6855
|
PJMEDIA_PIA_CCNT(&ae->stream_cbp.port->info),
|
|
6800
6856
|
PJMEDIA_PIA_SPF(&ae->stream_cbp.port->info),
|
|
6801
6857
|
PJMEDIA_PIA_BITS(&ae->stream_cbp.port->info),
|
|
6802
|
-
on_inband_dtmf, call, &
|
|
6858
|
+
on_inband_dtmf, call, &fp->port);
|
|
6803
6859
|
if (status != PJ_SUCCESS) {
|
|
6804
6860
|
set_error("pjmedia_dtmfdet_create failed");
|
|
6805
6861
|
return false;
|
|
6806
6862
|
}
|
|
6807
6863
|
|
|
6808
|
-
status = pjmedia_conf_add_port(ae->conf, call->inv->pool,
|
|
6864
|
+
status = pjmedia_conf_add_port(ae->conf, call->inv->pool, fp->port, NULL, &fp->slot);
|
|
6809
6865
|
if (status != PJ_SUCCESS) {
|
|
6810
6866
|
set_error("pjmedia_conf_add_port failed");
|
|
6811
6867
|
return false;
|
|
6812
6868
|
}
|
|
6813
6869
|
|
|
6814
|
-
|
|
6870
|
+
fp->connection_mode = CONNECTION_MODE_SINK;
|
|
6871
|
+
|
|
6872
|
+
return connect_feature_port_to_stream_port(call, ae, fp);
|
|
6815
6873
|
}
|
|
6816
6874
|
|
|
6817
|
-
bool prepare_fax(Call *call, AudioEndpoint *ae, bool is_sender, const char *file,
|
|
6818
|
-
unsigned flags) {
|
|
6875
|
+
bool prepare_fax(Call *call, AudioEndpoint *ae, bool is_sender, const char *file, unsigned flags) {
|
|
6819
6876
|
pj_status_t status;
|
|
6820
6877
|
|
|
6878
|
+
ConfBridgePort *fp = &ae->feature_cbps[FP_FAX];
|
|
6879
|
+
|
|
6821
6880
|
status = pjmedia_fax_port_create(
|
|
6822
6881
|
call->inv->pool,
|
|
6823
6882
|
PJMEDIA_PIA_SRATE(&ae->stream_cbp.port->info),
|
|
@@ -6825,26 +6884,29 @@ bool prepare_fax(Call *call, AudioEndpoint *ae, bool is_sender, const char *file
|
|
|
6825
6884
|
PJMEDIA_PIA_SPF(&ae->stream_cbp.port->info),
|
|
6826
6885
|
PJMEDIA_PIA_BITS(&ae->stream_cbp.port->info),
|
|
6827
6886
|
on_fax_result, call, is_sender, file,
|
|
6828
|
-
flags, &
|
|
6887
|
+
flags, &fp->port);
|
|
6829
6888
|
if (status != PJ_SUCCESS) {
|
|
6830
6889
|
set_error("pjmedia_fax_port_create failed");
|
|
6831
6890
|
return false;
|
|
6832
6891
|
}
|
|
6833
6892
|
|
|
6834
|
-
status = pjmedia_conf_add_port(ae->conf, call->inv->pool,
|
|
6893
|
+
status = pjmedia_conf_add_port(ae->conf, call->inv->pool, fp->port, NULL, &fp->slot);
|
|
6835
6894
|
if (status != PJ_SUCCESS) {
|
|
6836
6895
|
set_error("pjmedia_conf_add_port failed");
|
|
6837
6896
|
return false;
|
|
6838
6897
|
}
|
|
6839
6898
|
|
|
6840
|
-
|
|
6899
|
+
fp->connection_mode = CONNECTION_MODE_SOURCE_AND_SINK;
|
|
6900
|
+
|
|
6901
|
+
return connect_feature_port_to_stream_port(call, ae, fp);
|
|
6841
6902
|
}
|
|
6842
6903
|
|
|
6843
6904
|
bool prepare_flite(Call *call, AudioEndpoint *ae, const char *voice, bool end_of_speech_event) {
|
|
6844
|
-
printf("prepare_flite call.id=%i\n", call->id);
|
|
6845
6905
|
pj_status_t status;
|
|
6846
6906
|
|
|
6847
|
-
|
|
6907
|
+
ConfBridgePort *fp = &ae->feature_cbps[FP_SPEECH_SYNTH];
|
|
6908
|
+
|
|
6909
|
+
if(fp->port) {
|
|
6848
6910
|
printf("already prepared\n");
|
|
6849
6911
|
return true;
|
|
6850
6912
|
}
|
|
@@ -6853,34 +6915,39 @@ bool prepare_flite(Call *call, AudioEndpoint *ae, const char *voice, bool end_of
|
|
|
6853
6915
|
call->inv->pool, PJMEDIA_PIA_SRATE(&ae->stream_cbp.port->info),
|
|
6854
6916
|
PJMEDIA_PIA_CCNT(&ae->stream_cbp.port->info),
|
|
6855
6917
|
PJMEDIA_PIA_SPF(&ae->stream_cbp.port->info),
|
|
6856
|
-
PJMEDIA_PIA_BITS(&ae->stream_cbp.port->info),
|
|
6918
|
+
PJMEDIA_PIA_BITS(&ae->stream_cbp.port->info),
|
|
6919
|
+
voice,
|
|
6920
|
+
&fp->port);
|
|
6857
6921
|
if (status != PJ_SUCCESS) {
|
|
6858
6922
|
set_error("pjmedia_flite_port_create failed");
|
|
6859
6923
|
return false;
|
|
6860
6924
|
}
|
|
6861
6925
|
|
|
6862
6926
|
if (end_of_speech_event) {
|
|
6863
|
-
status = pjmedia_flite_port_set_eof_cb(
|
|
6927
|
+
status = pjmedia_flite_port_set_eof_cb(fp->port, (void*)call, on_end_of_speech);
|
|
6864
6928
|
if (status != PJ_SUCCESS) {
|
|
6865
6929
|
set_error("pjmedia_flite_port_set_eof_cb failed");
|
|
6866
6930
|
return false;
|
|
6867
6931
|
}
|
|
6868
6932
|
}
|
|
6869
6933
|
|
|
6870
|
-
status = pjmedia_conf_add_port(ae->conf, call->inv->pool,
|
|
6934
|
+
status = pjmedia_conf_add_port(ae->conf, call->inv->pool, fp->port, NULL, &fp->slot);
|
|
6871
6935
|
if (status != PJ_SUCCESS) {
|
|
6872
6936
|
set_error("pjmedia_conf_add_port failed");
|
|
6873
6937
|
return false;
|
|
6874
6938
|
}
|
|
6875
6939
|
|
|
6876
|
-
|
|
6940
|
+
fp->connection_mode = CONNECTION_MODE_SOURCE;
|
|
6941
|
+
|
|
6942
|
+
return connect_feature_port_to_stream_port(call, ae, fp);
|
|
6877
6943
|
}
|
|
6878
6944
|
|
|
6879
6945
|
bool prepare_pocketsphinx(Call *call, AudioEndpoint *ae) {
|
|
6880
|
-
printf("prepare_pocketsphinx call.id=%i\n", call->id);
|
|
6881
6946
|
pj_status_t status;
|
|
6882
6947
|
|
|
6883
|
-
|
|
6948
|
+
ConfBridgePort *fp = &ae->feature_cbps[FP_SPEECH_RECOG];
|
|
6949
|
+
|
|
6950
|
+
if(fp->port) {
|
|
6884
6951
|
printf("already prepared\n");
|
|
6885
6952
|
return true;
|
|
6886
6953
|
}
|
|
@@ -6892,19 +6959,21 @@ bool prepare_pocketsphinx(Call *call, AudioEndpoint *ae) {
|
|
|
6892
6959
|
PJMEDIA_PIA_BITS(&ae->stream_cbp.port->info),
|
|
6893
6960
|
on_speech_transcript,
|
|
6894
6961
|
call,
|
|
6895
|
-
&
|
|
6962
|
+
&fp->port);
|
|
6896
6963
|
if (status != PJ_SUCCESS) {
|
|
6897
6964
|
set_error("pjmedia_pocketsphinx_port_create failed");
|
|
6898
6965
|
return false;
|
|
6899
6966
|
}
|
|
6900
6967
|
|
|
6901
|
-
status = pjmedia_conf_add_port(ae->conf, call->inv->pool,
|
|
6968
|
+
status = pjmedia_conf_add_port(ae->conf, call->inv->pool, fp->port, NULL, &fp->slot);
|
|
6902
6969
|
if (status != PJ_SUCCESS) {
|
|
6903
6970
|
set_error("pjmedia_conf_add_port failed");
|
|
6904
6971
|
return false;
|
|
6905
6972
|
}
|
|
6906
6973
|
|
|
6907
|
-
|
|
6974
|
+
fp->connection_mode = CONNECTION_MODE_SINK;
|
|
6975
|
+
|
|
6976
|
+
return connect_feature_port_to_stream_port(call, ae, fp);
|
|
6908
6977
|
}
|
|
6909
6978
|
|
|
6910
6979
|
void on_rx_notify(pjsip_evsub *sub, pjsip_rx_data *rdata, int *p_st_code,
|