sip-lab 1.11.4 → 1.12.0

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