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
- // Customized media ports that can be chained
24
- #include "chainlink.h"
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->dtmfdet == port) {
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 = chainlink_tonegen_play_digits((pjmedia_port *)ae->tonegen, 1,
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("chainlink_tonegen_play_digits failed.");
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
- pjmedia_port *stream_port;
3428
- pj_status_t status = pjmedia_stream_get_port(ae->med_stream, &stream_port);
3429
- if (status != PJ_SUCCESS) {
3430
- set_error("pjmedia_stream_get_port failed with status=%i", status);
3431
- return status;
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 audio_endpoint_stop_play_wav(Call *call, AudioEndpoint *ae) {
3545
- pjmedia_port *stream_port;
3546
- pj_status_t status = pjmedia_stream_get_port(ae->med_stream, &stream_port);
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 (!prepare_wire(call->inv->pool, &ae->wav_player,
3553
- PJMEDIA_PIA_SRATE(&stream_port->info),
3554
- PJMEDIA_PIA_CCNT(&stream_port->info),
3555
- PJMEDIA_PIA_SPF(&stream_port->info),
3556
- PJMEDIA_PIA_BITS(&stream_port->info))) {
3557
- set_error("prepare_wire failed.");
3558
- return -1;
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
- connect_media_ports(ae);
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
- pjmedia_port *stream_port;
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
- // int pjw_call_start_fax(long call_id, bool is_sender, const char *file)
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 (ae->master_port) {
4329
- status = pjmedia_master_port_stop(ae->master_port);
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
- "setup_failed (pjmedia_master_port_stop failed)",
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
- pjmedia_port *stream_port;
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
- if (!init_media_ports(call, ae, PJMEDIA_PIA_SRATE(&stream_port->info),
4413
- PJMEDIA_PIA_CCNT(&stream_port->info),
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 (init_media_ports failed)", "");
4534
+ "setup_failed (pjmedia_conf_add_port failed)", "");
4418
4535
  dispatch_event(evt);
4419
4536
  return false;
4420
4537
  }
4421
4538
 
4422
- if (!set_ports(call, ae, stream_port, (pjmedia_port *)ae->dtmfdet)) {
4423
- make_evt_media_update(evt, sizeof(evt), call->id,
4424
- "setup_failed (set_ports failed)", "");
4425
- dispatch_event(evt);
4426
- return false;
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
- long val;
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
- Pair_Call_CallId pcc;
4733
- pcc.pCall = call;
4734
- pcc.id = call_id;
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
- close_media(call);
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 init_media_ports(Call *call, AudioEndpoint *ae, unsigned sampling_rate,
6357
- unsigned channel_count, unsigned samples_per_frame,
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 (!ae->null_port) {
6362
- status = pjmedia_null_port_create(call->inv->pool, sampling_rate,
6363
- channel_count, samples_per_frame,
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
- if (!ae->tonegen) {
6384
- if (!prepare_wire(call->inv->pool, &ae->tonegen, sampling_rate,
6385
- channel_count, samples_per_frame, bits_per_sample)) {
6386
- return false;
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
- if (!ae->dtmfdet) {
6391
- status = chainlink_dtmfdet_create(
6392
- call->inv->pool, sampling_rate, channel_count, samples_per_frame,
6393
- bits_per_sample, on_inband_dtmf, call, (pjmedia_port **)&ae->dtmfdet);
6394
- if (status != PJ_SUCCESS)
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
- if (!ae->fax) {
6399
- if (!prepare_wire(call->inv->pool, &ae->fax, sampling_rate, channel_count,
6400
- samples_per_frame, bits_per_sample)) {
6401
- return false;
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
- connect_media_ports(ae);
6466
+ printf("call.id=%i p4 (success)\n", c->id);
6406
6467
  return true;
6407
6468
  }
6408
6469
 
6409
- void connect_media_ports(AudioEndpoint *ae) {
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
- chainlink *link = (chainlink *)ae->tonegen;
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
- if (link->port.info.signature == CHAINLINK_WIRE_PORT_SIGNATURE) {
6430
- status = chainlink_tonegen_create(
6431
- c->inv->pool, PJMEDIA_PIA_SRATE(&stream_port->info),
6432
- PJMEDIA_PIA_CCNT(&stream_port->info),
6433
- PJMEDIA_PIA_SPF(&stream_port->info),
6434
- PJMEDIA_PIA_BITS(&stream_port->info), 0, (pjmedia_port **)&ae->tonegen);
6435
- if (status != PJ_SUCCESS)
6436
- return false;
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 prepare_wav_player(Call *c, AudioEndpoint *ae, const char *file) {
6506
+ bool prepare_wav_writer(Call *c, AudioEndpoint *ae, const char *file) {
6444
6507
  pj_status_t status;
6445
6508
 
6446
- chainlink *link = (chainlink *)ae->wav_player;
6447
-
6448
- pjmedia_port *stream_port;
6449
- status = pjmedia_stream_get_port(ae->med_stream, &stream_port);
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("pj_media_stream_get_port failed");
6515
+ set_error("pjmedia_wav_write_port_create failed");
6452
6516
  return false;
6453
6517
  }
6454
-
6455
- unsigned wav_ptime;
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("pjmedia_port_destroy failed");
6521
+ set_error("pjmedia_conf_add_port failed");
6462
6522
  return false;
6463
6523
  }
6464
6524
 
6465
- status = chainlink_wav_player_port_create(
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("chainllink_wav_player_port_create failed");
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 prepare_wav_writer(Call *c, AudioEndpoint *ae, const char *file) {
6534
+ bool prepare_dtmfdet(Call *c, AudioEndpoint *ae) {
6477
6535
  pj_status_t status;
6478
-
6479
- chainlink *link = (chainlink *)ae->wav_writer;
6480
-
6481
- pjmedia_port *stream_port;
6482
- status = pjmedia_stream_get_port(ae->med_stream, &stream_port);
6483
- if (status != PJ_SUCCESS)
6484
- return false;
6485
-
6486
- status = pjmedia_port_destroy((pjmedia_port *)link);
6487
- if (status != PJ_SUCCESS)
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 = chainlink_wav_writer_port_create(
6491
- c->inv->pool, file, PJMEDIA_PIA_SRATE(&stream_port->info),
6492
- PJMEDIA_PIA_CCNT(&stream_port->info), PJMEDIA_PIA_SPF(&stream_port->info),
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
- chainlink *link = (chainlink *)ae->fax;
6507
-
6508
- pjmedia_port *stream_port;
6509
- status = pjmedia_stream_get_port(ae->med_stream, &stream_port);
6510
- if (status != PJ_SUCCESS)
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 = pjmedia_port_destroy((pjmedia_port *)link);
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 = chainlink_fax_port_create(
6518
- c->inv->pool, PJMEDIA_PIA_SRATE(&stream_port->info),
6519
- PJMEDIA_PIA_CCNT(&stream_port->info), PJMEDIA_PIA_SPF(&stream_port->info),
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 = chainlink_wire_port_create(pool, sampling_rate, channel_count,
6544
- samples_per_frame, bits_per_sample,
6545
- (pjmedia_port **)link);
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
  }