sip-lab 1.17.10 → 1.18.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/src/sip.cpp
CHANGED
|
@@ -20,13 +20,8 @@
|
|
|
20
20
|
#include "idmanager.hpp"
|
|
21
21
|
#include "event_templates.hpp"
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
#include "
|
|
25
|
-
#include "chainlink_dtmfdet.h"
|
|
26
|
-
#include "chainlink_fax.h"
|
|
27
|
-
#include "chainlink_tonegen.h"
|
|
28
|
-
#include "chainlink_wav_port.h"
|
|
29
|
-
#include "chainlink_wire_port.h"
|
|
23
|
+
#include "dtmfdet.h"
|
|
24
|
+
#include "fax_port.h"
|
|
30
25
|
|
|
31
26
|
#include <ctime>
|
|
32
27
|
|
|
@@ -269,6 +264,14 @@ pjsip_route_hdr route_set;
|
|
|
269
264
|
pjsip_route_hdr *route;
|
|
270
265
|
const pj_str_t hname = pj_str((char *)"Route");
|
|
271
266
|
|
|
267
|
+
#define CONF_PORTS 1024
|
|
268
|
+
//#define CLOCK_RATE 16000
|
|
269
|
+
#define CLOCK_RATE 8000
|
|
270
|
+
#define CHANNEL_COUNT 1
|
|
271
|
+
#define PTIME 20
|
|
272
|
+
#define SAMPLES_PER_FRAME (CLOCK_RATE*PTIME/1000)
|
|
273
|
+
#define BITS_PER_SAMPLE 16
|
|
274
|
+
|
|
272
275
|
#define MAXDIGITS 256
|
|
273
276
|
|
|
274
277
|
#define DTMF_MODE_RFC2833 0
|
|
@@ -305,30 +308,32 @@ struct Subscription {
|
|
|
305
308
|
bool initialized;
|
|
306
309
|
};
|
|
307
310
|
|
|
311
|
+
struct ConfBridgePort {
|
|
312
|
+
unsigned slot;
|
|
313
|
+
pjmedia_port *port;
|
|
314
|
+
};
|
|
315
|
+
|
|
308
316
|
struct AudioEndpoint {
|
|
309
317
|
pjmedia_transport *med_transport;
|
|
310
318
|
pjmedia_stream *med_stream;
|
|
311
|
-
pjmedia_master_port *master_port;
|
|
312
|
-
pjmedia_port *media_port; // will contain Null Port, WAV File Player etc.
|
|
313
|
-
|
|
314
|
-
pjmedia_port *null_port;
|
|
315
|
-
chainlink *wav_writer;
|
|
316
|
-
chainlink *wav_player;
|
|
317
|
-
chainlink *tonegen;
|
|
318
|
-
chainlink *dtmfdet;
|
|
319
|
-
chainlink *fax;
|
|
320
319
|
|
|
321
320
|
char DigitBuffers[2][MAXDIGITS + 1];
|
|
322
321
|
int DigitBufferLength[2];
|
|
323
322
|
int last_digit_timestamp[2];
|
|
324
323
|
|
|
325
324
|
pj_str_t mode;
|
|
325
|
+
|
|
326
|
+
ConfBridgePort stream_cbp;
|
|
327
|
+
ConfBridgePort wav_player_cbp;
|
|
328
|
+
ConfBridgePort wav_writer_cbp;
|
|
329
|
+
ConfBridgePort tonegen_cbp;
|
|
330
|
+
ConfBridgePort dtmfdet_cbp;
|
|
331
|
+
ConfBridgePort fax_cbp;
|
|
326
332
|
};
|
|
327
333
|
|
|
328
334
|
struct VideoEndpoint {
|
|
329
335
|
pjmedia_transport *med_transport;
|
|
330
336
|
pjmedia_stream *med_stream;
|
|
331
|
-
pjmedia_master_port *master_port;
|
|
332
337
|
};
|
|
333
338
|
|
|
334
339
|
struct MrcpEndpoint {
|
|
@@ -426,6 +431,10 @@ struct Call {
|
|
|
426
431
|
pjmedia_sdp_session *active_remote_sdp;
|
|
427
432
|
|
|
428
433
|
bool local_sdp_answer_already_set;
|
|
434
|
+
|
|
435
|
+
pjmedia_conf *conf;
|
|
436
|
+
pjmedia_master_port *master_port;
|
|
437
|
+
pjmedia_port *null_port;
|
|
429
438
|
};
|
|
430
439
|
|
|
431
440
|
#define MAX_TCP_DATA 4096
|
|
@@ -439,11 +448,6 @@ struct AsockUserData {
|
|
|
439
448
|
pj_size_t len;
|
|
440
449
|
};
|
|
441
450
|
|
|
442
|
-
bool init_media_ports(Call *c, AudioEndpoint *ae, unsigned sampling_rate,
|
|
443
|
-
unsigned channel_count, unsigned samples_per_frame,
|
|
444
|
-
unsigned bits_per_sample);
|
|
445
|
-
void connect_media_ports(AudioEndpoint *ae);
|
|
446
|
-
|
|
447
451
|
struct Pair_Call_CallId {
|
|
448
452
|
Call *pCall;
|
|
449
453
|
long id;
|
|
@@ -606,20 +610,14 @@ void process_in_dialog_refer(pjsip_dialog *dlg, pjsip_rx_data *rdata);
|
|
|
606
610
|
|
|
607
611
|
void process_in_dialog_subscribe(pjsip_dialog *dlg, pjsip_rx_data *rdata);
|
|
608
612
|
|
|
609
|
-
static pj_bool_t set_ports(Call *call, AudioEndpoint *ae,
|
|
610
|
-
pjmedia_port *stream_port, pjmedia_port *media_port);
|
|
611
613
|
// static pj_bool_t stop_media_operation(Call *call);
|
|
612
614
|
static void build_stream_stat(ostringstream &oss, pjmedia_rtcp_stat *stat,
|
|
613
615
|
pjmedia_stream_info *stream_info);
|
|
614
616
|
|
|
615
|
-
bool prepare_wire(pj_pool_t *pool, chainlink **link, unsigned sampling_rate,
|
|
616
|
-
unsigned channel_count, unsigned samples_per_frame,
|
|
617
|
-
unsigned bits_per_sample);
|
|
618
|
-
|
|
619
617
|
bool prepare_tonegen(Call *call, AudioEndpoint *ae);
|
|
618
|
+
bool prepare_dtmfdet(Call *call, AudioEndpoint *ae);
|
|
620
619
|
bool prepare_wav_player(Call *c, AudioEndpoint *ae, const char *file);
|
|
621
620
|
bool prepare_wav_writer(Call *c, AudioEndpoint *ae, const char *file);
|
|
622
|
-
|
|
623
621
|
bool prepare_fax(Call *c, AudioEndpoint *ae, bool is_sender, const char *file,
|
|
624
622
|
unsigned flags);
|
|
625
623
|
|
|
@@ -629,7 +627,7 @@ void prepare_error_event(ostringstream *oss, char *scope, char *details);
|
|
|
629
627
|
void append_status(ostringstream *oss, pj_status_t s);
|
|
630
628
|
|
|
631
629
|
bool is_media_active(Call *c, MediaEndpoint *me);
|
|
632
|
-
void close_media_endpoint(MediaEndpoint *me);
|
|
630
|
+
void close_media_endpoint(Call *call, MediaEndpoint *me);
|
|
633
631
|
|
|
634
632
|
void close_media(Call *c);
|
|
635
633
|
|
|
@@ -637,6 +635,10 @@ bool process_media(Call *c, pjsip_dialog *dlg, Document &document, bool answer);
|
|
|
637
635
|
|
|
638
636
|
typedef pj_status_t (*audio_endpoint_stop_op_t)(Call *call, AudioEndpoint *ae);
|
|
639
637
|
|
|
638
|
+
pj_status_t audio_endpoint_stop_play_wav(Call *call, AudioEndpoint *ae);
|
|
639
|
+
pj_status_t audio_endpoint_stop_record_wav(Call *call, AudioEndpoint *ae);
|
|
640
|
+
pj_status_t audio_endpoint_stop_fax(Call *call, AudioEndpoint *ae);
|
|
641
|
+
|
|
640
642
|
static pjsip_module mod_tester = {
|
|
641
643
|
NULL,
|
|
642
644
|
NULL, /* prev, next. */
|
|
@@ -710,13 +712,90 @@ find_endpoint_by_inband_dtmf_media_stream(Call *call,
|
|
|
710
712
|
return -1;
|
|
711
713
|
}
|
|
712
714
|
|
|
715
|
+
pj_status_t setup_call_conf(Call *call) {
|
|
716
|
+
pj_status_t status;
|
|
717
|
+
status = pjmedia_conf_create(call->inv->pool,
|
|
718
|
+
CONF_PORTS,
|
|
719
|
+
CLOCK_RATE,
|
|
720
|
+
CHANNEL_COUNT,
|
|
721
|
+
SAMPLES_PER_FRAME,
|
|
722
|
+
BITS_PER_SAMPLE,
|
|
723
|
+
PJMEDIA_CONF_NO_DEVICE,
|
|
724
|
+
&call->conf);
|
|
725
|
+
|
|
726
|
+
if (status != PJ_SUCCESS) {
|
|
727
|
+
addon_log(L_DBG, "pjmedia_conf_create failed\n");
|
|
728
|
+
return false;
|
|
729
|
+
}
|
|
730
|
+
|
|
731
|
+
status = pjmedia_null_port_create(call->inv->pool, CLOCK_RATE, CHANNEL_COUNT, SAMPLES_PER_FRAME, BITS_PER_SAMPLE, &call->null_port);
|
|
732
|
+
if (status != PJ_SUCCESS) {
|
|
733
|
+
addon_log(L_DBG, "pjmedia_null_port_created failed\n");
|
|
734
|
+
return false;
|
|
735
|
+
}
|
|
736
|
+
|
|
737
|
+
pjmedia_port *conf_port = NULL;
|
|
738
|
+
|
|
739
|
+
conf_port = pjmedia_conf_get_master_port(call->conf);
|
|
740
|
+
if (conf_port == NULL) {
|
|
741
|
+
addon_log(L_DBG, "pjmedia_conf_get_master_port failed\n");
|
|
742
|
+
return false;
|
|
743
|
+
}
|
|
744
|
+
|
|
745
|
+
status = pjmedia_master_port_create(call->inv->pool, call->null_port, conf_port, 0, &call->master_port);
|
|
746
|
+
if (status != PJ_SUCCESS) {
|
|
747
|
+
addon_log(L_DBG, "pjmedia_master_port_create failed\n");
|
|
748
|
+
return false;
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
status = pjmedia_master_port_start(call->master_port);
|
|
752
|
+
if (status != PJ_SUCCESS) {
|
|
753
|
+
addon_log(L_DBG, "pjmedia_master_port_start failed\n");
|
|
754
|
+
return false;
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
return PJ_SUCCESS;
|
|
758
|
+
}
|
|
759
|
+
|
|
760
|
+
void release_call_conf(Call *call) {
|
|
761
|
+
pj_status_t status;
|
|
762
|
+
|
|
763
|
+
if (call->master_port) {
|
|
764
|
+
status = pjmedia_master_port_stop(call->master_port);
|
|
765
|
+
if(status != PJ_SUCCESS) {
|
|
766
|
+
addon_log(L_DBG, "pjmedia_master_port_stop failed\n");
|
|
767
|
+
}
|
|
768
|
+
pjmedia_master_port_destroy(call->master_port, 0);
|
|
769
|
+
if(status != PJ_SUCCESS) {
|
|
770
|
+
addon_log(L_DBG, "pjmedia_master_port_destroy failed\n");
|
|
771
|
+
}
|
|
772
|
+
call->master_port = NULL;
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
if (call->conf) {
|
|
776
|
+
status = pjmedia_conf_destroy(call->conf);
|
|
777
|
+
if(status != PJ_SUCCESS) {
|
|
778
|
+
addon_log(L_DBG, "pjmedia_conf_destroy failed\n");
|
|
779
|
+
}
|
|
780
|
+
call->conf = NULL;
|
|
781
|
+
}
|
|
782
|
+
|
|
783
|
+
if (call->null_port) {
|
|
784
|
+
status = pjmedia_port_destroy(call->null_port);
|
|
785
|
+
if(status != PJ_SUCCESS) {
|
|
786
|
+
addon_log(L_DBG, "pjmedia_port_destroy(null_port) failed\n");
|
|
787
|
+
}
|
|
788
|
+
call->null_port = NULL;
|
|
789
|
+
}
|
|
790
|
+
}
|
|
791
|
+
|
|
713
792
|
static int find_endpoint_by_inband_dtmf_media_port(Call *call,
|
|
714
793
|
pjmedia_port *port) {
|
|
715
794
|
for (int i = 0; i < call->media_count; i++) {
|
|
716
795
|
MediaEndpoint *me = (MediaEndpoint *)call->media[i];
|
|
717
796
|
if (ENDPOINT_TYPE_AUDIO == me->type) {
|
|
718
797
|
AudioEndpoint *ae = (AudioEndpoint *)me->endpoint.audio;
|
|
719
|
-
if ((pjmedia_port *)ae->
|
|
798
|
+
if (ae->dtmfdet_cbp.port && (pjmedia_port *)ae->dtmfdet_cbp.port == port) {
|
|
720
799
|
return i;
|
|
721
800
|
}
|
|
722
801
|
}
|
|
@@ -1116,6 +1195,8 @@ int __pjw_init() {
|
|
|
1116
1195
|
|
|
1117
1196
|
pj_status_t status;
|
|
1118
1197
|
|
|
1198
|
+
pjmedia_port *conf_port = NULL;
|
|
1199
|
+
|
|
1119
1200
|
status = pj_init();
|
|
1120
1201
|
if (status != PJ_SUCCESS) {
|
|
1121
1202
|
addon_log(L_DBG, "pj_init failed\n");
|
|
@@ -1309,6 +1390,7 @@ int __pjw_init() {
|
|
|
1309
1390
|
|
|
1310
1391
|
#if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
|
|
1311
1392
|
status = pjmedia_srtp_init_lib(g_med_endpt);
|
|
1393
|
+
|
|
1312
1394
|
if (status != PJ_SUCCESS) {
|
|
1313
1395
|
addon_log(L_DBG, "Error initializing SRTP library\n");
|
|
1314
1396
|
return 1;
|
|
@@ -2939,6 +3021,12 @@ int call_create(Transport *t, unsigned flags, pjsip_dialog *dlg,
|
|
|
2939
3021
|
}
|
|
2940
3022
|
// addon_log(L_DBG, "pjsip_dlg_add_usage OK\n");
|
|
2941
3023
|
|
|
3024
|
+
status = setup_call_conf(call);
|
|
3025
|
+
if (status != PJ_SUCCESS) {
|
|
3026
|
+
set_error("setup_call_conf failed");
|
|
3027
|
+
return -1;
|
|
3028
|
+
}
|
|
3029
|
+
|
|
2942
3030
|
return call_id;
|
|
2943
3031
|
}
|
|
2944
3032
|
|
|
@@ -2978,10 +3066,10 @@ pj_status_t audio_endpoint_send_dtmf(Call *call, AudioEndpoint *ae,
|
|
|
2978
3066
|
tone.on_msec = ON_DURATION;
|
|
2979
3067
|
tone.off_msec = OFF_DURATION;
|
|
2980
3068
|
tone.volume = 0;
|
|
2981
|
-
status =
|
|
3069
|
+
status = pjmedia_tonegen_play_digits((pjmedia_port *)ae->tonegen_cbp.port, 1,
|
|
2982
3070
|
&tone, 0);
|
|
2983
3071
|
if (status != PJ_SUCCESS) {
|
|
2984
|
-
set_error("
|
|
3072
|
+
set_error("pjmedia_tonegen_play_digits failed.");
|
|
2985
3073
|
return status;
|
|
2986
3074
|
}
|
|
2987
3075
|
}
|
|
@@ -3408,6 +3496,17 @@ int pjw_call_start_record_wav(long call_id, const char *json) {
|
|
|
3408
3496
|
|
|
3409
3497
|
ae = (AudioEndpoint *)me->endpoint.audio;
|
|
3410
3498
|
|
|
3499
|
+
if(!ae->stream_cbp.port) {
|
|
3500
|
+
set_error("stream port is not ready yet");
|
|
3501
|
+
goto out;
|
|
3502
|
+
}
|
|
3503
|
+
|
|
3504
|
+
// stop/destroy existing writer
|
|
3505
|
+
status = audio_endpoint_stop_record_wav(call, ae);
|
|
3506
|
+
if(status != PJ_SUCCESS) {
|
|
3507
|
+
goto out;
|
|
3508
|
+
}
|
|
3509
|
+
|
|
3411
3510
|
if (!prepare_wav_writer(call, ae, file)) {
|
|
3412
3511
|
set_error("prepare_wav_writer failed");
|
|
3413
3512
|
goto out;
|
|
@@ -3424,16 +3523,24 @@ out:
|
|
|
3424
3523
|
|
|
3425
3524
|
pj_status_t audio_endpoint_start_play_wav(Call *call, AudioEndpoint *ae,
|
|
3426
3525
|
const char *file) {
|
|
3427
|
-
|
|
3428
|
-
|
|
3429
|
-
if
|
|
3430
|
-
set_error("
|
|
3431
|
-
return
|
|
3526
|
+
pj_status_t status;
|
|
3527
|
+
|
|
3528
|
+
if(!ae->stream_cbp.port) {
|
|
3529
|
+
set_error("stream port is not ready yet");
|
|
3530
|
+
return -1;
|
|
3531
|
+
}
|
|
3532
|
+
|
|
3533
|
+
// First stop and destroy existing wav port.
|
|
3534
|
+
status = audio_endpoint_stop_play_wav(call, ae);
|
|
3535
|
+
if(status != PJ_SUCCESS) {
|
|
3536
|
+
return -1;
|
|
3432
3537
|
}
|
|
3433
3538
|
|
|
3434
3539
|
if (!prepare_wav_player(call, ae, file)) {
|
|
3435
3540
|
return -1;
|
|
3436
3541
|
}
|
|
3542
|
+
|
|
3543
|
+
return PJ_SUCCESS;
|
|
3437
3544
|
}
|
|
3438
3545
|
|
|
3439
3546
|
// int pjw_call_start_play_wav(long call_id, const char *file)
|
|
@@ -3541,28 +3648,41 @@ pj_status_t call_stop_audio_endpoints_op(Call *call,
|
|
|
3541
3648
|
return PJ_SUCCESS;
|
|
3542
3649
|
}
|
|
3543
3650
|
|
|
3544
|
-
pj_status_t
|
|
3545
|
-
|
|
3546
|
-
pj_status_t status
|
|
3547
|
-
if (status != PJ_SUCCESS) {
|
|
3548
|
-
set_error("pjmedia_stream_get_port failed with status=%i", status);
|
|
3549
|
-
return status;
|
|
3550
|
-
}
|
|
3651
|
+
pj_status_t audio_endpoint_remove_port(Call *call, ConfBridgePort *cbp) {
|
|
3652
|
+
printf("audio_endpoint_remove_port\n");
|
|
3653
|
+
pj_status_t status;
|
|
3551
3654
|
|
|
3552
|
-
if
|
|
3553
|
-
|
|
3554
|
-
|
|
3555
|
-
|
|
3556
|
-
|
|
3557
|
-
|
|
3558
|
-
|
|
3559
|
-
|
|
3655
|
+
if(cbp->port) {
|
|
3656
|
+
/*
|
|
3657
|
+
no need to call pjmedia_conf_disconnect_port because pjmedia_conf_remove_port calls:
|
|
3658
|
+
pjmedia_conf_disconnect_port_from_sources(conf, port);
|
|
3659
|
+
pjmedia_conf_disconnect_port_from_sinks(conf, port);
|
|
3660
|
+
*/
|
|
3661
|
+
|
|
3662
|
+
status = pjmedia_conf_remove_port(call->conf, cbp->slot);
|
|
3663
|
+
if (status != PJ_SUCCESS) {
|
|
3664
|
+
set_error("pjmedia_conf_remove_port failed");
|
|
3665
|
+
return false;
|
|
3666
|
+
}
|
|
3667
|
+
cbp->slot = 0;
|
|
3560
3668
|
|
|
3561
|
-
|
|
3669
|
+
status = pjmedia_port_destroy(cbp->port);
|
|
3670
|
+
if (status != PJ_SUCCESS) {
|
|
3671
|
+
set_error("pjmedia_port_destroy failed");
|
|
3672
|
+
return false;
|
|
3673
|
+
}
|
|
3674
|
+
cbp->port = NULL;
|
|
3675
|
+
}
|
|
3562
3676
|
|
|
3677
|
+
printf("success\n");
|
|
3563
3678
|
return PJ_SUCCESS;
|
|
3564
3679
|
}
|
|
3565
3680
|
|
|
3681
|
+
|
|
3682
|
+
pj_status_t audio_endpoint_stop_play_wav(Call *call, AudioEndpoint *ae) {
|
|
3683
|
+
return audio_endpoint_remove_port(call, &ae->wav_player_cbp);
|
|
3684
|
+
}
|
|
3685
|
+
|
|
3566
3686
|
int pjw_call_stop_play_wav(long call_id, const char *json) {
|
|
3567
3687
|
PJW_LOCK();
|
|
3568
3688
|
clear_error();
|
|
@@ -3639,26 +3759,7 @@ out:
|
|
|
3639
3759
|
}
|
|
3640
3760
|
|
|
3641
3761
|
pj_status_t audio_endpoint_stop_record_wav(Call *call, AudioEndpoint *ae) {
|
|
3642
|
-
|
|
3643
|
-
|
|
3644
|
-
pj_status_t status = pjmedia_stream_get_port(ae->med_stream, &stream_port);
|
|
3645
|
-
if (status != PJ_SUCCESS) {
|
|
3646
|
-
set_error("pjmedia_stream_get_port failed.");
|
|
3647
|
-
return status;
|
|
3648
|
-
}
|
|
3649
|
-
|
|
3650
|
-
if (!prepare_wire(call->inv->pool, &ae->wav_writer,
|
|
3651
|
-
PJMEDIA_PIA_SRATE(&stream_port->info),
|
|
3652
|
-
PJMEDIA_PIA_CCNT(&stream_port->info),
|
|
3653
|
-
PJMEDIA_PIA_SPF(&stream_port->info),
|
|
3654
|
-
PJMEDIA_PIA_BITS(&stream_port->info))) {
|
|
3655
|
-
set_error("prepare_wire failed.");
|
|
3656
|
-
return -1;
|
|
3657
|
-
}
|
|
3658
|
-
|
|
3659
|
-
connect_media_ports(ae);
|
|
3660
|
-
|
|
3661
|
-
return PJ_SUCCESS;
|
|
3762
|
+
return audio_endpoint_remove_port(call, &ae->wav_writer_cbp);
|
|
3662
3763
|
}
|
|
3663
3764
|
|
|
3664
3765
|
int pjw_call_stop_record_wav(long call_id, const char *json) {
|
|
@@ -3735,7 +3836,10 @@ out:
|
|
|
3735
3836
|
return 0;
|
|
3736
3837
|
}
|
|
3737
3838
|
|
|
3738
|
-
|
|
3839
|
+
pj_status_t audio_endpoint_stop_fax(Call *call, AudioEndpoint *ae) {
|
|
3840
|
+
return audio_endpoint_remove_port(call, &ae->fax_cbp);
|
|
3841
|
+
}
|
|
3842
|
+
|
|
3739
3843
|
int pjw_call_start_fax(long call_id, const char *json) {
|
|
3740
3844
|
PJW_LOCK();
|
|
3741
3845
|
clear_error();
|
|
@@ -3841,6 +3945,13 @@ int pjw_call_start_fax(long call_id, const char *json) {
|
|
|
3841
3945
|
flags |= FAX_FLAG_TRANSMIT_ON_IDLE;
|
|
3842
3946
|
}
|
|
3843
3947
|
|
|
3948
|
+
// First stop and destroy existing fax port.
|
|
3949
|
+
status = audio_endpoint_stop_fax(call, ae);
|
|
3950
|
+
if(status != PJ_SUCCESS) {
|
|
3951
|
+
set_error("audio_endpoint_stop_fax failed");
|
|
3952
|
+
return -1;
|
|
3953
|
+
}
|
|
3954
|
+
|
|
3844
3955
|
if (!prepare_fax(call, ae, is_sender, file, flags)) {
|
|
3845
3956
|
set_error("prepare_fax failed");
|
|
3846
3957
|
goto out;
|
|
@@ -3855,28 +3966,6 @@ out:
|
|
|
3855
3966
|
return 0;
|
|
3856
3967
|
}
|
|
3857
3968
|
|
|
3858
|
-
pj_status_t audio_endpoint_stop_fax(Call *call, AudioEndpoint *ae) {
|
|
3859
|
-
pjmedia_port *stream_port;
|
|
3860
|
-
pj_status_t status = pjmedia_stream_get_port(ae->med_stream, &stream_port);
|
|
3861
|
-
if (status != PJ_SUCCESS) {
|
|
3862
|
-
set_error("pjmedia_stream_get_port failed.");
|
|
3863
|
-
return status;
|
|
3864
|
-
}
|
|
3865
|
-
|
|
3866
|
-
if (!prepare_wire(call->inv->pool, &ae->fax,
|
|
3867
|
-
PJMEDIA_PIA_SRATE(&stream_port->info),
|
|
3868
|
-
PJMEDIA_PIA_CCNT(&stream_port->info),
|
|
3869
|
-
PJMEDIA_PIA_SPF(&stream_port->info),
|
|
3870
|
-
PJMEDIA_PIA_BITS(&stream_port->info))) {
|
|
3871
|
-
set_error("prepare_wire failed.");
|
|
3872
|
-
return -1;
|
|
3873
|
-
}
|
|
3874
|
-
|
|
3875
|
-
connect_media_ports(ae);
|
|
3876
|
-
|
|
3877
|
-
return PJ_SUCCESS;
|
|
3878
|
-
}
|
|
3879
|
-
|
|
3880
3969
|
int pjw_call_stop_fax(long call_id, const char *json) {
|
|
3881
3970
|
PJW_LOCK();
|
|
3882
3971
|
clear_error();
|
|
@@ -4050,30 +4139,6 @@ out:
|
|
|
4050
4139
|
return 0;
|
|
4051
4140
|
}
|
|
4052
4141
|
|
|
4053
|
-
bool stop_master_ports(Call *call) {
|
|
4054
|
-
for (int i = 0; i < call->media_count; i++) {
|
|
4055
|
-
MediaEndpoint *me = (MediaEndpoint *)call->media[i];
|
|
4056
|
-
pjmedia_master_port *master_port = NULL;
|
|
4057
|
-
if (ENDPOINT_TYPE_AUDIO == me->type) {
|
|
4058
|
-
AudioEndpoint *ae = (AudioEndpoint *)me->endpoint.audio;
|
|
4059
|
-
master_port = ae->master_port;
|
|
4060
|
-
} else if (ENDPOINT_TYPE_VIDEO == me->type) {
|
|
4061
|
-
VideoEndpoint *ve = (VideoEndpoint *)me->endpoint.video;
|
|
4062
|
-
master_port = ve->master_port;
|
|
4063
|
-
} else {
|
|
4064
|
-
continue;
|
|
4065
|
-
}
|
|
4066
|
-
|
|
4067
|
-
if (master_port) {
|
|
4068
|
-
if (pjmedia_master_port_stop(master_port) != PJ_SUCCESS) {
|
|
4069
|
-
return false;
|
|
4070
|
-
}
|
|
4071
|
-
}
|
|
4072
|
-
}
|
|
4073
|
-
|
|
4074
|
-
return true;
|
|
4075
|
-
}
|
|
4076
|
-
|
|
4077
4142
|
bool media_endpoint_present_in_session_media(
|
|
4078
4143
|
MediaEndpoint *me, const pjmedia_sdp_session *local_sdp) {
|
|
4079
4144
|
printf("media_endpoint_present_in_session_media:\n");
|
|
@@ -4325,16 +4390,71 @@ bool restart_media_stream(Call *call, MediaEndpoint *me,
|
|
|
4325
4390
|
|
|
4326
4391
|
pj_status_t status;
|
|
4327
4392
|
|
|
4328
|
-
if
|
|
4329
|
-
|
|
4393
|
+
if(ae->stream_cbp.port) {
|
|
4394
|
+
if(ae->tonegen_cbp.port) {
|
|
4395
|
+
status = pjmedia_conf_disconnect_port(call->conf, ae->tonegen_cbp.slot, ae->stream_cbp.slot);
|
|
4396
|
+
if (status != PJ_SUCCESS) {
|
|
4397
|
+
make_evt_media_update(evt, sizeof(evt), call->id,
|
|
4398
|
+
"setup_failed (pjmedia_conf_disconnect_port for tonegen failed)", "");
|
|
4399
|
+
dispatch_event(evt);
|
|
4400
|
+
return false;
|
|
4401
|
+
}
|
|
4402
|
+
}
|
|
4403
|
+
|
|
4404
|
+
if(ae->wav_player_cbp.port) {
|
|
4405
|
+
status = pjmedia_conf_disconnect_port(call->conf, ae->wav_player_cbp.slot, ae->stream_cbp.slot);
|
|
4406
|
+
if (status != PJ_SUCCESS) {
|
|
4407
|
+
make_evt_media_update(evt, sizeof(evt), call->id,
|
|
4408
|
+
"setup_failed (pjmedia_conf_disconnect_port for wav_player failed)", "");
|
|
4409
|
+
dispatch_event(evt);
|
|
4410
|
+
return false;
|
|
4411
|
+
}
|
|
4412
|
+
}
|
|
4413
|
+
|
|
4414
|
+
if(ae->dtmfdet_cbp.port) {
|
|
4415
|
+
status = pjmedia_conf_disconnect_port(call->conf, ae->stream_cbp.slot, ae->dtmfdet_cbp.slot);
|
|
4416
|
+
if (status != PJ_SUCCESS) {
|
|
4417
|
+
make_evt_media_update(evt, sizeof(evt), call->id,
|
|
4418
|
+
"setup_failed (pjmedia_conf_disconnect_port for dtmfdet failed)", "");
|
|
4419
|
+
dispatch_event(evt);
|
|
4420
|
+
return false;
|
|
4421
|
+
}
|
|
4422
|
+
}
|
|
4423
|
+
|
|
4424
|
+
if(ae->fax_cbp.port) {
|
|
4425
|
+
status = pjmedia_conf_disconnect_port(call->conf, ae->stream_cbp.slot, ae->fax_cbp.slot);
|
|
4426
|
+
if (status != PJ_SUCCESS) {
|
|
4427
|
+
make_evt_media_update(evt, sizeof(evt), call->id,
|
|
4428
|
+
"setup_failed (pjmedia_conf_disconnect_port fax dst failed)", "");
|
|
4429
|
+
dispatch_event(evt);
|
|
4430
|
+
return false;
|
|
4431
|
+
}
|
|
4432
|
+
|
|
4433
|
+
status = pjmedia_conf_disconnect_port(call->conf, ae->fax_cbp.slot, ae->stream_cbp.slot);
|
|
4434
|
+
if (status != PJ_SUCCESS) {
|
|
4435
|
+
make_evt_media_update(evt, sizeof(evt), call->id,
|
|
4436
|
+
"setup_failed (pjmedia_conf_disconnect_port for fax src failed)", "");
|
|
4437
|
+
dispatch_event(evt);
|
|
4438
|
+
return false;
|
|
4439
|
+
}
|
|
4440
|
+
}
|
|
4441
|
+
|
|
4442
|
+
status = pjmedia_conf_remove_port(call->conf, ae->stream_cbp.slot);
|
|
4330
4443
|
if (status != PJ_SUCCESS) {
|
|
4331
4444
|
make_evt_media_update(evt, sizeof(evt), call->id,
|
|
4332
|
-
|
|
4333
|
-
"");
|
|
4334
|
-
dispatch_event(evt);
|
|
4445
|
+
"setup_failed (pjmedia_conf_remove_port failed)", "");
|
|
4335
4446
|
return false;
|
|
4336
4447
|
}
|
|
4337
|
-
|
|
4448
|
+
ae->stream_cbp.slot = 0;
|
|
4449
|
+
|
|
4450
|
+
status = pjmedia_port_destroy(ae->stream_cbp.port);
|
|
4451
|
+
if (status != PJ_SUCCESS) {
|
|
4452
|
+
make_evt_media_update(evt, sizeof(evt), call->id,
|
|
4453
|
+
"setup_failed (pjmedia_port_destroy failed)", "");
|
|
4454
|
+
return false;
|
|
4455
|
+
}
|
|
4456
|
+
ae->stream_cbp.port = NULL;
|
|
4457
|
+
}
|
|
4338
4458
|
|
|
4339
4459
|
status =
|
|
4340
4460
|
pjmedia_stream_info_from_sdp(&stream_info, call->inv->dlg->pool,
|
|
@@ -4400,8 +4520,7 @@ bool restart_media_stream(Call *call, MediaEndpoint *me,
|
|
|
4400
4520
|
return false;
|
|
4401
4521
|
}
|
|
4402
4522
|
|
|
4403
|
-
|
|
4404
|
-
status = pjmedia_stream_get_port(ae->med_stream, &stream_port);
|
|
4523
|
+
status = pjmedia_stream_get_port(ae->med_stream, &ae->stream_cbp.port);
|
|
4405
4524
|
if (status != PJ_SUCCESS) {
|
|
4406
4525
|
make_evt_media_update(evt, sizeof(evt), call->id,
|
|
4407
4526
|
"setup_failed (pjmedia_stream_get_port failed)", "");
|
|
@@ -4409,21 +4528,71 @@ bool restart_media_stream(Call *call, MediaEndpoint *me,
|
|
|
4409
4528
|
return false;
|
|
4410
4529
|
}
|
|
4411
4530
|
|
|
4412
|
-
|
|
4413
|
-
|
|
4414
|
-
PJMEDIA_PIA_SPF(&stream_port->info),
|
|
4415
|
-
PJMEDIA_PIA_BITS(&stream_port->info))) {
|
|
4531
|
+
status = pjmedia_conf_add_port(call->conf, call->inv->pool, ae->stream_cbp.port, NULL, &ae->stream_cbp.slot);
|
|
4532
|
+
if (status != PJ_SUCCESS) {
|
|
4416
4533
|
make_evt_media_update(evt, sizeof(evt), call->id,
|
|
4417
|
-
"setup_failed (
|
|
4534
|
+
"setup_failed (pjmedia_conf_add_port failed)", "");
|
|
4418
4535
|
dispatch_event(evt);
|
|
4419
4536
|
return false;
|
|
4420
4537
|
}
|
|
4421
4538
|
|
|
4422
|
-
if
|
|
4423
|
-
|
|
4424
|
-
|
|
4425
|
-
|
|
4426
|
-
|
|
4539
|
+
if(!ae->dtmfdet_cbp.port) {
|
|
4540
|
+
if(!prepare_dtmfdet(call, ae)) {
|
|
4541
|
+
make_evt_media_update(evt, sizeof(evt), call->id,
|
|
4542
|
+
"setup_failed (prepare_dtmfdet failed)", "");
|
|
4543
|
+
dispatch_event(evt);
|
|
4544
|
+
return false;
|
|
4545
|
+
}
|
|
4546
|
+
}
|
|
4547
|
+
|
|
4548
|
+
if(ae->tonegen_cbp.port) {
|
|
4549
|
+
status = pjmedia_conf_connect_port(call->conf, ae->tonegen_cbp.slot, ae->stream_cbp.slot, 0);
|
|
4550
|
+
if (status != PJ_SUCCESS) {
|
|
4551
|
+
make_evt_media_update(evt, sizeof(evt), call->id,
|
|
4552
|
+
"setup_failed (pjmedia_conf_connect_port for tonegen failed)", "");
|
|
4553
|
+
dispatch_event(evt);
|
|
4554
|
+
return false;
|
|
4555
|
+
}
|
|
4556
|
+
}
|
|
4557
|
+
|
|
4558
|
+
if(ae->wav_player_cbp.port) {
|
|
4559
|
+
status = pjmedia_conf_connect_port(call->conf, ae->wav_player_cbp.slot, ae->stream_cbp.slot, 0);
|
|
4560
|
+
if (status != PJ_SUCCESS) {
|
|
4561
|
+
make_evt_media_update(evt, sizeof(evt), call->id,
|
|
4562
|
+
"setup_failed (pjmedia_conf_connect_port for wav_player failed)", "");
|
|
4563
|
+
dispatch_event(evt);
|
|
4564
|
+
return false;
|
|
4565
|
+
}
|
|
4566
|
+
}
|
|
4567
|
+
|
|
4568
|
+
if(ae->dtmfdet_cbp.port) {
|
|
4569
|
+
status = pjmedia_conf_connect_port(call->conf, ae->stream_cbp.slot, ae->dtmfdet_cbp.slot, 0);
|
|
4570
|
+
if (status != PJ_SUCCESS) {
|
|
4571
|
+
make_evt_media_update(evt, sizeof(evt), call->id,
|
|
4572
|
+
"setup_failed (pjmedia_conf_connect_port for dtmfdet failed)", "");
|
|
4573
|
+
dispatch_event(evt);
|
|
4574
|
+
return false;
|
|
4575
|
+
|
|
4576
|
+
}
|
|
4577
|
+
}
|
|
4578
|
+
|
|
4579
|
+
if(ae->fax_cbp.port) {
|
|
4580
|
+
status = pjmedia_conf_connect_port(call->conf, ae->stream_cbp.slot, ae->fax_cbp.slot, 0);
|
|
4581
|
+
if (status != PJ_SUCCESS) {
|
|
4582
|
+
make_evt_media_update(evt, sizeof(evt), call->id,
|
|
4583
|
+
"setup_failed (pjmedia_conf_connect_port for fax dst failed)", "");
|
|
4584
|
+
dispatch_event(evt);
|
|
4585
|
+
return false;
|
|
4586
|
+
|
|
4587
|
+
}
|
|
4588
|
+
|
|
4589
|
+
status = pjmedia_conf_connect_port(call->conf, ae->fax_cbp.slot, ae->stream_cbp.slot, 0);
|
|
4590
|
+
if (status != PJ_SUCCESS) {
|
|
4591
|
+
make_evt_media_update(evt, sizeof(evt), call->id,
|
|
4592
|
+
"setup_failed (pjmedia_conf_connect_port for fax src failed)", "");
|
|
4593
|
+
dispatch_event(evt);
|
|
4594
|
+
return false;
|
|
4595
|
+
}
|
|
4427
4596
|
}
|
|
4428
4597
|
|
|
4429
4598
|
return true;
|
|
@@ -4499,13 +4668,6 @@ static void on_media_update(pjsip_inv_session *inv, pj_status_t status) {
|
|
|
4499
4668
|
return;
|
|
4500
4669
|
}
|
|
4501
4670
|
|
|
4502
|
-
if (!stop_master_ports(call)) {
|
|
4503
|
-
make_evt_media_update(evt, sizeof(evt), call->id,
|
|
4504
|
-
"setup_failed (stop_master_port error)", "");
|
|
4505
|
-
dispatch_event(evt);
|
|
4506
|
-
return;
|
|
4507
|
-
}
|
|
4508
|
-
|
|
4509
4671
|
status = pjmedia_sdp_neg_get_active_local(inv->neg, &local_sdp);
|
|
4510
4672
|
if (status != PJ_SUCCESS) {
|
|
4511
4673
|
make_evt_media_update(
|
|
@@ -4541,7 +4703,7 @@ static void on_media_update(pjsip_inv_session *inv, pj_status_t status) {
|
|
|
4541
4703
|
for (int i = 0; i < local_sdp->media_count; i++) {
|
|
4542
4704
|
MediaEndpoint *me = call->media[i];
|
|
4543
4705
|
if (!local_sdp->media[i]->desc.port) {
|
|
4544
|
-
close_media_endpoint(me);
|
|
4706
|
+
close_media_endpoint(call, me);
|
|
4545
4707
|
} else {
|
|
4546
4708
|
if (me->type == ENDPOINT_TYPE_AUDIO) {
|
|
4547
4709
|
if (!restart_media_stream(call, me, local_sdp, remote_sdp, i)) {
|
|
@@ -4557,33 +4719,6 @@ static void on_media_update(pjsip_inv_session *inv, pj_status_t status) {
|
|
|
4557
4719
|
}
|
|
4558
4720
|
}
|
|
4559
4721
|
|
|
4560
|
-
/*
|
|
4561
|
-
printf("active_media_count=%d\n", active_media_count);
|
|
4562
|
-
call->media_count = 0;
|
|
4563
|
-
for (int i = 0; i < active_media_count; i++) {
|
|
4564
|
-
MediaEndpoint *me = active_media[i];
|
|
4565
|
-
call->media[call->media_count++] = me;
|
|
4566
|
-
|
|
4567
|
-
pjmedia_sdp_media *dummy;
|
|
4568
|
-
int idx = find_sdp_media_by_media_endpt(local_sdp, &dummy, me);
|
|
4569
|
-
printf("idx=%d\n", idx);
|
|
4570
|
-
|
|
4571
|
-
if(me->port != 0) {
|
|
4572
|
-
if (me->type == ENDPOINT_TYPE_AUDIO) {
|
|
4573
|
-
if (!restart_media_stream(call, me, local_sdp, remote_sdp, idx)) {
|
|
4574
|
-
return;
|
|
4575
|
-
}
|
|
4576
|
-
} else if(me->type == ENDPOINT_TYPE_MRCP) {
|
|
4577
|
-
if(call->outgoing) {
|
|
4578
|
-
if(!start_tcp_media(call, me, local_sdp, remote_sdp, idx)) {
|
|
4579
|
-
return;
|
|
4580
|
-
}
|
|
4581
|
-
}
|
|
4582
|
-
}
|
|
4583
|
-
}
|
|
4584
|
-
}
|
|
4585
|
-
*/
|
|
4586
|
-
|
|
4587
4722
|
char media[4096];
|
|
4588
4723
|
gen_media_json(media, sizeof(media), call, local_sdp, remote_sdp);
|
|
4589
4724
|
|
|
@@ -4591,62 +4726,6 @@ static void on_media_update(pjsip_inv_session *inv, pj_status_t status) {
|
|
|
4591
4726
|
dispatch_event(evt);
|
|
4592
4727
|
}
|
|
4593
4728
|
|
|
4594
|
-
static pj_bool_t set_ports(Call *call, AudioEndpoint *ae,
|
|
4595
|
-
pjmedia_port *stream_port,
|
|
4596
|
-
pjmedia_port *media_port) {
|
|
4597
|
-
pj_status_t status;
|
|
4598
|
-
|
|
4599
|
-
if (!ae->master_port) {
|
|
4600
|
-
status = pjmedia_master_port_create(call->inv->pool, stream_port,
|
|
4601
|
-
media_port, 0, &ae->master_port);
|
|
4602
|
-
if (status != PJ_SUCCESS) {
|
|
4603
|
-
return PJ_FALSE;
|
|
4604
|
-
}
|
|
4605
|
-
|
|
4606
|
-
status = pjmedia_master_port_start(ae->master_port);
|
|
4607
|
-
if (status != PJ_SUCCESS) {
|
|
4608
|
-
return PJ_FALSE;
|
|
4609
|
-
}
|
|
4610
|
-
|
|
4611
|
-
ae->media_port = media_port;
|
|
4612
|
-
return PJ_TRUE;
|
|
4613
|
-
}
|
|
4614
|
-
|
|
4615
|
-
status = pjmedia_master_port_stop(ae->master_port);
|
|
4616
|
-
if (status != PJ_SUCCESS) {
|
|
4617
|
-
return PJ_FALSE;
|
|
4618
|
-
}
|
|
4619
|
-
|
|
4620
|
-
status = pjmedia_master_port_set_uport(ae->master_port, stream_port);
|
|
4621
|
-
if (status != PJ_SUCCESS) {
|
|
4622
|
-
return PJ_FALSE;
|
|
4623
|
-
}
|
|
4624
|
-
|
|
4625
|
-
if (ae->media_port) {
|
|
4626
|
-
if (ae->media_port != media_port) {
|
|
4627
|
-
status = pjmedia_port_destroy(ae->media_port);
|
|
4628
|
-
if (status != PJ_SUCCESS) {
|
|
4629
|
-
return PJ_FALSE;
|
|
4630
|
-
}
|
|
4631
|
-
}
|
|
4632
|
-
ae->media_port = NULL;
|
|
4633
|
-
}
|
|
4634
|
-
|
|
4635
|
-
status = pjmedia_master_port_set_dport(ae->master_port, media_port);
|
|
4636
|
-
if (status != PJ_SUCCESS) {
|
|
4637
|
-
return PJ_FALSE;
|
|
4638
|
-
}
|
|
4639
|
-
|
|
4640
|
-
ae->media_port = media_port;
|
|
4641
|
-
|
|
4642
|
-
status = pjmedia_master_port_start(ae->master_port);
|
|
4643
|
-
if (status != PJ_SUCCESS) {
|
|
4644
|
-
return PJ_FALSE;
|
|
4645
|
-
}
|
|
4646
|
-
|
|
4647
|
-
return PJ_TRUE;
|
|
4648
|
-
}
|
|
4649
|
-
|
|
4650
4729
|
static void on_state_changed(pjsip_inv_session *inv, pjsip_event *e) {
|
|
4651
4730
|
addon_log(L_DBG, "on_state_changed\n");
|
|
4652
4731
|
|
|
@@ -4687,33 +4766,14 @@ static void on_state_changed(pjsip_inv_session *inv, pjsip_event *e) {
|
|
|
4687
4766
|
return;
|
|
4688
4767
|
}
|
|
4689
4768
|
|
|
4769
|
+
close_media(call);
|
|
4770
|
+
|
|
4690
4771
|
for (int i = 0; i < call->media_count; i++) {
|
|
4691
4772
|
addon_log(L_DBG, "processing media[%d]\n", i);
|
|
4692
4773
|
MediaEndpoint *me = call->media[i];
|
|
4693
4774
|
if (ENDPOINT_TYPE_AUDIO == me->type) {
|
|
4694
4775
|
AudioEndpoint *ae = (AudioEndpoint *)me->endpoint.audio;
|
|
4695
4776
|
addon_log(L_DBG, "processing media[%d] as AudioEndpoint\n", i);
|
|
4696
|
-
if (ae->master_port) {
|
|
4697
|
-
addon_log(L_DBG, "calling pjmedia_port_stop\n");
|
|
4698
|
-
status = pjmedia_master_port_stop(ae->master_port);
|
|
4699
|
-
if (status != PJ_SUCCESS) {
|
|
4700
|
-
addon_log(L_DBG, "pjmedia_master_port_stop failed\n");
|
|
4701
|
-
}
|
|
4702
|
-
|
|
4703
|
-
addon_log(L_DBG, "calling pjmedia_master_port_destroy\n");
|
|
4704
|
-
status = pjmedia_master_port_destroy(ae->master_port, PJ_FALSE);
|
|
4705
|
-
if (status != PJ_SUCCESS) {
|
|
4706
|
-
addon_log(L_DBG, "pjmedia_master_port_destroy failed\n");
|
|
4707
|
-
}
|
|
4708
|
-
}
|
|
4709
|
-
|
|
4710
|
-
if (ae->media_port) {
|
|
4711
|
-
addon_log(L_DBG, "calling pjmedia_port_destroy\n");
|
|
4712
|
-
status = pjmedia_port_destroy(ae->media_port);
|
|
4713
|
-
if (status != PJ_SUCCESS) {
|
|
4714
|
-
addon_log(L_DBG, "pjmedia_port_destroy failed\n");
|
|
4715
|
-
}
|
|
4716
|
-
}
|
|
4717
4777
|
|
|
4718
4778
|
if (ae->med_stream) {
|
|
4719
4779
|
addon_log(L_DBG, "calling pjmedia_stream_destroy");
|
|
@@ -4723,19 +4783,20 @@ static void on_state_changed(pjsip_inv_session *inv, pjsip_event *e) {
|
|
|
4723
4783
|
}
|
|
4724
4784
|
}
|
|
4725
4785
|
}
|
|
4786
|
+
}
|
|
4726
4787
|
|
|
4727
|
-
|
|
4728
|
-
if (!g_call_ids.remove(call_id, val)) {
|
|
4729
|
-
addon_log(L_DBG, "g_call_ids.remove failed\n");
|
|
4730
|
-
}
|
|
4788
|
+
release_call_conf(call);
|
|
4731
4789
|
|
|
4732
|
-
|
|
4733
|
-
|
|
4734
|
-
|
|
4735
|
-
g_LastCalls.push_back(pcc);
|
|
4790
|
+
long val;
|
|
4791
|
+
if (!g_call_ids.remove(call_id, val)) {
|
|
4792
|
+
addon_log(L_DBG, "g_call_ids.remove failed\n");
|
|
4736
4793
|
}
|
|
4737
4794
|
|
|
4738
|
-
|
|
4795
|
+
Pair_Call_CallId pcc;
|
|
4796
|
+
pcc.pCall = call;
|
|
4797
|
+
pcc.id = call_id;
|
|
4798
|
+
g_LastCalls.push_back(pcc);
|
|
4799
|
+
|
|
4739
4800
|
|
|
4740
4801
|
char evt[2048];
|
|
4741
4802
|
int sip_msg_len = 0;
|
|
@@ -5115,6 +5176,13 @@ static pj_bool_t on_rx_request(pjsip_rx_data *rdata) {
|
|
|
5115
5176
|
return PJ_TRUE;
|
|
5116
5177
|
}
|
|
5117
5178
|
|
|
5179
|
+
status = setup_call_conf(call);
|
|
5180
|
+
if (status != PJ_SUCCESS) {
|
|
5181
|
+
printf("setup_call_conf failed\n");
|
|
5182
|
+
pjsip_endpt_respond_stateless(g_sip_endpt, rdata, 500, &reason, NULL, NULL);
|
|
5183
|
+
return PJ_TRUE;
|
|
5184
|
+
}
|
|
5185
|
+
|
|
5118
5186
|
// TODO: check if this is really necessary as we are calling
|
|
5119
5187
|
// pjsip_dlg_add_usage subsequently
|
|
5120
5188
|
inv->dlg->mod_data[mod_tester.id] = call;
|
|
@@ -6315,12 +6383,20 @@ bool is_media_active(Call *c, MediaEndpoint *me) {
|
|
|
6315
6383
|
return false;
|
|
6316
6384
|
}
|
|
6317
6385
|
|
|
6318
|
-
void close_media_endpoint(MediaEndpoint *me) {
|
|
6386
|
+
void close_media_endpoint(Call *call, MediaEndpoint *me) {
|
|
6319
6387
|
printf("close_media_endpoint %x\n", me);
|
|
6320
6388
|
if(!me) return;
|
|
6321
6389
|
|
|
6322
6390
|
if (ENDPOINT_TYPE_AUDIO == me->type) {
|
|
6323
6391
|
AudioEndpoint *ae = (AudioEndpoint *)me->endpoint.audio;
|
|
6392
|
+
|
|
6393
|
+
audio_endpoint_remove_port(call, &ae->stream_cbp);
|
|
6394
|
+
audio_endpoint_remove_port(call, &ae->wav_player_cbp);
|
|
6395
|
+
audio_endpoint_remove_port(call, &ae->wav_writer_cbp);
|
|
6396
|
+
audio_endpoint_remove_port(call, &ae->tonegen_cbp);
|
|
6397
|
+
audio_endpoint_remove_port(call, &ae->dtmfdet_cbp);
|
|
6398
|
+
audio_endpoint_remove_port(call, &ae->fax_cbp);
|
|
6399
|
+
|
|
6324
6400
|
close_media_transport(ae->med_transport);
|
|
6325
6401
|
ae->med_transport = NULL;
|
|
6326
6402
|
} else if (ENDPOINT_TYPE_MRCP == me->type) {
|
|
@@ -6348,154 +6424,138 @@ void close_media(Call *c) {
|
|
|
6348
6424
|
printf("close_media call_id=%x\n", c->id);
|
|
6349
6425
|
for (int i = 0; i < c->media_count; ++i) {
|
|
6350
6426
|
MediaEndpoint *me = c->media[i];
|
|
6351
|
-
close_media_endpoint(me);
|
|
6427
|
+
close_media_endpoint(c, me);
|
|
6352
6428
|
}
|
|
6353
6429
|
c->media_count = 0;
|
|
6354
6430
|
}
|
|
6355
6431
|
|
|
6356
|
-
bool
|
|
6357
|
-
|
|
6358
|
-
unsigned bits_per_sample) {
|
|
6432
|
+
bool prepare_tonegen(Call *c, AudioEndpoint *ae) {
|
|
6433
|
+
printf("prepare_tone_gen call.id=%i\n", c->id);
|
|
6359
6434
|
pj_status_t status;
|
|
6360
6435
|
|
|
6361
|
-
if
|
|
6362
|
-
|
|
6363
|
-
|
|
6364
|
-
bits_per_sample, &ae->null_port);
|
|
6365
|
-
if (status != PJ_SUCCESS)
|
|
6366
|
-
return false;
|
|
6367
|
-
}
|
|
6368
|
-
|
|
6369
|
-
if (!ae->wav_writer) {
|
|
6370
|
-
if (!prepare_wire(call->inv->pool, &ae->wav_writer, sampling_rate,
|
|
6371
|
-
channel_count, samples_per_frame, bits_per_sample)) {
|
|
6372
|
-
return false;
|
|
6373
|
-
}
|
|
6374
|
-
}
|
|
6375
|
-
|
|
6376
|
-
if (!ae->wav_player) {
|
|
6377
|
-
if (!prepare_wire(call->inv->pool, &ae->wav_player, sampling_rate,
|
|
6378
|
-
channel_count, samples_per_frame, bits_per_sample)) {
|
|
6379
|
-
return false;
|
|
6380
|
-
}
|
|
6436
|
+
if(ae->tonegen_cbp.port) {
|
|
6437
|
+
printf("already prepared\n");
|
|
6438
|
+
return true;
|
|
6381
6439
|
}
|
|
6382
6440
|
|
|
6383
|
-
|
|
6384
|
-
|
|
6385
|
-
|
|
6386
|
-
|
|
6387
|
-
|
|
6441
|
+
printf("call.id=%i p1\n", c->id);
|
|
6442
|
+
status = pjmedia_tonegen_create(
|
|
6443
|
+
c->inv->pool, PJMEDIA_PIA_SRATE(&ae->stream_cbp.port->info),
|
|
6444
|
+
PJMEDIA_PIA_CCNT(&ae->stream_cbp.port->info),
|
|
6445
|
+
PJMEDIA_PIA_SPF(&ae->stream_cbp.port->info),
|
|
6446
|
+
PJMEDIA_PIA_BITS(&ae->stream_cbp.port->info), 0, &ae->tonegen_cbp.port);
|
|
6447
|
+
if (status != PJ_SUCCESS) {
|
|
6448
|
+
set_error("pjmedia_tonegen_create failed");
|
|
6449
|
+
return false;
|
|
6388
6450
|
}
|
|
6389
6451
|
|
|
6390
|
-
|
|
6391
|
-
|
|
6392
|
-
|
|
6393
|
-
|
|
6394
|
-
|
|
6395
|
-
return false;
|
|
6452
|
+
printf("call.id=%i p2\n", c->id);
|
|
6453
|
+
status = pjmedia_conf_add_port(c->conf, c->inv->pool, ae->tonegen_cbp.port, NULL, &ae->tonegen_cbp.slot);
|
|
6454
|
+
if (status != PJ_SUCCESS) {
|
|
6455
|
+
set_error("pjmedia_conf_add_port failed");
|
|
6456
|
+
return false;
|
|
6396
6457
|
}
|
|
6397
6458
|
|
|
6398
|
-
|
|
6399
|
-
|
|
6400
|
-
|
|
6401
|
-
|
|
6402
|
-
|
|
6459
|
+
printf("call.id=%i p3\n", c->id);
|
|
6460
|
+
status = pjmedia_conf_connect_port(c->conf, ae->tonegen_cbp.slot, ae->stream_cbp.slot, 0);
|
|
6461
|
+
if (status != PJ_SUCCESS) {
|
|
6462
|
+
set_error("pjmedia_conf_connect_port failed");
|
|
6463
|
+
return false;
|
|
6403
6464
|
}
|
|
6404
6465
|
|
|
6405
|
-
|
|
6466
|
+
printf("call.id=%i p4 (success)\n", c->id);
|
|
6406
6467
|
return true;
|
|
6407
6468
|
}
|
|
6408
6469
|
|
|
6409
|
-
|
|
6410
|
-
((chainlink *)ae->dtmfdet)->next = (pjmedia_port *)ae->tonegen;
|
|
6411
|
-
((chainlink *)ae->tonegen)->next = (pjmedia_port *)ae->wav_player;
|
|
6412
|
-
((chainlink *)ae->wav_player)->next = (pjmedia_port *)ae->wav_writer;
|
|
6413
|
-
((chainlink *)ae->wav_writer)->next = (pjmedia_port *)ae->fax;
|
|
6414
|
-
((chainlink *)ae->fax)->next = ae->null_port;
|
|
6415
|
-
}
|
|
6416
|
-
|
|
6417
|
-
bool prepare_tonegen(Call *c, AudioEndpoint *ae) {
|
|
6418
|
-
printf("prepare_tonegen\n");
|
|
6470
|
+
bool prepare_wav_player(Call *c, AudioEndpoint *ae, const char *file) {
|
|
6419
6471
|
pj_status_t status;
|
|
6420
6472
|
|
|
6421
|
-
|
|
6473
|
+
unsigned wav_ptime;
|
|
6474
|
+
wav_ptime = PJMEDIA_PIA_SPF(&ae->stream_cbp.port->info) * 1000 /
|
|
6475
|
+
PJMEDIA_PIA_SRATE(&ae->stream_cbp.port->info);
|
|
6476
|
+
|
|
6477
|
+
status = pjmedia_wav_player_port_create(
|
|
6478
|
+
c->inv->pool,
|
|
6479
|
+
file,
|
|
6480
|
+
wav_ptime,
|
|
6481
|
+
0, /* flags */
|
|
6482
|
+
-1, /* buf size */
|
|
6483
|
+
&ae->wav_player_cbp.port
|
|
6484
|
+
);
|
|
6422
6485
|
|
|
6423
|
-
pjmedia_port *stream_port;
|
|
6424
|
-
status = pjmedia_stream_get_port(ae->med_stream, &stream_port);
|
|
6425
6486
|
if (status != PJ_SUCCESS) {
|
|
6487
|
+
set_error("pjmedia_wav_player_port_create failed");
|
|
6426
6488
|
return false;
|
|
6427
6489
|
}
|
|
6428
6490
|
|
|
6429
|
-
|
|
6430
|
-
|
|
6431
|
-
|
|
6432
|
-
|
|
6433
|
-
|
|
6434
|
-
|
|
6435
|
-
|
|
6436
|
-
|
|
6491
|
+
status = pjmedia_conf_add_port(c->conf, c->inv->pool, ae->wav_player_cbp.port, NULL, &ae->wav_player_cbp.slot);
|
|
6492
|
+
if (status != PJ_SUCCESS) {
|
|
6493
|
+
set_error("pjmedia_conf_add_port failed");
|
|
6494
|
+
return false;
|
|
6495
|
+
}
|
|
6496
|
+
|
|
6497
|
+
status = pjmedia_conf_connect_port(c->conf, ae->wav_player_cbp.slot, ae->stream_cbp.slot, 0);
|
|
6498
|
+
if (status != PJ_SUCCESS) {
|
|
6499
|
+
set_error("pjmedia_conf_connect_port failed");
|
|
6500
|
+
return false;
|
|
6437
6501
|
}
|
|
6438
6502
|
|
|
6439
|
-
connect_media_ports(ae);
|
|
6440
6503
|
return true;
|
|
6441
6504
|
}
|
|
6442
6505
|
|
|
6443
|
-
bool
|
|
6506
|
+
bool prepare_wav_writer(Call *c, AudioEndpoint *ae, const char *file) {
|
|
6444
6507
|
pj_status_t status;
|
|
6445
6508
|
|
|
6446
|
-
|
|
6447
|
-
|
|
6448
|
-
|
|
6449
|
-
|
|
6509
|
+
status = pjmedia_wav_writer_port_create(
|
|
6510
|
+
c->inv->pool, file, PJMEDIA_PIA_SRATE(&ae->stream_cbp.port->info),
|
|
6511
|
+
PJMEDIA_PIA_CCNT(&ae->stream_cbp.port->info), PJMEDIA_PIA_SPF(&ae->stream_cbp.port->info),
|
|
6512
|
+
PJMEDIA_PIA_BITS(&ae->stream_cbp.port->info), PJMEDIA_FILE_WRITE_PCM, 0,
|
|
6513
|
+
(pjmedia_port **)&ae->wav_writer_cbp.port);
|
|
6450
6514
|
if (status != PJ_SUCCESS) {
|
|
6451
|
-
set_error("
|
|
6515
|
+
set_error("pjmedia_wav_write_port_create failed");
|
|
6452
6516
|
return false;
|
|
6453
6517
|
}
|
|
6454
|
-
|
|
6455
|
-
|
|
6456
|
-
wav_ptime = PJMEDIA_PIA_SPF(&stream_port->info) * 1000 /
|
|
6457
|
-
PJMEDIA_PIA_SRATE(&stream_port->info);
|
|
6458
|
-
|
|
6459
|
-
status = pjmedia_port_destroy((pjmedia_port *)link);
|
|
6518
|
+
|
|
6519
|
+
status = pjmedia_conf_add_port(c->conf, c->inv->pool, ae->wav_writer_cbp.port, NULL, &ae->wav_writer_cbp.slot);
|
|
6460
6520
|
if (status != PJ_SUCCESS) {
|
|
6461
|
-
set_error("
|
|
6521
|
+
set_error("pjmedia_conf_add_port failed");
|
|
6462
6522
|
return false;
|
|
6463
6523
|
}
|
|
6464
6524
|
|
|
6465
|
-
status =
|
|
6466
|
-
c->inv->pool, file, wav_ptime, 0, -1, (pjmedia_port **)&ae->wav_player);
|
|
6525
|
+
status = pjmedia_conf_connect_port(c->conf, ae->stream_cbp.slot, ae->wav_writer_cbp.slot, 0);
|
|
6467
6526
|
if (status != PJ_SUCCESS) {
|
|
6468
|
-
set_error("
|
|
6527
|
+
set_error("pjmedia_conf_connect_port failed");
|
|
6469
6528
|
return false;
|
|
6470
6529
|
}
|
|
6471
6530
|
|
|
6472
|
-
connect_media_ports(ae);
|
|
6473
6531
|
return true;
|
|
6474
6532
|
}
|
|
6475
6533
|
|
|
6476
|
-
bool
|
|
6534
|
+
bool prepare_dtmfdet(Call *c, AudioEndpoint *ae) {
|
|
6477
6535
|
pj_status_t status;
|
|
6478
|
-
|
|
6479
|
-
|
|
6480
|
-
|
|
6481
|
-
|
|
6482
|
-
|
|
6483
|
-
|
|
6484
|
-
|
|
6485
|
-
|
|
6486
|
-
|
|
6487
|
-
|
|
6536
|
+
status = pjmedia_dtmfdet_create(
|
|
6537
|
+
c->inv->pool,
|
|
6538
|
+
PJMEDIA_PIA_SRATE(&ae->stream_cbp.port->info),
|
|
6539
|
+
PJMEDIA_PIA_CCNT(&ae->stream_cbp.port->info), PJMEDIA_PIA_SPF(&ae->stream_cbp.port->info),
|
|
6540
|
+
PJMEDIA_PIA_BITS(&ae->stream_cbp.port->info),
|
|
6541
|
+
on_inband_dtmf, c, &ae->dtmfdet_cbp.port);
|
|
6542
|
+
if (status != PJ_SUCCESS) {
|
|
6543
|
+
set_error("pjmedia_dtmfdet_create failed");
|
|
6544
|
+
return false;
|
|
6545
|
+
}
|
|
6546
|
+
|
|
6547
|
+
status = pjmedia_conf_add_port(c->conf, c->inv->pool, ae->dtmfdet_cbp.port, NULL, &ae->dtmfdet_cbp.slot);
|
|
6548
|
+
if (status != PJ_SUCCESS) {
|
|
6549
|
+
set_error("pjmedia_conf_add_port failed");
|
|
6488
6550
|
return false;
|
|
6551
|
+
}
|
|
6489
6552
|
|
|
6490
|
-
status =
|
|
6491
|
-
|
|
6492
|
-
|
|
6493
|
-
PJMEDIA_PIA_BITS(&stream_port->info), PJMEDIA_FILE_WRITE_PCM, 0,
|
|
6494
|
-
(pjmedia_port **)&ae->wav_writer);
|
|
6495
|
-
if (status != PJ_SUCCESS)
|
|
6553
|
+
status = pjmedia_conf_connect_port(c->conf, ae->stream_cbp.slot, ae->dtmfdet_cbp.slot, 0);
|
|
6554
|
+
if (status != PJ_SUCCESS) {
|
|
6555
|
+
set_error("pjmedia_conf_connect_port failed");
|
|
6496
6556
|
return false;
|
|
6557
|
+
}
|
|
6497
6558
|
|
|
6498
|
-
connect_media_ports(ae);
|
|
6499
6559
|
return true;
|
|
6500
6560
|
}
|
|
6501
6561
|
|
|
@@ -6503,48 +6563,36 @@ bool prepare_fax(Call *c, AudioEndpoint *ae, bool is_sender, const char *file,
|
|
|
6503
6563
|
unsigned flags) {
|
|
6504
6564
|
pj_status_t status;
|
|
6505
6565
|
|
|
6506
|
-
|
|
6507
|
-
|
|
6508
|
-
|
|
6509
|
-
|
|
6510
|
-
|
|
6566
|
+
status = pjmedia_fax_port_create(
|
|
6567
|
+
c->inv->pool,
|
|
6568
|
+
PJMEDIA_PIA_SRATE(&ae->stream_cbp.port->info),
|
|
6569
|
+
PJMEDIA_PIA_CCNT(&ae->stream_cbp.port->info),
|
|
6570
|
+
PJMEDIA_PIA_SPF(&ae->stream_cbp.port->info),
|
|
6571
|
+
PJMEDIA_PIA_BITS(&ae->stream_cbp.port->info),
|
|
6572
|
+
on_fax_result, c, is_sender, file,
|
|
6573
|
+
flags, &ae->fax_cbp.port);
|
|
6574
|
+
if (status != PJ_SUCCESS) {
|
|
6575
|
+
set_error("pjmedia_fax_port_create failed");
|
|
6511
6576
|
return false;
|
|
6577
|
+
}
|
|
6512
6578
|
|
|
6513
|
-
status =
|
|
6514
|
-
if (status != PJ_SUCCESS)
|
|
6579
|
+
status = pjmedia_conf_add_port(c->conf, c->inv->pool, ae->fax_cbp.port, NULL, &ae->fax_cbp.slot);
|
|
6580
|
+
if (status != PJ_SUCCESS) {
|
|
6581
|
+
set_error("pjmedia_conf_add_port failed");
|
|
6515
6582
|
return false;
|
|
6583
|
+
}
|
|
6516
6584
|
|
|
6517
|
-
status =
|
|
6518
|
-
|
|
6519
|
-
|
|
6520
|
-
PJMEDIA_PIA_BITS(&stream_port->info), on_fax_result, c, is_sender, file,
|
|
6521
|
-
flags, (pjmedia_port **)&ae->fax);
|
|
6522
|
-
if (status != PJ_SUCCESS)
|
|
6585
|
+
status = pjmedia_conf_connect_port(c->conf, ae->fax_cbp.slot, ae->stream_cbp.slot, 0);
|
|
6586
|
+
if (status != PJ_SUCCESS) {
|
|
6587
|
+
set_error("pjmedia_conf_connect_port failed");
|
|
6523
6588
|
return false;
|
|
6524
|
-
|
|
6525
|
-
connect_media_ports(ae);
|
|
6526
|
-
return true;
|
|
6527
|
-
}
|
|
6528
|
-
|
|
6529
|
-
bool prepare_wire(pj_pool_t *pool, chainlink **link, unsigned sampling_rate,
|
|
6530
|
-
unsigned channel_count, unsigned samples_per_frame,
|
|
6531
|
-
unsigned bits_per_sample) {
|
|
6532
|
-
pj_status_t status;
|
|
6533
|
-
|
|
6534
|
-
if (*link) {
|
|
6535
|
-
// addon_log(L_DBG, "prepare_wire: link is set. It will be destroyed\n");
|
|
6536
|
-
pjmedia_port *port = (pjmedia_port *)*link;
|
|
6537
|
-
status = pjmedia_port_destroy(port);
|
|
6538
|
-
*link = NULL;
|
|
6539
|
-
if (status != PJ_SUCCESS)
|
|
6540
|
-
return false;
|
|
6541
6589
|
}
|
|
6542
6590
|
|
|
6543
|
-
status =
|
|
6544
|
-
|
|
6545
|
-
|
|
6546
|
-
if (status != PJ_SUCCESS)
|
|
6591
|
+
status = pjmedia_conf_connect_port(c->conf, ae->stream_cbp.slot, ae->fax_cbp.slot, 0);
|
|
6592
|
+
if (status != PJ_SUCCESS) {
|
|
6593
|
+
set_error("pjmedia_conf_connect_port failed");
|
|
6547
6594
|
return false;
|
|
6595
|
+
}
|
|
6548
6596
|
|
|
6549
6597
|
return true;
|
|
6550
6598
|
}
|