sip-lab 1.17.10 → 1.19.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
 
@@ -228,10 +223,10 @@ bool json_get_and_check_uri(Document &document, const char *param,
228
223
  return true;
229
224
  }
230
225
 
231
- static pjsip_method info_method = {PJSIP_OTHER_METHOD, {"INFO", 4}};
232
- static pjsip_method message_method = {PJSIP_OTHER_METHOD, {"MESSAGE", 7}};
226
+ static pjsip_method info_method = {PJSIP_OTHER_METHOD, {(char*)"INFO", 4}};
227
+ static pjsip_method message_method = {PJSIP_OTHER_METHOD, {(char*)"MESSAGE", 7}};
233
228
 
234
- static pj_str_t trying_reason = pj_str("Trying");
229
+ static pj_str_t trying_reason = pj_str((char*)"Trying");
235
230
 
236
231
  #define PJW_LOCK() pthread_mutex_lock(&g_mutex)
237
232
  #define PJW_UNLOCK() pthread_mutex_unlock(&g_mutex)
@@ -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;
@@ -527,8 +531,8 @@ static void on_dtmf(pjmedia_stream *stream, void *user_data, int digit);
527
531
  /* Callback for Registration Status */
528
532
  static void on_registration_status(pjsip_regc_cbparam *param);
529
533
 
530
- static void on_tsx_state_changed(pjsip_inv_session *inv, pjsip_transaction *tsx,
531
- pjsip_event *e);
534
+ /* static void on_tsx_state_changed(pjsip_inv_session *inv, pjsip_transaction *tsx,
535
+ pjsip_event *e); */
532
536
 
533
537
  static void client_on_evsub_state(pjsip_evsub *sub, pjsip_event *event);
534
538
  static void on_client_refresh(pjsip_evsub *sub);
@@ -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
  }
@@ -856,9 +935,6 @@ static pj_bool_t on_data_read(pj_activesock_t *asock, void *data,
856
935
  return PJ_FALSE;
857
936
  }
858
937
 
859
- assert(ud->len >= 0);
860
-
861
- assert(size >= 0);
862
938
  assert(size + ud->len + 1 < MAX_TCP_DATA);
863
939
 
864
940
  memcpy(&ud->buf[ud->len], data, size);
