sip-lab 1.11.2 → 1.12.1
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/{late_negotiation.js → delayed_media.js} +22 -25
- package/samples/g729.js +11 -11
- package/samples/register_subscribe.js +30 -7
- package/samples/reinvite_and_dtmf.js +22 -24
- package/samples/send_and_receive_fax.js +7 -11
- package/samples/simple.js +10 -12
- package/samples/sip_cancel.js +10 -12
- package/samples/tcp_and_extra_headers.js +333 -0
- package/src/addon.cpp +107 -498
- package/src/event_templates.cpp +22 -22
- package/src/event_templates.hpp +10 -10
- package/src/sip.cpp +1267 -599
- 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;
|
|
@@ -312,10 +426,10 @@ static void server_on_evsub_rx_refresh(pjsip_evsub *sub, pjsip_rx_data *rdata, i
|
|
|
312
426
|
|
|
313
427
|
bool dlg_create(pjsip_dialog **dlg, Transport *transport, const char *from_uri, const char *to_uri, const char *request_uri, const char *realm, const char *username, const char *password, const char *local_contact);
|
|
314
428
|
|
|
315
|
-
static int call_create(Transport *t, unsigned flags, pjsip_dialog *dlg, const char *proxy_uri,
|
|
429
|
+
static int call_create(Transport *t, unsigned flags, pjsip_dialog *dlg, const char *proxy_uri, Document &document);
|
|
316
430
|
|
|
317
|
-
|
|
318
|
-
bool subscription_subscribe(Subscription *s, int expires,
|
|
431
|
+
bool subscription_subscribe_no_headers(Subscription *s, int expires);
|
|
432
|
+
bool subscription_subscribe(Subscription *s, int expires, Document &document);
|
|
319
433
|
|
|
320
434
|
static pjmedia_transport *create_media_transport(const pj_str_t *addr);
|
|
321
435
|
void close_media_transport(pjmedia_transport *med_transport);
|
|
@@ -333,11 +447,12 @@ bool set_proxy(pjsip_dialog *dlg, const char *proxy_uri);
|
|
|
333
447
|
void build_local_contact(char *dest, pjsip_transport *transport, const char *contact_username);
|
|
334
448
|
void build_local_contact_from_tpfactory(char *dest, pjsip_tpfactory *tpfactory, const char *contact_username, pjsip_transport_type_e type);
|
|
335
449
|
|
|
336
|
-
pj_bool_t add_additional_headers(pj_pool_t *pool, pjsip_tx_data *tdata, const char *additional_headers);
|
|
450
|
+
//pj_bool_t add_additional_headers(pj_pool_t *pool, pjsip_tx_data *tdata, const char *additional_headers);
|
|
451
|
+
pj_bool_t add_headers(pj_pool_t *pool, pjsip_tx_data *tdata, Document &document);
|
|
337
452
|
|
|
338
|
-
pj_bool_t
|
|
453
|
+
pj_bool_t add_headers_for_account(pjsip_regc* regc, Document &document);
|
|
339
454
|
|
|
340
|
-
pj_bool_t
|
|
455
|
+
pj_bool_t get_content_type_and_subtype_from_headers(Document &document, char *type, char *subtype);
|
|
341
456
|
|
|
342
457
|
bool build_subscribe_info(ostringstream *oss, pjsip_rx_data *rdata, Subscriber *s);
|
|
343
458
|
//bool build_notify_info(pjsip_rx_data *rdata, Subscription *s);
|
|
@@ -372,7 +487,7 @@ void append_status(ostringstream *oss, pj_status_t s);
|
|
|
372
487
|
static pjsip_module mod_tester =
|
|
373
488
|
{
|
|
374
489
|
NULL, NULL, /* prev, next. */
|
|
375
|
-
{ "mod_tester", 10 }, /* Name. */
|
|
490
|
+
{ (char*)"mod_tester", 10 }, /* Name. */
|
|
376
491
|
-1, /* Id */
|
|
377
492
|
//PJSIP_MOD_PRIORITY_APPLICATION, /* Priority */
|
|
378
493
|
PJSIP_MOD_PRIORITY_DIALOG_USAGE, /* Priority */
|
|
@@ -400,10 +515,6 @@ Timer _timer;
|
|
|
400
515
|
|
|
401
516
|
void dispatch_event(const char * evt);
|
|
402
517
|
|
|
403
|
-
int check_uri(const char *uri) {
|
|
404
|
-
return (strstr(uri, "sip:") != NULL);
|
|
405
|
-
}
|
|
406
|
-
|
|
407
518
|
const char *translate_pjsip_inv_state(int state)
|
|
408
519
|
{
|
|
409
520
|
switch(state)
|
|
@@ -489,11 +600,12 @@ void dispatch_event(const char * evt)
|
|
|
489
600
|
}
|
|
490
601
|
|
|
491
602
|
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";
|
|
603
|
+
if(mode == SENDRECV) return (char*)"sendrecv";
|
|
604
|
+
if(mode == SENDONLY) return (char*)"sendonly";
|
|
605
|
+
if(mode == RECVONLY) return (char*)"recvonly";
|
|
606
|
+
if(mode == INACTIVE) return (char*)"inactive";
|
|
607
|
+
if(mode == UNKNOWN) return (char*)"unknown";
|
|
608
|
+
return (char*)"unexpected";
|
|
497
609
|
}
|
|
498
610
|
|
|
499
611
|
static int get_media_mode(pjmedia_sdp_attr **attrs, int count) {
|
|
@@ -541,7 +653,7 @@ int __pjw_init()
|
|
|
541
653
|
|
|
542
654
|
pj_caching_pool_init(&cp, &pj_pool_factory_default_policy, 0);
|
|
543
655
|
|
|
544
|
-
char *sip_endpt_name = "mysip";
|
|
656
|
+
char *sip_endpt_name = (char*)"mysip";
|
|
545
657
|
|
|
546
658
|
status = pjsip_endpt_create(&cp.factory, sip_endpt_name, &g_sip_endpt);
|
|
547
659
|
if(status != PJ_SUCCESS)
|
|
@@ -560,9 +672,9 @@ int __pjw_init()
|
|
|
560
672
|
return 1;
|
|
561
673
|
}
|
|
562
674
|
|
|
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 };
|
|
675
|
+
const pj_str_t msg_tag = { (char*)"MESSAGE", 7 };
|
|
676
|
+
const pj_str_t STR_MIME_TEXT_PLAIN = { (char*)"text/plain", 10 };
|
|
677
|
+
const pj_str_t STR_MIME_APP_ISCOMPOSING = { (char*)"application/im-iscomposing+xml", 30 };
|
|
566
678
|
|
|
567
679
|
/* Register support for MESSAGE method. */
|
|
568
680
|
status = pjsip_endpt_add_capability(g_sip_endpt, &mod_tester, PJSIP_H_ALLOW,
|
|
@@ -818,7 +930,7 @@ pjsip_transport *allocate_udp_transport(pjsip_endpoint* sip_endpt, pj_str_t *ipa
|
|
|
818
930
|
|
|
819
931
|
pjsip_transport *create_udp_transport(pjsip_endpoint* sip_endpt, pj_str_t *ipaddr, int *allocated_port)
|
|
820
932
|
{
|
|
821
|
-
pj_status_t status;
|
|
933
|
+
//pj_status_t status;
|
|
822
934
|
pjsip_transport *transport;
|
|
823
935
|
|
|
824
936
|
int port = 5060;
|
|
@@ -836,11 +948,11 @@ pjsip_transport *create_udp_transport(pjsip_endpoint* sip_endpt, pj_str_t *ipadd
|
|
|
836
948
|
}
|
|
837
949
|
|
|
838
950
|
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);
|
|
951
|
+
printf("allocate_tcp_tpfactory ipaddr=%.*s port=%i\n", (int)ipaddr->slen, ipaddr->ptr, port);
|
|
840
952
|
pj_status_t status;
|
|
841
953
|
pjsip_tpfactory *tpfactory;
|
|
842
954
|
pj_sockaddr local_addr;
|
|
843
|
-
pjsip_host_port a_name;
|
|
955
|
+
//pjsip_host_port a_name;
|
|
844
956
|
|
|
845
957
|
int af;
|
|
846
958
|
af = pj_AF_INET();
|
|
@@ -864,7 +976,7 @@ pjsip_tpfactory *allocate_tcp_tpfactory(pjsip_endpoint* sip_endpt, pj_str_t *ipa
|
|
|
864
976
|
|
|
865
977
|
pjsip_tpfactory *create_tcp_tpfactory(pjsip_endpoint* sip_endpt, pj_str_t *ipaddr, int *allocated_port)
|
|
866
978
|
{
|
|
867
|
-
pj_status_t status;
|
|
979
|
+
//pj_status_t status;
|
|
868
980
|
pjsip_tpfactory *tpfactory;
|
|
869
981
|
|
|
870
982
|
int port = 6060;
|
|
@@ -886,7 +998,7 @@ pjsip_tpfactory *allocate_tls_tpfactory(pjsip_endpoint* sip_endpt, pj_str_t *ipa
|
|
|
886
998
|
pj_status_t status;
|
|
887
999
|
pjsip_tpfactory *tpfactory;
|
|
888
1000
|
pj_sockaddr local_addr;
|
|
889
|
-
pjsip_host_port a_name;
|
|
1001
|
+
//pjsip_host_port a_name;
|
|
890
1002
|
|
|
891
1003
|
int af;
|
|
892
1004
|
af = pj_AF_INET();
|
|
@@ -913,7 +1025,7 @@ pjsip_tpfactory *allocate_tls_tpfactory(pjsip_endpoint* sip_endpt, pj_str_t *ipa
|
|
|
913
1025
|
|
|
914
1026
|
pjsip_tpfactory *create_tls_tpfactory(pjsip_endpoint* sip_endpt, pj_str_t *ipaddr, int *allocated_port)
|
|
915
1027
|
{
|
|
916
|
-
pj_status_t status;
|
|
1028
|
+
//pj_status_t status;
|
|
917
1029
|
pjsip_tpfactory *tpfactory;
|
|
918
1030
|
|
|
919
1031
|
int port = 6060;
|
|
@@ -930,31 +1042,83 @@ pjsip_tpfactory *create_tls_tpfactory(pjsip_endpoint* sip_endpt, pj_str_t *ipadd
|
|
|
930
1042
|
return NULL;
|
|
931
1043
|
}
|
|
932
1044
|
|
|
933
|
-
int pjw_transport_create(const char *sip_ipaddr, int port, pjsip_transport_type_e type, int *out_t_id, int *out_port)
|
|
1045
|
+
//int pjw_transport_create(const char *sip_ipaddr, int port, pjsip_transport_type_e type, int *out_t_id, int *out_port)
|
|
1046
|
+
int pjw_transport_create(const char *json, int *out_t_id, char *out_t_address, int *out_port)
|
|
934
1047
|
{
|
|
935
1048
|
PJW_LOCK();
|
|
936
1049
|
clear_error();
|
|
937
1050
|
|
|
938
|
-
|
|
1051
|
+
char *addr;
|
|
1052
|
+
pj_str_t address; // = pj_str((char*)sip_ipaddr);
|
|
1053
|
+
int port = 0;
|
|
1054
|
+
pjsip_transport_type_e type = PJSIP_TRANSPORT_UDP;
|
|
939
1055
|
|
|
940
1056
|
pj_status_t status;
|
|
941
1057
|
Transport *t = NULL;
|
|
942
1058
|
long t_id;
|
|
943
1059
|
|
|
1060
|
+
char buffer[MAX_JSON_INPUT];
|
|
1061
|
+
|
|
1062
|
+
Document document;
|
|
1063
|
+
|
|
1064
|
+
if(!parse_json(document, json, buffer, MAX_JSON_INPUT)) {
|
|
1065
|
+
goto out;
|
|
1066
|
+
}
|
|
1067
|
+
|
|
1068
|
+
// address
|
|
1069
|
+
if(!document.HasMember("address")) {
|
|
1070
|
+
set_error("Parameter address is required");
|
|
1071
|
+
goto out;
|
|
1072
|
+
}
|
|
1073
|
+
|
|
1074
|
+
if(!document["address"].IsString()) {
|
|
1075
|
+
set_error("Parameter address must be a string");
|
|
1076
|
+
goto out;
|
|
1077
|
+
}
|
|
1078
|
+
addr = (char*)document["address"].GetString();
|
|
1079
|
+
address = pj_str((char*)addr);
|
|
1080
|
+
|
|
1081
|
+
// port
|
|
1082
|
+
if(document.HasMember("port")) {
|
|
1083
|
+
if(!document["port"].IsInt()) {
|
|
1084
|
+
set_error("Parameter port must be an integer");
|
|
1085
|
+
goto out;
|
|
1086
|
+
}
|
|
1087
|
+
port = document["port"].GetInt();
|
|
1088
|
+
}
|
|
1089
|
+
|
|
1090
|
+
// type
|
|
1091
|
+
if(document.HasMember("type")) {
|
|
1092
|
+
if(!document["type"].IsString()) {
|
|
1093
|
+
set_error("Parameter type must be a string");
|
|
1094
|
+
goto out;
|
|
1095
|
+
}
|
|
1096
|
+
const char *t = document["type"].GetString();
|
|
1097
|
+
if(stricmp(t, "UDP") == 0) {
|
|
1098
|
+
type = PJSIP_TRANSPORT_UDP;
|
|
1099
|
+
} else if(stricmp(t, "TCP") == 0) {
|
|
1100
|
+
type = PJSIP_TRANSPORT_TCP;
|
|
1101
|
+
} else if(stricmp(t, "TLS") == 0) {
|
|
1102
|
+
type = PJSIP_TRANSPORT_TLS;
|
|
1103
|
+
} else {
|
|
1104
|
+
set_error("Invalid type %s. It must be one of 'UDP' (default), 'TCP' or 'TLS'", type);
|
|
1105
|
+
goto out;
|
|
1106
|
+
}
|
|
1107
|
+
}
|
|
1108
|
+
|
|
944
1109
|
if(type == PJSIP_TRANSPORT_UDP) {
|
|
945
1110
|
pjsip_transport *sip_transport = NULL;
|
|
946
1111
|
|
|
947
1112
|
if(port != 0) {
|
|
948
|
-
sip_transport = allocate_udp_transport(g_sip_endpt, &
|
|
1113
|
+
sip_transport = allocate_udp_transport(g_sip_endpt, &address, port);
|
|
949
1114
|
} else {
|
|
950
|
-
sip_transport = create_udp_transport(g_sip_endpt, &
|
|
1115
|
+
sip_transport = create_udp_transport(g_sip_endpt, &address, &port);
|
|
951
1116
|
}
|
|
952
1117
|
|
|
953
1118
|
if(!sip_transport)
|
|
954
1119
|
{
|
|
955
|
-
PJW_UNLOCK();
|
|
956
1120
|
set_error("Unable to start UDP transport");
|
|
957
|
-
|
|
1121
|
+
goto out;
|
|
958
1122
|
}
|
|
959
1123
|
|
|
960
1124
|
t = new Transport;
|
|
@@ -963,32 +1127,27 @@ int pjw_transport_create(const char *sip_ipaddr, int port, pjsip_transport_type_
|
|
|
963
1127
|
|
|
964
1128
|
if(!g_transport_ids.add((long)t, t_id)){
|
|
965
1129
|
status = pjsip_udp_transport_pause(sip_transport,PJSIP_UDP_TRANSPORT_DESTROY_SOCKET);
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
PJW_UNLOCK();
|
|
1130
|
+
printf("pjsip_dup_transport_pause status=%i\n", status);
|
|
969
1131
|
set_error("Failed to allocate id");
|
|
970
|
-
|
|
1132
|
+
goto out;
|
|
971
1133
|
}
|
|
972
1134
|
|
|
973
|
-
|
|
974
|
-
g_SipTransportMap.insert(make_pair(sip_transport, t_id));
|
|
975
|
-
}
|
|
1135
|
+
g_SipTransportMap.insert(make_pair(sip_transport, t_id));
|
|
976
1136
|
} else if(type == PJSIP_TRANSPORT_TCP) {
|
|
977
1137
|
pjsip_tpfactory *tpfactory;
|
|
978
|
-
int af;
|
|
1138
|
+
//int af;
|
|
979
1139
|
|
|
980
1140
|
|
|
981
1141
|
if(port != 0) {
|
|
982
|
-
tpfactory = allocate_tcp_tpfactory(g_sip_endpt, &
|
|
1142
|
+
tpfactory = allocate_tcp_tpfactory(g_sip_endpt, &address, port);
|
|
983
1143
|
} else {
|
|
984
|
-
tpfactory = create_tcp_tpfactory(g_sip_endpt, &
|
|
1144
|
+
tpfactory = create_tcp_tpfactory(g_sip_endpt, &address, &port);
|
|
985
1145
|
}
|
|
986
1146
|
|
|
987
1147
|
if(!tpfactory)
|
|
988
1148
|
{
|
|
989
|
-
PJW_UNLOCK();
|
|
990
1149
|
set_error("Unable to start TCP transport");
|
|
991
|
-
|
|
1150
|
+
goto out;
|
|
992
1151
|
}
|
|
993
1152
|
|
|
994
1153
|
t = new Transport;
|
|
@@ -998,40 +1157,37 @@ int pjw_transport_create(const char *sip_ipaddr, int port, pjsip_transport_type_
|
|
|
998
1157
|
if(!g_transport_ids.add((long)t, t_id)){
|
|
999
1158
|
status = (tpfactory->destroy)(tpfactory);
|
|
1000
1159
|
|
|
1001
|
-
PJW_UNLOCK();
|
|
1002
1160
|
set_error("Failed to allocate id");
|
|
1003
|
-
|
|
1161
|
+
goto out;
|
|
1004
1162
|
}
|
|
1005
1163
|
|
|
1006
1164
|
g_TcpTransportId = t_id;
|
|
1007
1165
|
} else {
|
|
1008
1166
|
pjsip_tpfactory *tpfactory;
|
|
1009
|
-
int af;
|
|
1167
|
+
//int af;
|
|
1010
1168
|
|
|
1011
1169
|
|
|
1012
1170
|
if(port != 0) {
|
|
1013
|
-
tpfactory = allocate_tls_tpfactory(g_sip_endpt, &
|
|
1171
|
+
tpfactory = allocate_tls_tpfactory(g_sip_endpt, &address, port);
|
|
1014
1172
|
} else {
|
|
1015
|
-
tpfactory = create_tls_tpfactory(g_sip_endpt, &
|
|
1173
|
+
tpfactory = create_tls_tpfactory(g_sip_endpt, &address, &port);
|
|
1016
1174
|
}
|
|
1017
1175
|
|
|
1018
1176
|
if(!tpfactory)
|
|
1019
1177
|
{
|
|
1020
|
-
PJW_UNLOCK();
|
|
1021
1178
|
set_error("Unable to start TLS transport");
|
|
1022
|
-
|
|
1179
|
+
goto out;
|
|
1023
1180
|
}
|
|
1024
1181
|
|
|
1025
1182
|
t = new Transport;
|
|
1026
1183
|
t->type = PJSIP_TRANSPORT_TLS;
|
|
1027
1184
|
t->tpfactory = tpfactory;
|
|
1028
1185
|
|
|
1029
|
-
if(!g_transport_ids.add((long)t, t_id)){
|
|
1186
|
+
if(!g_transport_ids.add((long)t, t_id)) {
|
|
1030
1187
|
status = (tpfactory->destroy)(tpfactory);
|
|
1031
1188
|
|
|
1032
|
-
PJW_UNLOCK();
|
|
1033
1189
|
set_error("Failed to allocate id");
|
|
1034
|
-
|
|
1190
|
+
goto out;
|
|
1035
1191
|
}
|
|
1036
1192
|
|
|
1037
1193
|
g_TlsTransportId = t_id;
|
|
@@ -1039,14 +1195,18 @@ int pjw_transport_create(const char *sip_ipaddr, int port, pjsip_transport_type_
|
|
|
1039
1195
|
|
|
1040
1196
|
t->id = t_id;
|
|
1041
1197
|
|
|
1042
|
-
PJW_UNLOCK();
|
|
1043
|
-
|
|
1044
1198
|
if(g_PacketDumper) {
|
|
1045
|
-
g_PacketDumper->add_endpoint( inet_addr(
|
|
1199
|
+
g_PacketDumper->add_endpoint( inet_addr(addr), htons(port) );
|
|
1046
1200
|
}
|
|
1047
|
-
|
|
1201
|
+
|
|
1048
1202
|
*out_t_id = t_id;
|
|
1203
|
+
strcpy(out_t_address, addr);
|
|
1049
1204
|
*out_port = port;
|
|
1205
|
+
out:
|
|
1206
|
+
PJW_UNLOCK();
|
|
1207
|
+
if(pjw_errorstring[0]){
|
|
1208
|
+
return -1;
|
|
1209
|
+
}
|
|
1050
1210
|
return 0;
|
|
1051
1211
|
}
|
|
1052
1212
|
|
|
@@ -1056,71 +1216,122 @@ int pjw_transport_get_info(int t_id, char *out_sip_ipaddr, int *out_port)
|
|
|
1056
1216
|
clear_error();
|
|
1057
1217
|
|
|
1058
1218
|
long val;
|
|
1219
|
+
Transport *t;
|
|
1220
|
+
|
|
1221
|
+
int port;
|
|
1222
|
+
int len;
|
|
1059
1223
|
|
|
1060
1224
|
if(!g_transport_ids.get(t_id, val)){
|
|
1061
|
-
PJW_UNLOCK();
|
|
1062
1225
|
set_error("Invalid transport_id");
|
|
1063
|
-
|
|
1226
|
+
goto out;
|
|
1064
1227
|
}
|
|
1228
|
+
t = (Transport*)val;
|
|
1065
1229
|
|
|
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];
|
|
1230
|
+
port = t->sip_transport->local_name.port;
|
|
1231
|
+
len = t->sip_transport->local_name.host.slen;
|
|
1071
1232
|
strncpy(out_sip_ipaddr, t->sip_transport->local_name.host.ptr, len);
|
|
1072
1233
|
out_sip_ipaddr[len] = 0;
|
|
1073
1234
|
*out_port = port;
|
|
1074
1235
|
|
|
1236
|
+
out:
|
|
1075
1237
|
PJW_UNLOCK();
|
|
1238
|
+
if(pjw_errorstring[0]){
|
|
1239
|
+
return -1;
|
|
1240
|
+
}
|
|
1076
1241
|
return 0;
|
|
1077
1242
|
}
|
|
1078
1243
|
|
|
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)
|
|
1244
|
+
//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)
|
|
1245
|
+
int pjw_account_create(int t_id, const char *json, int *out_acc_id)
|
|
1080
1246
|
{
|
|
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
1247
|
PJW_LOCK();
|
|
1083
1248
|
clear_error();
|
|
1084
1249
|
|
|
1085
1250
|
long val;
|
|
1086
1251
|
|
|
1252
|
+
pj_status_t status;
|
|
1253
|
+
pjsip_regc *regc;
|
|
1254
|
+
|
|
1255
|
+
char *domain;
|
|
1256
|
+
char *server;
|
|
1257
|
+
char *username;
|
|
1258
|
+
char *password;
|
|
1259
|
+
char *c_to_uri = NULL;
|
|
1260
|
+
int expires = 60;
|
|
1261
|
+
|
|
1262
|
+
pj_str_t server_uri;
|
|
1263
|
+
pj_str_t from_uri;
|
|
1264
|
+
pj_str_t to_uri;
|
|
1265
|
+
pj_str_t contact;
|
|
1266
|
+
|
|
1267
|
+
long acc_id;
|
|
1268
|
+
|
|
1269
|
+
Transport *t;
|
|
1270
|
+
|
|
1271
|
+
int local_port;
|
|
1272
|
+
int len;
|
|
1273
|
+
char local_addr[100];
|
|
1274
|
+
|
|
1275
|
+
char temp[400];
|
|
1276
|
+
char *p;
|
|
1277
|
+
|
|
1278
|
+
pjsip_cred_info cred;
|
|
1279
|
+
pjsip_tpselector sel;
|
|
1280
|
+
|
|
1281
|
+
char buffer[MAX_JSON_INPUT];
|
|
1282
|
+
|
|
1283
|
+
Document document;
|
|
1284
|
+
|
|
1087
1285
|
if(!g_transport_ids.get(t_id, val)){
|
|
1088
|
-
PJW_UNLOCK();
|
|
1089
1286
|
set_error("Invalid transport id");
|
|
1090
|
-
|
|
1287
|
+
goto out;
|
|
1091
1288
|
}
|
|
1289
|
+
t = (Transport*)val;
|
|
1290
|
+
|
|
1291
|
+
if(!parse_json(document, json, buffer, MAX_JSON_INPUT)) {
|
|
1292
|
+
goto out;
|
|
1293
|
+
}
|
|
1092
1294
|
|
|
1093
|
-
|
|
1295
|
+
if(!json_get_string_param(document, "domain", false, &domain)) {
|
|
1296
|
+
goto out;
|
|
1297
|
+
}
|
|
1094
1298
|
|
|
1095
|
-
|
|
1096
|
-
|
|
1299
|
+
if(!json_get_string_param(document, "server", false, &server)) {
|
|
1300
|
+
goto out;
|
|
1301
|
+
}
|
|
1302
|
+
|
|
1303
|
+
if(!json_get_string_param(document, "username", false, &username)) {
|
|
1304
|
+
goto out;
|
|
1305
|
+
}
|
|
1306
|
+
|
|
1307
|
+
if(!json_get_string_param(document, "password", false, &password)) {
|
|
1308
|
+
goto out;
|
|
1309
|
+
}
|
|
1310
|
+
|
|
1311
|
+
if(!json_get_string_param(document, "to_uri", true, &c_to_uri)) {
|
|
1312
|
+
goto out;
|
|
1313
|
+
}
|
|
1314
|
+
|
|
1315
|
+
if(!json_get_int_param(document, "expires", true, &expires)) {
|
|
1316
|
+
goto out;
|
|
1317
|
+
}
|
|
1097
1318
|
|
|
1098
1319
|
status = pjsip_regc_create(g_sip_endpt, NULL, on_registration_status, ®c);
|
|
1099
1320
|
if(status != PJ_SUCCESS)
|
|
1100
1321
|
{
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
return -1;
|
|
1322
|
+
set_error("pjsip_regc_create failed with status=%i", status);
|
|
1323
|
+
goto out;
|
|
1104
1324
|
}
|
|
1105
1325
|
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
PJW_UNLOCK();
|
|
1109
|
-
set_error("add_additional_headers_for_account failed");
|
|
1110
|
-
return -1;
|
|
1111
|
-
}
|
|
1326
|
+
if(!add_headers_for_account(regc, document)) {
|
|
1327
|
+
goto out;
|
|
1112
1328
|
}
|
|
1113
1329
|
|
|
1114
|
-
long acc_id;
|
|
1115
1330
|
if(!g_account_ids.add((long)regc, acc_id)){
|
|
1116
|
-
PJW_UNLOCK();
|
|
1117
1331
|
set_error("Failed to allocate id");
|
|
1118
|
-
|
|
1332
|
+
goto out;
|
|
1119
1333
|
}
|
|
1120
1334
|
|
|
1121
|
-
int local_port;
|
|
1122
|
-
int len;
|
|
1123
|
-
char local_addr[100];
|
|
1124
1335
|
if(t->type == PJSIP_TRANSPORT_UDP) {
|
|
1125
1336
|
local_port = t->sip_transport->local_name.port;
|
|
1126
1337
|
len= t->sip_transport->local_name.host.slen;
|
|
@@ -1132,50 +1343,47 @@ int pjw_account_create(int t_id, const char *domain, const char *server, const c
|
|
|
1132
1343
|
}
|
|
1133
1344
|
local_addr[len] = 0;
|
|
1134
1345
|
|
|
1135
|
-
|
|
1136
|
-
char *p = temp;
|
|
1346
|
+
p = temp;
|
|
1137
1347
|
|
|
1138
1348
|
len = sprintf(p, "sip:%s", server);
|
|
1139
|
-
|
|
1349
|
+
printf("server_uri=%s\n", p);
|
|
1350
|
+
server_uri = pj_str(p);
|
|
1140
1351
|
p += len + 2;
|
|
1141
1352
|
|
|
1142
1353
|
len = sprintf(p, "<sip:%s@%s>", username, domain);
|
|
1143
|
-
|
|
1354
|
+
printf("from_uri=%s\n", p);
|
|
1355
|
+
from_uri = pj_str(p);
|
|
1144
1356
|
p += len + 2;
|
|
1145
1357
|
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
if(c_to_url && c_to_url[0]) {
|
|
1149
|
-
to_url = pj_str((char*)c_to_url);
|
|
1150
|
-
}
|
|
1358
|
+
to_uri = from_uri;
|
|
1151
1359
|
|
|
1152
|
-
if(
|
|
1153
|
-
|
|
1360
|
+
if(c_to_uri && c_to_uri[0]) {
|
|
1361
|
+
printf("c_to_uri=%s\n", c_to_uri);
|
|
1362
|
+
to_uri = pj_str((char*)c_to_uri);
|
|
1154
1363
|
}
|
|
1155
1364
|
|
|
1156
1365
|
len = sprintf(p, "sip:%s@%s:%u", username, local_addr, local_port);
|
|
1157
|
-
|
|
1366
|
+
printf("contact=%s\n", p);
|
|
1367
|
+
contact = pj_str(p);
|
|
1158
1368
|
p += len + 2;
|
|
1159
1369
|
|
|
1160
1370
|
status = pjsip_regc_init(regc,
|
|
1161
|
-
&
|
|
1162
|
-
&
|
|
1163
|
-
&
|
|
1371
|
+
&server_uri,
|
|
1372
|
+
&from_uri,
|
|
1373
|
+
&to_uri,
|
|
1164
1374
|
1, &contact,
|
|
1165
1375
|
expires);
|
|
1166
1376
|
if(status != PJ_SUCCESS)
|
|
1167
1377
|
{
|
|
1168
1378
|
status = pjsip_regc_destroy(regc);
|
|
1169
1379
|
//ToDo: log status
|
|
1170
|
-
PJW_UNLOCK();
|
|
1171
1380
|
set_error("pjsip_regc_init failed");
|
|
1172
|
-
|
|
1381
|
+
goto out;
|
|
1173
1382
|
}
|
|
1174
1383
|
|
|
1175
|
-
pjsip_cred_info cred;
|
|
1176
1384
|
pj_bzero(&cred, sizeof(cred));
|
|
1177
|
-
cred.realm = pj_str("*");
|
|
1178
|
-
cred.scheme = pj_str("digest");
|
|
1385
|
+
cred.realm = pj_str((char*)"*");
|
|
1386
|
+
cred.scheme = pj_str((char*)"digest");
|
|
1179
1387
|
cred.username = pj_str((char*)username);
|
|
1180
1388
|
cred.data_type = PJSIP_CRED_DATA_PLAIN_PASSWD;
|
|
1181
1389
|
cred.data = pj_str((char*)password);
|
|
@@ -1184,12 +1392,10 @@ int pjw_account_create(int t_id, const char *domain, const char *server, const c
|
|
|
1184
1392
|
{
|
|
1185
1393
|
status = pjsip_regc_destroy(regc);
|
|
1186
1394
|
//ToDo: log status
|
|
1187
|
-
PJW_UNLOCK();
|
|
1188
1395
|
set_error("pjsip_regc_set_credentials failed");
|
|
1189
|
-
|
|
1396
|
+
goto out;
|
|
1190
1397
|
}
|
|
1191
1398
|
|
|
1192
|
-
pjsip_tpselector sel;
|
|
1193
1399
|
pj_bzero(&sel, sizeof(sel));
|
|
1194
1400
|
if(t->type == PJSIP_TRANSPORT_UDP) {
|
|
1195
1401
|
sel.type = PJSIP_TPSELECTOR_TRANSPORT;
|
|
@@ -1204,50 +1410,72 @@ int pjw_account_create(int t_id, const char *domain, const char *server, const c
|
|
|
1204
1410
|
{
|
|
1205
1411
|
status = pjsip_regc_destroy(regc);
|
|
1206
1412
|
//ToDo: log status
|
|
1207
|
-
PJW_UNLOCK();
|
|
1208
1413
|
set_error("pjsip_regc_set_transport failed");
|
|
1209
|
-
|
|
1414
|
+
goto out;
|
|
1210
1415
|
}
|
|
1416
|
+
|
|
1417
|
+
out:
|
|
1211
1418
|
PJW_UNLOCK();
|
|
1419
|
+
if(pjw_errorstring[0]){
|
|
1420
|
+
return -1;
|
|
1421
|
+
}
|
|
1422
|
+
|
|
1212
1423
|
*out_acc_id = acc_id;
|
|
1213
1424
|
return 0;
|
|
1214
1425
|
}
|
|
1215
1426
|
|
|
1216
|
-
int pjw_account_register(long acc_id, pj_bool_t autoreg)
|
|
1427
|
+
//int pjw_account_register(long acc_id, pj_bool_t autoreg)
|
|
1428
|
+
int pjw_account_register(long acc_id, const char *json)
|
|
1217
1429
|
{
|
|
1218
1430
|
PJW_LOCK();
|
|
1219
1431
|
clear_error();
|
|
1220
1432
|
|
|
1221
1433
|
long val;
|
|
1434
|
+
pjsip_regc *regc;
|
|
1435
|
+
|
|
1436
|
+
pj_status_t status;
|
|
1437
|
+
pjsip_tx_data *tdata;
|
|
1438
|
+
|
|
1439
|
+
char buffer[MAX_JSON_INPUT];
|
|
1440
|
+
|
|
1441
|
+
bool auto_register = false;
|
|
1442
|
+
|
|
1443
|
+
Document document;
|
|
1222
1444
|
|
|
1223
1445
|
if(!g_account_ids.get(acc_id, val)){
|
|
1224
|
-
PJW_UNLOCK();
|
|
1225
1446
|
set_error("Invalid account_id");
|
|
1226
|
-
|
|
1447
|
+
goto out;
|
|
1227
1448
|
}
|
|
1449
|
+
regc = (pjsip_regc*)val;
|
|
1228
1450
|
|
|
1229
|
-
|
|
1451
|
+
if(!parse_json(document, json, buffer, MAX_JSON_INPUT)) {
|
|
1452
|
+
goto out;
|
|
1453
|
+
}
|
|
1230
1454
|
|
|
1231
|
-
|
|
1232
|
-
|
|
1455
|
+
if(!json_get_bool_param(document, "auto_register", true, &auto_register)) {
|
|
1456
|
+
goto out;
|
|
1457
|
+
}
|
|
1233
1458
|
|
|
1234
|
-
status = pjsip_regc_register(regc,
|
|
1459
|
+
status = pjsip_regc_register(regc, auto_register, &tdata);
|
|
1235
1460
|
if(status != PJ_SUCCESS)
|
|
1236
1461
|
{
|
|
1237
|
-
PJW_UNLOCK();
|
|
1238
1462
|
set_error("pjsip_regc_register failed");
|
|
1239
|
-
|
|
1463
|
+
goto out;
|
|
1240
1464
|
}
|
|
1241
1465
|
|
|
1242
1466
|
status = pjsip_regc_send(regc, tdata);
|
|
1243
1467
|
if(status != PJ_SUCCESS)
|
|
1244
1468
|
{
|
|
1245
|
-
PJW_UNLOCK();
|
|
1246
1469
|
set_error("pjsip_regc_send failed");
|
|
1247
|
-
|
|
1470
|
+
goto out;
|
|
1248
1471
|
}
|
|
1249
1472
|
|
|
1473
|
+
out:
|
|
1250
1474
|
PJW_UNLOCK();
|
|
1475
|
+
if(pjw_errorstring[0]){
|
|
1476
|
+
return -1;
|
|
1477
|
+
}
|
|
1478
|
+
|
|
1251
1479
|
return 0;
|
|
1252
1480
|
}
|
|
1253
1481
|
|
|
@@ -1258,63 +1486,88 @@ int pjw_account_unregister(long acc_id)
|
|
|
1258
1486
|
|
|
1259
1487
|
long val;
|
|
1260
1488
|
|
|
1261
|
-
|
|
1262
|
-
PJW_UNLOCK();
|
|
1263
|
-
set_error("Invalid account_id");
|
|
1264
|
-
return -1;
|
|
1265
|
-
}
|
|
1266
|
-
|
|
1267
|
-
pjsip_regc *regc = (pjsip_regc*)val;
|
|
1489
|
+
pjsip_regc *regc;
|
|
1268
1490
|
|
|
1269
1491
|
pj_status_t status;
|
|
1270
1492
|
pjsip_tx_data *tdata;
|
|
1271
1493
|
|
|
1494
|
+
if(!g_account_ids.get(acc_id, val)){
|
|
1495
|
+
set_error("Invalid account_id");
|
|
1496
|
+
goto out;
|
|
1497
|
+
}
|
|
1498
|
+
regc = (pjsip_regc*)val;
|
|
1499
|
+
|
|
1272
1500
|
status = pjsip_regc_unregister(regc, &tdata);
|
|
1273
1501
|
if(status != PJ_SUCCESS)
|
|
1274
1502
|
{
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
return -1;
|
|
1503
|
+
set_error("pjsip_regc_unregister failed with status=%i", status);
|
|
1504
|
+
goto out;
|
|
1278
1505
|
}
|
|
1279
1506
|
|
|
1280
1507
|
status = pjsip_regc_send(regc, tdata);
|
|
1281
1508
|
if(status != PJ_SUCCESS)
|
|
1282
1509
|
{
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
return -1;
|
|
1510
|
+
set_error("pjsip_regc_send failed with status=%i", status);
|
|
1511
|
+
goto out;
|
|
1286
1512
|
}
|
|
1287
1513
|
|
|
1514
|
+
out:
|
|
1288
1515
|
PJW_UNLOCK();
|
|
1516
|
+
if(pjw_errorstring[0]){
|
|
1517
|
+
return -1;
|
|
1518
|
+
}
|
|
1519
|
+
|
|
1289
1520
|
return 0;
|
|
1290
1521
|
}
|
|
1291
1522
|
|
|
1292
|
-
int pjw_call_respond(long call_id, int code, const char *reason, const char *additional_headers)
|
|
1523
|
+
//int pjw_call_respond(long call_id, int code, const char *reason, const char *additional_headers)
|
|
1524
|
+
int pjw_call_respond(long call_id, const char *json)
|
|
1293
1525
|
{
|
|
1294
|
-
printf("pjw_call_respond: call_id=%
|
|
1526
|
+
printf("pjw_call_respond: call_id=%lu json=%s\n", call_id, json);
|
|
1295
1527
|
PJW_LOCK();
|
|
1528
|
+
clear_error();
|
|
1296
1529
|
|
|
1297
1530
|
long val;
|
|
1298
1531
|
|
|
1532
|
+
int code;
|
|
1533
|
+
char *reason;
|
|
1534
|
+
|
|
1535
|
+
pj_str_t r;// pj_str((char*)reason);
|
|
1536
|
+
|
|
1537
|
+
pj_status_t status;
|
|
1538
|
+
|
|
1539
|
+
pjsip_tx_data *tdata;
|
|
1540
|
+
|
|
1541
|
+
Call *call;
|
|
1542
|
+
|
|
1543
|
+
char buffer[MAX_JSON_INPUT];
|
|
1544
|
+
|
|
1545
|
+
Document document;
|
|
1546
|
+
|
|
1299
1547
|
if(!g_call_ids.get(call_id, val)){
|
|
1300
|
-
PJW_UNLOCK();
|
|
1301
1548
|
set_error("Invalid call_id");
|
|
1302
|
-
|
|
1549
|
+
goto out;
|
|
1303
1550
|
}
|
|
1304
|
-
|
|
1305
|
-
Call *call = (Call*)val;
|
|
1551
|
+
call = (Call*)val;
|
|
1306
1552
|
|
|
1307
1553
|
if(call->outgoing) {
|
|
1308
|
-
PJW_UNLOCK();
|
|
1309
1554
|
set_error("You cannot respond an outgoing call");
|
|
1310
|
-
|
|
1555
|
+
goto out;
|
|
1311
1556
|
}
|
|
1312
1557
|
|
|
1313
|
-
|
|
1558
|
+
if(!parse_json(document, json, buffer, MAX_JSON_INPUT)) {
|
|
1559
|
+
goto out;
|
|
1560
|
+
}
|
|
1561
|
+
|
|
1562
|
+
if(!json_get_int_param(document, "code", true, &code)) {
|
|
1563
|
+
goto out;
|
|
1564
|
+
}
|
|
1314
1565
|
|
|
1315
|
-
|
|
1566
|
+
if(!json_get_string_param(document, "reason", true, &reason)) {
|
|
1567
|
+
goto out;
|
|
1568
|
+
}
|
|
1316
1569
|
|
|
1317
|
-
|
|
1570
|
+
r = pj_str((char*)reason);
|
|
1318
1571
|
|
|
1319
1572
|
if(call->initial_invite_rdata) {
|
|
1320
1573
|
status = pjsip_inv_initial_answer(call->inv, call->initial_invite_rdata,
|
|
@@ -1323,16 +1576,14 @@ int pjw_call_respond(long call_id, int code, const char *reason, const char *add
|
|
|
1323
1576
|
NULL,
|
|
1324
1577
|
&tdata);
|
|
1325
1578
|
if(status != PJ_SUCCESS) {
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
return -1;
|
|
1579
|
+
set_error("pjsip_inv_initial_answer failed with status=%i", status);
|
|
1580
|
+
goto out;
|
|
1329
1581
|
}
|
|
1330
1582
|
|
|
1331
1583
|
status = pjsip_rx_data_free_cloned(call->initial_invite_rdata);
|
|
1332
1584
|
if(status != PJ_SUCCESS) {
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
return -1;
|
|
1585
|
+
set_error("pjsip_rx_data_free_cloned failed with status=%i", status);
|
|
1586
|
+
goto out;
|
|
1336
1587
|
}
|
|
1337
1588
|
call->initial_invite_rdata = 0;
|
|
1338
1589
|
} else {
|
|
@@ -1343,150 +1594,210 @@ int pjw_call_respond(long call_id, int code, const char *reason, const char *add
|
|
|
1343
1594
|
&tdata);
|
|
1344
1595
|
|
|
1345
1596
|
if(status != PJ_SUCCESS){
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
return -1;
|
|
1597
|
+
set_error("pjsip_inv_answer failed with status=%i", status);
|
|
1598
|
+
goto out;
|
|
1349
1599
|
}
|
|
1350
1600
|
|
|
1351
|
-
if(!
|
|
1601
|
+
if(!add_headers(call->inv->dlg->pool, tdata, document)) {
|
|
1352
1602
|
goto out;
|
|
1353
1603
|
}
|
|
1354
1604
|
}
|
|
1355
1605
|
|
|
1356
1606
|
status = pjsip_inv_send_msg(call->inv, tdata);
|
|
1357
1607
|
if(status != PJ_SUCCESS){
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
return -1;
|
|
1608
|
+
set_error("pjsip_inv_send_msg failed with status=%i", status);
|
|
1609
|
+
goto out;
|
|
1361
1610
|
}
|
|
1362
1611
|
|
|
1363
1612
|
out:
|
|
1364
1613
|
PJW_UNLOCK();
|
|
1365
|
-
|
|
1366
1614
|
if(pjw_errorstring[0]) {
|
|
1367
1615
|
return -1;
|
|
1368
1616
|
}
|
|
1369
|
-
|
|
1370
1617
|
return 0;
|
|
1371
1618
|
}
|
|
1372
1619
|
|
|
1373
|
-
int pjw_call_terminate(long call_id, int code, const char *reason, const char *additional_headers)
|
|
1620
|
+
//int pjw_call_terminate(long call_id, int code, const char *reason, const char *additional_headers)
|
|
1621
|
+
int pjw_call_terminate(long call_id, const char *json)
|
|
1374
1622
|
{
|
|
1375
1623
|
PJW_LOCK();
|
|
1624
|
+
clear_error();
|
|
1376
1625
|
|
|
1377
1626
|
long val;
|
|
1627
|
+
pjsip_tx_data *tdata;
|
|
1628
|
+
pj_status_t status;
|
|
1629
|
+
int code = 0;
|
|
1630
|
+
char *reason = (char*)"";
|
|
1631
|
+
pj_str_t r;// = pj_str((char*)reason);
|
|
1632
|
+
|
|
1633
|
+
Call *call;
|
|
1634
|
+
|
|
1635
|
+
char buffer[MAX_JSON_INPUT];
|
|
1636
|
+
|
|
1637
|
+
Document document;
|
|
1378
1638
|
|
|
1379
1639
|
if(!g_call_ids.get(call_id, val)){
|
|
1380
|
-
PJW_UNLOCK();
|
|
1381
1640
|
set_error("Invalid call_id");
|
|
1382
|
-
|
|
1641
|
+
goto out;
|
|
1383
1642
|
}
|
|
1643
|
+
call = (Call*)val;
|
|
1384
1644
|
|
|
1385
|
-
|
|
1645
|
+
if(!parse_json(document, json, buffer, MAX_JSON_INPUT)) {
|
|
1646
|
+
goto out;
|
|
1647
|
+
}
|
|
1386
1648
|
|
|
1387
|
-
|
|
1649
|
+
if(!json_get_int_param(document, "code", true, &code)) {
|
|
1650
|
+
goto out;
|
|
1651
|
+
}
|
|
1652
|
+
|
|
1653
|
+
if(!json_get_string_param(document, "reason", true, &reason)) {
|
|
1654
|
+
goto out;
|
|
1655
|
+
}
|
|
1656
|
+
|
|
1657
|
+
r = pj_str((char*)reason);
|
|
1388
1658
|
|
|
1389
|
-
pjsip_tx_data *tdata;
|
|
1390
|
-
pj_status_t status;
|
|
1391
1659
|
status = pjsip_inv_end_session(call->inv,
|
|
1392
1660
|
code,
|
|
1393
1661
|
&r,
|
|
1394
1662
|
&tdata);
|
|
1395
1663
|
if(status != PJ_SUCCESS){
|
|
1396
|
-
PJW_UNLOCK();
|
|
1397
1664
|
set_error("pjsip_inv_end_session failed");
|
|
1398
|
-
|
|
1665
|
+
goto out;
|
|
1399
1666
|
}
|
|
1400
1667
|
|
|
1401
1668
|
if(!tdata)
|
|
1402
1669
|
{
|
|
1403
1670
|
//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;
|
|
1671
|
+
goto out;
|
|
1406
1672
|
}
|
|
1407
1673
|
|
|
1408
|
-
if(!
|
|
1409
|
-
|
|
1410
|
-
set_error("add_additional_headers failed");
|
|
1411
|
-
return -1;
|
|
1674
|
+
if(!add_headers(call->inv->dlg->pool, tdata, document)) {
|
|
1675
|
+
goto out;
|
|
1412
1676
|
}
|
|
1413
1677
|
|
|
1414
1678
|
status = pjsip_inv_send_msg(call->inv, tdata);
|
|
1415
1679
|
if(status != PJ_SUCCESS){
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
return -1;
|
|
1680
|
+
set_error("pjsip_inv_send_msg failed with status=%i", status);
|
|
1681
|
+
goto out;
|
|
1419
1682
|
}
|
|
1420
1683
|
|
|
1684
|
+
out:
|
|
1421
1685
|
PJW_UNLOCK();
|
|
1686
|
+
if(pjw_errorstring[0]){
|
|
1687
|
+
return -1;
|
|
1688
|
+
}
|
|
1689
|
+
|
|
1422
1690
|
return 0;
|
|
1423
1691
|
}
|
|
1424
1692
|
|
|
1425
1693
|
|
|
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)
|
|
1694
|
+
//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)
|
|
1695
|
+
int pjw_call_create(long t_id, const char *json, long *out_call_id, char *out_sip_call_id)
|
|
1427
1696
|
{
|
|
1428
1697
|
PJW_LOCK();
|
|
1429
1698
|
clear_error();
|
|
1430
1699
|
|
|
1431
|
-
int n;
|
|
1700
|
+
//int n;
|
|
1432
1701
|
long val;
|
|
1433
1702
|
Transport *t;
|
|
1434
|
-
char *start;
|
|
1435
|
-
char *end;
|
|
1703
|
+
//char *start;
|
|
1704
|
+
//char *end;
|
|
1436
1705
|
char local_contact[400];
|
|
1437
|
-
char *p;
|
|
1438
|
-
int len;
|
|
1706
|
+
//char *p;
|
|
1707
|
+
//int len;
|
|
1439
1708
|
const char *contact_username = "sip";
|
|
1440
1709
|
int call_id;
|
|
1441
1710
|
|
|
1711
|
+
char *from_uri = NULL;
|
|
1712
|
+
char *to_uri = NULL;
|
|
1713
|
+
char *request_uri = NULL;
|
|
1714
|
+
char *proxy_uri = NULL;
|
|
1715
|
+
|
|
1716
|
+
char *realm = NULL;
|
|
1717
|
+
char *username = NULL;
|
|
1718
|
+
char *password = NULL;
|
|
1719
|
+
|
|
1720
|
+
unsigned flags = 0;
|
|
1442
1721
|
|
|
1443
1722
|
pjsip_dialog *dlg;
|
|
1444
1723
|
|
|
1724
|
+
char buffer[MAX_JSON_INPUT];
|
|
1725
|
+
|
|
1726
|
+
Document document;
|
|
1727
|
+
|
|
1445
1728
|
if(!g_transport_ids.get(t_id, val)){
|
|
1446
1729
|
set_error("Invalid transport_id");
|
|
1447
1730
|
goto out;
|
|
1448
1731
|
}
|
|
1449
1732
|
t = (Transport*)val;
|
|
1450
1733
|
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
}
|
|
1734
|
+
if(!parse_json(document, json, buffer, MAX_JSON_INPUT)) {
|
|
1735
|
+
goto out;
|
|
1736
|
+
}
|
|
1455
1737
|
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1738
|
+
if(!json_get_and_check_uri(document, "from_uri", false, &from_uri)) {
|
|
1739
|
+
goto out;
|
|
1740
|
+
}
|
|
1741
|
+
|
|
1742
|
+
if(!json_get_and_check_uri(document, "to_uri", false, &to_uri)) {
|
|
1743
|
+
goto out;
|
|
1744
|
+
}
|
|
1460
1745
|
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1746
|
+
request_uri = to_uri;
|
|
1747
|
+
if(!json_get_and_check_uri(document, "request_uri", true, &request_uri)) {
|
|
1748
|
+
goto out;
|
|
1749
|
+
}
|
|
1750
|
+
|
|
1751
|
+
if(!json_get_and_check_uri(document, "proxy_uri", true, &proxy_uri)) {
|
|
1752
|
+
goto out;
|
|
1753
|
+
}
|
|
1754
|
+
|
|
1755
|
+
if(document.HasMember("auth")) {
|
|
1756
|
+
if(!document["auth"].IsObject()) {
|
|
1757
|
+
set_error("Parameter auth must be an object");
|
|
1758
|
+
goto out;
|
|
1759
|
+
} else {
|
|
1760
|
+
const Value& auth = document["auth"];
|
|
1761
|
+
|
|
1762
|
+
for (Value::ConstMemberIterator itr = auth.MemberBegin(); itr != auth.MemberEnd(); ++itr) {
|
|
1763
|
+
const char *name = itr->name.GetString();
|
|
1764
|
+
if(strcmp(name, "realm") == 0) {
|
|
1765
|
+
if(!itr->value.IsString()) {
|
|
1766
|
+
set_error("%s must be a string", itr->name.GetString());
|
|
1767
|
+
goto out;
|
|
1768
|
+
}
|
|
1769
|
+
realm = (char*)itr->value.GetString();
|
|
1770
|
+
} else if(strcmp(name, "username") == 0) {
|
|
1771
|
+
if(!itr->value.IsString()) {
|
|
1772
|
+
set_error("%s must be a string", itr->name.GetString());
|
|
1773
|
+
goto out;
|
|
1774
|
+
}
|
|
1775
|
+
username = (char*)itr->value.GetString();
|
|
1776
|
+
contact_username = username;
|
|
1777
|
+
} else if(strcmp(name, "password") == 0) {
|
|
1778
|
+
if(!itr->value.IsString()) {
|
|
1779
|
+
set_error("%s must be a string", itr->name.GetString());
|
|
1780
|
+
goto out;
|
|
1781
|
+
}
|
|
1782
|
+
password = (char*)itr->value.GetString();
|
|
1467
1783
|
} else {
|
|
1468
|
-
|
|
1784
|
+
set_error("Unknown auth paramter %s", itr->name.GetString());
|
|
1785
|
+
goto out;
|
|
1469
1786
|
}
|
|
1470
|
-
|
|
1471
|
-
request_uri = to_uri;
|
|
1787
|
+
}
|
|
1472
1788
|
}
|
|
1789
|
+
}
|
|
1473
1790
|
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1791
|
+
if(document.HasMember("delayed_media")) {
|
|
1792
|
+
if(!document["delayed_media"].IsBool()) {
|
|
1793
|
+
set_error("Parameter delayed_media must be a boolean");
|
|
1794
|
+
goto out;
|
|
1795
|
+
} else {
|
|
1796
|
+
if(document["delayed_media"].GetBool()) {
|
|
1797
|
+
flags = flags | CALL_FLAG_DELAYED_MEDIA;
|
|
1798
|
+
}
|
|
1481
1799
|
}
|
|
1482
|
-
|
|
1483
|
-
if(realm){
|
|
1484
|
-
if(!username || !password) {
|
|
1485
|
-
set_error("Incomplete credentials");
|
|
1486
|
-
goto out;
|
|
1487
|
-
}
|
|
1488
|
-
contact_username = username;
|
|
1489
|
-
}
|
|
1800
|
+
}
|
|
1490
1801
|
|
|
1491
1802
|
if(t->type == PJSIP_TRANSPORT_UDP) {
|
|
1492
1803
|
build_local_contact(local_contact, t->sip_transport, contact_username);
|
|
@@ -1498,7 +1809,7 @@ int pjw_call_create(long t_id, unsigned flags, const char *from_uri, const char
|
|
|
1498
1809
|
goto out;
|
|
1499
1810
|
}
|
|
1500
1811
|
|
|
1501
|
-
call_id = call_create(t, flags, dlg, proxy_uri,
|
|
1812
|
+
call_id = call_create(t, flags, dlg, proxy_uri, document);
|
|
1502
1813
|
if(call_id < 0) {
|
|
1503
1814
|
goto out;
|
|
1504
1815
|
}
|
|
@@ -1620,6 +1931,7 @@ bool set_proxy(pjsip_dialog *dlg, const char *proxy_uri) {
|
|
|
1620
1931
|
NULL);
|
|
1621
1932
|
if(!route){
|
|
1622
1933
|
status = pjsip_dlg_terminate(dlg); //ToDo:
|
|
1934
|
+
printf("pjsip_dlg_terminate status=%i\n", status);
|
|
1623
1935
|
set_error("pjsip_parse_hdr failed");
|
|
1624
1936
|
return false;
|
|
1625
1937
|
}
|
|
@@ -1658,7 +1970,7 @@ bool dlg_create(pjsip_dialog **dlg, Transport *transport, const char *from_uri,
|
|
|
1658
1970
|
|
|
1659
1971
|
if(realm && realm[0]){
|
|
1660
1972
|
pjsip_cred_info cred[1];
|
|
1661
|
-
cred[0].scheme = pj_str("digest");
|
|
1973
|
+
cred[0].scheme = pj_str((char*)"digest");
|
|
1662
1974
|
cred[0].realm = pj_str((char*)realm);
|
|
1663
1975
|
cred[0].username = pj_str((char*)username);
|
|
1664
1976
|
cred[0].data_type = PJSIP_CRED_DATA_PLAIN_PASSWD;
|
|
@@ -1671,11 +1983,12 @@ bool dlg_create(pjsip_dialog **dlg, Transport *transport, const char *from_uri,
|
|
|
1671
1983
|
}
|
|
1672
1984
|
}
|
|
1673
1985
|
|
|
1674
|
-
|
|
1986
|
+
*dlg = p_dlg;
|
|
1987
|
+
return true;
|
|
1675
1988
|
}
|
|
1676
1989
|
|
|
1677
1990
|
|
|
1678
|
-
int call_create(Transport *t, unsigned flags, pjsip_dialog *dlg, const char *proxy_uri,
|
|
1991
|
+
int call_create(Transport *t, unsigned flags, pjsip_dialog *dlg, const char *proxy_uri, Document &document)
|
|
1679
1992
|
{
|
|
1680
1993
|
pjsip_inv_session *inv;
|
|
1681
1994
|
//in_addr addr;
|
|
@@ -1706,7 +2019,7 @@ int call_create(Transport *t, unsigned flags, pjsip_dialog *dlg, const char *pro
|
|
|
1706
2019
|
|
|
1707
2020
|
pjmedia_sdp_session *sdp = 0;
|
|
1708
2021
|
|
|
1709
|
-
if(!(flags &
|
|
2022
|
+
if(!(flags & CALL_FLAG_DELAYED_MEDIA)) {
|
|
1710
2023
|
status = pjmedia_endpt_create_sdp( g_med_endpt,
|
|
1711
2024
|
dlg->pool,
|
|
1712
2025
|
1,
|
|
@@ -1760,7 +2073,7 @@ int call_create(Transport *t, unsigned flags, pjsip_dialog *dlg, const char *pro
|
|
|
1760
2073
|
|
|
1761
2074
|
|
|
1762
2075
|
|
|
1763
|
-
if(!
|
|
2076
|
+
if(!add_headers(dlg->pool, tdata, document)) {
|
|
1764
2077
|
g_call_ids.remove(call_id, (long &)call);
|
|
1765
2078
|
close_media_transport(med_transport); //Todo:
|
|
1766
2079
|
status = pjsip_dlg_terminate(dlg); //ToDo:
|
|
@@ -1800,7 +2113,8 @@ int call_create(Transport *t, unsigned flags, pjsip_dialog *dlg, const char *pro
|
|
|
1800
2113
|
return call_id;
|
|
1801
2114
|
}
|
|
1802
2115
|
|
|
1803
|
-
int pjw_call_send_dtmf(long call_id, const char *digits, int mode)
|
|
2116
|
+
//int pjw_call_send_dtmf(long call_id, const char *digits, int mode)
|
|
2117
|
+
int pjw_call_send_dtmf(long call_id, const char *json)
|
|
1804
2118
|
{
|
|
1805
2119
|
#define ON_DURATION 200
|
|
1806
2120
|
#define OFF_DURATION 50
|
|
@@ -1808,38 +2122,61 @@ int pjw_call_send_dtmf(long call_id, const char *digits, int mode)
|
|
|
1808
2122
|
#define MAX_LENGTH 31 // pjsip allows for 31 digits (inband allows for 32 digits)
|
|
1809
2123
|
|
|
1810
2124
|
PJW_LOCK();
|
|
1811
|
-
|
|
2125
|
+
clear_error();
|
|
1812
2126
|
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
return -1;
|
|
1817
|
-
}
|
|
2127
|
+
long val;
|
|
2128
|
+
char *digits;
|
|
2129
|
+
int mode = 0;;
|
|
1818
2130
|
|
|
1819
|
-
|
|
1820
|
-
set_error("DTMF list too long");
|
|
1821
|
-
return -1;
|
|
1822
|
-
}
|
|
2131
|
+
int len;
|
|
1823
2132
|
|
|
1824
|
-
|
|
2133
|
+
char adjusted_digits[MAX_LENGTH+1]; // use the greater size
|
|
2134
|
+
|
|
2135
|
+
pj_str_t ds;
|
|
2136
|
+
pj_status_t status;
|
|
2137
|
+
|
|
2138
|
+
Call *call;
|
|
2139
|
+
|
|
2140
|
+
char buffer[MAX_JSON_INPUT];
|
|
2141
|
+
|
|
2142
|
+
Document document;
|
|
2143
|
+
|
|
2144
|
+
if(!parse_json(document, json, buffer, MAX_JSON_INPUT)) {
|
|
2145
|
+
goto out;
|
|
2146
|
+
}
|
|
1825
2147
|
|
|
1826
2148
|
if(!g_call_ids.get(call_id, val)){
|
|
1827
|
-
PJW_UNLOCK();
|
|
1828
2149
|
set_error("Invalid call_id");
|
|
1829
|
-
|
|
2150
|
+
goto out;
|
|
1830
2151
|
}
|
|
2152
|
+
call = (Call*)val;
|
|
1831
2153
|
|
|
1832
|
-
|
|
2154
|
+
if(!json_get_string_param(document, "digits", false, &digits)) {
|
|
2155
|
+
goto out;
|
|
2156
|
+
}
|
|
2157
|
+
|
|
2158
|
+
if(!json_get_int_param(document, "mode", false, &mode)) {
|
|
2159
|
+
goto out;
|
|
2160
|
+
}
|
|
2161
|
+
|
|
2162
|
+
if(mode != DTMF_MODE_RFC2833 && mode != DTMF_MODE_INBAND) {
|
|
2163
|
+
set_error("Invalid DTMF mode. It must be eiter 0 (RFC2833) or 1 (INBAND).");
|
|
2164
|
+
goto out;
|
|
2165
|
+
}
|
|
2166
|
+
|
|
2167
|
+
len = strlen(digits);
|
|
2168
|
+
|
|
2169
|
+
if(len > MAX_LENGTH) {
|
|
2170
|
+
set_error("DTMF string too long");
|
|
2171
|
+
goto out;
|
|
2172
|
+
}
|
|
1833
2173
|
|
|
1834
2174
|
if(!call->med_stream)
|
|
1835
2175
|
{
|
|
1836
|
-
PJW_UNLOCK();
|
|
1837
2176
|
set_error("Unable to send DTMF: Media not ready");
|
|
1838
|
-
|
|
2177
|
+
goto out;
|
|
1839
2178
|
}
|
|
1840
2179
|
|
|
1841
|
-
char adjusted_digits[MAX_LENGTH+1]; // use the greater size
|
|
1842
|
-
|
|
1843
2180
|
for(int i=0; i<len ; ++i) {
|
|
1844
2181
|
if( !(digits[i] >= '0' && digits[i] <= '9') &&
|
|
1845
2182
|
!(digits[i] >= 'a' && digits[i] <= 'f') &&
|
|
@@ -1847,9 +2184,8 @@ int pjw_call_send_dtmf(long call_id, const char *digits, int mode)
|
|
|
1847
2184
|
!(digits[i] == '*') &&
|
|
1848
2185
|
!(digits[i] == '#') )
|
|
1849
2186
|
{
|
|
1850
|
-
PJW_UNLOCK();
|
|
1851
2187
|
set_error("Invalid character");
|
|
1852
|
-
|
|
2188
|
+
goto out;
|
|
1853
2189
|
}
|
|
1854
2190
|
char d = digits[i];
|
|
1855
2191
|
if(d == 'e' || d == 'E') {
|
|
@@ -1863,22 +2199,19 @@ int pjw_call_send_dtmf(long call_id, const char *digits, int mode)
|
|
|
1863
2199
|
adjusted_digits[len] = 0;
|
|
1864
2200
|
//addon_log(LOG_LEVEL_DEBUG, ">>%s<<\n", adjusted_digits);
|
|
1865
2201
|
|
|
1866
|
-
|
|
1867
|
-
pj_status_t status;
|
|
2202
|
+
ds = pj_str((char*)adjusted_digits);
|
|
1868
2203
|
|
|
1869
2204
|
if(DTMF_MODE_RFC2833 == mode) {
|
|
1870
2205
|
status = pjmedia_stream_dial_dtmf(call->med_stream, &ds);
|
|
1871
2206
|
if(status != PJ_SUCCESS)
|
|
1872
2207
|
{
|
|
1873
|
-
PJW_UNLOCK();
|
|
1874
2208
|
set_error("pjmedia_stream_dial_dtmf failed.");
|
|
1875
|
-
|
|
2209
|
+
goto out;
|
|
1876
2210
|
}
|
|
1877
2211
|
} else {
|
|
1878
2212
|
if(!prepare_tonegen(call)) {
|
|
1879
|
-
PJW_UNLOCK();
|
|
1880
2213
|
set_error("prepare_tonegen failed.");
|
|
1881
|
-
|
|
2214
|
+
goto out;
|
|
1882
2215
|
}
|
|
1883
2216
|
|
|
1884
2217
|
for(int i=0; i<len ; ++i) {
|
|
@@ -1889,38 +2222,72 @@ int pjw_call_send_dtmf(long call_id, const char *digits, int mode)
|
|
|
1889
2222
|
tone.volume = 0;
|
|
1890
2223
|
status = chainlink_tonegen_play_digits((pjmedia_port*)call->tonegen, 1, &tone, 0);
|
|
1891
2224
|
if(status != PJ_SUCCESS) {
|
|
1892
|
-
PJW_UNLOCK();
|
|
1893
2225
|
set_error("chainlink_tonegen_play_digits failed.");
|
|
1894
|
-
|
|
2226
|
+
goto out;
|
|
1895
2227
|
}
|
|
1896
2228
|
}
|
|
1897
2229
|
}
|
|
1898
2230
|
|
|
2231
|
+
out:
|
|
1899
2232
|
PJW_UNLOCK();
|
|
2233
|
+
if(pjw_errorstring[0]){
|
|
2234
|
+
return -1;
|
|
2235
|
+
}
|
|
2236
|
+
|
|
1900
2237
|
return 0;
|
|
1901
2238
|
}
|
|
1902
2239
|
|
|
1903
|
-
int pjw_call_reinvite(long call_id, int hold, unsigned flags)
|
|
2240
|
+
//int pjw_call_reinvite(long call_id, int hold, unsigned flags)
|
|
2241
|
+
int pjw_call_reinvite(long call_id, const char *json)
|
|
1904
2242
|
{
|
|
1905
2243
|
PJW_LOCK();
|
|
2244
|
+
clear_error();
|
|
2245
|
+
|
|
2246
|
+
bool hold = false;
|
|
2247
|
+
unsigned flags;
|
|
1906
2248
|
|
|
1907
2249
|
long val;
|
|
2250
|
+
Call *call;
|
|
2251
|
+
|
|
2252
|
+
pj_status_t status;
|
|
2253
|
+
|
|
2254
|
+
const pjmedia_sdp_session *old_sdp = NULL;
|
|
2255
|
+
|
|
2256
|
+
pjsip_tx_data *tdata;
|
|
2257
|
+
pjmedia_sdp_session *sdp = 0;
|
|
2258
|
+
|
|
2259
|
+
char buffer[MAX_JSON_INPUT];
|
|
2260
|
+
|
|
2261
|
+
Document document;
|
|
1908
2262
|
|
|
1909
2263
|
if(!g_call_ids.get(call_id, val)){
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
return -1;
|
|
2264
|
+
set_error("Invalid call_id");
|
|
2265
|
+
goto out;
|
|
1913
2266
|
}
|
|
2267
|
+
call = (Call*)val;
|
|
1914
2268
|
|
|
1915
|
-
|
|
2269
|
+
if(!parse_json(document, json, buffer, MAX_JSON_INPUT)) {
|
|
2270
|
+
goto out;
|
|
2271
|
+
}
|
|
1916
2272
|
|
|
1917
|
-
|
|
2273
|
+
if(!json_get_bool_param(document, "hold", true, &hold)) {
|
|
2274
|
+
goto out;
|
|
2275
|
+
}
|
|
1918
2276
|
|
|
1919
|
-
|
|
2277
|
+
if(document.HasMember("delayed_media")) {
|
|
2278
|
+
if(!document["delayed_media"].IsBool()) {
|
|
2279
|
+
set_error("Parameter delayed_media must be a boolean");
|
|
2280
|
+
goto out;
|
|
2281
|
+
} else {
|
|
2282
|
+
if(document["delayed_media"].GetBool()) {
|
|
2283
|
+
flags = flags | CALL_FLAG_DELAYED_MEDIA;
|
|
2284
|
+
}
|
|
2285
|
+
}
|
|
2286
|
+
}
|
|
1920
2287
|
|
|
1921
2288
|
call->local_hold = hold;
|
|
1922
2289
|
|
|
1923
|
-
if(!(flags &
|
|
2290
|
+
if(!(flags & CALL_FLAG_DELAYED_MEDIA)) {
|
|
1924
2291
|
pjmedia_transport_info tpinfo;
|
|
1925
2292
|
pjmedia_transport_info_init(&tpinfo);
|
|
1926
2293
|
pjmedia_transport_get_info(call->med_transport,&tpinfo);
|
|
@@ -1931,9 +2298,8 @@ int pjw_call_reinvite(long call_id, int hold, unsigned flags)
|
|
|
1931
2298
|
&tpinfo.sock_info,
|
|
1932
2299
|
&sdp);
|
|
1933
2300
|
if(status != PJ_SUCCESS){
|
|
1934
|
-
PJW_UNLOCK();
|
|
1935
2301
|
set_error("pjmedia_endpt_create_sdp failed");
|
|
1936
|
-
|
|
2302
|
+
goto out;
|
|
1937
2303
|
}
|
|
1938
2304
|
|
|
1939
2305
|
pjmedia_sdp_attr *attr;
|
|
@@ -1957,47 +2323,54 @@ int pjw_call_reinvite(long call_id, int hold, unsigned flags)
|
|
|
1957
2323
|
|
|
1958
2324
|
pjmedia_sdp_media_add_attr(sdp->media[0], attr);
|
|
1959
2325
|
|
|
1960
|
-
|
|
2326
|
+
old_sdp = NULL;
|
|
1961
2327
|
|
|
1962
2328
|
status = pjmedia_sdp_neg_get_active_local(call->inv->neg, &old_sdp);
|
|
1963
2329
|
if (status != PJ_SUCCESS || old_sdp == NULL){
|
|
1964
|
-
PJW_UNLOCK();
|
|
1965
2330
|
set_error("pjmedia_sdp_neg_get_active failed");
|
|
1966
|
-
|
|
2331
|
+
goto out;
|
|
1967
2332
|
}
|
|
1968
2333
|
|
|
1969
2334
|
sdp->origin.version = old_sdp->origin.version + 1;
|
|
1970
2335
|
}
|
|
1971
2336
|
|
|
1972
|
-
pjsip_tx_data *tdata;
|
|
1973
2337
|
status = pjsip_inv_reinvite(call->inv, NULL, sdp, &tdata);
|
|
1974
2338
|
if(status != PJ_SUCCESS){
|
|
1975
|
-
PJW_UNLOCK();
|
|
1976
2339
|
set_error("pjsip_inv_reinvite failed");
|
|
1977
|
-
|
|
2340
|
+
goto out;
|
|
1978
2341
|
}
|
|
1979
2342
|
|
|
1980
2343
|
status = pjsip_inv_send_msg(call->inv, tdata);
|
|
1981
2344
|
if(status != PJ_SUCCESS){
|
|
1982
|
-
PJW_UNLOCK();
|
|
1983
2345
|
set_error("pjsip_inv_send_msg failed");
|
|
1984
|
-
|
|
2346
|
+
goto out;
|
|
1985
2347
|
}
|
|
1986
2348
|
|
|
2349
|
+
out:
|
|
1987
2350
|
PJW_UNLOCK();
|
|
2351
|
+
if(pjw_errorstring[0]){
|
|
2352
|
+
return -1;
|
|
2353
|
+
}
|
|
2354
|
+
|
|
1988
2355
|
return 0;
|
|
1989
2356
|
}
|
|
1990
2357
|
|
|
1991
2358
|
//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)
|
|
2359
|
+
//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)
|
|
2360
|
+
int pjw_call_send_request(long call_id, const char *json)
|
|
1993
2361
|
{
|
|
1994
2362
|
PJW_LOCK();
|
|
1995
2363
|
clear_error();
|
|
1996
2364
|
|
|
1997
|
-
|
|
2365
|
+
char *method = NULL;
|
|
2366
|
+
char *body = NULL;
|
|
2367
|
+
char *ct_type = NULL;
|
|
2368
|
+
char *ct_subtype = NULL;
|
|
2369
|
+
|
|
2370
|
+
pj_str_t s_method;
|
|
1998
2371
|
pjsip_tx_data *tdata;
|
|
1999
2372
|
pj_status_t status;
|
|
2000
|
-
pjsip_method
|
|
2373
|
+
pjsip_method meth;
|
|
2001
2374
|
|
|
2002
2375
|
pjsip_msg_body *msg_body;
|
|
2003
2376
|
|
|
@@ -2009,14 +2382,37 @@ int pjw_call_send_request(long call_id, const char *method_name, const char *add
|
|
|
2009
2382
|
|
|
2010
2383
|
long val;
|
|
2011
2384
|
|
|
2385
|
+
char buffer[MAX_JSON_INPUT];
|
|
2386
|
+
|
|
2387
|
+
Document document;
|
|
2388
|
+
|
|
2389
|
+
if(!parse_json(document, json, buffer, MAX_JSON_INPUT)) {
|
|
2390
|
+
goto out;
|
|
2391
|
+
}
|
|
2392
|
+
|
|
2012
2393
|
if(!g_call_ids.get(call_id, val)){
|
|
2013
2394
|
set_error("Invalid call_id");
|
|
2014
2395
|
goto out;
|
|
2015
2396
|
}
|
|
2016
|
-
|
|
2017
2397
|
call = (Call*)val;
|
|
2018
2398
|
|
|
2019
|
-
|
|
2399
|
+
if(!json_get_string_param(document, "method", false, &method)) {
|
|
2400
|
+
goto out;
|
|
2401
|
+
}
|
|
2402
|
+
|
|
2403
|
+
if(!json_get_string_param(document, "body", true, &body)) {
|
|
2404
|
+
goto out;
|
|
2405
|
+
}
|
|
2406
|
+
|
|
2407
|
+
if(!json_get_string_param(document, "ct_type", true, &ct_type)) {
|
|
2408
|
+
goto out;
|
|
2409
|
+
}
|
|
2410
|
+
|
|
2411
|
+
if(!json_get_string_param(document, "ct_subtype", true, &ct_subtype)) {
|
|
2412
|
+
goto out;
|
|
2413
|
+
}
|
|
2414
|
+
|
|
2415
|
+
if(strcmp(method,"INVITE")==0 || strcmp(method,"UPDATE")==0 || strcmp(method,"PRACK")==0 || strcmp(method,"BYE")==0) {
|
|
2020
2416
|
set_error("Invalid method");
|
|
2021
2417
|
goto out;
|
|
2022
2418
|
}
|
|
@@ -2028,17 +2424,17 @@ int pjw_call_send_request(long call_id, const char *method_name, const char *add
|
|
|
2028
2424
|
}
|
|
2029
2425
|
}
|
|
2030
2426
|
|
|
2031
|
-
|
|
2427
|
+
s_method = pj_str((char*)method);
|
|
2032
2428
|
|
|
2033
|
-
pjsip_method_init_np(&
|
|
2429
|
+
pjsip_method_init_np(&meth, &s_method);
|
|
2034
2430
|
|
|
2035
|
-
status = pjsip_dlg_create_request(call->inv->dlg, &
|
|
2431
|
+
status = pjsip_dlg_create_request(call->inv->dlg, &meth, -1, &tdata);
|
|
2036
2432
|
if (status != PJ_SUCCESS) {
|
|
2037
|
-
set_error("pjsip_dlg_create_request failed");
|
|
2433
|
+
set_error("pjsip_dlg_create_request failed with status=%i", status);
|
|
2038
2434
|
goto out;
|
|
2039
2435
|
}
|
|
2040
2436
|
|
|
2041
|
-
if(!
|
|
2437
|
+
if(!add_headers(call->inv->dlg->pool, tdata, document)) {
|
|
2042
2438
|
goto out;
|
|
2043
2439
|
}
|
|
2044
2440
|
|
|
@@ -2058,222 +2454,294 @@ int pjw_call_send_request(long call_id, const char *method_name, const char *add
|
|
|
2058
2454
|
|
|
2059
2455
|
status = pjsip_dlg_send_request(call->inv->dlg, tdata, -1, NULL);
|
|
2060
2456
|
if (status != PJ_SUCCESS) {
|
|
2061
|
-
set_error("pjsip_dlg_send_request failed");
|
|
2457
|
+
set_error("pjsip_dlg_send_request failed with status=%i", status);
|
|
2062
2458
|
goto out;
|
|
2063
2459
|
}
|
|
2064
2460
|
|
|
2065
|
-
PJW_UNLOCK();
|
|
2066
|
-
return 0;
|
|
2067
|
-
|
|
2068
2461
|
out:
|
|
2069
2462
|
PJW_UNLOCK();
|
|
2070
|
-
|
|
2071
2463
|
if(pjw_errorstring[0]) {
|
|
2072
2464
|
return -1;
|
|
2073
2465
|
}
|
|
2074
|
-
return 0;
|
|
2075
2466
|
|
|
2467
|
+
return 0;
|
|
2076
2468
|
}
|
|
2077
2469
|
|
|
2078
|
-
int pjw_call_start_record_wav(long call_id, const char *file)
|
|
2470
|
+
//int pjw_call_start_record_wav(long call_id, const char *file)
|
|
2471
|
+
int pjw_call_start_record_wav(long call_id, const char *json)
|
|
2079
2472
|
{
|
|
2080
2473
|
PJW_LOCK();
|
|
2474
|
+
clear_error();
|
|
2081
2475
|
|
|
2082
2476
|
long val;
|
|
2477
|
+
Call *call;
|
|
2478
|
+
pj_status_t status;
|
|
2479
|
+
pjmedia_port *stream_port;
|
|
2480
|
+
|
|
2481
|
+
char *file;
|
|
2482
|
+
|
|
2483
|
+
char buffer[MAX_JSON_INPUT];
|
|
2484
|
+
|
|
2485
|
+
Document document;
|
|
2083
2486
|
|
|
2084
2487
|
if(!g_call_ids.get(call_id, val)){
|
|
2085
|
-
PJW_UNLOCK();
|
|
2086
2488
|
set_error("Invalid call_id");
|
|
2087
|
-
|
|
2489
|
+
goto out;
|
|
2088
2490
|
}
|
|
2089
|
-
|
|
2090
|
-
Call *call = (Call*)val;
|
|
2491
|
+
call = (Call*)val;
|
|
2091
2492
|
|
|
2092
2493
|
if(!call->med_stream)
|
|
2093
2494
|
{
|
|
2094
|
-
PJW_UNLOCK();
|
|
2095
2495
|
set_error("Media not ready");
|
|
2096
|
-
|
|
2496
|
+
goto out;
|
|
2097
2497
|
}
|
|
2098
2498
|
|
|
2099
|
-
|
|
2499
|
+
if(!parse_json(document, json, buffer, MAX_JSON_INPUT)) {
|
|
2500
|
+
goto out;
|
|
2501
|
+
}
|
|
2100
2502
|
|
|
2101
|
-
|
|
2503
|
+
if(!json_get_string_param(document, "file", false, &file)) {
|
|
2504
|
+
goto out;
|
|
2505
|
+
}
|
|
2506
|
+
|
|
2507
|
+
if(!file[0]) {
|
|
2508
|
+
set_error("file cannot be blank string");
|
|
2509
|
+
goto out;
|
|
2510
|
+
}
|
|
2511
|
+
|
|
2102
2512
|
status = pjmedia_stream_get_port(call->med_stream,
|
|
2103
2513
|
&stream_port);
|
|
2104
2514
|
if(status != PJ_SUCCESS)
|
|
2105
2515
|
{
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
return -1;
|
|
2516
|
+
set_error("pjmedia_stream_get_port failed with status=%i", status);
|
|
2517
|
+
goto out;
|
|
2109
2518
|
}
|
|
2110
2519
|
|
|
2111
2520
|
if(!prepare_wav_writer(call, file)) {
|
|
2112
|
-
PJW_UNLOCK();
|
|
2113
2521
|
set_error("prepare_wav_writer failed");
|
|
2114
|
-
|
|
2522
|
+
goto out;
|
|
2115
2523
|
}
|
|
2116
2524
|
|
|
2525
|
+
out:
|
|
2117
2526
|
PJW_UNLOCK();
|
|
2527
|
+
if(pjw_errorstring[0]){
|
|
2528
|
+
return -1;
|
|
2529
|
+
}
|
|
2530
|
+
|
|
2118
2531
|
return 0;
|
|
2119
2532
|
}
|
|
2120
2533
|
|
|
2121
2534
|
|
|
2122
|
-
int pjw_call_start_play_wav(long call_id, const char *file)
|
|
2535
|
+
//int pjw_call_start_play_wav(long call_id, const char *file)
|
|
2536
|
+
int pjw_call_start_play_wav(long call_id, const char *json)
|
|
2123
2537
|
{
|
|
2124
2538
|
PJW_LOCK();
|
|
2539
|
+
clear_error();
|
|
2125
2540
|
|
|
2126
2541
|
long val;
|
|
2542
|
+
Call *call;
|
|
2543
|
+
pj_status_t status;
|
|
2544
|
+
pjmedia_port *stream_port;
|
|
2545
|
+
|
|
2546
|
+
char *file;
|
|
2547
|
+
|
|
2548
|
+
char buffer[MAX_JSON_INPUT];
|
|
2549
|
+
|
|
2550
|
+
Document document;
|
|
2127
2551
|
|
|
2128
2552
|
if(!g_call_ids.get(call_id, val)){
|
|
2129
|
-
PJW_UNLOCK();
|
|
2130
2553
|
set_error("Invalid call_id");
|
|
2131
|
-
|
|
2554
|
+
goto out;
|
|
2132
2555
|
}
|
|
2133
|
-
|
|
2134
|
-
Call *call = (Call*)val;
|
|
2556
|
+
call = (Call*)val;
|
|
2135
2557
|
|
|
2136
2558
|
if(!call->med_stream)
|
|
2137
2559
|
{
|
|
2138
|
-
PJW_UNLOCK();
|
|
2139
2560
|
set_error("Media not ready");
|
|
2140
|
-
|
|
2561
|
+
goto out;
|
|
2141
2562
|
}
|
|
2142
2563
|
|
|
2143
|
-
|
|
2564
|
+
if(!parse_json(document, json, buffer, MAX_JSON_INPUT)) {
|
|
2565
|
+
goto out;
|
|
2566
|
+
}
|
|
2567
|
+
|
|
2568
|
+
if(!json_get_string_param(document, "file", false, &file)) {
|
|
2569
|
+
goto out;
|
|
2570
|
+
}
|
|
2571
|
+
|
|
2572
|
+
if(!file[0]) {
|
|
2573
|
+
set_error("file cannot be blank string");
|
|
2574
|
+
goto out;
|
|
2575
|
+
}
|
|
2144
2576
|
|
|
2145
|
-
pjmedia_port *stream_port;
|
|
2146
2577
|
status = pjmedia_stream_get_port(call->med_stream,
|
|
2147
2578
|
&stream_port);
|
|
2148
2579
|
if(status != PJ_SUCCESS)
|
|
2149
2580
|
{
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
return -1;
|
|
2581
|
+
set_error("pjmedia_stream_get_port failed with status=%i", status);
|
|
2582
|
+
goto out;
|
|
2153
2583
|
}
|
|
2154
2584
|
|
|
2155
2585
|
if(!prepare_wav_player(call, file)){
|
|
2156
|
-
|
|
2157
|
-
|
|
2158
|
-
|
|
2159
|
-
}
|
|
2586
|
+
set_error("prepare_wav_player failed");
|
|
2587
|
+
goto out;
|
|
2588
|
+
}
|
|
2160
2589
|
|
|
2590
|
+
out:
|
|
2161
2591
|
PJW_UNLOCK();
|
|
2592
|
+
if(pjw_errorstring[0]){
|
|
2593
|
+
return -1;
|
|
2594
|
+
}
|
|
2595
|
+
|
|
2162
2596
|
return 0;
|
|
2163
2597
|
}
|
|
2164
2598
|
|
|
2165
2599
|
int pjw_call_stop_play_wav(long call_id)
|
|
2166
2600
|
{
|
|
2167
2601
|
PJW_LOCK();
|
|
2602
|
+
clear_error();
|
|
2603
|
+
|
|
2604
|
+
Call *call;
|
|
2605
|
+
|
|
2606
|
+
pjmedia_port *stream_port;
|
|
2607
|
+
pj_status_t status;
|
|
2168
2608
|
|
|
2169
2609
|
long val;
|
|
2170
2610
|
|
|
2171
2611
|
if(!g_call_ids.get(call_id, val)){
|
|
2172
|
-
PJW_UNLOCK();
|
|
2173
2612
|
set_error("Invalid call_id");
|
|
2174
|
-
|
|
2613
|
+
goto out;
|
|
2175
2614
|
}
|
|
2615
|
+
call = (Call*)val;
|
|
2176
2616
|
|
|
2177
|
-
Call *call = (Call*)val;
|
|
2178
|
-
|
|
2179
|
-
pjmedia_port *stream_port;
|
|
2180
|
-
pj_status_t status;
|
|
2181
2617
|
status = pjmedia_stream_get_port(call->med_stream,
|
|
2182
2618
|
&stream_port);
|
|
2183
2619
|
if(status != PJ_SUCCESS) {
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
return -1;
|
|
2620
|
+
set_error("pjmedia_stream_get_port failed with status=%i", status);
|
|
2621
|
+
goto out;
|
|
2187
2622
|
}
|
|
2188
2623
|
|
|
2189
2624
|
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
2625
|
set_error("prepare_wire failed.");
|
|
2192
|
-
|
|
2626
|
+
goto out;
|
|
2193
2627
|
}
|
|
2194
2628
|
|
|
2195
2629
|
connect_media_ports(call);
|
|
2196
2630
|
|
|
2631
|
+
out:
|
|
2197
2632
|
PJW_UNLOCK();
|
|
2633
|
+
if(pjw_errorstring[0]){
|
|
2634
|
+
return -1;
|
|
2635
|
+
}
|
|
2636
|
+
|
|
2198
2637
|
return 0;
|
|
2199
2638
|
}
|
|
2200
2639
|
|
|
2201
2640
|
int pjw_call_stop_record_wav(long call_id)
|
|
2202
2641
|
{
|
|
2203
2642
|
PJW_LOCK();
|
|
2643
|
+
clear_error();
|
|
2204
2644
|
|
|
2205
2645
|
long val;
|
|
2646
|
+
Call *call = (Call*)val;
|
|
2647
|
+
pjmedia_port *stream_port;
|
|
2648
|
+
pj_status_t status;
|
|
2206
2649
|
|
|
2207
2650
|
if(!g_call_ids.get(call_id, val)){
|
|
2208
|
-
PJW_UNLOCK();
|
|
2209
2651
|
set_error("Invalid call_id");
|
|
2210
|
-
|
|
2652
|
+
goto out;
|
|
2211
2653
|
}
|
|
2654
|
+
call = (Call*)val;
|
|
2212
2655
|
|
|
2213
|
-
Call *call = (Call*)val;
|
|
2214
|
-
|
|
2215
|
-
pjmedia_port *stream_port;
|
|
2216
|
-
pj_status_t status;
|
|
2217
2656
|
status = pjmedia_stream_get_port(call->med_stream,
|
|
2218
2657
|
&stream_port);
|
|
2219
2658
|
if(status != PJ_SUCCESS) {
|
|
2220
|
-
PJW_UNLOCK();
|
|
2221
2659
|
set_error("pjmedia_stream_get_port failed.");
|
|
2222
|
-
|
|
2660
|
+
goto out;
|
|
2223
2661
|
}
|
|
2224
2662
|
|
|
2225
2663
|
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
2664
|
set_error("prepare_wire failed.");
|
|
2228
|
-
|
|
2665
|
+
goto out;
|
|
2229
2666
|
}
|
|
2230
2667
|
|
|
2231
2668
|
connect_media_ports(call);
|
|
2232
|
-
|
|
2669
|
+
|
|
2670
|
+
out:
|
|
2233
2671
|
PJW_UNLOCK();
|
|
2672
|
+
if(pjw_errorstring[0]){
|
|
2673
|
+
return -1;
|
|
2674
|
+
}
|
|
2675
|
+
|
|
2234
2676
|
return 0;
|
|
2235
2677
|
}
|
|
2236
2678
|
|
|
2237
|
-
int pjw_call_start_fax(long call_id, bool is_sender, const char *file)
|
|
2679
|
+
//int pjw_call_start_fax(long call_id, bool is_sender, const char *file)
|
|
2680
|
+
int pjw_call_start_fax(long call_id, const char *json)
|
|
2238
2681
|
{
|
|
2239
2682
|
PJW_LOCK();
|
|
2683
|
+
clear_error();
|
|
2240
2684
|
|
|
2241
2685
|
long val;
|
|
2686
|
+
Call *call;
|
|
2687
|
+
pj_status_t status;
|
|
2688
|
+
pjmedia_port *stream_port;
|
|
2689
|
+
|
|
2690
|
+
bool is_sender;
|
|
2691
|
+
char *file;
|
|
2692
|
+
|
|
2693
|
+
char buffer[MAX_JSON_INPUT];
|
|
2694
|
+
|
|
2695
|
+
Document document;
|
|
2242
2696
|
|
|
2243
2697
|
if(!g_call_ids.get(call_id, val)){
|
|
2244
|
-
PJW_UNLOCK();
|
|
2245
2698
|
set_error("Invalid call_id");
|
|
2246
|
-
|
|
2699
|
+
goto out;
|
|
2247
2700
|
}
|
|
2248
|
-
|
|
2249
|
-
Call *call = (Call*)val;
|
|
2701
|
+
call = (Call*)val;
|
|
2250
2702
|
|
|
2251
2703
|
if(!call->med_stream)
|
|
2252
2704
|
{
|
|
2253
|
-
PJW_UNLOCK();
|
|
2254
2705
|
set_error("Media not ready");
|
|
2255
|
-
|
|
2706
|
+
goto out;
|
|
2256
2707
|
}
|
|
2257
2708
|
|
|
2258
|
-
|
|
2709
|
+
if(!parse_json(document, json, buffer, MAX_JSON_INPUT)) {
|
|
2710
|
+
goto out;
|
|
2711
|
+
}
|
|
2712
|
+
|
|
2713
|
+
if(!json_get_bool_param(document, "is_sender", false, &is_sender)) {
|
|
2714
|
+
goto out;
|
|
2715
|
+
}
|
|
2716
|
+
|
|
2717
|
+
if(!json_get_string_param(document, "file", false, &file)) {
|
|
2718
|
+
goto out;
|
|
2719
|
+
}
|
|
2720
|
+
|
|
2721
|
+
if(!file[0]) {
|
|
2722
|
+
set_error("file cannot be blank string");
|
|
2723
|
+
goto out;
|
|
2724
|
+
}
|
|
2259
2725
|
|
|
2260
|
-
pjmedia_port *stream_port;
|
|
2261
2726
|
status = pjmedia_stream_get_port(call->med_stream,
|
|
2262
2727
|
&stream_port);
|
|
2263
2728
|
if(status != PJ_SUCCESS)
|
|
2264
2729
|
{
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
return -1;
|
|
2730
|
+
set_error("pjmedia_stream_get_port failed with status=%i", status);
|
|
2731
|
+
goto out;
|
|
2268
2732
|
}
|
|
2269
2733
|
|
|
2270
2734
|
if(!prepare_fax(call, is_sender, file)){
|
|
2271
|
-
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
}
|
|
2735
|
+
set_error("prepare_fax failed");
|
|
2736
|
+
goto out;
|
|
2737
|
+
}
|
|
2275
2738
|
|
|
2739
|
+
out:
|
|
2276
2740
|
PJW_UNLOCK();
|
|
2741
|
+
if(pjw_errorstring[0]){
|
|
2742
|
+
return -1;
|
|
2743
|
+
}
|
|
2744
|
+
|
|
2277
2745
|
return 0;
|
|
2278
2746
|
}
|
|
2279
2747
|
|
|
@@ -2281,84 +2749,90 @@ int pjw_call_start_fax(long call_id, bool is_sender, const char *file)
|
|
|
2281
2749
|
int pjw_call_stop_fax(long call_id)
|
|
2282
2750
|
{
|
|
2283
2751
|
PJW_LOCK();
|
|
2752
|
+
clear_error();
|
|
2284
2753
|
|
|
2285
2754
|
long val;
|
|
2755
|
+
Call *call;
|
|
2756
|
+
|
|
2757
|
+
pjmedia_port *stream_port;
|
|
2758
|
+
pj_status_t status;
|
|
2286
2759
|
|
|
2287
2760
|
if(!g_call_ids.get(call_id, val)){
|
|
2288
|
-
PJW_UNLOCK();
|
|
2289
2761
|
set_error("Invalid call_id");
|
|
2290
|
-
|
|
2762
|
+
goto out;
|
|
2291
2763
|
}
|
|
2292
2764
|
|
|
2293
|
-
|
|
2765
|
+
call = (Call*)val;
|
|
2294
2766
|
|
|
2295
|
-
pjmedia_port *stream_port;
|
|
2296
|
-
pj_status_t status;
|
|
2297
2767
|
status = pjmedia_stream_get_port(call->med_stream,
|
|
2298
2768
|
&stream_port);
|
|
2299
2769
|
if(status != PJ_SUCCESS) {
|
|
2300
|
-
PJW_UNLOCK();
|
|
2301
2770
|
set_error("pjmedia_stream_get_port failed.");
|
|
2302
|
-
|
|
2771
|
+
goto out;
|
|
2303
2772
|
}
|
|
2304
2773
|
|
|
2305
2774
|
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
2775
|
set_error("prepare_wire failed.");
|
|
2308
|
-
|
|
2776
|
+
goto out;
|
|
2309
2777
|
}
|
|
2310
2778
|
|
|
2311
2779
|
connect_media_ports(call);
|
|
2312
2780
|
|
|
2781
|
+
out:
|
|
2313
2782
|
PJW_UNLOCK();
|
|
2783
|
+
if(pjw_errorstring[0]){
|
|
2784
|
+
return -1;
|
|
2785
|
+
}
|
|
2786
|
+
|
|
2314
2787
|
return 0;
|
|
2315
2788
|
}
|
|
2316
2789
|
|
|
2317
2790
|
|
|
2318
2791
|
int pjw_call_get_stream_stat(long call_id, char *out_stats){
|
|
2319
2792
|
PJW_LOCK();
|
|
2793
|
+
clear_error();
|
|
2320
2794
|
|
|
2321
2795
|
long val;
|
|
2796
|
+
Call *call;
|
|
2797
|
+
|
|
2798
|
+
pj_status_t status;
|
|
2799
|
+
pjmedia_rtcp_stat stat;
|
|
2800
|
+
pjmedia_stream_info stream_info;
|
|
2801
|
+
|
|
2802
|
+
ostringstream oss;
|
|
2322
2803
|
|
|
2323
2804
|
if(!g_call_ids.get(call_id, val)){
|
|
2324
|
-
PJW_UNLOCK();
|
|
2325
2805
|
set_error("Invalid call_id");
|
|
2326
|
-
|
|
2806
|
+
goto out;
|
|
2327
2807
|
}
|
|
2328
|
-
|
|
2329
|
-
Call *call = (Call*)val;
|
|
2808
|
+
call = (Call*)val;
|
|
2330
2809
|
|
|
2331
2810
|
if(!call->med_stream){
|
|
2332
|
-
PJW_UNLOCK();
|
|
2333
2811
|
set_error("Could not get stream stats. No media session");
|
|
2334
|
-
|
|
2812
|
+
goto out;
|
|
2335
2813
|
}
|
|
2336
2814
|
|
|
2337
|
-
pj_status_t status;
|
|
2338
|
-
|
|
2339
|
-
pjmedia_rtcp_stat stat;
|
|
2340
|
-
pjmedia_stream_info stream_info;
|
|
2341
|
-
|
|
2342
2815
|
status = pjmedia_stream_get_stat(call->med_stream, &stat);
|
|
2343
2816
|
if(status != PJ_SUCCESS){
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
return -1;
|
|
2817
|
+
set_error("Could not get stream stats. Call to pjmedia_stream_get_stream_stat failed with status=%i", status);
|
|
2818
|
+
goto out;
|
|
2347
2819
|
}
|
|
2348
2820
|
|
|
2349
2821
|
status = pjmedia_stream_get_info(call->med_stream, &stream_info);
|
|
2350
2822
|
if(status != PJ_SUCCESS){
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
return -1;
|
|
2823
|
+
set_error("Could not get stream info. Call to pjmedia_stream_get_info failed with status=%i", status);
|
|
2824
|
+
goto out;
|
|
2354
2825
|
}
|
|
2355
2826
|
|
|
2356
|
-
ostringstream oss;
|
|
2357
2827
|
build_stream_stat(oss, &stat, &stream_info);
|
|
2828
|
+
strcpy(out_stats, oss.str().c_str());
|
|
2358
2829
|
|
|
2830
|
+
out:
|
|
2359
2831
|
PJW_UNLOCK();
|
|
2832
|
+
if(pjw_errorstring[0]){
|
|
2833
|
+
return -1;
|
|
2834
|
+
}
|
|
2360
2835
|
|
|
2361
|
-
strcpy(out_stats, oss.str().c_str());
|
|
2362
2836
|
return 0;
|
|
2363
2837
|
}
|
|
2364
2838
|
|
|
@@ -2649,7 +3123,7 @@ static void on_state_changed( pjsip_inv_session *inv,
|
|
|
2649
3123
|
|
|
2650
3124
|
char evt[2048];
|
|
2651
3125
|
int sip_msg_len = 0;
|
|
2652
|
-
char *sip_msg = "";
|
|
3126
|
+
char *sip_msg = (char*)"";
|
|
2653
3127
|
if(e->type == PJSIP_EVENT_TSX_STATE) {
|
|
2654
3128
|
sip_msg_len = e->body.rx_msg.rdata->msg_info.len;
|
|
2655
3129
|
sip_msg = e->body.rx_msg.rdata->msg_info.msg_buf;
|
|
@@ -2766,7 +3240,7 @@ static void process_subscribe_request(pjsip_rx_data *rdata) {
|
|
|
2766
3240
|
|
|
2767
3241
|
out:
|
|
2768
3242
|
if(status != PJ_SUCCESS) {
|
|
2769
|
-
pj_str_t s_reason = pj_str(pjw_errorstring);
|
|
3243
|
+
//pj_str_t s_reason = pj_str(pjw_errorstring);
|
|
2770
3244
|
if(dlg) {
|
|
2771
3245
|
status = pjsip_dlg_create_response(dlg, rdata, 500, NULL, &tdata);
|
|
2772
3246
|
if(status == PJ_SUCCESS) {
|
|
@@ -2843,7 +3317,7 @@ static pj_bool_t on_rx_request( pjsip_rx_data *rdata ){
|
|
|
2843
3317
|
build_basic_request_info(&oss, rdata, &transport);
|
|
2844
3318
|
*/
|
|
2845
3319
|
|
|
2846
|
-
reason = pj_str("OK");
|
|
3320
|
+
reason = pj_str((char*)"OK");
|
|
2847
3321
|
|
|
2848
3322
|
pjsip_hdr hdr_list;
|
|
2849
3323
|
pj_list_init(&hdr_list);
|
|
@@ -2852,7 +3326,7 @@ static pj_bool_t on_rx_request( pjsip_rx_data *rdata ){
|
|
|
2852
3326
|
pjsip_hdr *hdr_from_request;
|
|
2853
3327
|
|
|
2854
3328
|
//Add Contact header from Request, if present
|
|
2855
|
-
pj_str_t STR_CONTACT = {
|
|
3329
|
+
pj_str_t STR_CONTACT = {(char*)"Contact" , 7 };
|
|
2856
3330
|
hdr_from_request = (pjsip_hdr*)pjsip_msg_find_hdr_by_name(rdata->msg_info.msg,
|
|
2857
3331
|
&STR_CONTACT,
|
|
2858
3332
|
NULL);
|
|
@@ -2862,7 +3336,7 @@ static pj_bool_t on_rx_request( pjsip_rx_data *rdata ){
|
|
|
2862
3336
|
}
|
|
2863
3337
|
|
|
2864
3338
|
//Add Expires header from Request, if present
|
|
2865
|
-
pj_str_t STR_EXPIRES = {
|
|
3339
|
+
pj_str_t STR_EXPIRES = {(char*)"Expires" , 7 };
|
|
2866
3340
|
hdr_from_request = (pjsip_hdr*)pjsip_msg_find_hdr_by_name(rdata->msg_info.msg,
|
|
2867
3341
|
&STR_EXPIRES,
|
|
2868
3342
|
NULL);
|
|
@@ -2883,13 +3357,13 @@ static pj_bool_t on_rx_request( pjsip_rx_data *rdata ){
|
|
|
2883
3357
|
unsigned options = 0;
|
|
2884
3358
|
status = pjsip_inv_verify_request(rdata, &options, NULL, NULL, g_sip_endpt, NULL);
|
|
2885
3359
|
if(status != PJ_SUCCESS) {
|
|
2886
|
-
reason = pj_str("Unable to handle this INVITE");
|
|
3360
|
+
reason = pj_str((char*)"Unable to handle this INVITE");
|
|
2887
3361
|
pjsip_endpt_respond_stateless(g_sip_endpt, rdata, 500, &reason, NULL, NULL);
|
|
2888
3362
|
return PJ_TRUE;
|
|
2889
3363
|
}
|
|
2890
3364
|
|
|
2891
3365
|
char local_contact[1000];
|
|
2892
|
-
build_local_contact(local_contact, rdata->tp_info.transport, "sip-
|
|
3366
|
+
build_local_contact(local_contact, rdata->tp_info.transport, "sip-lab");
|
|
2893
3367
|
pj_str_t url = pj_str(local_contact);
|
|
2894
3368
|
|
|
2895
3369
|
status = pjsip_dlg_create_uas_and_inc_lock(pjsip_ua_instance(),
|
|
@@ -2898,7 +3372,7 @@ static pj_bool_t on_rx_request( pjsip_rx_data *rdata ){
|
|
|
2898
3372
|
&dlg);
|
|
2899
3373
|
|
|
2900
3374
|
if(status != PJ_SUCCESS) {
|
|
2901
|
-
reason = pj_str("Internal Server Error (pjsip_dlg_create_uas_and_inc_lock failed)");
|
|
3375
|
+
reason = pj_str((char*)"Internal Server Error (pjsip_dlg_create_uas_and_inc_lock failed)");
|
|
2902
3376
|
pjsip_endpt_respond_stateless(g_sip_endpt, rdata, 500, &reason, NULL, NULL);
|
|
2903
3377
|
return PJ_TRUE;
|
|
2904
3378
|
}
|
|
@@ -2909,7 +3383,7 @@ static pj_bool_t on_rx_request( pjsip_rx_data *rdata ){
|
|
|
2909
3383
|
|
|
2910
3384
|
if(!med_transport)
|
|
2911
3385
|
{
|
|
2912
|
-
reason = pj_str("Internal Server Error (could not create media transport)");
|
|
3386
|
+
reason = pj_str((char*)"Internal Server Error (could not create media transport)");
|
|
2913
3387
|
pjsip_endpt_respond_stateless(g_sip_endpt, rdata, 500, &reason, NULL, NULL);
|
|
2914
3388
|
return PJ_TRUE;
|
|
2915
3389
|
}
|
|
@@ -2924,7 +3398,7 @@ static pj_bool_t on_rx_request( pjsip_rx_data *rdata ){
|
|
|
2924
3398
|
&sdp);
|
|
2925
3399
|
if(status != PJ_SUCCESS) {
|
|
2926
3400
|
close_media_transport(med_transport);
|
|
2927
|
-
reason = pj_str("Internal Server Error (pjmedia_endprt_create_sdp failed)");
|
|
3401
|
+
reason = pj_str((char*)"Internal Server Error (pjmedia_endprt_create_sdp failed)");
|
|
2928
3402
|
pjsip_endpt_respond_stateless(g_sip_endpt, rdata, 500, &reason, NULL, NULL);
|
|
2929
3403
|
return PJ_TRUE;
|
|
2930
3404
|
}
|
|
@@ -2933,14 +3407,14 @@ static pj_bool_t on_rx_request( pjsip_rx_data *rdata ){
|
|
|
2933
3407
|
status = pjsip_inv_create_uas(dlg, rdata, sdp, 0, &inv);
|
|
2934
3408
|
if(status != PJ_SUCCESS) {
|
|
2935
3409
|
close_media_transport(med_transport);
|
|
2936
|
-
reason = pj_str("Internal Server Error (pjsip_inv_create_uas failed)");
|
|
3410
|
+
reason = pj_str((char*)"Internal Server Error (pjsip_inv_create_uas failed)");
|
|
2937
3411
|
pjsip_endpt_respond_stateless(g_sip_endpt, rdata, 500, &reason, NULL, NULL);
|
|
2938
3412
|
return PJ_TRUE;
|
|
2939
3413
|
}
|
|
2940
3414
|
|
|
2941
3415
|
if(!dlg_set_transport(t, dlg)) {
|
|
2942
3416
|
close_media_transport(med_transport);
|
|
2943
|
-
reason = pj_str("Internal Server Error (set_transport failed)");
|
|
3417
|
+
reason = pj_str((char*)"Internal Server Error (set_transport failed)");
|
|
2944
3418
|
pjsip_endpt_respond_stateless(g_sip_endpt, rdata, 500, &reason, NULL, NULL);
|
|
2945
3419
|
return PJ_TRUE;
|
|
2946
3420
|
}
|
|
@@ -2956,7 +3430,7 @@ static pj_bool_t on_rx_request( pjsip_rx_data *rdata ){
|
|
|
2956
3430
|
NULL, NULL, &tdata);
|
|
2957
3431
|
if(status != PJ_SUCCESS) {
|
|
2958
3432
|
close_media_transport(med_transport);
|
|
2959
|
-
reason = pj_str("Internal Server Error (pjsip_inv_initial_answer failed)");
|
|
3433
|
+
reason = pj_str((char*)"Internal Server Error (pjsip_inv_initial_answer failed)");
|
|
2960
3434
|
pjsip_endpt_respond_stateless(g_sip_endpt, rdata, 500, &reason, NULL, NULL);
|
|
2961
3435
|
return PJ_TRUE;
|
|
2962
3436
|
}
|
|
@@ -2965,7 +3439,7 @@ static pj_bool_t on_rx_request( pjsip_rx_data *rdata ){
|
|
|
2965
3439
|
status = pjsip_inv_send_msg(inv, tdata);
|
|
2966
3440
|
if(status != PJ_SUCCESS) {
|
|
2967
3441
|
close_media_transport(med_transport);
|
|
2968
|
-
reason = pj_str("Internal Server Error (pjsip_inv_send_msg failed)");
|
|
3442
|
+
reason = pj_str((char*)"Internal Server Error (pjsip_inv_send_msg failed)");
|
|
2969
3443
|
pjsip_endpt_respond_stateless(g_sip_endpt, rdata, 500, &reason, NULL, NULL);
|
|
2970
3444
|
return PJ_TRUE;
|
|
2971
3445
|
}
|
|
@@ -2974,7 +3448,7 @@ static pj_bool_t on_rx_request( pjsip_rx_data *rdata ){
|
|
|
2974
3448
|
|
|
2975
3449
|
if(status != PJ_SUCCESS) {
|
|
2976
3450
|
close_media_transport(med_transport);
|
|
2977
|
-
reason = pj_str("Internal Server Error (pjsip_rx_data_clone failed)");
|
|
3451
|
+
reason = pj_str((char*)"Internal Server Error (pjsip_rx_data_clone failed)");
|
|
2978
3452
|
pjsip_endpt_respond_stateless(g_sip_endpt, rdata, 500, &reason, NULL, NULL);
|
|
2979
3453
|
return PJ_TRUE;
|
|
2980
3454
|
}
|
|
@@ -2987,7 +3461,7 @@ static pj_bool_t on_rx_request( pjsip_rx_data *rdata ){
|
|
|
2987
3461
|
|
|
2988
3462
|
if(status != PJ_SUCCESS) {
|
|
2989
3463
|
close_media_transport(med_transport);
|
|
2990
|
-
reason = pj_str("Internal Server Error (pjsip_rx_data_clone failed)");
|
|
3464
|
+
reason = pj_str((char*)"Internal Server Error (pjsip_rx_data_clone failed)");
|
|
2991
3465
|
pjsip_endpt_respond_stateless(g_sip_endpt, rdata, 500, &reason, NULL, NULL);
|
|
2992
3466
|
return PJ_TRUE;
|
|
2993
3467
|
}
|
|
@@ -3005,7 +3479,7 @@ static pj_bool_t on_rx_request( pjsip_rx_data *rdata ){
|
|
|
3005
3479
|
status = pjsip_dlg_add_usage(dlg, &mod_tester, call);
|
|
3006
3480
|
if(status != PJ_SUCCESS) {
|
|
3007
3481
|
close_media_transport(med_transport);
|
|
3008
|
-
reason = pj_str("Internal Server Error (pjsip_dlg_add_usage failed)");
|
|
3482
|
+
reason = pj_str((char*)"Internal Server Error (pjsip_dlg_add_usage failed)");
|
|
3009
3483
|
pjsip_endpt_respond_stateless(g_sip_endpt, rdata, 500, &reason, NULL, NULL);
|
|
3010
3484
|
return PJ_TRUE;
|
|
3011
3485
|
}
|
|
@@ -3147,15 +3621,17 @@ static void on_rx_offer(pjsip_inv_session *inv, const pjmedia_sdp_session *offer
|
|
|
3147
3621
|
addon_log(LOG_LEVEL_DEBUG, "on_rx_offer offer=%x\n", offer);
|
|
3148
3622
|
if(g_shutting_down) return;
|
|
3149
3623
|
|
|
3624
|
+
/*
|
|
3150
3625
|
bool is_reinvite = false;
|
|
3151
3626
|
|
|
3152
3627
|
if(inv->state == PJSIP_INV_STATE_CONFIRMED) {
|
|
3153
3628
|
is_reinvite = true;
|
|
3154
3629
|
}
|
|
3630
|
+
*/
|
|
3155
3631
|
|
|
3156
3632
|
char evt[2048];
|
|
3157
3633
|
|
|
3158
|
-
char *type;
|
|
3634
|
+
//char *type;
|
|
3159
3635
|
|
|
3160
3636
|
Call *call = (Call*)inv->dlg->mod_data[mod_tester.id];
|
|
3161
3637
|
|
|
@@ -3194,7 +3670,7 @@ static void on_rx_offer(pjsip_inv_session *inv, const pjmedia_sdp_session *offer
|
|
|
3194
3670
|
call->remote_hold = 0;
|
|
3195
3671
|
}
|
|
3196
3672
|
|
|
3197
|
-
char *mode = get_media_mode_str(remote_mode);
|
|
3673
|
+
//char *mode = get_media_mode_str(remote_mode);
|
|
3198
3674
|
|
|
3199
3675
|
pjmedia_sdp_attr *attr;
|
|
3200
3676
|
|
|
@@ -3208,17 +3684,13 @@ static void on_rx_offer(pjsip_inv_session *inv, const pjmedia_sdp_session *offer
|
|
|
3208
3684
|
// Keep call on-hold by setting 'sendonly' attribute.
|
|
3209
3685
|
// (See RFC 3264 Section 8.4 and RFC 4317 Section 3.1)
|
|
3210
3686
|
if(call->remote_hold) {
|
|
3211
|
-
printf("p1\n");
|
|
3212
3687
|
attr = pjmedia_sdp_attr_create(inv->pool, "inactive", NULL);
|
|
3213
3688
|
} else {
|
|
3214
|
-
printf("p2\n");
|
|
3215
3689
|
attr = pjmedia_sdp_attr_create(inv->pool, "sendonly", NULL);
|
|
3216
3690
|
}
|
|
3217
3691
|
} else if(call->remote_hold) {
|
|
3218
|
-
printf("p3\n");
|
|
3219
3692
|
attr = pjmedia_sdp_attr_create(inv->pool, "recvonly", NULL);
|
|
3220
3693
|
} else {
|
|
3221
|
-
printf("p4\n");
|
|
3222
3694
|
attr = pjmedia_sdp_attr_create(inv->pool, "sendrecv", NULL);
|
|
3223
3695
|
}
|
|
3224
3696
|
pjmedia_sdp_media_add_attr(answer->media[0], attr);
|
|
@@ -3362,7 +3834,7 @@ int pjw_get_codecs(char *out_codecs)
|
|
|
3362
3834
|
goto out;
|
|
3363
3835
|
}
|
|
3364
3836
|
|
|
3365
|
-
for(
|
|
3837
|
+
for(unsigned i=0; i<count; ++i) {
|
|
3366
3838
|
pjmedia_codec_info *info = &codec_info[i];
|
|
3367
3839
|
if(i != 0) oss << " ";
|
|
3368
3840
|
oss.write(info->encoding_name.ptr, info->encoding_name.slen);
|
|
@@ -3385,7 +3857,7 @@ out:
|
|
|
3385
3857
|
int pjw_set_codecs(const char *in_codec_info) {
|
|
3386
3858
|
clear_error();
|
|
3387
3859
|
|
|
3388
|
-
char error[1000];
|
|
3860
|
+
//char error[1000];
|
|
3389
3861
|
pjmedia_codec_mgr *codec_mgr;
|
|
3390
3862
|
pj_status_t status;
|
|
3391
3863
|
char codec_info[1000];
|
|
@@ -3400,7 +3872,7 @@ int pjw_set_codecs(const char *in_codec_info) {
|
|
|
3400
3872
|
goto out;
|
|
3401
3873
|
}
|
|
3402
3874
|
|
|
3403
|
-
codec_id = pj_str("");
|
|
3875
|
+
codec_id = pj_str((char*)"");
|
|
3404
3876
|
status = pjmedia_codec_mgr_set_codec_priority(codec_mgr, &codec_id, 0);
|
|
3405
3877
|
if(status != PJ_SUCCESS) {
|
|
3406
3878
|
set_error("pjmedia_codec_mgr_set_codec_priority(zero all) failed.");
|
|
@@ -3435,7 +3907,7 @@ out:
|
|
|
3435
3907
|
|
|
3436
3908
|
if(pjw_errorstring[0]){
|
|
3437
3909
|
//Try to put default priority to all codecs
|
|
3438
|
-
codec_id = pj_str("");
|
|
3910
|
+
codec_id = pj_str((char*)"");
|
|
3439
3911
|
status = pjmedia_codec_mgr_set_codec_priority(codec_mgr, &codec_id, 128);
|
|
3440
3912
|
return -1;
|
|
3441
3913
|
}
|
|
@@ -3576,7 +4048,13 @@ static void build_stream_stat(ostringstream &oss, pjmedia_rtcp_stat *stat, pjmed
|
|
|
3576
4048
|
{
|
|
3577
4049
|
char temp[200];
|
|
3578
4050
|
char duration[80], last_update[80];
|
|
3579
|
-
|
|
4051
|
+
|
|
4052
|
+
//char bps[16];
|
|
4053
|
+
//char ipbps[16];
|
|
4054
|
+
char packets[16];
|
|
4055
|
+
//char bytes[16];
|
|
4056
|
+
//char ipbytes[16];
|
|
4057
|
+
|
|
3580
4058
|
pj_time_val now;
|
|
3581
4059
|
|
|
3582
4060
|
pj_gettimeofday(&now);
|
|
@@ -3593,7 +4071,7 @@ static void build_stream_stat(ostringstream &oss, pjmedia_rtcp_stat *stat, pjmed
|
|
|
3593
4071
|
oss << duration;
|
|
3594
4072
|
|
|
3595
4073
|
sprintf(temp, ", \"CodecInfo\": \"%.*s/%d/%d\"",
|
|
3596
|
-
stream_info->fmt.encoding_name.slen,
|
|
4074
|
+
(int)stream_info->fmt.encoding_name.slen,
|
|
3597
4075
|
stream_info->fmt.encoding_name.ptr,
|
|
3598
4076
|
stream_info->fmt.clock_rate,
|
|
3599
4077
|
stream_info->fmt.channel_cnt);
|
|
@@ -3922,7 +4400,7 @@ void on_rx_notify(pjsip_evsub *sub, pjsip_rx_data *rdata, int *p_st_code, pj_str
|
|
|
3922
4400
|
|
|
3923
4401
|
static void on_client_refresh( pjsip_evsub *sub ) {
|
|
3924
4402
|
Subscription *subscription;
|
|
3925
|
-
pj_status_t status;
|
|
4403
|
+
//pj_status_t status;
|
|
3926
4404
|
|
|
3927
4405
|
subscription = (Subscription*) pjsip_evsub_get_mod_data(sub, mod_tester.id);
|
|
3928
4406
|
|
|
@@ -3931,7 +4409,7 @@ static void on_client_refresh( pjsip_evsub *sub ) {
|
|
|
3931
4409
|
goto out;
|
|
3932
4410
|
}
|
|
3933
4411
|
|
|
3934
|
-
if(!
|
|
4412
|
+
if(!subscription_subscribe_no_headers(subscription, -1)) {
|
|
3935
4413
|
goto out;
|
|
3936
4414
|
}
|
|
3937
4415
|
|
|
@@ -3962,7 +4440,7 @@ static void client_on_evsub_state( pjsip_evsub *sub, pjsip_event *event) {
|
|
|
3962
4440
|
}
|
|
3963
4441
|
|
|
3964
4442
|
pjsip_generic_string_hdr *refer_sub;
|
|
3965
|
-
const pj_str_t REFER_SUB = { "Refer-Sub", 9 };
|
|
4443
|
+
const pj_str_t REFER_SUB = { (char*)"Refer-Sub", 9 };
|
|
3966
4444
|
ostringstream oss;
|
|
3967
4445
|
|
|
3968
4446
|
// When subscription is accepted (got 200/OK)
|
|
@@ -4004,7 +4482,7 @@ static void client_on_evsub_state( pjsip_evsub *sub, pjsip_event *event) {
|
|
|
4004
4482
|
|
|
4005
4483
|
rdata = event->body.tsx_state.src.rdata;
|
|
4006
4484
|
|
|
4007
|
-
Transport *t;
|
|
4485
|
+
//Transport *t;
|
|
4008
4486
|
//build_basic_request_info(&oss, rdata, &t);
|
|
4009
4487
|
|
|
4010
4488
|
long subscription_id;
|
|
@@ -4041,8 +4519,8 @@ static void client_on_evsub_state( pjsip_evsub *sub, pjsip_event *event) {
|
|
|
4041
4519
|
static void server_on_evsub_state( pjsip_evsub *sub, pjsip_event *event)
|
|
4042
4520
|
{
|
|
4043
4521
|
Subscriber *s;
|
|
4044
|
-
pj_status_t status;
|
|
4045
|
-
pjsip_tx_data *tdata;
|
|
4522
|
+
//pj_status_t status;
|
|
4523
|
+
//pjsip_tx_data *tdata;
|
|
4046
4524
|
|
|
4047
4525
|
//addon_log(LOG_LEVEL_DEBUG, "server_on_evsub_state\n");
|
|
4048
4526
|
if(!sub) {
|
|
@@ -4084,7 +4562,7 @@ static void server_on_evsub_rx_refresh(pjsip_evsub *sub, pjsip_rx_data *rdata, i
|
|
|
4084
4562
|
|
|
4085
4563
|
ostringstream oss;
|
|
4086
4564
|
Subscriber *s;
|
|
4087
|
-
Transport *t;
|
|
4565
|
+
//Transport *t;
|
|
4088
4566
|
|
|
4089
4567
|
if(g_shutting_down) return;
|
|
4090
4568
|
addon_log(LOG_LEVEL_DEBUG, "server_on_evsub_rx_refresh\n");
|
|
@@ -4099,7 +4577,7 @@ static void server_on_evsub_rx_refresh(pjsip_evsub *sub, pjsip_rx_data *rdata, i
|
|
|
4099
4577
|
dispatch_event(evt);
|
|
4100
4578
|
|
|
4101
4579
|
if( pjsip_evsub_get_state(sub) == PJSIP_EVSUB_STATE_TERMINATED) {
|
|
4102
|
-
pj_str_t reason = { "noresource", 10 };
|
|
4580
|
+
pj_str_t reason = { (char*)"noresource", 10 };
|
|
4103
4581
|
status = pjsip_evsub_notify(sub,
|
|
4104
4582
|
PJSIP_EVSUB_STATE_TERMINATED,
|
|
4105
4583
|
NULL,
|
|
@@ -4140,17 +4618,17 @@ void process_in_dialog_refer(pjsip_dialog *dlg, pjsip_rx_data *rdata)
|
|
|
4140
4618
|
char evt[2048];
|
|
4141
4619
|
|
|
4142
4620
|
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 };
|
|
4621
|
+
//pjsip_tx_data *tdata;
|
|
4622
|
+
//int new_call;
|
|
4623
|
+
const pj_str_t str_refer_to = { (char*)"Refer-To", 8};
|
|
4624
|
+
const pj_str_t str_refer_sub = { (char*)"Refer-Sub", 9 };
|
|
4625
|
+
//const pj_str_t str_ref_by = { (char*)"Referred-By", 11 };
|
|
4148
4626
|
pjsip_generic_string_hdr *refer_to;
|
|
4149
4627
|
pjsip_generic_string_hdr *refer_sub;
|
|
4150
|
-
pjsip_hdr *ref_by_hdr;
|
|
4628
|
+
//pjsip_hdr *ref_by_hdr;
|
|
4151
4629
|
pj_bool_t no_refer_sub = PJ_FALSE;
|
|
4152
|
-
char *uri;
|
|
4153
|
-
pj_str_t tmp;
|
|
4630
|
+
//char *uri;
|
|
4631
|
+
//pj_str_t tmp;
|
|
4154
4632
|
pjsip_status_code code;
|
|
4155
4633
|
pjsip_evsub *sub;
|
|
4156
4634
|
|
|
@@ -4177,13 +4655,14 @@ void process_in_dialog_refer(pjsip_dialog *dlg, pjsip_rx_data *rdata)
|
|
|
4177
4655
|
/* Find optional Referred-By header (to be copied onto outgoing INVITE
|
|
4178
4656
|
* request.
|
|
4179
4657
|
*/
|
|
4658
|
+
/*
|
|
4180
4659
|
ref_by_hdr = (pjsip_hdr*)
|
|
4181
4660
|
pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &str_ref_by,
|
|
4182
4661
|
NULL);
|
|
4183
|
-
|
|
4184
|
-
if(ref_by_hdr) {
|
|
4662
|
+
*/
|
|
4663
|
+
/* if(ref_by_hdr) {
|
|
4185
4664
|
pjsip_generic_string_hdr *referred_by = (pjsip_generic_string_hdr*)ref_by_hdr;
|
|
4186
|
-
}
|
|
4665
|
+
} */
|
|
4187
4666
|
|
|
4188
4667
|
/* Find optional Refer-Sub header */
|
|
4189
4668
|
refer_sub = (pjsip_generic_string_hdr*)
|
|
@@ -4206,7 +4685,7 @@ void process_in_dialog_refer(pjsip_dialog *dlg, pjsip_rx_data *rdata)
|
|
|
4206
4685
|
* Always answer with 2xx.
|
|
4207
4686
|
*/
|
|
4208
4687
|
pjsip_tx_data *tdata;
|
|
4209
|
-
const pj_str_t str_false = { "false", 5};
|
|
4688
|
+
const pj_str_t str_false = { (char*)"false", 5};
|
|
4210
4689
|
pjsip_hdr *hdr;
|
|
4211
4690
|
|
|
4212
4691
|
status = pjsip_dlg_create_response(dlg, rdata, code, NULL,
|
|
@@ -4260,7 +4739,7 @@ void process_in_dialog_refer(pjsip_dialog *dlg, pjsip_rx_data *rdata)
|
|
|
4260
4739
|
* Refer-Sub in the response with value "true" too.
|
|
4261
4740
|
*/
|
|
4262
4741
|
if (refer_sub) {
|
|
4263
|
-
const pj_str_t str_true = { "true", 4 };
|
|
4742
|
+
const pj_str_t str_true = { (char*)"true", 4 };
|
|
4264
4743
|
pjsip_hdr *hdr;
|
|
4265
4744
|
|
|
4266
4745
|
hdr = (pjsip_hdr*)
|
|
@@ -4324,7 +4803,7 @@ static void on_tsx_state_changed(pjsip_inv_session *inv,
|
|
|
4324
4803
|
}
|
|
4325
4804
|
|
|
4326
4805
|
//ostringstream oss;
|
|
4327
|
-
Transport *t;
|
|
4806
|
+
//Transport *t;
|
|
4328
4807
|
if (tsx->role==PJSIP_ROLE_UAS &&
|
|
4329
4808
|
tsx->state==PJSIP_TSX_STATE_TRYING) {
|
|
4330
4809
|
if(pjsip_method_cmp(&tsx->method, pjsip_get_refer_method())==0) {
|
|
@@ -4342,15 +4821,16 @@ static void on_tsx_state_changed(pjsip_inv_session *inv,
|
|
|
4342
4821
|
}
|
|
4343
4822
|
}
|
|
4344
4823
|
|
|
4345
|
-
int pjw_call_refer(long call_id, const char *dest_uri, const char *additional_headers, long *out_subscription_id)
|
|
4824
|
+
//int pjw_call_refer(long call_id, const char *dest_uri, const char *additional_headers, long *out_subscription_id)
|
|
4825
|
+
int pjw_call_refer(long call_id, const char *json, long *out_subscription_id)
|
|
4346
4826
|
{
|
|
4347
4827
|
PJW_LOCK();
|
|
4348
4828
|
clear_error();
|
|
4349
4829
|
|
|
4350
|
-
|
|
4830
|
+
char *dest_uri;
|
|
4831
|
+
|
|
4351
4832
|
long val;
|
|
4352
4833
|
Call *call;
|
|
4353
|
-
Subscription *s;
|
|
4354
4834
|
pj_str_t s_dest_uri;
|
|
4355
4835
|
|
|
4356
4836
|
long subscription_id;
|
|
@@ -4359,17 +4839,23 @@ int pjw_call_refer(long call_id, const char *dest_uri, const char *additional_he
|
|
|
4359
4839
|
pjsip_tx_data *tdata;
|
|
4360
4840
|
pj_status_t status;
|
|
4361
4841
|
|
|
4842
|
+
char buffer[MAX_JSON_INPUT];
|
|
4843
|
+
|
|
4844
|
+
Document document;
|
|
4845
|
+
|
|
4362
4846
|
if(!g_call_ids.get(call_id, val)){
|
|
4363
4847
|
set_error("Invalid call_id");
|
|
4364
4848
|
goto out;
|
|
4365
4849
|
}
|
|
4366
|
-
|
|
4367
4850
|
call = (Call*)val;
|
|
4368
4851
|
|
|
4369
|
-
|
|
4370
|
-
|
|
4371
|
-
|
|
4372
|
-
|
|
4852
|
+
if(!parse_json(document, json, buffer, MAX_JSON_INPUT)) {
|
|
4853
|
+
goto out;
|
|
4854
|
+
}
|
|
4855
|
+
|
|
4856
|
+
if(!json_get_and_check_uri(document, "dest_uri", false, &dest_uri)) {
|
|
4857
|
+
goto out;
|
|
4858
|
+
}
|
|
4373
4859
|
|
|
4374
4860
|
pj_bzero(&xfer_cb, sizeof(xfer_cb));
|
|
4375
4861
|
xfer_cb.on_evsub_state = &client_on_evsub_state;
|
|
@@ -4377,30 +4863,30 @@ int pjw_call_refer(long call_id, const char *dest_uri, const char *additional_he
|
|
|
4377
4863
|
|
|
4378
4864
|
status = pjsip_xfer_create_uac(call->inv->dlg, &xfer_cb, &sub);
|
|
4379
4865
|
if(status != PJ_SUCCESS) {
|
|
4380
|
-
set_error("pjsip_xfer_create_uac failed");
|
|
4866
|
+
set_error("pjsip_xfer_create_uac failed with status=%i", status);
|
|
4381
4867
|
goto out;
|
|
4382
4868
|
}
|
|
4383
4869
|
|
|
4384
4870
|
s_dest_uri = pj_str((char*)dest_uri);
|
|
4385
4871
|
status = pjsip_xfer_initiate(sub, &s_dest_uri, &tdata);
|
|
4386
4872
|
|
|
4387
|
-
if(!
|
|
4873
|
+
if(!add_headers(call->inv->dlg->pool, tdata, document)) {
|
|
4388
4874
|
goto out;
|
|
4389
4875
|
}
|
|
4390
4876
|
|
|
4391
4877
|
status = pjsip_xfer_send_request(sub, tdata);
|
|
4392
4878
|
if(status != PJ_SUCCESS) {
|
|
4393
|
-
set_error("pjsip_xfer_send_request failed");
|
|
4879
|
+
set_error("pjsip_xfer_send_request failed with status=%i", status);
|
|
4394
4880
|
goto out;
|
|
4395
4881
|
}
|
|
4396
4882
|
|
|
4883
|
+
*out_subscription_id = subscription_id;
|
|
4884
|
+
|
|
4397
4885
|
out:
|
|
4398
4886
|
PJW_UNLOCK();
|
|
4399
|
-
|
|
4400
4887
|
if(pjw_errorstring[0]) {
|
|
4401
4888
|
return -1;
|
|
4402
4889
|
}
|
|
4403
|
-
*out_subscription_id = subscription_id;
|
|
4404
4890
|
return 0;
|
|
4405
4891
|
}
|
|
4406
4892
|
|
|
@@ -4437,7 +4923,7 @@ int pjw_call_get_info(long call_id, const char *required_info, char *out_info)
|
|
|
4437
4923
|
}
|
|
4438
4924
|
pj_str_t str_addr = pj_str( inet_ntoa( (in_addr&)session_info.rem_addr.ipv4.sin_addr.s_addr ) );
|
|
4439
4925
|
pj_uint16_t port = session_info.rem_addr.ipv4.sin_port;
|
|
4440
|
-
sprintf(info, "%.*s:%u", str_addr.slen, str_addr.ptr, ntohs(port));
|
|
4926
|
+
sprintf(info, "%.*s:%u", (int)str_addr.slen, str_addr.ptr, ntohs(port));
|
|
4441
4927
|
} else {
|
|
4442
4928
|
PJW_UNLOCK();
|
|
4443
4929
|
set_error("Unsupported info");
|
|
@@ -4449,9 +4935,9 @@ int pjw_call_get_info(long call_id, const char *required_info, char *out_info)
|
|
|
4449
4935
|
return 0;
|
|
4450
4936
|
}
|
|
4451
4937
|
|
|
4452
|
-
bool notify(pjsip_evsub *evsub, const char *content_type, const char *body, int subscription_state, const char *reason,
|
|
4453
|
-
pj_str_t s_content_type;
|
|
4454
|
-
pj_str_t s_body;
|
|
4938
|
+
bool notify(pjsip_evsub *evsub, const char *content_type, const char *body, int subscription_state, const char *reason, Document &document) {
|
|
4939
|
+
//pj_str_t s_content_type;
|
|
4940
|
+
//pj_str_t s_body;
|
|
4455
4941
|
pj_str_t s_reason;
|
|
4456
4942
|
|
|
4457
4943
|
char *temp;
|
|
@@ -4464,9 +4950,9 @@ bool notify(pjsip_evsub *evsub, const char *content_type, const char *body, int
|
|
|
4464
4950
|
char *content_type_buffer;
|
|
4465
4951
|
pj_str_t s_content_type_type;
|
|
4466
4952
|
pj_str_t s_content_type_subtype;
|
|
4467
|
-
pj_str_t s_content_type_param;
|
|
4953
|
+
//pj_str_t s_content_type_param;
|
|
4468
4954
|
|
|
4469
|
-
char *blank_string;
|
|
4955
|
+
//char *blank_string;
|
|
4470
4956
|
|
|
4471
4957
|
pjsip_tx_data *tdata;
|
|
4472
4958
|
pj_status_t status;
|
|
@@ -4503,7 +4989,9 @@ bool notify(pjsip_evsub *evsub, const char *content_type, const char *body, int
|
|
|
4503
4989
|
}
|
|
4504
4990
|
s_content_type_subtype = pj_str(tok);
|
|
4505
4991
|
|
|
4506
|
-
|
|
4992
|
+
if(!add_headers(tdata->pool, tdata, document)) {
|
|
4993
|
+
return false;
|
|
4994
|
+
}
|
|
4507
4995
|
|
|
4508
4996
|
msg_body->content_type.type = s_content_type_type;
|
|
4509
4997
|
msg_body->content_type.subtype = s_content_type_subtype;
|
|
@@ -4524,22 +5012,29 @@ bool notify(pjsip_evsub *evsub, const char *content_type, const char *body, int
|
|
|
4524
5012
|
return true;
|
|
4525
5013
|
}
|
|
4526
5014
|
|
|
4527
|
-
int pjw_notify(long subscriber_id, const char *content_type, const char *body, int subscription_state, const char *reason, const char *additional_headers)
|
|
5015
|
+
//int pjw_notify(long subscriber_id, const char *content_type, const char *body, int subscription_state, const char *reason, const char *additional_headers)
|
|
5016
|
+
int pjw_notify(long subscriber_id, const char *json)
|
|
4528
5017
|
{
|
|
4529
5018
|
PJW_LOCK();
|
|
4530
|
-
|
|
4531
5019
|
clear_error();
|
|
4532
5020
|
|
|
4533
|
-
|
|
5021
|
+
char *content_type = NULL;
|
|
5022
|
+
char *body = NULL;
|
|
5023
|
+
int subscription_state;
|
|
5024
|
+
char *reason = NULL;
|
|
5025
|
+
|
|
4534
5026
|
long val;
|
|
4535
5027
|
|
|
4536
5028
|
Subscriber *subscriber;
|
|
4537
5029
|
|
|
5030
|
+
char buffer[MAX_JSON_INPUT];
|
|
5031
|
+
|
|
5032
|
+
Document document;
|
|
5033
|
+
|
|
4538
5034
|
if(!g_subscriber_ids.get(subscriber_id, val)){
|
|
4539
5035
|
set_error("Invalid subscriber_id");
|
|
4540
5036
|
goto out;
|
|
4541
5037
|
}
|
|
4542
|
-
|
|
4543
5038
|
subscriber = (Subscriber*)val;
|
|
4544
5039
|
|
|
4545
5040
|
if(subscriber->created_by_refer) {
|
|
@@ -4547,40 +5042,63 @@ int pjw_notify(long subscriber_id, const char *content_type, const char *body, i
|
|
|
4547
5042
|
goto out;
|
|
4548
5043
|
}
|
|
4549
5044
|
|
|
4550
|
-
|
|
5045
|
+
if(!parse_json(document, json, buffer, MAX_JSON_INPUT)) {
|
|
5046
|
+
goto out;
|
|
5047
|
+
}
|
|
5048
|
+
|
|
5049
|
+
if(!json_get_string_param(document, "content_type", false, &content_type)) {
|
|
5050
|
+
goto out;
|
|
5051
|
+
}
|
|
5052
|
+
|
|
5053
|
+
if(!json_get_string_param(document, "body", false, &body)) {
|
|
5054
|
+
goto out;
|
|
5055
|
+
}
|
|
5056
|
+
|
|
5057
|
+
if(!json_get_int_param(document, "subscription_state", false, &subscription_state)) {
|
|
5058
|
+
goto out;
|
|
5059
|
+
}
|
|
5060
|
+
|
|
5061
|
+
if(!json_get_string_param(document, "reason", true, &reason)) {
|
|
5062
|
+
goto out;
|
|
5063
|
+
}
|
|
5064
|
+
|
|
5065
|
+
if(!notify(subscriber->evsub, content_type, body, subscription_state, reason, document)){
|
|
4551
5066
|
goto out;
|
|
4552
5067
|
}
|
|
4553
5068
|
|
|
4554
5069
|
out:
|
|
4555
5070
|
PJW_UNLOCK();
|
|
4556
|
-
|
|
4557
5071
|
if(pjw_errorstring[0]) {
|
|
4558
5072
|
return -1;
|
|
4559
5073
|
}
|
|
4560
|
-
|
|
4561
5074
|
return 0;
|
|
4562
5075
|
}
|
|
4563
5076
|
|
|
4564
5077
|
|
|
4565
|
-
int pjw_notify_xfer(long subscriber_id, int subscription_state, int xfer_status_code, const char *xfer_status_text) {
|
|
5078
|
+
//int pjw_notify_xfer(long subscriber_id, int subscription_state, int xfer_status_code, const char *xfer_status_text) {
|
|
5079
|
+
int pjw_notify_xfer(long subscriber_id, const char *json) {
|
|
4566
5080
|
PJW_LOCK();
|
|
4567
|
-
|
|
4568
5081
|
clear_error();
|
|
4569
5082
|
|
|
4570
|
-
int n;
|
|
4571
5083
|
pjsip_tx_data *tdata;
|
|
4572
5084
|
pj_status_t status;
|
|
4573
5085
|
|
|
5086
|
+
int subscription_state;
|
|
5087
|
+
int code;
|
|
5088
|
+
char *reason;
|
|
5089
|
+
|
|
4574
5090
|
long val;
|
|
4575
5091
|
|
|
4576
5092
|
Subscriber *subscriber;
|
|
4577
|
-
pj_str_t
|
|
5093
|
+
pj_str_t r;
|
|
5094
|
+
|
|
5095
|
+
char buffer[MAX_JSON_INPUT];
|
|
4578
5096
|
|
|
5097
|
+
Document document;
|
|
4579
5098
|
if(!g_subscriber_ids.get(subscriber_id, val)){
|
|
4580
5099
|
set_error("Invalid subscriber_id");
|
|
4581
5100
|
goto out;
|
|
4582
5101
|
}
|
|
4583
|
-
|
|
4584
5102
|
subscriber = (Subscriber*)val;
|
|
4585
5103
|
|
|
4586
5104
|
if(!subscriber->created_by_refer) {
|
|
@@ -4588,23 +5106,39 @@ int pjw_notify_xfer(long subscriber_id, int subscription_state, int xfer_status_
|
|
|
4588
5106
|
goto out;
|
|
4589
5107
|
}
|
|
4590
5108
|
|
|
4591
|
-
|
|
5109
|
+
if(!parse_json(document, json, buffer, MAX_JSON_INPUT)) {
|
|
5110
|
+
goto out;
|
|
5111
|
+
}
|
|
4592
5112
|
|
|
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
|
-
}
|
|
5113
|
+
if(!json_get_int_param(document, "subscription_state", false, &subscription_state)) {
|
|
5114
|
+
goto out;
|
|
5115
|
+
}
|
|
4602
5116
|
|
|
4603
|
-
|
|
4604
|
-
|
|
4605
|
-
|
|
4606
|
-
|
|
4607
|
-
|
|
5117
|
+
if(!json_get_int_param(document, "code", false, &code)) {
|
|
5118
|
+
goto out;
|
|
5119
|
+
}
|
|
5120
|
+
|
|
5121
|
+
if(!json_get_string_param(document, "reason", false, &reason)) {
|
|
5122
|
+
goto out;
|
|
5123
|
+
}
|
|
5124
|
+
|
|
5125
|
+
r = pj_str((char*)reason);
|
|
5126
|
+
|
|
5127
|
+
status = pjsip_xfer_notify( subscriber->evsub,
|
|
5128
|
+
(pjsip_evsub_state)subscription_state,
|
|
5129
|
+
code,
|
|
5130
|
+
&r,
|
|
5131
|
+
&tdata);
|
|
5132
|
+
if (status != PJ_SUCCESS) {
|
|
5133
|
+
set_error( "pjsip_xfer_notify failed with status=%i", status);
|
|
5134
|
+
goto out;
|
|
5135
|
+
}
|
|
5136
|
+
|
|
5137
|
+
status = pjsip_xfer_send_request( subscriber->evsub, tdata);
|
|
5138
|
+
if (status != PJ_SUCCESS) {
|
|
5139
|
+
set_error("pjsip_xfer_send_request failed with status=%i", status);
|
|
5140
|
+
goto out;
|
|
5141
|
+
}
|
|
4608
5142
|
|
|
4609
5143
|
out:
|
|
4610
5144
|
PJW_UNLOCK();
|
|
@@ -4616,6 +5150,7 @@ out:
|
|
|
4616
5150
|
return 0;
|
|
4617
5151
|
}
|
|
4618
5152
|
|
|
5153
|
+
/*
|
|
4619
5154
|
pj_bool_t add_additional_headers(pj_pool_t *pool, pjsip_tx_data *tdata, const char *additional_headers) {
|
|
4620
5155
|
|
|
4621
5156
|
if(additional_headers && additional_headers[0]){
|
|
@@ -4652,94 +5187,133 @@ pj_bool_t add_additional_headers(pj_pool_t *pool, pjsip_tx_data *tdata, const ch
|
|
|
4652
5187
|
}
|
|
4653
5188
|
return PJ_TRUE;
|
|
4654
5189
|
}
|
|
5190
|
+
*/
|
|
4655
5191
|
|
|
4656
|
-
pj_bool_t add_additional_headers_for_account(pjsip_regc *regc, const char *additional_headers) {
|
|
4657
5192
|
|
|
4658
|
-
|
|
4659
|
-
|
|
4660
|
-
|
|
5193
|
+
pj_bool_t add_headers(pj_pool_t *pool, pjsip_tx_data *tdata, Document &document) {
|
|
5194
|
+
if(!document.HasMember("headers")) {
|
|
5195
|
+
return PJ_TRUE;
|
|
5196
|
+
}
|
|
4661
5197
|
|
|
4662
|
-
|
|
4663
|
-
|
|
4664
|
-
|
|
5198
|
+
if(!document["headers"].IsObject()) {
|
|
5199
|
+
set_error("Parameter headers must be an object");
|
|
5200
|
+
return PJ_FALSE;
|
|
5201
|
+
}
|
|
4665
5202
|
|
|
4666
|
-
|
|
4667
|
-
strcpy(buf,additional_headers);
|
|
4668
|
-
char *saved;
|
|
4669
|
-
char *token = strtok_r(buf, "\n", &saved);
|
|
4670
|
-
while(token){
|
|
4671
|
-
char *name = strtok(token, ":");
|
|
4672
|
-
char *value = strtok(NULL, "\n");
|
|
4673
|
-
//addon_log(LOG_LEVEL_DEBUG, "Adding %s:%s\n", name, value);
|
|
5203
|
+
Value headers = document["headers"].GetObject();
|
|
4674
5204
|
|
|
4675
|
-
|
|
4676
|
-
|
|
4677
|
-
return PJ_FALSE;
|
|
4678
|
-
}
|
|
5205
|
+
for (Value::ConstMemberIterator itr = headers.MemberBegin(); itr != headers.MemberEnd(); ++itr) {
|
|
5206
|
+
printf("%s => '%s'\n", itr->name.GetString(), itr->value.GetString());
|
|
4679
5207
|
|
|
4680
|
-
|
|
4681
|
-
|
|
4682
|
-
|
|
4683
|
-
|
|
4684
|
-
|
|
4685
|
-
NULL);
|
|
5208
|
+
const char *name = itr->name.GetString();
|
|
5209
|
+
if(!itr->value.IsString()) {
|
|
5210
|
+
set_error("Parameter headers key '%s' found with non-string value", name);
|
|
5211
|
+
return PJ_FALSE;
|
|
5212
|
+
}
|
|
4686
5213
|
|
|
4687
|
-
|
|
4688
|
-
|
|
4689
|
-
|
|
4690
|
-
|
|
4691
|
-
|
|
4692
|
-
|
|
4693
|
-
|
|
4694
|
-
|
|
4695
|
-
|
|
4696
|
-
|
|
5214
|
+
const char *value = itr->value.GetString();
|
|
5215
|
+
|
|
5216
|
+
pj_str_t hname = pj_str((char*)name);
|
|
5217
|
+
pjsip_hdr *hdr = (pjsip_hdr*)pjsip_parse_hdr(pool,
|
|
5218
|
+
&hname,
|
|
5219
|
+
(char*)value,
|
|
5220
|
+
strlen(value),
|
|
5221
|
+
NULL);
|
|
5222
|
+
|
|
5223
|
+
if(!hdr) {
|
|
5224
|
+
set_error("Failed to parse header '%s' => '%s'", name, value);
|
|
5225
|
+
return PJ_FALSE;
|
|
5226
|
+
}
|
|
5227
|
+
pjsip_hdr *clone_hdr = (pjsip_hdr*) pjsip_hdr_clone(pool, hdr);
|
|
5228
|
+
pjsip_msg_add_hdr(tdata->msg, clone_hdr);
|
|
5229
|
+
}
|
|
4697
5230
|
return PJ_TRUE;
|
|
4698
5231
|
}
|
|
4699
5232
|
|
|
4700
|
-
pj_bool_t
|
|
5233
|
+
pj_bool_t add_headers_for_account(pjsip_regc *regc, Document &document) {
|
|
5234
|
+
pjsip_hdr hdr_list;
|
|
5235
|
+
pj_list_init(&hdr_list);
|
|
4701
5236
|
|
|
4702
|
-
|
|
4703
|
-
|
|
4704
|
-
|
|
4705
|
-
}
|
|
5237
|
+
char pool_buf[4096];
|
|
5238
|
+
pj_pool_t *pool;
|
|
5239
|
+
pool = pj_pool_create_on_buf(NULL, pool_buf, sizeof(pool_buf));
|
|
4706
5240
|
|
|
4707
|
-
|
|
4708
|
-
|
|
4709
|
-
|
|
4710
|
-
char *token = strtok_r(buf, "\n", &saved);
|
|
4711
|
-
while(token){
|
|
4712
|
-
char *name = strtok(token, ":");
|
|
4713
|
-
char *value = strtok(NULL, " ");
|
|
4714
|
-
addon_log(LOG_LEVEL_DEBUG, "Checking %s: %s\n", name, value);
|
|
4715
|
-
|
|
4716
|
-
if(!name || !value) {
|
|
4717
|
-
set_error("Invalid additional_header");
|
|
4718
|
-
return PJ_FALSE;
|
|
4719
|
-
}
|
|
5241
|
+
if(!document.HasMember("headers")) {
|
|
5242
|
+
return PJ_TRUE;
|
|
5243
|
+
}
|
|
4720
5244
|
|
|
4721
|
-
|
|
4722
|
-
|
|
4723
|
-
|
|
4724
|
-
|
|
4725
|
-
return PJ_FALSE;
|
|
4726
|
-
}
|
|
4727
|
-
|
|
4728
|
-
char *token_subtype = strtok(NULL, "\n");
|
|
4729
|
-
if(!token_subtype) {
|
|
4730
|
-
set_error("No subtype specified in header Content-Type");
|
|
4731
|
-
return PJ_FALSE;
|
|
4732
|
-
}
|
|
5245
|
+
if(!document["headers"].IsObject()) {
|
|
5246
|
+
set_error("Parameter headers must be an object");
|
|
5247
|
+
return PJ_FALSE;
|
|
5248
|
+
}
|
|
4733
5249
|
|
|
4734
|
-
|
|
4735
|
-
|
|
4736
|
-
|
|
4737
|
-
|
|
4738
|
-
|
|
4739
|
-
|
|
5250
|
+
Value headers = document["headers"].GetObject();
|
|
5251
|
+
|
|
5252
|
+
for (Value::ConstMemberIterator itr = headers.MemberBegin(); itr != headers.MemberEnd(); ++itr) {
|
|
5253
|
+
printf("%s => '%s'\n", itr->name.GetString(), itr->value.GetString());
|
|
5254
|
+
|
|
5255
|
+
const char *name = itr->name.GetString();
|
|
5256
|
+
if(!itr->value.IsString()) {
|
|
5257
|
+
set_error("Parameter headers key '%s' found with non-string value", name);
|
|
5258
|
+
return PJ_FALSE;
|
|
5259
|
+
}
|
|
5260
|
+
|
|
5261
|
+
const char *value = itr->value.GetString();
|
|
5262
|
+
|
|
5263
|
+
pj_str_t hname = pj_str((char*)name);
|
|
5264
|
+
pjsip_hdr *hdr = (pjsip_hdr*)pjsip_parse_hdr(pool,
|
|
5265
|
+
&hname,
|
|
5266
|
+
(char*)value,
|
|
5267
|
+
strlen(value),
|
|
5268
|
+
NULL);
|
|
5269
|
+
|
|
5270
|
+
if(!hdr) {
|
|
5271
|
+
set_error("Failed to parse header %s", name);
|
|
5272
|
+
return PJ_FALSE;
|
|
5273
|
+
}
|
|
5274
|
+
|
|
5275
|
+
pj_list_push_back(&hdr_list, hdr);
|
|
4740
5276
|
}
|
|
4741
|
-
|
|
4742
|
-
|
|
5277
|
+
|
|
5278
|
+
pjsip_regc_add_headers(regc, &hdr_list);
|
|
5279
|
+
return PJ_TRUE;
|
|
5280
|
+
}
|
|
5281
|
+
|
|
5282
|
+
pj_bool_t get_content_type_and_subtype_from_headers(Document &document, char *type, char *subtype) {
|
|
5283
|
+
if(!document.HasMember("headers")) {
|
|
5284
|
+
set_error("Parameter headers absent");
|
|
5285
|
+
return PJ_FALSE;
|
|
5286
|
+
}
|
|
5287
|
+
|
|
5288
|
+
if(!document["headers"].IsObject()) {
|
|
5289
|
+
set_error("Parameter headers must be an object");
|
|
5290
|
+
return PJ_FALSE;
|
|
5291
|
+
}
|
|
5292
|
+
|
|
5293
|
+
Value headers = document["headers"].GetObject();
|
|
5294
|
+
|
|
5295
|
+
if(!headers.HasMember("Content-Type")) {
|
|
5296
|
+
set_error("Parameter headers doesn't contain key Content-Type");
|
|
5297
|
+
return PJ_FALSE;
|
|
5298
|
+
}
|
|
5299
|
+
|
|
5300
|
+
const char *content_type = headers["Content-Type"].GetString();
|
|
5301
|
+
|
|
5302
|
+
const char *slash;
|
|
5303
|
+
int index;
|
|
5304
|
+
|
|
5305
|
+
slash = strchr(content_type, '/');
|
|
5306
|
+
if(!slash) {
|
|
5307
|
+
set_error("Invalid header Content-Type");
|
|
5308
|
+
return PJ_FALSE;
|
|
5309
|
+
}
|
|
5310
|
+
|
|
5311
|
+
index = (int)(slash - content_type);
|
|
5312
|
+
|
|
5313
|
+
strncpy(type, content_type, index-1);
|
|
5314
|
+
strcpy(subtype, content_type+index);
|
|
5315
|
+
addon_log(LOG_LEVEL_DEBUG, "Checking parsing of Content-Type. type=%s: subtype=%s\n", type, subtype);
|
|
5316
|
+
return PJ_TRUE;
|
|
4743
5317
|
}
|
|
4744
5318
|
|
|
4745
5319
|
|
|
@@ -4765,7 +5339,7 @@ int pjw_register_pkg(const char *event, const char *accept) {
|
|
|
4765
5339
|
|
|
4766
5340
|
clear_error();
|
|
4767
5341
|
|
|
4768
|
-
int n;
|
|
5342
|
+
//int n;
|
|
4769
5343
|
|
|
4770
5344
|
if(!register_pkg(event, accept)) {
|
|
4771
5345
|
goto out;
|
|
@@ -4780,12 +5354,23 @@ out:
|
|
|
4780
5354
|
return 0;
|
|
4781
5355
|
}
|
|
4782
5356
|
|
|
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) {
|
|
5357
|
+
//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) {
|
|
5358
|
+
int pjw_subscription_create(long transport_id, const char *json, long *out_subscription_id) {
|
|
4784
5359
|
PJW_LOCK();
|
|
4785
|
-
|
|
4786
5360
|
clear_error();
|
|
4787
5361
|
|
|
4788
|
-
|
|
5362
|
+
char *event = NULL;
|
|
5363
|
+
char *accept = NULL;
|
|
5364
|
+
|
|
5365
|
+
char *from_uri = NULL;
|
|
5366
|
+
char *to_uri = NULL;
|
|
5367
|
+
char *request_uri = NULL;
|
|
5368
|
+
char *proxy_uri = NULL;
|
|
5369
|
+
|
|
5370
|
+
char *realm = NULL;
|
|
5371
|
+
char *username = NULL;
|
|
5372
|
+
char *password = NULL;
|
|
5373
|
+
|
|
4789
5374
|
long subscription_id;
|
|
4790
5375
|
Subscription *subscription;
|
|
4791
5376
|
Transport *t;
|
|
@@ -4793,7 +5378,7 @@ int pjw_subscription_create(long transport_id, const char *event, const char *ac
|
|
|
4793
5378
|
const char *contact_username = "sip";
|
|
4794
5379
|
|
|
4795
5380
|
char local_contact[400];
|
|
4796
|
-
char *start;
|
|
5381
|
+
//char *start;
|
|
4797
5382
|
|
|
4798
5383
|
pjsip_dialog *dlg = NULL;
|
|
4799
5384
|
pjsip_evsub *evsub = NULL;
|
|
@@ -4803,38 +5388,80 @@ int pjw_subscription_create(long transport_id, const char *event, const char *ac
|
|
|
4803
5388
|
|
|
4804
5389
|
pj_status_t status;
|
|
4805
5390
|
|
|
5391
|
+
char buffer[MAX_JSON_INPUT];
|
|
5392
|
+
|
|
5393
|
+
Document document;
|
|
5394
|
+
|
|
4806
5395
|
if(!g_transport_ids.get(transport_id, val)){
|
|
4807
5396
|
set_error("Invalid transport_id");
|
|
4808
5397
|
goto out;
|
|
4809
5398
|
}
|
|
4810
5399
|
t = (Transport*)val;
|
|
4811
5400
|
|
|
4812
|
-
|
|
4813
|
-
|
|
4814
|
-
|
|
4815
|
-
}
|
|
5401
|
+
if(!parse_json(document, json, buffer, MAX_JSON_INPUT)) {
|
|
5402
|
+
goto out;
|
|
5403
|
+
}
|
|
4816
5404
|
|
|
4817
|
-
|
|
4818
|
-
|
|
4819
|
-
|
|
4820
|
-
|
|
5405
|
+
if(!json_get_string_param(document, "event", false, &event)) {
|
|
5406
|
+
goto out;
|
|
5407
|
+
}
|
|
5408
|
+
|
|
5409
|
+
if(!json_get_string_param(document, "accept", false, &accept)) {
|
|
5410
|
+
goto out;
|
|
5411
|
+
}
|
|
5412
|
+
|
|
5413
|
+
if(!json_get_and_check_uri(document, "from_uri", false, &from_uri)) {
|
|
5414
|
+
goto out;
|
|
5415
|
+
}
|
|
5416
|
+
|
|
5417
|
+
if(!json_get_and_check_uri(document, "to_uri", false, &to_uri)) {
|
|
5418
|
+
goto out;
|
|
5419
|
+
}
|
|
4821
5420
|
|
|
4822
|
-
|
|
4823
|
-
|
|
4824
|
-
|
|
5421
|
+
request_uri = to_uri;
|
|
5422
|
+
if(!json_get_and_check_uri(document, "request_uri", true, &request_uri)) {
|
|
5423
|
+
goto out;
|
|
5424
|
+
}
|
|
5425
|
+
|
|
5426
|
+
if(!json_get_and_check_uri(document, "proxy_uri", true, &proxy_uri)) {
|
|
5427
|
+
goto out;
|
|
5428
|
+
}
|
|
5429
|
+
|
|
5430
|
+
if(document.HasMember("auth")) {
|
|
5431
|
+
if(!document["auth"].IsObject()) {
|
|
5432
|
+
set_error("Parameter auth must be an object");
|
|
5433
|
+
goto out;
|
|
5434
|
+
} else {
|
|
5435
|
+
const Value& auth = document["auth"];
|
|
5436
|
+
|
|
5437
|
+
for (Value::ConstMemberIterator itr = auth.MemberBegin(); itr != auth.MemberEnd(); ++itr) {
|
|
5438
|
+
const char *name = itr->name.GetString();
|
|
5439
|
+
if(strcmp(name, "realm") == 0) {
|
|
5440
|
+
if(!itr->value.IsString()) {
|
|
5441
|
+
set_error("%s must be a string", itr->name.GetString());
|
|
4825
5442
|
goto out;
|
|
5443
|
+
}
|
|
5444
|
+
realm = (char*)itr->value.GetString();
|
|
5445
|
+
} else if(strcmp(name, "username") == 0) {
|
|
5446
|
+
if(!itr->value.IsString()) {
|
|
5447
|
+
set_error("%s must be a string", itr->name.GetString());
|
|
5448
|
+
goto out;
|
|
5449
|
+
}
|
|
5450
|
+
username = (char*)itr->value.GetString();
|
|
5451
|
+
contact_username = username;
|
|
5452
|
+
} else if(strcmp(name, "password") == 0) {
|
|
5453
|
+
if(!itr->value.IsString()) {
|
|
5454
|
+
set_error("%s must be a string", itr->name.GetString());
|
|
5455
|
+
goto out;
|
|
5456
|
+
}
|
|
5457
|
+
password = (char*)itr->value.GetString();
|
|
5458
|
+
} else {
|
|
5459
|
+
set_error("Unknown auth paramter %s", itr->name.GetString());
|
|
5460
|
+
goto out;
|
|
4826
5461
|
}
|
|
4827
|
-
|
|
4828
|
-
request_uri = to_uri;
|
|
5462
|
+
}
|
|
4829
5463
|
}
|
|
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
|
-
}
|
|
5464
|
+
}
|
|
4838
5465
|
|
|
4839
5466
|
build_local_contact(local_contact, t->sip_transport, contact_username);
|
|
4840
5467
|
|
|
@@ -4859,7 +5486,7 @@ int pjw_subscription_create(long transport_id, const char *event, const char *ac
|
|
|
4859
5486
|
PJSIP_EVSUB_NO_EVENT_ID,
|
|
4860
5487
|
&evsub);
|
|
4861
5488
|
if(status != PJ_SUCCESS) {
|
|
4862
|
-
set_error("pjsip_evsub_create_uac failed");
|
|
5489
|
+
set_error("pjsip_evsub_create_uac failed with status=%i", status);
|
|
4863
5490
|
goto out;
|
|
4864
5491
|
}
|
|
4865
5492
|
|
|
@@ -4885,17 +5512,46 @@ int pjw_subscription_create(long transport_id, const char *event, const char *ac
|
|
|
4885
5512
|
strcpy(subscription->accept, accept);
|
|
4886
5513
|
pjsip_evsub_set_mod_data(evsub, mod_tester.id, subscription);
|
|
4887
5514
|
|
|
5515
|
+
*out_subscription_id = subscription_id;
|
|
4888
5516
|
out:
|
|
4889
5517
|
PJW_UNLOCK();
|
|
4890
5518
|
if(pjw_errorstring[0]){
|
|
4891
5519
|
return -1;
|
|
4892
5520
|
}
|
|
4893
|
-
|
|
4894
|
-
*out_subscription_id = subscription_id;
|
|
4895
5521
|
return 0;
|
|
4896
5522
|
}
|
|
4897
5523
|
|
|
4898
|
-
bool
|
|
5524
|
+
bool subscription_subscribe_no_headers(Subscription *s, int expires) {
|
|
5525
|
+
pj_status_t status;
|
|
5526
|
+
pjsip_tx_data *tdata;
|
|
5527
|
+
|
|
5528
|
+
status = pjsip_evsub_initiate(s->evsub,
|
|
5529
|
+
NULL,
|
|
5530
|
+
expires,
|
|
5531
|
+
&tdata);
|
|
5532
|
+
if(status != PJ_SUCCESS) {
|
|
5533
|
+
set_error("pjsip_evsub_initiate failed");
|
|
5534
|
+
return false;
|
|
5535
|
+
}
|
|
5536
|
+
|
|
5537
|
+
status = pjsip_evsub_send_request(s->evsub, tdata);
|
|
5538
|
+
if(status != PJ_SUCCESS) {
|
|
5539
|
+
set_error("pjsip_inv_send_msg failed");
|
|
5540
|
+
return false;
|
|
5541
|
+
}
|
|
5542
|
+
|
|
5543
|
+
//Without this, on_rx_response will not be called
|
|
5544
|
+
status = pjsip_dlg_add_usage(s->dlg, &mod_tester, s);
|
|
5545
|
+
if(status != PJ_SUCCESS) {
|
|
5546
|
+
set_error("pjsip_dlg_add_usage failed");
|
|
5547
|
+
return false;
|
|
5548
|
+
}
|
|
5549
|
+
|
|
5550
|
+
return true;
|
|
5551
|
+
}
|
|
5552
|
+
|
|
5553
|
+
|
|
5554
|
+
bool subscription_subscribe(Subscription *s, int expires, Document &document) {
|
|
4899
5555
|
pj_status_t status;
|
|
4900
5556
|
pjsip_tx_data *tdata;
|
|
4901
5557
|
|
|
@@ -4908,7 +5564,7 @@ bool subscription_subscribe(Subscription *s, int expires, const char *additional
|
|
|
4908
5564
|
return false;
|
|
4909
5565
|
}
|
|
4910
5566
|
|
|
4911
|
-
if(!
|
|
5567
|
+
if(!add_headers(s->dlg->pool, tdata, document)) {
|
|
4912
5568
|
return false;
|
|
4913
5569
|
}
|
|
4914
5570
|
|
|
@@ -4928,29 +5584,41 @@ bool subscription_subscribe(Subscription *s, int expires, const char *additional
|
|
|
4928
5584
|
return true;
|
|
4929
5585
|
}
|
|
4930
5586
|
|
|
4931
|
-
int pjw_subscription_subscribe(long subscription_id, int expires, const char *additional_headers) {
|
|
5587
|
+
//int pjw_subscription_subscribe(long subscription_id, int expires, const char *additional_headers) {
|
|
5588
|
+
int pjw_subscription_subscribe(long subscription_id, const char *json) {
|
|
4932
5589
|
PJW_LOCK();
|
|
4933
|
-
|
|
4934
5590
|
clear_error();
|
|
4935
5591
|
|
|
5592
|
+
int expires;
|
|
5593
|
+
|
|
4936
5594
|
Subscription *subscription;
|
|
4937
5595
|
|
|
4938
5596
|
long val;
|
|
4939
5597
|
|
|
5598
|
+
char buffer[MAX_JSON_INPUT];
|
|
5599
|
+
|
|
5600
|
+
Document document;
|
|
5601
|
+
|
|
4940
5602
|
if(!g_subscription_ids.get(subscription_id, val)){
|
|
4941
5603
|
set_error("Invalid subscription_id");
|
|
4942
5604
|
goto out;
|
|
4943
5605
|
}
|
|
4944
|
-
|
|
4945
5606
|
subscription = (Subscription*)val;
|
|
4946
5607
|
|
|
4947
|
-
|
|
5608
|
+
if(!parse_json(document, json, buffer, MAX_JSON_INPUT)) {
|
|
5609
|
+
goto out;
|
|
5610
|
+
}
|
|
5611
|
+
|
|
5612
|
+
if(!json_get_int_param(document, "expires", true, &expires)) {
|
|
5613
|
+
goto out;
|
|
5614
|
+
}
|
|
5615
|
+
|
|
5616
|
+
if(!subscription_subscribe(subscription, expires, document)) {
|
|
4948
5617
|
goto out;
|
|
4949
5618
|
}
|
|
4950
5619
|
|
|
4951
5620
|
out:
|
|
4952
5621
|
PJW_UNLOCK();
|
|
4953
|
-
|
|
4954
5622
|
if(pjw_errorstring[0]) {
|
|
4955
5623
|
return -1;
|
|
4956
5624
|
}
|
|
@@ -4961,7 +5629,7 @@ void process_in_dialog_subscribe(pjsip_dialog *dlg, pjsip_rx_data *rdata) {
|
|
|
4961
5629
|
char evt[2048];
|
|
4962
5630
|
|
|
4963
5631
|
Subscriber *s;
|
|
4964
|
-
Transport *t;
|
|
5632
|
+
//Transport *t;
|
|
4965
5633
|
|
|
4966
5634
|
s = (Subscriber*)dlg->mod_data[mod_tester.id];
|
|
4967
5635
|
if(!s) {
|
|
@@ -4979,11 +5647,11 @@ int pjw_call_gen_string_replaces(long call_id, char *out_replaces) {
|
|
|
4979
5647
|
|
|
4980
5648
|
clear_error();
|
|
4981
5649
|
|
|
4982
|
-
int n;
|
|
5650
|
+
//int n;
|
|
4983
5651
|
long val;
|
|
4984
5652
|
Call *call;
|
|
4985
5653
|
pjsip_dialog *dlg;
|
|
4986
|
-
int len;
|
|
5654
|
+
//int len;
|
|
4987
5655
|
char *p;
|
|
4988
5656
|
char buf[2000];
|
|
4989
5657
|
pjsip_uri* uri;
|