sip-lab 1.23.0 → 1.27.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.
- package/README.md +3 -3
- package/binding.gyp +4 -0
- package/build_deps.sh +19 -0
- package/index.js +18 -0
- package/package.json +4 -2
- package/pocketsphinx/model/CMakeLists.txt +3 -0
- package/pocketsphinx/model/en-us/cmudict-en-us.dict +134782 -0
- package/pocketsphinx/model/en-us/en-us/README +34 -0
- package/pocketsphinx/model/en-us/en-us/feat.params +12 -0
- package/pocketsphinx/model/en-us/en-us/mdef +0 -0
- package/pocketsphinx/model/en-us/en-us/means +0 -0
- package/pocketsphinx/model/en-us/en-us/noisedict +5 -0
- package/pocketsphinx/model/en-us/en-us/sendump +0 -0
- package/pocketsphinx/model/en-us/en-us/transition_matrices +0 -0
- package/pocketsphinx/model/en-us/en-us/variances +0 -0
- package/pocketsphinx/model/en-us/en-us-phone.lm.bin +0 -0
- package/pocketsphinx/model/en-us/en-us.lm.bin +0 -0
- package/prebuilds/linux-x64/sip-lab.node +0 -0
- package/runtests +80 -0
- package/samples/artifacts/hello_good_morning.wav +0 -0
- package/samples/play_wav_and_speech_recog.bad_transcript.pcmu8000.js +182 -0
- package/samples/speech_synth_and_recog.speex16000.js +186 -0
- package/samples/tcp_and_extra_headers.js +44 -1
- package/src/addon.cpp +37 -0
- package/src/event_templates.cpp +6 -0
- package/src/event_templates.hpp +2 -0
- package/src/pjmedia/include/pjmedia/pocketsphinx_port.h +19 -0
- package/src/pjmedia/src/pjmedia/flite_port.c +4 -7
- package/src/pjmedia/src/pjmedia/pocketsphinx_port.c +169 -46
- package/src/sip.cpp +464 -293
- package/src/sip.hpp +3 -0
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
|
|
|
@@ -23,6 +24,7 @@
|
|
|
23
24
|
#include "dtmfdet.h"
|
|
24
25
|
#include "fax_port.h"
|
|
25
26
|
#include "flite_port.h"
|
|
27
|
+
#include "pocketsphinx_port.h"
|
|
26
28
|
|
|
27
29
|
#include <ctime>
|
|
28
30
|
|
|
@@ -265,14 +267,6 @@ pjsip_route_hdr route_set;
|
|
|
265
267
|
pjsip_route_hdr *route;
|
|
266
268
|
const pj_str_t hname = pj_str((char *)"Route");
|
|
267
269
|
|
|
268
|
-
#define CONF_PORTS 1024
|
|
269
|
-
//#define CLOCK_RATE 16000
|
|
270
|
-
#define CLOCK_RATE 8000
|
|
271
|
-
#define CHANNEL_COUNT 1
|
|
272
|
-
#define PTIME 20
|
|
273
|
-
#define SAMPLES_PER_FRAME (CLOCK_RATE*PTIME/1000)
|
|
274
|
-
#define BITS_PER_SAMPLE 16
|
|
275
|
-
|
|
276
270
|
#define MAXDIGITS 256
|
|
277
271
|
|
|
278
272
|
#define DTMF_MODE_RFC2833 0
|
|
@@ -312,8 +306,18 @@ struct Subscription {
|
|
|
312
306
|
struct ConfBridgePort {
|
|
313
307
|
unsigned slot;
|
|
314
308
|
pjmedia_port *port;
|
|
309
|
+
short connection_mode;
|
|
315
310
|
};
|
|
316
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
|
+
|
|
317
321
|
struct AudioEndpoint {
|
|
318
322
|
pjmedia_transport *med_transport;
|
|
319
323
|
pjmedia_stream *med_stream;
|
|
@@ -324,13 +328,12 @@ struct AudioEndpoint {
|
|
|
324
328
|
|
|
325
329
|
pj_str_t mode;
|
|
326
330
|
|
|
331
|
+
pjmedia_conf *conf;
|
|
332
|
+
pjmedia_master_port *master_port;
|
|
333
|
+
pjmedia_port *null_port;
|
|
334
|
+
|
|
327
335
|
ConfBridgePort stream_cbp;
|
|
328
|
-
ConfBridgePort
|
|
329
|
-
ConfBridgePort wav_writer_cbp;
|
|
330
|
-
ConfBridgePort tonegen_cbp;
|
|
331
|
-
ConfBridgePort dtmfdet_cbp;
|
|
332
|
-
ConfBridgePort fax_cbp;
|
|
333
|
-
ConfBridgePort flite_cbp;
|
|
336
|
+
ConfBridgePort feature_cbps[MAX_FP];
|
|
334
337
|
};
|
|
335
338
|
|
|
336
339
|
struct VideoEndpoint {
|
|
@@ -433,10 +436,6 @@ struct Call {
|
|
|
433
436
|
pjmedia_sdp_session *active_remote_sdp;
|
|
434
437
|
|
|
435
438
|
bool local_sdp_answer_already_set;
|
|
436
|
-
|
|
437
|
-
pjmedia_conf *conf;
|
|
438
|
-
pjmedia_master_port *master_port;
|
|
439
|
-
pjmedia_port *null_port;
|
|
440
439
|
};
|
|
441
440
|
|
|
442
441
|
#define MAX_TCP_DATA 4096
|
|
@@ -472,6 +471,10 @@ PackageSet g_PackageSet;
|
|
|
472
471
|
|
|
473
472
|
#define DEFAULT_EXPIRES 600
|
|
474
473
|
|
|
474
|
+
#define CONNECTION_MODE_SOURCE 0
|
|
475
|
+
#define CONNECTION_MODE_SINK 1
|
|
476
|
+
#define CONNECTION_MODE_SOURCE_AND_SINK 2
|
|
477
|
+
|
|
475
478
|
void handle_events() {
|
|
476
479
|
pj_time_val tv = {0, 1};
|
|
477
480
|
pjsip_endpt_handle_events(g_sip_endpt, &tv);
|
|
@@ -618,23 +621,23 @@ static void build_stream_stat(ostringstream &oss, pjmedia_rtcp_stat *stat,
|
|
|
618
621
|
|
|
619
622
|
bool prepare_tonegen(Call *call, AudioEndpoint *ae);
|
|
620
623
|
bool prepare_dtmfdet(Call *call, AudioEndpoint *ae);
|
|
621
|
-
bool prepare_wav_player(Call *
|
|
622
|
-
bool prepare_wav_writer(Call *
|
|
623
|
-
bool prepare_fax(Call *
|
|
624
|
-
|
|
625
|
-
bool
|
|
624
|
+
bool prepare_wav_player(Call *call, AudioEndpoint *ae, const char *file, unsigned flags, bool end_of_file_event);
|
|
625
|
+
bool prepare_wav_writer(Call *call, AudioEndpoint *ae, const char *file);
|
|
626
|
+
bool prepare_fax(Call *call, AudioEndpoint *ae, bool is_sender, const char *file, unsigned flags);
|
|
627
|
+
bool prepare_flite(Call *call, AudioEndpoint *ae, const char *voice, bool end_of_speech_event);
|
|
628
|
+
bool prepare_pocketsphinx(Call *call, AudioEndpoint *ae);
|
|
626
629
|
|
|
627
630
|
void prepare_error_event(ostringstream *oss, char *scope, char *details);
|
|
628
631
|
// void prepare_pjsipcall_error_event(ostringstream *oss, char *scope, char
|
|
629
632
|
// *function, pj_status_t s);
|
|
630
633
|
void append_status(ostringstream *oss, pj_status_t s);
|
|
631
634
|
|
|
632
|
-
bool is_media_active(Call *
|
|
635
|
+
bool is_media_active(Call *call, MediaEndpoint *me);
|
|
633
636
|
void close_media_endpoint(Call *call, MediaEndpoint *me);
|
|
634
637
|
|
|
635
|
-
void close_media(Call *
|
|
638
|
+
void close_media(Call *call);
|
|
636
639
|
|
|
637
|
-
bool process_media(Call *
|
|
640
|
+
bool process_media(Call *call, pjsip_dialog *dlg, Document &document, bool answer);
|
|
638
641
|
|
|
639
642
|
typedef pj_status_t (*audio_endpoint_stop_op_t)(Call *call, AudioEndpoint *ae);
|
|
640
643
|
|
|
@@ -642,6 +645,7 @@ pj_status_t audio_endpoint_stop_play_wav(Call *call, AudioEndpoint *ae);
|
|
|
642
645
|
pj_status_t audio_endpoint_stop_record_wav(Call *call, AudioEndpoint *ae);
|
|
643
646
|
pj_status_t audio_endpoint_stop_fax(Call *call, AudioEndpoint *ae);
|
|
644
647
|
pj_status_t audio_endpoint_stop_speech_synth(Call *call, AudioEndpoint *ae);
|
|
648
|
+
pj_status_t audio_endpoint_stop_speech_recog(Call *call, AudioEndpoint *ae);
|
|
645
649
|
|
|
646
650
|
static pjsip_module mod_tester = {
|
|
647
651
|
NULL,
|
|
@@ -716,23 +720,36 @@ find_endpoint_by_inband_dtmf_media_stream(Call *call,
|
|
|
716
720
|
return -1;
|
|
717
721
|
}
|
|
718
722
|
|
|
719
|
-
pj_status_t
|
|
723
|
+
pj_status_t create_audio_endpoint_conf(Call *call, AudioEndpoint *ae, pjmedia_port *stream_port) {
|
|
720
724
|
pj_status_t status;
|
|
725
|
+
int conf_ports = 16;
|
|
726
|
+
|
|
727
|
+
unsigned sampling_rate = PJMEDIA_PIA_SRATE(&stream_port->info);
|
|
728
|
+
unsigned channel_count = PJMEDIA_PIA_CCNT(&stream_port->info);
|
|
729
|
+
unsigned samples_per_frame = PJMEDIA_PIA_SPF(&stream_port->info);
|
|
730
|
+
unsigned bits_per_sample = PJMEDIA_PIA_BITS(&stream_port->info);
|
|
731
|
+
|
|
721
732
|
status = pjmedia_conf_create(call->inv->pool,
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
733
|
+
conf_ports,
|
|
734
|
+
sampling_rate,
|
|
735
|
+
channel_count,
|
|
736
|
+
samples_per_frame,
|
|
737
|
+
bits_per_sample,
|
|
727
738
|
PJMEDIA_CONF_NO_DEVICE,
|
|
728
|
-
&
|
|
739
|
+
&ae->conf);
|
|
729
740
|
|
|
730
741
|
if (status != PJ_SUCCESS) {
|
|
731
742
|
addon_log(L_DBG, "pjmedia_conf_create failed\n");
|
|
732
743
|
return false;
|
|
733
744
|
}
|
|
734
745
|
|
|
735
|
-
status = pjmedia_null_port_create(
|
|
746
|
+
status = pjmedia_null_port_create(
|
|
747
|
+
call->inv->pool,
|
|
748
|
+
sampling_rate,
|
|
749
|
+
channel_count,
|
|
750
|
+
samples_per_frame,
|
|
751
|
+
bits_per_sample,
|
|
752
|
+
&ae->null_port);
|
|
736
753
|
if (status != PJ_SUCCESS) {
|
|
737
754
|
addon_log(L_DBG, "pjmedia_null_port_created failed\n");
|
|
738
755
|
return false;
|
|
@@ -740,19 +757,19 @@ pj_status_t setup_call_conf(Call *call) {
|
|
|
740
757
|
|
|
741
758
|
pjmedia_port *conf_port = NULL;
|
|
742
759
|
|
|
743
|
-
conf_port = pjmedia_conf_get_master_port(
|
|
760
|
+
conf_port = pjmedia_conf_get_master_port(ae->conf);
|
|
744
761
|
if (conf_port == NULL) {
|
|
745
762
|
addon_log(L_DBG, "pjmedia_conf_get_master_port failed\n");
|
|
746
763
|
return false;
|
|
747
764
|
}
|
|
748
765
|
|
|
749
|
-
status = pjmedia_master_port_create(call->inv->pool,
|
|
766
|
+
status = pjmedia_master_port_create(call->inv->pool, ae->null_port, conf_port, 0, &ae->master_port);
|
|
750
767
|
if (status != PJ_SUCCESS) {
|
|
751
768
|
addon_log(L_DBG, "pjmedia_master_port_create failed\n");
|
|
752
769
|
return false;
|
|
753
770
|
}
|
|
754
771
|
|
|
755
|
-
status = pjmedia_master_port_start(
|
|
772
|
+
status = pjmedia_master_port_start(ae->master_port);
|
|
756
773
|
if (status != PJ_SUCCESS) {
|
|
757
774
|
addon_log(L_DBG, "pjmedia_master_port_start failed\n");
|
|
758
775
|
return false;
|
|
@@ -761,45 +778,13 @@ pj_status_t setup_call_conf(Call *call) {
|
|
|
761
778
|
return PJ_SUCCESS;
|
|
762
779
|
}
|
|
763
780
|
|
|
764
|
-
void release_call_conf(Call *call) {
|
|
765
|
-
pj_status_t status;
|
|
766
|
-
|
|
767
|
-
if (call->master_port) {
|
|
768
|
-
status = pjmedia_master_port_stop(call->master_port);
|
|
769
|
-
if(status != PJ_SUCCESS) {
|
|
770
|
-
addon_log(L_DBG, "pjmedia_master_port_stop failed\n");
|
|
771
|
-
}
|
|
772
|
-
pjmedia_master_port_destroy(call->master_port, 0);
|
|
773
|
-
if(status != PJ_SUCCESS) {
|
|
774
|
-
addon_log(L_DBG, "pjmedia_master_port_destroy failed\n");
|
|
775
|
-
}
|
|
776
|
-
call->master_port = NULL;
|
|
777
|
-
}
|
|
778
|
-
|
|
779
|
-
if (call->conf) {
|
|
780
|
-
status = pjmedia_conf_destroy(call->conf);
|
|
781
|
-
if(status != PJ_SUCCESS) {
|
|
782
|
-
addon_log(L_DBG, "pjmedia_conf_destroy failed\n");
|
|
783
|
-
}
|
|
784
|
-
call->conf = NULL;
|
|
785
|
-
}
|
|
786
|
-
|
|
787
|
-
if (call->null_port) {
|
|
788
|
-
status = pjmedia_port_destroy(call->null_port);
|
|
789
|
-
if(status != PJ_SUCCESS) {
|
|
790
|
-
addon_log(L_DBG, "pjmedia_port_destroy(null_port) failed\n");
|
|
791
|
-
}
|
|
792
|
-
call->null_port = NULL;
|
|
793
|
-
}
|
|
794
|
-
}
|
|
795
|
-
|
|
796
781
|
static int find_endpoint_by_inband_dtmf_media_port(Call *call,
|
|
797
782
|
pjmedia_port *port) {
|
|
798
783
|
for (int i = 0; i < call->media_count; i++) {
|
|
799
784
|
MediaEndpoint *me = (MediaEndpoint *)call->media[i];
|
|
800
785
|
if (ENDPOINT_TYPE_AUDIO == me->type) {
|
|
801
786
|
AudioEndpoint *ae = (AudioEndpoint *)me->endpoint.audio;
|
|
802
|
-
if (ae->
|
|
787
|
+
if (ae->feature_cbps[FP_DTMFDET].port && (pjmedia_port *)ae->feature_cbps[FP_DTMFDET].port == port) {
|
|
803
788
|
return i;
|
|
804
789
|
}
|
|
805
790
|
}
|
|
@@ -905,6 +890,22 @@ static void on_end_of_speech(pjmedia_port *port, void *user_data) {
|
|
|
905
890
|
dispatch_event(evt);
|
|
906
891
|
}
|
|
907
892
|
|
|
893
|
+
static void on_speech_transcript(pjmedia_port*, void *user_data, char* transcript) {
|
|
894
|
+
if (g_shutting_down)
|
|
895
|
+
return;
|
|
896
|
+
|
|
897
|
+
long call_id;
|
|
898
|
+
if (!g_call_ids.get_id((long)user_data, call_id)) {
|
|
899
|
+
addon_log(
|
|
900
|
+
L_DBG,
|
|
901
|
+
"on_speech_transcript: Failed to get call_id. Event will not be notified.\n");
|
|
902
|
+
return;
|
|
903
|
+
}
|
|
904
|
+
|
|
905
|
+
char evt[1024];
|
|
906
|
+
make_evt_speech_transcript(evt, sizeof(evt), call_id, transcript);
|
|
907
|
+
dispatch_event(evt);
|
|
908
|
+
}
|
|
908
909
|
|
|
909
910
|
void dispatch_event(const char *evt) {
|
|
910
911
|
addon_log(L_DBG, "dispach_event called with evt=%s\n", evt);
|
|
@@ -2800,9 +2801,47 @@ bool dlg_set_transport_by_t(Transport *t, pjsip_dialog *dlg) {
|
|
|
2800
2801
|
return true;
|
|
2801
2802
|
}
|
|
2802
2803
|
|
|
2803
|
-
|
|
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,
|
|
2804
2810
|
int port) {
|
|
2805
|
-
|
|
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);
|
|
2806
2845
|
}
|
|
2807
2846
|
|
|
2808
2847
|
void build_transport_tag_from_pjsip_transport(char *dest, pjsip_transport *t) {
|
|
@@ -2814,6 +2853,7 @@ void build_transport_tag_from_pjsip_transport(char *dest, pjsip_transport *t) {
|
|
|
2814
2853
|
assert(t->local_name.host.slen < 16);
|
|
2815
2854
|
strncpy(address, t->local_name.host.ptr, t->local_name.host.slen);
|
|
2816
2855
|
address[t->local_name.host.slen] = 0;
|
|
2856
|
+
printf("build_transport_tag_from_pjsip_transport address=%s\n", address);
|
|
2817
2857
|
|
|
2818
2858
|
if (t->key.type == PJSIP_TRANSPORT_UDP) {
|
|
2819
2859
|
type = "udp";
|
|
@@ -3047,12 +3087,6 @@ int call_create(Transport *t, unsigned flags, pjsip_dialog *dlg,
|
|
|
3047
3087
|
}
|
|
3048
3088
|
// addon_log(L_DBG, "pjsip_dlg_add_usage OK\n");
|
|
3049
3089
|
|
|
3050
|
-
status = setup_call_conf(call);
|
|
3051
|
-
if (status != PJ_SUCCESS) {
|
|
3052
|
-
set_error("setup_call_conf failed");
|
|
3053
|
-
return -1;
|
|
3054
|
-
}
|
|
3055
|
-
|
|
3056
3090
|
return call_id;
|
|
3057
3091
|
}
|
|
3058
3092
|
|
|
@@ -3092,7 +3126,7 @@ pj_status_t audio_endpoint_send_dtmf(Call *call, AudioEndpoint *ae,
|
|
|
3092
3126
|
tone.on_msec = ON_DURATION;
|
|
3093
3127
|
tone.off_msec = OFF_DURATION;
|
|
3094
3128
|
tone.volume = 0;
|
|
3095
|
-
status = pjmedia_tonegen_play_digits((pjmedia_port *)ae->
|
|
3129
|
+
status = pjmedia_tonegen_play_digits((pjmedia_port *)ae->feature_cbps[FP_TONEGEN].port, 1,
|
|
3096
3130
|
&tone, 0);
|
|
3097
3131
|
if (status != PJ_SUCCESS) {
|
|
3098
3132
|
set_error("pjmedia_tonegen_play_digits failed.");
|
|
@@ -3251,7 +3285,7 @@ out:
|
|
|
3251
3285
|
return 0;
|
|
3252
3286
|
}
|
|
3253
3287
|
|
|
3254
|
-
pj_status_t audio_endpoint_remove_port(Call *call, ConfBridgePort *cbp) {
|
|
3288
|
+
pj_status_t audio_endpoint_remove_port(Call *call, AudioEndpoint *ae, ConfBridgePort *cbp) {
|
|
3255
3289
|
printf("audio_endpoint_remove_port\n");
|
|
3256
3290
|
pj_status_t status;
|
|
3257
3291
|
|
|
@@ -3262,7 +3296,7 @@ pj_status_t audio_endpoint_remove_port(Call *call, ConfBridgePort *cbp) {
|
|
|
3262
3296
|
pjmedia_conf_disconnect_port_from_sinks(conf, port);
|
|
3263
3297
|
*/
|
|
3264
3298
|
|
|
3265
|
-
status = pjmedia_conf_remove_port(
|
|
3299
|
+
status = pjmedia_conf_remove_port(ae->conf, cbp->slot);
|
|
3266
3300
|
if (status != PJ_SUCCESS) {
|
|
3267
3301
|
set_error("pjmedia_conf_remove_port failed");
|
|
3268
3302
|
return false;
|
|
@@ -3799,7 +3833,7 @@ pj_status_t audio_endpoint_start_speech_synth(Call *call, AudioEndpoint *ae, con
|
|
|
3799
3833
|
return -1;
|
|
3800
3834
|
}
|
|
3801
3835
|
|
|
3802
|
-
pjmedia_flite_port_speak(ae->
|
|
3836
|
+
pjmedia_flite_port_speak(ae->feature_cbps[FP_SPEECH_SYNTH].port, text, flags);
|
|
3803
3837
|
|
|
3804
3838
|
return PJ_SUCCESS;
|
|
3805
3839
|
}
|
|
@@ -3928,6 +3962,121 @@ out:
|
|
|
3928
3962
|
return 0;
|
|
3929
3963
|
}
|
|
3930
3964
|
|
|
3965
|
+
pj_status_t audio_endpoint_start_speech_recog(Call *call, AudioEndpoint *ae) {
|
|
3966
|
+
pj_status_t status;
|
|
3967
|
+
|
|
3968
|
+
if(!ae->stream_cbp.port) {
|
|
3969
|
+
set_error("stream port is not ready yet");
|
|
3970
|
+
return -1;
|
|
3971
|
+
}
|
|
3972
|
+
|
|
3973
|
+
// First stop and destroy existing port.
|
|
3974
|
+
status = audio_endpoint_stop_speech_recog(call, ae);
|
|
3975
|
+
if(status != PJ_SUCCESS) {
|
|
3976
|
+
return -1;
|
|
3977
|
+
}
|
|
3978
|
+
|
|
3979
|
+
if (!prepare_pocketsphinx(call, ae)) {
|
|
3980
|
+
return -1;
|
|
3981
|
+
}
|
|
3982
|
+
|
|
3983
|
+
return PJ_SUCCESS;
|
|
3984
|
+
}
|
|
3985
|
+
|
|
3986
|
+
int pjw_call_start_speech_recog(long call_id, const char *json) {
|
|
3987
|
+
PJW_LOCK();
|
|
3988
|
+
clear_error();
|
|
3989
|
+
|
|
3990
|
+
long val;
|
|
3991
|
+
Call *call;
|
|
3992
|
+
|
|
3993
|
+
pj_status_t status;
|
|
3994
|
+
|
|
3995
|
+
MediaEndpoint *me;
|
|
3996
|
+
AudioEndpoint *ae;
|
|
3997
|
+
int ae_count;
|
|
3998
|
+
int res;
|
|
3999
|
+
|
|
4000
|
+
int media_id = -1;
|
|
4001
|
+
|
|
4002
|
+
char *voice;
|
|
4003
|
+
|
|
4004
|
+
char *text;
|
|
4005
|
+
|
|
4006
|
+
bool end_of_speech_event = false;
|
|
4007
|
+
|
|
4008
|
+
unsigned flags = 0;
|
|
4009
|
+
|
|
4010
|
+
bool no_loop = false;
|
|
4011
|
+
|
|
4012
|
+
char buffer[MAX_JSON_INPUT];
|
|
4013
|
+
|
|
4014
|
+
Document document;
|
|
4015
|
+
|
|
4016
|
+
const char *valid_params[] = {"media_id", ""};
|
|
4017
|
+
|
|
4018
|
+
if (!g_call_ids.get(call_id, val)) {
|
|
4019
|
+
set_error("Invalid call_id");
|
|
4020
|
+
goto out;
|
|
4021
|
+
}
|
|
4022
|
+
call = (Call *)val;
|
|
4023
|
+
|
|
4024
|
+
ae_count = count_media_by_type(call, ENDPOINT_TYPE_AUDIO);
|
|
4025
|
+
|
|
4026
|
+
if (ae_count == 0) {
|
|
4027
|
+
set_error("No audio endpoint");
|
|
4028
|
+
goto out;
|
|
4029
|
+
}
|
|
4030
|
+
|
|
4031
|
+
if (!parse_json(document, json, buffer, MAX_JSON_INPUT)) {
|
|
4032
|
+
goto out;
|
|
4033
|
+
}
|
|
4034
|
+
|
|
4035
|
+
if (!validate_params(document, valid_params)) {
|
|
4036
|
+
goto out;
|
|
4037
|
+
}
|
|
4038
|
+
|
|
4039
|
+
res = json_get_int_param(document, "media_id", true, &media_id);
|
|
4040
|
+
if (res <= 0) {
|
|
4041
|
+
goto out;
|
|
4042
|
+
}
|
|
4043
|
+
|
|
4044
|
+
if (NOT_FOUND_OPTIONAL == res) {
|
|
4045
|
+
// start on all audio media endpoints
|
|
4046
|
+
for (int i = 0; i < call->media_count; i++) {
|
|
4047
|
+
MediaEndpoint *me = (MediaEndpoint *)call->media[i];
|
|
4048
|
+
if (me->type == ENDPOINT_TYPE_AUDIO) {
|
|
4049
|
+
AudioEndpoint *ae = (AudioEndpoint *)me->endpoint.audio;
|
|
4050
|
+
status = audio_endpoint_start_speech_recog(call, ae);
|
|
4051
|
+
if (status != PJ_SUCCESS) goto out;
|
|
4052
|
+
}
|
|
4053
|
+
}
|
|
4054
|
+
} else {
|
|
4055
|
+
if ((int)media_id >= call->media_count) {
|
|
4056
|
+
set_error("invalid media_id");
|
|
4057
|
+
goto out;
|
|
4058
|
+
}
|
|
4059
|
+
|
|
4060
|
+
me = (MediaEndpoint *)call->media[media_id];
|
|
4061
|
+
if (ENDPOINT_TYPE_AUDIO != me->type) {
|
|
4062
|
+
set_error("media_endpoint is not audio endpoint");
|
|
4063
|
+
goto out;
|
|
4064
|
+
}
|
|
4065
|
+
|
|
4066
|
+
ae = (AudioEndpoint *)me->endpoint.audio;
|
|
4067
|
+
|
|
4068
|
+
audio_endpoint_start_speech_recog(call, ae);
|
|
4069
|
+
}
|
|
4070
|
+
|
|
4071
|
+
out:
|
|
4072
|
+
PJW_UNLOCK();
|
|
4073
|
+
if (pjw_errorstring[0]) {
|
|
4074
|
+
return -1;
|
|
4075
|
+
}
|
|
4076
|
+
|
|
4077
|
+
return 0;
|
|
4078
|
+
}
|
|
4079
|
+
|
|
3931
4080
|
pj_status_t call_stop_op_on_all_audio_endpoints(Call *call,
|
|
3932
4081
|
audio_endpoint_stop_op_t op) {
|
|
3933
4082
|
addon_log(L_DBG, "call_stop_op_on_audio_endpoints media_count=%d\n",
|
|
@@ -4017,28 +4166,27 @@ out:
|
|
|
4017
4166
|
return 0;
|
|
4018
4167
|
}
|
|
4019
4168
|
|
|
4020
|
-
pj_status_t audio_endpoint_stop_speech_synth(Call *call, AudioEndpoint *ae) {
|
|
4021
|
-
return audio_endpoint_remove_port(call, &ae->flite_cbp);
|
|
4022
|
-
}
|
|
4023
|
-
|
|
4024
4169
|
pj_status_t audio_endpoint_stop_play_wav(Call *call, AudioEndpoint *ae) {
|
|
4025
|
-
return audio_endpoint_remove_port(call, &ae->
|
|
4170
|
+
return audio_endpoint_remove_port(call, ae, &ae->feature_cbps[FP_WAV_PLAYER]);
|
|
4026
4171
|
}
|
|
4027
4172
|
|
|
4028
4173
|
pj_status_t audio_endpoint_stop_record_wav(Call *call, AudioEndpoint *ae) {
|
|
4029
|
-
return audio_endpoint_remove_port(call, &ae->
|
|
4174
|
+
return audio_endpoint_remove_port(call, ae, &ae->feature_cbps[FP_WAV_WRITER]);
|
|
4030
4175
|
}
|
|
4031
4176
|
|
|
4032
4177
|
pj_status_t audio_endpoint_stop_fax(Call *call, AudioEndpoint *ae) {
|
|
4033
|
-
return audio_endpoint_remove_port(call, &ae->
|
|
4178
|
+
return audio_endpoint_remove_port(call, ae, &ae->feature_cbps[FP_FAX]);
|
|
4034
4179
|
}
|
|
4035
4180
|
|
|
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]);
|
|
4183
|
+
}
|
|
4036
4184
|
|
|
4037
|
-
|
|
4038
|
-
|
|
4039
|
-
return audio_endpoint_stop_op(call_id, json, audio_endpoint_stop_speech_synth);
|
|
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]);
|
|
4040
4187
|
}
|
|
4041
4188
|
|
|
4189
|
+
|
|
4042
4190
|
int pjw_call_stop_play_wav(long call_id, const char *json) {
|
|
4043
4191
|
return audio_endpoint_stop_op(call_id, json, audio_endpoint_stop_play_wav);
|
|
4044
4192
|
}
|
|
@@ -4051,6 +4199,14 @@ int pjw_call_stop_fax(long call_id, const char *json) {
|
|
|
4051
4199
|
return audio_endpoint_stop_op(call_id, json, audio_endpoint_stop_fax);
|
|
4052
4200
|
}
|
|
4053
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
|
+
|
|
4054
4210
|
|
|
4055
4211
|
int pjw_call_start_fax(long call_id, const char *json) {
|
|
4056
4212
|
PJW_LOCK();
|
|
@@ -4523,82 +4679,77 @@ bool start_tcp_media(Call *call, MediaEndpoint *me,
|
|
|
4523
4679
|
return true;
|
|
4524
4680
|
}
|
|
4525
4681
|
|
|
4682
|
+
void close_audio_endpoint_ports_and_conf(Call *call, AudioEndpoint *ae) {
|
|
4683
|
+
pj_status_t status;
|
|
4526
4684
|
|
|
4527
|
-
|
|
4528
|
-
const pjmedia_sdp_session *local_sdp,
|
|
4529
|
-
const pjmedia_sdp_session *remote_sdp, int idx) {
|
|
4530
|
-
char evt[4096];
|
|
4531
|
-
pjmedia_stream_info stream_info;
|
|
4532
|
-
|
|
4533
|
-
AudioEndpoint *ae = (AudioEndpoint *)me->endpoint.audio;
|
|
4534
|
-
|
|
4535
|
-
pj_status_t status;
|
|
4685
|
+
audio_endpoint_remove_port(call, ae, &ae->stream_cbp);
|
|
4536
4686
|
|
|
4537
|
-
|
|
4538
|
-
|
|
4539
|
-
status = pjmedia_conf_disconnect_port(call->conf, ae->tonegen_cbp.slot, ae->stream_cbp.slot);
|
|
4540
|
-
if (status != PJ_SUCCESS) {
|
|
4541
|
-
make_evt_media_update(evt, sizeof(evt), call->id,
|
|
4542
|
-
"setup_failed (pjmedia_conf_disconnect_port for tonegen failed)", "");
|
|
4543
|
-
dispatch_event(evt);
|
|
4544
|
-
return false;
|
|
4545
|
-
}
|
|
4687
|
+
for(int i=0 ; i<MAX_FP ; i++) {
|
|
4688
|
+
audio_endpoint_remove_port(call, ae, &ae->feature_cbps[i]);
|
|
4546
4689
|
}
|
|
4547
4690
|
|
|
4548
|
-
if(ae->
|
|
4549
|
-
|
|
4550
|
-
|
|
4551
|
-
|
|
4552
|
-
|
|
4553
|
-
|
|
4554
|
-
|
|
4555
|
-
|
|
4691
|
+
if (ae->master_port) {
|
|
4692
|
+
status = pjmedia_master_port_stop(ae->master_port);
|
|
4693
|
+
if(status != PJ_SUCCESS) {
|
|
4694
|
+
addon_log(L_DBG, "pjmedia_master_port_stop failed\n");
|
|
4695
|
+
}
|
|
4696
|
+
pjmedia_master_port_destroy(ae->master_port, 0);
|
|
4697
|
+
if(status != PJ_SUCCESS) {
|
|
4698
|
+
addon_log(L_DBG, "pjmedia_master_port_destroy failed\n");
|
|
4699
|
+
}
|
|
4700
|
+
ae->master_port = NULL;
|
|
4556
4701
|
}
|
|
4557
4702
|
|
|
4558
|
-
if(ae->
|
|
4559
|
-
|
|
4560
|
-
|
|
4561
|
-
|
|
4562
|
-
|
|
4563
|
-
|
|
4564
|
-
return false;
|
|
4565
|
-
}
|
|
4703
|
+
if (ae->conf) {
|
|
4704
|
+
status = pjmedia_conf_destroy(ae->conf);
|
|
4705
|
+
if(status != PJ_SUCCESS) {
|
|
4706
|
+
addon_log(L_DBG, "pjmedia_conf_destroy failed\n");
|
|
4707
|
+
}
|
|
4708
|
+
ae->conf = NULL;
|
|
4566
4709
|
}
|
|
4567
4710
|
|
|
4568
|
-
if(ae->
|
|
4569
|
-
|
|
4570
|
-
|
|
4571
|
-
|
|
4572
|
-
|
|
4573
|
-
|
|
4574
|
-
return false;
|
|
4575
|
-
}
|
|
4576
|
-
|
|
4577
|
-
status = pjmedia_conf_disconnect_port(call->conf, ae->fax_cbp.slot, ae->stream_cbp.slot);
|
|
4578
|
-
if (status != PJ_SUCCESS) {
|
|
4579
|
-
make_evt_media_update(evt, sizeof(evt), call->id,
|
|
4580
|
-
"setup_failed (pjmedia_conf_disconnect_port for fax src failed)", "");
|
|
4581
|
-
dispatch_event(evt);
|
|
4582
|
-
return false;
|
|
4583
|
-
}
|
|
4711
|
+
if (ae->null_port) {
|
|
4712
|
+
status = pjmedia_port_destroy(ae->null_port);
|
|
4713
|
+
if(status != PJ_SUCCESS) {
|
|
4714
|
+
addon_log(L_DBG, "pjmedia_port_destroy(null_port) failed\n");
|
|
4715
|
+
}
|
|
4716
|
+
ae->null_port = NULL;
|
|
4584
4717
|
}
|
|
4718
|
+
}
|
|
4719
|
+
|
|
4720
|
+
bool connect_feature_port_to_stream_port(Call *call, AudioEndpoint *ae, ConfBridgePort *cbp) {
|
|
4721
|
+
pj_status_t status;
|
|
4585
4722
|
|
|
4586
|
-
|
|
4723
|
+
if(cbp->connection_mode == CONNECTION_MODE_SOURCE || cbp->connection_mode == CONNECTION_MODE_SOURCE_AND_SINK) {
|
|
4724
|
+
status = pjmedia_conf_connect_port(ae->conf, cbp->slot, ae->stream_cbp.slot, 0);
|
|
4587
4725
|
if (status != PJ_SUCCESS) {
|
|
4588
|
-
|
|
4589
|
-
"setup_failed (pjmedia_conf_remove_port failed)", "");
|
|
4726
|
+
set_error("pjmedia_conf_connect_port failed");
|
|
4590
4727
|
return false;
|
|
4591
4728
|
}
|
|
4592
|
-
|
|
4593
|
-
|
|
4594
|
-
status =
|
|
4729
|
+
}
|
|
4730
|
+
if(cbp->connection_mode == CONNECTION_MODE_SINK || cbp->connection_mode == CONNECTION_MODE_SOURCE_AND_SINK) {
|
|
4731
|
+
status = pjmedia_conf_connect_port(ae->conf, ae->stream_cbp.slot, cbp->slot, 0);
|
|
4732
|
+
printf("status=%i\n" ,status);
|
|
4595
4733
|
if (status != PJ_SUCCESS) {
|
|
4596
|
-
|
|
4597
|
-
"setup_failed (pjmedia_port_destroy failed)", "");
|
|
4734
|
+
set_error("pjmedia_conf_connect_port failed");
|
|
4598
4735
|
return false;
|
|
4599
4736
|
}
|
|
4600
|
-
|
|
4601
|
-
|
|
4737
|
+
}
|
|
4738
|
+
return true;
|
|
4739
|
+
}
|
|
4740
|
+
|
|
4741
|
+
bool restart_media_stream(Call *call, MediaEndpoint *me,
|
|
4742
|
+
const pjmedia_sdp_session *local_sdp,
|
|
4743
|
+
const pjmedia_sdp_session *remote_sdp, int idx) {
|
|
4744
|
+
char evt[4096];
|
|
4745
|
+
pjmedia_stream_info stream_info;
|
|
4746
|
+
|
|
4747
|
+
AudioEndpoint *ae = (AudioEndpoint *)me->endpoint.audio;
|
|
4748
|
+
|
|
4749
|
+
pj_status_t status;
|
|
4750
|
+
|
|
4751
|
+
pjmedia_port *old_port = ae->stream_cbp.port;
|
|
4752
|
+
pjmedia_port *new_port;
|
|
4602
4753
|
|
|
4603
4754
|
status =
|
|
4604
4755
|
pjmedia_stream_info_from_sdp(&stream_info, call->inv->dlg->pool,
|
|
@@ -4664,7 +4815,7 @@ bool restart_media_stream(Call *call, MediaEndpoint *me,
|
|
|
4664
4815
|
return false;
|
|
4665
4816
|
}
|
|
4666
4817
|
|
|
4667
|
-
status = pjmedia_stream_get_port(ae->med_stream, &
|
|
4818
|
+
status = pjmedia_stream_get_port(ae->med_stream, &new_port);
|
|
4668
4819
|
if (status != PJ_SUCCESS) {
|
|
4669
4820
|
make_evt_media_update(evt, sizeof(evt), call->id,
|
|
4670
4821
|
"setup_failed (pjmedia_stream_get_port failed)", "");
|
|
@@ -4672,73 +4823,90 @@ bool restart_media_stream(Call *call, MediaEndpoint *me,
|
|
|
4672
4823
|
return false;
|
|
4673
4824
|
}
|
|
4674
4825
|
|
|
4675
|
-
|
|
4676
|
-
|
|
4677
|
-
|
|
4678
|
-
|
|
4679
|
-
dispatch_event(evt);
|
|
4680
|
-
return false;
|
|
4681
|
-
}
|
|
4682
|
-
|
|
4683
|
-
if(!ae->dtmfdet_cbp.port) {
|
|
4684
|
-
if(!prepare_dtmfdet(call, ae)) {
|
|
4826
|
+
if(!old_port) {
|
|
4827
|
+
printf("call_id=%i restart_media_stream !old_port (first SDP negotiation)\n", call->id);
|
|
4828
|
+
status = create_audio_endpoint_conf(call, ae, new_port);
|
|
4829
|
+
if (status != PJ_SUCCESS) {
|
|
4685
4830
|
make_evt_media_update(evt, sizeof(evt), call->id,
|
|
4686
|
-
"setup_failed (
|
|
4831
|
+
"setup_failed (create_audio_endpoint_conf failed)", "");
|
|
4687
4832
|
dispatch_event(evt);
|
|
4688
4833
|
return false;
|
|
4689
4834
|
}
|
|
4690
|
-
}
|
|
4691
4835
|
|
|
4692
|
-
|
|
4693
|
-
status =
|
|
4836
|
+
ae->stream_cbp.port = new_port;
|
|
4837
|
+
status = pjmedia_conf_add_port(ae->conf, call->inv->pool, ae->stream_cbp.port, NULL, &ae->stream_cbp.slot);
|
|
4694
4838
|
if (status != PJ_SUCCESS) {
|
|
4695
4839
|
make_evt_media_update(evt, sizeof(evt), call->id,
|
|
4696
|
-
"setup_failed (
|
|
4840
|
+
"setup_failed (pjmedia_conf_add_port failed)", "");
|
|
4697
4841
|
dispatch_event(evt);
|
|
4698
4842
|
return false;
|
|
4699
4843
|
}
|
|
4700
|
-
}
|
|
4701
4844
|
|
|
4702
|
-
|
|
4703
|
-
|
|
4704
|
-
if (status != PJ_SUCCESS) {
|
|
4845
|
+
// we always add dtmfdet to audio endpoints
|
|
4846
|
+
if(!prepare_dtmfdet(call, ae)) {
|
|
4705
4847
|
make_evt_media_update(evt, sizeof(evt), call->id,
|
|
4706
|
-
|
|
4848
|
+
"setup_failed (prepare_dtmfdet failed)", "");
|
|
4707
4849
|
dispatch_event(evt);
|
|
4708
4850
|
return false;
|
|
4709
4851
|
}
|
|
4710
|
-
}
|
|
4711
|
-
|
|
4712
|
-
|
|
4713
|
-
|
|
4852
|
+
} else if(
|
|
4853
|
+
(PJMEDIA_PIA_SRATE(&old_port->info) != PJMEDIA_PIA_SRATE(&new_port->info)) ||
|
|
4854
|
+
(PJMEDIA_PIA_CCNT(&old_port->info) != PJMEDIA_PIA_CCNT(&new_port->info)) ||
|
|
4855
|
+
(PJMEDIA_PIA_SPF(&old_port->info) != PJMEDIA_PIA_SPF(&new_port->info)) ||
|
|
4856
|
+
(PJMEDIA_PIA_BITS(&old_port->info) != PJMEDIA_PIA_BITS(&new_port->info))) {
|
|
4857
|
+
// stream characteristics changed so we need to destroy old conf and ports
|
|
4858
|
+
printf("call_id=%i restart_media_stream: stream characteristics changed\n", call->id);
|
|
4859
|
+
close_audio_endpoint_ports_and_conf(call, ae);
|
|
4860
|
+
|
|
4861
|
+
// then create a new conf
|
|
4862
|
+
status = create_audio_endpoint_conf(call, ae, new_port);
|
|
4714
4863
|
if (status != PJ_SUCCESS) {
|
|
4715
4864
|
make_evt_media_update(evt, sizeof(evt), call->id,
|
|
4716
|
-
"setup_failed (
|
|
4865
|
+
"setup_failed (create_audio_endpoint_conf failed)", "");
|
|
4717
4866
|
dispatch_event(evt);
|
|
4718
4867
|
return false;
|
|
4719
|
-
|
|
4720
4868
|
}
|
|
4721
|
-
}
|
|
4722
4869
|
|
|
4723
|
-
|
|
4724
|
-
status =
|
|
4870
|
+
ae->stream_cbp.port = new_port;
|
|
4871
|
+
status = pjmedia_conf_add_port(ae->conf, call->inv->pool, ae->stream_cbp.port, NULL, &ae->stream_cbp.slot);
|
|
4725
4872
|
if (status != PJ_SUCCESS) {
|
|
4726
4873
|
make_evt_media_update(evt, sizeof(evt), call->id,
|
|
4727
|
-
"setup_failed (
|
|
4874
|
+
"setup_failed (pjmedia_conf_add_port failed)", "");
|
|
4728
4875
|
dispatch_event(evt);
|
|
4729
4876
|
return false;
|
|
4877
|
+
}
|
|
4730
4878
|
|
|
4879
|
+
// we always add dtmfdet to audio endpoints
|
|
4880
|
+
if(!prepare_dtmfdet(call, ae)) {
|
|
4881
|
+
make_evt_media_update(evt, sizeof(evt), call->id,
|
|
4882
|
+
"setup_failed (prepare_dtmfdet failed)", "");
|
|
4883
|
+
dispatch_event(evt);
|
|
4884
|
+
return false;
|
|
4731
4885
|
}
|
|
4732
4886
|
|
|
4733
|
-
|
|
4887
|
+
// at this point we could try to recreate ports (see #91)
|
|
4888
|
+
} else {
|
|
4889
|
+
printf("call_id=%i restart_media_stream: stream characteristics no change\n", call->id);
|
|
4890
|
+
// stream characteristics didn't change so just replace the stream port
|
|
4891
|
+
|
|
4892
|
+
audio_endpoint_remove_port(call, ae, &ae->stream_cbp);
|
|
4893
|
+
ae->stream_cbp.port = new_port;
|
|
4894
|
+
status = pjmedia_conf_add_port(ae->conf, call->inv->pool, ae->stream_cbp.port, NULL, &ae->stream_cbp.slot);
|
|
4734
4895
|
if (status != PJ_SUCCESS) {
|
|
4735
4896
|
make_evt_media_update(evt, sizeof(evt), call->id,
|
|
4736
|
-
"setup_failed (
|
|
4897
|
+
"setup_failed (pjmedia_conf_add_port failed)", "");
|
|
4737
4898
|
dispatch_event(evt);
|
|
4738
4899
|
return false;
|
|
4739
4900
|
}
|
|
4740
|
-
}
|
|
4741
4901
|
|
|
4902
|
+
// Need to connect ports to new stream port
|
|
4903
|
+
for(int i=0 ; i<MAX_FP ; i++) {
|
|
4904
|
+
if(ae->feature_cbps[i].port) {
|
|
4905
|
+
if(!connect_feature_port_to_stream_port(call, ae, &ae->feature_cbps[i])) return false;
|
|
4906
|
+
}
|
|
4907
|
+
}
|
|
4908
|
+
}
|
|
4909
|
+
|
|
4742
4910
|
return true;
|
|
4743
4911
|
}
|
|
4744
4912
|
|
|
@@ -4925,8 +5093,6 @@ static void on_state_changed(pjsip_inv_session *inv, pjsip_event *e) {
|
|
|
4925
5093
|
}
|
|
4926
5094
|
}
|
|
4927
5095
|
|
|
4928
|
-
release_call_conf(call);
|
|
4929
|
-
|
|
4930
5096
|
long val;
|
|
4931
5097
|
if (!g_call_ids.remove(call_id, val)) {
|
|
4932
5098
|
addon_log(L_DBG, "g_call_ids.remove failed\n");
|
|
@@ -5231,7 +5397,7 @@ static pj_bool_t on_rx_request(pjsip_rx_data *rdata) {
|
|
|
5231
5397
|
|
|
5232
5398
|
long transport_id;
|
|
5233
5399
|
|
|
5234
|
-
//
|
|
5400
|
+
//printf("on_rx_request transport_tag=%s\n", tag);
|
|
5235
5401
|
|
|
5236
5402
|
TransportMap::iterator iter = g_TransportMap.find(tag);
|
|
5237
5403
|
if (iter != g_TransportMap.end()) {
|
|
@@ -5317,13 +5483,6 @@ static pj_bool_t on_rx_request(pjsip_rx_data *rdata) {
|
|
|
5317
5483
|
return PJ_TRUE;
|
|
5318
5484
|
}
|
|
5319
5485
|
|
|
5320
|
-
status = setup_call_conf(call);
|
|
5321
|
-
if (status != PJ_SUCCESS) {
|
|
5322
|
-
printf("setup_call_conf failed\n");
|
|
5323
|
-
pjsip_endpt_respond_stateless(g_sip_endpt, rdata, 500, &reason, NULL, NULL);
|
|
5324
|
-
return PJ_TRUE;
|
|
5325
|
-
}
|
|
5326
|
-
|
|
5327
5486
|
// TODO: check if this is really necessary as we are calling
|
|
5328
5487
|
// pjsip_dlg_add_usage subsequently
|
|
5329
5488
|
inv->dlg->mod_data[mod_tester.id] = call;
|
|
@@ -5349,7 +5508,7 @@ static pj_bool_t on_rx_request(pjsip_rx_data *rdata) {
|
|
|
5349
5508
|
|
|
5350
5509
|
long transport_id;
|
|
5351
5510
|
|
|
5352
|
-
|
|
5511
|
+
printf("on_rx_request INVITE transport_tag=%s\n", tag);
|
|
5353
5512
|
|
|
5354
5513
|
TransportMap::iterator iter = g_TransportMap.find(tag);
|
|
5355
5514
|
if (iter != g_TransportMap.end()) {
|
|
@@ -6511,10 +6670,10 @@ bool process_media(Call *call, pjsip_dialog *dlg, Document &document, bool answe
|
|
|
6511
6670
|
return true;
|
|
6512
6671
|
}
|
|
6513
6672
|
|
|
6514
|
-
bool is_media_active(Call *
|
|
6673
|
+
bool is_media_active(Call *call, MediaEndpoint *me) {
|
|
6515
6674
|
// check if media from call->media_neg is on call->media
|
|
6516
|
-
for (int i = 0; i <
|
|
6517
|
-
if (me ==
|
|
6675
|
+
for (int i = 0; i < call->media_count; ++i) {
|
|
6676
|
+
if (me == call->media[i])
|
|
6518
6677
|
return true;
|
|
6519
6678
|
}
|
|
6520
6679
|
return false;
|
|
@@ -6522,19 +6681,14 @@ bool is_media_active(Call *c, MediaEndpoint *me) {
|
|
|
6522
6681
|
|
|
6523
6682
|
void close_media_endpoint(Call *call, MediaEndpoint *me) {
|
|
6524
6683
|
printf("close_media_endpoint %p\n", (void*)me);
|
|
6684
|
+
|
|
6685
|
+
pj_status_t status;
|
|
6686
|
+
|
|
6525
6687
|
if(!me) return;
|
|
6526
6688
|
|
|
6527
6689
|
if (ENDPOINT_TYPE_AUDIO == me->type) {
|
|
6528
6690
|
AudioEndpoint *ae = (AudioEndpoint *)me->endpoint.audio;
|
|
6529
|
-
|
|
6530
|
-
audio_endpoint_remove_port(call, &ae->stream_cbp);
|
|
6531
|
-
audio_endpoint_remove_port(call, &ae->wav_player_cbp);
|
|
6532
|
-
audio_endpoint_remove_port(call, &ae->wav_writer_cbp);
|
|
6533
|
-
audio_endpoint_remove_port(call, &ae->tonegen_cbp);
|
|
6534
|
-
audio_endpoint_remove_port(call, &ae->dtmfdet_cbp);
|
|
6535
|
-
audio_endpoint_remove_port(call, &ae->fax_cbp);
|
|
6536
|
-
audio_endpoint_remove_port(call, &ae->flite_cbp);
|
|
6537
|
-
|
|
6691
|
+
close_audio_endpoint_ports_and_conf(call, ae);
|
|
6538
6692
|
close_media_transport(ae->med_transport);
|
|
6539
6693
|
ae->med_transport = NULL;
|
|
6540
6694
|
} else if (ENDPOINT_TYPE_MRCP == me->type) {
|
|
@@ -6558,63 +6712,63 @@ void close_media_endpoint(Call *call, MediaEndpoint *me) {
|
|
|
6558
6712
|
me->port = 0;
|
|
6559
6713
|
}
|
|
6560
6714
|
|
|
6561
|
-
void close_media(Call *
|
|
6562
|
-
printf("close_media call_id=%i\n",
|
|
6563
|
-
for (int i = 0; i <
|
|
6564
|
-
MediaEndpoint *me =
|
|
6565
|
-
close_media_endpoint(
|
|
6715
|
+
void close_media(Call *call) {
|
|
6716
|
+
printf("close_media call_id=%i\n", call->id);
|
|
6717
|
+
for (int i = 0; i < call->media_count; ++i) {
|
|
6718
|
+
MediaEndpoint *me = call->media[i];
|
|
6719
|
+
close_media_endpoint(call, me);
|
|
6566
6720
|
}
|
|
6567
|
-
|
|
6721
|
+
call->media_count = 0;
|
|
6568
6722
|
}
|
|
6569
6723
|
|
|
6570
|
-
bool prepare_tonegen(Call *
|
|
6571
|
-
printf("prepare_tone_gen call.id=%i\n",
|
|
6724
|
+
bool prepare_tonegen(Call *call, AudioEndpoint *ae) {
|
|
6725
|
+
printf("prepare_tone_gen call.id=%i\n", call->id);
|
|
6572
6726
|
pj_status_t status;
|
|
6573
6727
|
|
|
6574
|
-
|
|
6728
|
+
ConfBridgePort *fp = &ae->feature_cbps[FP_TONEGEN];
|
|
6729
|
+
|
|
6730
|
+
if(fp->port) {
|
|
6575
6731
|
printf("already prepared\n");
|
|
6576
6732
|
return true;
|
|
6577
6733
|
}
|
|
6578
6734
|
|
|
6579
6735
|
status = pjmedia_tonegen_create(
|
|
6580
|
-
|
|
6736
|
+
call->inv->pool, PJMEDIA_PIA_SRATE(&ae->stream_cbp.port->info),
|
|
6581
6737
|
PJMEDIA_PIA_CCNT(&ae->stream_cbp.port->info),
|
|
6582
6738
|
PJMEDIA_PIA_SPF(&ae->stream_cbp.port->info),
|
|
6583
|
-
PJMEDIA_PIA_BITS(&ae->stream_cbp.port->info), 0, &
|
|
6739
|
+
PJMEDIA_PIA_BITS(&ae->stream_cbp.port->info), 0, &fp->port);
|
|
6584
6740
|
if (status != PJ_SUCCESS) {
|
|
6585
6741
|
set_error("pjmedia_tonegen_create failed");
|
|
6586
6742
|
return false;
|
|
6587
6743
|
}
|
|
6588
6744
|
|
|
6589
|
-
status = pjmedia_conf_add_port(
|
|
6745
|
+
status = pjmedia_conf_add_port(ae->conf, call->inv->pool, fp->port, NULL, &fp->slot);
|
|
6590
6746
|
if (status != PJ_SUCCESS) {
|
|
6591
6747
|
set_error("pjmedia_conf_add_port failed");
|
|
6592
6748
|
return false;
|
|
6593
6749
|
}
|
|
6594
6750
|
|
|
6595
|
-
|
|
6596
|
-
if (status != PJ_SUCCESS) {
|
|
6597
|
-
set_error("pjmedia_conf_connect_port failed");
|
|
6598
|
-
return false;
|
|
6599
|
-
}
|
|
6751
|
+
fp->connection_mode = CONNECTION_MODE_SOURCE;
|
|
6600
6752
|
|
|
6601
|
-
return
|
|
6753
|
+
return connect_feature_port_to_stream_port(call, ae, fp);
|
|
6602
6754
|
}
|
|
6603
6755
|
|
|
6604
|
-
bool prepare_wav_player(Call *
|
|
6756
|
+
bool prepare_wav_player(Call *call, AudioEndpoint *ae, const char *file, unsigned flags, bool end_of_file_event) {
|
|
6605
6757
|
pj_status_t status;
|
|
6606
6758
|
|
|
6759
|
+
ConfBridgePort *fp = &ae->feature_cbps[FP_WAV_PLAYER];
|
|
6760
|
+
|
|
6607
6761
|
unsigned wav_ptime;
|
|
6608
6762
|
wav_ptime = PJMEDIA_PIA_SPF(&ae->stream_cbp.port->info) * 1000 /
|
|
6609
6763
|
PJMEDIA_PIA_SRATE(&ae->stream_cbp.port->info);
|
|
6610
6764
|
|
|
6611
6765
|
status = pjmedia_wav_player_port_create(
|
|
6612
|
-
|
|
6766
|
+
call->inv->pool,
|
|
6613
6767
|
file,
|
|
6614
6768
|
wav_ptime,
|
|
6615
6769
|
flags,
|
|
6616
6770
|
-1, /* buf size */
|
|
6617
|
-
&
|
|
6771
|
+
&fp->port
|
|
6618
6772
|
);
|
|
6619
6773
|
|
|
6620
6774
|
if (status != PJ_SUCCESS) {
|
|
@@ -6623,164 +6777,181 @@ bool prepare_wav_player(Call *c, AudioEndpoint *ae, const char *file, unsigned f
|
|
|
6623
6777
|
}
|
|
6624
6778
|
|
|
6625
6779
|
if (end_of_file_event) {
|
|
6626
|
-
status = pjmedia_wav_player_set_eof_cb2(
|
|
6780
|
+
status = pjmedia_wav_player_set_eof_cb2(fp->port, (void*)call, on_end_of_file);
|
|
6627
6781
|
if (status != PJ_SUCCESS) {
|
|
6628
6782
|
set_error("pjmedia_wav_player_set_eof_cb2 failed");
|
|
6629
6783
|
return false;
|
|
6630
6784
|
}
|
|
6631
6785
|
}
|
|
6632
6786
|
|
|
6633
|
-
status = pjmedia_conf_add_port(
|
|
6787
|
+
status = pjmedia_conf_add_port(ae->conf, call->inv->pool, fp->port, NULL, &fp->slot);
|
|
6634
6788
|
if (status != PJ_SUCCESS) {
|
|
6635
6789
|
set_error("pjmedia_conf_add_port failed");
|
|
6636
6790
|
return false;
|
|
6637
6791
|
}
|
|
6638
6792
|
|
|
6639
|
-
|
|
6640
|
-
if (status != PJ_SUCCESS) {
|
|
6641
|
-
set_error("pjmedia_conf_connect_port failed");
|
|
6642
|
-
return false;
|
|
6643
|
-
}
|
|
6793
|
+
fp->connection_mode = CONNECTION_MODE_SOURCE;
|
|
6644
6794
|
|
|
6645
|
-
return
|
|
6795
|
+
return connect_feature_port_to_stream_port(call, ae, fp);
|
|
6646
6796
|
}
|
|
6647
6797
|
|
|
6648
|
-
bool prepare_wav_writer(Call *
|
|
6798
|
+
bool prepare_wav_writer(Call *call, AudioEndpoint *ae, const char *file) {
|
|
6649
6799
|
pj_status_t status;
|
|
6650
6800
|
|
|
6801
|
+
ConfBridgePort *fp = &ae->feature_cbps[FP_WAV_WRITER];
|
|
6802
|
+
|
|
6651
6803
|
status = pjmedia_wav_writer_port_create(
|
|
6652
|
-
|
|
6804
|
+
call->inv->pool, file, PJMEDIA_PIA_SRATE(&ae->stream_cbp.port->info),
|
|
6653
6805
|
PJMEDIA_PIA_CCNT(&ae->stream_cbp.port->info), PJMEDIA_PIA_SPF(&ae->stream_cbp.port->info),
|
|
6654
6806
|
PJMEDIA_PIA_BITS(&ae->stream_cbp.port->info), PJMEDIA_FILE_WRITE_PCM, 0,
|
|
6655
|
-
(pjmedia_port **)&
|
|
6807
|
+
(pjmedia_port **)&fp->port);
|
|
6656
6808
|
if (status != PJ_SUCCESS) {
|
|
6657
6809
|
set_error("pjmedia_wav_write_port_create failed");
|
|
6658
6810
|
return false;
|
|
6659
6811
|
}
|
|
6660
6812
|
|
|
6661
|
-
status = pjmedia_conf_add_port(
|
|
6813
|
+
status = pjmedia_conf_add_port(ae->conf, call->inv->pool, fp->port, NULL, &fp->slot);
|
|
6662
6814
|
if (status != PJ_SUCCESS) {
|
|
6663
6815
|
set_error("pjmedia_conf_add_port failed");
|
|
6664
6816
|
return false;
|
|
6665
6817
|
}
|
|
6666
6818
|
|
|
6667
|
-
|
|
6668
|
-
if (status != PJ_SUCCESS) {
|
|
6669
|
-
set_error("pjmedia_conf_connect_port failed");
|
|
6670
|
-
return false;
|
|
6671
|
-
}
|
|
6819
|
+
fp->connection_mode = CONNECTION_MODE_SINK;
|
|
6672
6820
|
|
|
6673
|
-
return
|
|
6821
|
+
return connect_feature_port_to_stream_port(call, ae, fp);
|
|
6674
6822
|
}
|
|
6675
6823
|
|
|
6676
|
-
bool prepare_dtmfdet(Call *
|
|
6824
|
+
bool prepare_dtmfdet(Call *call, AudioEndpoint *ae) {
|
|
6677
6825
|
pj_status_t status;
|
|
6826
|
+
|
|
6827
|
+
ConfBridgePort *fp = &ae->feature_cbps[FP_DTMFDET];
|
|
6828
|
+
|
|
6678
6829
|
status = pjmedia_dtmfdet_create(
|
|
6679
|
-
|
|
6830
|
+
call->inv->pool,
|
|
6680
6831
|
PJMEDIA_PIA_SRATE(&ae->stream_cbp.port->info),
|
|
6681
|
-
PJMEDIA_PIA_CCNT(&ae->stream_cbp.port->info),
|
|
6832
|
+
PJMEDIA_PIA_CCNT(&ae->stream_cbp.port->info),
|
|
6833
|
+
PJMEDIA_PIA_SPF(&ae->stream_cbp.port->info),
|
|
6682
6834
|
PJMEDIA_PIA_BITS(&ae->stream_cbp.port->info),
|
|
6683
|
-
on_inband_dtmf,
|
|
6835
|
+
on_inband_dtmf, call, &fp->port);
|
|
6684
6836
|
if (status != PJ_SUCCESS) {
|
|
6685
6837
|
set_error("pjmedia_dtmfdet_create failed");
|
|
6686
6838
|
return false;
|
|
6687
6839
|
}
|
|
6688
6840
|
|
|
6689
|
-
status = pjmedia_conf_add_port(
|
|
6841
|
+
status = pjmedia_conf_add_port(ae->conf, call->inv->pool, fp->port, NULL, &fp->slot);
|
|
6690
6842
|
if (status != PJ_SUCCESS) {
|
|
6691
6843
|
set_error("pjmedia_conf_add_port failed");
|
|
6692
6844
|
return false;
|
|
6693
6845
|
}
|
|
6694
6846
|
|
|
6695
|
-
|
|
6696
|
-
if (status != PJ_SUCCESS) {
|
|
6697
|
-
set_error("pjmedia_conf_connect_port failed");
|
|
6698
|
-
return false;
|
|
6699
|
-
}
|
|
6847
|
+
fp->connection_mode = CONNECTION_MODE_SINK;
|
|
6700
6848
|
|
|
6701
|
-
return
|
|
6849
|
+
return connect_feature_port_to_stream_port(call, ae, fp);
|
|
6702
6850
|
}
|
|
6703
6851
|
|
|
6704
|
-
bool prepare_fax(Call *
|
|
6705
|
-
unsigned flags) {
|
|
6852
|
+
bool prepare_fax(Call *call, AudioEndpoint *ae, bool is_sender, const char *file, unsigned flags) {
|
|
6706
6853
|
pj_status_t status;
|
|
6707
6854
|
|
|
6855
|
+
ConfBridgePort *fp = &ae->feature_cbps[FP_FAX];
|
|
6856
|
+
|
|
6708
6857
|
status = pjmedia_fax_port_create(
|
|
6709
|
-
|
|
6858
|
+
call->inv->pool,
|
|
6710
6859
|
PJMEDIA_PIA_SRATE(&ae->stream_cbp.port->info),
|
|
6711
6860
|
PJMEDIA_PIA_CCNT(&ae->stream_cbp.port->info),
|
|
6712
6861
|
PJMEDIA_PIA_SPF(&ae->stream_cbp.port->info),
|
|
6713
6862
|
PJMEDIA_PIA_BITS(&ae->stream_cbp.port->info),
|
|
6714
|
-
on_fax_result,
|
|
6715
|
-
flags, &
|
|
6863
|
+
on_fax_result, call, is_sender, file,
|
|
6864
|
+
flags, &fp->port);
|
|
6716
6865
|
if (status != PJ_SUCCESS) {
|
|
6717
6866
|
set_error("pjmedia_fax_port_create failed");
|
|
6718
6867
|
return false;
|
|
6719
6868
|
}
|
|
6720
6869
|
|
|
6721
|
-
status = pjmedia_conf_add_port(
|
|
6870
|
+
status = pjmedia_conf_add_port(ae->conf, call->inv->pool, fp->port, NULL, &fp->slot);
|
|
6722
6871
|
if (status != PJ_SUCCESS) {
|
|
6723
6872
|
set_error("pjmedia_conf_add_port failed");
|
|
6724
6873
|
return false;
|
|
6725
6874
|
}
|
|
6726
6875
|
|
|
6727
|
-
|
|
6728
|
-
if (status != PJ_SUCCESS) {
|
|
6729
|
-
set_error("pjmedia_conf_connect_port failed");
|
|
6730
|
-
return false;
|
|
6731
|
-
}
|
|
6876
|
+
fp->connection_mode = CONNECTION_MODE_SOURCE_AND_SINK;
|
|
6732
6877
|
|
|
6733
|
-
|
|
6734
|
-
if (status != PJ_SUCCESS) {
|
|
6735
|
-
set_error("pjmedia_conf_connect_port failed");
|
|
6736
|
-
return false;
|
|
6737
|
-
}
|
|
6738
|
-
|
|
6739
|
-
return true;
|
|
6878
|
+
return connect_feature_port_to_stream_port(call, ae, fp);
|
|
6740
6879
|
}
|
|
6741
6880
|
|
|
6742
|
-
bool prepare_flite(Call *
|
|
6743
|
-
printf("prepare_flite call.id=%i\n", c->id);
|
|
6881
|
+
bool prepare_flite(Call *call, AudioEndpoint *ae, const char *voice, bool end_of_speech_event) {
|
|
6744
6882
|
pj_status_t status;
|
|
6745
6883
|
|
|
6746
|
-
|
|
6884
|
+
ConfBridgePort *fp = &ae->feature_cbps[FP_SPEECH_SYNTH];
|
|
6885
|
+
|
|
6886
|
+
if(fp->port) {
|
|
6747
6887
|
printf("already prepared\n");
|
|
6748
6888
|
return true;
|
|
6749
6889
|
}
|
|
6750
6890
|
|
|
6751
6891
|
status = pjmedia_flite_port_create(
|
|
6752
|
-
|
|
6892
|
+
call->inv->pool, PJMEDIA_PIA_SRATE(&ae->stream_cbp.port->info),
|
|
6753
6893
|
PJMEDIA_PIA_CCNT(&ae->stream_cbp.port->info),
|
|
6754
6894
|
PJMEDIA_PIA_SPF(&ae->stream_cbp.port->info),
|
|
6755
|
-
PJMEDIA_PIA_BITS(&ae->stream_cbp.port->info),
|
|
6895
|
+
PJMEDIA_PIA_BITS(&ae->stream_cbp.port->info),
|
|
6896
|
+
voice,
|
|
6897
|
+
&fp->port);
|
|
6756
6898
|
if (status != PJ_SUCCESS) {
|
|
6757
6899
|
set_error("pjmedia_flite_port_create failed");
|
|
6758
6900
|
return false;
|
|
6759
6901
|
}
|
|
6760
6902
|
|
|
6761
6903
|
if (end_of_speech_event) {
|
|
6762
|
-
status = pjmedia_flite_port_set_eof_cb(
|
|
6904
|
+
status = pjmedia_flite_port_set_eof_cb(fp->port, (void*)call, on_end_of_speech);
|
|
6763
6905
|
if (status != PJ_SUCCESS) {
|
|
6764
6906
|
set_error("pjmedia_flite_port_set_eof_cb failed");
|
|
6765
6907
|
return false;
|
|
6766
6908
|
}
|
|
6767
6909
|
}
|
|
6768
6910
|
|
|
6769
|
-
status = pjmedia_conf_add_port(
|
|
6911
|
+
status = pjmedia_conf_add_port(ae->conf, call->inv->pool, fp->port, NULL, &fp->slot);
|
|
6770
6912
|
if (status != PJ_SUCCESS) {
|
|
6771
6913
|
set_error("pjmedia_conf_add_port failed");
|
|
6772
6914
|
return false;
|
|
6773
6915
|
}
|
|
6774
6916
|
|
|
6775
|
-
|
|
6917
|
+
fp->connection_mode = CONNECTION_MODE_SOURCE;
|
|
6918
|
+
|
|
6919
|
+
return connect_feature_port_to_stream_port(call, ae, fp);
|
|
6920
|
+
}
|
|
6921
|
+
|
|
6922
|
+
bool prepare_pocketsphinx(Call *call, AudioEndpoint *ae) {
|
|
6923
|
+
pj_status_t status;
|
|
6924
|
+
|
|
6925
|
+
ConfBridgePort *fp = &ae->feature_cbps[FP_SPEECH_RECOG];
|
|
6926
|
+
|
|
6927
|
+
if(fp->port) {
|
|
6928
|
+
printf("already prepared\n");
|
|
6929
|
+
return true;
|
|
6930
|
+
}
|
|
6931
|
+
|
|
6932
|
+
status = pjmedia_pocketsphinx_port_create(
|
|
6933
|
+
call->inv->pool, PJMEDIA_PIA_SRATE(&ae->stream_cbp.port->info),
|
|
6934
|
+
PJMEDIA_PIA_CCNT(&ae->stream_cbp.port->info),
|
|
6935
|
+
PJMEDIA_PIA_SPF(&ae->stream_cbp.port->info),
|
|
6936
|
+
PJMEDIA_PIA_BITS(&ae->stream_cbp.port->info),
|
|
6937
|
+
on_speech_transcript,
|
|
6938
|
+
call,
|
|
6939
|
+
&fp->port);
|
|
6776
6940
|
if (status != PJ_SUCCESS) {
|
|
6777
|
-
set_error("
|
|
6941
|
+
set_error("pjmedia_pocketsphinx_port_create failed");
|
|
6778
6942
|
return false;
|
|
6779
6943
|
}
|
|
6780
6944
|
|
|
6781
|
-
|
|
6782
|
-
|
|
6945
|
+
status = pjmedia_conf_add_port(ae->conf, call->inv->pool, fp->port, NULL, &fp->slot);
|
|
6946
|
+
if (status != PJ_SUCCESS) {
|
|
6947
|
+
set_error("pjmedia_conf_add_port failed");
|
|
6948
|
+
return false;
|
|
6949
|
+
}
|
|
6783
6950
|
|
|
6951
|
+
fp->connection_mode = CONNECTION_MODE_SINK;
|
|
6952
|
+
|
|
6953
|
+
return connect_feature_port_to_stream_port(call, ae, fp);
|
|
6954
|
+
}
|
|
6784
6955
|
|
|
6785
6956
|
void on_rx_notify(pjsip_evsub *sub, pjsip_rx_data *rdata, int *p_st_code,
|
|
6786
6957
|
pj_str_t **p_st_text, pjsip_hdr *res_hdr,
|
|
@@ -8168,8 +8339,8 @@ static int g_now;
|
|
|
8168
8339
|
|
|
8169
8340
|
void check_digit_buffer(Call *call, int mode) {
|
|
8170
8341
|
// addon_log(L_DBG, "check_digit_buffer g_now=%i for call_id=%i and mode=%i
|
|
8171
|
-
// timestamp=%i len=%i\n", g_now,
|
|
8172
|
-
//
|
|
8342
|
+
// timestamp=%i len=%i\n", g_now, call->id, mode, call->last_digit_timestamp[mode],
|
|
8343
|
+
// call->DigitBufferLength[mode]);
|
|
8173
8344
|
char evt[1024];
|
|
8174
8345
|
|
|
8175
8346
|
for (int i = 0; i < call->media_count; i++) {
|
|
@@ -8193,10 +8364,10 @@ void check_digit_buffer(Call *call, int mode) {
|
|
|
8193
8364
|
}
|
|
8194
8365
|
|
|
8195
8366
|
void check_digit_buffers(long id, long val) {
|
|
8196
|
-
Call *
|
|
8367
|
+
Call *call = (Call *)val;
|
|
8197
8368
|
|
|
8198
|
-
check_digit_buffer(
|
|
8199
|
-
check_digit_buffer(
|
|
8369
|
+
check_digit_buffer(call, DTMF_MODE_RFC2833);
|
|
8370
|
+
check_digit_buffer(call, DTMF_MODE_INBAND);
|
|
8200
8371
|
}
|
|
8201
8372
|
|
|
8202
8373
|
static int digit_buffer_thread(void *arg) {
|