sip-lab 1.13.0 → 1.14.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
@@ -433,7 +433,7 @@ struct AsockUserData {
433
433
  MediaEndpoint *media_endpt;
434
434
  Call *call;
435
435
  char buf[MAX_TCP_DATA];
436
- char len;
436
+ pj_size_t len;
437
437
  };
438
438
 
439
439
  bool init_media_ports(Call *c, AudioEndpoint *ae, unsigned sampling_rate,
@@ -841,18 +841,20 @@ static pj_bool_t on_data_read(pj_activesock_t *asock, void *data,
841
841
  AsockUserData *ud = (AsockUserData*)pj_activesock_get_user_data(asock);
842
842
  if(!ud) return PJ_FALSE;
843
843
 
844
- printf("%.*s\n", size, data);
845
844
  if (size == 0) {
846
845
  // TODO: destroy the activesock.
847
846
  return PJ_FALSE;
848
847
  }
849
848
 
850
- assert(size + ud->len < MAX_TCP_DATA);
849
+ assert(ud->len >= 0);
850
+
851
+ assert(size >= 0);
852
+ assert(size + ud->len + 1 < MAX_TCP_DATA);
851
853
 
852
854
  memcpy(&ud->buf[ud->len], data, size);
853
- ud->len = size + ud->len;
855
+ ud->len = ud->len + size;
854
856
  ud->buf[ud->len] = '\0';
855
-
857
+
856
858
  char *sep = strstr(ud->buf, "\r\n\r\n");
857
859
  if(!sep) {
858
860
  // msg incomplete
@@ -877,8 +879,10 @@ static pj_bool_t on_data_read(pj_activesock_t *asock, void *data,
877
879
  num_str[len] = '\0';
878
880
  int body_len = atoi(num_str);
879
881
 
880
- if(sep+4+body_len < ud->buf+ud->len) {
881
- // msg incomplete
882
+ assert(body_len > 0 && body_len < 4096);
883
+
884
+ if(ud->buf+ud->len < sep+4+body_len) {
885
+ printf("tcp data: msg incomplete %i %i\n", ud->buf+ud->len, sep+4+body_len);
882
886
  *remainder = 0;
883
887
  return PJ_TRUE;
884
888
  }
@@ -1293,6 +1297,14 @@ int __pjw_init() {
1293
1297
  }
1294
1298
  #endif
1295
1299
 
1300
+ #if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
1301
+ status = pjmedia_srtp_init_lib(g_med_endpt);
1302
+ if (status != PJ_SUCCESS) {
1303
+ addon_log(L_DBG, "Error initializing SRTP library\n");
1304
+ return 1;
1305
+ }
1306
+ #endif
1307
+
1296
1308
  status = pjmedia_codec_bcg729_init(g_med_endpt);
1297
1309
  if (status != PJ_SUCCESS) {
1298
1310
  printf("pjmedia_codec_bcg729_init failed\n");
@@ -2948,6 +2960,9 @@ pj_status_t send_dtmf(Call *call, const char *digits, int mode) {
2948
2960
  if (me->type != ENDPOINT_TYPE_AUDIO)
2949
2961
  continue;
2950
2962
 
2963
+ if(me->port == 0)
2964
+ continue;
2965
+
2951
2966
  AudioEndpoint *ae = (AudioEndpoint *)me->endpoint.audio;
2952
2967
 
2953
2968
  pj_status_t status = audio_endpoint_send_dtmf(call, ae, digits, mode);
@@ -3294,7 +3309,7 @@ int pjw_call_start_record_wav(long call_id, const char *json) {
3294
3309
  pj_status_t status;
3295
3310
  pjmedia_port *stream_port;
3296
3311
 
3297
- unsigned media_id;
3312
+ unsigned media_id = 0;
3298
3313
 
3299
3314
  MediaEndpoint *me;
3300
3315
  AudioEndpoint *ae;
@@ -3399,7 +3414,7 @@ int pjw_call_start_play_wav(long call_id, const char *json) {
3399
3414
  AudioEndpoint *ae;
3400
3415
  int ae_count;
3401
3416
 
3402
- unsigned media_id;
3417
+ unsigned media_id = 0;
3403
3418
 
3404
3419
  char *file;
3405
3420
 
@@ -3527,7 +3542,7 @@ int pjw_call_stop_play_wav(long call_id, const char *json) {
3527
3542
  int ae_count;
3528
3543
  int res;
3529
3544
 
3530
- unsigned media_id;
3545
+ unsigned media_id = 0;
3531
3546
 
3532
3547
  char buffer[MAX_JSON_INPUT];
3533
3548
 
@@ -3624,7 +3639,7 @@ int pjw_call_stop_record_wav(long call_id, const char *json) {
3624
3639
  int ae_count;
3625
3640
  int res;
3626
3641
 
3627
- unsigned media_id;
3642
+ unsigned media_id = 0;
3628
3643
 
3629
3644
  char buffer[MAX_JSON_INPUT];
3630
3645
 
@@ -3703,7 +3718,7 @@ int pjw_call_start_fax(long call_id, const char *json) {
3703
3718
  AudioEndpoint *ae;
3704
3719
  int ae_count;
3705
3720
 
3706
- unsigned media_id;
3721
+ unsigned media_id = 0;
3707
3722
 
3708
3723
  char buffer[MAX_JSON_INPUT];
3709
3724
 
@@ -3841,7 +3856,7 @@ int pjw_call_stop_fax(long call_id, const char *json) {
3841
3856
  int ae_count;
3842
3857
  int res;
3843
3858
 
3844
- unsigned media_id;
3859
+ unsigned media_id = 0;
3845
3860
 
3846
3861
  char buffer[MAX_JSON_INPUT];
3847
3862
 
@@ -3924,7 +3939,7 @@ int pjw_call_get_stream_stat(long call_id, const char *json, char *out_stats) {
3924
3939
  AudioEndpoint *ae;
3925
3940
  VideoEndpoint *ve;
3926
3941
 
3927
- unsigned media_id;
3942
+ unsigned media_id = 0;
3928
3943
 
3929
3944
  pjmedia_stream *med_stream = NULL;
3930
3945
 
@@ -4098,6 +4113,20 @@ void gen_media_json(char *dest, int len, Call *call,
4098
4113
  pjmedia_sdp_media *local_media = local_sdp->media[idx];
4099
4114
  pjmedia_sdp_media *remote_media = remote_sdp->media[idx];
4100
4115
 
4116
+ if(!me->port) {
4117
+ switch (me->type) {
4118
+ case ENDPOINT_TYPE_AUDIO:
4119
+ p += sprintf(p, "{\"type\": \"audio\", \"port\": 0}");
4120
+ break;
4121
+ case ENDPOINT_TYPE_MRCP:
4122
+ p += sprintf(p, "{\"type\": \"mrcp\", \"port\": 0}");
4123
+ break;
4124
+ default:
4125
+ p += sprintf(p, "{\"type\": \"unknown\", \"port\": 0}");
4126
+ }
4127
+ continue;
4128
+ }
4129
+
4101
4130
  switch (me->type) {
4102
4131
  case ENDPOINT_TYPE_AUDIO: {
4103
4132
  AudioEndpoint *ae = (AudioEndpoint *)me->endpoint.audio;
@@ -4449,29 +4478,30 @@ static void on_media_update(pjsip_inv_session *inv, pj_status_t status) {
4449
4478
  call->id, b);
4450
4479
 
4451
4480
  // update media endpoint based on sdp media
4452
-
4453
4481
  bool in_use_chart[PJMEDIA_MAX_SDP_MEDIA] = {false};
4454
4482
  MediaEndpoint *active_media[PJMEDIA_MAX_SDP_MEDIA] = {NULL};
4455
4483
  int active_media_count = 0;
4456
4484
 
4457
4485
  for (int i = 0; i < local_sdp->media_count; i++) {
4458
- pjmedia_sdp_media *media = local_sdp->media[i];
4459
- if (media->desc.port) {
4460
- MediaEndpoint *me =
4461
- find_media_endpt_by_sdp_media(call, media, in_use_chart);
4462
- if (me) {
4463
- active_media[active_media_count++] = me;
4464
- }
4465
- }
4466
- }
4467
-
4468
- for (int i = 0; i < call->media_count; i++) {
4469
4486
  MediaEndpoint *me = call->media[i];
4470
- if (!is_media_in_active_media(me, active_media, active_media_count)) {
4487
+ if (!local_sdp->media[i]->desc.port) {
4471
4488
  close_media_endpoint(me);
4489
+ } else {
4490
+ if (me->type == ENDPOINT_TYPE_AUDIO) {
4491
+ if (!restart_media_stream(call, me, local_sdp, remote_sdp, i)) {
4492
+ return;
4493
+ }
4494
+ } else if(me->type == ENDPOINT_TYPE_MRCP) {
4495
+ if(call->outgoing) {
4496
+ if(!start_tcp_media(call, me, local_sdp, remote_sdp, i)) {
4497
+ return;
4498
+ }
4499
+ }
4500
+ }
4472
4501
  }
4473
4502
  }
4474
4503
 
4504
+ /*
4475
4505
  printf("active_media_count=%d\n", active_media_count);
4476
4506
  call->media_count = 0;
4477
4507
  for (int i = 0; i < active_media_count; i++) {
@@ -4482,18 +4512,21 @@ static void on_media_update(pjsip_inv_session *inv, pj_status_t status) {
4482
4512
  int idx = find_sdp_media_by_media_endpt(local_sdp, &dummy, me);
4483
4513
  printf("idx=%d\n", idx);
4484
4514
 
4485
- if (me->type == ENDPOINT_TYPE_AUDIO) {
4486
- if (!restart_media_stream(call, me, local_sdp, remote_sdp, idx)) {
4487
- return;
4488
- }
4489
- } else if(me->type == ENDPOINT_TYPE_MRCP) {
4490
- if(call->outgoing) {
4491
- if(!start_tcp_media(call, me, local_sdp, remote_sdp, idx)) {
4515
+ if(me->port != 0) {
4516
+ if (me->type == ENDPOINT_TYPE_AUDIO) {
4517
+ if (!restart_media_stream(call, me, local_sdp, remote_sdp, idx)) {
4492
4518
  return;
4493
4519
  }
4520
+ } else if(me->type == ENDPOINT_TYPE_MRCP) {
4521
+ if(call->outgoing) {
4522
+ if(!start_tcp_media(call, me, local_sdp, remote_sdp, idx)) {
4523
+ return;
4524
+ }
4525
+ }
4494
4526
  }
4495
4527
  }
4496
4528
  }
4529
+ */
4497
4530
 
4498
4531
  char media[4096];
4499
4532
  gen_media_json(media, sizeof(media), call, local_sdp, remote_sdp);
@@ -5761,15 +5794,31 @@ bool create_media_endpoint(Call *call, Document &document, Value &descr,
5761
5794
  const char *type = (const char *)descr["type"].GetString();
5762
5795
  const pj_str_t str_addr = pj_str(address);
5763
5796
 
5764
- if (strcmp("audio", type) == 0) {
5765
- pj_uint16_t allocated_port;
5766
- pjmedia_transport *med_transport =
5767
- create_media_transport(&str_addr, &allocated_port);
5797
+ pj_bool_t must_not_be_used = PJ_FALSE;
5768
5798
 
5769
- if (!med_transport) {
5770
- set_error("create_media_transport failed");
5799
+ if (descr.HasMember("port")) {
5800
+ if (!descr["port"].IsInt()) {
5801
+ set_error("Parameter port must be an integer");
5771
5802
  return false;
5772
5803
  }
5804
+ int port = descr["port"].GetInt();
5805
+ if(port == 0) {
5806
+ must_not_be_used = PJ_TRUE;
5807
+ }
5808
+ }
5809
+
5810
+ if (strcmp("audio", type) == 0) {
5811
+ pj_uint16_t allocated_port;
5812
+ pjmedia_transport *med_transport = NULL;
5813
+ if(must_not_be_used) {
5814
+ allocated_port = 0;
5815
+ } else {
5816
+ med_transport = create_media_transport(&str_addr, &allocated_port);
5817
+ if (!med_transport) {
5818
+ set_error("create_media_transport failed");
5819
+ return false;
5820
+ }
5821
+ }
5773
5822
 
5774
5823
  AudioEndpoint *audio_endpt =
5775
5824
  (AudioEndpoint *)pj_pool_zalloc(dlg->pool, sizeof(AudioEndpoint));
@@ -5785,16 +5834,20 @@ bool create_media_endpoint(Call *call, Document &document, Value &descr,
5785
5834
  MrcpEndpoint *mrcp_endpt = (MrcpEndpoint *)pj_pool_zalloc(dlg->pool, sizeof(MrcpEndpoint));
5786
5835
  pj_uint16_t allocated_port;
5787
5836
  pj_activesock_t *asock = NULL;
5788
- if (call->outgoing) {
5789
- allocated_port = 9; // client must use port 9
5837
+ if(must_not_be_used) {
5838
+ allocated_port = 0;
5790
5839
  } else {
5791
- pj_str_t ipaddr = pj_str(address);
5792
- asock = create_tcp_socket(g_sip_endpt, &ipaddr, &allocated_port, med_endpt, call);
5793
- if(!asock) {
5794
- set_error("create_media_transport MrcpEndpoint failed");
5795
- return false;
5840
+ if (call->outgoing) {
5841
+ allocated_port = 9; // client must use port 9
5842
+ } else {
5843
+ pj_str_t ipaddr = pj_str(address);
5844
+ asock = create_tcp_socket(g_sip_endpt, &ipaddr, &allocated_port, med_endpt, call);
5845
+ if(!asock) {
5846
+ set_error("create_media_transport MrcpEndpoint failed");
5847
+ return false;
5848
+ }
5849
+ mrcp_endpt->asock = asock;
5796
5850
  }
5797
- mrcp_endpt->asock = asock;
5798
5851
  }
5799
5852
 
5800
5853
  med_endpt->type = ENDPOINT_TYPE_MRCP;
@@ -5819,7 +5872,7 @@ bool create_media_endpoint(Call *call, Document &document, Value &descr,
5819
5872
  }
5820
5873
 
5821
5874
  MediaEndpoint *find_media_by_json_descr(Call *call, Value &descr,
5822
- bool in_use_chart[]) {
5875
+ bool in_use_chart[], int *idx) {
5823
5876
  const char *type_name = (const char *)descr["type"].GetString();
5824
5877
 
5825
5878
  int type_id = media_type_name_to_type_id(type_name);
@@ -5831,6 +5884,7 @@ MediaEndpoint *find_media_by_json_descr(Call *call, Value &descr,
5831
5884
 
5832
5885
  if (me->type == type_id) {
5833
5886
  in_use_chart[i] = true;
5887
+ *idx = i;
5834
5888
  return me;
5835
5889
  }
5836
5890
  }
@@ -5875,6 +5929,33 @@ pjmedia_sdp_media *create_sdp_media(MediaEndpoint *me, pjsip_dialog *dlg) {
5875
5929
  pj_status_t status;
5876
5930
  pjmedia_sdp_media *media;
5877
5931
 
5932
+ if(me->port == 0) {
5933
+ // media not in use
5934
+ media = (pjmedia_sdp_media *)pj_pool_zalloc(dlg->pool,
5935
+ sizeof(pjmedia_sdp_media));
5936
+ if (!media) {
5937
+ set_error("create pjmedia_sdp_media for mrcp endpoint failed");
5938
+ return NULL;
5939
+ }
5940
+
5941
+ pj_strdup(dlg->pool, &media->desc.media, &me->media);
5942
+
5943
+ pj_strdup(dlg->pool, &media->desc.transport, &me->transport);
5944
+
5945
+ media->desc.port = me->port;
5946
+ pj_strdup2(
5947
+ dlg->pool, &media->desc.fmt[media->desc.fmt_count++],
5948
+ "0");
5949
+
5950
+ media->conn =
5951
+ (pjmedia_sdp_conn *)pj_pool_zalloc(dlg->pool, sizeof(pjmedia_sdp_conn));
5952
+ pj_strdup2(dlg->pool, &media->conn->net_type, "IN");
5953
+ pj_strdup2(dlg->pool, &media->conn->addr_type, "IP4");
5954
+ pj_strdup(dlg->pool, &media->conn->addr, &me->addr);
5955
+
5956
+ return media;
5957
+ }
5958
+
5878
5959
  if (ENDPOINT_TYPE_AUDIO == me->type) {
5879
5960
  AudioEndpoint *audio = (AudioEndpoint *)me->endpoint.audio;
5880
5961
  pjmedia_transport_info med_tpinfo;
@@ -6021,9 +6102,51 @@ bool process_media(Call *call, pjsip_dialog *dlg, Document &document) {
6021
6102
  for (SizeType i = 0; i < media.Size(); i++) {
6022
6103
  Value descr = media[i].GetObject();
6023
6104
 
6024
- MediaEndpoint *me = find_media_by_json_descr(call, descr, in_use_chart);
6105
+ int idx;
6106
+ MediaEndpoint *me = find_media_by_json_descr(call, descr, in_use_chart, &idx);
6107
+
6025
6108
  if (me) {
6026
6109
  addon_log(L_DBG, "i=%d media found\n", i);
6110
+ if (me->port && descr.HasMember("port")) {
6111
+ // me was active but it must be deactivated
6112
+ MediaEndpoint *new_me;
6113
+
6114
+ if(!create_media_endpoint(call, document, descr, dlg, "0.0.0.0", &new_me))
6115
+ return false;
6116
+ addon_log(L_DBG, "i=%d media port=0 created %x\n", i, me);
6117
+
6118
+ pjmedia_sdp_media *media = create_sdp_media(new_me, dlg);
6119
+ if (!media)
6120
+ return false;
6121
+
6122
+ sdp->media[sdp->media_count++] = media;
6123
+ } else if(!me->port && !descr.HasMember("port")) {
6124
+ // me was not active but it is activated now
6125
+ if (!create_media_endpoint(call, document, descr, dlg, t->address, &me))
6126
+ return false;
6127
+ addon_log(L_DBG, "i=%d media created %x\n", i, me);
6128
+ call->media[idx] = me;
6129
+
6130
+ if (!update_media_fields(me, dlg->pool, descr)) {
6131
+ return false;
6132
+ }
6133
+
6134
+ pjmedia_sdp_media *media = create_sdp_media(me, dlg);
6135
+ if (!media)
6136
+ return false;
6137
+
6138
+ sdp->media[sdp->media_count++] = media;
6139
+ } else {
6140
+ if (!update_media_fields(me, dlg->pool, descr)) {
6141
+ return false;
6142
+ }
6143
+
6144
+ pjmedia_sdp_media *media = create_sdp_media(me, dlg);
6145
+ if (!media)
6146
+ return false;
6147
+
6148
+ sdp->media[sdp->media_count++] = media;
6149
+ }
6027
6150
  } else {
6028
6151
  addon_log(L_DBG, "i=%d media not found\n", i);
6029
6152
  if (!create_media_endpoint(call, document, descr, dlg, t->address, &me))
@@ -6032,17 +6155,17 @@ bool process_media(Call *call, pjsip_dialog *dlg, Document &document) {
6032
6155
  call->media[call->media_count++] = me;
6033
6156
  in_use_chart[call->media_count - 1] =
6034
6157
  true; // added elements must be set as in use
6035
- }
6036
6158
 
6037
- if (!update_media_fields(me, dlg->pool, descr)) {
6038
- return false;
6039
- }
6159
+ if (!update_media_fields(me, dlg->pool, descr)) {
6160
+ return false;
6161
+ }
6040
6162
 
6041
- pjmedia_sdp_media *media = create_sdp_media(me, dlg);
6042
- if (!media)
6043
- return false;
6163
+ pjmedia_sdp_media *media = create_sdp_media(me, dlg);
6164
+ if (!media)
6165
+ return false;
6044
6166
 
6045
- sdp->media[sdp->media_count++] = media;
6167
+ sdp->media[sdp->media_count++] = media;
6168
+ }
6046
6169
  }
6047
6170
 
6048
6171
  call->local_sdp = sdp;
@@ -6066,8 +6189,12 @@ bool is_media_active(Call *c, MediaEndpoint *me) {
6066
6189
 
6067
6190
  void close_media_endpoint(MediaEndpoint *me) {
6068
6191
  printf("close_media_endpoint %x\n", me);
6192
+ if(!me) return;
6193
+
6069
6194
  if (ENDPOINT_TYPE_AUDIO == me->type) {
6070
- close_media_transport(me->endpoint.audio->med_transport);
6195
+ AudioEndpoint *ae = (AudioEndpoint *)me->endpoint.audio;
6196
+ close_media_transport(ae->med_transport);
6197
+ ae->med_transport = NULL;
6071
6198
  } else if (ENDPOINT_TYPE_MRCP == me->type) {
6072
6199
  if(me->endpoint.mrcp->asock) {
6073
6200
  pj_activesock_t *asock = me->endpoint.mrcp->asock;
@@ -6084,7 +6211,9 @@ void close_media_endpoint(MediaEndpoint *me) {
6084
6211
  printf("pj_activesock_close failed\n");
6085
6212
  }
6086
6213
  }
6214
+ me->endpoint.mrcp->asock = NULL;
6087
6215
  }
6216
+ me->port = 0;
6088
6217
  }
6089
6218
 
6090
6219
  void close_media(Call *c) {
@@ -7601,7 +7730,7 @@ int pjw_call_send_tcp_msg(long call_id, const char *json) {
7601
7730
  MrcpEndpoint *mrcp_endpt;
7602
7731
  int res;
7603
7732
 
7604
- unsigned media_id;
7733
+ unsigned media_id = 0;
7605
7734
 
7606
7735
  char buffer[MAX_JSON_INPUT];
7607
7736