sip-lab 1.31.0 → 1.33.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.
Files changed (65) hide show
  1. package/README.md +5 -0
  2. package/binding.gyp +1 -0
  3. package/index.js +4 -5
  4. package/package.json +1 -1
  5. package/prebuilds/linux-x64/node.abi102.node +0 -0
  6. package/prebuilds/linux-x64/node.abi108.node +0 -0
  7. package/prebuilds/linux-x64/node.abi111.node +0 -0
  8. package/prebuilds/linux-x64/node.abi115.node +0 -0
  9. package/prebuilds/linux-x64/node.abi120.node +0 -0
  10. package/prebuilds/linux-x64/node.abi88.node +0 -0
  11. package/prebuilds/linux-x64/node.abi93.node +0 -0
  12. package/samples/100_calls.js +7 -4
  13. package/samples/16_audio_streams.js +1 -0
  14. package/samples/183_session_progress.js +1 -0
  15. package/samples/custom_call_id.js +1 -0
  16. package/samples/delayed_media.js +1 -0
  17. package/samples/four_audio_streams_two_refused.js +1 -0
  18. package/samples/g729.js +1 -0
  19. package/samples/media_fields.js +1 -0
  20. package/samples/mrcp_and_audio.js +1 -0
  21. package/samples/mrcp_and_audio.simplified_media.js +1 -0
  22. package/samples/multiple_audio_streams.js +1 -0
  23. package/samples/options.js +1 -0
  24. package/samples/pcma.js +1 -0
  25. package/samples/play_wav_and_speech_recog.bad_transcript.pcmu8000.js +1 -0
  26. package/samples/refer.js +1 -0
  27. package/samples/refuse_telephone_event.js +1 -0
  28. package/samples/register_no_expires.js +1 -0
  29. package/samples/register_subscribe.js +1 -0
  30. package/samples/reinvite_and_dtmf.js +1 -0
  31. package/samples/reinvite_audio_audio.js +1 -0
  32. package/samples/reinvite_with_hold_unhold.js +1 -0
  33. package/samples/rtp_and_srtp.js +1 -0
  34. package/samples/rtp_and_srtp.rtp_refused.js +1 -0
  35. package/samples/rtp_and_srtp.unbalanced_sdp_answer.js.future +1 -0
  36. package/samples/{send_and_receive_bfsk.js.future → send_and_receive_bfsk.js} +25 -27
  37. package/samples/send_and_receive_fax.js +1 -0
  38. package/samples/session_expires.update.js.future +1 -0
  39. package/samples/session_expires.update.with_sipjs-lab.js +64 -47
  40. package/samples/simple.js +1 -0
  41. package/samples/sip_cancel.js +1 -0
  42. package/samples/speech_synth_and_recog.speex16000.js +1 -0
  43. package/samples/srtp.js +1 -0
  44. package/samples/start_play_wav_with_end_of_file_event.js +1 -0
  45. package/samples/start_play_wav_with_no_loop.js +1 -0
  46. package/samples/stop_with_cleanup.js +134 -0
  47. package/samples/tcp.js +1 -0
  48. package/samples/text_to_speech.js +1 -0
  49. package/samples/tls.js +1 -0
  50. package/samples/two_audio_streams.js +1 -0
  51. package/samples/two_audio_streams.port_zero.js +1 -0
  52. package/samples_extra/ws_speech_server.bfsk.js +1 -0
  53. package/samples_extra/ws_speech_server.dtmf.js +1 -0
  54. package/samples_extra/ws_speech_server.google.js +1 -0
  55. package/samples_extra/ws_speech_server.send_bfsk.js +1 -0
  56. package/samples_extra/{ws_speech_server.start_bfsk_detection.js.future → ws_speech_server.start_bfsk_detection.js} +1 -0
  57. package/src/addon.cpp +9 -1
  58. package/src/idmanager.cpp +4 -0
  59. package/src/idmanager.hpp +1 -0
  60. package/src/pjmedia/include/pjmedia/bfsk_det2.h +23 -0
  61. package/src/pjmedia/src/pjmedia/bfsk_det.c +124 -131
  62. package/src/pjmedia/src/pjmedia/bfsk_det2.c +226 -0
  63. package/src/pjmedia/src/pjmedia/ws_speech_port.cpp +16 -1
  64. package/src/sip.cpp +114 -108
  65. package/src/sip.hpp +1 -1
