sip-lab 1.29.0 → 1.31.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
@@ -267,7 +267,7 @@ int ms_timestamp();
267
267
  bool g_shutting_down;
268
268
 
269
269
  int g_dtmf_inter_digit_timer = 0;
270
- int g_bfsk_inter_bit_timer = 0;
270
+ int g_bfsk_inter_bit_timer = 200;
271
271
 
272
272
  pj_str_t g_sip_ipaddress;
273
273
 
@@ -614,7 +614,7 @@ void build_local_contact_from_tpfactory(char *dest, pjsip_tpfactory *tpfactory,
614
614
  // pj_bool_t add_additional_headers(pj_pool_t *pool, pjsip_tx_data *tdata, const
615
615
  // char *additional_headers);
616
616
  pj_bool_t add_headers(pj_pool_t *pool, pjsip_tx_data *tdata,
617
- Document &document);
617
+ Document &document, pjsip_dialog *dlg);
618
618
 
619
619
  pj_bool_t add_headers_for_account(pjsip_regc *regc, Document &document);
620
620
 
@@ -641,12 +641,12 @@ static void build_stream_stat(ostringstream &oss, pjmedia_rtcp_stat *stat,
641
641
 
642
642
  bool prepare_tonegen(Call *call, AudioEndpoint *ae);
643
643
  bool prepare_dtmfdet(Call *call, AudioEndpoint *ae);
644
- bool prepare_bfsk_det(Call *call, AudioEndpoint *ae, const int freq_zero, const int freq_one, const int min_level, const int baud_rate);
644
+ bool prepare_bfsk_det(Call *call, AudioEndpoint *ae, const int freq_zero, const int freq_one);
645
645
  bool prepare_wav_player(Call *call, AudioEndpoint *ae, const char *file, unsigned flags, bool end_of_file_event);
646
646
  bool prepare_wav_writer(Call *call, AudioEndpoint *ae, const char *file);
647
647
  bool prepare_fax(Call *call, AudioEndpoint *ae, bool is_sender, const char *file, unsigned flags);
648
- bool prepare_speech_synth(Call *call, AudioEndpoint *ae, const char *server_url, const char *engine, const char *voice, const char *language, const char *text, int times);
649
- bool prepare_speech_recog(Call *call, AudioEndpoint *ae, const char *server_url, const char *engine, const char *language);
648
+ bool prepare_speech_synth(Call *call, AudioEndpoint *ae, const char *server_url, const char *uuid, const char *engine, const char *voice, const char *language, const char *text, int times);
649
+ bool prepare_speech_recog(Call *call, AudioEndpoint *ae, const char *server_url, const char *uuid, const char *engine, const char *language);
650
650
 
651
651
  void prepare_error_event(ostringstream *oss, char *scope, char *details);
652
652
  // void prepare_pjsipcall_error_event(ostringstream *oss, char *scope, char
@@ -897,7 +897,7 @@ static void on_bfsk_bit(pjmedia_port *port, void *user_data, int bit) {
897
897
  return;
898
898
  }
899
899
 
900
- ae->BfskBuffer[len] = bit;
900
+ ae->BfskBuffer[len] = bit == 0 ? '0' : '1';
901
901
  ae->BfskBufferLength++;
902
902
 
903
903
  ae->last_bit_timestamp = ms_timestamp();
@@ -905,7 +905,7 @@ static void on_bfsk_bit(pjmedia_port *port, void *user_data, int bit) {
905
905
  } else {
906
906
  char evt[1024];
907
907
  char the_bit[1];
908
- the_bit[0] = bit;
908
+ the_bit[0] = bit == 0 ? '0' : '1';
909
909
  make_evt_bfsk(evt, sizeof(evt), call_id, 1, the_bit, media_id);
910
910
  dispatch_event(evt);
911
911
  }
@@ -1457,11 +1457,13 @@ int __pjw_init() {
1457
1457
  return 1;
1458
1458
  }
1459
1459
 
1460
+ /*
1460
1461
  status = pjsip_replaces_init_module(g_sip_endpt);
1461
1462
  if (status != PJ_SUCCESS) {
1462
1463
  addon_log(L_DBG, "pjsip_replaces_init_module failed\n");
1463
1464
  return 1;
1464
1465
  }
1466
+ */
1465
1467
 
1466
1468
  pjsip_inv_callback inv_cb;
1467
1469
  pj_bzero(&inv_cb, sizeof(inv_cb));
@@ -2359,6 +2361,10 @@ int pjw_call_respond(long call_id, const char *json) {
2359
2361
 
2360
2362
  status = pjsip_dlg_send_response(call->inv->dlg, tsx, tdata);
2361
2363
 
2364
+ if (status != PJ_SUCCESS) {
2365
+ printf("Failed to send response, status=%d\n", status);
2366
+ }
2367
+
2362
2368
  assert(status == PJ_SUCCESS);
2363
2369
 
2364
2370
  if (code >= 200) {
@@ -2421,9 +2427,9 @@ int pjw_call_respond(long call_id, const char *json) {
2421
2427
  }
2422
2428
  call->pending_rdata = 0;
2423
2429
 
2424
- if (code >= 200 && code < 300) {
2425
- call->pending_request = -1;
2426
- }
2430
+ call->pending_request = -1;
2431
+
2432
+ pjsip_msg_find_remove_hdr(tdata->msg, PJSIP_H_SUPPORTED, NULL);
2427
2433
  }
2428
2434
  } else {
2429
2435
  status = pjsip_inv_answer(call->inv, code, &r,
@@ -2444,12 +2450,26 @@ int pjw_call_respond(long call_id, const char *json) {
2444
2450
  call->pending_rdata = 0;
2445
2451
  }
2446
2452
 
2447
- if (code >= 200 && code < 300) {
2448
- call->pending_request = -1;
2449
- }
2453
+ call->pending_request = -1;
2454
+
2455
+ /*
2456
+ int printed;
2457
+ char buf[2048];
2458
+ printed = pjsip_msg_print(tdata->msg, buf, sizeof(buf));
2459
+ printf("tdata before len=%i :\n%s\n", printed, buf);
2460
+ */
2461
+
2462
+ // the below works (header Supported is removed)
2463
+ // but something (the 100rel module) adds 'Supported: 100rel' later.
2464
+ pjsip_msg_find_remove_hdr(tdata->msg, PJSIP_H_SUPPORTED, NULL);
2465
+
2466
+ /*
2467
+ printed = pjsip_msg_print(tdata->msg, buf, sizeof(buf));
2468
+ printf("tdata after len=%i :\n%s\n", printed, buf);
2469
+ */
2450
2470
  }
2451
2471
 
2452
- if (!add_headers(call->inv->dlg->pool, tdata, document)) {
2472
+ if (!add_headers(call->inv->dlg->pool, tdata, document, NULL)) {
2453
2473
  goto out;
2454
2474
  }
2455
2475
  }
@@ -2530,7 +2550,7 @@ int pjw_call_terminate(long call_id, const char *json) {
2530
2550
  goto out;
2531
2551
  }
2532
2552
 
2533
- if (!add_headers(call->inv->dlg->pool, tdata, document)) {
2553
+ if (!add_headers(call->inv->dlg->pool, tdata, document, NULL)) {
2534
2554
  goto out;
2535
2555
  }
2536
2556
 
@@ -2667,7 +2687,7 @@ int pjw_request_create(long t_id, const char *json, long *out_request_id,
2667
2687
  goto out;
2668
2688
  }
2669
2689
 
2670
- if (!add_headers(tdata->pool, tdata, document)) {
2690
+ if (!add_headers(tdata->pool, tdata, document, NULL)) {
2671
2691
  goto out;
2672
2692
  }
2673
2693
 
@@ -2767,7 +2787,7 @@ int pjw_request_respond(long request_id, const char *json) {
2767
2787
  goto out;
2768
2788
  }
2769
2789
 
2770
- if (!add_headers(tdata->pool, tdata, document)) {
2790
+ if (!add_headers(tdata->pool, tdata, document, NULL)) {
2771
2791
  goto out;
2772
2792
  }
2773
2793
 
@@ -2836,7 +2856,7 @@ int pjw_call_create(long t_id, const char *json, long *out_call_id,
2836
2856
 
2837
2857
  const char *valid_params[] = {"from_uri", "to_uri", "request_uri",
2838
2858
  "proxy_uri", "auth", "delayed_media",
2839
- "headers", "media", ""};
2859
+ "headers", "media", "from_tag", ""};
2840
2860
 
2841
2861
  if (!g_transport_ids.get(t_id, val)) {
2842
2862
  set_error("Invalid transport_id");
@@ -3237,7 +3257,22 @@ int call_create(Transport *t, unsigned flags, pjsip_dialog *dlg,
3237
3257
  return -1;
3238
3258
  }
3239
3259
 
3240
- if (!add_headers(dlg->pool, tdata, document)) {
3260
+ if (document.HasMember("from_tag")) {
3261
+ if (!document["from_tag"].IsString()) {
3262
+ g_call_ids.remove(call_id, (long&)call);
3263
+ close_media(call);
3264
+ status = pjsip_dlg_terminate(dlg); // ToDo:
3265
+ set_error("Parameter from_tag must be a string");
3266
+ return -1;
3267
+ }
3268
+
3269
+ char *from_tag = (char *)document["from_tag"].GetString();
3270
+
3271
+ pjsip_from_hdr *from_hdr = (pjsip_from_hdr*) pjsip_msg_find_hdr(tdata->msg, PJSIP_H_FROM, NULL);
3272
+ pj_strdup2(tdata->pool, &from_hdr->tag, from_tag);
3273
+ }
3274
+
3275
+ if (!add_headers(dlg->pool, tdata, document, dlg)) {
3241
3276
  g_call_ids.remove(call_id, (long&)call);
3242
3277
  close_media(call); // Todo:
3243
3278
  status = pjsip_dlg_terminate(dlg); // ToDo:
@@ -3249,6 +3284,8 @@ int call_create(Transport *t, unsigned flags, pjsip_dialog *dlg,
3249
3284
  }
3250
3285
  addon_log(L_DBG, "inv=%p tdata=%p\n", (void*)inv, (void*)tdata);
3251
3286
 
3287
+ pjsip_msg_find_remove_hdr(tdata->msg, PJSIP_H_SUPPORTED, NULL);
3288
+
3252
3289
  status = pjsip_inv_send_msg(inv, tdata);
3253
3290
  addon_log(L_DBG, "status=%d\n", status);
3254
3291
  if (status != PJ_SUCCESS) {
@@ -3470,7 +3507,7 @@ out:
3470
3507
  }
3471
3508
 
3472
3509
  pj_status_t audio_endpoint_send_bfsk(Call *call, AudioEndpoint *ae,
3473
- const char *bits, const int freq_zero, const int freq_one, const int level, const int baud_rate) {
3510
+ const char *bits, const int freq_zero, const int freq_one, const int level, const int signal_duration) {
3474
3511
  pj_status_t status;
3475
3512
 
3476
3513
  if (!prepare_tonegen(call, ae)) {
@@ -3480,14 +3517,12 @@ pj_status_t audio_endpoint_send_bfsk(Call *call, AudioEndpoint *ae,
3480
3517
 
3481
3518
  int len = strlen(bits);
3482
3519
 
3483
- int duration = 1000 / baud_rate; // Duration of each tone in milliseconds
3484
-
3485
3520
  pjmedia_tone_desc *tones = (pjmedia_tone_desc*)pj_pool_zalloc(call->inv->pool, sizeof(pjmedia_tone_desc) * len);
3486
3521
 
3487
3522
  for (int i = 0; i < len; ++i) {
3488
3523
  tones[i].freq1 = bits[i] == '0' ? freq_zero : freq_one;
3489
- tones[i].on_msec = duration;
3490
- tones[i].off_msec = duration;
3524
+ tones[i].on_msec = signal_duration;
3525
+ tones[i].off_msec = signal_duration;
3491
3526
  tones[i].volume = level;
3492
3527
  }
3493
3528
 
@@ -3500,7 +3535,7 @@ pj_status_t audio_endpoint_send_bfsk(Call *call, AudioEndpoint *ae,
3500
3535
  return PJ_SUCCESS;
3501
3536
  }
3502
3537
 
3503
- pj_status_t send_bfsk(Call *call, const char *bits, const int freq_zero, const int freq_one, const int level, const int baud_rate) {
3538
+ pj_status_t send_bfsk(Call *call, const char *bits, const int freq_zero, const int freq_one, const int level, const int signal_duration) {
3504
3539
  for (int i = 0; i < call->media_count; i++) {
3505
3540
  MediaEndpoint *me = (MediaEndpoint *)call->media[i];
3506
3541
  if (me->type != ENDPOINT_TYPE_AUDIO)
@@ -3511,7 +3546,7 @@ pj_status_t send_bfsk(Call *call, const char *bits, const int freq_zero, const i
3511
3546
 
3512
3547
  AudioEndpoint *ae = (AudioEndpoint *)me->endpoint.audio;
3513
3548
 
3514
- pj_status_t status = audio_endpoint_send_bfsk(call, ae, bits, freq_zero, freq_one, level, baud_rate);
3549
+ pj_status_t status = audio_endpoint_send_bfsk(call, ae, bits, freq_zero, freq_one, level, signal_duration);
3515
3550
  if (status != PJ_SUCCESS)
3516
3551
  return status;
3517
3552
  }
@@ -3536,8 +3571,8 @@ int pjw_call_send_bfsk(long call_id, const char *json) {
3536
3571
  char *bits;
3537
3572
  int freq_zero;
3538
3573
  int freq_one;
3539
- int level;
3540
- int baud_rate;
3574
+ int level = 24000;
3575
+ int signal_duration = 10;
3541
3576
 
3542
3577
  MediaEndpoint *me;
3543
3578
  AudioEndpoint *ae;
@@ -3549,7 +3584,7 @@ int pjw_call_send_bfsk(long call_id, const char *json) {
3549
3584
 
3550
3585
  Document document;
3551
3586
 
3552
- const char *valid_params[] = {"bits", "freq_zero", "freq_one", "level", "baud_rate", "media_id", ""};
3587
+ const char *valid_params[] = {"bits", "freq_zero", "freq_one", "level", "signal_duration", "media_id", ""};
3553
3588
 
3554
3589
  if (!g_call_ids.get(call_id, val)) {
3555
3590
  set_error("Invalid call_id");
@@ -3577,11 +3612,11 @@ int pjw_call_send_bfsk(long call_id, const char *json) {
3577
3612
  goto out;
3578
3613
  }
3579
3614
 
3580
- if (json_get_int_param(document, "level", false, &level) <= 0) {
3615
+ if (json_get_int_param(document, "level", true, &level) <= 0) {
3581
3616
  goto out;
3582
3617
  }
3583
3618
 
3584
- if (json_get_int_param(document, "baud_rate", false, &baud_rate) <= 0) {
3619
+ if (json_get_int_param(document, "signal_duration", true, &signal_duration) <= 0) {
3585
3620
  goto out;
3586
3621
  }
3587
3622
 
@@ -3606,7 +3641,7 @@ int pjw_call_send_bfsk(long call_id, const char *json) {
3606
3641
 
3607
3642
  if (NOT_FOUND_OPTIONAL == res) {
3608
3643
  // send_bfsk_bits to all audio endpoints
3609
- status = send_bfsk(call, bits, freq_zero, freq_one, level, baud_rate);
3644
+ status = send_bfsk(call, bits, freq_zero, freq_one, level, signal_duration);
3610
3645
  if (status != PJ_SUCCESS) {
3611
3646
  goto out;
3612
3647
  }
@@ -3626,7 +3661,7 @@ int pjw_call_send_bfsk(long call_id, const char *json) {
3626
3661
 
3627
3662
  ae = (AudioEndpoint *)me->endpoint.audio;
3628
3663
 
3629
- status = audio_endpoint_send_bfsk(call, ae, bits, freq_one, freq_zero, level, baud_rate);
3664
+ status = audio_endpoint_send_bfsk(call, ae, bits, freq_one, freq_zero, level, signal_duration);
3630
3665
  if (status != PJ_SUCCESS) {
3631
3666
  goto out;
3632
3667
  }
@@ -3759,6 +3794,76 @@ int pjw_call_reinvite(long call_id, const char *json) {
3759
3794
  goto out;
3760
3795
  }
3761
3796
 
3797
+ pjsip_msg_find_remove_hdr(tdata->msg, PJSIP_H_SUPPORTED, NULL);
3798
+
3799
+ status = pjsip_inv_send_msg(call->inv, tdata);
3800
+ if (status != PJ_SUCCESS) {
3801
+ set_error("pjsip_inv_send_msg failed");
3802
+ goto out;
3803
+ }
3804
+
3805
+ out:
3806
+ PJW_UNLOCK();
3807
+ if (pjw_errorstring[0]) {
3808
+ return -1;
3809
+ }
3810
+
3811
+ return 0;
3812
+ }
3813
+
3814
+
3815
+ int pjw_call_update(long call_id, const char *json) {
3816
+ addon_log(L_DBG, "pjw_call_update call_id=%d\n", call_id);
3817
+
3818
+ PJW_LOCK();
3819
+ clear_error();
3820
+
3821
+ unsigned flags = 0;
3822
+
3823
+ long val;
3824
+ Call *call;
3825
+ pjsip_inv_session *inv;
3826
+
3827
+ pj_status_t status;
3828
+
3829
+ pjsip_tx_data *tdata;
3830
+ // pjmedia_sdp_session *sdp = 0;
3831
+
3832
+ char buffer[MAX_JSON_INPUT];
3833
+
3834
+ Document document;
3835
+
3836
+ const char *valid_params[] = {"headers", ""};
3837
+
3838
+ if (!g_call_ids.get(call_id, val)) {
3839
+ set_error("Invalid call_id");
3840
+ goto out;
3841
+ }
3842
+ call = (Call *)val;
3843
+
3844
+ inv = call->inv;
3845
+
3846
+ if (!parse_json(document, json, buffer, MAX_JSON_INPUT)) {
3847
+ goto out;
3848
+ }
3849
+
3850
+ if (!validate_params(document, valid_params)) {
3851
+ goto out;
3852
+ }
3853
+
3854
+ status = pjsip_inv_update(call->inv, NULL, NULL, &tdata);
3855
+ printf("status=%d\n", status);
3856
+ if (status != PJ_SUCCESS) {
3857
+ set_error("pjsip_inv_update failed");
3858
+ goto out;
3859
+ }
3860
+
3861
+ pjsip_msg_find_remove_hdr(tdata->msg, PJSIP_H_SUPPORTED, NULL);
3862
+
3863
+ if (!add_headers(call->inv->dlg->pool, tdata, document, NULL)) {
3864
+ goto out;
3865
+ }
3866
+
3762
3867
  status = pjsip_inv_send_msg(call->inv, tdata);
3763
3868
  if (status != PJ_SUCCESS) {
3764
3869
  set_error("pjsip_inv_send_msg failed");
@@ -3860,7 +3965,7 @@ int pjw_call_send_request(long call_id, const char *json) {
3860
3965
  goto out;
3861
3966
  }
3862
3967
 
3863
- if (!add_headers(call->inv->dlg->pool, tdata, document)) {
3968
+ if (!add_headers(call->inv->dlg->pool, tdata, document, NULL)) {
3864
3969
  goto out;
3865
3970
  }
3866
3971
 
@@ -4171,7 +4276,7 @@ out:
4171
4276
  return 0;
4172
4277
  }
4173
4278
 
4174
- pj_status_t audio_endpoint_start_speech_synth(Call *call, AudioEndpoint *ae, const char *server_url, const char *engine, const char *voice, const char *language, const char *text, int times) {
4279
+ pj_status_t audio_endpoint_start_speech_synth(Call *call, AudioEndpoint *ae, const char *server_url, const char *uuid, const char *engine, const char *voice, const char *language, const char *text, int times) {
4175
4280
  pj_status_t status;
4176
4281
 
4177
4282
  if(!ae->stream_cbp.port) {
@@ -4185,7 +4290,7 @@ pj_status_t audio_endpoint_start_speech_synth(Call *call, AudioEndpoint *ae, con
4185
4290
  return -1;
4186
4291
  }
4187
4292
 
4188
- if (!prepare_speech_synth(call, ae, server_url, engine, voice, language, text, times)) {
4293
+ if (!prepare_speech_synth(call, ae, server_url, uuid, engine, voice, language, text, times)) {
4189
4294
  return -1;
4190
4295
  }
4191
4296
 
@@ -4304,13 +4409,16 @@ int pjw_call_start_speech_synth(long call_id, const char *json) {
4304
4409
  }
4305
4410
  }
4306
4411
 
4412
+ char uuid[1024];
4413
+ sprintf(uuid, "%.*s", call->inv->dlg->call_id->id.slen, call->inv->dlg->call_id->id.ptr);
4414
+
4307
4415
  if (NOT_FOUND_OPTIONAL == res) {
4308
4416
  // start on all audio media endpoints
4309
4417
  for (int i = 0; i < call->media_count; i++) {
4310
4418
  MediaEndpoint *me = (MediaEndpoint *)call->media[i];
4311
4419
  if (me->type == ENDPOINT_TYPE_AUDIO) {
4312
4420
  AudioEndpoint *ae = (AudioEndpoint *)me->endpoint.audio;
4313
- status = audio_endpoint_start_speech_synth(call, ae, server_url, engine, voice, language, text, times);
4421
+ status = audio_endpoint_start_speech_synth(call, ae, server_url, uuid, engine, voice, language, text, times);
4314
4422
  if (status != PJ_SUCCESS) goto out;
4315
4423
  }
4316
4424
  }
@@ -4328,7 +4436,7 @@ int pjw_call_start_speech_synth(long call_id, const char *json) {
4328
4436
 
4329
4437
  ae = (AudioEndpoint *)me->endpoint.audio;
4330
4438
 
4331
- audio_endpoint_start_speech_synth(call, ae, server_url, engine, voice, language, text, times);
4439
+ audio_endpoint_start_speech_synth(call, ae, server_url, uuid, engine, voice, language, text, times);
4332
4440
  }
4333
4441
 
4334
4442
  out:
@@ -4340,7 +4448,7 @@ out:
4340
4448
  return 0;
4341
4449
  }
4342
4450
 
4343
- pj_status_t audio_endpoint_start_speech_recog(Call *call, AudioEndpoint *ae, const char *server_url, const char *engine, const char *language) {
4451
+ pj_status_t audio_endpoint_start_speech_recog(Call *call, AudioEndpoint *ae, const char *server_url, const char *uuid, const char *engine, const char *language) {
4344
4452
  pj_status_t status;
4345
4453
 
4346
4454
  if(!ae->stream_cbp.port) {
@@ -4354,7 +4462,7 @@ pj_status_t audio_endpoint_start_speech_recog(Call *call, AudioEndpoint *ae, con
4354
4462
  return -1;
4355
4463
  }
4356
4464
 
4357
- if (!prepare_speech_recog(call, ae, server_url, engine, language)) {
4465
+ if (!prepare_speech_recog(call, ae, server_url, uuid, engine, language)) {
4358
4466
  return -1;
4359
4467
  }
4360
4468
 
@@ -4445,13 +4553,16 @@ int pjw_call_start_speech_recog(long call_id, const char *json) {
4445
4553
  }
4446
4554
  }
4447
4555
 
4556
+ char uuid[1024];
4557
+ sprintf(uuid, "%.*s", call->inv->dlg->call_id->id.slen, call->inv->dlg->call_id->id.ptr);
4558
+
4448
4559
  if (NOT_FOUND_OPTIONAL == res) {
4449
4560
  // start on all audio media endpoints
4450
4561
  for (int i = 0; i < call->media_count; i++) {
4451
4562
  MediaEndpoint *me = (MediaEndpoint *)call->media[i];
4452
4563
  if (me->type == ENDPOINT_TYPE_AUDIO) {
4453
4564
  AudioEndpoint *ae = (AudioEndpoint *)me->endpoint.audio;
4454
- status = audio_endpoint_start_speech_recog(call, ae, server_url, engine, language);
4565
+ status = audio_endpoint_start_speech_recog(call, ae, server_url, uuid, engine, language);
4455
4566
  if (status != PJ_SUCCESS) goto out;
4456
4567
  }
4457
4568
  }
@@ -4469,7 +4580,7 @@ int pjw_call_start_speech_recog(long call_id, const char *json) {
4469
4580
 
4470
4581
  ae = (AudioEndpoint *)me->endpoint.audio;
4471
4582
 
4472
- audio_endpoint_start_speech_recog(call, ae, server_url, engine, language);
4583
+ audio_endpoint_start_speech_recog(call, ae, server_url, uuid, engine, language);
4473
4584
  }
4474
4585
 
4475
4586
  out:
@@ -4580,7 +4691,7 @@ out:
4580
4691
  return 0;
4581
4692
  }
4582
4693
 
4583
- pj_status_t audio_endpoint_start_bfsk_detection(Call *call, AudioEndpoint *ae, const int freq_zero, const int freq_one, const int min_level, const int baud_rate) {
4694
+ pj_status_t audio_endpoint_start_bfsk_detection(Call *call, AudioEndpoint *ae, const int freq_zero, const int freq_one) {
4584
4695
  pj_status_t status;
4585
4696
 
4586
4697
  if(!ae->stream_cbp.port) {
@@ -4588,7 +4699,7 @@ pj_status_t audio_endpoint_start_bfsk_detection(Call *call, AudioEndpoint *ae, c
4588
4699
  return -1;
4589
4700
  }
4590
4701
 
4591
- if(!prepare_bfsk_det(call, ae, freq_zero, freq_one, min_level, baud_rate)) {
4702
+ if(!prepare_bfsk_det(call, ae, freq_zero, freq_one)) {
4592
4703
  return -1;
4593
4704
  }
4594
4705
 
@@ -4614,14 +4725,12 @@ int pjw_call_start_bfsk_detection(long call_id, const char *json) {
4614
4725
 
4615
4726
  int freq_zero;
4616
4727
  int freq_one;
4617
- int min_level;
4618
- int baud_rate;
4619
4728
 
4620
4729
  char buffer[MAX_JSON_INPUT];
4621
4730
 
4622
4731
  Document document;
4623
4732
 
4624
- const char *valid_params[] = {"freq_zero", "freq_one", "min_level", "baud_rate", "media_id", ""};
4733
+ const char *valid_params[] = {"freq_zero", "freq_one", "media_id", ""};
4625
4734
 
4626
4735
  if (!g_call_ids.get(call_id, val)) {
4627
4736
  set_error("Invalid call_id");
@@ -4654,16 +4763,6 @@ int pjw_call_start_bfsk_detection(long call_id, const char *json) {
4654
4763
  goto out;
4655
4764
  }
4656
4765
 
4657
- res = json_get_int_param(document, "min_level", false, &min_level);
4658
- if (res <= 0) {
4659
- goto out;
4660
- }
4661
-
4662
- res = json_get_int_param(document, "baud_rate", false, &baud_rate);
4663
- if (res <= 0) {
4664
- goto out;
4665
- }
4666
-
4667
4766
  res = json_get_int_param(document, "media_id", true, &media_id);
4668
4767
  if (res <= 0) {
4669
4768
  goto out;
@@ -4674,7 +4773,7 @@ int pjw_call_start_bfsk_detection(long call_id, const char *json) {
4674
4773
  MediaEndpoint *me = (MediaEndpoint *)call->media[i];
4675
4774
  if (me->type == ENDPOINT_TYPE_AUDIO) {
4676
4775
  AudioEndpoint *ae = (AudioEndpoint *)me->endpoint.audio;
4677
- status = audio_endpoint_start_bfsk_detection(call, ae, freq_zero, freq_one, min_level, baud_rate);
4776
+ status = audio_endpoint_start_bfsk_detection(call, ae, freq_zero, freq_one);
4678
4777
  if (status != PJ_SUCCESS) goto out;
4679
4778
  }
4680
4779
  }
@@ -4692,7 +4791,7 @@ int pjw_call_start_bfsk_detection(long call_id, const char *json) {
4692
4791
 
4693
4792
  ae = (AudioEndpoint *)me->endpoint.audio;
4694
4793
 
4695
- audio_endpoint_start_bfsk_detection(call, ae, freq_zero, freq_one, min_level, baud_rate);
4794
+ audio_endpoint_start_bfsk_detection(call, ae, freq_zero, freq_one);
4696
4795
  }
4697
4796
 
4698
4797
  out:
@@ -7488,7 +7587,7 @@ bool prepare_dtmfdet(Call *call, AudioEndpoint *ae) {
7488
7587
  return connect_feature_port_to_stream_port(call, ae, fp);
7489
7588
  }
7490
7589
 
7491
- bool prepare_bfsk_det(Call *call, AudioEndpoint *ae, const int freq_zero, const int freq_one, const int min_level, const int baud_rate) {
7590
+ bool prepare_bfsk_det(Call *call, AudioEndpoint *ae, const int freq_zero, const int freq_one) {
7492
7591
  printf("DEBUG prepare_bfsk_det\n");
7493
7592
  pj_status_t status;
7494
7593
 
@@ -7505,7 +7604,7 @@ bool prepare_bfsk_det(Call *call, AudioEndpoint *ae, const int freq_zero, const
7505
7604
  PJMEDIA_PIA_CCNT(&ae->stream_cbp.port->info),
7506
7605
  PJMEDIA_PIA_SPF(&ae->stream_cbp.port->info),
7507
7606
  PJMEDIA_PIA_BITS(&ae->stream_cbp.port->info),
7508
- on_bfsk_bit, call, freq_zero, freq_one, min_level, baud_rate, &fp->port);
7607
+ on_bfsk_bit, call, freq_zero, freq_one, &fp->port);
7509
7608
  if (status != PJ_SUCCESS) {
7510
7609
  set_error("pjmedia_bfsk_det_create failed");
7511
7610
  return false;
@@ -7552,7 +7651,7 @@ bool prepare_fax(Call *call, AudioEndpoint *ae, bool is_sender, const char *file
7552
7651
  return connect_feature_port_to_stream_port(call, ae, fp);
7553
7652
  }
7554
7653
 
7555
- bool prepare_speech_synth(Call *call, AudioEndpoint *ae, const char *server_url, const char *engine, const char *voice, const char *language, const char *text, int times) {
7654
+ bool prepare_speech_synth(Call *call, AudioEndpoint *ae, const char *server_url, const char *uuid, const char *engine, const char *voice, const char *language, const char *text, int times) {
7556
7655
  pj_status_t status;
7557
7656
 
7558
7657
  ConfBridgePort *fp = &ae->feature_cbps[FP_SPEECH_SYNTH];
@@ -7607,6 +7706,7 @@ bool prepare_speech_synth(Call *call, AudioEndpoint *ae, const char *server_url,
7607
7706
  PJMEDIA_PIA_BITS(&ae->stream_cbp.port->info),
7608
7707
  g_ws_endpt,
7609
7708
  server_url,
7709
+ uuid,
7610
7710
  engine,
7611
7711
  voice,
7612
7712
  language,
@@ -7640,7 +7740,7 @@ bool prepare_speech_synth(Call *call, AudioEndpoint *ae, const char *server_url,
7640
7740
  return PJ_SUCCESS;
7641
7741
  }
7642
7742
 
7643
- bool prepare_speech_recog(Call *call, AudioEndpoint *ae, const char *server_url, const char *engine, const char *language) {
7743
+ bool prepare_speech_recog(Call *call, AudioEndpoint *ae, const char *server_url, const char *uuid, const char *engine, const char *language) {
7644
7744
  pj_status_t status;
7645
7745
 
7646
7746
  ConfBridgePort *fp = &ae->feature_cbps[FP_SPEECH_RECOG];
@@ -7672,6 +7772,7 @@ bool prepare_speech_recog(Call *call, AudioEndpoint *ae, const char *server_url,
7672
7772
  PJMEDIA_PIA_BITS(&ae->stream_cbp.port->info),
7673
7773
  g_ws_endpt,
7674
7774
  server_url,
7775
+ uuid,
7675
7776
  NULL,
7676
7777
  NULL,
7677
7778
  NULL,
@@ -8262,7 +8363,7 @@ bool notify(pjsip_evsub *evsub, const char *content_type, const char *body,
8262
8363
  }
8263
8364
  s_content_type_subtype = pj_str(tok);
8264
8365
 
8265
- if (!add_headers(tdata->pool, tdata, document)) {
8366
+ if (!add_headers(tdata->pool, tdata, document, NULL)) {
8266
8367
  return false;
8267
8368
  }
8268
8369
 
@@ -8439,7 +8540,7 @@ out:
8439
8540
  }
8440
8541
 
8441
8542
  pj_bool_t add_headers(pj_pool_t *pool, pjsip_tx_data *tdata,
8442
- Document &document) {
8543
+ Document &document, pjsip_dialog *dlg) {
8443
8544
  if (!document.HasMember("headers")) {
8444
8545
  return PJ_TRUE;
8445
8546
  }
@@ -8459,24 +8560,34 @@ pj_bool_t add_headers(pj_pool_t *pool, pjsip_tx_data *tdata,
8459
8560
  }
8460
8561
  printf("%s => '%s'\n", itr->name.GetString(), itr->value.GetString());
8461
8562
 
8462
- const char *name = itr->name.GetString();
8463
- if (!itr->value.IsString()) {
8464
- set_error("Parameter headers key '%s' found with non-string value", name);
8465
- return PJ_FALSE;
8466
- }
8563
+ if(stricmp(itr->name.GetString(), "call-id") == 0) {
8564
+ printf("Setting INVIITE call_id->id to %s\n", itr->value.GetString());
8565
+ pjsip_cid_hdr *call_id_hdr = (pjsip_cid_hdr*) pjsip_msg_find_hdr(tdata->msg, PJSIP_H_CALL_ID, NULL);
8566
+ pj_strdup2(tdata->pool, &call_id_hdr->id, itr->value.GetString());
8567
+ if(dlg) {
8568
+ printf("Setting DLG call_id->id to %s\n", itr->value.GetString());
8569
+ pj_strdup2(dlg->pool, &dlg->call_id->id, itr->value.GetString());
8570
+ }
8571
+ } else {
8572
+ const char *name = itr->name.GetString();
8573
+ if (!itr->value.IsString()) {
8574
+ set_error("Parameter headers key '%s' found with non-string value", name);
8575
+ return PJ_FALSE;
8576
+ }
8467
8577
 
8468
- const char *value = itr->value.GetString();
8578
+ const char *value = itr->value.GetString();
8469
8579
 
8470
- pj_str_t hname = pj_str((char *)name);
8471
- pjsip_hdr *hdr = (pjsip_hdr *)pjsip_parse_hdr(pool, &hname, (char *)value,
8472
- strlen(value), NULL);
8580
+ pj_str_t hname = pj_str((char *)name);
8581
+ pjsip_hdr *hdr = (pjsip_hdr *)pjsip_parse_hdr(pool, &hname, (char *)value,
8582
+ strlen(value), NULL);
8473
8583
 
8474
- if (!hdr) {
8475
- set_error("Failed to parse header '%s' => '%s'", name, value);
8476
- return PJ_FALSE;
8584
+ if (!hdr) {
8585
+ set_error("Failed to parse header '%s' => '%s'", name, value);
8586
+ return PJ_FALSE;
8587
+ }
8588
+ pjsip_hdr *clone_hdr = (pjsip_hdr *)pjsip_hdr_clone(pool, hdr);
8589
+ pjsip_msg_add_hdr(tdata->msg, clone_hdr);
8477
8590
  }
8478
- pjsip_hdr *clone_hdr = (pjsip_hdr *)pjsip_hdr_clone(pool, hdr);
8479
- pjsip_msg_add_hdr(tdata->msg, clone_hdr);
8480
8591
  }
8481
8592
  return PJ_TRUE;
8482
8593
  }
@@ -8823,7 +8934,7 @@ bool subscription_subscribe(Subscription *s, int expires, Document &document) {
8823
8934
  return false;
8824
8935
  }
8825
8936
 
8826
- if (!add_headers(s->dlg->pool, tdata, document)) {
8937
+ if (!add_headers(s->dlg->pool, tdata, document, NULL)) {
8827
8938
  return false;
8828
8939
  }
8829
8940
 
@@ -9106,6 +9217,18 @@ void check_digit_buffer(Call *call, int mode) {
9106
9217
  *pLen = 0;
9107
9218
  ae->last_digit_timestamp[mode] = 0;
9108
9219
  }
9220
+ }
9221
+ }
9222
+
9223
+ void check_bit_buffer(Call *call) {
9224
+ char evt[1024];
9225
+
9226
+ for (int i = 0; i < call->media_count; i++) {
9227
+ MediaEndpoint *me = (MediaEndpoint *)call->media[i];
9228
+ if (ENDPOINT_TYPE_AUDIO != me->type)
9229
+ continue;
9230
+
9231
+ AudioEndpoint *ae = (AudioEndpoint *)me->endpoint.audio;
9109
9232
 
9110
9233
  if (ae->last_bit_timestamp > 0 &&
9111
9234
  g_now - ae->last_bit_timestamp > g_bfsk_inter_bit_timer) {
@@ -9118,11 +9241,12 @@ void check_digit_buffer(Call *call, int mode) {
9118
9241
  }
9119
9242
  }
9120
9243
 
9121
- void check_digit_buffers(long id, long val) {
9244
+ void check_buffers(long id, long val) {
9122
9245
  Call *call = (Call *)val;
9123
9246
 
9124
9247
  check_digit_buffer(call, DTMF_MODE_RFC2833);
9125
9248
  check_digit_buffer(call, DTMF_MODE_INBAND);
9249
+ check_bit_buffer(call);
9126
9250
  }
9127
9251
 
9128
9252
  static int digit_buffer_thread(void *arg) {
@@ -9137,7 +9261,7 @@ static int digit_buffer_thread(void *arg) {
9137
9261
  PJW_LOCK();
9138
9262
  if (g_dtmf_inter_digit_timer > 0) {
9139
9263
  g_now = ms_timestamp();
9140
- g_call_ids.iterate(check_digit_buffers);
9264
+ g_call_ids.iterate(check_buffers);
9141
9265
  }
9142
9266
  PJW_UNLOCK();
9143
9267