sip-lab 1.17.9 → 1.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -17,7 +17,6 @@ TODO:
17
17
  - add support for T.38 fax
18
18
  - add support for WebSocket
19
19
  - add support for WebRTC
20
- - add support for SRTP
21
20
  - add support for MSRP
22
21
 
23
22
  ### Installation
@@ -25,7 +24,7 @@ TODO:
25
24
  This is a node.js addon and it is known to work on Debian 11, Debian 10, Ubuntu 22.04 and Ubuntu 20.04.
26
25
  It is distributed with prebuild binaries for node.js 15.0.0 and above (but built for Debian 11. For other Debian versions or for Ubuntu a local build of the addon will be executed. Being the case, be patient as the build process will take several minutes to complete).
27
26
 
28
- To install it, first install some build dependencies (you might not need them if your are on Debian 11).
27
+ To install it, first install build dependencies:
29
28
  ```
30
29
  apt install build-essential automake autoconf libtool libspeex-dev libopus-dev libsdl2-dev libavdevice-dev libswscale-dev libv4l-dev libopencore-amrnb-dev libopencore-amrwb-dev libvo-amrwbenc-dev libvo-amrwbenc-dev libboost-dev libtiff-dev libpcap-dev libssl-dev uuid-dev cmake
31
30
  ```
package/binding.gyp CHANGED
@@ -14,7 +14,6 @@
14
14
  "src",
15
15
  "src/pjmedia/include",
16
16
  "src/pjmedia/include/pjmedia",
17
- "src/pjmedia/include/chainlink",
18
17
  "3rdParty/rapidjson/include",
19
18
  "3rdParty/boost_1_51_0",
20
19
  "3rdParty/spandsp/src",
@@ -50,11 +49,11 @@
50
49
  '-l speex-x86_64-unknown-linux-gnu',
51
50
  '-l gsmcodec-x86_64-unknown-linux-gnu',
52
51
  '-l g7221codec-x86_64-unknown-linux-gnu',
53
- '-l resample-x86_64-unknown-linux-gnu',
54
52
  '-l pjmedia-audiodev-x86_64-unknown-linux-gnu',
53
+ '-l pjmedia-x86_64-unknown-linux-gnu',
54
+ '-l resample-x86_64-unknown-linux-gnu',
55
55
  '-l pjmedia-codec-x86_64-unknown-linux-gnu',
56
56
  '-l pjmedia-videodev-x86_64-unknown-linux-gnu',
57
- '-l pjmedia-x86_64-unknown-linux-gnu',
58
57
  '-l pjsdp-x86_64-unknown-linux-gnu',
59
58
  '-l pjsip-x86_64-unknown-linux-gnu',
60
59
  '-l pjsua2-x86_64-unknown-linux-gnu',
@@ -108,12 +107,8 @@
108
107
  'src/idmanager.cpp',
109
108
  'src/sip.cpp',
110
109
  'src/addon.cpp',
111
- 'src/pjmedia/src/chainlink/chainlink_dtmfdet.c',
112
- 'src/pjmedia/src/chainlink/chainlink_tonegen.c',
113
- 'src/pjmedia/src/chainlink/chainlink_wav_player.c',
114
- 'src/pjmedia/src/chainlink/chainlink_wav_writer.c',
115
- 'src/pjmedia/src/chainlink/chainlink_wire_port.c',
116
- 'src/pjmedia/src/chainlink/chainlink_fax.c',
110
+ 'src/pjmedia/src/pjmedia/dtmfdet.c',
111
+ 'src/pjmedia/src/pjmedia/fax_port.c',
117
112
  ],
118
113
  },
119
114
  ],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sip-lab",
3
- "version": "1.17.9",
3
+ "version": "1.18.0",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "engines": {
Binary file
@@ -0,0 +1,25 @@
1
+ #ifndef __FAX_PORT_H__
2
+ #define __FAX_PORT_H__
3
+
4
+ #include <pjmedia/port.h>
5
+
6
+ PJ_BEGIN_DECL
7
+
8
+ PJ_DECL(pj_status_t) pjmedia_fax_port_create( pj_pool_t *pool,
9
+ unsigned clock_rate,
10
+ unsigned channel_count,
11
+ unsigned samples_per_frame,
12
+ unsigned bits_per_sample,
13
+ void (*cb)(pjmedia_port*,
14
+ void *user_data,
15
+ int result),
16
+ void *user_data,
17
+ int is_sender,
18
+ const char *file,
19
+ unsigned flags,
20
+ pjmedia_port **p_port);
21
+
22
+
23
+ PJ_END_DECL
24
+
25
+ #endif /* __FAX_PORT_H__ */
@@ -20,13 +20,15 @@
20
20
 
21
21
  #include <pjmedia/dtmfdet.h>
22
22
  #include <pjmedia/errno.h>
23
+ #include <pjmedia/port.h>
23
24
  #include <pj/assert.h>
24
25
  #include <pj/pool.h>
25
26
  #include <pj/string.h>
26
27
 
27
28
  #include <spandsp.h>
29
+ #include <spandsp/expose.h>
28
30
 
29
- #define SIGNATURE PJMEDIA_PORT_SIGNATURE('d', 't', 'd', 't')
31
+ #define SIGNATURE PJMEDIA_SIGNATURE('d', 't', 'd', 't')
30
32
  #define THIS_FILE "dtmfdet.c"
31
33
 
32
34
  #if 0
@@ -36,12 +38,12 @@
36
38
  #endif
37
39
 
38
40
  static pj_status_t dtmfdet_put_frame(pjmedia_port *this_port,
39
- const pjmedia_frame *frame);
41
+ pjmedia_frame *frame);
40
42
  static pj_status_t dtmfdet_on_destroy(pjmedia_port *this_port);
