sip-lab 1.12.10 → 1.12.14

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/DEV.md ADDED
@@ -0,0 +1,30 @@
1
+ ### For devs
2
+
3
+ We build and statically link to libs pjproject, spandsp, bgc729 and rapidjson.
4
+
5
+ Basic tasks for development:
6
+
7
+ #### To build
8
+ ```
9
+ npm install
10
+ ```
11
+
12
+ #### To clean up (for a clean rebuild)
13
+ ```
14
+ npx node-gyp clean
15
+ ```
16
+
17
+ #### To update pjproject, spandsp, bcg729 or rapidjson
18
+ Just delete the corresponding library subfolder in subfolder 3drParty.
19
+
20
+
21
+ Then temporarily change install.sh to not checkout a specific version (or checkout a desired commit)
22
+
23
+ Then run
24
+ ```
25
+ npm install
26
+ ```
27
+
28
+ Then perform code changes and tests. When you are satisfied with them, update install.sh with the new commit id.
29
+
30
+
package/README.md CHANGED
@@ -25,12 +25,17 @@ apt install build-essential automake autoconf libtool libspeex-dev libopus-dev l
25
25
 
26
26
  Then install sip-lab by doing:
27
27
  ```
28
- npm install sip-lab
28
+ npm install sip-lab
29
29
  ```
30
30
 
31
31
  Be patient because we will need to download pjproject and build it.
32
32
 
33
- We will also download rapidjson.
33
+ We will also download and build spandsp, bcg729 and rapidjson.
34
+
35
+ However since it takes several minutes to build this module, you can install it globally:
36
+ ```
37
+ npm install -g sip-lab
38
+ ```
34
39
 
35
40
  To test from within this repo just build and install by doing:
36
41
  ```
@@ -49,9 +54,11 @@ It was originally developed with node v.10 and tested with v.12 and v16.13.1 and
49
54
  (it is known to not work with node v.8)
50
55
 
51
56
 
57
+
52
58
  ### About the code
53
59
 
54
60
  Although the code in written in *.cpp/*.hpp named files, this is not actually a C++ project.
55
61
 
56
62
  It is mostly written in C using some C++ facilities.
57
63
 
64
+
package/devjournal CHANGED
@@ -438,5 +438,12 @@ When rebuilding the addon, this should be enough (it should be fast):
438
438
  ```
439
439
  npm install --unsafe-perm