@@ -892,7 +968,7 @@ static pj_bool_t on_data_read(pj_activesock_t *asock, void *data,
892
968
  assert(body_len > 0 && body_len < 4096);
893
969
 
894
970
  if(ud->buf+ud->len < sep+4+body_len) {
895
- printf("tcp data: msg incomplete %i %i\n", ud->buf+ud->len, sep+4+body_len);
971
+ //printf("tcp data: msg incomplete %i %i\n", ud->buf+ud->len, sep+4+body_len);
896
972
  *remainder = 0;
897
973
  return PJ_TRUE;
898
974
  }
@@ -1022,17 +1098,14 @@ static pj_bool_t on_connect_complete(pj_activesock_t *asock,
1022
1098
  }
1023
1099
 
1024
1100
  static pj_activesock_t* create_tcp_socket(pjsip_endpoint *sip_endpt, pj_str_t *ipaddr, pj_uint16_t *out_port, MediaEndpoint *media_endpt, Call *call) {
1025
- pj_ioqueue_key_t **skey;
1026
1101
  pj_ioqueue_t *ioqueue = pjsip_endpt_get_ioqueue(sip_endpt);
1027
1102
 
1028
1103
  pj_pool_t *pool = call->inv->dlg->pool;
1029
1104
 
1030
- skey = (pj_ioqueue_key_t **)pj_pool_alloc(pool, sizeof(pj_ioqueue_key_t *));
1031
1105
  pj_sock_t *sock = (pj_sock_t *)pj_pool_alloc(pool, sizeof(pj_sock_t));
1032
1106
 
1033
1107
  pj_status_t rc;
1034
- pj_sockaddr_in addr, client_add, rmt_addr;
1035
- int client_addr_len;
1108
+ pj_sockaddr_in addr;
1036
1109
 
1037
1110
  pj_activesock_t *asock = NULL;
1038
1111
 
@@ -1309,6 +1382,7 @@ int __pjw_init() {
1309
1382
 
1310
1383
  #if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
1311
1384
  status = pjmedia_srtp_init_lib(g_med_endpt);
1385
+
1312
1386
  if (status != PJ_SUCCESS) {
1313
1387
  addon_log(L_DBG, "Error initializing SRTP library\n");
1314
1388
  return 1;
@@ -2010,8 +2084,6 @@ int pjw_call_respond(long call_id, const char *json) {
2010
2084
 
2011
2085
  pjsip_tx_data *tdata;
2012
2086
 
2013
- const pjmedia_sdp_session *local_sdp;
2014
-
2015
2087
  Call *call;
2016
2088
 
2017
2089
  char buffer[MAX_JSON_INPUT];
@@ -2897,7 +2969,7 @@ int call_create(Transport *t, unsigned flags, pjsip_dialog *dlg,
2897
2969
  pjsip_tx_data *tdata;
2898
2970
  status = pjsip_inv_invite(inv, &tdata);
2899
2971
  if (status != PJ_SUCCESS) {
2900
- g_call_ids.remove(call_id, (long &)call);
2972
+ g_call_ids.remove(call_id, (long&)call);
2901
2973
  close_media(call);
2902
2974
  status = pjsip_dlg_terminate(dlg); // ToDo:
2903
2975
  set_error("pjsip_inv_invite failed");
@@ -2905,7 +2977,7 @@ int call_create(Transport *t, unsigned flags, pjsip_dialog *dlg,
2905
2977
  }
2906
2978
 
2907
2979
  if (!add_headers(dlg->pool, tdata, document)) {
2908
- g_call_ids.remove(call_id, (long &)call);
2980
+ g_call_ids.remove(call_id, (long&)call);
2909
2981
  close_media(call); // Todo:
2910
2982
  status = pjsip_dlg_terminate(dlg); // ToDo:
2911
2983
  return -1;
@@ -2914,13 +2986,12 @@ int call_create(Transport *t, unsigned flags, pjsip_dialog *dlg,
2914
2986
  if (!dlg_set_transport_by_t(t, dlg)) {
2915
2987
  return -1;
2916
2988
  }
2917
- addon_log(L_DBG, "inv=%x tdata=%x\n", inv, tdata);
2989
+ addon_log(L_DBG, "inv=%p tdata=%p\n", (void*)inv, (void*)tdata);
2918
2990
 
2919
2991
  status = pjsip_inv_send_msg(inv, tdata);
2920
2992
  addon_log(L_DBG, "status=%d\n", status);
2921
- pj_perror(0, "", status, "");
2922
2993
  if (status != PJ_SUCCESS) {
2923
- g_call_ids.remove(call_id, (long &)call);
2994
+ g_call_ids.remove(call_id, (long&)call);
2924
2995
  close_media(call); // Todo:
2925
2996
  // The below code cannot be called here it will cause seg fault
2926
2997
  // status = pjsip_dlg_terminate(dlg); //ToDo:
@@ -2931,7 +3002,7 @@ int call_create(Transport *t, unsigned flags, pjsip_dialog *dlg,
2931
3002
  // Without this, on_rx_response will not be called
2932
3003
  status = pjsip_dlg_add_usage(dlg, &mod_tester, call);
2933
3004
  if (status != PJ_SUCCESS) {
2934
- g_call_ids.remove(call_id, (long &)call);
3005
+ g_call_ids.remove(call_id, (long&)call);
2935
3006
  close_media(call); // Todo:
2936
3007
  status = pjsip_dlg_terminate(dlg); // ToDo:
2937
3008
  set_error("pjsip_dlg_add_usage failed");
@@ -2939,6 +3010,12 @@ int call_create(Transport *t, unsigned flags, pjsip_dialog *dlg,
2939
3010
  }
2940
3011
  // addon_log(L_DBG, "pjsip_dlg_add_usage OK\n");
2941
3012
 
3013
+ status = setup_call_conf(call);
3014
+ if (status != PJ_SUCCESS) {
3015
+ set_error("setup_call_conf failed");
3016
+ return -1;
3017
+ }
3018
+
2942
3019
  return call_id;
2943
3020
  }
2944
3021
 
@@ -2978,10 +3055,10 @@ pj_status_t audio_endpoint_send_dtmf(Call *call, AudioEndpoint *ae,
2978
3055
  tone.on_msec = ON_DURATION;
2979
3056
  tone.off_msec = OFF_DURATION;
2980
3057
  tone.volume = 0;
2981
- status = chainlink_tonegen_play_digits((pjmedia_port *)ae->tonegen, 1,
3058
+ status = pjmedia_tonegen_play_digits((pjmedia_port *)ae->tonegen_cbp.port, 1,
2982
3059
  &tone, 0);
2983
3060
  if (status != PJ_SUCCESS) {
2984
- set_error("chainlink_tonegen_play_digits failed.");
3061
+ set_error("pjmedia_tonegen_play_digits failed.");
2985
3062
  return status;
2986
3063
  }
2987
3064
  }
@@ -3022,8 +3099,6 @@ int pjw_call_send_dtmf(long call_id, const char *json) {
3022
3099
  int mode = 0;
3023
3100
  ;
3024
3101
 
3025
- pj_status_t status;
3026
-
3027
3102
  Call *call;
3028
3103
 
3029
3104
  char buffer[MAX_JSON_INPUT];
@@ -3115,8 +3190,6 @@ int pjw_call_reinvite(long call_id, const char *json) {
3115
3190
 
3116
3191
  pj_status_t status;
3117
3192
 
3118
- const pjmedia_sdp_session *old_sdp = NULL;
3119
-
3120
3193
  pjsip_tx_data *tdata;
3121
3194
  // pjmedia_sdp_session *sdp = 0;
3122
3195
 
@@ -3343,9 +3416,8 @@ int pjw_call_start_record_wav(long call_id, const char *json) {
3343
3416
  long val;
3344
3417
  Call *call;
3345
3418
  pj_status_t status;
3346
- pjmedia_port *stream_port;
3347
3419
 
3348
- unsigned media_id = 0;
3420
+ unsigned media_id = 0;
3349
3421
 
3350
3422
  MediaEndpoint *me;
3351
3423
  AudioEndpoint *ae;
@@ -3395,7 +3467,7 @@ int pjw_call_start_record_wav(long call_id, const char *json) {
3395
3467
  }
3396
3468
  }
3397
3469
 
3398
- if (media_id >= call->media_count) {
3470
+ if ((int)media_id >= call->media_count) {
3399
3471
  set_error("invalid media_id");
3400
3472
  goto out;
3401
3473
  }
@@ -3408,6 +3480,17 @@ int pjw_call_start_record_wav(long call_id, const char *json) {
3408
3480
 
3409
3481
  ae = (AudioEndpoint *)me->endpoint.audio;
3410
3482
 
3483
+ if(!ae->stream_cbp.port) {
3484
+ set_error("stream port is not ready yet");
3485
+ goto out;
3486
+ }
3487
+
3488
+ // stop/destroy existing writer
3489
+ status = audio_endpoint_stop_record_wav(call, ae);
3490
+ if(status != PJ_SUCCESS) {
3491
+ goto out;
3492
+ }
3493
+
3411
3494
  if (!prepare_wav_writer(call, ae, file)) {
3412
3495
  set_error("prepare_wav_writer failed");
3413
3496
  goto out;
@@ -3424,16 +3507,24 @@ out:
3424
3507
 
3425
3508
  pj_status_t audio_endpoint_start_play_wav(Call *call, AudioEndpoint *ae,
3426
3509
  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;
3510
+ pj_status_t status;
3511
+
3512
+ if(!ae->stream_cbp.port) {
3513
+ set_error("stream port is not ready yet");
3514
+ return -1;
3515
+ }
3516
+
3517
+ // First stop and destroy existing wav port.
3518
+ status = audio_endpoint_stop_play_wav(call, ae);
3519
+ if(status != PJ_SUCCESS) {
3520
+ return -1;
3432
3521
  }
3433
3522
 
3434
3523
  if (!prepare_wav_player(call, ae, file)) {
3435
3524
  return -1;
3436
3525
  }
3526
+
3527
+ return PJ_SUCCESS;
3437
3528
  }
3438
3529
 
3439
3530
  // int pjw_call_start_play_wav(long call_id, const char *file)
@@ -3443,8 +3534,6 @@ int pjw_call_start_play_wav(long call_id, const char *json) {
3443
3534
 
3444
3535
  long val;
3445
3536
  Call *call;
3446
- pj_status_t status;
3447
- pjmedia_port *stream_port;
3448
3537
 
3449
3538
  MediaEndpoint *me;
3450
3539
  AudioEndpoint *ae;
@@ -3496,7 +3585,7 @@ int pjw_call_start_play_wav(long call_id, const char *json) {
3496
3585
  }
3497
3586
  }
3498
3587
 
3499
- if (media_id >= call->media_count) {
3588
+ if ((int)media_id >= call->media_count) {
3500
3589
  set_error("invalid media_id");
3501
3590
  goto out;
3502
3591
  }
@@ -3541,28 +3630,41 @@ pj_status_t call_stop_audio_endpoints_op(Call *call,
3541
3630
  return PJ_SUCCESS;
3542
3631
  }
3543
3632
 
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
- }
3633
+ pj_status_t audio_endpoint_remove_port(Call *call, ConfBridgePort *cbp) {
3634
+ printf("audio_endpoint_remove_port\n");
3635
+ pj_status_t status;
3551
3636
 
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
- }
3637
+ if(cbp->port) {
3638
+ /*
3639
+ no need to call pjmedia_conf_disconnect_port because pjmedia_conf_remove_port calls:
3640
+ pjmedia_conf_disconnect_port_from_sources(conf, port);
3641
+ pjmedia_conf_disconnect_port_from_sinks(conf, port);
3642
+ */
3643
+
3644
+ status = pjmedia_conf_remove_port(call->conf, cbp->slot);
3645
+ if (status != PJ_SUCCESS) {
3646
+ set_error("pjmedia_conf_remove_port failed");
3647
+ return false;
3648
+ }
3649
+ cbp->slot = 0;
3560
3650
 
3561
- connect_media_ports(ae);
3651
+ status = pjmedia_port_destroy(cbp->port);
3652
+ if (status != PJ_SUCCESS) {
3653
+ set_error("pjmedia_port_destroy failed");
3654
+ return false;
3655
+ }
3656
+ cbp->port = NULL;
3657
+ }
3562
3658
 
3659
+ printf("success\n");
3563
3660
  return PJ_SUCCESS;
3564
3661
  }
3565
3662
 
3663
+
3664
+ pj_status_t audio_endpoint_stop_play_wav(Call *call, AudioEndpoint *ae) {
3665
+ return audio_endpoint_remove_port(call, &ae->wav_player_cbp);
3666
+ }
3667
+
3566
3668
  int pjw_call_stop_play_wav(long call_id, const char *json) {
3567
3669
  PJW_LOCK();
3568
3670
  clear_error();
@@ -3575,15 +3677,12 @@ int pjw_call_stop_play_wav(long call_id, const char *json) {
3575
3677
 
3576
3678
  MediaEndpoint *me;
3577
3679
  AudioEndpoint *ae;
3578
- int ae_count;
3579
3680
  int res;
3580
3681
 
3581
3682
  unsigned media_id = 0;
3582
3683
 
3583
3684
  char buffer[MAX_JSON_INPUT];
3584
3685
 
3585
- const char *valid_params[] = {"media_id", ""};
3586
-
3587
3686
  Document document;
3588
3687
 
3589
3688
  if (!g_call_ids.get(call_id, val)) {
@@ -3610,7 +3709,7 @@ int pjw_call_stop_play_wav(long call_id, const char *json) {
3610
3709
  } else {
3611
3710
  // Stop play wav on specified media_id
3612
3711
 
3613
- if (media_id >= call->media_count) {
3712
+ if ((int)media_id >= call->media_count) {
3614
3713
  set_error("invalid media_id");
3615
3714
  goto out;
3616
3715
  }
@@ -3639,26 +3738,7 @@ out:
3639
3738
  }
3640
3739
 
3641
3740
  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;
3741
+ return audio_endpoint_remove_port(call, &ae->wav_writer_cbp);
3662
3742
  }
3663
3743
 
3664
3744
  int pjw_call_stop_record_wav(long call_id, const char *json) {
@@ -3667,20 +3747,16 @@ int pjw_call_stop_record_wav(long call_id, const char *json) {
3667
3747
 
3668
3748
  long val;
3669
3749
  Call *call = (Call *)val;
3670
- pjmedia_port *stream_port;
3671
3750
  pj_status_t status;
3672
3751
 
3673
3752
  MediaEndpoint *me;
3674
3753
  AudioEndpoint *ae;
3675
- int ae_count;
3676
3754
  int res;
3677
3755
 
3678
3756
  unsigned media_id = 0;
3679
3757
 
3680
3758
  char buffer[MAX_JSON_INPUT];
3681
3759
 
3682
- const char *valid_params[] = {"media_id", ""};
3683
-
3684
3760
  Document document;
3685
3761
 
3686
3762
  if (!g_call_ids.get(call_id, val)) {
@@ -3707,7 +3783,7 @@ int pjw_call_stop_record_wav(long call_id, const char *json) {
3707
3783
  } else {
3708
3784
  // Stop record wav on specified media_id
3709
3785
 
3710
- if (media_id >= call->media_count) {
3786
+ if ((int)media_id >= call->media_count) {
3711
3787
  set_error("invalid media_id");
3712
3788
  goto out;
3713
3789
  }
@@ -3735,7 +3811,10 @@ out:
3735
3811
  return 0;
3736
3812
  }
3737
3813
 
3738
- // int pjw_call_start_fax(long call_id, bool is_sender, const char *file)
3814
+ pj_status_t audio_endpoint_stop_fax(Call *call, AudioEndpoint *ae) {
3815
+ return audio_endpoint_remove_port(call, &ae->fax_cbp);
3816
+ }
3817
+
3739
3818
  int pjw_call_start_fax(long call_id, const char *json) {
3740
3819
  PJW_LOCK();
3741
3820
  clear_error();
@@ -3743,7 +3822,6 @@ int pjw_call_start_fax(long call_id, const char *json) {
3743
3822
  long val;
3744
3823
  Call *call;
3745
3824
  pj_status_t status;
3746
- pjmedia_port *stream_port;
3747
3825
 
3748
3826
  bool is_sender;
3749
3827
  char *file;
@@ -3799,7 +3877,7 @@ int pjw_call_start_fax(long call_id, const char *json) {
3799
3877
  }
3800
3878
  }
3801
3879
 
3802
- if (media_id >= call->media_count) {
3880
+ if ((int)media_id >= call->media_count) {
3803
3881
  set_error("invalid media_id");
3804
3882
  goto out;
3805
3883
  }
@@ -3841,6 +3919,13 @@ int pjw_call_start_fax(long call_id, const char *json) {
3841
3919
  flags |= FAX_FLAG_TRANSMIT_ON_IDLE;
3842
3920
  }
3843
3921
 
3922
+ // First stop and destroy existing fax port.
3923
+ status = audio_endpoint_stop_fax(call, ae);
3924
+ if(status != PJ_SUCCESS) {
3925
+ set_error("audio_endpoint_stop_fax failed");
3926
+ return -1;
3927
+ }
3928
+
3844
3929
  if (!prepare_fax(call, ae, is_sender, file, flags)) {
3845
3930
  set_error("prepare_fax failed");
3846
3931
  goto out;
@@ -3855,28 +3940,6 @@ out:
3855
3940
  return 0;
3856
3941
  }
3857
3942
 
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
3943
  int pjw_call_stop_fax(long call_id, const char *json) {
3881
3944
  PJW_LOCK();
3882
3945
  clear_error();
@@ -3884,20 +3947,16 @@ int pjw_call_stop_fax(long call_id, const char *json) {
3884
3947
  long val;
3885
3948
  Call *call;
3886
3949
 
3887
- pjmedia_port *stream_port;
3888
3950
  pj_status_t status;
3889
3951
 
3890
3952
  MediaEndpoint *me;
3891
3953
  AudioEndpoint *ae;
3892
- int ae_count;
3893
3954
  int res;
3894
3955
 
3895
3956
  unsigned media_id = 0;
3896
3957
 
3897
3958
  char buffer[MAX_JSON_INPUT];
3898
3959
 
3899
- const char *valid_params[] = {"media_id", ""};
3900
-
3901
3960
  Document document;
3902
3961
 
3903
3962
  if (!g_call_ids.get(call_id, val)) {
@@ -3924,7 +3983,7 @@ int pjw_call_stop_fax(long call_id, const char *json) {
3924
3983
  } else {
3925
3984
  // Stop fax on specified media_id
3926
3985
 
3927
- if (media_id >= call->media_count) {
3986
+ if ((int)media_id >= call->media_count) {
3928
3987
  set_error("invalid media_id");
3929
3988
  goto out;
3930
3989
  }
@@ -3961,8 +4020,6 @@ int pjw_call_get_stream_stat(long call_id, const char *json, char *out_stats) {
3961
4020
 
3962
4021
  char buffer[MAX_JSON_INPUT];
3963
4022
 
3964
- const char *valid_params[] = {"media_id", ""};
3965
-
3966
4023
  Document document;
3967
4024
 
3968
4025
  pj_status_t status;
@@ -3993,7 +4050,7 @@ int pjw_call_get_stream_stat(long call_id, const char *json, char *out_stats) {
3993
4050
  goto out;
3994
4051
  }
3995
4052
 
3996
- if (media_id >= call->media_count) {
4053
+ if ((int)media_id >= call->media_count) {
3997
4054
  set_error("invalid media_id");
3998
4055
  goto out;
3999
4056
  }
@@ -4050,38 +4107,14 @@ out:
4050
4107
  return 0;
4051
4108
  }
4052
4109
 
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
4110
  bool media_endpoint_present_in_session_media(
4078
4111
  MediaEndpoint *me, const pjmedia_sdp_session *local_sdp) {
4079
4112
  printf("media_endpoint_present_in_session_media:\n");
4080
- for (int i = 0; i < local_sdp->media_count; i++) {
4113
+ for (unsigned i = 0; i < local_sdp->media_count; i++) {
4081
4114
  pjmedia_sdp_media *media = local_sdp->media[i];
4082
4115
  printf("port: %d %d\n", me->port, media->desc.port);
4083
- printf("media: %.*s %.*s\n", me->media.slen, me->media.ptr,
4084
- media->desc.media.slen, media->desc.media.ptr);
4116
+ printf("media: %.*s %.*s\n", (int)me->media.slen, me->media.ptr,
4117
+ (int)media->desc.media.slen, media->desc.media.ptr);
4085
4118
  if (me->port && (me->port == media->desc.port) &&
4086
4119
  (pj_strcmp(&me->media, &media->desc.media) == 0) &&
4087
4120
  (pj_strcmp(&me->transport, &media->desc.transport) == 0) &&
@@ -4097,10 +4130,10 @@ bool media_endpoint_present_in_session_media(
4097
4130
  int find_sdp_media_by_media_endpt(const pjmedia_sdp_session *sdp,
4098
4131
  pjmedia_sdp_media **media_out,
4099
4132
  MediaEndpoint *me) {
4100
- printf("find_sdp_media_by_media_endpt %x\n", me);
4101
- for (int i = 0; i < sdp->media_count; i++) {
4133
+ printf("find_sdp_media_by_media_endpt %p\n", (void*)me);
4134
+ for (unsigned int i = 0; i < sdp->media_count; i++) {
4102
4135
  pjmedia_sdp_media *media = sdp->media[i];
4103
- printf("i=%d me->port=%i media->desc.port=%i me->media=%.*s media->desc.media=%.*s me->transport=%.*s media->desc.transport=%.*s\n", i, me->port, media->desc.port, me->media.slen, me->media.ptr, media->desc.media.slen, media->desc.media.ptr, me->transport.slen, me->transport.ptr, media->desc.transport.slen, media->desc.transport.ptr);
4136
+ printf("i=%d me->port=%i media->desc.port=%i me->media=%.*s media->desc.media=%.*s me->transport=%.*s media->desc.transport=%.*s\n", i, me->port, media->desc.port, (int)me->media.slen, me->media.ptr, (int)media->desc.media.slen, media->desc.media.ptr, (int)me->transport.slen, me->transport.ptr, (int)media->desc.transport.slen, media->desc.transport.ptr);
4104
4137
 
4105
4138
  if ((me->port == media->desc.port) &&
4106
4139
  (pj_strcmp(&me->media, &media->desc.media) == 0) &&
@@ -4116,10 +4149,10 @@ int find_sdp_media_by_media_endpt(const pjmedia_sdp_session *sdp,
4116
4149
 
4117
4150
  bool is_media_in_active_media(MediaEndpoint *me, MediaEndpoint **active_media,
4118
4151
  unsigned count) {
4119
- printf("is_media_in_active_media me=%x\n", me);
4120
- for (int i = 0; i < count; i++) {
4152
+ printf("is_media_in_active_media me=%p\n", (void*)me);
4153
+ for (unsigned i = 0; i < count; i++) {
4121
4154
  MediaEndpoint *current = active_media[i];
4122
- printf("i=%d current=%x\n", i, current);
4155
+ printf("i=%d current=%p\n", i, (void*)current);
4123
4156
  if (current == me) {
4124
4157
  printf("yes\n");
4125
4158
  return true;
@@ -4153,10 +4186,10 @@ void gen_media_json(char *dest, int len, Call *call,
4153
4186
  if(!me->port) {
4154
4187
  switch (me->type) {
4155
4188
  case ENDPOINT_TYPE_AUDIO:
4156
- p += sprintf(p, "{\"type\": \"audio\", \"protocol\": \"%.*s\", \"port\": 0}", me->transport.slen, me->transport.ptr);
4189
+ p += sprintf(p, "{\"type\": \"audio\", \"protocol\": \"%.*s\", \"port\": 0}", (int)me->transport.slen, me->transport.ptr);
4157
4190
  break;
4158
4191
  case ENDPOINT_TYPE_MRCP:
4159
- p += sprintf(p, "{\"type\": \"mrcp\", \"protocol\": \"%.*s\", \"port\": 0}", me->transport.slen, me->transport.ptr);
4192
+ p += sprintf(p, "{\"type\": \"mrcp\", \"protocol\": \"%.*s\", \"port\": 0}", (int)me->transport.slen, me->transport.ptr);
4160
4193
  break;
4161
4194
  default:
4162
4195
  p += sprintf(p, "{\"type\": \"unknown\", \"port\": 0}");
@@ -4166,8 +4199,6 @@ void gen_media_json(char *dest, int len, Call *call,
4166
4199
 
4167
4200
  switch (me->type) {
4168
4201
  case ENDPOINT_TYPE_AUDIO: {
4169
- AudioEndpoint *ae = (AudioEndpoint *)me->endpoint.audio;
4170
-
4171
4202
  const char *local_mode =
4172
4203
  get_media_mode(local_media->attr, local_media->attr_count);
4173
4204
  const char *remote_mode =
@@ -4191,21 +4222,21 @@ void gen_media_json(char *dest, int len, Call *call,
4191
4222
  "{\"type\": \"audio\", \"protocol\": \"%.*s\", \"local\": {\"addr\": \"%.*s\", "
4192
4223
  "\"port\": %d, \"mode\": \"%s\"}, \"remote\": {\"addr\": "
4193
4224
  "\"%.*s\", \"port\": %d, \"mode\": \"%s\"}, \"fmt\": [",
4194
- me->transport.slen, me->transport.ptr,
4195
- local_addr->slen, local_addr->ptr, local_media->desc.port,
4196
- local_mode, remote_addr->slen, remote_addr->ptr,
4225
+ (int)me->transport.slen, me->transport.ptr,
4226
+ (int)local_addr->slen, local_addr->ptr, local_media->desc.port,
4227
+ local_mode, (int)remote_addr->slen, remote_addr->ptr,
4197
4228
  remote_media->desc.port, remote_mode);
4198
4229
 
4199
- for (int i = 0; i < local_media->desc.fmt_count; i++) {
4230
+ for (unsigned i = 0; i < local_media->desc.fmt_count; i++) {
4200
4231
  if (i > 0)
4201
4232
  p += sprintf(p, ",");
4202
4233
  pj_str_t *fmt = &local_media->desc.fmt[i];
4203
4234
  pjmedia_sdp_attr *attr = pjmedia_sdp_attr_find2(
4204
4235
  local_media->attr_count, local_media->attr, "rtpmap", fmt);
4205
4236
  if (attr) {
4206
- p += sprintf(p, "\"%.*s\"", attr->value.slen, attr->value.ptr);
4237
+ p += sprintf(p, "\"%.*s\"", (int)attr->value.slen, attr->value.ptr);
4207
4238
  } else {
4208
- p += sprintf(p, "\"%.*s\"", fmt->slen, fmt->ptr);
4239
+ p += sprintf(p, "\"%.*s\"", (int)fmt->slen, fmt->ptr);
4209
4240
  }
4210
4241
  }
4211
4242
  p += sprintf(p, "]}");
@@ -4215,7 +4246,7 @@ void gen_media_json(char *dest, int len, Call *call,
4215
4246
  p += sprintf(p,
4216
4247
  "{\"type\": \"mrcp\", \"protocol\": \"%.*s\", \"local\": {\"port\": %d}, "
4217
4248
  "\"remote\": {\"port\": %d}}",
4218
- me->transport.slen, me->transport.ptr,
4249
+ (int)me->transport.slen, me->transport.ptr,
4219
4250
  local_sdp->media[idx]->desc.port,
4220
4251
  remote_sdp->media[idx]->desc.port);
4221
4252
  break;
@@ -4253,14 +4284,12 @@ bool start_tcp_media(Call *call, MediaEndpoint *me,
4253
4284
  } else {
4254
4285
  remote_addr = &remote_sdp->conn->addr;
4255
4286
  }
4256
- printf("start_tcp_media remote port: %d, remote addr: %.*s\n", remote_media->desc.port, remote_addr->slen, remote_addr->ptr);
4287
+ printf("start_tcp_media remote port: %d, remote addr: %.*s\n", remote_media->desc.port, (int)remote_addr->slen, remote_addr->ptr);
4257
4288
 
4258
4289
  pj_sock_t *sock = (pj_sock_t *)pj_pool_alloc(pool, sizeof(pj_sock_t));
4259
4290
 
4260
4291
  pj_activesock_t *asock = NULL;
4261
4292
 
4262
- unsigned allocated_port = 0;
4263
-
4264
4293
  AsockUserData *ud = NULL;
4265
4294
 
4266
4295
  status = pj_sock_socket(pj_AF_INET(), pj_SOCK_STREAM(), 0, sock);
@@ -4325,16 +4354,71 @@ bool restart_media_stream(Call *call, MediaEndpoint *me,
4325
4354
 
4326
4355
  pj_status_t status;
4327
4356
 
4328
- if (ae->master_port) {
4329
- status = pjmedia_master_port_stop(ae->master_port);
4357
+ if(ae->stream_cbp.port) {
4358
+ if(ae->tonegen_cbp.port) {
4359
+ status = pjmedia_conf_disconnect_port(call->conf, ae->tonegen_cbp.slot, ae->stream_cbp.slot);
4360
+ if (status != PJ_SUCCESS) {
4361
+ make_evt_media_update(evt, sizeof(evt), call->id,
4362
+ "setup_failed (pjmedia_conf_disconnect_port for tonegen failed)", "");
4363
+ dispatch_event(evt);
4364
+ return false;
4365
+ }
4366
+ }
4367
+
4368
+ if(ae->wav_player_cbp.port) {
4369
+ status = pjmedia_conf_disconnect_port(call->conf, ae->wav_player_cbp.slot, ae->stream_cbp.slot);
4370
+ if (status != PJ_SUCCESS) {
4371
+ make_evt_media_update(evt, sizeof(evt), call->id,
4372
+ "setup_failed (pjmedia_conf_disconnect_port for wav_player failed)", "");
4373
+ dispatch_event(evt);
4374
+ return false;
4375
+ }
4376
+ }
4377
+
4378
+ if(ae->dtmfdet_cbp.port) {
4379
+ status = pjmedia_conf_disconnect_port(call->conf, ae->stream_cbp.slot, ae->dtmfdet_cbp.slot);
4380
+ if (status != PJ_SUCCESS) {
4381
+ make_evt_media_update(evt, sizeof(evt), call->id,
4382
+ "setup_failed (pjmedia_conf_disconnect_port for dtmfdet failed)", "");
4383
+ dispatch_event(evt);
4384
+ return false;
4385
+ }
4386
+ }
4387
+
4388
+ if(ae->fax_cbp.port) {
4389
+ status = pjmedia_conf_disconnect_port(call->conf, ae->stream_cbp.slot, ae->fax_cbp.slot);
4390
+ if (status != PJ_SUCCESS) {
4391
+ make_evt_media_update(evt, sizeof(evt), call->id,
4392
+ "setup_failed (pjmedia_conf_disconnect_port fax dst failed)", "");
4393
+ dispatch_event(evt);
4394
+ return false;
4395
+ }
4396
+
4397
+ status = pjmedia_conf_disconnect_port(call->conf, ae->fax_cbp.slot, ae->stream_cbp.slot);
4398
+ if (status != PJ_SUCCESS) {
4399
+ make_evt_media_update(evt, sizeof(evt), call->id,
4400
+ "setup_failed (pjmedia_conf_disconnect_port for fax src failed)", "");
4401
+ dispatch_event(evt);
4402
+ return false;
4403
+ }
4404
+ }
4405
+
4406
+ status = pjmedia_conf_remove_port(call->conf, ae->stream_cbp.slot);
4330
4407
  if (status != PJ_SUCCESS) {
4331
4408
  make_evt_media_update(evt, sizeof(evt), call->id,
4332
- "setup_failed (pjmedia_master_port_stop failed)",
4333
- "");
4334
- dispatch_event(evt);
4409
+ "setup_failed (pjmedia_conf_remove_port failed)", "");
4335
4410
  return false;
4336
4411
  }
4337
- }
4412
+ ae->stream_cbp.slot = 0;
4413
+
4414
+ status = pjmedia_port_destroy(ae->stream_cbp.port);
4415
+ if (status != PJ_SUCCESS) {
4416
+ make_evt_media_update(evt, sizeof(evt), call->id,
4417
+ "setup_failed (pjmedia_port_destroy failed)", "");
4418
+ return false;
4419
+ }
4420
+ ae->stream_cbp.port = NULL;
4421
+ }
4338
4422
 
4339
4423
  status =
4340
4424
  pjmedia_stream_info_from_sdp(&stream_info, call->inv->dlg->pool,
@@ -4400,8 +4484,7 @@ bool restart_media_stream(Call *call, MediaEndpoint *me,
4400
4484
  return false;
4401
4485
  }
4402
4486
 
4403
- pjmedia_port *stream_port;
4404
- status = pjmedia_stream_get_port(ae->med_stream, &stream_port);
4487
+ status = pjmedia_stream_get_port(ae->med_stream, &ae->stream_cbp.port);
4405
4488
  if (status != PJ_SUCCESS) {
4406
4489
  make_evt_media_update(evt, sizeof(evt), call->id,
4407
4490
  "setup_failed (pjmedia_stream_get_port failed)", "");
@@ -4409,21 +4492,71 @@ bool restart_media_stream(Call *call, MediaEndpoint *me,
4409
4492
  return false;
4410
4493
  }
4411
4494
 
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))) {
4495
+ status = pjmedia_conf_add_port(call->conf, call->inv->pool, ae->stream_cbp.port, NULL, &ae->stream_cbp.slot);
4496
+ if (status != PJ_SUCCESS) {
4416
4497
  make_evt_media_update(evt, sizeof(evt), call->id,
4417
- "setup_failed (init_media_ports failed)", "");
4498
+ "setup_failed (pjmedia_conf_add_port failed)", "");
4418
4499
  dispatch_event(evt);
4419
4500
  return false;
4420
4501
  }
4421
4502
 
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;
4503
+ if(!ae->dtmfdet_cbp.port) {
4504
+ if(!prepare_dtmfdet(call, ae)) {
4505
+ make_evt_media_update(evt, sizeof(evt), call->id,
4506
+ "setup_failed (prepare_dtmfdet failed)", "");
4507
+ dispatch_event(evt);
4508
+ return false;
4509
+ }
4510
+ }
4511
+
4512
+ if(ae->tonegen_cbp.port) {
4513
+ status = pjmedia_conf_connect_port(call->conf, ae->tonegen_cbp.slot, ae->stream_cbp.slot, 0);
4514
+ if (status != PJ_SUCCESS) {
4515
+ make_evt_media_update(evt, sizeof(evt), call->id,
4516
+ "setup_failed (pjmedia_conf_connect_port for tonegen failed)", "");
4517
+ dispatch_event(evt);
4518
+ return false;
4519
+ }
4520
+ }
4521
+
4522
+ if(ae->wav_player_cbp.port) {
4523
+ status = pjmedia_conf_connect_port(call->conf, ae->wav_player_cbp.slot, ae->stream_cbp.slot, 0);
4524
+ if (status != PJ_SUCCESS) {
4525
+ make_evt_media_update(evt, sizeof(evt), call->id,
4526
+ "setup_failed (pjmedia_conf_connect_port for wav_player failed)", "");
4527
+ dispatch_event(evt);
4528
+ return false;
4529
+ }
4530
+ }
4531
+
4532
+ if(ae->dtmfdet_cbp.port) {
4533
+ status = pjmedia_conf_connect_port(call->conf, ae->stream_cbp.slot, ae->dtmfdet_cbp.slot, 0);
4534
+ if (status != PJ_SUCCESS) {
4535
+ make_evt_media_update(evt, sizeof(evt), call->id,
4536
+ "setup_failed (pjmedia_conf_connect_port for dtmfdet failed)", "");
4537
+ dispatch_event(evt);
4538
+ return false;
4539
+
4540
+ }
4541
+ }
4542
+
4543
+ if(ae->fax_cbp.port) {
4544
+ status = pjmedia_conf_connect_port(call->conf, ae->stream_cbp.slot, ae->fax_cbp.slot, 0);
4545
+ if (status != PJ_SUCCESS) {
4546
+ make_evt_media_update(evt, sizeof(evt), call->id,
4547
+ "setup_failed (pjmedia_conf_connect_port for fax dst failed)", "");
4548
+ dispatch_event(evt);
4549
+ return false;
4550
+
4551
+ }
4552
+
4553
+ status = pjmedia_conf_connect_port(call->conf, ae->fax_cbp.slot, ae->stream_cbp.slot, 0);
4554
+ if (status != PJ_SUCCESS) {
4555
+ make_evt_media_update(evt, sizeof(evt), call->id,
4556
+ "setup_failed (pjmedia_conf_connect_port for fax src failed)", "");
4557
+ dispatch_event(evt);
4558
+ return false;
4559
+ }
4427
4560
  }
4428
4561
 
4429
4562
  return true;
@@ -4459,7 +4592,7 @@ MediaEndpoint *find_media_endpt_by_sdp_media(Call *call,
4459
4592
  }
4460
4593
  }
4461
4594
  } else {
4462
- printf("local_media->desc.media=%.*s\n", local_media->desc.media.slen,
4595
+ printf("local_media->desc.media=%.*s\n", (int)local_media->desc.media.slen,
4463
4596
  local_media->desc.media.ptr);
4464
4597
  assert(0);
4465
4598
  // missing media type support implementation
@@ -4484,9 +4617,8 @@ static void on_media_update(pjsip_inv_session *inv, pj_status_t status) {
4484
4617
  "be notified.\n");
4485
4618
  return;
4486
4619
  }
4487
- printf("call_id=%d\n", call_id);
4620
+ printf("call_id=%li\n", call_id);
4488
4621
 
4489
- pjmedia_stream_info stream_info;
4490
4622
  const pjmedia_sdp_session *local_sdp;
4491
4623
  const pjmedia_sdp_session *remote_sdp;
4492
4624
 
@@ -4499,13 +4631,6 @@ static void on_media_update(pjsip_inv_session *inv, pj_status_t status) {
4499
4631
  return;
4500
4632
  }
4501
4633
 
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
4634
  status = pjmedia_sdp_neg_get_active_local(inv->neg, &local_sdp);
4510
4635
  if (status != PJ_SUCCESS) {
4511
4636
  make_evt_media_update(
@@ -4534,14 +4659,11 @@ static void on_media_update(pjsip_inv_session *inv, pj_status_t status) {
4534
4659
  call->id, b);
4535
4660
 
4536
4661
  // update media endpoint based on sdp media
4537
- bool in_use_chart[PJMEDIA_MAX_SDP_MEDIA] = {false};
4538
- MediaEndpoint *active_media[PJMEDIA_MAX_SDP_MEDIA] = {NULL};
4539
- int active_media_count = 0;
4540
4662
 
4541
- for (int i = 0; i < local_sdp->media_count; i++) {
4663
+ for (unsigned i = 0; i < local_sdp->media_count; i++) {
4542
4664
  MediaEndpoint *me = call->media[i];
4543
4665
  if (!local_sdp->media[i]->desc.port) {
4544
- close_media_endpoint(me);
4666
+ close_media_endpoint(call, me);
4545
4667
  } else {
4546
4668
  if (me->type == ENDPOINT_TYPE_AUDIO) {
4547
4669
  if (!restart_media_stream(call, me, local_sdp, remote_sdp, i)) {
@@ -4557,33 +4679,6 @@ static void on_media_update(pjsip_inv_session *inv, pj_status_t status) {
4557
4679
  }
4558
4680
  }
4559
4681
 
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
4682
  char media[4096];
4588
4683
  gen_media_json(media, sizeof(media), call, local_sdp, remote_sdp);
4589
4684
 
@@ -4591,62 +4686,6 @@ static void on_media_update(pjsip_inv_session *inv, pj_status_t status) {
4591
4686
  dispatch_event(evt);
4592
4687
  }
4593
4688
 
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
4689
  static void on_state_changed(pjsip_inv_session *inv, pjsip_event *e) {
4651
4690
  addon_log(L_DBG, "on_state_changed\n");
4652
4691
 
@@ -4677,7 +4716,7 @@ static void on_state_changed(pjsip_inv_session *inv, pjsip_event *e) {
4677
4716
  printf("inv->state=%d\n", inv->state);
4678
4717
 
4679
4718
  if (PJSIP_INV_STATE_DISCONNECTED == inv->state) {
4680
- addon_log(L_DBG, "call will terminate call=%x\n", call);
4719
+ addon_log(L_DBG, "call will terminate call=%p\n", (void*)call);
4681
4720
  pj_status_t status;
4682
4721
 
4683
4722
  long call_id;
@@ -4687,33 +4726,14 @@ static void on_state_changed(pjsip_inv_session *inv, pjsip_event *e) {
4687
4726
  return;
4688
4727
  }
4689
4728
 
4729
+ close_media(call);
4730
+
4690
4731
  for (int i = 0; i < call->media_count; i++) {
4691
4732
  addon_log(L_DBG, "processing media[%d]\n", i);
4692
4733
  MediaEndpoint *me = call->media[i];
4693
4734
  if (ENDPOINT_TYPE_AUDIO == me->type) {
4694
4735
  AudioEndpoint *ae = (AudioEndpoint *)me->endpoint.audio;
4695
4736
  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
4737
 
4718
4738
  if (ae->med_stream) {
4719
4739
  addon_log(L_DBG, "calling pjmedia_stream_destroy");
@@ -4723,19 +4743,20 @@ static void on_state_changed(pjsip_inv_session *inv, pjsip_event *e) {
4723
4743
  }
4724
4744
  }
4725
4745
  }
4746
+ }
4726
4747
 
4727
- long val;
4728
- if (!g_call_ids.remove(call_id, val)) {
4729
- addon_log(L_DBG, "g_call_ids.remove failed\n");
4730
- }
4748
+ release_call_conf(call);
4731
4749
 
4732
- Pair_Call_CallId pcc;
4733
- pcc.pCall = call;
4734
- pcc.id = call_id;
4735
- g_LastCalls.push_back(pcc);
4750
+ long val;
4751
+ if (!g_call_ids.remove(call_id, val)) {
4752
+ addon_log(L_DBG, "g_call_ids.remove failed\n");
4736
4753
  }
4737
4754
 
4738
- close_media(call);
4755
+ Pair_Call_CallId pcc;
4756
+ pcc.pCall = call;
4757
+ pcc.id = call_id;
4758
+ g_LastCalls.push_back(pcc);
4759
+
4739
4760
 
4740
4761
  char evt[2048];
4741
4762
  int sip_msg_len = 0;
@@ -4769,7 +4790,7 @@ static pjmedia_transport *create_media_transport(const pj_str_t *addr,
4769
4790
  pjmedia_transport_info tpinfo;
4770
4791
  pjmedia_transport_info_init(&tpinfo);
4771
4792
  status = pjmedia_transport_get_info(med_transport, &tpinfo);
4772
- //printf("create_media_transport port=%i created %x\n", port, med_transport);
4793
+ //printf("create_media_transport port=%i created %p\n", port, (void*)med_transport);
4773
4794
  *allocated_port = port;
4774
4795
  return med_transport;
4775
4796
  } else {
@@ -5115,6 +5136,13 @@ static pj_bool_t on_rx_request(pjsip_rx_data *rdata) {
5115
5136
  return PJ_TRUE;
5116
5137
  }
5117
5138
 
5139
+ status = setup_call_conf(call);
5140
+ if (status != PJ_SUCCESS) {
5141
+ printf("setup_call_conf failed\n");
5142
+ pjsip_endpt_respond_stateless(g_sip_endpt, rdata, 500, &reason, NULL, NULL);
5143
+ return PJ_TRUE;
5144
+ }
5145
+
5118
5146
  // TODO: check if this is really necessary as we are calling
5119
5147
  // pjsip_dlg_add_usage subsequently
5120
5148
  inv->dlg->mod_data[mod_tester.id] = call;
@@ -5156,7 +5184,7 @@ static pj_bool_t on_rx_request(pjsip_rx_data *rdata) {
5156
5184
  Transport *transport = (Transport *)val;
5157
5185
  call->transport = transport;
5158
5186
  } else {
5159
- printf("could not resolve transport id=%d\n", transport_id);
5187
+ printf("could not resolve transport id=%li\n", transport_id);
5160
5188
  exit(1);
5161
5189
  }
5162
5190
 
@@ -5207,7 +5235,7 @@ static pj_bool_t on_rx_response(pjsip_rx_data *rdata) {
5207
5235
  long call_id;
5208
5236
 
5209
5237
  if (call) {
5210
- // addon_log(L_DBG, "call:%x\n",call);
5238
+ // addon_log(L_DBG, "call:%p\n", (void*)call);
5211
5239
  if (!g_call_ids.get_id((long)call, call_id)) {
5212
5240
  // addon_log(L_DBG, "The call is not present in g_call_ids.\n");
5213
5241
  // It means the call terminated and was removed from g_call_ids\n");
@@ -5252,16 +5280,12 @@ static void on_rx_offer2(pjsip_inv_session *inv,
5252
5280
  if (g_shutting_down)
5253
5281
  return;
5254
5282
 
5255
- char evt[2048];
5256
-
5257
5283
  Call *call = (Call *)inv->dlg->mod_data[mod_tester.id];
5258
5284
 
5259
5285
  printf("on_rx_offer2 call_id=%d\n", call->id);
5260
5286
 
5261
5287
  pj_status_t status;
5262
5288
 
5263
- const pjsip_rx_data *rdata = param->rdata;
5264
-
5265
5289
  pjmedia_sdp_neg_state state = pjmedia_sdp_neg_get_state(inv->neg);
5266
5290
  printf("neg state: %d\n", state);
5267
5291
  if (PJMEDIA_SDP_NEG_STATE_NULL == state ||
@@ -5783,7 +5807,7 @@ static void build_stream_stat(ostringstream &oss, pjmedia_rtcp_stat *stat,
5783
5807
  }
5784
5808
 
5785
5809
  void close_media_transport(pjmedia_transport *med_transport) {
5786
- printf("close_media_transport %x\n", med_transport);
5810
+ printf("close_media_transport %p\n", (void*)med_transport);
5787
5811
  pjmedia_transport_info tpinfo;
5788
5812
  pjmedia_transport_info_init(&tpinfo);
5789
5813
  pj_status_t status = pjmedia_transport_get_info(med_transport, &tpinfo);
@@ -5818,7 +5842,7 @@ bool has_attribute_mode(MediaEndpoint *me) {
5818
5842
  }
5819
5843
 
5820
5844
  void remove_mode_attributes(pjmedia_sdp_media *m) {
5821
- for (int i = 0; i < m->attr_count; i++) {
5845
+ for (unsigned i = 0; i < m->attr_count; i++) {
5822
5846
  pjmedia_sdp_attr *attr = m->attr[i];
5823
5847
  if ((pj_strcmp2(&attr->name, "sendrecv") == 0) ||
5824
5848
  (pj_strcmp2(&attr->name, "sendonly") == 0) ||
@@ -5922,7 +5946,7 @@ bool create_media_endpoint(Call *call, Document &document, Value &descr,
5922
5946
  }
5923
5947
  audio_endpt->med_transport = srtp;
5924
5948
 
5925
- status = pjmedia_transport_media_create(audio_endpt->med_transport, dlg->pool, NULL, NULL, 0);
5949
+ status = pjmedia_transport_media_create(audio_endpt->med_transport, dlg->pool, 0, NULL, 0);
5926
5950
  if(status != PJ_SUCCESS) {
5927
5951
  set_error("pjmedia_transport_media_create failed");
5928
5952
  return false;
@@ -6227,9 +6251,9 @@ bool process_media(Call *call, pjsip_dialog *dlg, Document &document, bool answe
6227
6251
  // me was active but it must be deactivated
6228
6252
  MediaEndpoint *new_me;
6229
6253
 
6230
- if(!create_media_endpoint(call, document, descr, dlg, "0.0.0.0", &new_me))
6254
+ if(!create_media_endpoint(call, document, descr, dlg, (char*)"0.0.0.0", &new_me))
6231
6255
  return false;
6232
- addon_log(L_DBG, "i=%d media port=0 created %x\n", i, me);
6256
+ addon_log(L_DBG, "i=%d media port=0 created %p\n", i, (void*)me);
6233
6257
 
6234
6258
  pjmedia_sdp_media *media = create_sdp_media(new_me, dlg);
6235
6259
  if (!media)
@@ -6240,7 +6264,7 @@ bool process_media(Call *call, pjsip_dialog *dlg, Document &document, bool answe
6240
6264
  // me was not active but it is activated now
6241
6265
  if (!create_media_endpoint(call, document, descr, dlg, t->address, &me))
6242
6266
  return false;
6243
- addon_log(L_DBG, "i=%d media created %x\n", i, me);
6267
+ addon_log(L_DBG, "i=%d media created %p\n", i, (void*)me);
6244
6268
  call->media[idx] = me;
6245
6269
 
6246
6270
  if (!update_media_fields(me, dlg->pool, descr)) {
@@ -6267,7 +6291,7 @@ bool process_media(Call *call, pjsip_dialog *dlg, Document &document, bool answe
6267
6291
  addon_log(L_DBG, "i=%d media not found\n", i);
6268
6292
  if (!create_media_endpoint(call, document, descr, dlg, t->address, &me))
6269
6293
  return false;
6270
- addon_log(L_DBG, "i=%d media created %x\n", i, me);
6294
+ addon_log(L_DBG, "i=%d media created %p\n", i, (void*)me);
6271
6295
  call->media[call->media_count++] = me;
6272
6296
  in_use_chart[call->media_count - 1] =
6273
6297
  true; // added elements must be set as in use
@@ -6315,12 +6339,20 @@ bool is_media_active(Call *c, MediaEndpoint *me) {
6315
6339
  return false;
6316
6340
  }
6317
6341
 
6318
- void close_media_endpoint(MediaEndpoint *me) {
6319
- printf("close_media_endpoint %x\n", me);
6342
+ void close_media_endpoint(Call *call, MediaEndpoint *me) {
6343
+ printf("close_media_endpoint %p\n", (void*)me);
6320
6344
  if(!me) return;
6321
6345
 
6322
6346
  if (ENDPOINT_TYPE_AUDIO == me->type) {
6323
6347
  AudioEndpoint *ae = (AudioEndpoint *)me->endpoint.audio;
6348
+
6349
+ audio_endpoint_remove_port(call, &ae->stream_cbp);
6350
+ audio_endpoint_remove_port(call, &ae->wav_player_cbp);
6351
+ audio_endpoint_remove_port(call, &ae->wav_writer_cbp);
6352
+ audio_endpoint_remove_port(call, &ae->tonegen_cbp);
6353
+ audio_endpoint_remove_port(call, &ae->dtmfdet_cbp);
6354
+ audio_endpoint_remove_port(call, &ae->fax_cbp);
6355
+
6324
6356
  close_media_transport(ae->med_transport);
6325
6357
  ae->med_transport = NULL;
6326
6358
  } else if (ENDPOINT_TYPE_MRCP == me->type) {
@@ -6345,157 +6377,141 @@ void close_media_endpoint(MediaEndpoint *me) {
6345
6377
  }
6346
6378
 
6347
6379
  void close_media(Call *c) {
6348
- printf("close_media call_id=%x\n", c->id);
6380
+ printf("close_media call_id=%li\n", c->id);
6349
6381
  for (int i = 0; i < c->media_count; ++i) {
6350
6382
  MediaEndpoint *me = c->media[i];
6351
- close_media_endpoint(me);
6383
+ close_media_endpoint(c, me);
6352
6384
  }
6353
6385
  c->media_count = 0;
6354
6386
  }
6355
6387
 
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) {
6388
+ bool prepare_tonegen(Call *c, AudioEndpoint *ae) {
6389
+ printf("prepare_tone_gen call.id=%i\n", c->id);
6359
6390
  pj_status_t status;
6360
6391
 
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;
6392
+ if(ae->tonegen_cbp.port) {
6393
+ printf("already prepared\n");
6394
+ return true;
6367
6395
  }
6368
6396
 
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
- }
6381
- }
6382
-
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
- }
6397
+ printf("call.id=%i p1\n", c->id);
6398
+ status = pjmedia_tonegen_create(
6399
+ c->inv->pool, PJMEDIA_PIA_SRATE(&ae->stream_cbp.port->info),
6400
+ PJMEDIA_PIA_CCNT(&ae->stream_cbp.port->info),
6401
+ PJMEDIA_PIA_SPF(&ae->stream_cbp.port->info),
6402
+ PJMEDIA_PIA_BITS(&ae->stream_cbp.port->info), 0, &ae->tonegen_cbp.port);
6403
+ if (status != PJ_SUCCESS) {
6404
+ set_error("pjmedia_tonegen_create failed");
6405
+ return false;
6388
6406
  }
6389
6407
 
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;
6408
+ printf("call.id=%i p2\n", c->id);
6409
+ status = pjmedia_conf_add_port(c->conf, c->inv->pool, ae->tonegen_cbp.port, NULL, &ae->tonegen_cbp.slot);
6410
+ if (status != PJ_SUCCESS) {
6411
+ set_error("pjmedia_conf_add_port failed");
6412
+ return false;
6396
6413
  }
6397
6414
 
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
- }
6415
+ printf("call.id=%i p3\n", c->id);
6416
+ status = pjmedia_conf_connect_port(c->conf, ae->tonegen_cbp.slot, ae->stream_cbp.slot, 0);
6417
+ if (status != PJ_SUCCESS) {
6418
+ set_error("pjmedia_conf_connect_port failed");
6419
+ return false;
6403
6420
  }
6404
6421
 
6405
- connect_media_ports(ae);
6422
+ printf("call.id=%i p4 (success)\n", c->id);
6406
6423
  return true;
6407
6424
  }
6408
6425
 
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");
6426
+ bool prepare_wav_player(Call *c, AudioEndpoint *ae, const char *file) {
6419
6427
  pj_status_t status;
6420
6428
 
6421
- chainlink *link = (chainlink *)ae->tonegen;
6429
+ unsigned wav_ptime;
6430
+ wav_ptime = PJMEDIA_PIA_SPF(&ae->stream_cbp.port->info) * 1000 /
6431
+ PJMEDIA_PIA_SRATE(&ae->stream_cbp.port->info);
6432
+
6433
+ status = pjmedia_wav_player_port_create(
6434
+ c->inv->pool,
6435
+ file,
6436
+ wav_ptime,
6437
+ 0, /* flags */
6438
+ -1, /* buf size */
6439
+ &ae->wav_player_cbp.port
6440
+ );
6441
+
6442
+ if (status != PJ_SUCCESS) {
6443
+ set_error("pjmedia_wav_player_port_create failed");
6444
+ return false;
6445
+ }
6422
6446
 
6423
- pjmedia_port *stream_port;
6424
- status = pjmedia_stream_get_port(ae->med_stream, &stream_port);
6447
+ status = pjmedia_conf_add_port(c->conf, c->inv->pool, ae->wav_player_cbp.port, NULL, &ae->wav_player_cbp.slot);
6425
6448
  if (status != PJ_SUCCESS) {
6449
+ set_error("pjmedia_conf_add_port failed");
6426
6450
  return false;
6427
6451
  }
6428
6452
 
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;
6453
+ status = pjmedia_conf_connect_port(c->conf, ae->wav_player_cbp.slot, ae->stream_cbp.slot, 0);
6454
+ if (status != PJ_SUCCESS) {
6455
+ set_error("pjmedia_conf_connect_port failed");
6456
+ return false;
6437
6457
  }
6438
6458
 
6439
- connect_media_ports(ae);
6440
6459
  return true;
6441
6460
  }
6442
6461
 
6443
- bool prepare_wav_player(Call *c, AudioEndpoint *ae, const char *file) {
6462
+ bool prepare_wav_writer(Call *c, AudioEndpoint *ae, const char *file) {
6444
6463
  pj_status_t status;
6445
6464
 
6446
- chainlink *link = (chainlink *)ae->wav_player;
6447
-
6448
- pjmedia_port *stream_port;
6449
- status = pjmedia_stream_get_port(ae->med_stream, &stream_port);
6465
+ status = pjmedia_wav_writer_port_create(
6466
+ c->inv->pool, file, PJMEDIA_PIA_SRATE(&ae->stream_cbp.port->info),
6467
+ PJMEDIA_PIA_CCNT(&ae->stream_cbp.port->info), PJMEDIA_PIA_SPF(&ae->stream_cbp.port->info),
6468
+ PJMEDIA_PIA_BITS(&ae->stream_cbp.port->info), PJMEDIA_FILE_WRITE_PCM, 0,
6469
+ (pjmedia_port **)&ae->wav_writer_cbp.port);
6450
6470
  if (status != PJ_SUCCESS) {
6451
- set_error("pj_media_stream_get_port failed");
6471
+ set_error("pjmedia_wav_write_port_create failed");
6452
6472
  return false;
6453
6473
  }
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);
6474
+
6475
+ status = pjmedia_conf_add_port(c->conf, c->inv->pool, ae->wav_writer_cbp.port, NULL, &ae->wav_writer_cbp.slot);
6460
6476
  if (status != PJ_SUCCESS) {
6461
- set_error("pjmedia_port_destroy failed");
6477
+ set_error("pjmedia_conf_add_port failed");
6462
6478
  return false;
6463
6479
  }
6464
6480
 
6465
- status = chainlink_wav_player_port_create(
6466
- c->inv->pool, file, wav_ptime, 0, -1, (pjmedia_port **)&ae->wav_player);
6481
+ status = pjmedia_conf_connect_port(c->conf, ae->stream_cbp.slot, ae->wav_writer_cbp.slot, 0);
6467
6482
  if (status != PJ_SUCCESS) {
6468
- set_error("chainllink_wav_player_port_create failed");
6483
+ set_error("pjmedia_conf_connect_port failed");
6469
6484
  return false;
6470
6485
  }
6471
6486
 
6472
- connect_media_ports(ae);
6473
6487
  return true;
6474
6488
  }
6475
6489
 
6476
- bool prepare_wav_writer(Call *c, AudioEndpoint *ae, const char *file) {
6490
+ bool prepare_dtmfdet(Call *c, AudioEndpoint *ae) {
6477
6491
  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)
6492
+ status = pjmedia_dtmfdet_create(
6493
+ c->inv->pool,
6494
+ PJMEDIA_PIA_SRATE(&ae->stream_cbp.port->info),
6495
+ PJMEDIA_PIA_CCNT(&ae->stream_cbp.port->info), PJMEDIA_PIA_SPF(&ae->stream_cbp.port->info),
6496
+ PJMEDIA_PIA_BITS(&ae->stream_cbp.port->info),
6497
+ on_inband_dtmf, c, &ae->dtmfdet_cbp.port);
6498
+ if (status != PJ_SUCCESS) {
6499
+ set_error("pjmedia_dtmfdet_create failed");
6500
+ return false;
6501
+ }
6502
+
6503
+ status = pjmedia_conf_add_port(c->conf, c->inv->pool, ae->dtmfdet_cbp.port, NULL, &ae->dtmfdet_cbp.slot);
6504
+ if (status != PJ_SUCCESS) {
6505
+ set_error("pjmedia_conf_add_port failed");
6488
6506
  return false;
6507
+ }
6489
6508
 
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)
6509
+ status = pjmedia_conf_connect_port(c->conf, ae->stream_cbp.slot, ae->dtmfdet_cbp.slot, 0);
6510
+ if (status != PJ_SUCCESS) {
6511
+ set_error("pjmedia_conf_connect_port failed");
6496
6512
  return false;
6513
+ }
6497
6514
 
6498
- connect_media_ports(ae);
6499
6515
  return true;
6500
6516
  }
6501
6517
 
@@ -6503,48 +6519,36 @@ bool prepare_fax(Call *c, AudioEndpoint *ae, bool is_sender, const char *file,
6503
6519
  unsigned flags) {
6504
6520
  pj_status_t status;
6505
6521
 
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)
6522
+ status = pjmedia_fax_port_create(
6523
+ c->inv->pool,
6524
+ PJMEDIA_PIA_SRATE(&ae->stream_cbp.port->info),
6525
+ PJMEDIA_PIA_CCNT(&ae->stream_cbp.port->info),
6526
+ PJMEDIA_PIA_SPF(&ae->stream_cbp.port->info),
6527
+ PJMEDIA_PIA_BITS(&ae->stream_cbp.port->info),
6528
+ on_fax_result, c, is_sender, file,
6529
+ flags, &ae->fax_cbp.port);
6530
+ if (status != PJ_SUCCESS) {
6531
+ set_error("pjmedia_fax_port_create failed");
6511
6532
  return false;
6533
+ }
6512
6534
 
6513
- status = pjmedia_port_destroy((pjmedia_port *)link);
6514
- if (status != PJ_SUCCESS)
6535
+ status = pjmedia_conf_add_port(c->conf, c->inv->pool, ae->fax_cbp.port, NULL, &ae->fax_cbp.slot);
6536
+ if (status != PJ_SUCCESS) {
6537
+ set_error("pjmedia_conf_add_port failed");
6515
6538
  return false;
6539
+ }
6516
6540
 
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)
6541
+ status = pjmedia_conf_connect_port(c->conf, ae->fax_cbp.slot, ae->stream_cbp.slot, 0);
6542
+ if (status != PJ_SUCCESS) {
6543
+ set_error("pjmedia_conf_connect_port failed");
6523
6544
  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
6545
  }
6542
6546
 
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)
6547
+ status = pjmedia_conf_connect_port(c->conf, ae->stream_cbp.slot, ae->fax_cbp.slot, 0);
6548
+ if (status != PJ_SUCCESS) {
6549
+ set_error("pjmedia_conf_connect_port failed");
6547
6550
  return false;
6551
+ }
6548
6552
 
6549
6553
  return true;
6550
6554
  }
@@ -6941,7 +6945,7 @@ void process_in_dialog_refer(pjsip_dialog *dlg, pjsip_rx_data *rdata) {
6941
6945
  }
6942
6946
  }
6943
6947
 
6944
- static void on_tsx_state_changed(pjsip_inv_session *inv, pjsip_transaction *tsx,
6948
+ /* static void on_tsx_state_changed(pjsip_inv_session *inv, pjsip_transaction *tsx,
6945
6949
  pjsip_event *e) {
6946
6950
  addon_log(L_DBG, "on_tsx_state change method=%.*s.\n", tsx->method.name.slen,
6947
6951
  tsx->method.name.ptr);
@@ -6962,11 +6966,11 @@ static void on_tsx_state_changed(pjsip_inv_session *inv, pjsip_transaction *tsx,
6962
6966
  printf("call_id=%d\n", call->id);
6963
6967
 
6964
6968
  if (call->inv == NULL) {
6965
- /* Shouldn't happen. It happens only when we don't terminate the
6966
- * server subscription caused by REFER after the call has been
6967
- * transfered (and this call has been disconnected), and we
6968
- * receive another REFER for this call.
6969
- */
6969
+ // Shouldn't happen. It happens only when we don't terminate the
6970
+ // server subscription caused by REFER after the call has been
6971
+ // transfered (and this call has been disconnected), and we
6972
+ // receive another REFER for this call.
6973
+ //
6970
6974
  return;
6971
6975
  }
6972
6976
 
@@ -6974,9 +6978,9 @@ static void on_tsx_state_changed(pjsip_inv_session *inv, pjsip_transaction *tsx,
6974
6978
  // Transport *t;
6975
6979
  if (tsx->role == PJSIP_ROLE_UAS && tsx->state == PJSIP_TSX_STATE_TRYING) {
6976
6980
  if (pjsip_method_cmp(&tsx->method, pjsip_get_refer_method()) == 0) {
6977
- /*
6978
- * Incoming REFER request.
6979
- */
6981
+ //
6982
+ // Incoming REFER request.
6983
+ //
6980
6984
 
6981
6985
  process_in_dialog_refer(call->inv->dlg, e->body.tsx_state.src.rdata);
6982
6986
  } else {
@@ -7005,7 +7009,7 @@ static void on_tsx_state_changed(pjsip_inv_session *inv, pjsip_transaction *tsx,
7005
7009
  } else {
7006
7010
  addon_log(L_DBG, "doing nothiing");
7007
7011
  }
7008
- }
7012
+ } */
7009
7013
 
7010
7014
  int pjw_call_get_info(long call_id, const char *required_info, char *out_info) {
7011
7015
  PJW_LOCK();
@@ -7626,7 +7630,7 @@ int pjw_subscription_create(long transport_id, const char *json,
7626
7630
 
7627
7631
  pjsip_evsub_set_mod_data(evsub, mod_tester.id, subscription);
7628
7632
 
7629
- printf("subscription=%x\n", subscription);
7633
+ printf("subscription=%p\n", (void*)subscription);
7630
7634
 
7631
7635
  *out_subscription_id = subscription_id;
7632
7636
  out:
@@ -7742,8 +7746,6 @@ out:
7742
7746
  }
7743
7747
 
7744
7748
  void process_in_dialog_subscribe(pjsip_dialog *dlg, pjsip_rx_data *rdata) {
7745
- char evt[2048];
7746
-
7747
7749
  return;
7748
7750
  }
7749
7751
 
@@ -7811,7 +7813,7 @@ pj_status_t tcp_endpoint_send_msg(Call *call, MediaEndpoint *me, char *msg, pj_s
7811
7813
  send_key = (pj_ioqueue_op_key_t*)pj_pool_alloc(call->inv->pool, sizeof(pj_ioqueue_op_key_t));
7812
7814
  char *data = (char*)pj_pool_alloc(call->inv->pool, size);
7813
7815
  memcpy(data, msg, size);
7814
- printf("tcp_endpoint_send_msg send_key %x\n", send_key);
7816
+ printf("tcp_endpoint_send_msg send_key %p\n", (void*)send_key);
7815
7817
  //status = pj_activesock_send(asock, send_key, data, &size, 0);
7816
7818
  status = pj_activesock_send(asock, send_key, data, &size, PJ_IOQUEUE_ALWAYS_ASYNC);
7817
7819
  if (status != PJ_SUCCESS) {
@@ -7832,7 +7834,6 @@ pj_status_t call_send_tcp_msg(Call *call, char *msg, pj_ssize_t size) {
7832
7834
  pj_status_t status;
7833
7835
  for (int i = 0; i < call->media_count; i++) {
7834
7836
  MediaEndpoint *me = (MediaEndpoint *)call->media[i];
7835
- pj_activesock_t *asock = NULL;
7836
7837
  if (ENDPOINT_TYPE_MRCP == me->type) {
7837
7838
  status = tcp_endpoint_send_msg(call, me, msg, size);
7838
7839
  if(status != PJ_SUCCESS) {
@@ -7855,15 +7856,12 @@ int pjw_call_send_tcp_msg(long call_id, const char *json) {
7855
7856
  long val;
7856
7857
 
7857
7858
  MediaEndpoint *me;
7858
- MrcpEndpoint *mrcp_endpt;
7859
7859
  int res;
7860
7860
 
7861
7861
  unsigned media_id = 0;
7862
7862
 
7863
7863
  char buffer[MAX_JSON_INPUT];
7864
7864
 
7865
- const char *valid_params[] = {"msg", "media_id", ""};
7866
-
7867
7865
  char *msg;
7868
7866
  pj_ssize_t size;
7869
7867
 
@@ -7898,7 +7896,7 @@ int pjw_call_send_tcp_msg(long call_id, const char *json) {
7898
7896
  } else {
7899
7897
  // Send msg to specified media_id
7900
7898
 
7901
- if (media_id >= call->media_count) {
7899
+ if ((int)media_id >= call->media_count) {
7902
7900
  set_error("invalid media_id");
7903
7901
  goto out;
7904
7902
  }