@@ -0,0 +1,226 @@
1
+ /* $Id: bfsk_det2.c 0000 2024-09-29 09:41:55Z mayamatakeshi $ */
2
+ /*
3
+ * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
4
+ * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
5
+ *
6
+ * This program is free software; you can redistribute it and/or modify
7
+ * it under the terms of the GNU General Public License as published by
8
+ * the Free Software Foundation; either version 2 of the License, or
9
+ * (at your option) any later version.
10
+ *
11
+ * This program is distributed in the hope that it will be useful,
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ * GNU General Public License for more details.
15
+ *
16
+ * You should have received a copy of the GNU General Public License
17
+ * along with this program; if not, write to the Free Software
18
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
+ */
20
+
21
+ #include <pjmedia/bfsk_det2.h>
22
+ #include <pjmedia/errno.h>
23
+ #include <pjmedia/port.h>
24
+ #include <pj/assert.h>
25
+ #include <pj/pool.h>
26
+ #include <pj/string.h>
27
+
28
+ #include <spandsp.h>
29
+ #include <spandsp/expose.h>
30
+ #include <spandsp/tone_detect.h>
31
+
32
+ #include <math.h>
33
+
34
+ #define SIGNATURE PJMEDIA_SIGNATURE('b', 'f', 'd', '2')
35
+ #define THIS_FILE "bfsk_det2.c"
36
+
37
+ #if 0
38
+ # define TRACE_(expr) PJ_LOG(4,expr)
39
+ #else
40
+ # define TRACE_(expr)
41
+ #endif
42
+
43
+ #include <stdio.h>
44
+ #include <stdlib.h>
45
+ #include <stdbool.h>
46
+
47
+ static pj_status_t bfsk_det2_put_frame(pjmedia_port *this_port,
48
+ pjmedia_frame *frame);
49
+ static pj_status_t bfsk_det2_on_destroy(pjmedia_port *this_port);
50
+
51
+ struct bfsk_det2
52
+ {
53
+ struct pjmedia_port base;
54
+ int clock_rate;
55
+ int freq_zero;
56
+ int freq_one;
57
+
58
+ int zero_in_progress;
59
+ int one_in_progress;
60
+
61
+ int32_t threshold;
62
+ int32_t energy;
63
+
64
+ goertzel_descriptor_t desc_zero;
65
+ goertzel_descriptor_t desc_one;
66
+
67
+ goertzel_state_t *goertzel_zero;
68
+ goertzel_state_t *goertzel_one;
69
+
70
+ void (*bfsk_cb)(pjmedia_port*, void*, int);
71
+ void *bfsk_cb_user_data;
72
+ };
73
+
74
+ #define DTMF_SAMPLES_PER_BLOCK 102
75
+
76
+ PJ_DEF(pj_status_t) pjmedia_bfsk_det2_create( pj_pool_t *pool,
77
+ unsigned clock_rate,
78
+ unsigned channel_count,
79
+ unsigned samples_per_frame,
80
+ unsigned bits_per_sample,
81
+ void (*cb)(pjmedia_port*,
82
+ void *user_data,
83
+ int bit),
84
+ void *user_data,
85
+ int freq_zero,
86
+ int freq_one,
87
+ pjmedia_port **p_port)
88
+ {
89
+ //printf("pjmedia_bfsk_det2_create\n");
90
+ struct bfsk_det2 *det;
91
+
92
+ const pj_str_t name = pj_str("bfsk_det2");
93
+
94
+ PJ_ASSERT_RETURN(pool && clock_rate && channel_count &&
95
+ samples_per_frame && bits_per_sample == 16 &&
96
+ p_port != NULL, PJ_EINVAL);
97
+
98
+ PJ_ASSERT_RETURN(pool && p_port, PJ_EINVAL);
99
+
100
+ det = PJ_POOL_ZALLOC_T(pool, struct bfsk_det2);
101
+ PJ_ASSERT_RETURN(pool != NULL, PJ_ENOMEM);
102
+
103
+ pjmedia_port_info_init(&det->base.info, &name, SIGNATURE, clock_rate,
104
+ channel_count, bits_per_sample, samples_per_frame);
105
+
106
+ det->base.put_frame = &bfsk_det2_put_frame;
107
+ det->base.on_destroy = &bfsk_det2_on_destroy;
108
+
109
+ det->bfsk_cb = cb;
110
+ det->bfsk_cb_user_data = user_data;
111
+
112
+ det->clock_rate = clock_rate;
113
+ det->freq_zero = freq_zero;
114
+ det->freq_one = freq_one;
115
+
116
+ make_goertzel_descriptor(&det->desc_zero, freq_zero, DTMF_SAMPLES_PER_BLOCK);
117
+ make_goertzel_descriptor(&det->desc_one, freq_one, DTMF_SAMPLES_PER_BLOCK);
118
+
119
+ goertzel_init(&det->goertzel_zero, &det->desc_zero);
120
+ goertzel_init(&det->goertzel_one, &det->desc_one);
121
+
122
+ int sample_rate = clock_rate;
123
+
124
+ //printf("bfsk_det2: clock_rate=%u channel_count=%u samples_per_frame=%u bits_per_frame=%u", clock_rate, channel_count, samples_per_frame, bits_per_sample);
125
+
126
+ goertzel_det_init(&det->goertzel_zero, det->freq_zero, sample_rate);
127
+ goertzel_det_init(&det->goertzel_one, det->freq_one, sample_rate);
128
+
129
+ *p_port = &det->base;
130
+ return PJ_SUCCESS;
131
+ }
132
+
133
+ static pj_status_t bfsk_det2_put_frame(pjmedia_port *this_port,
134
+ pjmedia_frame *frame)
135
+ {
136
+ //printf("bfsk_det2 put_frame\n");
137
+ if(frame->type != PJMEDIA_FRAME_TYPE_AUDIO) return PJ_SUCCESS;
138
+
139
+ struct bfsk_det2 *dport = (struct bfsk_det2*) this_port;
140
+
141
+ int size = frame->size;
142
+ int bps = PJMEDIA_PIA_BITS(&dport->base.info);
143
+
144
+ //printf("p=%x, size=%i clock_rate=%i bits_per_sample=%i\n", frame->buf, size, dport->clock_rate, bps);
145
+
146
+ int16_t * samples = (int16_t*)frame->buf;
147
+ int16_t * num_samples = frame->size/2;
148
+
149
+ /*
150
+ printf("Buffer contents:\n");
151
+ for (int i = 0; i < size; i++) {
152
+ printf("%02x", samples[i] & 0xFF);
153
+ printf("%02x", samples[i] >> 8 & 0xFF);
154
+ }
155
+ printf("\n");
156
+ */
157
+
158
+ #if defined(SPANDSP_USE_FIXED_POINT)
159
+ int32_t row_energy[4];
160
+ int32_t col_energy[4];
161
+ int16_t xamp;
162
+ float famp;
163
+ #else
164
+ float row_energy[4];
165
+ float col_energy[4];
166
+ float xamp;
167
+ float famp;
168
+ #endif
169
+
170
+ float v1;
171
+ int i;
172
+ int j;
173
+ int sample;
174
+ int limit;
175
+ uint8_t hit;
176
+
177
+ for (sample = 0; sample < num_samples; sample = limit)
178
+ {
179
+ limit = num_samples;
180
+ for (j = sample; j < limit; j++)
181
+ {
182
+ xamp = samples[j];
183
+ xamp = goertzel_preadjust_amp(xamp);
184
+ #if defined(SPANDSP_USE_FIXED_POINT)
185
+ dport->energy += ((int32_t) xamp*xamp);
186
+ #else
187
+ dport->energy += xamp*xamp;
188
+ #endif
189
+ goertzel_samplex(&dport->goertzel_zero, xamp);
190
+ goertzel_samplex(&dport->goertzel_one, xamp);
191
+ }
192
+ }
193
+ int32_t zero_power = goertzel_result(&dport->goertzel_zero);
194
+ int32_t one_power = goertzel_result(&dport->goertzel_one);
195
+
196
+ int zero = zero_power > dport->threshold;
197
+ int one = one_power > dport->threshold;
198
+
199
+ printf("zero_power=%f zero_in_progress=%i zero=%i threshold=%f\n", zero_power, dport->zero_in_progress, zero, dport->threshold);
200
+ printf(" one_power=%f one_in_progress=%i one=%i threshold=%f\n", one_power, dport->one_in_progress, one, dport->threshold);
201
+
202
+ // Check for zero signal extinction
203
+ if(dport->zero_in_progress && zero == 0) {
204
+ printf("notifying bit=0\n");
205
+ dport->bfsk_cb((pjmedia_port*)dport, dport->bfsk_cb_user_data, 0);
206
+ dport->zero_in_progress = 0;
207
+ } else {
208
+ dport->zero_in_progress = zero;
209
+ }
210
+
211
+ // Check for one signal extinction
212
+ if(dport->one_in_progress && one == 0) {
213
+ printf("notifying bit=1\n");
214
+ dport->bfsk_cb((pjmedia_port*)dport, dport->bfsk_cb_user_data, 1);
215
+ dport->one_in_progress = 0;
216
+ } else {
217
+ dport->one_in_progress = one;
218
+ }
219
+
220
+ return PJ_SUCCESS;
221
+ }
222
+
223
+ static pj_status_t bfsk_det2_on_destroy(pjmedia_port *this_port)
224
+ {
225
+ return PJ_SUCCESS;
226
+ }
@@ -338,10 +338,25 @@ PJ_DEF(pj_status_t) pjmedia_ws_speech_port_create(pj_pool_t *pool,
338
338
  }
