sip-lab 1.11.0 → 1.12.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 +8 -3
- package/binding.gyp +1 -0
- package/index.js +23 -13
- package/install.sh +12 -1
- package/package.json +2 -1
- package/samples/artifacts/marielle_presente.tiff +0 -0
- package/samples/{fax_doc.tiff → artifacts/sample.tiff} +0 -0
- package/samples/artifacts/this-is-never-ok.tiff +0 -0
- package/samples/{late_negotiation.js → delayed_media.js} +22 -25
- package/samples/g729.js +11 -11
- package/samples/register_subscribe.js +24 -7
- package/samples/reinvite_and_dtmf.js +22 -24
- package/samples/send_and_receive_fax.js +10 -12
- package/samples/simple.js +10 -12
- package/samples/sip_cancel.js +10 -12
- package/src/addon.cpp +107 -498
- package/src/event_templates.cpp +22 -22
- package/src/event_templates.hpp +10 -10
- package/src/sip.cpp +1121 -498
- package/src/sip.hpp +58 -17
package/src/sip.cpp
CHANGED
|
@@ -34,12 +34,17 @@
|
|
|
34
34
|
|
|
35
35
|
#include "log.hpp"
|
|
36
36
|
|
|
37
|
+
#include "rapidjson/document.h"
|
|
38
|
+
|
|
39
|
+
using namespace rapidjson;
|
|
37
40
|
using namespace std;
|
|
38
41
|
|
|
39
42
|
#define EVT_DATA_SEP "|"
|
|
40
43
|
|
|
41
44
|
#define IDS_MAX (2000)
|
|
42
45
|
|
|
46
|
+
#define MAX_JSON_INPUT 4096
|
|
47
|
+
|
|
43
48
|
IdManager g_transport_ids(IDS_MAX);
|
|
44
49
|
IdManager g_account_ids(IDS_MAX);
|
|
45
50
|
IdManager g_call_ids(IDS_MAX);
|
|
@@ -64,8 +69,8 @@ static pj_caching_pool cp;
|
|
|
64
69
|
static pj_pool_t *g_pool;
|
|
65
70
|
static pjmedia_endpt *g_med_endpt;
|
|
66
71
|
|
|
67
|
-
static pj_thread_t *g_thread = NULL;
|
|
68
|
-
static pj_bool_t g_thread_quit_flag;
|
|
72
|
+
//static pj_thread_t *g_thread = NULL;
|
|
73
|
+
//static pj_bool_t g_thread_quit_flag;
|
|
69
74
|
|
|
70
75
|
static deque<string> g_events;
|
|
71
76
|
static pthread_mutex_t g_mutex;
|
|
@@ -76,15 +81,119 @@ void clear_error() {
|
|
|
76
81
|
pjw_errorstring[0] = 0;
|
|
77
82
|
}
|
|
78
83
|
|
|
84
|
+
/*
|
|
79
85
|
void set_error(char *err) {
|
|
80
86
|
//printf("set_error: %s\n", err);
|
|
81
87
|
strcpy(pjw_errorstring, err);
|
|
82
88
|
}
|
|
89
|
+
*/
|
|
90
|
+
|
|
91
|
+
void set_error(const char* format, ...)
|
|
92
|
+
{
|
|
93
|
+
va_list args;
|
|
94
|
+
va_start(args, format);
|
|
95
|
+
vsnprintf(pjw_errorstring, sizeof(pjw_errorstring), format, args);
|
|
96
|
+
va_end(args);
|
|
97
|
+
}
|
|
83
98
|
|
|
84
99
|
char *pjw_get_error() {
|
|
85
100
|
return pjw_errorstring;
|
|
86
101
|
}
|
|
87
102
|
|
|
103
|
+
int check_uri(const char *uri) {
|
|
104
|
+
return (strstr(uri, "sip:") != NULL);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
bool parse_json(Document &document, const char *json, char *buffer, long unsigned int len) {
|
|
108
|
+
if(strlen(json) > len -1) {
|
|
109
|
+
set_error("JSON too large");
|
|
110
|
+
return false;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
strcpy(buffer, json);
|
|
114
|
+
if (document.ParseInsitu(buffer).HasParseError()) {
|
|
115
|
+
set_error("Failed to parse JSON");
|
|
116
|
+
return false;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if(!document.IsObject()) {
|
|
120
|
+
set_error("Invalid JSON root. Must be an object");
|
|
121
|
+
return false;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return true;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
bool json_get_string_param(Document &document, const char *param, bool optional, char **dest) {
|
|
128
|
+
printf("json_get_string_param %s\n", param);
|
|
129
|
+
if(!document.HasMember(param)) {
|
|
130
|
+
if(optional) {
|
|
131
|
+
return true;
|
|
132
|
+
}
|
|
133
|
+
set_error("Parameter %s is required", param);
|
|
134
|
+
return false;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
if(!document[param].IsString()) {
|
|
138
|
+
set_error("Parameter %s must be a string", param);
|
|
139
|
+
return false;
|
|
140
|
+
}
|
|
141
|
+
*dest = (char*)document[param].GetString();
|
|
142
|
+
return true;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
bool json_get_int_param(Document &document, const char *param, bool optional, int *dest) {
|
|
146
|
+
if(!document.HasMember(param)) {
|
|
147
|
+
if(optional) {
|
|
148
|
+
return true;
|
|
149
|
+
}
|
|
150
|
+
set_error("Parameter %s is required", param);
|
|
151
|
+
return false;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
if(!document[param].IsInt()) {
|
|
155
|
+
set_error("Parameter %s must be an integer", param);
|
|
156
|
+
return false;
|
|
157
|
+
}
|
|
158
|
+
*dest = document[param].GetInt();
|
|
159
|
+
return true;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
bool json_get_bool_param(Document &document, const char *param, bool optional, bool *dest) {
|
|
163
|
+
if(!document.HasMember(param)) {
|
|
164
|
+
if(optional) {
|
|
165
|
+
return true;
|
|
166
|
+
}
|
|
167
|
+
set_error("Parameter %s is required", param);
|
|
168
|
+
return false;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
if(!document[param].IsBool()) {
|
|
172
|
+
set_error("Parameter %s must be a boolean", param);
|
|
173
|
+
return false;
|
|
174
|
+
}
|
|
175
|
+
*dest = document[param].GetBool();
|
|
176
|
+
return true;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
bool json_get_and_check_uri(Document &document, const char *param, bool optional, char **dest) {
|
|
181
|
+
if(!json_get_string_param(document, param, optional, dest)) {
|
|
182
|
+
return false;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
if(*dest && *dest[0]) {
|
|
186
|
+
if(!check_uri(*dest)) {
|
|
187
|
+
set_error("Invalid %s", param);
|
|
188
|
+
return false;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
return true;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
|
|
88
197
|
#define PJW_LOCK() pthread_mutex_lock(&g_mutex)
|
|
89
198
|
#define PJW_UNLOCK() pthread_mutex_unlock(&g_mutex)
|
|
90
199
|
|
|
@@ -117,7 +226,7 @@ unsigned g_flags = 0;
|
|
|
117
226
|
|
|
118
227
|
pjsip_route_hdr route_set;
|
|
119
228
|
pjsip_route_hdr *route;
|
|
120
|
-
const pj_str_t hname =
|
|
229
|
+
const pj_str_t hname = pj_str((char*)"Route");
|
|
121
230
|
|
|
122
231
|
#define MAXDIGITS 256
|
|
123
232
|
#define INITIAL_DIGITBUFFERLENGTH 1
|
|
@@ -205,6 +314,7 @@ PackageSet g_PackageSet;
|
|
|
205
314
|
|
|
206
315
|
#define DEFAULT_EXPIRES 600
|
|
207
316
|
|
|
317
|
+
/*
|
|
208
318
|
static void pool_callback(pj_pool_t *pool, pj_size_t size)
|
|
209
319
|
{
|
|
210
320
|
PJ_CHECK_STACK();
|
|
@@ -213,18 +323,21 @@ static void pool_callback(pj_pool_t *pool, pj_size_t size)
|
|
|
213
323
|
|
|
214
324
|
PJ_THROW(PJ_NO_MEMORY_EXCEPTION);
|
|
215
325
|
}
|
|
326
|
+
*/
|
|
216
327
|
|
|
217
328
|
void handle_events(){
|
|
218
|
-
unsigned count = 0;
|
|
329
|
+
//unsigned count = 0;
|
|
219
330
|
//pj_time_val tv = {0, 500};
|
|
220
331
|
//pj_time_val tv = {0,10};
|
|
221
332
|
//pj_time_val tv = {0,100};
|
|
222
333
|
pj_time_val tv = {0,1};
|
|
223
334
|
//pj_time_val_normalize(&tv);
|
|
224
|
-
|
|
225
|
-
status = pjsip_endpt_handle_events(g_sip_endpt, &tv);
|
|
335
|
+
//pj_status_t status;
|
|
336
|
+
//status = pjsip_endpt_handle_events(g_sip_endpt, &tv);
|
|
337
|
+
pjsip_endpt_handle_events(g_sip_endpt, &tv);
|
|
226
338
|
}
|
|
227
339
|
|
|
340
|
+
/*
|
|
228
341
|
static int worker_thread(void *arg)
|
|
229
342
|
{
|
|
230
343
|
//addon_log(LOG_LEVEL_DEBUG, "Starting worker_thread\n");
|
|
@@ -246,6 +359,7 @@ static int worker_thread(void *arg)
|
|
|
246
359
|
}
|
|
247
360
|
return 0;
|
|
248
361
|
}
|
|
362
|
+
*/
|
|
249
363
|
|
|
250
364
|
void init_tpselector(Transport *t, pjsip_tpselector *sel) {
|
|
251
365
|
unsigned flag;
|
|
@@ -314,7 +428,6 @@ bool dlg_create(pjsip_dialog **dlg, Transport *transport, const char *from_uri,
|
|
|
314
428
|
|
|
315
429
|
static int call_create(Transport *t, unsigned flags, pjsip_dialog *dlg, const char *proxy_uri, const char *additional_headers);
|
|
316
430
|
|
|
317
|
-
static int subscription_create(pjsip_dialog *dlg, const char *event, const char *proxy_uri, const char *additional_headers);
|
|
318
431
|
bool subscription_subscribe(Subscription *s, int expires, const char *additional_headers);
|
|
319
432
|
|
|
320
433
|
static pjmedia_transport *create_media_transport(const pj_str_t *addr);
|
|
@@ -372,7 +485,7 @@ void append_status(ostringstream *oss, pj_status_t s);
|
|
|
372
485
|
static pjsip_module mod_tester =
|
|
373
486
|
{
|
|
374
487
|
NULL, NULL, /* prev, next. */
|
|
375
|
-
{ "mod_tester", 10 }, /* Name. */
|
|
488
|
+
{ (char*)"mod_tester", 10 }, /* Name. */
|
|
376
489
|
-1, /* Id */
|
|
377
490
|
//PJSIP_MOD_PRIORITY_APPLICATION, /* Priority */
|
|
378
491
|
PJSIP_MOD_PRIORITY_DIALOG_USAGE, /* Priority */
|
|
@@ -400,10 +513,6 @@ Timer _timer;
|
|
|
400
513
|
|
|
401
514
|
void dispatch_event(const char * evt);
|
|
402
515
|
|
|
403
|
-
int check_uri(const char *uri) {
|
|
404
|
-
return (strstr(uri, "sip:") != NULL);
|
|
405
|
-
}
|
|
406
|
-
|
|
407
516
|
const char *translate_pjsip_inv_state(int state)
|
|
408
517
|
{
|
|
409
518
|
switch(state)
|
|
@@ -489,11 +598,12 @@ void dispatch_event(const char * evt)
|
|
|
489
598
|
}
|
|
490
599
|
|
|
491
600
|
static char *get_media_mode_str(int mode) {
|
|
492
|
-
if(mode == SENDRECV) return "sendrecv";
|
|
493
|
-
if(mode == SENDONLY) return "sendonly";
|
|
494
|
-
if(mode == RECVONLY) return "recvonly";
|
|
495
|
-
if(mode == INACTIVE) return "inactive";
|
|
496
|
-
if(mode == UNKNOWN) return "unknown";
|
|
601
|
+
if(mode == SENDRECV) return (char*)"sendrecv";
|
|
602
|
+
if(mode == SENDONLY) return (char*)"sendonly";
|
|
603
|
+
if(mode == RECVONLY) return (char*)"recvonly";
|
|
604
|
+
if(mode == INACTIVE) return (char*)"inactive";
|
|
605
|
+
if(mode == UNKNOWN) return (char*)"unknown";
|
|
606
|
+
return (char*)"unexpected";
|
|
497
607
|
}
|
|
498
608
|
|
|
499
609
|
static int get_media_mode(pjmedia_sdp_attr **attrs, int count) {
|
|
@@ -541,7 +651,7 @@ int __pjw_init()
|
|
|
541
651
|
|
|
542
652
|
pj_caching_pool_init(&cp, &pj_pool_factory_default_policy, 0);
|
|
543
653
|
|
|
544
|
-
char *sip_endpt_name = "mysip";
|
|
654
|
+
char *sip_endpt_name = (char*)"mysip";
|
|
545
655
|
|
|
546
656
|
status = pjsip_endpt_create(&cp.factory, sip_endpt_name, &g_sip_endpt);
|
|
547
657
|
if(status != PJ_SUCCESS)
|
|
@@ -560,9 +670,9 @@ int __pjw_init()
|
|
|
560
670
|
return 1;
|
|
561
671
|
}
|
|
562
672
|
|
|
563
|
-
const pj_str_t msg_tag = { "MESSAGE", 7 };
|
|
564
|
-
const pj_str_t STR_MIME_TEXT_PLAIN = { "text/plain", 10 };
|
|
565
|
-
const pj_str_t STR_MIME_APP_ISCOMPOSING = { "application/im-iscomposing+xml", 30 };
|
|
673
|
+
const pj_str_t msg_tag = { (char*)"MESSAGE", 7 };
|
|
674
|
+
const pj_str_t STR_MIME_TEXT_PLAIN = { (char*)"text/plain", 10 };
|
|
675
|
+
const pj_str_t STR_MIME_APP_ISCOMPOSING = { (char*)"application/im-iscomposing+xml", 30 };
|
|
566
676
|
|
|
567
677
|
/* Register support for MESSAGE method. */
|
|
568
678
|
status = pjsip_endpt_add_capability(g_sip_endpt, &mod_tester, PJSIP_H_ALLOW,
|
|
@@ -818,7 +928,7 @@ pjsip_transport *allocate_udp_transport(pjsip_endpoint* sip_endpt, pj_str_t *ipa
|
|
|
818
928
|
|
|
819
929
|
pjsip_transport *create_udp_transport(pjsip_endpoint* sip_endpt, pj_str_t *ipaddr, int *allocated_port)
|
|
820
930
|
{
|
|
821
|
-
pj_status_t status;
|
|
931
|
+
//pj_status_t status;
|
|
822
932
|
pjsip_transport *transport;
|
|
823
933
|
|
|
824
934
|
int port = 5060;
|
|
@@ -836,11 +946,11 @@ pjsip_transport *create_udp_transport(pjsip_endpoint* sip_endpt, pj_str_t *ipadd
|
|
|
836
946
|
}
|
|
837
947
|
|
|
838
948
|
pjsip_tpfactory *allocate_tcp_tpfactory(pjsip_endpoint* sip_endpt, pj_str_t *ipaddr, int port) {
|
|
839
|
-
printf("allocate_tcp_tpfactory ipaddr=%.*s port=%i\n", ipaddr->slen, ipaddr->ptr, port);
|
|
949
|
+
printf("allocate_tcp_tpfactory ipaddr=%.*s port=%i\n", (int)ipaddr->slen, ipaddr->ptr, port);
|
|
840
950
|
pj_status_t status;
|
|
841
951
|
pjsip_tpfactory *tpfactory;
|
|
842
952
|
pj_sockaddr local_addr;
|
|
843
|
-
pjsip_host_port a_name;
|
|
953
|
+
//pjsip_host_port a_name;
|
|
844
954
|
|
|
845
955
|
int af;
|
|
846
956
|
af = pj_AF_INET();
|
|
@@ -864,7 +974,7 @@ pjsip_tpfactory *allocate_tcp_tpfactory(pjsip_endpoint* sip_endpt, pj_str_t *ipa
|
|
|
864
974
|
|
|
865
975
|
pjsip_tpfactory *create_tcp_tpfactory(pjsip_endpoint* sip_endpt, pj_str_t *ipaddr, int *allocated_port)
|
|
866
976
|
{
|
|
867
|
-
pj_status_t status;
|
|
977
|
+
//pj_status_t status;
|
|
868
978
|
pjsip_tpfactory *tpfactory;
|
|
869
979
|
|
|
870
980
|
int port = 6060;
|
|
@@ -886,7 +996,7 @@ pjsip_tpfactory *allocate_tls_tpfactory(pjsip_endpoint* sip_endpt, pj_str_t *ipa
|
|
|
886
996
|
pj_status_t status;
|
|
887
997
|
pjsip_tpfactory *tpfactory;
|
|
888
998
|
pj_sockaddr local_addr;
|
|
889
|
-
pjsip_host_port a_name;
|
|
999
|
+
//pjsip_host_port a_name;
|
|
890
1000
|
|
|
891
1001
|
int af;
|
|
892
1002
|
af = pj_AF_INET();
|
|
@@ -913,7 +1023,7 @@ pjsip_tpfactory *allocate_tls_tpfactory(pjsip_endpoint* sip_endpt, pj_str_t *ipa
|
|
|
913
1023
|
|
|
914
1024
|
pjsip_tpfactory *create_tls_tpfactory(pjsip_endpoint* sip_endpt, pj_str_t *ipaddr, int *allocated_port)
|
|
915
1025
|
{
|
|
916
|
-
pj_status_t status;
|
|
1026
|
+
//pj_status_t status;
|
|
917
1027
|
pjsip_tpfactory *tpfactory;
|
|
918
1028
|
|
|
919
1029
|
int port = 6060;
|
|
@@ -930,31 +1040,83 @@ pjsip_tpfactory *create_tls_tpfactory(pjsip_endpoint* sip_endpt, pj_str_t *ipadd
|
|
|
930
1040
|
return NULL;
|
|
931
1041
|
}
|
|
932
1042
|
|
|
933
|
-
int pjw_transport_create(const char *sip_ipaddr, int port, pjsip_transport_type_e type, int *out_t_id, int *out_port)
|
|
1043
|
+
//int pjw_transport_create(const char *sip_ipaddr, int port, pjsip_transport_type_e type, int *out_t_id, int *out_port)
|
|
1044
|
+
int pjw_transport_create(const char *json, int *out_t_id, char *out_t_address, int *out_port)
|
|
934
1045
|
{
|
|
935
1046
|
PJW_LOCK();
|
|
936
1047
|
clear_error();
|
|
937
1048
|
|
|
938
|
-
|
|
1049
|
+
char *addr;
|
|
1050
|
+
pj_str_t address; // = pj_str((char*)sip_ipaddr);
|
|
1051
|
+
int port = 0;
|
|
1052
|
+
pjsip_transport_type_e type = PJSIP_TRANSPORT_UDP;
|
|
939
1053
|
|
|
940
1054
|
pj_status_t status;
|
|
941
1055
|
Transport *t = NULL;
|
|
942
1056
|
long t_id;
|
|
943
1057
|
|
|
1058
|
+
char buffer[MAX_JSON_INPUT];
|
|
1059
|
+
|
|
1060
|
+
Document document;
|
|
1061
|
+
|
|
1062
|
+
if(!parse_json(document, json, buffer, MAX_JSON_INPUT)) {
|
|
1063
|
+
goto out;
|
|
1064
|
+
}
|
|
1065
|
+
|
|
1066
|
+
// address
|
|
1067
|
+
if(!document.HasMember("address")) {
|
|
1068
|
+
set_error("Parameter address is required");
|
|
1069
|
+
goto out;
|
|
1070
|
+
}
|
|
1071
|
+
|
|
1072
|
+
if(!document["address"].IsString()) {
|
|
1073
|
+
set_error("Parameter address must be a string");
|
|
1074
|
+
goto out;
|
|
1075
|
+
}
|
|
1076
|
+
addr = (char*)document["address"].GetString();
|
|
1077
|
+
address = pj_str((char*)addr);
|
|
1078
|
+
|
|
1079
|
+
// port
|
|
1080
|
+
if(document.HasMember("port")) {
|
|
1081
|
+
if(!document["port"].IsInt()) {
|
|
1082
|
+
set_error("Parameter port must be an integer");
|
|
1083
|
+
goto out;
|
|
1084
|
+
}
|
|
1085
|
+
port = document["port"].GetInt();
|
|
1086
|
+
}
|
|
1087
|
+
|
|
1088
|
+
// type
|
|
1089
|
+
if(document.HasMember("type")) {
|
|
1090
|
+
if(!document["type"].IsString()) {
|
|
1091
|
+
set_error("Parameter type must be a string");
|
|
1092
|
+
goto out;
|
|
1093
|
+
}
|
|
1094
|
+
const char *t = document["type"].GetString();
|
|
1095
|
+
if(stricmp(t, "UDP") == 0) {
|
|
1096
|
+
type = PJSIP_TRANSPORT_UDP;
|
|
1097
|
+
} else if(stricmp(t, "TCP") == 0) {
|
|
1098
|
+
type = PJSIP_TRANSPORT_TCP;
|
|
1099
|
+
} else if(stricmp(t, "TLS") == 0) {
|
|
1100
|
+
type = PJSIP_TRANSPORT_TLS;
|
|
1101
|
+
} else {
|
|
1102
|
+
set_error("Invalid type %s. It must be one of 'UDP' (default), 'TCP' or 'TLS'", type);
|
|
1103
|
+
goto out;
|
|
1104
|
+
}
|
|
1105
|
+
}
|
|
1106
|
+
|
|
944
1107
|
if(type == PJSIP_TRANSPORT_UDP) {
|
|
945
1108
|
pjsip_transport *sip_transport = NULL;
|
|
946
1109
|
|
|
947
1110
|
if(port != 0) {
|
|
948
|
-
sip_transport = allocate_udp_transport(g_sip_endpt, &
|
|
1111
|
+
sip_transport = allocate_udp_transport(g_sip_endpt, &address, port);
|
|
949
1112
|
} else {
|
|
950
|
-
sip_transport = create_udp_transport(g_sip_endpt, &
|
|
1113
|
+
sip_transport = create_udp_transport(g_sip_endpt, &address, &port);
|
|
951
1114
|
}
|
|
952
1115
|
|
|
953
1116
|
if(!sip_transport)
|
|
954
1117
|
{
|
|
955
|
-
PJW_UNLOCK();
|
|
956
1118
|
set_error("Unable to start UDP transport");
|
|
957
|
-
|
|
1119
|
+
goto out;
|
|
958
1120
|
}
|
|
959
1121
|
|
|
960
1122
|
t = new Transport;
|
|
@@ -963,32 +1125,27 @@ int pjw_transport_create(const char *sip_ipaddr, int port, pjsip_transport_type_
|
|
|
963
1125
|
|
|
964
1126
|
if(!g_transport_ids.add((long)t, t_id)){
|
|
965
1127
|
status = pjsip_udp_transport_pause(sip_transport,PJSIP_UDP_TRANSPORT_DESTROY_SOCKET);
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
PJW_UNLOCK();
|
|
1128
|
+
printf("pjsip_dup_transport_pause status=%i\n", status);
|
|
969
1129
|
set_error("Failed to allocate id");
|
|
970
|
-
|
|
1130
|
+
goto out;
|
|
971
1131
|
}
|
|
972
1132
|
|
|
973
|
-
|
|
974
|
-
g_SipTransportMap.insert(make_pair(sip_transport, t_id));
|
|
975
|
-
}
|
|
1133
|
+
g_SipTransportMap.insert(make_pair(sip_transport, t_id));
|
|
976
1134
|
} else if(type == PJSIP_TRANSPORT_TCP) {
|
|
977
1135
|
pjsip_tpfactory *tpfactory;
|
|
978
|
-
int af;
|
|
1136
|
+
//int af;
|
|
979
1137
|
|
|
980
1138
|
|
|
981
1139
|
if(port != 0) {
|
|
982
|
-
tpfactory = allocate_tcp_tpfactory(g_sip_endpt, &
|
|
1140
|
+
tpfactory = allocate_tcp_tpfactory(g_sip_endpt, &address, port);
|
|
983
1141
|
} else {
|
|
984
|
-
tpfactory = create_tcp_tpfactory(g_sip_endpt, &
|
|
1142
|
+
tpfactory = create_tcp_tpfactory(g_sip_endpt, &address, &port);
|
|
985
1143
|
}
|
|
986
1144
|
|
|
987
1145
|
if(!tpfactory)
|
|
988
1146
|
{
|
|
989
|
-
PJW_UNLOCK();
|
|
990
1147
|
set_error("Unable to start TCP transport");
|
|
991
|
-
|
|
1148
|
+
goto out;
|
|
992
1149
|
}
|
|
993
1150
|
|
|
994
1151
|
t = new Transport;
|
|
@@ -998,40 +1155,37 @@ int pjw_transport_create(const char *sip_ipaddr, int port, pjsip_transport_type_
|
|
|
998
1155
|
if(!g_transport_ids.add((long)t, t_id)){
|
|
999
1156
|
status = (tpfactory->destroy)(tpfactory);
|
|
1000
1157
|
|
|
1001
|
-
PJW_UNLOCK();
|
|
1002
1158
|
set_error("Failed to allocate id");
|
|
1003
|
-
|
|
1159
|
+
goto out;
|
|
1004
1160
|
}
|
|
1005
1161
|
|
|
1006
1162
|
g_TcpTransportId = t_id;
|
|
1007
1163
|
} else {
|
|
1008
1164
|
pjsip_tpfactory *tpfactory;
|
|
1009
|
-
int af;
|
|
1165
|
+
//int af;
|
|
1010
1166
|
|
|
1011
1167
|
|
|
1012
1168
|
if(port != 0) {
|
|
1013
|
-
tpfactory = allocate_tls_tpfactory(g_sip_endpt, &
|
|
1169
|
+
tpfactory = allocate_tls_tpfactory(g_sip_endpt, &address, port);
|
|
1014
1170
|
} else {
|
|
1015
|
-
tpfactory = create_tls_tpfactory(g_sip_endpt, &
|
|
1171
|
+
tpfactory = create_tls_tpfactory(g_sip_endpt, &address, &port);
|
|
1016
1172
|
}
|
|
1017
1173
|
|
|
1018
1174
|
if(!tpfactory)
|
|
1019
1175
|
{
|
|
1020
|
-
PJW_UNLOCK();
|
|
1021
1176
|
set_error("Unable to start TLS transport");
|
|
1022
|
-
|
|
1177
|
+
goto out;
|
|
1023
1178
|
}
|
|
1024
1179
|
|
|
1025
1180
|
t = new Transport;
|
|
1026
1181
|
t->type = PJSIP_TRANSPORT_TLS;
|
|
1027
1182
|
t->tpfactory = tpfactory;
|
|
1028
1183
|
|
|
1029
|
-
if(!g_transport_ids.add((long)t, t_id)){
|
|
1184
|
+
if(!g_transport_ids.add((long)t, t_id)) {
|
|
1030
1185
|
status = (tpfactory->destroy)(tpfactory);
|
|
1031
1186
|
|
|
1032
|
-
PJW_UNLOCK();
|
|
1033
1187
|
set_error("Failed to allocate id");
|
|
1034
|
-
|
|
1188
|
+
goto out;
|
|
1035
1189
|
}
|
|
1036
1190
|
|
|
1037
1191
|
g_TlsTransportId = t_id;
|
|
@@ -1039,14 +1193,18 @@ int pjw_transport_create(const char *sip_ipaddr, int port, pjsip_transport_type_
|
|
|
1039
1193
|
|
|
1040
1194
|
t->id = t_id;
|
|
1041
1195
|
|
|
1042
|
-
PJW_UNLOCK();
|
|
1043
|
-
|
|
1044
1196
|
if(g_PacketDumper) {
|
|
1045
|
-
g_PacketDumper->add_endpoint( inet_addr(
|
|
1197
|
+
g_PacketDumper->add_endpoint( inet_addr(addr), htons(port) );
|
|
1046
1198
|
}
|
|
1047
|
-
|
|
1199
|
+
|
|
1048
1200
|
*out_t_id = t_id;
|
|
1201
|
+
strcpy(out_t_address, addr);
|
|
1049
1202
|
*out_port = port;
|
|
1203
|
+
out:
|
|
1204
|
+
PJW_UNLOCK();
|
|
1205
|
+
if(pjw_errorstring[0]){
|
|
1206
|
+
return -1;
|
|
1207
|
+
}
|
|
1050
1208
|
return 0;
|
|
1051
1209
|
}
|
|
1052
1210
|
|
|
@@ -1056,71 +1214,126 @@ int pjw_transport_get_info(int t_id, char *out_sip_ipaddr, int *out_port)
|
|
|
1056
1214
|
clear_error();
|
|
1057
1215
|
|
|
1058
1216
|
long val;
|
|
1217
|
+
Transport *t;
|
|
1218
|
+
|
|
1219
|
+
int port;
|
|
1220
|
+
int len;
|
|
1059
1221
|
|
|
1060
1222
|
if(!g_transport_ids.get(t_id, val)){
|
|
1061
|
-
PJW_UNLOCK();
|
|
1062
1223
|
set_error("Invalid transport_id");
|
|
1063
|
-
|
|
1224
|
+
goto out;
|
|
1064
1225
|
}
|
|
1226
|
+
t = (Transport*)val;
|
|
1065
1227
|
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
int port = t->sip_transport->local_name.port;
|
|
1069
|
-
int len = t->sip_transport->local_name.host.slen;
|
|
1070
|
-
char addr[100];
|
|
1228
|
+
port = t->sip_transport->local_name.port;
|
|
1229
|
+
len = t->sip_transport->local_name.host.slen;
|
|
1071
1230
|
strncpy(out_sip_ipaddr, t->sip_transport->local_name.host.ptr, len);
|
|
1072
1231
|
out_sip_ipaddr[len] = 0;
|
|
1073
1232
|
*out_port = port;
|
|
1074
1233
|
|
|
1234
|
+
out:
|
|
1075
1235
|
PJW_UNLOCK();
|
|
1236
|
+
if(pjw_errorstring[0]){
|
|
1237
|
+
return -1;
|
|
1238
|
+
}
|
|
1076
1239
|
return 0;
|
|
1077
1240
|
}
|
|
1078
1241
|
|
|
1079
|
-
int pjw_account_create(int t_id, const char *domain, const char *server, const char *username, const char *password, const char *additional_headers, const char *c_to_url, int expires, int *out_acc_id)
|
|
1242
|
+
//int pjw_account_create(int t_id, const char *domain, const char *server, const char *username, const char *password, const char *additional_headers, const char *c_to_url, int expires, int *out_acc_id)
|
|
1243
|
+
int pjw_account_create(int t_id, const char *json, int *out_acc_id)
|
|
1080
1244
|
{
|
|
1081
|
-
//printf("domain=%s, server=%s, username=%s, password=%s, additional_headers=%s, c_to_url=%s expires=%u\n", domain, server, username, password, additional_headers, c_to_url, expires);
|
|
1082
1245
|
PJW_LOCK();
|
|
1083
1246
|
clear_error();
|
|
1084
1247
|
|
|
1085
1248
|
long val;
|
|
1086
1249
|
|
|
1250
|
+
pj_status_t status;
|
|
1251
|
+
pjsip_regc *regc;
|
|
1252
|
+
|
|
1253
|
+
char *domain;
|
|
1254
|
+
char *server;
|
|
1255
|
+
char *username;
|
|
1256
|
+
char *password;
|
|
1257
|
+
char *c_to_uri = NULL;
|
|
1258
|
+
int expires = 60;
|
|
1259
|
+
char *additional_headers = NULL;
|
|
1260
|
+
|
|
1261
|
+
pj_str_t server_uri;
|
|
1262
|
+
pj_str_t from_uri;
|
|
1263
|
+
pj_str_t to_uri;
|
|
1264
|
+
pj_str_t contact;
|
|
1265
|
+
|
|
1266
|
+
long acc_id;
|
|
1267
|
+
|
|
1268
|
+
Transport *t;
|
|
1269
|
+
|
|
1270
|
+
int local_port;
|
|
1271
|
+
int len;
|
|
1272
|
+
char local_addr[100];
|
|
1273
|
+
|
|
1274
|
+
char temp[400];
|
|
1275
|
+
char *p;
|
|
1276
|
+
|
|
1277
|
+
pjsip_cred_info cred;
|
|
1278
|
+
pjsip_tpselector sel;
|
|
1279
|
+
|
|
1280
|
+
char buffer[MAX_JSON_INPUT];
|
|
1281
|
+
|
|
1282
|
+
Document document;
|
|
1283
|
+
|
|
1087
1284
|
if(!g_transport_ids.get(t_id, val)){
|
|
1088
|
-
PJW_UNLOCK();
|
|
1089
1285
|
set_error("Invalid transport id");
|
|
1090
|
-
|
|
1286
|
+
goto out;
|
|
1091
1287
|
}
|
|
1288
|
+
t = (Transport*)val;
|
|
1092
1289
|
|
|
1093
|
-
|
|
1290
|
+
if(!parse_json(document, json, buffer, MAX_JSON_INPUT)) {
|
|
1291
|
+
goto out;
|
|
1292
|
+
}
|
|
1094
1293
|
|
|
1095
|
-
|
|
1096
|
-
|
|
1294
|
+
if(!json_get_string_param(document, "domain", false, &domain)) {
|
|
1295
|
+
goto out;
|
|
1296
|
+
}
|
|
1297
|
+
|
|
1298
|
+
if(!json_get_string_param(document, "server", false, &server)) {
|
|
1299
|
+
goto out;
|
|
1300
|
+
}
|
|
1301
|
+
|
|
1302
|
+
if(!json_get_string_param(document, "username", false, &username)) {
|
|
1303
|
+
goto out;
|
|
1304
|
+
}
|
|
1305
|
+
|
|
1306
|
+
if(!json_get_string_param(document, "password", false, &password)) {
|
|
1307
|
+
goto out;
|
|
1308
|
+
}
|
|
1309
|
+
|
|
1310
|
+
if(!json_get_string_param(document, "to_uri", true, &c_to_uri)) {
|
|
1311
|
+
goto out;
|
|
1312
|
+
}
|
|
1313
|
+
|
|
1314
|
+
if(!json_get_int_param(document, "expires", true, &expires)) {
|
|
1315
|
+
goto out;
|
|
1316
|
+
}
|
|
1097
1317
|
|
|
1098
1318
|
status = pjsip_regc_create(g_sip_endpt, NULL, on_registration_status, ®c);
|
|
1099
1319
|
if(status != PJ_SUCCESS)
|
|
1100
1320
|
{
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
return -1;
|
|
1321
|
+
set_error("pjsip_regc_create failed with status=%i", status);
|
|
1322
|
+
goto out;
|
|
1104
1323
|
}
|
|
1105
1324
|
|
|
1106
1325
|
if(additional_headers) {
|
|
1107
1326
|
if(!add_additional_headers_for_account(regc, additional_headers)) {
|
|
1108
|
-
PJW_UNLOCK();
|
|
1109
1327
|
set_error("add_additional_headers_for_account failed");
|
|
1110
|
-
|
|
1328
|
+
goto out;
|
|
1111
1329
|
}
|
|
1112
1330
|
}
|
|
1113
1331
|
|
|
1114
|
-
long acc_id;
|
|
1115
1332
|
if(!g_account_ids.add((long)regc, acc_id)){
|
|
1116
|
-
PJW_UNLOCK();
|
|
1117
1333
|
set_error("Failed to allocate id");
|
|
1118
|
-
|
|
1334
|
+
goto out;
|
|
1119
1335
|
}
|
|
1120
1336
|
|
|
1121
|
-
int local_port;
|
|
1122
|
-
int len;
|
|
1123
|
-
char local_addr[100];
|
|
1124
1337
|
if(t->type == PJSIP_TRANSPORT_UDP) {
|
|
1125
1338
|
local_port = t->sip_transport->local_name.port;
|
|
1126
1339
|
len= t->sip_transport->local_name.host.slen;
|
|
@@ -1132,50 +1345,47 @@ int pjw_account_create(int t_id, const char *domain, const char *server, const c
|
|
|
1132
1345
|
}
|
|
1133
1346
|
local_addr[len] = 0;
|
|
1134
1347
|
|
|
1135
|
-
|
|
1136
|
-
char *p = temp;
|
|
1348
|
+
p = temp;
|
|
1137
1349
|
|
|
1138
1350
|
len = sprintf(p, "sip:%s", server);
|
|
1139
|
-
|
|
1351
|
+
printf("server_uri=%s\n", p);
|
|
1352
|
+
server_uri = pj_str(p);
|
|
1140
1353
|
p += len + 2;
|
|
1141
1354
|
|
|
1142
1355
|
len = sprintf(p, "<sip:%s@%s>", username, domain);
|
|
1143
|
-
|
|
1356
|
+
printf("from_uri=%s\n", p);
|
|
1357
|
+
from_uri = pj_str(p);
|
|
1144
1358
|
p += len + 2;
|
|
1145
1359
|
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
if(c_to_url && c_to_url[0]) {
|
|
1149
|
-
to_url = pj_str((char*)c_to_url);
|
|
1150
|
-
}
|
|
1360
|
+
to_uri = from_uri;
|
|
1151
1361
|
|
|
1152
|
-
if(
|
|
1153
|
-
|
|
1362
|
+
if(c_to_uri && c_to_uri[0]) {
|
|
1363
|
+
printf("c_to_uri=%s\n", c_to_uri);
|
|
1364
|
+
to_uri = pj_str((char*)c_to_uri);
|
|
1154
1365
|
}
|
|
1155
1366
|
|
|
1156
1367
|
len = sprintf(p, "sip:%s@%s:%u", username, local_addr, local_port);
|
|
1157
|
-
|
|
1368
|
+
printf("contact=%s\n", p);
|
|
1369
|
+
contact = pj_str(p);
|
|
1158
1370
|
p += len + 2;
|
|
1159
1371
|
|
|
1160
1372
|
status = pjsip_regc_init(regc,
|
|
1161
|
-
&
|
|
1162
|
-
&
|
|
1163
|
-
&
|
|
1373
|
+
&server_uri,
|
|
1374
|
+
&from_uri,
|
|
1375
|
+
&to_uri,
|
|
1164
1376
|
1, &contact,
|
|
1165
1377
|
expires);
|
|
1166
1378
|
if(status != PJ_SUCCESS)
|
|
1167
1379
|
{
|
|
1168
1380
|
status = pjsip_regc_destroy(regc);
|
|
1169
1381
|
//ToDo: log status
|
|
1170
|
-
PJW_UNLOCK();
|
|
1171
1382
|
set_error("pjsip_regc_init failed");
|
|
1172
|
-
|
|
1383
|
+
goto out;
|
|
1173
1384
|
}
|
|
1174
1385
|
|
|
1175
|
-
pjsip_cred_info cred;
|
|
1176
1386
|
pj_bzero(&cred, sizeof(cred));
|
|
1177
|
-
cred.realm = pj_str("*");
|
|
1178
|
-
cred.scheme = pj_str("digest");
|
|
1387
|
+
cred.realm = pj_str((char*)"*");
|
|
1388
|
+
cred.scheme = pj_str((char*)"digest");
|
|
1179
1389
|
cred.username = pj_str((char*)username);
|
|
1180
1390
|
cred.data_type = PJSIP_CRED_DATA_PLAIN_PASSWD;
|
|
1181
1391
|
cred.data = pj_str((char*)password);
|
|
@@ -1184,12 +1394,10 @@ int pjw_account_create(int t_id, const char *domain, const char *server, const c
|
|
|
1184
1394
|
{
|
|
1185
1395
|
status = pjsip_regc_destroy(regc);
|
|
1186
1396
|
//ToDo: log status
|
|
1187
|
-
PJW_UNLOCK();
|
|
1188
1397
|
set_error("pjsip_regc_set_credentials failed");
|
|
1189
|
-
|
|
1398
|
+
goto out;
|
|
1190
1399
|
}
|
|
1191
1400
|
|
|
1192
|
-
pjsip_tpselector sel;
|
|
1193
1401
|
pj_bzero(&sel, sizeof(sel));
|
|
1194
1402
|
if(t->type == PJSIP_TRANSPORT_UDP) {
|
|
1195
1403
|
sel.type = PJSIP_TPSELECTOR_TRANSPORT;
|
|
@@ -1204,50 +1412,72 @@ int pjw_account_create(int t_id, const char *domain, const char *server, const c
|
|
|
1204
1412
|
{
|
|
1205
1413
|
status = pjsip_regc_destroy(regc);
|
|
1206
1414
|
//ToDo: log status
|
|
1207
|
-
PJW_UNLOCK();
|
|
1208
1415
|
set_error("pjsip_regc_set_transport failed");
|
|
1209
|
-
|
|
1416
|
+
goto out;
|
|
1210
1417
|
}
|
|
1418
|
+
|
|
1419
|
+
out:
|
|
1211
1420
|
PJW_UNLOCK();
|
|
1421
|
+
if(pjw_errorstring[0]){
|
|
1422
|
+
return -1;
|
|
1423
|
+
}
|
|
1424
|
+
|
|
1212
1425
|
*out_acc_id = acc_id;
|
|
1213
1426
|
return 0;
|
|
1214
1427
|
}
|
|
1215
1428
|
|
|
1216
|
-
int pjw_account_register(long acc_id, pj_bool_t autoreg)
|
|
1429
|
+
//int pjw_account_register(long acc_id, pj_bool_t autoreg)
|
|
1430
|
+
int pjw_account_register(long acc_id, const char *json)
|
|
1217
1431
|
{
|
|
1218
1432
|
PJW_LOCK();
|
|
1219
1433
|
clear_error();
|
|
1220
1434
|
|
|
1221
1435
|
long val;
|
|
1436
|
+
pjsip_regc *regc;
|
|
1437
|
+
|
|
1438
|
+
pj_status_t status;
|
|
1439
|
+
pjsip_tx_data *tdata;
|
|
1440
|
+
|
|
1441
|
+
char buffer[MAX_JSON_INPUT];
|
|
1442
|
+
|
|
1443
|
+
bool auto_register = false;
|
|
1444
|
+
|
|
1445
|
+
Document document;
|
|
1222
1446
|
|
|
1223
1447
|
if(!g_account_ids.get(acc_id, val)){
|
|
1224
|
-
PJW_UNLOCK();
|
|
1225
1448
|
set_error("Invalid account_id");
|
|
1226
|
-
|
|
1449
|
+
goto out;
|
|
1227
1450
|
}
|
|
1451
|
+
regc = (pjsip_regc*)val;
|
|
1228
1452
|
|
|
1229
|
-
|
|
1453
|
+
if(!parse_json(document, json, buffer, MAX_JSON_INPUT)) {
|
|
1454
|
+
goto out;
|
|
1455
|
+
}
|
|
1230
1456
|
|
|
1231
|
-
|
|
1232
|
-
|
|
1457
|
+
if(!json_get_bool_param(document, "auto_register", true, &auto_register)) {
|
|
1458
|
+
goto out;
|
|
1459
|
+
}
|
|
1233
1460
|
|
|
1234
|
-
status = pjsip_regc_register(regc,
|
|
1461
|
+
status = pjsip_regc_register(regc, auto_register, &tdata);
|
|
1235
1462
|
if(status != PJ_SUCCESS)
|
|
1236
1463
|
{
|
|
1237
|
-
PJW_UNLOCK();
|
|
1238
1464
|
set_error("pjsip_regc_register failed");
|
|
1239
|
-
|
|
1465
|
+
goto out;
|
|
1240
1466
|
}
|
|
1241
1467
|
|
|
1242
1468
|
status = pjsip_regc_send(regc, tdata);
|
|
1243
1469
|
if(status != PJ_SUCCESS)
|
|
1244
1470
|
{
|
|
1245
|
-
PJW_UNLOCK();
|
|
1246
1471
|
set_error("pjsip_regc_send failed");
|
|
1247
|
-
|
|
1472
|
+
goto out;
|
|
1248
1473
|
}
|
|
1249
1474
|
|
|
1475
|
+
out:
|
|
1250
1476
|
PJW_UNLOCK();
|
|
1477
|
+
if(pjw_errorstring[0]){
|
|
1478
|
+
return -1;
|
|
1479
|
+
}
|
|
1480
|
+
|
|
1251
1481
|
return 0;
|
|
1252
1482
|
}
|
|
1253
1483
|
|
|
@@ -1258,63 +1488,90 @@ int pjw_account_unregister(long acc_id)
|
|
|
1258
1488
|
|
|
1259
1489
|
long val;
|
|
1260
1490
|
|
|
1261
|
-
|
|
1262
|
-
PJW_UNLOCK();
|
|
1263
|
-
set_error("Invalid account_id");
|
|
1264
|
-
return -1;
|
|
1265
|
-
}
|
|
1266
|
-
|
|
1267
|
-
pjsip_regc *regc = (pjsip_regc*)val;
|
|
1491
|
+
pjsip_regc *regc;
|
|
1268
1492
|
|
|
1269
1493
|
pj_status_t status;
|
|
1270
1494
|
pjsip_tx_data *tdata;
|
|
1271
1495
|
|
|
1496
|
+
if(!g_account_ids.get(acc_id, val)){
|
|
1497
|
+
set_error("Invalid account_id");
|
|
1498
|
+
goto out;
|
|
1499
|
+
}
|
|
1500
|
+
regc = (pjsip_regc*)val;
|
|
1501
|
+
|
|
1272
1502
|
status = pjsip_regc_unregister(regc, &tdata);
|
|
1273
1503
|
if(status != PJ_SUCCESS)
|
|
1274
1504
|
{
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
return -1;
|
|
1505
|
+
set_error("pjsip_regc_unregister failed with status=%i", status);
|
|
1506
|
+
goto out;
|
|
1278
1507
|
}
|
|
1279
1508
|
|
|
1280
1509
|
status = pjsip_regc_send(regc, tdata);
|
|
1281
1510
|
if(status != PJ_SUCCESS)
|
|
1282
1511
|
{
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
return -1;
|
|
1512
|
+
set_error("pjsip_regc_send failed with status=%i", status);
|
|
1513
|
+
goto out;
|
|
1286
1514
|
}
|
|
1287
1515
|
|
|
1516
|
+
out:
|
|
1288
1517
|
PJW_UNLOCK();
|
|
1518
|
+
if(pjw_errorstring[0]){
|
|
1519
|
+
return -1;
|
|
1520
|
+
}
|
|
1521
|
+
|
|
1289
1522
|
return 0;
|
|
1290
1523
|
}
|
|
1291
1524
|
|
|
1292
|
-
int pjw_call_respond(long call_id, int code, const char *reason, const char *additional_headers)
|
|
1525
|
+
//int pjw_call_respond(long call_id, int code, const char *reason, const char *additional_headers)
|
|
1526
|
+
int pjw_call_respond(long call_id, const char *json)
|
|
1293
1527
|
{
|
|
1294
|
-
printf("pjw_call_respond: call_id=%
|
|
1528
|
+
printf("pjw_call_respond: call_id=%lu json=%s\n", call_id, json);
|
|
1295
1529
|
PJW_LOCK();
|
|
1530
|
+
clear_error();
|
|
1296
1531
|
|
|
1297
1532
|
long val;
|
|
1298
1533
|
|
|
1534
|
+
int code;
|
|
1535
|
+
char *reason;
|
|
1536
|
+
|
|
1537
|
+
pj_str_t r;// pj_str((char*)reason);
|
|
1538
|
+
|
|
1539
|
+
pj_status_t status;
|
|
1540
|
+
|
|
1541
|
+
pjsip_tx_data *tdata;
|
|
1542
|
+
|
|
1543
|
+
Call *call;
|
|
1544
|
+
|
|
1545
|
+
char *additional_headers = NULL;
|
|
1546
|
+
|
|
1547
|
+
char buffer[MAX_JSON_INPUT];
|
|
1548
|
+
|
|
1549
|
+
Document document;
|
|
1550
|
+
|
|
1299
1551
|
if(!g_call_ids.get(call_id, val)){
|
|
1300
|
-
PJW_UNLOCK();
|
|
1301
1552
|
set_error("Invalid call_id");
|
|
1302
|
-
|
|
1553
|
+
goto out;
|
|
1303
1554
|
}
|
|
1304
|
-
|
|
1305
|
-
Call *call = (Call*)val;
|
|
1555
|
+
call = (Call*)val;
|
|
1306
1556
|
|
|
1307
1557
|
if(call->outgoing) {
|
|
1308
|
-
PJW_UNLOCK();
|
|
1309
1558
|
set_error("You cannot respond an outgoing call");
|
|
1310
|
-
|
|
1559
|
+
goto out;
|
|
1311
1560
|
}
|
|
1312
1561
|
|
|
1313
|
-
|
|
1562
|
+
if(!parse_json(document, json, buffer, MAX_JSON_INPUT)) {
|
|
1563
|
+
goto out;
|
|
1564
|
+
}
|
|
1314
1565
|
|
|
1315
|
-
|
|
1566
|
+
if(!json_get_int_param(document, "code", true, &code)) {
|
|
1567
|
+
goto out;
|
|
1568
|
+
}
|
|
1316
1569
|
|
|
1317
|
-
|
|
1570
|
+
if(!json_get_string_param(document, "reason", true, &reason)) {
|
|
1571
|
+
goto out;
|
|
1572
|
+
}
|
|
1573
|
+
|
|
1574
|
+
r = pj_str((char*)reason);
|
|
1318
1575
|
|
|
1319
1576
|
if(call->initial_invite_rdata) {
|
|
1320
1577
|
status = pjsip_inv_initial_answer(call->inv, call->initial_invite_rdata,
|
|
@@ -1323,16 +1580,14 @@ int pjw_call_respond(long call_id, int code, const char *reason, const char *add
|
|
|
1323
1580
|
NULL,
|
|
1324
1581
|
&tdata);
|
|
1325
1582
|
if(status != PJ_SUCCESS) {
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
return -1;
|
|
1583
|
+
set_error("pjsip_inv_initial_answer failed with status=%i", status);
|
|
1584
|
+
goto out;
|
|
1329
1585
|
}
|
|
1330
1586
|
|
|
1331
1587
|
status = pjsip_rx_data_free_cloned(call->initial_invite_rdata);
|
|
1332
1588
|
if(status != PJ_SUCCESS) {
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
return -1;
|
|
1589
|
+
set_error("pjsip_rx_data_free_cloned failed with status=%i", status);
|
|
1590
|
+
goto out;
|
|
1336
1591
|
}
|
|
1337
1592
|
call->initial_invite_rdata = 0;
|
|
1338
1593
|
} else {
|
|
@@ -1343,9 +1598,8 @@ int pjw_call_respond(long call_id, int code, const char *reason, const char *add
|
|
|
1343
1598
|
&tdata);
|
|
1344
1599
|
|
|
1345
1600
|
if(status != PJ_SUCCESS){
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
return -1;
|
|
1601
|
+
set_error("pjsip_inv_answer failed with status=%i", status);
|
|
1602
|
+
goto out;
|
|
1349
1603
|
}
|
|
1350
1604
|
|
|
1351
1605
|
if(!add_additional_headers(call->inv->dlg->pool, tdata, additional_headers)) {
|
|
@@ -1355,138 +1609,214 @@ int pjw_call_respond(long call_id, int code, const char *reason, const char *add
|
|
|
1355
1609
|
|
|
1356
1610
|
status = pjsip_inv_send_msg(call->inv, tdata);
|
|
1357
1611
|
if(status != PJ_SUCCESS){
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
return -1;
|
|
1612
|
+
set_error("pjsip_inv_send_msg failed with status=%i", status);
|
|
1613
|
+
goto out;
|
|
1361
1614
|
}
|
|
1362
1615
|
|
|
1363
1616
|
out:
|
|
1364
1617
|
PJW_UNLOCK();
|
|
1365
|
-
|
|
1366
1618
|
if(pjw_errorstring[0]) {
|
|
1367
1619
|
return -1;
|
|
1368
1620
|
}
|
|
1369
|
-
|
|
1370
1621
|
return 0;
|
|
1371
1622
|
}
|
|
1372
1623
|
|
|
1373
|
-
int pjw_call_terminate(long call_id, int code, const char *reason, const char *additional_headers)
|
|
1624
|
+
//int pjw_call_terminate(long call_id, int code, const char *reason, const char *additional_headers)
|
|
1625
|
+
int pjw_call_terminate(long call_id, const char *json)
|
|
1374
1626
|
{
|
|
1375
1627
|
PJW_LOCK();
|
|
1628
|
+
clear_error();
|
|
1376
1629
|
|
|
1377
1630
|
long val;
|
|
1631
|
+
pjsip_tx_data *tdata;
|
|
1632
|
+
pj_status_t status;
|
|
1633
|
+
int code = 0;
|
|
1634
|
+
char *reason = (char*)"";
|
|
1635
|
+
pj_str_t r;// = pj_str((char*)reason);
|
|
1636
|
+
|
|
1637
|
+
const char *additional_headers;
|
|
1638
|
+
|
|
1639
|
+
Call *call;
|
|
1640
|
+
|
|
1641
|
+
char buffer[MAX_JSON_INPUT];
|
|
1642
|
+
|
|
1643
|
+
Document document;
|
|
1378
1644
|
|
|
1379
1645
|
if(!g_call_ids.get(call_id, val)){
|
|
1380
|
-
PJW_UNLOCK();
|
|
1381
1646
|
set_error("Invalid call_id");
|
|
1382
|
-
|
|
1647
|
+
goto out;
|
|
1383
1648
|
}
|
|
1649
|
+
call = (Call*)val;
|
|
1384
1650
|
|
|
1385
|
-
|
|
1651
|
+
if(!parse_json(document, json, buffer, MAX_JSON_INPUT)) {
|
|
1652
|
+
goto out;
|
|
1653
|
+
}
|
|
1386
1654
|
|
|
1387
|
-
|
|
1655
|
+
if(!json_get_int_param(document, "code", true, &code)) {
|
|
1656
|
+
goto out;
|
|
1657
|
+
}
|
|
1658
|
+
|
|
1659
|
+
if(!json_get_string_param(document, "reason", true, &reason)) {
|
|
1660
|
+
goto out;
|
|
1661
|
+
}
|
|
1662
|
+
|
|
1663
|
+
r = pj_str((char*)reason);
|
|
1388
1664
|
|
|
1389
|
-
pjsip_tx_data *tdata;
|
|
1390
|
-
pj_status_t status;
|
|
1391
1665
|
status = pjsip_inv_end_session(call->inv,
|
|
1392
1666
|
code,
|
|
1393
1667
|
&r,
|
|
1394
1668
|
&tdata);
|
|
1395
1669
|
if(status != PJ_SUCCESS){
|
|
1396
|
-
PJW_UNLOCK();
|
|
1397
1670
|
set_error("pjsip_inv_end_session failed");
|
|
1398
|
-
|
|
1671
|
+
goto out;
|
|
1399
1672
|
}
|
|
1400
1673
|
|
|
1401
1674
|
if(!tdata)
|
|
1402
1675
|
{
|
|
1403
1676
|
//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.
|
|
1404
|
-
|
|
1405
|
-
return 0;
|
|
1677
|
+
goto out;
|
|
1406
1678
|
}
|
|
1407
1679
|
|
|
1408
1680
|
if(!add_additional_headers(call->inv->dlg->pool, tdata, additional_headers)) {
|
|
1409
|
-
PJW_UNLOCK();
|
|
1410
1681
|
set_error("add_additional_headers failed");
|
|
1411
|
-
|
|
1682
|
+
goto out;
|
|
1412
1683
|
}
|
|
1413
1684
|
|
|
1414
1685
|
status = pjsip_inv_send_msg(call->inv, tdata);
|
|
1415
1686
|
if(status != PJ_SUCCESS){
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
return -1;
|
|
1687
|
+
set_error("pjsip_inv_send_msg failed with status=%i", status);
|
|
1688
|
+
goto out;
|
|
1419
1689
|
}
|
|
1420
1690
|
|
|
1691
|
+
out:
|
|
1421
1692
|
PJW_UNLOCK();
|
|
1693
|
+
if(pjw_errorstring[0]){
|
|
1694
|
+
return -1;
|
|
1695
|
+
}
|
|
1696
|
+
|
|
1422
1697
|
return 0;
|
|
1423
1698
|
}
|
|
1424
1699
|
|
|
1425
1700
|
|
|
1426
|
-
int pjw_call_create(long t_id, unsigned flags, const char *from_uri, const char *to_uri, const char *request_uri, const char *proxy_uri, const char *additional_headers, const char *realm, const char *username, const char *password, long *out_call_id, char *out_sip_call_id)
|
|
1701
|
+
//int pjw_call_create(long t_id, unsigned flags, const char *from_uri, const char *to_uri, const char *request_uri, const char *proxy_uri, const char *additional_headers, const char *realm, const char *username, const char *password, long *out_call_id, char *out_sip_call_id)
|
|
1702
|
+
int pjw_call_create(long t_id, const char *json, long *out_call_id, char *out_sip_call_id)
|
|
1427
1703
|
{
|
|
1428
1704
|
PJW_LOCK();
|
|
1429
1705
|
clear_error();
|
|
1430
1706
|
|
|
1431
|
-
int n;
|
|
1707
|
+
//int n;
|
|
1432
1708
|
long val;
|
|
1433
1709
|
Transport *t;
|
|
1434
|
-
char *start;
|
|
1435
|
-
char *end;
|
|
1710
|
+
//char *start;
|
|
1711
|
+
//char *end;
|
|
1436
1712
|
char local_contact[400];
|
|
1437
|
-
char *p;
|
|
1438
|
-
int len;
|
|
1713
|
+
//char *p;
|
|
1714
|
+
//int len;
|
|
1439
1715
|
const char *contact_username = "sip";
|
|
1440
1716
|
int call_id;
|
|
1441
1717
|
|
|
1718
|
+
char *from_uri = NULL;
|
|
1719
|
+
char *to_uri = NULL;
|
|
1720
|
+
char *request_uri = NULL;
|
|
1721
|
+
char *proxy_uri = NULL;
|
|
1722
|
+
|
|
1723
|
+
char *headers = NULL;
|
|
1724
|
+
|
|
1725
|
+
char *realm = NULL;
|
|
1726
|
+
char *username = NULL;
|
|
1727
|
+
char *password = NULL;
|
|
1728
|
+
|
|
1729
|
+
unsigned flags = 0;
|
|
1442
1730
|
|
|
1443
1731
|
pjsip_dialog *dlg;
|
|
1444
1732
|
|
|
1733
|
+
char buffer[MAX_JSON_INPUT];
|
|
1734
|
+
|
|
1735
|
+
Document document;
|
|
1736
|
+
|
|
1445
1737
|
if(!g_transport_ids.get(t_id, val)){
|
|
1446
1738
|
set_error("Invalid transport_id");
|
|
1447
1739
|
goto out;
|
|
1448
1740
|
}
|
|
1449
1741
|
t = (Transport*)val;
|
|
1450
1742
|
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
}
|
|
1743
|
+
if(!parse_json(document, json, buffer, MAX_JSON_INPUT)) {
|
|
1744
|
+
goto out;
|
|
1745
|
+
}
|
|
1455
1746
|
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1747
|
+
if(!json_get_and_check_uri(document, "from_uri", false, &from_uri)) {
|
|
1748
|
+
goto out;
|
|
1749
|
+
}
|
|
1750
|
+
|
|
1751
|
+
if(!json_get_and_check_uri(document, "to_uri", false, &to_uri)) {
|
|
1752
|
+
goto out;
|
|
1753
|
+
}
|
|
1754
|
+
|
|
1755
|
+
request_uri = to_uri;
|
|
1756
|
+
if(!json_get_and_check_uri(document, "request_uri", true, &request_uri)) {
|
|
1757
|
+
goto out;
|
|
1758
|
+
}
|
|
1759
|
+
|
|
1760
|
+
if(!json_get_and_check_uri(document, "proxy_uri", true, &proxy_uri)) {
|
|
1761
|
+
goto out;
|
|
1762
|
+
}
|
|
1763
|
+
|
|
1764
|
+
/*
|
|
1765
|
+
const Value& headers = document["headers"];
|
|
1766
|
+
if(document.HasMember("headers") {
|
|
1767
|
+
if(!headers.IsArray()) {
|
|
1768
|
+
set_error("headers must be an array");
|
|
1769
|
+
goto out;
|
|
1459
1770
|
}
|
|
1771
|
+
}
|
|
1772
|
+
*/
|
|
1460
1773
|
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1774
|
+
if(document.HasMember("auth")) {
|
|
1775
|
+
if(!document["auth"].IsObject()) {
|
|
1776
|
+
set_error("Parameter auth must be an object");
|
|
1777
|
+
goto out;
|
|
1778
|
+
} else {
|
|
1779
|
+
const Value& auth = document["auth"];
|
|
1780
|
+
|
|
1781
|
+
for (Value::ConstMemberIterator itr = auth.MemberBegin(); itr != auth.MemberEnd(); ++itr) {
|
|
1782
|
+
const char *name = itr->name.GetString();
|
|
1783
|
+
if(strcmp(name, "realm") == 0) {
|
|
1784
|
+
if(!itr->value.IsString()) {
|
|
1785
|
+
set_error("%s must be a string", itr->name.GetString());
|
|
1786
|
+
goto out;
|
|
1787
|
+
}
|
|
1788
|
+
realm = (char*)itr->value.GetString();
|
|
1789
|
+
} else if(strcmp(name, "username") == 0) {
|
|
1790
|
+
if(!itr->value.IsString()) {
|
|
1791
|
+
set_error("%s must be a string", itr->name.GetString());
|
|
1792
|
+
goto out;
|
|
1793
|
+
}
|
|
1794
|
+
username = (char*)itr->value.GetString();
|
|
1795
|
+
contact_username = username;
|
|
1796
|
+
} else if(strcmp(name, "password") == 0) {
|
|
1797
|
+
if(!itr->value.IsString()) {
|
|
1798
|
+
set_error("%s must be a string", itr->name.GetString());
|
|
1799
|
+
goto out;
|
|
1800
|
+
}
|
|
1801
|
+
password = (char*)itr->value.GetString();
|
|
1467
1802
|
} else {
|
|
1468
|
-
|
|
1803
|
+
set_error("Unknown auth paramter %s", itr->name.GetString());
|
|
1804
|
+
goto out;
|
|
1469
1805
|
}
|
|
1470
|
-
|
|
1471
|
-
request_uri = to_uri;
|
|
1806
|
+
}
|
|
1472
1807
|
}
|
|
1808
|
+
}
|
|
1473
1809
|
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1810
|
+
if(document.HasMember("delayed_media")) {
|
|
1811
|
+
if(!document["delayed_media"].IsBool()) {
|
|
1812
|
+
set_error("Parameter delayed_media must be a boolean");
|
|
1813
|
+
goto out;
|
|
1814
|
+
} else {
|
|
1815
|
+
if(document["delayed_media"].GetBool()) {
|
|
1816
|
+
flags = flags | CALL_FLAG_DELAYED_MEDIA;
|
|
1817
|
+
}
|
|
1481
1818
|
}
|
|
1482
|
-
|
|
1483
|
-
if(realm){
|
|
1484
|
-
if(!username || !password) {
|
|
1485
|
-
set_error("Incomplete credentials");
|
|
1486
|
-
goto out;
|
|
1487
|
-
}
|
|
1488
|
-
contact_username = username;
|
|
1489
|
-
}
|
|
1819
|
+
}
|
|
1490
1820
|
|
|
1491
1821
|
if(t->type == PJSIP_TRANSPORT_UDP) {
|
|
1492
1822
|
build_local_contact(local_contact, t->sip_transport, contact_username);
|
|
@@ -1498,7 +1828,7 @@ int pjw_call_create(long t_id, unsigned flags, const char *from_uri, const char
|
|
|
1498
1828
|
goto out;
|
|
1499
1829
|
}
|
|
1500
1830
|
|
|
1501
|
-
call_id = call_create(t, flags, dlg, proxy_uri,
|
|
1831
|
+
call_id = call_create(t, flags, dlg, proxy_uri, headers);
|
|
1502
1832
|
if(call_id < 0) {
|
|
1503
1833
|
goto out;
|
|
1504
1834
|
}
|
|
@@ -1620,6 +1950,7 @@ bool set_proxy(pjsip_dialog *dlg, const char *proxy_uri) {
|
|
|
1620
1950
|
NULL);
|
|
1621
1951
|
if(!route){
|
|
1622
1952
|
status = pjsip_dlg_terminate(dlg); //ToDo:
|
|
1953
|
+
printf("pjsip_dlg_terminate status=%i\n", status);
|
|
1623
1954
|
set_error("pjsip_parse_hdr failed");
|
|
1624
1955
|
return false;
|
|
1625
1956
|
}
|
|
@@ -1658,7 +1989,7 @@ bool dlg_create(pjsip_dialog **dlg, Transport *transport, const char *from_uri,
|
|
|
1658
1989
|
|
|
1659
1990
|
if(realm && realm[0]){
|
|
1660
1991
|
pjsip_cred_info cred[1];
|
|
1661
|
-
cred[0].scheme = pj_str("digest");
|
|
1992
|
+
cred[0].scheme = pj_str((char*)"digest");
|
|
1662
1993
|
cred[0].realm = pj_str((char*)realm);
|
|
1663
1994
|
cred[0].username = pj_str((char*)username);
|
|
1664
1995
|
cred[0].data_type = PJSIP_CRED_DATA_PLAIN_PASSWD;
|
|
@@ -1671,7 +2002,8 @@ bool dlg_create(pjsip_dialog **dlg, Transport *transport, const char *from_uri,
|
|
|
1671
2002
|
}
|
|
1672
2003
|
}
|
|
1673
2004
|
|
|
1674
|
-
|
|
2005
|
+
*dlg = p_dlg;
|
|
2006
|
+
return true;
|
|
1675
2007
|
}
|
|
1676
2008
|
|
|
1677
2009
|
|
|
@@ -1706,7 +2038,7 @@ int call_create(Transport *t, unsigned flags, pjsip_dialog *dlg, const char *pro
|
|
|
1706
2038
|
|
|
1707
2039
|
pjmedia_sdp_session *sdp = 0;
|
|
1708
2040
|
|
|
1709
|
-
if(!(flags &
|
|
2041
|
+
if(!(flags & CALL_FLAG_DELAYED_MEDIA)) {
|
|
1710
2042
|
status = pjmedia_endpt_create_sdp( g_med_endpt,
|
|
1711
2043
|
dlg->pool,
|
|
1712
2044
|
1,
|
|
@@ -1800,7 +2132,8 @@ int call_create(Transport *t, unsigned flags, pjsip_dialog *dlg, const char *pro
|
|
|
1800
2132
|
return call_id;
|
|
1801
2133
|
}
|
|
1802
2134
|
|
|
1803
|
-
int pjw_call_send_dtmf(long call_id, const char *digits, int mode)
|
|
2135
|
+
//int pjw_call_send_dtmf(long call_id, const char *digits, int mode)
|
|
2136
|
+
int pjw_call_send_dtmf(long call_id, const char *json)
|
|
1804
2137
|
{
|
|
1805
2138
|
#define ON_DURATION 200
|
|
1806
2139
|
#define OFF_DURATION 50
|
|
@@ -1808,38 +2141,61 @@ int pjw_call_send_dtmf(long call_id, const char *digits, int mode)
|
|
|
1808
2141
|
#define MAX_LENGTH 31 // pjsip allows for 31 digits (inband allows for 32 digits)
|
|
1809
2142
|
|
|
1810
2143
|
PJW_LOCK();
|
|
1811
|
-
|
|
2144
|
+
clear_error();
|
|
1812
2145
|
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
return -1;
|
|
1817
|
-
}
|
|
2146
|
+
long val;
|
|
2147
|
+
char *digits;
|
|
2148
|
+
int mode = 0;;
|
|
1818
2149
|
|
|
1819
|
-
|
|
1820
|
-
set_error("DTMF list too long");
|
|
1821
|
-
return -1;
|
|
1822
|
-
}
|
|
2150
|
+
int len;
|
|
1823
2151
|
|
|
1824
|
-
|
|
2152
|
+
char adjusted_digits[MAX_LENGTH+1]; // use the greater size
|
|
2153
|
+
|
|
2154
|
+
pj_str_t ds;
|
|
2155
|
+
pj_status_t status;
|
|
2156
|
+
|
|
2157
|
+
Call *call;
|
|
2158
|
+
|
|
2159
|
+
char buffer[MAX_JSON_INPUT];
|
|
2160
|
+
|
|
2161
|
+
Document document;
|
|
2162
|
+
|
|
2163
|
+
if(!parse_json(document, json, buffer, MAX_JSON_INPUT)) {
|
|
2164
|
+
goto out;
|
|
2165
|
+
}
|
|
1825
2166
|
|
|
1826
2167
|
if(!g_call_ids.get(call_id, val)){
|
|
1827
|
-
PJW_UNLOCK();
|
|
1828
2168
|
set_error("Invalid call_id");
|
|
1829
|
-
|
|
2169
|
+
goto out;
|
|
1830
2170
|
}
|
|
2171
|
+
call = (Call*)val;
|
|
1831
2172
|
|
|
1832
|
-
|
|
2173
|
+
if(!json_get_string_param(document, "digits", false, &digits)) {
|
|
2174
|
+
goto out;
|
|
2175
|
+
}
|
|
2176
|
+
|
|
2177
|
+
if(!json_get_int_param(document, "mode", false, &mode)) {
|
|
2178
|
+
goto out;
|
|
2179
|
+
}
|
|
2180
|
+
|
|
2181
|
+
if(mode != DTMF_MODE_RFC2833 && mode != DTMF_MODE_INBAND) {
|
|
2182
|
+
set_error("Invalid DTMF mode. It must be eiter 0 (RFC2833) or 1 (INBAND).");
|
|
2183
|
+
goto out;
|
|
2184
|
+
}
|
|
2185
|
+
|
|
2186
|
+
len = strlen(digits);
|
|
2187
|
+
|
|
2188
|
+
if(len > MAX_LENGTH) {
|
|
2189
|
+
set_error("DTMF string too long");
|
|
2190
|
+
goto out;
|
|
2191
|
+
}
|
|
1833
2192
|
|
|
1834
2193
|
if(!call->med_stream)
|
|
1835
2194
|
{
|
|
1836
|
-
PJW_UNLOCK();
|
|
1837
2195
|
set_error("Unable to send DTMF: Media not ready");
|
|
1838
|
-
|
|
2196
|
+
goto out;
|
|
1839
2197
|
}
|
|
1840
2198
|
|
|
1841
|
-
char adjusted_digits[MAX_LENGTH+1]; // use the greater size
|
|
1842
|
-
|
|
1843
2199
|
for(int i=0; i<len ; ++i) {
|
|
1844
2200
|
if( !(digits[i] >= '0' && digits[i] <= '9') &&
|
|
1845
2201
|
!(digits[i] >= 'a' && digits[i] <= 'f') &&
|
|
@@ -1847,9 +2203,8 @@ int pjw_call_send_dtmf(long call_id, const char *digits, int mode)
|
|
|
1847
2203
|
!(digits[i] == '*') &&
|
|
1848
2204
|
!(digits[i] == '#') )
|
|
1849
2205
|
{
|
|
1850
|
-
PJW_UNLOCK();
|
|
1851
2206
|
set_error("Invalid character");
|
|
1852
|
-
|
|
2207
|
+
goto out;
|
|
1853
2208
|
}
|
|
1854
2209
|
char d = digits[i];
|
|
1855
2210
|
if(d == 'e' || d == 'E') {
|
|
@@ -1863,22 +2218,19 @@ int pjw_call_send_dtmf(long call_id, const char *digits, int mode)
|
|
|
1863
2218
|
adjusted_digits[len] = 0;
|
|
1864
2219
|
//addon_log(LOG_LEVEL_DEBUG, ">>%s<<\n", adjusted_digits);
|
|
1865
2220
|
|
|
1866
|
-
|
|
1867
|
-
pj_status_t status;
|
|
2221
|
+
ds = pj_str((char*)adjusted_digits);
|
|
1868
2222
|
|
|
1869
2223
|
if(DTMF_MODE_RFC2833 == mode) {
|
|
1870
2224
|
status = pjmedia_stream_dial_dtmf(call->med_stream, &ds);
|
|
1871
2225
|
if(status != PJ_SUCCESS)
|
|
1872
2226
|
{
|
|
1873
|
-
PJW_UNLOCK();
|
|
1874
2227
|
set_error("pjmedia_stream_dial_dtmf failed.");
|
|
1875
|
-
|
|
2228
|
+
goto out;
|
|
1876
2229
|
}
|
|
1877
2230
|
} else {
|
|
1878
2231
|
if(!prepare_tonegen(call)) {
|
|
1879
|
-
PJW_UNLOCK();
|
|
1880
2232
|
set_error("prepare_tonegen failed.");
|
|
1881
|
-
|
|
2233
|
+
goto out;
|
|
1882
2234
|
}
|
|
1883
2235
|
|
|
1884
2236
|
for(int i=0; i<len ; ++i) {
|
|
@@ -1889,38 +2241,72 @@ int pjw_call_send_dtmf(long call_id, const char *digits, int mode)
|
|
|
1889
2241
|
tone.volume = 0;
|
|
1890
2242
|
status = chainlink_tonegen_play_digits((pjmedia_port*)call->tonegen, 1, &tone, 0);
|
|
1891
2243
|
if(status != PJ_SUCCESS) {
|
|
1892
|
-
PJW_UNLOCK();
|
|
1893
2244
|
set_error("chainlink_tonegen_play_digits failed.");
|
|
1894
|
-
|
|
2245
|
+
goto out;
|
|
1895
2246
|
}
|
|
1896
2247
|
}
|
|
1897
2248
|
}
|
|
1898
2249
|
|
|
2250
|
+
out:
|
|
1899
2251
|
PJW_UNLOCK();
|
|
2252
|
+
if(pjw_errorstring[0]){
|
|
2253
|
+
return -1;
|
|
2254
|
+
}
|
|
2255
|
+
|
|
1900
2256
|
return 0;
|
|
1901
2257
|
}
|
|
1902
2258
|
|
|
1903
|
-
int pjw_call_reinvite(long call_id, int hold, unsigned flags)
|
|
2259
|
+
//int pjw_call_reinvite(long call_id, int hold, unsigned flags)
|
|
2260
|
+
int pjw_call_reinvite(long call_id, const char *json)
|
|
1904
2261
|
{
|
|
1905
2262
|
PJW_LOCK();
|
|
2263
|
+
clear_error();
|
|
2264
|
+
|
|
2265
|
+
bool hold = false;
|
|
2266
|
+
unsigned flags;
|
|
1906
2267
|
|
|
1907
2268
|
long val;
|
|
2269
|
+
Call *call;
|
|
2270
|
+
|
|
2271
|
+
pj_status_t status;
|
|
2272
|
+
|
|
2273
|
+
const pjmedia_sdp_session *old_sdp = NULL;
|
|
2274
|
+
|
|
2275
|
+
pjsip_tx_data *tdata;
|
|
2276
|
+
pjmedia_sdp_session *sdp = 0;
|
|
2277
|
+
|
|
2278
|
+
char buffer[MAX_JSON_INPUT];
|
|
2279
|
+
|
|
2280
|
+
Document document;
|
|
1908
2281
|
|
|
1909
2282
|
if(!g_call_ids.get(call_id, val)){
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
return -1;
|
|
2283
|
+
set_error("Invalid call_id");
|
|
2284
|
+
goto out;
|
|
1913
2285
|
}
|
|
2286
|
+
call = (Call*)val;
|
|
1914
2287
|
|
|
1915
|
-
|
|
2288
|
+
if(!parse_json(document, json, buffer, MAX_JSON_INPUT)) {
|
|
2289
|
+
goto out;
|
|
2290
|
+
}
|
|
1916
2291
|
|
|
1917
|
-
|
|
2292
|
+
if(!json_get_bool_param(document, "hold", true, &hold)) {
|
|
2293
|
+
goto out;
|
|
2294
|
+
}
|
|
1918
2295
|
|
|
1919
|
-
|
|
2296
|
+
if(document.HasMember("delayed_media")) {
|
|
2297
|
+
if(!document["delayed_media"].IsBool()) {
|
|
2298
|
+
set_error("Parameter delayed_media must be a boolean");
|
|
2299
|
+
goto out;
|
|
2300
|
+
} else {
|
|
2301
|
+
if(document["delayed_media"].GetBool()) {
|
|
2302
|
+
flags = flags | CALL_FLAG_DELAYED_MEDIA;
|
|
2303
|
+
}
|
|
2304
|
+
}
|
|
2305
|
+
}
|
|
1920
2306
|
|
|
1921
2307
|
call->local_hold = hold;
|
|
1922
2308
|
|
|
1923
|
-
if(!(flags &
|
|
2309
|
+
if(!(flags & CALL_FLAG_DELAYED_MEDIA)) {
|
|
1924
2310
|
pjmedia_transport_info tpinfo;
|
|
1925
2311
|
pjmedia_transport_info_init(&tpinfo);
|
|
1926
2312
|
pjmedia_transport_get_info(call->med_transport,&tpinfo);
|
|
@@ -1931,9 +2317,8 @@ int pjw_call_reinvite(long call_id, int hold, unsigned flags)
|
|
|
1931
2317
|
&tpinfo.sock_info,
|
|
1932
2318
|
&sdp);
|
|
1933
2319
|
if(status != PJ_SUCCESS){
|
|
1934
|
-
PJW_UNLOCK();
|
|
1935
2320
|
set_error("pjmedia_endpt_create_sdp failed");
|
|
1936
|
-
|
|
2321
|
+
goto out;
|
|
1937
2322
|
}
|
|
1938
2323
|
|
|
1939
2324
|
pjmedia_sdp_attr *attr;
|
|
@@ -1957,47 +2342,55 @@ int pjw_call_reinvite(long call_id, int hold, unsigned flags)
|
|
|
1957
2342
|
|
|
1958
2343
|
pjmedia_sdp_media_add_attr(sdp->media[0], attr);
|
|
1959
2344
|
|
|
1960
|
-
|
|
2345
|
+
old_sdp = NULL;
|
|
1961
2346
|
|
|
1962
2347
|
status = pjmedia_sdp_neg_get_active_local(call->inv->neg, &old_sdp);
|
|
1963
2348
|
if (status != PJ_SUCCESS || old_sdp == NULL){
|
|
1964
|
-
PJW_UNLOCK();
|
|
1965
2349
|
set_error("pjmedia_sdp_neg_get_active failed");
|
|
1966
|
-
|
|
2350
|
+
goto out;
|
|
1967
2351
|
}
|
|
1968
2352
|
|
|
1969
2353
|
sdp->origin.version = old_sdp->origin.version + 1;
|
|
1970
2354
|
}
|
|
1971
2355
|
|
|
1972
|
-
pjsip_tx_data *tdata;
|
|
1973
2356
|
status = pjsip_inv_reinvite(call->inv, NULL, sdp, &tdata);
|
|
1974
2357
|
if(status != PJ_SUCCESS){
|
|
1975
|
-
PJW_UNLOCK();
|
|
1976
2358
|
set_error("pjsip_inv_reinvite failed");
|
|
1977
|
-
|
|
2359
|
+
goto out;
|
|
1978
2360
|
}
|
|
1979
2361
|
|
|
1980
2362
|
status = pjsip_inv_send_msg(call->inv, tdata);
|
|
1981
2363
|
if(status != PJ_SUCCESS){
|
|
1982
|
-
PJW_UNLOCK();
|
|
1983
2364
|
set_error("pjsip_inv_send_msg failed");
|
|
1984
|
-
|
|
2365
|
+
goto out;
|
|
1985
2366
|
}
|
|
1986
2367
|
|
|
2368
|
+
out:
|
|
1987
2369
|
PJW_UNLOCK();
|
|
2370
|
+
if(pjw_errorstring[0]){
|
|
2371
|
+
return -1;
|
|
2372
|
+
}
|
|
2373
|
+
|
|
1988
2374
|
return 0;
|
|
1989
2375
|
}
|
|
1990
2376
|
|
|
1991
2377
|
//To send INFO and other requests inside dialog
|
|
1992
|
-
int pjw_call_send_request(long call_id, const char *method_name, const char *additional_headers, const char *body, const char *ct_type, const char *ct_subtype)
|
|
2378
|
+
//int pjw_call_send_request(long call_id, const char *method_name, const char *additional_headers, const char *body, const char *ct_type, const char *ct_subtype)
|
|
2379
|
+
int pjw_call_send_request(long call_id, const char *json)
|
|
1993
2380
|
{
|
|
1994
2381
|
PJW_LOCK();
|
|
1995
2382
|
clear_error();
|
|
1996
2383
|
|
|
1997
|
-
|
|
2384
|
+
char *method = NULL;
|
|
2385
|
+
char *additional_headers = NULL;
|
|
2386
|
+
char *body = NULL;
|
|
2387
|
+
char *ct_type = NULL;
|
|
2388
|
+
char *ct_subtype = NULL;
|
|
2389
|
+
|
|
2390
|
+
pj_str_t s_method;
|
|
1998
2391
|
pjsip_tx_data *tdata;
|
|
1999
2392
|
pj_status_t status;
|
|
2000
|
-
pjsip_method
|
|
2393
|
+
pjsip_method meth;
|
|
2001
2394
|
|
|
2002
2395
|
pjsip_msg_body *msg_body;
|
|
2003
2396
|
|
|
@@ -2009,14 +2402,37 @@ int pjw_call_send_request(long call_id, const char *method_name, const char *add
|
|
|
2009
2402
|
|
|
2010
2403
|
long val;
|
|
2011
2404
|
|
|
2405
|
+
char buffer[MAX_JSON_INPUT];
|
|
2406
|
+
|
|
2407
|
+
Document document;
|
|
2408
|
+
|
|
2409
|
+
if(!parse_json(document, json, buffer, MAX_JSON_INPUT)) {
|
|
2410
|
+
goto out;
|
|
2411
|
+
}
|
|
2412
|
+
|
|
2012
2413
|
if(!g_call_ids.get(call_id, val)){
|
|
2013
2414
|
set_error("Invalid call_id");
|
|
2014
2415
|
goto out;
|
|
2015
2416
|
}
|
|
2016
|
-
|
|
2017
2417
|
call = (Call*)val;
|
|
2018
2418
|
|
|
2019
|
-
|
|
2419
|
+
if(!json_get_string_param(document, "method", false, &method)) {
|
|
2420
|
+
goto out;
|
|
2421
|
+
}
|
|
2422
|
+
|
|
2423
|
+
if(!json_get_string_param(document, "body", true, &body)) {
|
|
2424
|
+
goto out;
|
|
2425
|
+
}
|
|
2426
|
+
|
|
2427
|
+
if(!json_get_string_param(document, "ct_type", true, &ct_type)) {
|
|
2428
|
+
goto out;
|
|
2429
|
+
}
|
|
2430
|
+
|
|
2431
|
+
if(!json_get_string_param(document, "ct_subtype", true, &ct_subtype)) {
|
|
2432
|
+
goto out;
|
|
2433
|
+
}
|
|
2434
|
+
|
|
2435
|
+
if(strcmp(method,"INVITE")==0 || strcmp(method,"UPDATE")==0 || strcmp(method,"PRACK")==0 || strcmp(method,"BYE")==0) {
|
|
2020
2436
|
set_error("Invalid method");
|
|
2021
2437
|
goto out;
|
|
2022
2438
|
}
|
|
@@ -2028,13 +2444,13 @@ int pjw_call_send_request(long call_id, const char *method_name, const char *add
|
|
|
2028
2444
|
}
|
|
2029
2445
|
}
|
|
2030
2446
|
|
|
2031
|
-
|
|
2447
|
+
s_method = pj_str((char*)method);
|
|
2032
2448
|
|
|
2033
|
-
pjsip_method_init_np(&
|
|
2449
|
+
pjsip_method_init_np(&meth, &s_method);
|
|
2034
2450
|
|
|
2035
|
-
status = pjsip_dlg_create_request(call->inv->dlg, &
|
|
2451
|
+
status = pjsip_dlg_create_request(call->inv->dlg, &meth, -1, &tdata);
|
|
2036
2452
|
if (status != PJ_SUCCESS) {
|
|
2037
|
-
set_error("pjsip_dlg_create_request failed");
|
|
2453
|
+
set_error("pjsip_dlg_create_request failed with status=%i", status);
|
|
2038
2454
|
goto out;
|
|
2039
2455
|
}
|
|
2040
2456
|
|
|
@@ -2058,222 +2474,294 @@ int pjw_call_send_request(long call_id, const char *method_name, const char *add
|
|
|
2058
2474
|
|
|
2059
2475
|
status = pjsip_dlg_send_request(call->inv->dlg, tdata, -1, NULL);
|
|
2060
2476
|
if (status != PJ_SUCCESS) {
|
|
2061
|
-
set_error("pjsip_dlg_send_request failed");
|
|
2477
|
+
set_error("pjsip_dlg_send_request failed with status=%i", status);
|
|
2062
2478
|
goto out;
|
|
2063
2479
|
}
|
|
2064
2480
|
|
|
2065
|
-
PJW_UNLOCK();
|
|
2066
|
-
return 0;
|
|
2067
|
-
|
|
2068
2481
|
out:
|
|
2069
2482
|
PJW_UNLOCK();
|
|
2070
|
-
|
|
2071
2483
|
if(pjw_errorstring[0]) {
|
|
2072
2484
|
return -1;
|
|
2073
2485
|
}
|
|
2074
|
-
return 0;
|
|
2075
2486
|
|
|
2487
|
+
return 0;
|
|
2076
2488
|
}
|
|
2077
2489
|
|
|
2078
|
-
int pjw_call_start_record_wav(long call_id, const char *file)
|
|
2490
|
+
//int pjw_call_start_record_wav(long call_id, const char *file)
|
|
2491
|
+
int pjw_call_start_record_wav(long call_id, const char *json)
|
|
2079
2492
|
{
|
|
2080
2493
|
PJW_LOCK();
|
|
2494
|
+
clear_error();
|
|
2081
2495
|
|
|
2082
2496
|
long val;
|
|
2497
|
+
Call *call;
|
|
2498
|
+
pj_status_t status;
|
|
2499
|
+
pjmedia_port *stream_port;
|
|
2500
|
+
|
|
2501
|
+
char *file;
|
|
2502
|
+
|
|
2503
|
+
char buffer[MAX_JSON_INPUT];
|
|
2504
|
+
|
|
2505
|
+
Document document;
|
|
2083
2506
|
|
|
2084
2507
|
if(!g_call_ids.get(call_id, val)){
|
|
2085
|
-
PJW_UNLOCK();
|
|
2086
2508
|
set_error("Invalid call_id");
|
|
2087
|
-
|
|
2509
|
+
goto out;
|
|
2088
2510
|
}
|
|
2089
|
-
|
|
2090
|
-
Call *call = (Call*)val;
|
|
2511
|
+
call = (Call*)val;
|
|
2091
2512
|
|
|
2092
2513
|
if(!call->med_stream)
|
|
2093
2514
|
{
|
|
2094
|
-
PJW_UNLOCK();
|
|
2095
2515
|
set_error("Media not ready");
|
|
2096
|
-
|
|
2516
|
+
goto out;
|
|
2097
2517
|
}
|
|
2098
2518
|
|
|
2099
|
-
|
|
2519
|
+
if(!parse_json(document, json, buffer, MAX_JSON_INPUT)) {
|
|
2520
|
+
goto out;
|
|
2521
|
+
}
|
|
2100
2522
|
|
|
2101
|
-
|
|
2523
|
+
if(!json_get_string_param(document, "file", false, &file)) {
|
|
2524
|
+
goto out;
|
|
2525
|
+
}
|
|
2526
|
+
|
|
2527
|
+
if(!file[0]) {
|
|
2528
|
+
set_error("file cannot be blank string");
|
|
2529
|
+
goto out;
|
|
2530
|
+
}
|
|
2531
|
+
|
|
2102
2532
|
status = pjmedia_stream_get_port(call->med_stream,
|
|
2103
2533
|
&stream_port);
|
|
2104
2534
|
if(status != PJ_SUCCESS)
|
|
2105
2535
|
{
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
return -1;
|
|
2536
|
+
set_error("pjmedia_stream_get_port failed with status=%i", status);
|
|
2537
|
+
goto out;
|
|
2109
2538
|
}
|
|
2110
2539
|
|
|
2111
2540
|
if(!prepare_wav_writer(call, file)) {
|
|
2112
|
-
PJW_UNLOCK();
|
|
2113
2541
|
set_error("prepare_wav_writer failed");
|
|
2114
|
-
|
|
2542
|
+
goto out;
|
|
2115
2543
|
}
|
|
2116
2544
|
|
|
2545
|
+
out:
|
|
2117
2546
|
PJW_UNLOCK();
|
|
2547
|
+
if(pjw_errorstring[0]){
|
|
2548
|
+
return -1;
|
|
2549
|
+
}
|
|
2550
|
+
|
|
2118
2551
|
return 0;
|
|
2119
2552
|
}
|
|
2120
2553
|
|
|
2121
2554
|
|
|
2122
|
-
int pjw_call_start_play_wav(long call_id, const char *file)
|
|
2555
|
+
//int pjw_call_start_play_wav(long call_id, const char *file)
|
|
2556
|
+
int pjw_call_start_play_wav(long call_id, const char *json)
|
|
2123
2557
|
{
|
|
2124
2558
|
PJW_LOCK();
|
|
2559
|
+
clear_error();
|
|
2125
2560
|
|
|
2126
2561
|
long val;
|
|
2562
|
+
Call *call;
|
|
2563
|
+
pj_status_t status;
|
|
2564
|
+
pjmedia_port *stream_port;
|
|
2565
|
+
|
|
2566
|
+
char *file;
|
|
2567
|
+
|
|
2568
|
+
char buffer[MAX_JSON_INPUT];
|
|
2569
|
+
|
|
2570
|
+
Document document;
|
|
2127
2571
|
|
|
2128
2572
|
if(!g_call_ids.get(call_id, val)){
|
|
2129
|
-
PJW_UNLOCK();
|
|
2130
2573
|
set_error("Invalid call_id");
|
|
2131
|
-
|
|
2574
|
+
goto out;
|
|
2132
2575
|
}
|
|
2133
|
-
|
|
2134
|
-
Call *call = (Call*)val;
|
|
2576
|
+
call = (Call*)val;
|
|
2135
2577
|
|
|
2136
2578
|
if(!call->med_stream)
|
|
2137
2579
|
{
|
|
2138
|
-
PJW_UNLOCK();
|
|
2139
2580
|
set_error("Media not ready");
|
|
2140
|
-
|
|
2581
|
+
goto out;
|
|
2141
2582
|
}
|
|
2142
2583
|
|
|
2143
|
-
|
|
2584
|
+
if(!parse_json(document, json, buffer, MAX_JSON_INPUT)) {
|
|
2585
|
+
goto out;
|
|
2586
|
+
}
|
|
2587
|
+
|
|
2588
|
+
if(!json_get_string_param(document, "file", false, &file)) {
|
|
2589
|
+
goto out;
|
|
2590
|
+
}
|
|
2591
|
+
|
|
2592
|
+
if(!file[0]) {
|
|
2593
|
+
set_error("file cannot be blank string");
|
|
2594
|
+
goto out;
|
|
2595
|
+
}
|
|
2144
2596
|
|
|
2145
|
-
pjmedia_port *stream_port;
|
|
2146
2597
|
status = pjmedia_stream_get_port(call->med_stream,
|
|
2147
2598
|
&stream_port);
|
|
2148
2599
|
if(status != PJ_SUCCESS)
|
|
2149
2600
|
{
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
return -1;
|
|
2601
|
+
set_error("pjmedia_stream_get_port failed with status=%i", status);
|
|
2602
|
+
goto out;
|
|
2153
2603
|
}
|
|
2154
2604
|
|
|
2155
2605
|
if(!prepare_wav_player(call, file)){
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
}
|
|
2606
|
+
set_error("prepare_wav_player failed");
|
|
2607
|
+
goto out;
|
|
2608
|
+
}
|
|
2160
2609
|
|
|
2610
|
+
out:
|
|
2161
2611
|
PJW_UNLOCK();
|
|
2612
|
+
if(pjw_errorstring[0]){
|
|
2613
|
+
return -1;
|
|
2614
|
+
}
|
|
2615
|
+
|
|
2162
2616
|
return 0;
|
|
2163
2617
|
}
|
|
2164
2618
|
|
|
2165
2619
|
int pjw_call_stop_play_wav(long call_id)
|
|
2166
2620
|
{
|
|
2167
2621
|
PJW_LOCK();
|
|
2622
|
+
clear_error();
|
|
2623
|
+
|
|
2624
|
+
Call *call;
|
|
2625
|
+
|
|
2626
|
+
pjmedia_port *stream_port;
|
|
2627
|
+
pj_status_t status;
|
|
2168
2628
|
|
|
2169
2629
|
long val;
|
|
2170
2630
|
|
|
2171
2631
|
if(!g_call_ids.get(call_id, val)){
|
|
2172
|
-
PJW_UNLOCK();
|
|
2173
2632
|
set_error("Invalid call_id");
|
|
2174
|
-
|
|
2633
|
+
goto out;
|
|
2175
2634
|
}
|
|
2635
|
+
call = (Call*)val;
|
|
2176
2636
|
|
|
2177
|
-
Call *call = (Call*)val;
|
|
2178
|
-
|
|
2179
|
-
pjmedia_port *stream_port;
|
|
2180
|
-
pj_status_t status;
|
|
2181
2637
|
status = pjmedia_stream_get_port(call->med_stream,
|
|
2182
2638
|
&stream_port);
|
|
2183
2639
|
if(status != PJ_SUCCESS) {
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
return -1;
|
|
2640
|
+
set_error("pjmedia_stream_get_port failed with status=%i", status);
|
|
2641
|
+
goto out;
|
|
2187
2642
|
}
|
|
2188
2643
|
|
|
2189
2644
|
if(!prepare_wire(call->inv->pool, &call->wav_player, PJMEDIA_PIA_SRATE(&stream_port->info), PJMEDIA_PIA_CCNT(&stream_port->info), PJMEDIA_PIA_SPF(&stream_port->info), PJMEDIA_PIA_BITS(&stream_port->info))) {
|
|
2190
|
-
PJW_UNLOCK();
|
|
2191
2645
|
set_error("prepare_wire failed.");
|
|
2192
|
-
|
|
2646
|
+
goto out;
|
|
2193
2647
|
}
|
|
2194
2648
|
|
|
2195
2649
|
connect_media_ports(call);
|
|
2196
2650
|
|
|
2651
|
+
out:
|
|
2197
2652
|
PJW_UNLOCK();
|
|
2653
|
+
if(pjw_errorstring[0]){
|
|
2654
|
+
return -1;
|
|
2655
|
+
}
|
|
2656
|
+
|
|
2198
2657
|
return 0;
|
|
2199
2658
|
}
|
|
2200
2659
|
|
|
2201
2660
|
int pjw_call_stop_record_wav(long call_id)
|
|
2202
2661
|
{
|
|
2203
2662
|
PJW_LOCK();
|
|
2663
|
+
clear_error();
|
|
2204
2664
|
|
|
2205
2665
|
long val;
|
|
2666
|
+
Call *call = (Call*)val;
|
|
2667
|
+
pjmedia_port *stream_port;
|
|
2668
|
+
pj_status_t status;
|
|
2206
2669
|
|
|
2207
2670
|
if(!g_call_ids.get(call_id, val)){
|
|
2208
|
-
PJW_UNLOCK();
|
|
2209
2671
|
set_error("Invalid call_id");
|
|
2210
|
-
|
|
2672
|
+
goto out;
|
|
2211
2673
|
}
|
|
2674
|
+
call = (Call*)val;
|
|
2212
2675
|
|
|
2213
|
-
Call *call = (Call*)val;
|
|
2214
|
-
|
|
2215
|
-
pjmedia_port *stream_port;
|
|
2216
|
-
pj_status_t status;
|
|
2217
2676
|
status = pjmedia_stream_get_port(call->med_stream,
|
|
2218
2677
|
&stream_port);
|
|
2219
2678
|
if(status != PJ_SUCCESS) {
|
|
2220
|
-
PJW_UNLOCK();
|
|
2221
2679
|
set_error("pjmedia_stream_get_port failed.");
|
|
2222
|
-
|
|
2680
|
+
goto out;
|
|
2223
2681
|
}
|
|
2224
2682
|
|
|
2225
2683
|
if(!prepare_wire(call->inv->pool, &call->wav_writer, PJMEDIA_PIA_SRATE(&stream_port->info), PJMEDIA_PIA_CCNT(&stream_port->info), PJMEDIA_PIA_SPF(&stream_port->info), PJMEDIA_PIA_BITS(&stream_port->info))) {
|
|
2226
|
-
PJW_UNLOCK();
|
|
2227
2684
|
set_error("prepare_wire failed.");
|
|
2228
|
-
|
|
2685
|
+
goto out;
|
|
2229
2686
|
}
|
|
2230
2687
|
|
|
2231
2688
|
connect_media_ports(call);
|
|
2232
|
-
|
|
2689
|
+
|
|
2690
|
+
out:
|
|
2233
2691
|
PJW_UNLOCK();
|
|
2692
|
+
if(pjw_errorstring[0]){
|
|
2693
|
+
return -1;
|
|
2694
|
+
}
|
|
2695
|
+
|
|
2234
2696
|
return 0;
|
|
2235
2697
|
}
|
|
2236
2698
|
|
|
2237
|
-
int pjw_call_start_fax(long call_id, bool is_sender, const char *file)
|
|
2699
|
+
//int pjw_call_start_fax(long call_id, bool is_sender, const char *file)
|
|
2700
|
+
int pjw_call_start_fax(long call_id, const char *json)
|
|
2238
2701
|
{
|
|
2239
2702
|
PJW_LOCK();
|
|
2703
|
+
clear_error();
|
|
2240
2704
|
|
|
2241
2705
|
long val;
|
|
2706
|
+
Call *call;
|
|
2707
|
+
pj_status_t status;
|
|
2708
|
+
pjmedia_port *stream_port;
|
|
2709
|
+
|
|
2710
|
+
bool is_sender;
|
|
2711
|
+
char *file;
|
|
2712
|
+
|
|
2713
|
+
char buffer[MAX_JSON_INPUT];
|
|
2714
|
+
|
|
2715
|
+
Document document;
|
|
2242
2716
|
|
|
2243
2717
|
if(!g_call_ids.get(call_id, val)){
|
|
2244
|
-
PJW_UNLOCK();
|
|
2245
2718
|
set_error("Invalid call_id");
|
|
2246
|
-
|
|
2719
|
+
goto out;
|
|
2247
2720
|
}
|
|
2248
|
-
|
|
2249
|
-
Call *call = (Call*)val;
|
|
2721
|
+
call = (Call*)val;
|
|
2250
2722
|
|
|
2251
2723
|
if(!call->med_stream)
|
|
2252
2724
|
{
|
|
2253
|
-
PJW_UNLOCK();
|
|
2254
2725
|
set_error("Media not ready");
|
|
2255
|
-
|
|
2726
|
+
goto out;
|
|
2256
2727
|
}
|
|
2257
2728
|
|
|
2258
|
-
|
|
2729
|
+
if(!parse_json(document, json, buffer, MAX_JSON_INPUT)) {
|
|
2730
|
+
goto out;
|
|
2731
|
+
}
|
|
2732
|
+
|
|
2733
|
+
if(!json_get_bool_param(document, "is_sender", false, &is_sender)) {
|
|
2734
|
+
goto out;
|
|
2735
|
+
}
|
|
2736
|
+
|
|
2737
|
+
if(!json_get_string_param(document, "file", false, &file)) {
|
|
2738
|
+
goto out;
|
|
2739
|
+
}
|
|
2740
|
+
|
|
2741
|
+
if(!file[0]) {
|
|
2742
|
+
set_error("file cannot be blank string");
|
|
2743
|
+
goto out;
|
|
2744
|
+
}
|
|
2259
2745
|
|
|
2260
|
-
pjmedia_port *stream_port;
|
|
2261
2746
|
status = pjmedia_stream_get_port(call->med_stream,
|
|
2262
2747
|
&stream_port);
|
|
2263
2748
|
if(status != PJ_SUCCESS)
|
|
2264
2749
|
{
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
return -1;
|
|
2750
|
+
set_error("pjmedia_stream_get_port failed with status=%i", status);
|
|
2751
|
+
goto out;
|
|
2268
2752
|
}
|
|
2269
2753
|
|
|
2270
2754
|
if(!prepare_fax(call, is_sender, file)){
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
}
|
|
2755
|
+
set_error("prepare_fax failed");
|
|
2756
|
+
goto out;
|
|
2757
|
+
}
|
|
2275
2758
|
|
|
2759
|
+
out:
|
|
2276
2760
|
PJW_UNLOCK();
|
|
2761
|
+
if(pjw_errorstring[0]){
|
|
2762
|
+
return -1;
|
|
2763
|
+
}
|
|
2764
|
+
|
|
2277
2765
|
return 0;
|
|
2278
2766
|
}
|
|
2279
2767
|
|
|
@@ -2281,84 +2769,90 @@ int pjw_call_start_fax(long call_id, bool is_sender, const char *file)
|
|
|
2281
2769
|
int pjw_call_stop_fax(long call_id)
|
|
2282
2770
|
{
|
|
2283
2771
|
PJW_LOCK();
|
|
2772
|
+
clear_error();
|
|
2284
2773
|
|
|
2285
2774
|
long val;
|
|
2775
|
+
Call *call;
|
|
2776
|
+
|
|
2777
|
+
pjmedia_port *stream_port;
|
|
2778
|
+
pj_status_t status;
|
|
2286
2779
|
|
|
2287
2780
|
if(!g_call_ids.get(call_id, val)){
|
|
2288
|
-
PJW_UNLOCK();
|
|
2289
2781
|
set_error("Invalid call_id");
|
|
2290
|
-
|
|
2782
|
+
goto out;
|
|
2291
2783
|
}
|
|
2292
2784
|
|
|
2293
|
-
|
|
2785
|
+
call = (Call*)val;
|
|
2294
2786
|
|
|
2295
|
-
pjmedia_port *stream_port;
|
|
2296
|
-
pj_status_t status;
|
|
2297
2787
|
status = pjmedia_stream_get_port(call->med_stream,
|
|
2298
2788
|
&stream_port);
|
|
2299
2789
|
if(status != PJ_SUCCESS) {
|
|
2300
|
-
PJW_UNLOCK();
|
|
2301
2790
|
set_error("pjmedia_stream_get_port failed.");
|
|
2302
|
-
|
|
2791
|
+
goto out;
|
|
2303
2792
|
}
|
|
2304
2793
|
|
|
2305
2794
|
if(!prepare_wire(call->inv->pool, &call->fax, PJMEDIA_PIA_SRATE(&stream_port->info), PJMEDIA_PIA_CCNT(&stream_port->info), PJMEDIA_PIA_SPF(&stream_port->info), PJMEDIA_PIA_BITS(&stream_port->info))) {
|
|
2306
|
-
PJW_UNLOCK();
|
|
2307
2795
|
set_error("prepare_wire failed.");
|
|
2308
|
-
|
|
2796
|
+
goto out;
|
|
2309
2797
|
}
|
|
2310
2798
|
|
|
2311
2799
|
connect_media_ports(call);
|
|
2312
2800
|
|
|
2801
|
+
out:
|
|
2313
2802
|
PJW_UNLOCK();
|
|
2803
|
+
if(pjw_errorstring[0]){
|
|
2804
|
+
return -1;
|
|
2805
|
+
}
|
|
2806
|
+
|
|
2314
2807
|
return 0;
|
|
2315
2808
|
}
|
|
2316
2809
|
|
|
2317
2810
|
|
|
2318
2811
|
int pjw_call_get_stream_stat(long call_id, char *out_stats){
|
|
2319
2812
|
PJW_LOCK();
|
|
2813
|
+
clear_error();
|
|
2320
2814
|
|
|
2321
2815
|
long val;
|
|
2816
|
+
Call *call;
|
|
2817
|
+
|
|
2818
|
+
pj_status_t status;
|
|
2819
|
+
pjmedia_rtcp_stat stat;
|
|
2820
|
+
pjmedia_stream_info stream_info;
|
|
2821
|
+
|
|
2822
|
+
ostringstream oss;
|
|
2322
2823
|
|
|
2323
2824
|
if(!g_call_ids.get(call_id, val)){
|
|
2324
|
-
PJW_UNLOCK();
|
|
2325
2825
|
set_error("Invalid call_id");
|
|
2326
|
-
|
|
2826
|
+
goto out;
|
|
2327
2827
|
}
|
|
2328
|
-
|
|
2329
|
-
Call *call = (Call*)val;
|
|
2828
|
+
call = (Call*)val;
|
|
2330
2829
|
|
|
2331
2830
|
if(!call->med_stream){
|
|
2332
|
-
PJW_UNLOCK();
|
|
2333
2831
|
set_error("Could not get stream stats. No media session");
|
|
2334
|
-
|
|
2832
|
+
goto out;
|
|
2335
2833
|
}
|
|
2336
2834
|
|
|
2337
|
-
pj_status_t status;
|
|
2338
|
-
|
|
2339
|
-
pjmedia_rtcp_stat stat;
|
|
2340
|
-
pjmedia_stream_info stream_info;
|
|
2341
|
-
|
|
2342
2835
|
status = pjmedia_stream_get_stat(call->med_stream, &stat);
|
|
2343
2836
|
if(status != PJ_SUCCESS){
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
return -1;
|
|
2837
|
+
set_error("Could not get stream stats. Call to pjmedia_stream_get_stream_stat failed with status=%i", status);
|
|
2838
|
+
goto out;
|
|
2347
2839
|
}
|
|
2348
2840
|
|
|
2349
2841
|
status = pjmedia_stream_get_info(call->med_stream, &stream_info);
|
|
2350
2842
|
if(status != PJ_SUCCESS){
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
return -1;
|
|
2843
|
+
set_error("Could not get stream info. Call to pjmedia_stream_get_info failed with status=%i", status);
|
|
2844
|
+
goto out;
|
|
2354
2845
|
}
|
|
2355
2846
|
|
|
2356
|
-
ostringstream oss;
|
|
2357
2847
|
build_stream_stat(oss, &stat, &stream_info);
|
|
2848
|
+
strcpy(out_stats, oss.str().c_str());
|
|
2358
2849
|
|
|
2850
|
+
out:
|
|
2359
2851
|
PJW_UNLOCK();
|
|
2852
|
+
if(pjw_errorstring[0]){
|
|
2853
|
+
return -1;
|
|
2854
|
+
}
|
|
2360
2855
|
|
|
2361
|
-
strcpy(out_stats, oss.str().c_str());
|
|
2362
2856
|
return 0;
|
|
2363
2857
|
}
|
|
2364
2858
|
|
|
@@ -2649,7 +3143,7 @@ static void on_state_changed( pjsip_inv_session *inv,
|
|
|
2649
3143
|
|
|
2650
3144
|
char evt[2048];
|
|
2651
3145
|
int sip_msg_len = 0;
|
|
2652
|
-
char *sip_msg = "";
|
|
3146
|
+
char *sip_msg = (char*)"";
|
|
2653
3147
|
if(e->type == PJSIP_EVENT_TSX_STATE) {
|
|
2654
3148
|
sip_msg_len = e->body.rx_msg.rdata->msg_info.len;
|
|
2655
3149
|
sip_msg = e->body.rx_msg.rdata->msg_info.msg_buf;
|
|
@@ -2766,7 +3260,7 @@ static void process_subscribe_request(pjsip_rx_data *rdata) {
|
|
|
2766
3260
|
|
|
2767
3261
|
out:
|
|
2768
3262
|
if(status != PJ_SUCCESS) {
|
|
2769
|
-
pj_str_t s_reason = pj_str(pjw_errorstring);
|
|
3263
|
+
//pj_str_t s_reason = pj_str(pjw_errorstring);
|
|
2770
3264
|
if(dlg) {
|
|
2771
3265
|
status = pjsip_dlg_create_response(dlg, rdata, 500, NULL, &tdata);
|
|
2772
3266
|
if(status == PJ_SUCCESS) {
|
|
@@ -2843,7 +3337,7 @@ static pj_bool_t on_rx_request( pjsip_rx_data *rdata ){
|
|
|
2843
3337
|
build_basic_request_info(&oss, rdata, &transport);
|
|
2844
3338
|
*/
|
|
2845
3339
|
|
|
2846
|
-
reason = pj_str("OK");
|
|
3340
|
+
reason = pj_str((char*)"OK");
|
|
2847
3341
|
|
|
2848
3342
|
pjsip_hdr hdr_list;
|
|
2849
3343
|
pj_list_init(&hdr_list);
|
|
@@ -2852,7 +3346,7 @@ static pj_bool_t on_rx_request( pjsip_rx_data *rdata ){
|
|
|
2852
3346
|
pjsip_hdr *hdr_from_request;
|
|
2853
3347
|
|
|
2854
3348
|
//Add Contact header from Request, if present
|
|
2855
|
-
pj_str_t STR_CONTACT = {
|
|
3349
|
+
pj_str_t STR_CONTACT = {(char*)"Contact" , 7 };
|
|
2856
3350
|
hdr_from_request = (pjsip_hdr*)pjsip_msg_find_hdr_by_name(rdata->msg_info.msg,
|
|
2857
3351
|
&STR_CONTACT,
|
|
2858
3352
|
NULL);
|
|
@@ -2862,7 +3356,7 @@ static pj_bool_t on_rx_request( pjsip_rx_data *rdata ){
|
|
|
2862
3356
|
}
|
|
2863
3357
|
|
|
2864
3358
|
//Add Expires header from Request, if present
|
|
2865
|
-
pj_str_t STR_EXPIRES = {
|
|
3359
|
+
pj_str_t STR_EXPIRES = {(char*)"Expires" , 7 };
|
|
2866
3360
|
hdr_from_request = (pjsip_hdr*)pjsip_msg_find_hdr_by_name(rdata->msg_info.msg,
|
|
2867
3361
|
&STR_EXPIRES,
|
|
2868
3362
|
NULL);
|
|
@@ -2883,13 +3377,13 @@ static pj_bool_t on_rx_request( pjsip_rx_data *rdata ){
|
|
|
2883
3377
|
unsigned options = 0;
|
|
2884
3378
|
status = pjsip_inv_verify_request(rdata, &options, NULL, NULL, g_sip_endpt, NULL);
|
|
2885
3379
|
if(status != PJ_SUCCESS) {
|
|
2886
|
-
reason = pj_str("Unable to handle this INVITE");
|
|
3380
|
+
reason = pj_str((char*)"Unable to handle this INVITE");
|
|
2887
3381
|
pjsip_endpt_respond_stateless(g_sip_endpt, rdata, 500, &reason, NULL, NULL);
|
|
2888
3382
|
return PJ_TRUE;
|
|
2889
3383
|
}
|
|
2890
3384
|
|
|
2891
3385
|
char local_contact[1000];
|
|
2892
|
-
build_local_contact(local_contact, rdata->tp_info.transport, "sip-
|
|
3386
|
+
build_local_contact(local_contact, rdata->tp_info.transport, "sip-lab");
|
|
2893
3387
|
pj_str_t url = pj_str(local_contact);
|
|
2894
3388
|
|
|
2895
3389
|
status = pjsip_dlg_create_uas_and_inc_lock(pjsip_ua_instance(),
|
|
@@ -2898,7 +3392,7 @@ static pj_bool_t on_rx_request( pjsip_rx_data *rdata ){
|
|
|
2898
3392
|
&dlg);
|
|
2899
3393
|
|
|
2900
3394
|
if(status != PJ_SUCCESS) {
|
|
2901
|
-
reason = pj_str("Internal Server Error (pjsip_dlg_create_uas_and_inc_lock failed)");
|
|
3395
|
+
reason = pj_str((char*)"Internal Server Error (pjsip_dlg_create_uas_and_inc_lock failed)");
|
|
2902
3396
|
pjsip_endpt_respond_stateless(g_sip_endpt, rdata, 500, &reason, NULL, NULL);
|
|
2903
3397
|
return PJ_TRUE;
|
|
2904
3398
|
}
|
|
@@ -2909,7 +3403,7 @@ static pj_bool_t on_rx_request( pjsip_rx_data *rdata ){
|
|
|
2909
3403
|
|
|
2910
3404
|
if(!med_transport)
|
|
2911
3405
|
{
|
|
2912
|
-
reason = pj_str("Internal Server Error (could not create media transport)");
|
|
3406
|
+
reason = pj_str((char*)"Internal Server Error (could not create media transport)");
|
|
2913
3407
|
pjsip_endpt_respond_stateless(g_sip_endpt, rdata, 500, &reason, NULL, NULL);
|
|
2914
3408
|
return PJ_TRUE;
|
|
2915
3409
|
}
|
|
@@ -2924,7 +3418,7 @@ static pj_bool_t on_rx_request( pjsip_rx_data *rdata ){
|
|
|
2924
3418
|
&sdp);
|
|
2925
3419
|
if(status != PJ_SUCCESS) {
|
|
2926
3420
|
close_media_transport(med_transport);
|
|
2927
|
-
reason = pj_str("Internal Server Error (pjmedia_endprt_create_sdp failed)");
|
|
3421
|
+
reason = pj_str((char*)"Internal Server Error (pjmedia_endprt_create_sdp failed)");
|
|
2928
3422
|
pjsip_endpt_respond_stateless(g_sip_endpt, rdata, 500, &reason, NULL, NULL);
|
|
2929
3423
|
return PJ_TRUE;
|
|
2930
3424
|
}
|
|
@@ -2933,14 +3427,14 @@ static pj_bool_t on_rx_request( pjsip_rx_data *rdata ){
|
|
|
2933
3427
|
status = pjsip_inv_create_uas(dlg, rdata, sdp, 0, &inv);
|
|
2934
3428
|
if(status != PJ_SUCCESS) {
|
|
2935
3429
|
close_media_transport(med_transport);
|
|
2936
|
-
reason = pj_str("Internal Server Error (pjsip_inv_create_uas failed)");
|
|
3430
|
+
reason = pj_str((char*)"Internal Server Error (pjsip_inv_create_uas failed)");
|
|
2937
3431
|
pjsip_endpt_respond_stateless(g_sip_endpt, rdata, 500, &reason, NULL, NULL);
|
|
2938
3432
|
return PJ_TRUE;
|
|
2939
3433
|
}
|
|
2940
3434
|
|
|
2941
3435
|
if(!dlg_set_transport(t, dlg)) {
|
|
2942
3436
|
close_media_transport(med_transport);
|
|
2943
|
-
reason = pj_str("Internal Server Error (set_transport failed)");
|
|
3437
|
+
reason = pj_str((char*)"Internal Server Error (set_transport failed)");
|
|
2944
3438
|
pjsip_endpt_respond_stateless(g_sip_endpt, rdata, 500, &reason, NULL, NULL);
|
|
2945
3439
|
return PJ_TRUE;
|
|
2946
3440
|
}
|
|
@@ -2956,7 +3450,7 @@ static pj_bool_t on_rx_request( pjsip_rx_data *rdata ){
|
|
|
2956
3450
|
NULL, NULL, &tdata);
|
|
2957
3451
|
if(status != PJ_SUCCESS) {
|
|
2958
3452
|
close_media_transport(med_transport);
|
|
2959
|
-
reason = pj_str("Internal Server Error (pjsip_inv_initial_answer failed)");
|
|
3453
|
+
reason = pj_str((char*)"Internal Server Error (pjsip_inv_initial_answer failed)");
|
|
2960
3454
|
pjsip_endpt_respond_stateless(g_sip_endpt, rdata, 500, &reason, NULL, NULL);
|
|
2961
3455
|
return PJ_TRUE;
|
|
2962
3456
|
}
|
|
@@ -2965,7 +3459,7 @@ static pj_bool_t on_rx_request( pjsip_rx_data *rdata ){
|
|
|
2965
3459
|
status = pjsip_inv_send_msg(inv, tdata);
|
|
2966
3460
|
if(status != PJ_SUCCESS) {
|
|
2967
3461
|
close_media_transport(med_transport);
|
|
2968
|
-
reason = pj_str("Internal Server Error (pjsip_inv_send_msg failed)");
|
|
3462
|
+
reason = pj_str((char*)"Internal Server Error (pjsip_inv_send_msg failed)");
|
|
2969
3463
|
pjsip_endpt_respond_stateless(g_sip_endpt, rdata, 500, &reason, NULL, NULL);
|
|
2970
3464
|
return PJ_TRUE;
|
|
2971
3465
|
}
|
|
@@ -2974,7 +3468,7 @@ static pj_bool_t on_rx_request( pjsip_rx_data *rdata ){
|
|
|
2974
3468
|
|
|
2975
3469
|
if(status != PJ_SUCCESS) {
|
|
2976
3470
|
close_media_transport(med_transport);
|
|
2977
|
-
reason = pj_str("Internal Server Error (pjsip_rx_data_clone failed)");
|
|
3471
|
+
reason = pj_str((char*)"Internal Server Error (pjsip_rx_data_clone failed)");
|
|
2978
3472
|
pjsip_endpt_respond_stateless(g_sip_endpt, rdata, 500, &reason, NULL, NULL);
|
|
2979
3473
|
return PJ_TRUE;
|
|
2980
3474
|
}
|
|
@@ -2987,7 +3481,7 @@ static pj_bool_t on_rx_request( pjsip_rx_data *rdata ){
|
|
|
2987
3481
|
|
|
2988
3482
|
if(status != PJ_SUCCESS) {
|
|
2989
3483
|
close_media_transport(med_transport);
|
|
2990
|
-
reason = pj_str("Internal Server Error (pjsip_rx_data_clone failed)");
|
|
3484
|
+
reason = pj_str((char*)"Internal Server Error (pjsip_rx_data_clone failed)");
|
|
2991
3485
|
pjsip_endpt_respond_stateless(g_sip_endpt, rdata, 500, &reason, NULL, NULL);
|
|
2992
3486
|
return PJ_TRUE;
|
|
2993
3487
|
}
|
|
@@ -3005,7 +3499,7 @@ static pj_bool_t on_rx_request( pjsip_rx_data *rdata ){
|
|
|
3005
3499
|
status = pjsip_dlg_add_usage(dlg, &mod_tester, call);
|
|
3006
3500
|
if(status != PJ_SUCCESS) {
|
|
3007
3501
|
close_media_transport(med_transport);
|
|
3008
|
-
reason = pj_str("Internal Server Error (pjsip_dlg_add_usage failed)");
|
|
3502
|
+
reason = pj_str((char*)"Internal Server Error (pjsip_dlg_add_usage failed)");
|
|
3009
3503
|
pjsip_endpt_respond_stateless(g_sip_endpt, rdata, 500, &reason, NULL, NULL);
|
|
3010
3504
|
return PJ_TRUE;
|
|
3011
3505
|
}
|
|
@@ -3147,15 +3641,17 @@ static void on_rx_offer(pjsip_inv_session *inv, const pjmedia_sdp_session *offer
|
|
|
3147
3641
|
addon_log(LOG_LEVEL_DEBUG, "on_rx_offer offer=%x\n", offer);
|
|
3148
3642
|
if(g_shutting_down) return;
|
|
3149
3643
|
|
|
3644
|
+
/*
|
|
3150
3645
|
bool is_reinvite = false;
|
|
3151
3646
|
|
|
3152
3647
|
if(inv->state == PJSIP_INV_STATE_CONFIRMED) {
|
|
3153
3648
|
is_reinvite = true;
|
|
3154
3649
|
}
|
|
3650
|
+
*/
|
|
3155
3651
|
|
|
3156
3652
|
char evt[2048];
|
|
3157
3653
|
|
|
3158
|
-
char *type;
|
|
3654
|
+
//char *type;
|
|
3159
3655
|
|
|
3160
3656
|
Call *call = (Call*)inv->dlg->mod_data[mod_tester.id];
|
|
3161
3657
|
|
|
@@ -3194,7 +3690,7 @@ static void on_rx_offer(pjsip_inv_session *inv, const pjmedia_sdp_session *offer
|
|
|
3194
3690
|
call->remote_hold = 0;
|
|
3195
3691
|
}
|
|
3196
3692
|
|
|
3197
|
-
char *mode = get_media_mode_str(remote_mode);
|
|
3693
|
+
//char *mode = get_media_mode_str(remote_mode);
|
|
3198
3694
|
|
|
3199
3695
|
pjmedia_sdp_attr *attr;
|
|
3200
3696
|
|
|
@@ -3362,7 +3858,7 @@ int pjw_get_codecs(char *out_codecs)
|
|
|
3362
3858
|
goto out;
|
|
3363
3859
|
}
|
|
3364
3860
|
|
|
3365
|
-
for(
|
|
3861
|
+
for(unsigned i=0; i<count; ++i) {
|
|
3366
3862
|
pjmedia_codec_info *info = &codec_info[i];
|
|
3367
3863
|
if(i != 0) oss << " ";
|
|
3368
3864
|
oss.write(info->encoding_name.ptr, info->encoding_name.slen);
|
|
@@ -3385,7 +3881,7 @@ out:
|
|
|
3385
3881
|
int pjw_set_codecs(const char *in_codec_info) {
|
|
3386
3882
|
clear_error();
|
|
3387
3883
|
|
|
3388
|
-
char error[1000];
|
|
3884
|
+
//char error[1000];
|
|
3389
3885
|
pjmedia_codec_mgr *codec_mgr;
|
|
3390
3886
|
pj_status_t status;
|
|
3391
3887
|
char codec_info[1000];
|
|
@@ -3400,7 +3896,7 @@ int pjw_set_codecs(const char *in_codec_info) {
|
|
|
3400
3896
|
goto out;
|
|
3401
3897
|
}
|
|
3402
3898
|
|
|
3403
|
-
codec_id = pj_str("");
|
|
3899
|
+
codec_id = pj_str((char*)"");
|
|
3404
3900
|
status = pjmedia_codec_mgr_set_codec_priority(codec_mgr, &codec_id, 0);
|
|
3405
3901
|
if(status != PJ_SUCCESS) {
|
|
3406
3902
|
set_error("pjmedia_codec_mgr_set_codec_priority(zero all) failed.");
|
|
@@ -3435,7 +3931,7 @@ out:
|
|
|
3435
3931
|
|
|
3436
3932
|
if(pjw_errorstring[0]){
|
|
3437
3933
|
//Try to put default priority to all codecs
|
|
3438
|
-
codec_id = pj_str("");
|
|
3934
|
+
codec_id = pj_str((char*)"");
|
|
3439
3935
|
status = pjmedia_codec_mgr_set_codec_priority(codec_mgr, &codec_id, 128);
|
|
3440
3936
|
return -1;
|
|
3441
3937
|
}
|
|
@@ -3576,7 +4072,13 @@ static void build_stream_stat(ostringstream &oss, pjmedia_rtcp_stat *stat, pjmed
|
|
|
3576
4072
|
{
|
|
3577
4073
|
char temp[200];
|
|
3578
4074
|
char duration[80], last_update[80];
|
|
3579
|
-
|
|
4075
|
+
|
|
4076
|
+
//char bps[16];
|
|
4077
|
+
//char ipbps[16];
|
|
4078
|
+
char packets[16];
|
|
4079
|
+
//char bytes[16];
|
|
4080
|
+
//char ipbytes[16];
|
|
4081
|
+
|
|
3580
4082
|
pj_time_val now;
|
|
3581
4083
|
|
|
3582
4084
|
pj_gettimeofday(&now);
|
|
@@ -3593,7 +4095,7 @@ static void build_stream_stat(ostringstream &oss, pjmedia_rtcp_stat *stat, pjmed
|
|
|
3593
4095
|
oss << duration;
|
|
3594
4096
|
|
|
3595
4097
|
sprintf(temp, ", \"CodecInfo\": \"%.*s/%d/%d\"",
|
|
3596
|
-
stream_info->fmt.encoding_name.slen,
|
|
4098
|
+
(int)stream_info->fmt.encoding_name.slen,
|
|
3597
4099
|
stream_info->fmt.encoding_name.ptr,
|
|
3598
4100
|
stream_info->fmt.clock_rate,
|
|
3599
4101
|
stream_info->fmt.channel_cnt);
|
|
@@ -3922,7 +4424,7 @@ void on_rx_notify(pjsip_evsub *sub, pjsip_rx_data *rdata, int *p_st_code, pj_str
|
|
|
3922
4424
|
|
|
3923
4425
|
static void on_client_refresh( pjsip_evsub *sub ) {
|
|
3924
4426
|
Subscription *subscription;
|
|
3925
|
-
pj_status_t status;
|
|
4427
|
+
//pj_status_t status;
|
|
3926
4428
|
|
|
3927
4429
|
subscription = (Subscription*) pjsip_evsub_get_mod_data(sub, mod_tester.id);
|
|
3928
4430
|
|
|
@@ -3962,7 +4464,7 @@ static void client_on_evsub_state( pjsip_evsub *sub, pjsip_event *event) {
|
|
|
3962
4464
|
}
|
|
3963
4465
|
|
|
3964
4466
|
pjsip_generic_string_hdr *refer_sub;
|
|
3965
|
-
const pj_str_t REFER_SUB = { "Refer-Sub", 9 };
|
|
4467
|
+
const pj_str_t REFER_SUB = { (char*)"Refer-Sub", 9 };
|
|
3966
4468
|
ostringstream oss;
|
|
3967
4469
|
|
|
3968
4470
|
// When subscription is accepted (got 200/OK)
|
|
@@ -4004,7 +4506,7 @@ static void client_on_evsub_state( pjsip_evsub *sub, pjsip_event *event) {
|
|
|
4004
4506
|
|
|
4005
4507
|
rdata = event->body.tsx_state.src.rdata;
|
|
4006
4508
|
|
|
4007
|
-
Transport *t;
|
|
4509
|
+
//Transport *t;
|
|
4008
4510
|
//build_basic_request_info(&oss, rdata, &t);
|
|
4009
4511
|
|
|
4010
4512
|
long subscription_id;
|
|
@@ -4041,8 +4543,8 @@ static void client_on_evsub_state( pjsip_evsub *sub, pjsip_event *event) {
|
|
|
4041
4543
|
static void server_on_evsub_state( pjsip_evsub *sub, pjsip_event *event)
|
|
4042
4544
|
{
|
|
4043
4545
|
Subscriber *s;
|
|
4044
|
-
pj_status_t status;
|
|
4045
|
-
pjsip_tx_data *tdata;
|
|
4546
|
+
//pj_status_t status;
|
|
4547
|
+
//pjsip_tx_data *tdata;
|
|
4046
4548
|
|
|
4047
4549
|
//addon_log(LOG_LEVEL_DEBUG, "server_on_evsub_state\n");
|
|
4048
4550
|
if(!sub) {
|
|
@@ -4084,7 +4586,7 @@ static void server_on_evsub_rx_refresh(pjsip_evsub *sub, pjsip_rx_data *rdata, i
|
|
|
4084
4586
|
|
|
4085
4587
|
ostringstream oss;
|
|
4086
4588
|
Subscriber *s;
|
|
4087
|
-
Transport *t;
|
|
4589
|
+
//Transport *t;
|
|
4088
4590
|
|
|
4089
4591
|
if(g_shutting_down) return;
|
|
4090
4592
|
addon_log(LOG_LEVEL_DEBUG, "server_on_evsub_rx_refresh\n");
|
|
@@ -4099,7 +4601,7 @@ static void server_on_evsub_rx_refresh(pjsip_evsub *sub, pjsip_rx_data *rdata, i
|
|
|
4099
4601
|
dispatch_event(evt);
|
|
4100
4602
|
|
|
4101
4603
|
if( pjsip_evsub_get_state(sub) == PJSIP_EVSUB_STATE_TERMINATED) {
|
|
4102
|
-
pj_str_t reason = { "noresource", 10 };
|
|
4604
|
+
pj_str_t reason = { (char*)"noresource", 10 };
|
|
4103
4605
|
status = pjsip_evsub_notify(sub,
|
|
4104
4606
|
PJSIP_EVSUB_STATE_TERMINATED,
|
|
4105
4607
|
NULL,
|
|
@@ -4140,17 +4642,17 @@ void process_in_dialog_refer(pjsip_dialog *dlg, pjsip_rx_data *rdata)
|
|
|
4140
4642
|
char evt[2048];
|
|
4141
4643
|
|
|
4142
4644
|
pj_status_t status;
|
|
4143
|
-
pjsip_tx_data *tdata;
|
|
4144
|
-
int new_call;
|
|
4145
|
-
const pj_str_t str_refer_to = { "Refer-To", 8};
|
|
4146
|
-
const pj_str_t str_refer_sub = { "Refer-Sub", 9 };
|
|
4147
|
-
const pj_str_t str_ref_by = { "Referred-By", 11 };
|
|
4645
|
+
//pjsip_tx_data *tdata;
|
|
4646
|
+
//int new_call;
|
|
4647
|
+
const pj_str_t str_refer_to = { (char*)"Refer-To", 8};
|
|
4648
|
+
const pj_str_t str_refer_sub = { (char*)"Refer-Sub", 9 };
|
|
4649
|
+
//const pj_str_t str_ref_by = { (char*)"Referred-By", 11 };
|
|
4148
4650
|
pjsip_generic_string_hdr *refer_to;
|
|
4149
4651
|
pjsip_generic_string_hdr *refer_sub;
|
|
4150
|
-
pjsip_hdr *ref_by_hdr;
|
|
4652
|
+
//pjsip_hdr *ref_by_hdr;
|
|
4151
4653
|
pj_bool_t no_refer_sub = PJ_FALSE;
|
|
4152
|
-
char *uri;
|
|
4153
|
-
pj_str_t tmp;
|
|
4654
|
+
//char *uri;
|
|
4655
|
+
//pj_str_t tmp;
|
|
4154
4656
|
pjsip_status_code code;
|
|
4155
4657
|
pjsip_evsub *sub;
|
|
4156
4658
|
|
|
@@ -4177,13 +4679,14 @@ void process_in_dialog_refer(pjsip_dialog *dlg, pjsip_rx_data *rdata)
|
|
|
4177
4679
|
/* Find optional Referred-By header (to be copied onto outgoing INVITE
|
|
4178
4680
|
* request.
|
|
4179
4681
|
*/
|
|
4682
|
+
/*
|
|
4180
4683
|
ref_by_hdr = (pjsip_hdr*)
|
|
4181
4684
|
pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &str_ref_by,
|
|
4182
4685
|
NULL);
|
|
4183
|
-
|
|
4184
|
-
if(ref_by_hdr) {
|
|
4686
|
+
*/
|
|
4687
|
+
/* if(ref_by_hdr) {
|
|
4185
4688
|
pjsip_generic_string_hdr *referred_by = (pjsip_generic_string_hdr*)ref_by_hdr;
|
|
4186
|
-
}
|
|
4689
|
+
} */
|
|
4187
4690
|
|
|
4188
4691
|
/* Find optional Refer-Sub header */
|
|
4189
4692
|
refer_sub = (pjsip_generic_string_hdr*)
|
|
@@ -4206,7 +4709,7 @@ void process_in_dialog_refer(pjsip_dialog *dlg, pjsip_rx_data *rdata)
|
|
|
4206
4709
|
* Always answer with 2xx.
|
|
4207
4710
|
*/
|
|
4208
4711
|
pjsip_tx_data *tdata;
|
|
4209
|
-
const pj_str_t str_false = { "false", 5};
|
|
4712
|
+
const pj_str_t str_false = { (char*)"false", 5};
|
|
4210
4713
|
pjsip_hdr *hdr;
|
|
4211
4714
|
|
|
4212
4715
|
status = pjsip_dlg_create_response(dlg, rdata, code, NULL,
|
|
@@ -4260,7 +4763,7 @@ void process_in_dialog_refer(pjsip_dialog *dlg, pjsip_rx_data *rdata)
|
|
|
4260
4763
|
* Refer-Sub in the response with value "true" too.
|
|
4261
4764
|
*/
|
|
4262
4765
|
if (refer_sub) {
|
|
4263
|
-
const pj_str_t str_true = { "true", 4 };
|
|
4766
|
+
const pj_str_t str_true = { (char*)"true", 4 };
|
|
4264
4767
|
pjsip_hdr *hdr;
|
|
4265
4768
|
|
|
4266
4769
|
hdr = (pjsip_hdr*)
|
|
@@ -4324,7 +4827,7 @@ static void on_tsx_state_changed(pjsip_inv_session *inv,
|
|
|
4324
4827
|
}
|
|
4325
4828
|
|
|
4326
4829
|
//ostringstream oss;
|
|
4327
|
-
Transport *t;
|
|
4830
|
+
//Transport *t;
|
|
4328
4831
|
if (tsx->role==PJSIP_ROLE_UAS &&
|
|
4329
4832
|
tsx->state==PJSIP_TSX_STATE_TRYING) {
|
|
4330
4833
|
if(pjsip_method_cmp(&tsx->method, pjsip_get_refer_method())==0) {
|
|
@@ -4342,15 +4845,17 @@ static void on_tsx_state_changed(pjsip_inv_session *inv,
|
|
|
4342
4845
|
}
|
|
4343
4846
|
}
|
|
4344
4847
|
|
|
4345
|
-
int pjw_call_refer(long call_id, const char *dest_uri, const char *additional_headers, long *out_subscription_id)
|
|
4848
|
+
//int pjw_call_refer(long call_id, const char *dest_uri, const char *additional_headers, long *out_subscription_id)
|
|
4849
|
+
int pjw_call_refer(long call_id, const char *json, long *out_subscription_id)
|
|
4346
4850
|
{
|
|
4347
4851
|
PJW_LOCK();
|
|
4348
4852
|
clear_error();
|
|
4349
4853
|
|
|
4350
|
-
|
|
4854
|
+
char *dest_uri;
|
|
4855
|
+
char *additional_headers;
|
|
4856
|
+
|
|
4351
4857
|
long val;
|
|
4352
4858
|
Call *call;
|
|
4353
|
-
Subscription *s;
|
|
4354
4859
|
pj_str_t s_dest_uri;
|
|
4355
4860
|
|
|
4356
4861
|
long subscription_id;
|
|
@@ -4359,17 +4864,23 @@ int pjw_call_refer(long call_id, const char *dest_uri, const char *additional_he
|
|
|
4359
4864
|
pjsip_tx_data *tdata;
|
|
4360
4865
|
pj_status_t status;
|
|
4361
4866
|
|
|
4867
|
+
char buffer[MAX_JSON_INPUT];
|
|
4868
|
+
|
|
4869
|
+
Document document;
|
|
4870
|
+
|
|
4362
4871
|
if(!g_call_ids.get(call_id, val)){
|
|
4363
4872
|
set_error("Invalid call_id");
|
|
4364
4873
|
goto out;
|
|
4365
4874
|
}
|
|
4366
|
-
|
|
4367
4875
|
call = (Call*)val;
|
|
4368
4876
|
|
|
4369
|
-
|
|
4370
|
-
|
|
4371
|
-
|
|
4372
|
-
|
|
4877
|
+
if(!parse_json(document, json, buffer, MAX_JSON_INPUT)) {
|
|
4878
|
+
goto out;
|
|
4879
|
+
}
|
|
4880
|
+
|
|
4881
|
+
if(!json_get_and_check_uri(document, "dest_uri", false, &dest_uri)) {
|
|
4882
|
+
goto out;
|
|
4883
|
+
}
|
|
4373
4884
|
|
|
4374
4885
|
pj_bzero(&xfer_cb, sizeof(xfer_cb));
|
|
4375
4886
|
xfer_cb.on_evsub_state = &client_on_evsub_state;
|
|
@@ -4377,7 +4888,7 @@ int pjw_call_refer(long call_id, const char *dest_uri, const char *additional_he
|
|
|
4377
4888
|
|
|
4378
4889
|
status = pjsip_xfer_create_uac(call->inv->dlg, &xfer_cb, &sub);
|
|
4379
4890
|
if(status != PJ_SUCCESS) {
|
|
4380
|
-
set_error("pjsip_xfer_create_uac failed");
|
|
4891
|
+
set_error("pjsip_xfer_create_uac failed with status=%i", status);
|
|
4381
4892
|
goto out;
|
|
4382
4893
|
}
|
|
4383
4894
|
|
|
@@ -4390,17 +4901,17 @@ int pjw_call_refer(long call_id, const char *dest_uri, const char *additional_he
|
|
|
4390
4901
|
|
|
4391
4902
|
status = pjsip_xfer_send_request(sub, tdata);
|
|
4392
4903
|
if(status != PJ_SUCCESS) {
|
|
4393
|
-
set_error("pjsip_xfer_send_request failed");
|
|
4904
|
+
set_error("pjsip_xfer_send_request failed with status=%i", status);
|
|
4394
4905
|
goto out;
|
|
4395
4906
|
}
|
|
4396
4907
|
|
|
4908
|
+
*out_subscription_id = subscription_id;
|
|
4909
|
+
|
|
4397
4910
|
out:
|
|
4398
4911
|
PJW_UNLOCK();
|
|
4399
|
-
|
|
4400
4912
|
if(pjw_errorstring[0]) {
|
|
4401
4913
|
return -1;
|
|
4402
4914
|
}
|
|
4403
|
-
*out_subscription_id = subscription_id;
|
|
4404
4915
|
return 0;
|
|
4405
4916
|
}
|
|
4406
4917
|
|
|
@@ -4437,7 +4948,7 @@ int pjw_call_get_info(long call_id, const char *required_info, char *out_info)
|
|
|
4437
4948
|
}
|
|
4438
4949
|
pj_str_t str_addr = pj_str( inet_ntoa( (in_addr&)session_info.rem_addr.ipv4.sin_addr.s_addr ) );
|
|
4439
4950
|
pj_uint16_t port = session_info.rem_addr.ipv4.sin_port;
|
|
4440
|
-
sprintf(info, "%.*s:%u", str_addr.slen, str_addr.ptr, ntohs(port));
|
|
4951
|
+
sprintf(info, "%.*s:%u", (int)str_addr.slen, str_addr.ptr, ntohs(port));
|
|
4441
4952
|
} else {
|
|
4442
4953
|
PJW_UNLOCK();
|
|
4443
4954
|
set_error("Unsupported info");
|
|
@@ -4450,8 +4961,8 @@ int pjw_call_get_info(long call_id, const char *required_info, char *out_info)
|
|
|
4450
4961
|
}
|
|
4451
4962
|
|
|
4452
4963
|
bool notify(pjsip_evsub *evsub, const char *content_type, const char *body, int subscription_state, const char *reason, const char *additional_headers) {
|
|
4453
|
-
pj_str_t s_content_type;
|
|
4454
|
-
pj_str_t s_body;
|
|
4964
|
+
//pj_str_t s_content_type;
|
|
4965
|
+
//pj_str_t s_body;
|
|
4455
4966
|
pj_str_t s_reason;
|
|
4456
4967
|
|
|
4457
4968
|
char *temp;
|
|
@@ -4464,9 +4975,9 @@ bool notify(pjsip_evsub *evsub, const char *content_type, const char *body, int
|
|
|
4464
4975
|
char *content_type_buffer;
|
|
4465
4976
|
pj_str_t s_content_type_type;
|
|
4466
4977
|
pj_str_t s_content_type_subtype;
|
|
4467
|
-
pj_str_t s_content_type_param;
|
|
4978
|
+
//pj_str_t s_content_type_param;
|
|
4468
4979
|
|
|
4469
|
-
char *blank_string;
|
|
4980
|
+
//char *blank_string;
|
|
4470
4981
|
|
|
4471
4982
|
pjsip_tx_data *tdata;
|
|
4472
4983
|
pj_status_t status;
|
|
@@ -4524,22 +5035,30 @@ bool notify(pjsip_evsub *evsub, const char *content_type, const char *body, int
|
|
|
4524
5035
|
return true;
|
|
4525
5036
|
}
|
|
4526
5037
|
|
|
4527
|
-
int pjw_notify(long subscriber_id, const char *content_type, const char *body, int subscription_state, const char *reason, const char *additional_headers)
|
|
5038
|
+
//int pjw_notify(long subscriber_id, const char *content_type, const char *body, int subscription_state, const char *reason, const char *additional_headers)
|
|
5039
|
+
int pjw_notify(long subscriber_id, const char *json)
|
|
4528
5040
|
{
|
|
4529
5041
|
PJW_LOCK();
|
|
4530
|
-
|
|
4531
5042
|
clear_error();
|
|
4532
5043
|
|
|
4533
|
-
|
|
5044
|
+
char *content_type = NULL;
|
|
5045
|
+
char *body = NULL;
|
|
5046
|
+
int subscription_state;
|
|
5047
|
+
char *reason = NULL;
|
|
5048
|
+
char *additional_headers = NULL;
|
|
5049
|
+
|
|
4534
5050
|
long val;
|
|
4535
5051
|
|
|
4536
5052
|
Subscriber *subscriber;
|
|
4537
5053
|
|
|
5054
|
+
char buffer[MAX_JSON_INPUT];
|
|
5055
|
+
|
|
5056
|
+
Document document;
|
|
5057
|
+
|
|
4538
5058
|
if(!g_subscriber_ids.get(subscriber_id, val)){
|
|
4539
5059
|
set_error("Invalid subscriber_id");
|
|
4540
5060
|
goto out;
|
|
4541
5061
|
}
|
|
4542
|
-
|
|
4543
5062
|
subscriber = (Subscriber*)val;
|
|
4544
5063
|
|
|
4545
5064
|
if(subscriber->created_by_refer) {
|
|
@@ -4547,40 +5066,63 @@ int pjw_notify(long subscriber_id, const char *content_type, const char *body, i
|
|
|
4547
5066
|
goto out;
|
|
4548
5067
|
}
|
|
4549
5068
|
|
|
5069
|
+
if(!parse_json(document, json, buffer, MAX_JSON_INPUT)) {
|
|
5070
|
+
goto out;
|
|
5071
|
+
}
|
|
5072
|
+
|
|
5073
|
+
if(!json_get_string_param(document, "content_type", false, &content_type)) {
|
|
5074
|
+
goto out;
|
|
5075
|
+
}
|
|
5076
|
+
|
|
5077
|
+
if(!json_get_string_param(document, "body", false, &body)) {
|
|
5078
|
+
goto out;
|
|
5079
|
+
}
|
|
5080
|
+
|
|
5081
|
+
if(!json_get_int_param(document, "subscription_state", false, &subscription_state)) {
|
|
5082
|
+
goto out;
|
|
5083
|
+
}
|
|
5084
|
+
|
|
5085
|
+
if(!json_get_string_param(document, "reason", true, &reason)) {
|
|
5086
|
+
goto out;
|
|
5087
|
+
}
|
|
5088
|
+
|
|
4550
5089
|
if(!notify(subscriber->evsub, content_type, body, subscription_state, reason, additional_headers)){
|
|
4551
5090
|
goto out;
|
|
4552
5091
|
}
|
|
4553
5092
|
|
|
4554
5093
|
out:
|
|
4555
5094
|
PJW_UNLOCK();
|
|
4556
|
-
|
|
4557
5095
|
if(pjw_errorstring[0]) {
|
|
4558
5096
|
return -1;
|
|
4559
5097
|
}
|
|
4560
|
-
|
|
4561
5098
|
return 0;
|
|
4562
5099
|
}
|
|
4563
5100
|
|
|
4564
5101
|
|
|
4565
|
-
int pjw_notify_xfer(long subscriber_id, int subscription_state, int xfer_status_code, const char *xfer_status_text) {
|
|
5102
|
+
//int pjw_notify_xfer(long subscriber_id, int subscription_state, int xfer_status_code, const char *xfer_status_text) {
|
|
5103
|
+
int pjw_notify_xfer(long subscriber_id, const char *json) {
|
|
4566
5104
|
PJW_LOCK();
|
|
4567
|
-
|
|
4568
5105
|
clear_error();
|
|
4569
5106
|
|
|
4570
|
-
int n;
|
|
4571
5107
|
pjsip_tx_data *tdata;
|
|
4572
5108
|
pj_status_t status;
|
|
4573
5109
|
|
|
5110
|
+
int subscription_state;
|
|
5111
|
+
int code;
|
|
5112
|
+
char *reason;
|
|
5113
|
+
|
|
4574
5114
|
long val;
|
|
4575
5115
|
|
|
4576
5116
|
Subscriber *subscriber;
|
|
4577
|
-
pj_str_t
|
|
5117
|
+
pj_str_t r;
|
|
4578
5118
|
|
|
5119
|
+
char buffer[MAX_JSON_INPUT];
|
|
5120
|
+
|
|
5121
|
+
Document document;
|
|
4579
5122
|
if(!g_subscriber_ids.get(subscriber_id, val)){
|
|
4580
5123
|
set_error("Invalid subscriber_id");
|
|
4581
5124
|
goto out;
|
|
4582
5125
|
}
|
|
4583
|
-
|
|
4584
5126
|
subscriber = (Subscriber*)val;
|
|
4585
5127
|
|
|
4586
5128
|
if(!subscriber->created_by_refer) {
|
|
@@ -4588,23 +5130,39 @@ int pjw_notify_xfer(long subscriber_id, int subscription_state, int xfer_status_
|
|
|
4588
5130
|
goto out;
|
|
4589
5131
|
}
|
|
4590
5132
|
|
|
4591
|
-
|
|
5133
|
+
if(!parse_json(document, json, buffer, MAX_JSON_INPUT)) {
|
|
5134
|
+
goto out;
|
|
5135
|
+
}
|
|
4592
5136
|
|
|
4593
|
-
|
|
4594
|
-
|
|
4595
|
-
|
|
4596
|
-
&s_xfer_status_text,
|
|
4597
|
-
&tdata);
|
|
4598
|
-
if (status != PJ_SUCCESS) {
|
|
4599
|
-
set_error( "Unable to create NOTIFY for 'Event: refer'");
|
|
4600
|
-
goto out;
|
|
4601
|
-
}
|
|
5137
|
+
if(!json_get_int_param(document, "subscription_state", false, &subscription_state)) {
|
|
5138
|
+
goto out;
|
|
5139
|
+
}
|
|
4602
5140
|
|
|
4603
|
-
|
|
4604
|
-
|
|
4605
|
-
|
|
4606
|
-
|
|
4607
|
-
|
|
5141
|
+
if(!json_get_int_param(document, "code", false, &code)) {
|
|
5142
|
+
goto out;
|
|
5143
|
+
}
|
|
5144
|
+
|
|
5145
|
+
if(!json_get_string_param(document, "reason", false, &reason)) {
|
|
5146
|
+
goto out;
|
|
5147
|
+
}
|
|
5148
|
+
|
|
5149
|
+
r = pj_str((char*)reason);
|
|
5150
|
+
|
|
5151
|
+
status = pjsip_xfer_notify( subscriber->evsub,
|
|
5152
|
+
(pjsip_evsub_state)subscription_state,
|
|
5153
|
+
code,
|
|
5154
|
+
&r,
|
|
5155
|
+
&tdata);
|
|
5156
|
+
if (status != PJ_SUCCESS) {
|
|
5157
|
+
set_error( "pjsip_xfer_notify failed with status=%i", status);
|
|
5158
|
+
goto out;
|
|
5159
|
+
}
|
|
5160
|
+
|
|
5161
|
+
status = pjsip_xfer_send_request( subscriber->evsub, tdata);
|
|
5162
|
+
if (status != PJ_SUCCESS) {
|
|
5163
|
+
set_error("pjsip_xfer_send_request failed with status=%i", status);
|
|
5164
|
+
goto out;
|
|
5165
|
+
}
|
|
4608
5166
|
|
|
4609
5167
|
out:
|
|
4610
5168
|
PJW_UNLOCK();
|
|
@@ -4765,7 +5323,7 @@ int pjw_register_pkg(const char *event, const char *accept) {
|
|
|
4765
5323
|
|
|
4766
5324
|
clear_error();
|
|
4767
5325
|
|
|
4768
|
-
int n;
|
|
5326
|
+
//int n;
|
|
4769
5327
|
|
|
4770
5328
|
if(!register_pkg(event, accept)) {
|
|
4771
5329
|
goto out;
|
|
@@ -4780,12 +5338,23 @@ out:
|
|
|
4780
5338
|
return 0;
|
|
4781
5339
|
}
|
|
4782
5340
|
|
|
4783
|
-
int pjw_subscription_create(long transport_id, const char *event, const char *accept, const char *from_uri, const char *to_uri, const char *request_uri, const char *proxy_uri, const char *realm, const char *username, const char *password, long *out_subscription_id) {
|
|
5341
|
+
//int pjw_subscription_create(long transport_id, const char *event, const char *accept, const char *from_uri, const char *to_uri, const char *request_uri, const char *proxy_uri, const char *realm, const char *username, const char *password, long *out_subscription_id) {
|
|
5342
|
+
int pjw_subscription_create(long transport_id, const char *json, long *out_subscription_id) {
|
|
4784
5343
|
PJW_LOCK();
|
|
4785
|
-
|
|
4786
5344
|
clear_error();
|
|
4787
5345
|
|
|
4788
|
-
|
|
5346
|
+
char *event = NULL;
|
|
5347
|
+
char *accept = NULL;
|
|
5348
|
+
|
|
5349
|
+
char *from_uri = NULL;
|
|
5350
|
+
char *to_uri = NULL;
|
|
5351
|
+
char *request_uri = NULL;
|
|
5352
|
+
char *proxy_uri = NULL;
|
|
5353
|
+
|
|
5354
|
+
char *realm = NULL;
|
|
5355
|
+
char *username = NULL;
|
|
5356
|
+
char *password = NULL;
|
|
5357
|
+
|
|
4789
5358
|
long subscription_id;
|
|
4790
5359
|
Subscription *subscription;
|
|
4791
5360
|
Transport *t;
|
|
@@ -4793,7 +5362,7 @@ int pjw_subscription_create(long transport_id, const char *event, const char *ac
|
|
|
4793
5362
|
const char *contact_username = "sip";
|
|
4794
5363
|
|
|
4795
5364
|
char local_contact[400];
|
|
4796
|
-
char *start;
|
|
5365
|
+
//char *start;
|
|
4797
5366
|
|
|
4798
5367
|
pjsip_dialog *dlg = NULL;
|
|
4799
5368
|
pjsip_evsub *evsub = NULL;
|
|
@@ -4803,38 +5372,80 @@ int pjw_subscription_create(long transport_id, const char *event, const char *ac
|
|
|
4803
5372
|
|
|
4804
5373
|
pj_status_t status;
|
|
4805
5374
|
|
|
5375
|
+
char buffer[MAX_JSON_INPUT];
|
|
5376
|
+
|
|
5377
|
+
Document document;
|
|
5378
|
+
|
|
4806
5379
|
if(!g_transport_ids.get(transport_id, val)){
|
|
4807
5380
|
set_error("Invalid transport_id");
|
|
4808
5381
|
goto out;
|
|
4809
5382
|
}
|
|
4810
5383
|
t = (Transport*)val;
|
|
4811
5384
|
|
|
4812
|
-
|
|
4813
|
-
|
|
4814
|
-
|
|
4815
|
-
}
|
|
5385
|
+
if(!parse_json(document, json, buffer, MAX_JSON_INPUT)) {
|
|
5386
|
+
goto out;
|
|
5387
|
+
}
|
|
4816
5388
|
|
|
4817
|
-
|
|
4818
|
-
|
|
4819
|
-
|
|
4820
|
-
|
|
5389
|
+
if(!json_get_string_param(document, "event", false, &event)) {
|
|
5390
|
+
goto out;
|
|
5391
|
+
}
|
|
5392
|
+
|
|
5393
|
+
if(!json_get_string_param(document, "accept", false, &accept)) {
|
|
5394
|
+
goto out;
|
|
5395
|
+
}
|
|
5396
|
+
|
|
5397
|
+
if(!json_get_and_check_uri(document, "from_uri", false, &from_uri)) {
|
|
5398
|
+
goto out;
|
|
5399
|
+
}
|
|
5400
|
+
|
|
5401
|
+
if(!json_get_and_check_uri(document, "to_uri", false, &to_uri)) {
|
|
5402
|
+
goto out;
|
|
5403
|
+
}
|
|
5404
|
+
|
|
5405
|
+
request_uri = to_uri;
|
|
5406
|
+
if(!json_get_and_check_uri(document, "request_uri", true, &request_uri)) {
|
|
5407
|
+
goto out;
|
|
5408
|
+
}
|
|
5409
|
+
|
|
5410
|
+
if(!json_get_and_check_uri(document, "proxy_uri", true, &proxy_uri)) {
|
|
5411
|
+
goto out;
|
|
5412
|
+
}
|
|
4821
5413
|
|
|
4822
|
-
|
|
4823
|
-
|
|
4824
|
-
|
|
5414
|
+
if(document.HasMember("auth")) {
|
|
5415
|
+
if(!document["auth"].IsObject()) {
|
|
5416
|
+
set_error("Parameter auth must be an object");
|
|
5417
|
+
goto out;
|
|
5418
|
+
} else {
|
|
5419
|
+
const Value& auth = document["auth"];
|
|
5420
|
+
|
|
5421
|
+
for (Value::ConstMemberIterator itr = auth.MemberBegin(); itr != auth.MemberEnd(); ++itr) {
|
|
5422
|
+
const char *name = itr->name.GetString();
|
|
5423
|
+
if(strcmp(name, "realm") == 0) {
|
|
5424
|
+
if(!itr->value.IsString()) {
|
|
5425
|
+
set_error("%s must be a string", itr->name.GetString());
|
|
5426
|
+
goto out;
|
|
5427
|
+
}
|
|
5428
|
+
realm = (char*)itr->value.GetString();
|
|
5429
|
+
} else if(strcmp(name, "username") == 0) {
|
|
5430
|
+
if(!itr->value.IsString()) {
|
|
5431
|
+
set_error("%s must be a string", itr->name.GetString());
|
|
4825
5432
|
goto out;
|
|
5433
|
+
}
|
|
5434
|
+
username = (char*)itr->value.GetString();
|
|
5435
|
+
contact_username = username;
|
|
5436
|
+
} else if(strcmp(name, "password") == 0) {
|
|
5437
|
+
if(!itr->value.IsString()) {
|
|
5438
|
+
set_error("%s must be a string", itr->name.GetString());
|
|
5439
|
+
goto out;
|
|
5440
|
+
}
|
|
5441
|
+
password = (char*)itr->value.GetString();
|
|
5442
|
+
} else {
|
|
5443
|
+
set_error("Unknown auth paramter %s", itr->name.GetString());
|
|
5444
|
+
goto out;
|
|
4826
5445
|
}
|
|
4827
|
-
|
|
4828
|
-
request_uri = to_uri;
|
|
5446
|
+
}
|
|
4829
5447
|
}
|
|
4830
|
-
|
|
4831
|
-
if(realm) {
|
|
4832
|
-
if(!username || !password) {
|
|
4833
|
-
set_error("Not all authentication data was provided");
|
|
4834
|
-
goto out;
|
|
4835
|
-
}
|
|
4836
|
-
contact_username = username;
|
|
4837
|
-
}
|
|
5448
|
+
}
|
|
4838
5449
|
|
|
4839
5450
|
build_local_contact(local_contact, t->sip_transport, contact_username);
|
|
4840
5451
|
|
|
@@ -4859,7 +5470,7 @@ int pjw_subscription_create(long transport_id, const char *event, const char *ac
|
|
|
4859
5470
|
PJSIP_EVSUB_NO_EVENT_ID,
|
|
4860
5471
|
&evsub);
|
|
4861
5472
|
if(status != PJ_SUCCESS) {
|
|
4862
|
-
set_error("pjsip_evsub_create_uac failed");
|
|
5473
|
+
set_error("pjsip_evsub_create_uac failed with status=%i", status);
|
|
4863
5474
|
goto out;
|
|
4864
5475
|
}
|
|
4865
5476
|
|
|
@@ -4885,13 +5496,12 @@ int pjw_subscription_create(long transport_id, const char *event, const char *ac
|
|
|
4885
5496
|
strcpy(subscription->accept, accept);
|
|
4886
5497
|
pjsip_evsub_set_mod_data(evsub, mod_tester.id, subscription);
|
|
4887
5498
|
|
|
5499
|
+
*out_subscription_id = subscription_id;
|
|
4888
5500
|
out:
|
|
4889
5501
|
PJW_UNLOCK();
|
|
4890
5502
|
if(pjw_errorstring[0]){
|
|
4891
5503
|
return -1;
|
|
4892
5504
|
}
|
|
4893
|
-
|
|
4894
|
-
*out_subscription_id = subscription_id;
|
|
4895
5505
|
return 0;
|
|
4896
5506
|
}
|
|
4897
5507
|
|
|
@@ -4928,29 +5538,42 @@ bool subscription_subscribe(Subscription *s, int expires, const char *additional
|
|
|
4928
5538
|
return true;
|
|
4929
5539
|
}
|
|
4930
5540
|
|
|
4931
|
-
int pjw_subscription_subscribe(long subscription_id, int expires, const char *additional_headers) {
|
|
5541
|
+
//int pjw_subscription_subscribe(long subscription_id, int expires, const char *additional_headers) {
|
|
5542
|
+
int pjw_subscription_subscribe(long subscription_id, const char *json) {
|
|
4932
5543
|
PJW_LOCK();
|
|
4933
|
-
|
|
4934
5544
|
clear_error();
|
|
4935
5545
|
|
|
5546
|
+
int expires;
|
|
5547
|
+
char *additional_headers = NULL;
|
|
5548
|
+
|
|
4936
5549
|
Subscription *subscription;
|
|
4937
5550
|
|
|
4938
5551
|
long val;
|
|
4939
5552
|
|
|
5553
|
+
char buffer[MAX_JSON_INPUT];
|
|
5554
|
+
|
|
5555
|
+
Document document;
|
|
5556
|
+
|
|
4940
5557
|
if(!g_subscription_ids.get(subscription_id, val)){
|
|
4941
5558
|
set_error("Invalid subscription_id");
|
|
4942
5559
|
goto out;
|
|
4943
5560
|
}
|
|
4944
|
-
|
|
4945
5561
|
subscription = (Subscription*)val;
|
|
4946
5562
|
|
|
5563
|
+
if(!parse_json(document, json, buffer, MAX_JSON_INPUT)) {
|
|
5564
|
+
goto out;
|
|
5565
|
+
}
|
|
5566
|
+
|
|
5567
|
+
if(!json_get_int_param(document, "expires", true, &expires)) {
|
|
5568
|
+
goto out;
|
|
5569
|
+
}
|
|
5570
|
+
|
|
4947
5571
|
if(!subscription_subscribe(subscription, expires, additional_headers)) {
|
|
4948
5572
|
goto out;
|
|
4949
5573
|
}
|
|
4950
5574
|
|
|
4951
5575
|
out:
|
|
4952
5576
|
PJW_UNLOCK();
|
|
4953
|
-
|
|
4954
5577
|
if(pjw_errorstring[0]) {
|
|
4955
5578
|
return -1;
|
|
4956
5579
|
}
|
|
@@ -4961,7 +5584,7 @@ void process_in_dialog_subscribe(pjsip_dialog *dlg, pjsip_rx_data *rdata) {
|
|
|
4961
5584
|
char evt[2048];
|
|
4962
5585
|
|
|
4963
5586
|
Subscriber *s;
|
|
4964
|
-
Transport *t;
|
|
5587
|
+
//Transport *t;
|
|
4965
5588
|
|
|
4966
5589
|
s = (Subscriber*)dlg->mod_data[mod_tester.id];
|
|
4967
5590
|
if(!s) {
|
|
@@ -4979,11 +5602,11 @@ int pjw_call_gen_string_replaces(long call_id, char *out_replaces) {
|
|
|
4979
5602
|
|
|
4980
5603
|
clear_error();
|
|
4981
5604
|
|
|
4982
|
-
int n;
|
|
5605
|
+
//int n;
|
|
4983
5606
|
long val;
|
|
4984
5607
|
Call *call;
|
|
4985
5608
|
pjsip_dialog *dlg;
|
|
4986
|
-
int len;
|
|
5609
|
+
//int len;
|
|
4987
5610
|
char *p;
|
|
4988
5611
|
char buf[2000];
|
|
4989
5612
|
pjsip_uri* uri;
|