41
43
 
42
44
  struct dtmfdet
43
45
  {
44
- pjmedia_port base;
46
+ struct pjmedia_port base;
45
47
  dtmf_rx_state_t state;
46
48
  void (*dtmf_cb)(pjmedia_port*, void*, char);
47
49
  void *dtmf_cb_user_data;
@@ -106,13 +108,13 @@ PJ_DEF(pj_status_t) pjmedia_dtmfdet_create( pj_pool_t *pool,
106
108
  }
107
109
 
108
110
  static pj_status_t dtmfdet_put_frame(pjmedia_port *this_port,
109
- const pjmedia_frame *frame)
111
+ pjmedia_frame *frame)
110
112
  {
111
113
  if(frame->type != PJMEDIA_FRAME_TYPE_AUDIO) return PJ_SUCCESS;
112
114
 
113
115
  struct dtmfdet *dport = (struct dtmfdet*) this_port;
114
116
  dtmf_rx(&dport->state, (const pj_int16_t*)frame->buf,
115
- dport->base.info.samples_per_frame);
117
+ PJMEDIA_PIA_SPF(&dport->base.info));
116
118
 
117
119
  return PJ_SUCCESS;
118
120
 
@@ -0,0 +1,278 @@
1
+
2
+ #include "fax_port.h"
3
+ #include <pjmedia/errno.h>
4
+ #include <pjmedia/port.h>
5
+ #include <pj/assert.h>
6
+ #include <pj/lock.h>
7
+ #include <pj/pool.h>
8
+ #include <pj/string.h>
9
+
10
+ #include "siplab_constants.h"
11
+
12
+ #define SPANDSP_EXPOSE_INTERNAL_STRUCTURES
13
+ #include <spandsp.h>
14
+
15
+ #define SIGNATURE PJMEDIA_SIGNATURE('f', 'a', 'x', 'p')
16
+ #define THIS_FILE "fax_port.c"
17
+
18
+ #if 0
19
+ # define TRACE_(expr) PJ_LOG(4,expr)
20
+ #else
21
+ # define TRACE_(expr)
22
+ #endif
23
+
24
+ #define FAX_DATA_CHUNK 320
25
+ #define T38_DATA_CHUNK 160
26
+
27
+ enum
28
+ {
29
+ /*! No compression */
30
+ T30_SUPPORT_NO_COMPRESSION = 0x01,
31
+ /*! T.1 1D compression */
32
+ T30_SUPPORT_T4_1D_COMPRESSION = 0x02,
33
+ /*! T.4 2D compression */
34
+ T30_SUPPORT_T4_2D_COMPRESSION = 0x04,
35
+ /*! T.6 2D compression */
36
+ T30_SUPPORT_T6_COMPRESSION = 0x08,
37
+ /*! T.85 monochrome JBIG compression */
38
+ T30_SUPPORT_T85_COMPRESSION = 0x10,
39
+ /*! T.43 colour JBIG compression */
40
+ T30_SUPPORT_T43_COMPRESSION = 0x20,
41
+ /*! T.45 run length colour compression */
42
+ T30_SUPPORT_T45_COMPRESSION = 0x40,
43
+ /*! T.81 + T.30 Annex E colour JPEG compression */
44
+ T30_SUPPORT_T81_COMPRESSION = 0x80,
45
+ /*! T.81 + T.30 Annex K colour sYCC-JPEG compression */
46
+ T30_SUPPORT_SYCC_T81_COMPRESSION = 0x100,
47
+ /*! T.88 monochrome JBIG2 compression */
48
+ T30_SUPPORT_T88_COMPRESSION = 0x200
49
+ };
50
+
51
+ static pj_status_t fax_get_frame(pjmedia_port *this_port,
52
+ pjmedia_frame *frame);
53
+ static pj_status_t fax_put_frame(pjmedia_port *this_port,
54
+ pjmedia_frame *frame);
55
+ static pj_status_t fax_on_destroy(pjmedia_port *this_port);
56
+
57
+ struct fax_device
58
+ {
59
+ struct pjmedia_port base;
60
+ fax_state_t fax;
61
+ void (*fax_cb)(pjmedia_port*, void*, int);
62
+ void *fax_cb_user_data;
63
+ int is_sender;
64
+ bool result_sent;
65
+
66
+ pj_lock_t *lock;
67
+ };
68
+
69
+ static int phase_b_handler(void* user_data, int result)
70
+ {
71
+ printf("fax phase_b_handler user_data=%p result=%i\n", user_data, result);
72
+ return T30_ERR_OK;
73
+ }
74
+
75
+ static int phase_d_handler(void* user_data, int result)
76
+ {
77
+ printf("fax phase_b_handler user_data=%p result=%i\n", user_data, result);
78
+ return T30_ERR_OK;
79
+ }
80
+
81
+ static void phase_e_handler(void* user_data, int result)
82
+ {
83
+ printf("fax phase_e_handler user_data=%p result=%i\n", user_data, result);
84
+
85
+ if (!user_data) {
86
+ printf("not user_data\n");
87
+ return;
88
+ }
89
+
90
+ struct fax_device *fd = (struct fax_device*)user_data;
91
+ if(!fd->fax_cb) {
92
+ printf("not fax_cb\n");
93
+ return;
94
+ }
95
+
96
+ if(!fd->result_sent) {
97
+ fd->fax_cb((pjmedia_port*)fd, fd->fax_cb_user_data, result);
98
+ fd->result_sent = true;
99
+ }
100
+ }
101
+
102
+ static int document_handler(void* user_data, int result)
103
+ {
104
+ printf("fax document_handler user_data=%p result=%i\n", user_data, result);
105
+
106
+ if (!user_data) return 0;
107
+
108
+ struct fax_device *fd = (struct fax_device*)user_data;
109
+ if(!fd->fax_cb) return 0;
110
+
111
+ if(!fd->result_sent) {
112
+ fd->fax_cb((pjmedia_port*)fd, fd->fax_cb_user_data, result);
113
+ fd->result_sent = true;
114
+ }
115
+
116
+ return 0;
117
+ }
118
+
119
+ PJ_DEF(pj_status_t) pjmedia_fax_port_create( pj_pool_t *pool,
120
+ unsigned clock_rate,
121
+ unsigned channel_count,
122
+ unsigned samples_per_frame,
123
+ unsigned bits_per_sample,
124
+ void (*cb)(pjmedia_port*,
125
+ void *user_data,
126
+ int result),
127
+ void *user_data,
128
+ int is_sender,
129
+ const char *file,
130
+ unsigned flags,
131
+ pjmedia_port **p_port)
132
+ {
133
+ struct fax_device *fd;
134
+ const pj_str_t name = pj_str("fax_device");
135
+
136
+ PJ_ASSERT_RETURN(pool && clock_rate && channel_count &&
137
+ samples_per_frame && bits_per_sample == 16 &&
138
+ p_port != NULL, PJ_EINVAL);
139
+
140
+ PJ_ASSERT_RETURN(pool && p_port, PJ_EINVAL);
141
+
142
+ fd = PJ_POOL_ZALLOC_T(pool, struct fax_device);
143
+ PJ_ASSERT_RETURN(pool != NULL, PJ_ENOMEM);
144
+
145
+ pjmedia_port_info_init(&fd->base.info, &name, SIGNATURE, clock_rate,
146
+ channel_count, bits_per_sample, samples_per_frame);
147
+
148
+ fd->base.get_frame = &fax_get_frame;
149
+ fd->base.put_frame = &fax_put_frame;
150
+ fd->base.on_destroy = &fax_on_destroy;
151
+
152
+ fax_init(&fd->fax, is_sender);
153
+
154
+ t30_state_t *t30 = fax_get_t30_state(&fd->fax);
155
+
156
+ span_log_set_level(fax_get_logging_state(&fd->fax), SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
157
+ span_log_set_level(t30_get_logging_state(t30), SPAN_LOG_SHOW_SEVERITY | SPAN_LOG_SHOW_PROTOCOL | SPAN_LOG_FLOW);
158
+
159
+ char ident[] = "fax_port";
160
+
161
+ t30_set_tx_ident(t30, ident);
162
+ t30_set_phase_b_handler(t30, &phase_b_handler, (void*)fd);
163
+ t30_set_phase_d_handler(t30, &phase_d_handler, (void*)fd);
164
+ t30_set_phase_e_handler(t30, &phase_e_handler, (void*)fd);
165
+ //printf("setting document_handler with user_data=%p\n", (void*)fd);
166
+ t30_set_document_handler(t30, &document_handler, (void*)fd);
167
+
168
+ fd->is_sender = is_sender;
169
+ fd->result_sent = false;
170
+
171
+ pj_status_t status = pj_lock_create_simple_mutex(pool, "fax", &fd->lock);
172
+
173
+ if (status != PJ_SUCCESS) {
174
+ printf("failed to create lock\n");
175
+ return status;
176
+ }
177
+
178
+ if (is_sender)
179
+ t30_set_tx_file(t30,file,-1,-1);
180
+ else
181
+ t30_set_rx_file(t30,file,-1);
182
+
183
+ t30_set_ecm_capability(t30,1);
184
+ t30_set_supported_compressions(t30,T30_SUPPORT_T4_1D_COMPRESSION |
185
+ T30_SUPPORT_T4_2D_COMPRESSION | T30_SUPPORT_T6_COMPRESSION);
186
+
187
+ if(flags & FAX_FLAG_TRANSMIT_ON_IDLE) {
188
+ fax_set_transmit_on_idle(&fd->fax, 1);
189
+ }
190
+
191
+ fd->fax_cb = cb;
192
+ fd->fax_cb_user_data = user_data;
193
+
194
+ TRACE_((THIS_FILE, "fax_device created: %u/%u/%u/%u", clock_rate,
195
+ channel_count, samples_per_frame, bits_per_sample));
196
+
197
+ *p_port = &fd->base;
198
+ return PJ_SUCCESS;
199
+ }
200
+
201
+ // called when pjmedia needs data to be sent out
202
+ static pj_status_t fax_get_frame(pjmedia_port *this_port,
203
+ pjmedia_frame *frame) {
204
+
205
+ //printf("ENTER fax_get_frame frame_size=%i\n", frame->size);
206
+
207
+ PJ_ASSERT_RETURN(this_port && frame, PJ_EINVAL);
208
+ char *p = (char*)frame->buf;
209
+
210
+ struct fax_device *fd = (struct fax_device*)this_port;
211
+ pj_lock_acquire(fd->lock);
212
+
213
+ int tx = 0;
214
+
215
+ if ((tx = fax_tx(&fd->fax, (int16_t *)frame->buf, frame->size/2)) < 0) {
216
+ printf("fax_tx reported an error\n");
217
+ pj_lock_release(fd->lock);
218
+ printf("EXIT fax_get_frame\n");
219
+ return PJ_FALSE;
220
+ }
221
+ pj_lock_release(fd->lock);
222
+
223
+ frame->type = PJMEDIA_FRAME_TYPE_AUDIO;
224
+ frame->timestamp.u64 = 0;
225
+
226
+ //printf("EXIT fax_get_frame\n");
227
+ return PJ_SUCCESS;
228
+ }
229
+
230
+ // called when pjmedia has received data
231
+ static pj_status_t fax_put_frame(pjmedia_port *this_port,
232
+ pjmedia_frame *frame)
233
+ {
234
+ if(frame->type != PJMEDIA_FRAME_TYPE_AUDIO) return PJ_SUCCESS;
235
+ //printf("ENTER fax_put_frame frame->buf=%x frame->size=%i\n", frame->buf, frame->size);
236
+
237
+ struct fax_device *fd = (struct fax_device*) this_port;
238
+ pj_lock_acquire(fd->lock);
239
+
240
+ unsigned int pos = 0;
241
+
242
+ while (pos < frame->size)
243
+ {
244
+ // feed the decoder with small chunks of data (16 bytes/ms)
245
+ int len = frame->size - pos;
246
+ if (len > FAX_DATA_CHUNK) len = FAX_DATA_CHUNK;
247
+
248
+ /* Pass the new incoming audio frame to the fax_rx function */
249
+ if (fax_rx(&fd->fax, (int16_t *)(frame->buf)+pos, len/2)) {
250
+ printf("fax_rx reported an error\n");
251
+ pj_lock_release(fd->lock);
252
+ printf("EXIT fax_put_frame\n");
253
+ return 0;
254
+ }
255
+
256
+ pos += len;
257
+ }
258
+
259
+ pj_lock_release(fd->lock);
260
+
261
+ return PJ_SUCCESS;
262
+ }
263
+
264
+ /*
265
+ * Destroy port.
266
+ */
267
+ static pj_status_t fax_on_destroy(pjmedia_port *this_port)
268
+ {
269
+ printf("fax_on_destroy\n");
270
+
271
+ struct fax_device *fd = (struct fax_device*)this_port;
272
+
273
+ fax_release(&fd->fax);
274
+
275
+ if(fd->lock) pj_lock_destroy(fd->lock);
276
+ return PJ_SUCCESS;
277
+ }
278
+