339
339
 
340
340
  static pj_status_t put_frame(pjmedia_port *this_port, pjmedia_frame *frame) {
341
+ printf("ws_speech_port put_frame\n");
341
342
  if(frame->type != PJMEDIA_FRAME_TYPE_AUDIO) return PJ_SUCCESS;
342
343
 
343
344
  struct ws_speech_t *port = (struct ws_speech_t*) this_port;
344
345
 
346
+ int size = PJMEDIA_PIA_SPF(&port->base.info);
347
+ int bps = PJMEDIA_PIA_BITS(&port->base.info);
348
+
349
+ printf("p=%x, size=%i bits_per_sample=%i\n", frame->buf, size, bps);
350
+
351
+ int16_t * samples = (int16_t*)frame->buf;
352
+
353
+ printf("Buffer contents:\n");
354
+ for (int i = 0; i < size; i++) {
355
+ printf("%02x", samples[i] & 0xFF);
356
+ printf("%02x", samples[i] >> 8 & 0xFF);
357
+ }
358
+ printf("\n");
359
+
345
360
  if(port->wc && port->connected) {
346
361
  pj_websock_send(port->wc, PJ_WEBSOCK_OP_BIN, PJ_TRUE, PJ_TRUE, frame->buf, frame->size);
347
362
  }
@@ -364,7 +379,7 @@ static pj_status_t get_frame(pjmedia_port *this_port, pjmedia_frame *frame) {
364
379
  int len = PJMEDIA_PIA_SPF(&this_port->info)*2;
365
380
 
366
381
  if(port->buffering_count >= MINIMAl_BUFFERING && port->buffer_top > 0 && port->buffer_top >= len) {
367
- printf("get_frame top=%i\n", port->buffer_top);
382
+ //printf("get_frame top=%i\n", port->buffer_top);
368
383
  memcpy(frame->buf, port->buffer, len);
369
384
  port->buffer_top -= len;
370
385
  memcpy(port->buffer, port->buffer + len, port->buffer_top);
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 = 200;
270
+ int g_bfsk_inter_bit_timer = 50;
271
271
 
272
272
  pj_str_t g_sip_ipaddress;
273
273
 
@@ -6641,120 +6641,126 @@ int pjw_enable_telephone_event() {
6641
6641
  return 0;
6642
6642
  }
6643
6643
 
6644
- int __pjw_shutdown() {
6645
- // addon_log(L_DBG, "pjw_shutdown thread_id=%i\n", syscall(SYS_gettid));
6646
- PJW_LOCK();
6647
-
6648
- g_shutting_down = true;
6649
-
6650
- // disable auto cleanup
6651
-
6652
- /*
6653
- map<long, long>::iterator iter;
6654
- iter = g_call_ids.id_map.begin();
6655
- while(iter != g_call_ids.id_map.end()){
6656
- Call *call = (Call*)iter->second;
6657
-
6658
- addon_log(L_DBG, "Terminating call %d\n", iter->first);
6659
-
6660
- pjsip_tx_data *tdata;
6661
- pj_status_t status;
6662
- status = pjsip_inv_end_session(call->inv,
6663
- 603,
6664
- NULL,
6665
- &tdata); //Copied from pjsua
6666
- if(status != PJ_SUCCESS){
6667
- //ignore
6668
- char err[256];
6669
- pj_strerror(status, err, sizeof(err));
6670
- addon_log(L_DBG, "pjsip_inv_end_session failed statut=%i
6671
- (%s)\n", status, err);
6672
- ++iter;
6673
- continue;
6674
- }
6675
-
6676
- if(!tdata)
6677
- {
6678
- //if tdata was not set by pjsip_inv_end_session, it means
6679
- we didn't receive any response yet (100 Trying) and we cannot send CANCEL
6680
- in this situation. So we just can return here without calling
6681
- pjsip_inv_send_msg.
6682
- ++iter;
6683
- addon_log(L_DBG, "no tdata\n");
6684
- continue;
6685
- }
6686
-
6687
- status = pjsip_inv_send_msg(call->inv, tdata);
6688
- if(status != PJ_SUCCESS){
6689
- addon_log(L_DBG, "pjsip_inv_send_msg failed\n");
6690
- }
6691
- ++iter;
6692
- }
6693
-
6694
- iter = g_account_ids.id_map.begin();
6695
- while(iter != g_account_ids.id_map.end()){
6696
- pjsip_regc *regc = (pjsip_regc*)iter->second;
6697
-
6698
- addon_log(L_DBG, "Unregistering account %d\n", iter->first);
6699
-
6700
- pjsip_tx_data *tdata;
6701
- pj_status_t status;
6702
-
6703
- status = pjsip_regc_unregister(regc, &tdata);
6704
- if(status != PJ_SUCCESS)
6705
- {
6706
- addon_log(L_DBG, "pjsip_regc_unregister failed\n");
6707
- }
6708
-
6709
- status = pjsip_regc_send(regc, tdata);
6710
- if(status != PJ_SUCCESS)
6711
- {
6712
- addon_log(L_DBG, "pjsip_regc_send failed\n");
6713
- }
6714
- ++iter;
6715
- }
6644
+ int __pjw_shutdown(int clean_up) {
6645
+ //addon_log(L_DBG, "pjw_shutdown thread_id=%i\n", syscall(SYS_gettid));
6716
6646
 
6717
- Subscription *subscription;
6718
- iter = g_subscription_ids.id_map.begin();
6719
- while(iter != g_subscription_ids.id_map.end()){
6720
- addon_log(L_DBG, "Unsubscribing subscription %d\n", iter->first);
6647
+ g_shutting_down = true;
6721
6648
 
6722
- subscription = (Subscription*)iter->second;
6723
- if(!subscription_subscribe(subscription, 0, NULL)) {
6724
- addon_log(L_DBG, "Unsubscription failed failed\n");
6725
- }
6726
- ++iter;
6727
- }
6728
-
6729
- PJW_UNLOCK();
6730
-
6731
- //uint32_t wait = 100000 * (g_call_ids.id_map.size() +
6732
- g_account_ids.id_map.size()));
6733
- //wait += 1000000; //Wait one whole second to permit packet capture to get
6734
- any final packets
6735
-
6736
- timeval tv_start;
6737
- timeval tv_end;
6738
- gettimeofday(&tv_start, NULL);
6739
- gettimeofday(&tv_end, NULL);
6649
+ if(!clean_up) {
6650
+ return 0;
6651
+ }
6740
6652
 
6741
- unsigned int start = tv_start.tv_sec * 1000 + (tv_start.tv_usec / 1000);
6742
- unsigned int end = tv_end.tv_sec * 1000 + (tv_end.tv_usec / 1000);
6653
+ addon_log(L_DBG, "INITIATING CLEANUP\n");
6743
6654
 
6744
- int DELAY = 2000; // 1000 ms delay
6745
- while(end - start < DELAY) {
6746
- pj_time_val tv = {0, 500};
6747
- pj_status_t status;
6748
- status = pjsip_endpt_handle_events(g_sip_endpt, &tv);
6655
+ PJW_LOCK();
6749
6656
 
6750
- gettimeofday(&tv_end, NULL);
6751
- end = tv_end.tv_sec * 1000 + (tv_end.tv_usec / 1000);
6752
- //time(&end);
6753
- }
6657
+ map<long, long>::iterator iter;
6658
+ iter = g_call_ids.id_map.begin();
6659
+ while(iter != g_call_ids.id_map.end()){
6660
+ Call *call = (Call*)iter->second;
6661
+
6662
+ addon_log(L_DBG, "Terminating call %d\n", iter->first);
6663
+
6664
+ pjsip_tx_data *tdata;
6665
+ pj_status_t status;
6666
+ status = pjsip_inv_end_session(call->inv,
6667
+ 603,
6668
+ NULL,
6669
+ &tdata); //Copied from pjsua
6670
+ if(status != PJ_SUCCESS){
6671
+ //ignore
6672
+ char err[256];
6673
+ pj_strerror(status, err, sizeof(err));
6674
+ addon_log(L_DBG, "pjsip_inv_end_session failed statut=%i (%s)\n", status, err);
6675
+ ++iter;
6676
+ continue;
6677
+ }
6678
+
6679
+ if(!tdata)
6680
+ {
6681
+ //if tdata was not set by pjsip_inv_end_session, it means we didn't receive any response yet (100 Trying) and we cannot send CANCEL in this situation. So we just can return here without calling pjsip_inv_send_msg.
6682
+ ++iter;
6683
+ addon_log(L_DBG, "no tdata\n");
6684
+ continue;
6685
+ }
6686
+
6687
+ status = pjsip_inv_send_msg(call->inv, tdata);
6688
+ if(status != PJ_SUCCESS){
6689
+ addon_log(L_DBG, "pjsip_inv_send_msg failed\n");
6690
+ }
6691
+ ++iter;
6692
+ }
6693
+
6694
+ iter = g_account_ids.id_map.begin();
6695
+ while(iter != g_account_ids.id_map.end()){
6696
+ pjsip_regc *regc = (pjsip_regc*)iter->second;
6697
+
6698
+ addon_log(L_DBG, "Unregistering account %d\n", iter->first);
6699
+
6700
+ pjsip_tx_data *tdata;
6701
+ pj_status_t status;
6702
+
6703
+ status = pjsip_regc_unregister(regc, &tdata);
6704
+ if(status != PJ_SUCCESS)
6705
+ {
6706
+ addon_log(L_DBG, "pjsip_regc_unregister failed\n");
6707
+ }
6708
+
6709
+ status = pjsip_regc_send(regc, tdata);
6710
+ if(status != PJ_SUCCESS)
6711
+ {
6712
+ addon_log(L_DBG, "pjsip_regc_send failed\n");
6713
+ }
6714
+ ++iter;
6715
+ }
6716
+
6717
+ Subscription *subscription;
6718
+ iter = g_subscription_ids.id_map.begin();
6719
+
6720
+ rapidjson::Document doc;
6721
+ doc.Parse("{\"expires\": 0}");
6722
+
6723
+ while(iter != g_subscription_ids.id_map.end()){
6724
+ addon_log(L_DBG, "Unsubscribing subscription %d\n", iter->first);
6725
+
6726
+ subscription = (Subscription*)iter->second;
6727
+ if(!subscription_subscribe(subscription, 0, doc)) {
6728
+ addon_log(L_DBG, "Unsubscription failed failed\n");
6729
+ }
6730
+ ++iter;
6731
+ }
6754
6732
 
6755
- */
6733
+ PJW_UNLOCK();
6756
6734
 
6757
- return 0;
6735
+ //uint32_t wait = 100000 * (g_call_ids.id_map.size() + g_account_ids.id_map.size()));
6736
+ //wait += 1000000; //Wait one whole second to permit packet capture to get any final packets
6737
+
6738
+ /*
6739
+ time_t end,start;
6740
+ time(&start);
6741
+ end = start;
6742
+ */
6743
+ timeval tv_start;
6744
+ timeval tv_end;
6745
+ gettimeofday(&tv_start, NULL);
6746
+ gettimeofday(&tv_end, NULL);
6747
+
6748
+ unsigned int start = tv_start.tv_sec * 1000 + (tv_start.tv_usec / 1000);
6749
+ unsigned int end = tv_end.tv_sec * 1000 + (tv_end.tv_usec / 1000);
6750
+
6751
+ int DELAY = 1000; // 1000 ms delay
6752
+ while(end - start < DELAY) {
6753
+ pj_time_val tv = {0, 500};
6754
+ pj_status_t status;
6755
+ status = pjsip_endpt_handle_events(g_sip_endpt, &tv);
6756
+
6757
+ gettimeofday(&tv_end, NULL);
6758
+ end = tv_end.tv_sec * 1000 + (tv_end.tv_usec / 1000);
6759
+ //time(&end);
6760
+ }
6761
+
6762
+ addon_log(L_DBG, "CLEANUP DONE\n");
6763
+ return 0;
6758
6764
  }
6759
6765
 
6760
6766
  // Copied from streamutil.c (pjsip sample)
package/src/sip.hpp CHANGED
@@ -92,7 +92,7 @@ int pjw_get_codecs(char *out_codecs);
92
92
 
93
93
  int pjw_set_codecs(const char *in_codec_info);
94
94
 
95
- int __pjw_shutdown();
95
+ int __pjw_shutdown(int clean_up);
96
96
 
97
97
  int pjw_notify(long subscriber_id, const char *json);
98
98