440
440
  ```
441
+ ------------------------------------------------------------
442
+ 2022/09/11 takeshi:
443
+
444
+ To try to solve #21, we upraded pjproject to commit 797088ed133c98492519b7d042b75735f6f9388c.
445
+ However, after doing it we verified sending CANCEL doesn't cause the other side to send '497 Request Terminated' by itself anymore (see samples/sip_cancel.js)
446
+
447
+
441
448
 
442
449
 
package/install.sh CHANGED
@@ -52,10 +52,8 @@ then
52
52
  git clone https://github.com/pjsip/pjproject
53
53
  cd pjproject
54
54
  #git checkout de3d744c2e1188b59bb907b6ee32ef83740ebc64
55
- git checkout 33a3c9e0a5eb84426edef05a9aa98af17d8011c3 # required for bcg729
56
-
57
- #echo "Patching sip_transaction.c to avoid problems with CANCEL"
58
- sed -i -r 's|event->body.tx_msg.tdata == tsx->last_tx,|\t\t\t1, /* \0 */|' pjsip/src/pjsip/sip_transaction.c
55
+ #git checkout 33a3c9e0a5eb84426edef05a9aa98af17d8011c3 # required for bcg729
56
+ git checkout 797088ed133c98492519b7d042b75735f6f9388c # updated as part of #21
59
57
 
60
58
  cat > user.mak <<EOF
61
59
  export CFLAGS += -fPIC -g
package/package.json CHANGED
@@ -1,13 +1,14 @@
1
1
  {
2
2
  "name": "sip-lab",
3
- "version": "1.12.10",
3
+ "version": "1.12.14",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "engines": {
7
7
  "node": ">=10.22"
8
8
  },
9
9
  "scripts": {
10
- "install": "./install.sh"
10
+ "install": "./install.sh",
11
+ "test": "./runtests"
11
12
  },
12
13
  "repository": {
13
14
  "type": "git",
@@ -3,6 +3,7 @@ var Zeq = require('@mayama/zeq')
3
3
  var z = new Zeq()
4
4
  var m = require('data-matching')
5
5
  var sip_msg = require('sip-matching')
6
+ var assert = require('assert')
6
7
 
7
8
  async function test() {
8
9
  //sip.set_log_level(6)
@@ -116,12 +117,14 @@ async function test() {
116
117
  msg: sip_msg({
117
118
  $rm: 'NOTIFY',
118
119
  '$hdr(Event)': 'dialog',
119
- '$hdr(Subscription-State)': 'active;expires=120',
120
+ '$hdr(Subscription-State)': 'active;expires=!{sub_expires}',
120
121
  '$hdr(Allow-Events)': 'refer, dialog',
121
122
  }),
122
123
  },
123
124
  ], 1000)
124
125
 
126
+ assert(parseInt(z.store.sub_expires) > 0)
127
+
125
128
  sip.account.unregister(a1)
126
129
 
127
130
  await z.wait([
@@ -87,6 +87,11 @@ async function test() {
87
87
  $rr: 'OK',
88
88
  }),
89
89
  },
90
+ ], 1000)
91
+
92
+ sip.call.respond(ic.id, {code: 487, reason: 'Request Terminated'})
93
+
94
+ await z.wait([
90
95
  {
91
96
  event: 'response',
92
97
  call_id: oc.id,
@@ -26,8 +26,11 @@ int make_evt_dtmf(char *dest, int size, long call_id, int digits_len, const char
26
26
  }
27
27
 
28
28
  int make_evt_call_ended(char *dest, int size, long call_id, int sip_msg_len, const char *sip_msg) {
29
- printf("sip_msg_len=%i sip_msg=%s\n", sip_msg_len, sip_msg);
30
- if(sip_msg_len > 500 && sip_msg_len < 2000 && sip_msg) {
29
+ printf("sip_msg_len=%i sip_msg=%x\n", sip_msg_len, sip_msg);
30
+ if(!sip_msg || sip_msg == (char*)0xc000000000000) {
31
+ // received invalid pointer to sip_msg so do not add the message to the event
32
+ return snprintf(dest, size, "{\"event\": \"call_ended\", \"call_id\": %ld}", call_id);
33
+ } else if(sip_msg_len > 500 && sip_msg_len < 2000 && sip_msg) {
31
34
  /* sip_msg_len sometimes show up as a large value like sip_msg_len=11560297 which seems to be a bug in pjsip */
32
35
  return snprintf(dest, size, "{\"event\": \"call_ended\", \"call_id\": %ld}\n%.*s", call_id, sip_msg_len, sip_msg);
33
36
  } else {
package/src/sip.cpp CHANGED
@@ -126,6 +126,33 @@ bool parse_json(Document &document, const char *json, char *buffer, long unsigne
126
126
  return true;
127
127
  }
128
128
 
129
+
130
+ bool param_is_valid(const char *param, const char **valid_params) {
131
+ char **valid_param = (char**)valid_params;
132
+ while(*valid_param[0]) {
133
+ //printf("checking param=%s valid_param=%s\n", param, *valid_param);
134
+ if(strcmp(param, *valid_param) == 0) {
135
+ return true;
136
+ }
137
+ valid_param++;
138
+ }
139
+ return false;
140
+ }
141
+
142
+ bool validate_params(Document &document, const char **valid_params) {
143
+ for (Value::ConstMemberIterator itr = document.MemberBegin();
144
+ itr != document.MemberEnd(); ++itr)
145
+ {
146
+ const char *param = itr->name.GetString();
147
+ if(!param_is_valid(param, valid_params)) {
148
+ set_error("Invalid param %s", param);
149
+ return false;
150
+ }
151
+ }
152
+
153
+ return true;
154
+ }
155
+
129
156
  bool json_get_string_param(Document &document, const char *param, bool optional, char **dest) {
130
157
  printf("json_get_string_param %s\n", param);
131
158
  if(!document.HasMember(param)) {
@@ -1078,11 +1105,17 @@ int pjw_transport_create(const char *json, int *out_t_id, char *out_t_address, i
1078
1105
 
1079
1106
  char buffer[MAX_JSON_INPUT];
1080
1107
 
1108
+ const char *valid_params[] = {"address", "port", "type", ""};
1109
+
1081
1110
  Document document;
1082
1111
 
1083
1112
  if(!parse_json(document, json, buffer, MAX_JSON_INPUT)) {
1084
1113
  goto out;
1085
1114
  }
1115
+
1116
+ if(!validate_params(document, valid_params)) {
1117
+ goto out;
1118
+ }
1086
1119
 
1087
1120
  // address
1088
1121
  if(!document.HasMember("address")) {
@@ -1301,6 +1334,8 @@ int pjw_account_create(int t_id, const char *json, int *out_acc_id)
1301
1334
 
1302
1335
  Document document;
1303
1336
 
1337
+ const char *valid_params[] = {"domain", "server", "username", "password", "to_url", "expires", "headers", ""};
1338
+
1304
1339
  if(!g_transport_ids.get(t_id, val)){
1305
1340
  set_error("Invalid transport id");
1306
1341
  goto out;
@@ -1310,6 +1345,10 @@ int pjw_account_create(int t_id, const char *json, int *out_acc_id)
1310
1345
  if(!parse_json(document, json, buffer, MAX_JSON_INPUT)) {
1311
1346
  goto out;
1312
1347
  }
1348
+
1349
+ if(!validate_params(document, valid_params)) {
1350
+ goto out;
1351
+ }
1313
1352
 
1314
1353
  if(!json_get_string_param(document, "domain", false, &domain)) {
1315
1354
  goto out;
@@ -1461,6 +1500,8 @@ int pjw_account_register(long acc_id, const char *json)
1461
1500
 
1462
1501
  Document document;
1463
1502
 
1503
+ const char *valid_params[] = {"auto_refresh", ""};
1504
+
1464
1505
  if(!g_account_ids.get(acc_id, val)){
1465
1506
  set_error("Invalid account_id");
1466
1507
  goto out;
@@ -1471,6 +1512,10 @@ int pjw_account_register(long acc_id, const char *json)
1471
1512
  goto out;
1472
1513
  }
1473
1514
 
1515
+ if(!validate_params(document, valid_params)) {
1516
+ goto out;
1517
+ }
1518
+
1474
1519
  if(!json_get_bool_param(document, "auto_refresh", true, &auto_refresh)) {
1475
1520
  goto out;
1476
1521
  }
@@ -1563,6 +1608,8 @@ int pjw_call_respond(long call_id, const char *json)
1563
1608
 
1564
1609
  Document document;
1565
1610
 
1611
+ const char *valid_params[] = {"code", "reason", "headers", ""};
1612
+
1566
1613
  if(!g_call_ids.get(call_id, val)){
1567
1614
  set_error("Invalid call_id");
1568
1615
  goto out;
@@ -1577,6 +1624,10 @@ int pjw_call_respond(long call_id, const char *json)
1577
1624
  if(!parse_json(document, json, buffer, MAX_JSON_INPUT)) {
1578
1625
  goto out;
1579
1626
  }
1627
+
1628
+ if(!validate_params(document, valid_params)) {
1629
+ goto out;
1630
+ }
1580
1631
 
1581
1632
  if(!json_get_int_param(document, "code", true, &code)) {
1582
1633
  goto out;
@@ -1655,6 +1706,8 @@ int pjw_call_terminate(long call_id, const char *json)
1655
1706
 
1656
1707
  Document document;
1657
1708
 
1709
+ const char *valid_params[] = {"code", "reason", "headers", ""};
1710
+
1658
1711
  if(!g_call_ids.get(call_id, val)){
1659
1712
  set_error("Invalid call_id");
1660
1713
  goto out;
@@ -1664,6 +1717,10 @@ int pjw_call_terminate(long call_id, const char *json)
1664
1717
  if(!parse_json(document, json, buffer, MAX_JSON_INPUT)) {
1665
1718
  goto out;
1666
1719
  }
1720
+
1721
+ if(!validate_params(document, valid_params)) {
1722
+ goto out;
1723
+ }
1667
1724
 
1668
1725
  if(!json_get_int_param(document, "code", true, &code)) {
1669
1726
  goto out;
@@ -1744,6 +1801,8 @@ int pjw_call_create(long t_id, const char *json, long *out_call_id, char *out_si
1744
1801
 
1745
1802
  Document document;
1746
1803
 
1804
+ const char *valid_params[] = {"from_uri", "to_uri", "request_uri", "proxy_uri", "auth", "delayed_media", "headers", ""};
1805
+
1747
1806
  if(!g_transport_ids.get(t_id, val)){
1748
1807
  set_error("Invalid transport_id");
1749
1808
  goto out;
@@ -1753,6 +1812,10 @@ int pjw_call_create(long t_id, const char *json, long *out_call_id, char *out_si
1753
1812
  if(!parse_json(document, json, buffer, MAX_JSON_INPUT)) {
1754
1813
  goto out;
1755
1814
  }
1815
+
1816
+ if(!validate_params(document, valid_params)) {
1817
+ goto out;
1818
+ }
1756
1819
 
1757
1820
  if(!json_get_and_check_uri(document, "from_uri", false, &from_uri)) {
1758
1821
  goto out;
@@ -2160,10 +2223,17 @@ int pjw_call_send_dtmf(long call_id, const char *json)
2160
2223
 
2161
2224
  Document document;
2162
2225
 
2226
+ const char *valid_params[] = {"digits", "mode", ""};
2227
+
2228
+
2163
2229
  if(!parse_json(document, json, buffer, MAX_JSON_INPUT)) {
2164
2230
  goto out;
2165
2231
  }
2166
2232
 
2233
+ if(!validate_params(document, valid_params)) {
2234
+ goto out;
2235
+ }
2236
+
2167
2237
  if(!g_call_ids.get(call_id, val)){
2168
2238
  set_error("Invalid call_id");
2169
2239
  goto out;
@@ -2278,6 +2348,8 @@ int pjw_call_reinvite(long call_id, const char *json)
2278
2348
  char buffer[MAX_JSON_INPUT];
2279
2349
 
2280
2350
  Document document;
2351
+
2352
+ const char *valid_params[] = {"hold", "delayed_media", ""};
2281
2353
 
2282
2354
  if(!g_call_ids.get(call_id, val)){
2283
2355
  set_error("Invalid call_id");
@@ -2289,6 +2361,10 @@ int pjw_call_reinvite(long call_id, const char *json)
2289
2361
  goto out;
2290
2362
  }
2291
2363
 
2364
+ if(!validate_params(document, valid_params)) {
2365
+ goto out;
2366
+ }
2367
+
2292
2368
  if(!json_get_bool_param(document, "hold", true, &hold)) {
2293
2369
  goto out;
2294
2370
  }
@@ -2404,11 +2480,17 @@ int pjw_call_send_request(long call_id, const char *json)
2404
2480
  char buffer[MAX_JSON_INPUT];
2405
2481
 
2406
2482
  Document document;
2483
+
2484
+ const char *valid_params[] = {"method", "body", "ct_type", "ct_subtype", "headers", ""};
2407
2485
 
2408
2486
  if(!parse_json(document, json, buffer, MAX_JSON_INPUT)) {
2409
2487
  goto out;
2410
2488
  }
2411
2489
 
2490
+ if(!validate_params(document, valid_params)) {
2491
+ goto out;
2492
+ }
2493
+
2412
2494
  if(!g_call_ids.get(call_id, val)){
2413
2495
  set_error("Invalid call_id");
2414
2496
  goto out;
@@ -2503,6 +2585,8 @@ int pjw_call_start_record_wav(long call_id, const char *json)
2503
2585
 
2504
2586
  Document document;
2505
2587
 
2588
+ const char *valid_params[] = {"file", ""};
2589
+
2506
2590
  if(!g_call_ids.get(call_id, val)){
2507
2591
  set_error("Invalid call_id");
2508
2592
  goto out;
@@ -2519,6 +2603,10 @@ int pjw_call_start_record_wav(long call_id, const char *json)
2519
2603
  goto out;
2520
2604
  }
2521
2605
 
2606
+ if(!validate_params(document, valid_params)) {
2607
+ goto out;
2608
+ }
2609
+
2522
2610
  if(!json_get_string_param(document, "file", false, &file)) {
2523
2611
  goto out;
2524
2612
  }
@@ -2567,6 +2655,8 @@ int pjw_call_start_play_wav(long call_id, const char *json)
2567
2655
  char buffer[MAX_JSON_INPUT];
2568
2656
 
2569
2657
  Document document;
2658
+
2659
+ const char *valid_params[] = {"file", ""};
2570
2660
 
2571
2661
  if(!g_call_ids.get(call_id, val)){
2572
2662
  set_error("Invalid call_id");
@@ -2584,6 +2674,10 @@ int pjw_call_start_play_wav(long call_id, const char *json)
2584
2674
  goto out;
2585
2675
  }
2586
2676
 
2677
+ if(!validate_params(document, valid_params)) {
2678
+ goto out;
2679
+ }
2680
+
2587
2681
  if(!json_get_string_param(document, "file", false, &file)) {
2588
2682
  goto out;
2589
2683
  }
@@ -2715,6 +2809,8 @@ int pjw_call_start_fax(long call_id, const char *json)
2715
2809
 
2716
2810
  Document document;
2717
2811
 
2812
+ const char *valid_params[] = {"is_sender", "file", "transmit_on_idle", ""};
2813
+
2718
2814
  if(!g_call_ids.get(call_id, val)){
2719
2815
  set_error("Invalid call_id");
2720
2816
  goto out;
@@ -2731,6 +2827,10 @@ int pjw_call_start_fax(long call_id, const char *json)
2731
2827
  goto out;
2732
2828
  }
2733
2829
 
2830
+ if(!validate_params(document, valid_params)) {
2831
+ goto out;
2832
+ }
2833
+
2734
2834
  if(!json_get_bool_param(document, "is_sender", false, &is_sender)) {
2735
2835
  goto out;
2736
2836
  }
@@ -4873,6 +4973,8 @@ int pjw_call_refer(long call_id, const char *json, long *out_subscription_id)
4873
4973
 
4874
4974
  Document document;
4875
4975
 
4976
+ const char *valid_params[] = {"dest_uri", "headers", ""};
4977
+
4876
4978
  if(!g_call_ids.get(call_id, val)){
4877
4979
  set_error("Invalid call_id");
4878
4980
  goto out;
@@ -4883,6 +4985,10 @@ int pjw_call_refer(long call_id, const char *json, long *out_subscription_id)
4883
4985
  goto out;
4884
4986
  }
4885
4987
 
4988
+ if(!validate_params(document, valid_params)) {
4989
+ goto out;
4990
+ }
4991
+
4886
4992
  if(!json_get_and_check_uri(document, "dest_uri", false, &dest_uri)) {
4887
4993
  goto out;
4888
4994
  }
@@ -5061,6 +5167,8 @@ int pjw_notify(long subscriber_id, const char *json)
5061
5167
 
5062
5168
  Document document;
5063
5169
 
5170
+ const char *valid_params[] = {"content_type", "body", "subscription_state", "reason", ""};
5171
+
5064
5172
  if(!g_subscriber_ids.get(subscriber_id, val)){
5065
5173
  set_error("Invalid subscriber_id");
5066
5174
  goto out;
@@ -5076,6 +5184,10 @@ int pjw_notify(long subscriber_id, const char *json)
5076
5184
  goto out;
5077
5185
  }
5078
5186
 
5187
+ if(!validate_params(document, valid_params)) {
5188
+ goto out;
5189
+ }
5190
+
5079
5191
  if(!json_get_string_param(document, "content_type", false, &content_type)) {
5080
5192
  goto out;
5081
5193
  }
@@ -5125,6 +5237,9 @@ int pjw_notify_xfer(long subscriber_id, const char *json) {
5125
5237
  char buffer[MAX_JSON_INPUT];
5126
5238
 
5127
5239
  Document document;
5240
+
5241
+ const char *valid_params[] = {"subscription_state", "code", "reason", ""};
5242
+
5128
5243
  if(!g_subscriber_ids.get(subscriber_id, val)){
5129
5244
  set_error("Invalid subscriber_id");
5130
5245
  goto out;
@@ -5140,6 +5255,10 @@ int pjw_notify_xfer(long subscriber_id, const char *json) {
5140
5255
  goto out;
5141
5256
  }
5142
5257
 
5258
+ if(!validate_params(document, valid_params)) {
5259
+ goto out;
5260
+ }
5261
+
5143
5262
  if(!json_get_int_param(document, "subscription_state", false, &subscription_state)) {
5144
5263
  goto out;
5145
5264
  }
@@ -5422,6 +5541,8 @@ int pjw_subscription_create(long transport_id, const char *json, long *out_subsc
5422
5541
 
5423
5542
  Document document;
5424
5543
 
5544
+ const char *valid_params[] = {"event", "accept", "from_uri", "to_uri", "request_uri", "proxy_uri", "auth", ""};
5545
+
5425
5546
  if(!g_transport_ids.get(transport_id, val)){
5426
5547
  set_error("Invalid transport_id");
5427
5548
  goto out;
@@ -5432,6 +5553,10 @@ int pjw_subscription_create(long transport_id, const char *json, long *out_subsc
5432
5553
  goto out;
5433
5554
  }
5434
5555
 
5556
+ if(!validate_params(document, valid_params)) {
5557
+ goto out;
5558
+ }
5559
+
5435
5560
  if(!json_get_string_param(document, "event", false, &event)) {
5436
5561
  goto out;
5437
5562
  }
@@ -5628,6 +5753,8 @@ int pjw_subscription_subscribe(long subscription_id, const char *json) {
5628
5753
  char buffer[MAX_JSON_INPUT];
5629
5754
 
5630
5755
  Document document;
5756
+
5757
+ const char *valid_params[] = {"expires", "headers", ""};
5631
5758
 
5632
5759
  if(!g_subscription_ids.get(subscription_id, val)){
5633
5760
  set_error("Invalid subscription_id");
@@ -5639,6 +5766,10 @@ int pjw_subscription_subscribe(long subscription_id, const char *json) {
5639
5766
  goto out;
5640
5767
  }
5641
5768
 
5769
+ if(!validate_params(document, valid_params)) {
5770
+ goto out;
5771
+ }
5772
+
5642
5773
  if(!json_get_int_param(document, "expires", true, &expires)) {
5643
5774
  goto out;
5644
5775
  }