1 /*
2 eXosip - This is the eXtended osip library.
3 Copyright (C) 2001-2020 Aymeric MOIZARD amoizard@antisip.com
4
5 eXosip is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
9
10 eXosip is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19 In addition, as a special exception, the copyright holders give
20 permission to link the code of portions of this program with the
21 OpenSSL library under certain conditions as described in each
22 individual source file, and distribute linked combinations
23 including the two.
24 You must obey the GNU General Public License in all respects
25 for all of the code used other than OpenSSL. If you modify
26 file(s) with this exception, you may extend this exception to your
27 version of the file(s), but you are not obligated to do so. If you
28 do not wish to do so, delete this exception statement from your
29 version. If you delete this exception statement from all source
30 files in the program, then also delete it here.
31 */
32
33 #include "eXosip2.h"
34
35 #include <eXosip2/eXosip.h>
36
37 /* Private functions */
38 static void rcvregister_failure(osip_transaction_t *tr, osip_message_t *sip);
39
_eXosip_register_contact_is_modified(eXosip_reg_t * jr,osip_message_t * request,osip_message_t * response)40 static void _eXosip_register_contact_is_modified(eXosip_reg_t *jr, osip_message_t *request, osip_message_t *response) {
41 osip_via_t *via;
42 osip_generic_param_t *br = NULL;
43
44 char *received_viahost = NULL;
45 char *rport_viaport = NULL;
46 static char *port_5061 = "5061";
47 static char *port_5060 = "5060";
48
49 osip_contact_t *contact;
50 char *contact_port = NULL;
51
52 /* no action if expires=0 */
53 if (jr->r_reg_period == 0)
54 return;
55
56 osip_message_get_via(response, 0, &via);
57
58 if (via == NULL || via->protocol == NULL || via->host == NULL)
59 return;
60
61 osip_message_get_contact(request, 0, &contact);
62
63 if (contact == NULL || contact->url == NULL || contact->url->host == NULL)
64 return;
65
66 /* via host:port info */
67
68 osip_via_param_get_byname(via, "received", &br);
69
70 if (br != NULL && br->gvalue != NULL)
71 received_viahost = br->gvalue;
72
73 osip_via_param_get_byname(via, "rport", &br);
74
75 if (br != NULL && br->gvalue == NULL)
76 return; /* the feature doesn't work if no rport is provided back */
77
78 if (br != NULL && br->gvalue != NULL)
79 rport_viaport = br->gvalue;
80
81 if (rport_viaport == NULL)
82 rport_viaport = via->port;
83
84 if (rport_viaport == NULL) {
85 /* could be 5060 or 5061 */
86 if (osip_strcasecmp(via->protocol, "DTLS") == 0 || osip_strcasecmp(via->protocol, "TLS") == 0)
87 rport_viaport = port_5061;
88
89 else
90 rport_viaport = port_5060;
91 }
92
93 /* contact host:port info */
94 contact_port = contact->url->port;
95
96 if (contact_port == NULL) {
97 /* could be 5060 or 5061 */
98 if (osip_strcasecmp(via->protocol, "DTLS") == 0 || osip_strcasecmp(via->protocol, "TLS") == 0)
99 contact_port = port_5061;
100
101 else
102 contact_port = port_5060;
103 }
104
105 if (jr->r_last_deletion > 0)
106 return; /* avoid loop. */
107
108 if (osip_strcasecmp(contact_port, rport_viaport) != 0) {
109 /* the port parameter is different from contact. */
110 jr->registration_step = RS_DELETIONREQUIRED; /* proceed with deletion and re-registration of new contact */
111 jr->r_last_deletion = osip_getsystemtime(NULL);
112 return;
113 }
114
115 if (received_viahost != NULL && osip_strcasecmp(received_viahost, contact->url->host) != 0) {
116 /* a received parameter was added and is different from contact. */
117 jr->registration_step = RS_DELETIONREQUIRED; /* proceed with deletion and re-registration of new contact */
118 jr->r_last_deletion = osip_getsystemtime(NULL);
119 return;
120 }
121
122 if (received_viahost == NULL) {
123 if (osip_strcasecmp(via->host, contact->url->host) != 0) {
124 /* a received parameter was not added and local ip is different from contact: there is a possibility of IP change */
125 jr->registration_step = RS_DELETIONREQUIRED; /* proceed with deletion and re-registration of new contact */
126 jr->r_last_deletion = osip_getsystemtime(NULL);
127 }
128
129 return;
130 }
131 }
132
_eXosip_snd_message(struct eXosip_t * excontext,osip_transaction_t * tr,osip_message_t * sip,char * host,int port,int out_socket)133 int _eXosip_snd_message(struct eXosip_t *excontext, osip_transaction_t *tr, osip_message_t *sip, char *host, int port, int out_socket) {
134 int i;
135 osip_via_t *via;
136
137 if (sip->status_code == 101)
138 return OSIP_SUCCESS;
139
140 via = (osip_via_t *) osip_list_get(&sip->vias, 0);
141
142 if (via == NULL || via->protocol == NULL)
143 return -1;
144
145 if (host == NULL) {
146 if (MSG_IS_REQUEST(sip)) {
147 osip_route_t *route;
148
149 osip_message_get_route(sip, 0, &route);
150
151 if (route != NULL) {
152 osip_uri_param_t *lr_param = NULL;
153
154 osip_uri_uparam_get_byname(route->url, "lr", &lr_param);
155
156 if (lr_param == NULL)
157 route = NULL;
158 }
159
160 if (route != NULL) {
161 port = 5060;
162
163 if (route->url->port != NULL)
164 port = osip_atoi(route->url->port);
165
166 host = route->url->host;
167
168 } else {
169 /* search for maddr parameter */
170 osip_uri_param_t *maddr_param = NULL;
171 osip_uri_param_t *obr_param = NULL;
172 osip_uri_param_t *obp_param = NULL;
173
174 osip_uri_uparam_get_byname(sip->req_uri, "maddr", &maddr_param);
175 host = NULL;
176
177 if (maddr_param != NULL && maddr_param->gvalue != NULL)
178 host = maddr_param->gvalue;
179
180 port = 5060;
181
182 if (sip->req_uri->port != NULL)
183 port = osip_atoi(sip->req_uri->port);
184
185 if (host == NULL) {
186 /* if ob was used in Contact, then exosip adds "x-obr" and "x-obp", thus, when
187 processing request, the ip/port destination are re-used here */
188 osip_uri_uparam_get_byname(sip->req_uri, "x-obr", &obr_param);
189 osip_uri_uparam_get_byname(sip->req_uri, "x-obp", &obp_param);
190
191 if (obr_param != NULL && obr_param->gvalue != NULL && obp_param != NULL && obp_param->gvalue != NULL) {
192 host = obr_param->gvalue;
193 port = atoi(obp_param->gvalue);
194 }
195 }
196
197 if (host == NULL)
198 host = sip->req_uri->host;
199 }
200
201 } else {
202 osip_generic_param_t *maddr;
203 osip_generic_param_t *received;
204 osip_generic_param_t *rport;
205
206 osip_via_param_get_byname(via, "maddr", &maddr);
207 osip_via_param_get_byname(via, "received", &received);
208 osip_via_param_get_byname(via, "rport", &rport);
209
210 if (maddr != NULL && maddr->gvalue != NULL)
211 host = maddr->gvalue;
212
213 else if (received != NULL && received->gvalue != NULL)
214 host = received->gvalue;
215
216 else
217 host = via->host;
218
219 if (rport == NULL || rport->gvalue == NULL) {
220 if (via->port != NULL)
221 port = osip_atoi(via->port);
222
223 else
224 port = 5060;
225
226 } else
227 port = osip_atoi(rport->gvalue);
228 }
229 }
230
231 if (excontext->cbsipCallback != NULL) {
232 excontext->cbsipCallback(sip, 0);
233 }
234
235 i = -1;
236 i = excontext->eXtl_transport.tl_send_message(excontext, tr, sip, host, port, out_socket);
237
238 if (i != 0) {
239 return i;
240 }
241
242 return OSIP_SUCCESS;
243 }
244
cb_snd_message(osip_transaction_t * tr,osip_message_t * sip,char * host,int port,int out_socket)245 static int cb_snd_message(osip_transaction_t *tr, osip_message_t *sip, char *host, int port, int out_socket) {
246 struct eXosip_t *excontext = (struct eXosip_t *) osip_transaction_get_reserved1(tr);
247
248 return _eXosip_snd_message(excontext, tr, sip, host, port, out_socket);
249 }
250
cb_xixt_kill_transaction(int type,osip_transaction_t * tr)251 static void cb_xixt_kill_transaction(int type, osip_transaction_t *tr) {
252 int i;
253 struct eXosip_t *excontext = (struct eXosip_t *) osip_transaction_get_reserved1(tr);
254 struct timeval time_sub;
255 osip_timersub(&tr->destroyed_time, &tr->created_time, &time_sub);
256
257 OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_INFO1, NULL, "[eXosip] [tid=%i] [cb_xixt_kill_transaction] [duration=%3li,%03lis]\n", tr->transactionid, time_sub.tv_sec, time_sub.tv_usec / 1000));
258 i = osip_remove_transaction(excontext->j_osip, tr);
259
260 if (i != 0) {
261 OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_BUG, NULL, "[eXosip] [tid=%i] [cb_xixt_kill_transaction] **cannot remove transaction from the oSIP stack**\n", tr->transactionid));
262 }
263
264 if (MSG_IS_REGISTER(tr->orig_request) && type == OSIP_NICT_KILL_TRANSACTION && tr->last_response == NULL) {
265 rcvregister_failure(tr, NULL);
266 return;
267 }
268
269 #ifndef MINISIZE
270
271 if (type == OSIP_NICT_KILL_TRANSACTION) {
272 eXosip_call_t *jc = (eXosip_call_t *) osip_transaction_get_reserved2(tr);
273 eXosip_dialog_t *jd = (eXosip_dialog_t *) osip_transaction_get_reserved3(tr);
274 eXosip_subscribe_t *js = (eXosip_subscribe_t *) osip_transaction_get_reserved5(tr);
275 eXosip_notify_t *jn = (eXosip_notify_t *) osip_transaction_get_reserved4(tr);
276
277 if (jc == NULL && jn == NULL && js == NULL && tr->last_response == NULL) {
278 eXosip_event_t *je;
279
280 je = _eXosip_event_init_for_message(EXOSIP_MESSAGE_REQUESTFAILURE, tr);
281 _eXosip_report_event(excontext, je);
282 return;
283 }
284
285 if (jc != NULL && jn == NULL && js == NULL && tr->last_response == NULL) {
286 _eXosip_report_call_event(excontext, EXOSIP_CALL_MESSAGE_REQUESTFAILURE, jc, jd, tr);
287 return;
288 }
289
290 /* no answer to a NOTIFY request! */
291 if (jn != NULL && MSG_IS_NOTIFY(tr->orig_request) && tr->last_response == NULL) {
292 /* delete the dialog! */
293 eXosip_event_t *je;
294
295 je = _eXosip_event_init_for_notify(EXOSIP_NOTIFICATION_REQUESTFAILURE, jn, jd, tr);
296 _eXosip_report_event(excontext, je);
297
298 REMOVE_ELEMENT(excontext->j_notifies, jn);
299 _eXosip_notify_free(excontext, jn);
300 return;
301 }
302
303 if (jn != NULL && MSG_IS_NOTIFY(tr->orig_request) && tr->last_response != NULL && tr->last_response->status_code > 299) {
304 /* delete the dialog! */
305 if (tr->last_response->status_code != 407 && tr->last_response->status_code != 401) {
306 REMOVE_ELEMENT(excontext->j_notifies, jn);
307 _eXosip_notify_free(excontext, jn);
308 return;
309 }
310 }
311
312 if (jn != NULL && MSG_IS_NOTIFY(tr->orig_request) && tr->last_response != NULL && tr->last_response->status_code > 199 && tr->last_response->status_code < 300) {
313 if (jn->n_ss_status == EXOSIP_SUBCRSTATE_TERMINATED) {
314 /* delete the dialog! */
315 REMOVE_ELEMENT(excontext->j_notifies, jn);
316 _eXosip_notify_free(excontext, jn);
317 return;
318 }
319 }
320
321 /* no answer to a SUBSCRIBE request! */
322 if (js != NULL && (MSG_IS_SUBSCRIBE(tr->orig_request) || MSG_IS_REFER(tr->orig_request)) && (tr->last_response == NULL || tr->last_response->status_code <= 199)) {
323 eXosip_event_t *je;
324
325 je = _eXosip_event_init_for_subscription(EXOSIP_SUBSCRIPTION_REQUESTFAILURE, js, jd, tr);
326 _eXosip_report_event(excontext, je);
327
328 /* delete the dialog! */
329 REMOVE_ELEMENT(excontext->j_subscribes, js);
330 _eXosip_subscription_free(excontext, js);
331 return;
332 }
333
334 /* detect SUBSCRIBE request that close the dialogs! */
335 if (js != NULL && (MSG_IS_SUBSCRIBE(tr->orig_request) || MSG_IS_REFER(tr->orig_request)) && tr->last_response != NULL && (tr->last_response->status_code == 401 || tr->last_response->status_code == 407)) {
336 /* delete the dialog later because we need to authenticate */
337 } else if (js != NULL && (MSG_IS_SUBSCRIBE(tr->orig_request) || MSG_IS_REFER(tr->orig_request))) {
338 osip_header_t *expires;
339
340 osip_message_get_expires(tr->orig_request, 0, &expires);
341
342 if (expires == NULL || expires->hvalue == NULL) {
343 } else if (0 == strcmp(expires->hvalue, "0")) {
344 REMOVE_ELEMENT(excontext->j_subscribes, js);
345 _eXosip_subscription_free(excontext, js);
346 return;
347 }
348 }
349 }
350
351 #endif
352 }
353
cb_rcvcancel(int type,osip_transaction_t * tr,osip_message_t * sip)354 static void cb_rcvcancel(int type, osip_transaction_t *tr, osip_message_t *sip) {
355 struct eXosip_t *excontext = (struct eXosip_t *) osip_transaction_get_reserved1(tr);
356 eXosip_call_t *jc = (eXosip_call_t *) osip_transaction_get_reserved2(tr);
357 eXosip_dialog_t *jd = (eXosip_dialog_t *) osip_transaction_get_reserved3(tr);
358
359 OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_INFO3, NULL, "[eXosip] [tid=%i] [cb_rcvcancel]\n", tr->transactionid));
360
361 if ((jd != NULL) && (jc != NULL)) {
362 /* do propagate CANCEL to the application */
363 _eXosip_report_call_event(excontext, EXOSIP_CALL_CANCELLED, jc, jd, tr);
364 }
365 }
366
cb_rcvregister(int type,osip_transaction_t * tr,osip_message_t * sip)367 static void cb_rcvregister(int type, osip_transaction_t *tr, osip_message_t *sip) {
368 struct eXosip_t *excontext = (struct eXosip_t *) osip_transaction_get_reserved1(tr);
369 eXosip_event_t *je;
370
371 OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_INFO3, NULL, "[eXosip] [tid=%i] [cb_rcvregister]\n", tr->transactionid));
372
373 je = _eXosip_event_init_for_message(EXOSIP_MESSAGE_NEW, tr);
374 _eXosip_event_add(excontext, je);
375 return;
376 }
377
cb_rcvrequest(int type,osip_transaction_t * tr,osip_message_t * sip)378 static void cb_rcvrequest(int type, osip_transaction_t *tr, osip_message_t *sip) {
379 struct eXosip_t *excontext = (struct eXosip_t *) osip_transaction_get_reserved1(tr);
380 eXosip_call_t *jc = (eXosip_call_t *) osip_transaction_get_reserved2(tr);
381 eXosip_dialog_t *jd = (eXosip_dialog_t *) osip_transaction_get_reserved3(tr);
382
383 #ifndef MINISIZE
384 eXosip_subscribe_t *js = (eXosip_subscribe_t *) osip_transaction_get_reserved5(tr);
385 eXosip_notify_t *jn = (eXosip_notify_t *) osip_transaction_get_reserved4(tr);
386 #endif
387
388 OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_INFO3, NULL, "[eXosip] [tid=%i] [cb_rcvrequest]\n", tr->transactionid));
389
390 if (jc != NULL) {
391 OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_INFO3, NULL, "[eXosip] [tid=%i] [cb_rcvrequest]\n", tr->transactionid));
392
393 if (MSG_IS_BYE(sip)) {
394 if (excontext->autoanswer_bye == 0) {
395 /* not already sent */
396 _eXosip_report_call_event(excontext, EXOSIP_CALL_MESSAGE_NEW, jc, jd, tr);
397 _eXosip_report_call_event(excontext, EXOSIP_CALL_CLOSED, jc, jd, tr);
398 }
399
400 } else
401 _eXosip_report_call_event(excontext, EXOSIP_CALL_MESSAGE_NEW, jc, jd, tr);
402
403 return;
404 }
405 #ifndef MINISIZE
406
407 else if (jn != NULL) {
408 if (MSG_IS_SUBSCRIBE(sip) || MSG_IS_REFER(sip)) {
409 eXosip_event_t *je;
410
411 je = _eXosip_event_init_for_notify(EXOSIP_IN_SUBSCRIPTION_NEW, jn, jd, tr);
412 _eXosip_report_event(excontext, je);
413 return;
414 }
415
416 return;
417
418 } else if (js != NULL) {
419 if (MSG_IS_NOTIFY(sip)) {
420 eXosip_event_t *je;
421
422 je = _eXosip_event_init_for_subscription(EXOSIP_SUBSCRIPTION_NOTIFY, js, jd, tr);
423 _eXosip_report_event(excontext, je);
424 return;
425 }
426
427 return;
428 }
429 #endif
430
431 else {
432 eXosip_event_t *je;
433
434 je = _eXosip_event_init_for_message(EXOSIP_MESSAGE_NEW, tr);
435 _eXosip_event_add(excontext, je);
436 return;
437 }
438 }
439
_eXosip_delete_reserved(osip_transaction_t * transaction)440 void _eXosip_delete_reserved(osip_transaction_t *transaction) {
441 if (transaction == NULL)
442 return;
443
444 osip_transaction_set_reserved2(transaction, NULL);
445 osip_transaction_set_reserved3(transaction, NULL);
446 osip_transaction_set_reserved4(transaction, NULL);
447 osip_transaction_set_reserved5(transaction, NULL);
448 }
449
cb_rcv1xx(int type,osip_transaction_t * tr,osip_message_t * sip)450 static void cb_rcv1xx(int type, osip_transaction_t *tr, osip_message_t *sip) {
451 struct eXosip_t *excontext = (struct eXosip_t *) osip_transaction_get_reserved1(tr);
452 eXosip_call_t *jc = (eXosip_call_t *) osip_transaction_get_reserved2(tr);
453 eXosip_dialog_t *jd = (eXosip_dialog_t *) osip_transaction_get_reserved3(tr);
454
455 #ifndef MINISIZE
456 eXosip_subscribe_t *js = (eXosip_subscribe_t *) osip_transaction_get_reserved5(tr);
457 eXosip_notify_t *jn = (eXosip_notify_t *) osip_transaction_get_reserved4(tr);
458 #endif
459
460 OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_INFO3, NULL, "[eXosip] [tid=%i] [cb_rcv1xx]\n", tr->transactionid));
461
462 if (MSG_IS_RESPONSE_FOR(sip, "OPTIONS")) {
463 if (jc == NULL) {
464 eXosip_event_t *je;
465
466 OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_INFO3, NULL, "[eXosip] [tid=%i] [cb_rcv1xx] OPTIONS outside of any call\n", tr->transactionid));
467
468 je = _eXosip_event_init_for_message(EXOSIP_MESSAGE_PROCEEDING, tr);
469 _eXosip_event_add(excontext, je);
470 return;
471 }
472
473 _eXosip_report_call_event(excontext, EXOSIP_CALL_MESSAGE_PROCEEDING, jc, jd, tr);
474 return;
475 }
476
477 if (MSG_IS_RESPONSE_FOR(sip, "INVITE") && MSG_TEST_CODE(sip, 100)) {
478 _eXosip_report_call_event(excontext, EXOSIP_CALL_PROCEEDING, jc, jd, tr);
479 return;
480 }
481
482 #ifndef MINISIZE
483
484 if (MSG_IS_RESPONSE_FOR(sip, "SUBSCRIBE") && MSG_TEST_CODE(sip, 100)) {
485 eXosip_event_t *je;
486
487 je = _eXosip_event_init_for_subscription(EXOSIP_SUBSCRIPTION_PROCEEDING, js, jd, tr);
488 _eXosip_report_event(excontext, je);
489 return;
490 }
491
492 #endif
493
494 if (MSG_IS_RESPONSE_FOR(sip, "REFER") && MSG_TEST_CODE(sip, 100)) {
495 /* not easy to differentiate now (EXOSIP_SUBSCRIPTION_PROCEEDING or EXOSIP_CALL_MESSAGE_PROCEEDING) */
496 return;
497 }
498
499 if (MSG_IS_RESPONSE_FOR(sip, "INVITE")
500 #ifndef MINISIZE
501 || MSG_IS_RESPONSE_FOR(sip, "REFER") || MSG_IS_RESPONSE_FOR(sip, "SUBSCRIBE")
502 #endif
503 ) {
504 int i;
505
506 #ifndef MINISIZE
507
508 /* for SUBSCRIBE, test if the dialog has been already created
509 with a previous NOTIFY */
510 if (jd == NULL && js != NULL && js->s_dialogs != NULL && (MSG_IS_RESPONSE_FOR(sip, "SUBSCRIBE") || MSG_IS_RESPONSE_FOR(sip, "REFER"))) {
511 /* find if existing dialog match the to tag */
512 osip_generic_param_t *tag;
513 int i;
514
515 i = osip_to_get_tag(sip->to, &tag);
516
517 if (i == 0 && tag != NULL && tag->gvalue != NULL) {
518 for (jd = js->s_dialogs; jd != NULL; jd = jd->next) {
519 if (0 == strcmp(jd->d_dialog->remote_tag, tag->gvalue)) {
520 OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_INFO1, NULL, "[eXosip] [tid=%i] [cb_rcv1xx] found established early dialog for this subscription\n", tr->transactionid));
521 osip_transaction_set_reserved3(tr, jd);
522 break;
523 }
524 }
525 }
526 }
527
528 #endif
529
530 if (jd == NULL) {
531 /* This transaction initiate a dialog in the case of
532 INVITE (else it would be attached to a "jd" element. */
533 /* allocate a jd */
534
535 i = _eXosip_dialog_init_as_uac(&jd, sip);
536
537 if (i != 0) {
538 OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_ERROR, NULL, "[eXosip] [tid=%i] [cb_rcv1xx] cannot establish a dialog\n", tr->transactionid));
539 return;
540 }
541
542 if (jc != NULL) {
543 ADD_ELEMENT(jc->c_dialogs, jd);
544 osip_transaction_set_reserved3(tr, jd);
545 _eXosip_update(excontext);
546 }
547 #ifndef MINISIZE
548
549 else if (js != NULL) {
550 ADD_ELEMENT(js->s_dialogs, jd);
551 osip_transaction_set_reserved3(tr, jd);
552 _eXosip_update(excontext);
553
554 } else if (jn != NULL) {
555 ADD_ELEMENT(jn->n_dialogs, jd);
556 osip_transaction_set_reserved3(tr, jd);
557 _eXosip_update(excontext);
558 }
559 #endif
560
561 else {
562 }
563 } else {
564 if (jd->d_dialog == NULL) {
565 } else if (jd->d_dialog->remote_tag == NULL) {
566 osip_dialog_update_route_set_as_uac(jd->d_dialog, sip);
567 osip_dialog_update_tag_as_uac(jd->d_dialog, sip);
568
569 } else {
570 osip_generic_param_t *tag;
571 int i;
572
573 i = osip_to_get_tag(sip->to, &tag);
574
575 if (tag != NULL && tag->gvalue != NULL && 0 == strcmp(jd->d_dialog->remote_tag, tag->gvalue)) {
576 /* Update only if it is the same dialog */
577 osip_dialog_update_route_set_as_uac(jd->d_dialog, sip);
578 }
579 #if 1 /* to be tested */
580
581 else {
582 /* the best thing is to replace the current dialog
583 information... Much easier than creating a useless dialog! */
584 int current_local_cseq = jd->d_dialog->local_cseq;
585
586 osip_dialog_free(jd->d_dialog);
587 i = osip_dialog_init_as_uac(&(jd->d_dialog), sip);
588
589 if (i != 0) {
590 OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_ERROR, NULL, "[eXosip] [tid=%i] [cb_rcv1xx] cannot replace the dialog\n", tr->transactionid));
591
592 } else {
593 jd->d_dialog->local_cseq = current_local_cseq;
594 OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_WARNING, NULL, "[eXosip] [tid=%i] [cb_rcv1xx] the dialog has been replaced with the new one from 1xx\n", tr->transactionid));
595 }
596 }
597
598 #endif
599 }
600 }
601
602 if (jd != NULL && MSG_IS_RESPONSE_FOR(sip, "INVITE") && sip->status_code < 180) {
603 _eXosip_check_allow_header(jd, sip);
604 _eXosip_report_call_event(excontext, EXOSIP_CALL_PROCEEDING, jc, jd, tr);
605
606 } else if (jd != NULL && MSG_IS_RESPONSE_FOR(sip, "INVITE") && sip->status_code >= 180) {
607 _eXosip_check_allow_header(jd, sip);
608 _eXosip_report_call_event(excontext, EXOSIP_CALL_RINGING, jc, jd, tr);
609 }
610 #ifndef MINISIZE
611
612 else if (jd != NULL && (MSG_IS_RESPONSE_FOR(sip, "SUBSCRIBE") || MSG_IS_RESPONSE_FOR(sip, "REFER"))) {
613 eXosip_event_t *je;
614
615 je = _eXosip_event_init_for_subscription(EXOSIP_SUBSCRIPTION_PROCEEDING, js, jd, tr);
616 _eXosip_report_event(excontext, je);
617 }
618
619 #endif
620
621 if (jc != NULL && MSG_IS_RESPONSE_FOR(sip, "INVITE")) {
622 _eXosip_call_renew_expire_time(jc);
623 }
624 }
625 }
626
cb_rcv2xx_4invite(osip_transaction_t * tr,osip_message_t * sip)627 static void cb_rcv2xx_4invite(osip_transaction_t *tr, osip_message_t *sip) {
628 struct eXosip_t *excontext = (struct eXosip_t *) osip_transaction_get_reserved1(tr);
629 int i;
630 eXosip_call_t *jc = (eXosip_call_t *) osip_transaction_get_reserved2(tr);
631 eXosip_dialog_t *jd = (eXosip_dialog_t *) osip_transaction_get_reserved3(tr);
632
633 if (jc == NULL)
634 return;
635
636 if (jd == NULL) {
637 /* This transaction initiate a dialog in the case of
638 INVITE (else it would be attached to a "jd" element. */
639 /* allocate a jd */
640 i = _eXosip_dialog_init_as_uac(&jd, sip);
641
642 if (i != 0) {
643 OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_ERROR, NULL, "[eXosip] [tid=%i] [cb_rcv2xx_4invite] cannot establish a dialog\n", tr->transactionid));
644 return;
645 }
646
647 ADD_ELEMENT(jc->c_dialogs, jd);
648 osip_transaction_set_reserved3(tr, jd);
649 _eXosip_update(excontext);
650
651 } else {
652 /* Here is a special case:
653 We have initiated a dialog and we have received informationnal
654 answers from 2 or more remote SIP UA. Those answer can be
655 differentiated with the "To" header's tag.
656
657 We have used the first informationnal answer to create a
658 dialog, but we now want to be sure the 200ok received is
659 for the dialog this dialog.
660
661 We have to check the To tag and if it does not match, we
662 just have to modify the existing dialog and replace it. */
663 osip_generic_param_t *tag;
664 int i;
665
666 i = osip_to_get_tag(sip->to, &tag);
667 i = 1; /* default is the same dialog */
668
669 if (jd->d_dialog == NULL) {
670 /* There are real use-case where a BYE is received/processed before
671 the 200ok of the previous INVITE. In this case, jd->d_dialog is
672 empty and the transaction should be silently discarded. */
673 /* a ACK should still be sent... -but there is no dialog built- */
674 return;
675 }
676
677 if (jd->d_dialog->remote_tag == NULL && tag == NULL) {
678 } /* non compliant remote UA -> assume it is the same dialog */
679 else if (jd->d_dialog->remote_tag != NULL && tag == NULL) {
680 i = 0;
681 } /* different dialog! */
682
683 else if (jd->d_dialog->remote_tag == NULL && tag != NULL) {
684 i = 0;
685 } /* different dialog! */
686
687 else if (jd->d_dialog->remote_tag != NULL && tag != NULL && tag->gvalue != NULL && 0 != strcmp(jd->d_dialog->remote_tag, tag->gvalue)) {
688 i = 0;
689 }
690
691 /* different dialog! */
692 if (i == 1) { /* just update the dialog */
693 osip_dialog_update_route_set_as_uac(jd->d_dialog, sip);
694
695 if (jd->d_dialog->remote_tag == NULL)
696 osip_dialog_update_tag_as_uac(jd->d_dialog, sip);
697
698 osip_dialog_set_state(jd->d_dialog, DIALOG_CONFIRMED);
699
700 } else {
701 /* the best thing is to replace the current dialog
702 information... Much easier than creating a useless dialog! */
703 int current_local_cseq = jd->d_dialog->local_cseq;
704
705 osip_dialog_free(jd->d_dialog);
706 i = osip_dialog_init_as_uac(&(jd->d_dialog), sip);
707
708 if (i != 0) {
709 OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_ERROR, NULL, "[eXosip] [tid=%i] [cb_rcv2xx_4invite] cannot replace the dialog\n", tr->transactionid));
710
711 } else {
712 jd->d_dialog->local_cseq = current_local_cseq;
713 OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_WARNING, NULL, "[eXosip] [tid=%i] [cb_rcv2xx_4invite] the dialog has been replaced with the new one from 200ok\n", tr->transactionid));
714 }
715 }
716 }
717
718 if (jd != NULL) {
719 osip_header_t *se_exp = NULL;
720 osip_header_t *se_exp_answer = NULL;
721
722 _eXosip_check_allow_header(jd, sip);
723
724 osip_message_header_get_byname(tr->orig_request, "session-expires", 0, &se_exp);
725
726 if (se_exp == NULL)
727 osip_message_header_get_byname(tr->orig_request, "x", 0, &se_exp);
728
729 osip_message_header_get_byname(sip, "session-expires", 0, &se_exp_answer);
730
731 if (se_exp_answer == NULL)
732 osip_message_header_get_byname(sip, "x", 0, &se_exp_answer);
733
734 if (se_exp != NULL && se_exp_answer != NULL) {
735 osip_content_disposition_t *exp_h = NULL;
736
737 /* syntax of Session-Expires is equivalent to "Content-Disposition" */
738 osip_content_disposition_init(&exp_h);
739
740 if (exp_h != NULL) {
741 osip_content_disposition_parse(exp_h, se_exp_answer->hvalue);
742
743 if (exp_h->element != NULL) {
744 osip_generic_param_t *param = NULL;
745
746 osip_generic_param_get_byname(&exp_h->gen_params, "refresher", ¶m);
747
748 if (param == NULL) {
749 jd->d_refresher = 0; /* me? in which case? */
750
751 } else {
752 if (osip_strcasecmp(param->gvalue, "uac") == 0)
753 jd->d_refresher = 0;
754
755 else
756 jd->d_refresher = 1;
757 }
758
759 jd->d_session_timer_start = osip_getsystemtime(NULL);
760 jd->d_session_timer_length = atoi(exp_h->element);
761
762 if (jd->d_session_timer_length <= 90)
763 jd->d_session_timer_length = 90;
764 }
765
766 osip_content_disposition_free(exp_h);
767 exp_h = NULL;
768 }
769
770 } else if (se_exp != NULL && se_exp_answer == NULL && excontext->opt_sessiontimers_force > 0) {
771 /* not supported on remote end, but we want timer at UAC with */
772 osip_content_disposition_t *exp_h = NULL;
773
774 /* syntax of Session-Expires is equivalent to "Content-Disposition" */
775 osip_content_disposition_init(&exp_h);
776
777 if (exp_h != NULL) {
778 osip_content_disposition_parse(exp_h, se_exp->hvalue);
779
780 if (exp_h->element != NULL) {
781 jd->d_refresher = 0;
782 jd->d_session_timer_start = osip_getsystemtime(NULL);
783 jd->d_session_timer_length = atoi(exp_h->element);
784
785 if (jd->d_session_timer_length <= 90)
786 jd->d_session_timer_length = 90;
787 }
788
789 osip_content_disposition_free(exp_h);
790 exp_h = NULL;
791 }
792 }
793 }
794
795 /* _eXosip_dialog_set_200ok (jd, sip); */
796
797 _eXosip_report_call_event(excontext, EXOSIP_CALL_ANSWERED, jc, jd, tr);
798
799 /* look for the SDP information and decide if this answer was for
800 an initial INVITE, an HoldCall, or a RetreiveCall */
801
802 /* don't handle hold/unhold by now... */
803 /* _eXosip_update_audio_session(tr); */
804 }
805
806 #ifndef MINISIZE
cb_rcv2xx_4subscribe(osip_transaction_t * tr,osip_message_t * sip)807 static void cb_rcv2xx_4subscribe(osip_transaction_t *tr, osip_message_t *sip) {
808 struct eXosip_t *excontext = (struct eXosip_t *) osip_transaction_get_reserved1(tr);
809 int i;
810 eXosip_dialog_t *jd = (eXosip_dialog_t *) osip_transaction_get_reserved3(tr);
811 eXosip_subscribe_t *js = (eXosip_subscribe_t *) osip_transaction_get_reserved5(tr);
812
813 if (MSG_IS_RESPONSE_FOR(sip, "REFER")) {
814 osip_header_t *refer_sub;
815
816 osip_message_header_get_byname(sip, "Refer-Sub", 0, &refer_sub);
817
818 if (refer_sub != NULL && refer_sub->hvalue != NULL && osip_strncasecmp(refer_sub->hvalue, "false", 5) == 0) {
819 /* do not create JD, deletion will be immediate */
820 eXosip_event_t *je;
821
822 je = _eXosip_event_init_for_subscription(EXOSIP_SUBSCRIPTION_ANSWERED, js, jd, tr);
823 _eXosip_report_event(excontext, je);
824 return;
825 }
826 }
827
828 _eXosip_subscription_set_refresh_interval(js, sip);
829
830 /* for SUBSCRIBE, test if the dialog has been already created
831 with a previous NOTIFY */
832 if (jd == NULL && js != NULL && js->s_dialogs != NULL && (MSG_IS_RESPONSE_FOR(sip, "SUBSCRIBE") || MSG_IS_RESPONSE_FOR(sip, "REFER"))) {
833 /* find if existing dialog match the to tag */
834 osip_generic_param_t *tag;
835 int i;
836
837 i = osip_to_get_tag(sip->to, &tag);
838
839 if (i == 0 && tag != NULL && tag->gvalue != NULL) {
840 for (jd = js->s_dialogs; jd != NULL; jd = jd->next) {
841 if (0 == strcmp(jd->d_dialog->remote_tag, tag->gvalue)) {
842 OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_INFO1, NULL, "[eXosip] [tid=%i] [cb_rcv2xx_4subscribe] found established early dialog for this subscription\n", tr->transactionid));
843 osip_transaction_set_reserved3(tr, jd);
844 break;
845 }
846 }
847 }
848 }
849
850 if (jd == NULL) {
851 /* This transaction initiate a dialog in the case of
852 SUBSCRIBE (else it would be attached to a "jd" element. */
853 /* allocate a jd */
854 i = _eXosip_dialog_init_as_uac(&jd, sip);
855
856 if (i != 0) {
857 OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_ERROR, NULL, "[eXosip] [tid=%i] [cb_rcv2xx_4subscribe] cannot establish a dialog\n", tr->transactionid));
858 return;
859 }
860
861 ADD_ELEMENT(js->s_dialogs, jd);
862 osip_transaction_set_reserved3(tr, jd);
863 _eXosip_update(excontext);
864
865 } else {
866 osip_dialog_update_route_set_as_uac(jd->d_dialog, sip);
867
868 if (jd->d_dialog->remote_tag == NULL)
869 osip_dialog_update_tag_as_uac(jd->d_dialog, sip);
870
871 osip_dialog_set_state(jd->d_dialog, DIALOG_CONFIRMED);
872 }
873
874 /* look for the body information */
875
876 {
877 eXosip_event_t *je;
878
879 je = _eXosip_event_init_for_subscription(EXOSIP_SUBSCRIPTION_ANSWERED, js, jd, tr);
880 _eXosip_report_event(excontext, je);
881 }
882 }
883
884 #endif
885
_eXosip_update_expires_according_to_contact(eXosip_reg_t * jreg,osip_transaction_t * tr,osip_message_t * sip)886 static int _eXosip_update_expires_according_to_contact(eXosip_reg_t *jreg, osip_transaction_t *tr, osip_message_t *sip) {
887 osip_list_iterator_t it;
888 osip_contact_t *co_register;
889 int maxval = 0;
890
891 if (jreg == NULL)
892 return OSIP_BADPARAMETER;
893
894 /* only update if only one Contact was in INVITE */
895 if (tr->orig_request == NULL)
896 return OSIP_BADPARAMETER;
897
898 if (osip_list_size(&tr->orig_request->contacts) != 1)
899 return OSIP_SUCCESS;
900
901 /* search for matching contact (line parameter must be equal) */
902 co_register = (osip_contact_t *) osip_list_get_first(&sip->contacts, &it);
903
904 while (co_register != OSIP_SUCCESS) {
905 osip_uri_param_t *line_param = NULL;
906
907 if (co_register->url != NULL)
908 osip_uri_uparam_get_byname(co_register->url, "line", &line_param);
909
910 if (line_param != NULL && line_param->gvalue != NULL) {
911 if (osip_strcasecmp(jreg->r_line, line_param->gvalue) == 0) {
912 /* found contact */
913 int val;
914 osip_generic_param_t *exp_param = NULL;
915
916 osip_contact_param_get_byname(co_register, "expires", &exp_param);
917
918 if (exp_param != NULL && exp_param->gvalue != NULL) {
919 val = atoi(exp_param->gvalue);
920
921 if (val > maxval) {
922 maxval = val;
923 }
924 }
925 }
926 }
927
928 co_register = (osip_contact_t *) osip_list_get_next(&it);
929 }
930
931 if (maxval == 0)
932 return OSIP_NOTFOUND;
933
934 /* update only if expires value has REALLY be
935 decreased (more than one minutes):
936 In many cases value is decreased because a few seconds has
937 elapsed when server send the 200ok. */
938 if (maxval < jreg->r_reg_period - 15) {
939 jreg->r_reg_period = maxval;
940
941 } else if (maxval > jreg->r_reg_period) {
942 jreg->r_reg_period = maxval;
943 }
944
945 return OSIP_SUCCESS;
946 }
947
cb_rcv2xx(int type,osip_transaction_t * tr,osip_message_t * sip)948 static void cb_rcv2xx(int type, osip_transaction_t *tr, osip_message_t *sip) {
949 struct eXosip_t *excontext = (struct eXosip_t *) osip_transaction_get_reserved1(tr);
950 eXosip_call_t *jc = (eXosip_call_t *) osip_transaction_get_reserved2(tr);
951 eXosip_dialog_t *jd = (eXosip_dialog_t *) osip_transaction_get_reserved3(tr);
952
953 #ifndef MINISIZE
954 eXosip_subscribe_t *js = (eXosip_subscribe_t *) osip_transaction_get_reserved5(tr);
955 eXosip_notify_t *jn = (eXosip_notify_t *) osip_transaction_get_reserved4(tr);
956 #endif
957 osip_header_t *sub_state;
958 osip_header_t *refer_sub;
959 time_t now = osip_getsystemtime(NULL);
960
961 OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_INFO3, NULL, "[eXosip] [tid=%i] [cb_rcv2xx]\n", tr->transactionid));
962
963 #ifndef MINISIZE
964
965 if (MSG_IS_RESPONSE_FOR(sip, "PUBLISH")) {
966 eXosip_pub_t *pub = NULL;
967 eXosip_event_t *je;
968 int i;
969
970 i = _eXosip_pub_update(excontext, &pub, tr, sip);
971
972 if (i != 0) {
973 OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_ERROR, NULL, "[eXosip] [tid=%i] [cb_rcv2xx] no publication to update\n", tr->transactionid));
974 }
975
976 if (pub != NULL) {
977 /* update registration interval */
978 osip_header_t *exp;
979
980 osip_message_header_get_byname(sip, "expires", 0, &exp);
981
982 if (exp != NULL && exp->hvalue != NULL) {
983 int val = atoi(exp->hvalue);
984
985 if (val > 0) {
986 /* update only if expires value has REALLY be
987 decreased (more than one minutes):
988 In many cases value is decreased because a few seconds has
989 elapsed when server send the 200ok. */
990 if (val < pub->p_period - 15) {
991 pub->p_period = val;
992 }
993 }
994 }
995
996 pub->p_retry = 0; /* reset value */
997 }
998
999 je = _eXosip_event_init_for_message(EXOSIP_MESSAGE_ANSWERED, tr);
1000 _eXosip_report_event(excontext, je);
1001 return;
1002 }
1003
1004 #endif
1005
1006 if (MSG_IS_RESPONSE_FOR(sip, "REGISTER")) {
1007 eXosip_event_t *je;
1008 eXosip_reg_t *jreg = NULL;
1009
1010 /* find matching j_reg */
1011 _eXosip_reg_find(excontext, &jreg, tr);
1012
1013 if (jreg != NULL) {
1014 if (jreg->registration_step != RS_DELETIONPROCEEDING) { /* step to remove contact */
1015 /* update registration interval */
1016 osip_header_t *exp;
1017
1018 osip_message_header_get_byname(sip, "expires", 0, &exp);
1019
1020 if (exp != NULL && exp->hvalue != NULL) {
1021 int val = atoi(exp->hvalue);
1022
1023 if (val > 0) {
1024 /* update only if expires value has REALLY be
1025 decreased (more than one minutes):
1026 In many cases value is decreased because a few seconds has
1027 elapsed when server send the 200ok. */
1028 if (val < jreg->r_reg_period - 15) {
1029 jreg->r_reg_period = val;
1030 }
1031 }
1032 }
1033
1034 _eXosip_update_expires_according_to_contact(jreg, tr, sip);
1035 }
1036
1037 if (jreg->registration_step == RS_DELETIONPROCEEDING)
1038 jreg->registration_step = RS_MASQUERADINGREQUIRED; /* final registration with correct contact to be done */
1039
1040 if (jreg->registration_step > RS_MASQUERADINGREQUIRED)
1041 _eXosip_register_contact_is_modified(jreg, tr->orig_request, sip);
1042
1043 je = _eXosip_event_init_for_reg(EXOSIP_REGISTRATION_SUCCESS, jreg, tr);
1044 _eXosip_report_event(excontext, je);
1045 jreg->r_retry = 0; /* reset value */
1046 jreg->r_retryfailover = 0;
1047 }
1048
1049 return;
1050 }
1051
1052 if (jd != NULL)
1053 jd->d_retry = 0; /* reset marker for authentication */
1054
1055 if (jc != NULL)
1056 jc->c_retry = 0; /* reset marker for authentication */
1057
1058 #ifndef MINISIZE
1059
1060 if (js != NULL)
1061 js->s_retry = 0; /* reset marker for authentication */
1062
1063 #endif
1064
1065 if (MSG_IS_RESPONSE_FOR(sip, "INVITE")) {
1066 cb_rcv2xx_4invite(tr, sip);
1067 return;
1068 }
1069
1070 if (jc != NULL) {
1071 if (MSG_IS_RESPONSE_FOR(sip, "BYE")) {
1072 _eXosip_report_call_event(excontext, EXOSIP_CALL_MESSAGE_ANSWERED, jc, jd, tr);
1073 return;
1074 }
1075
1076 if (jd != NULL)
1077 _eXosip_check_allow_header(jd, sip);
1078
1079 if (MSG_IS_RESPONSE_FOR(sip, "UPDATE")) {
1080 if (jd != NULL) {
1081 osip_header_t *se_exp = NULL;
1082 osip_header_t *se_exp_answer = NULL;
1083
1084 osip_message_header_get_byname(tr->orig_request, "session-expires", 0, &se_exp);
1085
1086 if (se_exp == NULL)
1087 osip_message_header_get_byname(tr->orig_request, "x", 0, &se_exp);
1088
1089 osip_message_header_get_byname(sip, "session-expires", 0, &se_exp_answer);
1090
1091 if (se_exp_answer == NULL)
1092 osip_message_header_get_byname(sip, "x", 0, &se_exp_answer);
1093
1094 if (se_exp != NULL && se_exp_answer != NULL) {
1095 osip_content_disposition_t *exp_h = NULL;
1096
1097 /* syntax of Session-Expires is equivalent to "Content-Disposition" */
1098 osip_content_disposition_init(&exp_h);
1099
1100 if (exp_h != NULL) {
1101 osip_content_disposition_parse(exp_h, se_exp_answer->hvalue);
1102
1103 if (exp_h->element != NULL) {
1104 osip_generic_param_t *param = NULL;
1105
1106 osip_generic_param_get_byname(&exp_h->gen_params, "refresher", ¶m);
1107
1108 if (param == NULL) {
1109 jd->d_refresher = 0; /* me? in which case? */
1110
1111 } else {
1112 if (osip_strcasecmp(param->gvalue, "uac") == 0)
1113 jd->d_refresher = 0;
1114
1115 else
1116 jd->d_refresher = 1;
1117 }
1118
1119 jd->d_session_timer_start = osip_getsystemtime(NULL);
1120 jd->d_session_timer_length = atoi(exp_h->element);
1121
1122 if (jd->d_session_timer_length <= 90)
1123 jd->d_session_timer_length = 90;
1124 }
1125
1126 osip_content_disposition_free(exp_h);
1127 exp_h = NULL;
1128 }
1129
1130 } else if (se_exp != NULL && se_exp_answer == NULL && excontext->opt_sessiontimers_force > 0) {
1131 /* not supported on remote end, but we want timer at UAC with */
1132 osip_content_disposition_t *exp_h = NULL;
1133
1134 /* syntax of Session-Expires is equivalent to "Content-Disposition" */
1135 osip_content_disposition_init(&exp_h);
1136
1137 if (exp_h != NULL) {
1138 osip_content_disposition_parse(exp_h, se_exp->hvalue);
1139
1140 if (exp_h->element != NULL) {
1141 jd->d_refresher = 0;
1142 jd->d_session_timer_start = osip_getsystemtime(NULL);
1143 jd->d_session_timer_length = atoi(exp_h->element);
1144
1145 if (jd->d_session_timer_length <= 90)
1146 jd->d_session_timer_length = 90;
1147 }
1148
1149 osip_content_disposition_free(exp_h);
1150 exp_h = NULL;
1151 }
1152 }
1153 }
1154
1155 } else if (MSG_IS_RESPONSE_FOR(sip, "NOTIFY")) {
1156 if (jd != NULL) {
1157 /* get subscription-state */
1158 jd->implicit_subscription_expire_time = 0;
1159 osip_message_header_get_byname(tr->orig_request, "subscription-state", 0, &sub_state);
1160
1161 if (sub_state != NULL && sub_state->hvalue != NULL) {
1162 if (0 == osip_strncasecmp(sub_state->hvalue, "active", 6) || 0 == osip_strncasecmp(sub_state->hvalue, "pending", 7)) {
1163 const char *tmp = strstr(sub_state->hvalue + 6, "expires");
1164 const char *ss_expires = NULL;
1165
1166 if (tmp != NULL) {
1167 ss_expires = strchr(tmp + 7, '=');
1168 jd->implicit_subscription_expire_time = now + excontext->implicit_subscription_expires;
1169
1170 if (ss_expires != NULL) {
1171 int exp;
1172
1173 ss_expires++;
1174 exp = osip_atoi(ss_expires);
1175
1176 if (exp >= 0 && exp < 600) {
1177 jd->implicit_subscription_expire_time = now + exp;
1178 }
1179 }
1180 }
1181
1182 OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_INFO3, NULL, "[eXosip] [tid=%i] [cb_rcv2xx] dialog marked for implicit-subscription [did=%i]\n", tr->transactionid, jd->d_id));
1183 }
1184 }
1185 }
1186
1187 } else if (MSG_IS_RESPONSE_FOR(sip, "REFER")) {
1188 if (jd != NULL) {
1189 /* check for "Refer-Sub: false" */
1190 osip_message_header_get_byname(tr->orig_request, "Refer-Sub", 0, &refer_sub);
1191 jd->implicit_subscription_expire_time = now + excontext->implicit_subscription_expires;
1192
1193 if ((refer_sub != NULL) && (refer_sub->hvalue != NULL) && (0 == osip_strncasecmp(refer_sub->hvalue, "false", 5))) {
1194 /* implicit subscription removed */
1195 jd->implicit_subscription_expire_time = 0;
1196 OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_WARNING, NULL, "[eXosip] [tid=%i] [cb_rcv2xx] dialog un-marked for implicit-subscription [did=%i]\n", tr->transactionid, jd->d_id));
1197 }
1198 }
1199 }
1200
1201 _eXosip_report_call_event(excontext, EXOSIP_CALL_MESSAGE_ANSWERED, jc, jd, tr);
1202 return;
1203 }
1204
1205 #ifndef MINISIZE
1206
1207 if (js != NULL) {
1208 if (MSG_IS_RESPONSE_FOR(sip, "SUBSCRIBE") || MSG_IS_RESPONSE_FOR(sip, "REFER")) {
1209 cb_rcv2xx_4subscribe(tr, sip);
1210 return;
1211 }
1212
1213 return;
1214 }
1215
1216 if (jn != NULL) {
1217 if (MSG_IS_RESPONSE_FOR(sip, "NOTIFY") && jn != NULL) {
1218 eXosip_event_t *je;
1219 osip_header_t *sub_state;
1220
1221 je = _eXosip_event_init_for_notify(EXOSIP_NOTIFICATION_ANSWERED, jn, jd, tr);
1222 _eXosip_report_event(excontext, je);
1223
1224 osip_message_header_get_byname(tr->orig_request, "subscription-state", 0, &sub_state);
1225
1226 if (sub_state == NULL || sub_state->hvalue == NULL) {
1227 /* UNCOMPLIANT UA without a subscription-state header */
1228 } else if (0 == osip_strncasecmp(sub_state->hvalue, "terminated", 10)) {
1229 /* delete the dialog! */
1230 if (jn != NULL) {
1231 REMOVE_ELEMENT(excontext->j_notifies, jn);
1232 _eXosip_notify_free(excontext, jn);
1233 }
1234 }
1235
1236 return;
1237 }
1238
1239 return;
1240 }
1241
1242 #endif
1243
1244 {
1245 eXosip_event_t *je;
1246
1247 /* For all requests outside of calls */
1248 je = _eXosip_event_init_for_message(EXOSIP_MESSAGE_ANSWERED, tr);
1249 _eXosip_report_event(excontext, je);
1250 return;
1251 }
1252 }
1253
_eXosip_delete_early_dialog(struct eXosip_t * excontext,eXosip_dialog_t * jd)1254 static void _eXosip_delete_early_dialog(struct eXosip_t *excontext, eXosip_dialog_t *jd) {
1255 if (jd == NULL) /* bug? */
1256 return;
1257
1258 /* an early dialog was created, but the call is not established */
1259 if (jd->d_dialog != NULL && jd->d_dialog->state == DIALOG_EARLY) {
1260 osip_dialog_free(jd->d_dialog);
1261 jd->d_dialog = NULL;
1262 _eXosip_update(excontext); /* AMD 30/09/05 */
1263 }
1264 }
1265
rcvregister_failure(osip_transaction_t * tr,osip_message_t * sip)1266 static void rcvregister_failure(osip_transaction_t *tr, osip_message_t *sip) {
1267 struct eXosip_t *excontext = (struct eXosip_t *) osip_transaction_get_reserved1(tr);
1268 eXosip_event_t *je;
1269 eXosip_reg_t *jreg = NULL;
1270
1271 /* find matching j_reg */
1272 _eXosip_reg_find(excontext, &jreg, tr);
1273
1274 if (jreg != NULL) {
1275 /* proceed with deletion and re-registration of new contact */
1276 if (jreg->registration_step > RS_MASQUERADINGREQUIRED && sip != NULL)
1277 _eXosip_register_contact_is_modified(jreg, tr->orig_request, sip);
1278
1279 je = _eXosip_event_init_for_reg(EXOSIP_REGISTRATION_FAILURE, jreg, tr);
1280 _eXosip_report_event(excontext, je);
1281
1282 if (tr->naptr_record != NULL && sip != NULL && sip->status_code == 503) {
1283 /* no matter which one, we'll move them all */
1284 osip_gettimeofday(&tr->naptr_record->sipudp_record.srventry[tr->naptr_record->sipudp_record.index].srv_is_broken, NULL);
1285 osip_gettimeofday(&tr->naptr_record->siptcp_record.srventry[tr->naptr_record->siptcp_record.index].srv_is_broken, NULL);
1286 osip_gettimeofday(&tr->naptr_record->siptls_record.srventry[tr->naptr_record->siptls_record.index].srv_is_broken, NULL);
1287 osip_gettimeofday(&tr->naptr_record->sipdtls_record.srventry[tr->naptr_record->sipdtls_record.index].srv_is_broken, NULL);
1288 osip_gettimeofday(&tr->naptr_record->sipsctp_record.srventry[tr->naptr_record->sipsctp_record.index].srv_is_broken, NULL);
1289 _eXosip_mark_registration_expired(excontext, sip->call_id->number);
1290 }
1291 }
1292 }
1293
1294 #ifndef MINISIZE
1295
cb_rcv3xx(int type,osip_transaction_t * tr,osip_message_t * sip)1296 static void cb_rcv3xx(int type, osip_transaction_t *tr, osip_message_t *sip) {
1297 struct eXosip_t *excontext = (struct eXosip_t *) osip_transaction_get_reserved1(tr);
1298 eXosip_call_t *jc = (eXosip_call_t *) osip_transaction_get_reserved2(tr);
1299 eXosip_dialog_t *jd = (eXosip_dialog_t *) osip_transaction_get_reserved3(tr);
1300 eXosip_subscribe_t *js = (eXosip_subscribe_t *) osip_transaction_get_reserved5(tr);
1301 eXosip_notify_t *jn = (eXosip_notify_t *) osip_transaction_get_reserved4(tr);
1302
1303 OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_INFO3, NULL, "[eXosip] [tid=%i] [cb_rcv3xx]\n", tr->transactionid));
1304
1305 if (MSG_IS_RESPONSE_FOR(sip, "PUBLISH")) {
1306 eXosip_event_t *je;
1307 eXosip_pub_t *pub;
1308 int i;
1309
1310 i = _eXosip_pub_update(excontext, &pub, tr, sip);
1311
1312 if (i != 0) {
1313 OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_ERROR, NULL, "[eXosip] [tid=%i] [cb_rcv3xx] no publication to update\n", tr->transactionid));
1314 }
1315
1316 je = _eXosip_event_init_for_message(EXOSIP_MESSAGE_REDIRECTED, tr);
1317 _eXosip_report_event(excontext, je);
1318 return;
1319 }
1320
1321 if (MSG_IS_RESPONSE_FOR(sip, "REGISTER")) {
1322 rcvregister_failure(tr, sip);
1323 return;
1324 }
1325
1326 if (MSG_IS_RESPONSE_FOR(sip, "INVITE")) {
1327 _eXosip_report_call_event(excontext, EXOSIP_CALL_REDIRECTED, jc, jd, tr);
1328
1329 } else if (MSG_IS_RESPONSE_FOR(sip, "NOTIFY") && jn != NULL) {
1330 eXosip_event_t *je;
1331
1332 je = _eXosip_event_init_for_notify(EXOSIP_NOTIFICATION_REDIRECTED, jn, jd, tr);
1333 _eXosip_report_event(excontext, je);
1334
1335 } else if (js != NULL && (MSG_IS_RESPONSE_FOR(sip, "SUBSCRIBE") || MSG_IS_RESPONSE_FOR(sip, "REFER"))) {
1336 eXosip_event_t *je;
1337
1338 je = _eXosip_event_init_for_subscription(EXOSIP_SUBSCRIPTION_REDIRECTED, js, jd, tr);
1339 _eXosip_report_event(excontext, je);
1340
1341 } else if (jc != NULL) {
1342 _eXosip_report_call_event(excontext, EXOSIP_CALL_MESSAGE_REDIRECTED, jc, jd, tr);
1343 return;
1344
1345 } else if (jc == NULL && js == NULL && jn == NULL) {
1346 eXosip_event_t *je;
1347
1348 /* For all requests outside of calls */
1349 je = _eXosip_event_init_for_message(EXOSIP_MESSAGE_REDIRECTED, tr);
1350 _eXosip_report_event(excontext, je);
1351 return;
1352 }
1353
1354 if (jd == NULL)
1355 return;
1356
1357 if (MSG_IS_RESPONSE_FOR(sip, "INVITE") || MSG_IS_RESPONSE_FOR(sip, "REFER") || MSG_IS_RESPONSE_FOR(sip, "SUBSCRIBE")) {
1358 _eXosip_delete_early_dialog(excontext, jd);
1359 }
1360 }
1361
cb_rcv4xx(int type,osip_transaction_t * tr,osip_message_t * sip)1362 static void cb_rcv4xx(int type, osip_transaction_t *tr, osip_message_t *sip) {
1363 struct eXosip_t *excontext = (struct eXosip_t *) osip_transaction_get_reserved1(tr);
1364 eXosip_call_t *jc = (eXosip_call_t *) osip_transaction_get_reserved2(tr);
1365 eXosip_dialog_t *jd = (eXosip_dialog_t *) osip_transaction_get_reserved3(tr);
1366 eXosip_subscribe_t *js = (eXosip_subscribe_t *) osip_transaction_get_reserved5(tr);
1367 eXosip_notify_t *jn = (eXosip_notify_t *) osip_transaction_get_reserved4(tr);
1368
1369 OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_INFO3, NULL, "[eXosip] [tid=%i] [cb_rcv4xx]\n", tr->transactionid));
1370
1371 if (MSG_IS_RESPONSE_FOR(sip, "PUBLISH")) {
1372 eXosip_pub_t *pub;
1373 eXosip_event_t *je;
1374 int i;
1375
1376 i = _eXosip_pub_update(excontext, &pub, tr, sip);
1377
1378 if (i != 0) {
1379 OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_ERROR, NULL, "[eXosip] [tid=%i] [cb_rcv4xx] no publication to update\n", tr->transactionid));
1380 }
1381
1382 /* For all requests outside of calls */
1383 je = _eXosip_event_init_for_message(EXOSIP_MESSAGE_REQUESTFAILURE, tr);
1384 _eXosip_report_event(excontext, je);
1385 return;
1386 }
1387
1388 if (MSG_IS_RESPONSE_FOR(sip, "REGISTER")) {
1389 rcvregister_failure(tr, sip);
1390 return;
1391 }
1392
1393 if (MSG_IS_RESPONSE_FOR(sip, "INVITE")) {
1394 _eXosip_report_call_event(excontext, EXOSIP_CALL_REQUESTFAILURE, jc, jd, tr);
1395
1396 } else if (MSG_IS_RESPONSE_FOR(sip, "NOTIFY") && jn != NULL) {
1397 eXosip_event_t *je;
1398
1399 je = _eXosip_event_init_for_notify(EXOSIP_NOTIFICATION_REQUESTFAILURE, jn, jd, tr);
1400 _eXosip_report_event(excontext, je);
1401
1402 } else if (js != NULL && (MSG_IS_RESPONSE_FOR(sip, "SUBSCRIBE") || MSG_IS_RESPONSE_FOR(sip, "REFER"))) {
1403 eXosip_event_t *je;
1404
1405 je = _eXosip_event_init_for_subscription(EXOSIP_SUBSCRIPTION_REQUESTFAILURE, js, jd, tr);
1406 _eXosip_report_event(excontext, je);
1407
1408 } else if (jc != NULL) {
1409 _eXosip_report_call_event(excontext, EXOSIP_CALL_MESSAGE_REQUESTFAILURE, jc, jd, tr);
1410 return;
1411
1412 } else if (jc == NULL && js == NULL && jn == NULL) {
1413 eXosip_event_t *je;
1414
1415 /* For all requests outside of calls */
1416 je = _eXosip_event_init_for_message(EXOSIP_MESSAGE_REQUESTFAILURE, tr);
1417 _eXosip_report_event(excontext, je);
1418 return;
1419 }
1420
1421 if (jd == NULL)
1422 return;
1423
1424 if (MSG_IS_RESPONSE_FOR(sip, "INVITE") || MSG_IS_RESPONSE_FOR(sip, "REFER") || MSG_IS_RESPONSE_FOR(sip, "SUBSCRIBE")) {
1425 _eXosip_delete_early_dialog(excontext, jd);
1426 }
1427 }
1428
cb_rcv5xx(int type,osip_transaction_t * tr,osip_message_t * sip)1429 static void cb_rcv5xx(int type, osip_transaction_t *tr, osip_message_t *sip) {
1430 struct eXosip_t *excontext = (struct eXosip_t *) osip_transaction_get_reserved1(tr);
1431 eXosip_call_t *jc = (eXosip_call_t *) osip_transaction_get_reserved2(tr);
1432 eXosip_dialog_t *jd = (eXosip_dialog_t *) osip_transaction_get_reserved3(tr);
1433 eXosip_subscribe_t *js = (eXosip_subscribe_t *) osip_transaction_get_reserved5(tr);
1434 eXosip_notify_t *jn = (eXosip_notify_t *) osip_transaction_get_reserved4(tr);
1435
1436 OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_INFO3, NULL, "[eXosip] [tid=%i] [cb_rcv5xx]\n", tr->transactionid));
1437
1438 if (MSG_IS_RESPONSE_FOR(sip, "PUBLISH")) {
1439 eXosip_pub_t *pub;
1440 eXosip_event_t *je;
1441 int i;
1442
1443 i = _eXosip_pub_update(excontext, &pub, tr, sip);
1444
1445 if (i != 0) {
1446 OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_ERROR, NULL, "[eXosip] [tid=%i] [cb_rcv5xx] no publication to update\n", tr->transactionid));
1447 }
1448
1449 je = _eXosip_event_init_for_message(EXOSIP_MESSAGE_SERVERFAILURE, tr);
1450 _eXosip_report_event(excontext, je);
1451 return;
1452 }
1453
1454 if (MSG_IS_RESPONSE_FOR(sip, "REGISTER")) {
1455 rcvregister_failure(tr, sip);
1456 return;
1457 }
1458
1459 if (MSG_IS_RESPONSE_FOR(sip, "INVITE")) {
1460 _eXosip_report_call_event(excontext, EXOSIP_CALL_SERVERFAILURE, jc, jd, tr);
1461
1462 } else if (MSG_IS_RESPONSE_FOR(sip, "NOTIFY") && jn != NULL) {
1463 eXosip_event_t *je;
1464
1465 je = _eXosip_event_init_for_notify(EXOSIP_NOTIFICATION_SERVERFAILURE, jn, jd, tr);
1466 _eXosip_report_event(excontext, je);
1467
1468 } else if (js != NULL && (MSG_IS_RESPONSE_FOR(sip, "SUBSCRIBE") || MSG_IS_RESPONSE_FOR(sip, "REFER"))) {
1469 eXosip_event_t *je;
1470
1471 je = _eXosip_event_init_for_subscription(EXOSIP_SUBSCRIPTION_SERVERFAILURE, js, jd, tr);
1472 _eXosip_report_event(excontext, je);
1473
1474 } else if (jc != NULL) {
1475 _eXosip_report_call_event(excontext, EXOSIP_CALL_MESSAGE_SERVERFAILURE, jc, jd, tr);
1476 return;
1477
1478 } else if (jc == NULL && js == NULL && jn == NULL) {
1479 eXosip_event_t *je;
1480
1481 /* For all requests outside of calls */
1482 je = _eXosip_event_init_for_message(EXOSIP_MESSAGE_SERVERFAILURE, tr);
1483 _eXosip_report_event(excontext, je);
1484 return;
1485 }
1486
1487 if (jd == NULL)
1488 return;
1489
1490 if (MSG_IS_RESPONSE_FOR(sip, "INVITE") || MSG_IS_RESPONSE_FOR(sip, "REFER") || MSG_IS_RESPONSE_FOR(sip, "SUBSCRIBE")) {
1491 _eXosip_delete_early_dialog(excontext, jd);
1492 }
1493 }
1494
cb_rcv6xx(int type,osip_transaction_t * tr,osip_message_t * sip)1495 static void cb_rcv6xx(int type, osip_transaction_t *tr, osip_message_t *sip) {
1496 struct eXosip_t *excontext = (struct eXosip_t *) osip_transaction_get_reserved1(tr);
1497 eXosip_call_t *jc = (eXosip_call_t *) osip_transaction_get_reserved2(tr);
1498 eXosip_dialog_t *jd = (eXosip_dialog_t *) osip_transaction_get_reserved3(tr);
1499 eXosip_subscribe_t *js = (eXosip_subscribe_t *) osip_transaction_get_reserved5(tr);
1500 eXosip_notify_t *jn = (eXosip_notify_t *) osip_transaction_get_reserved4(tr);
1501
1502 OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_INFO3, NULL, "[eXosip] [tid=%i] [cb_rcv6xx]\n", tr->transactionid));
1503
1504 if (MSG_IS_RESPONSE_FOR(sip, "PUBLISH")) {
1505 eXosip_pub_t *pub;
1506 eXosip_event_t *je;
1507 int i;
1508
1509 i = _eXosip_pub_update(excontext, &pub, tr, sip);
1510
1511 if (i != 0) {
1512 OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_ERROR, NULL, "[eXosip] [tid=%i] [cb_rcv6xx] no publication to update\n", tr->transactionid));
1513 }
1514
1515 je = _eXosip_event_init_for_message(EXOSIP_MESSAGE_GLOBALFAILURE, tr);
1516 _eXosip_report_event(excontext, je);
1517 return;
1518 }
1519
1520 if (MSG_IS_RESPONSE_FOR(sip, "REGISTER")) {
1521 rcvregister_failure(tr, sip);
1522 return;
1523 }
1524
1525 if (MSG_IS_RESPONSE_FOR(sip, "INVITE")) {
1526 _eXosip_report_call_event(excontext, EXOSIP_CALL_GLOBALFAILURE, jc, jd, tr);
1527
1528 } else if (MSG_IS_RESPONSE_FOR(sip, "NOTIFY") && jn != NULL) {
1529 eXosip_event_t *je;
1530
1531 je = _eXosip_event_init_for_notify(EXOSIP_NOTIFICATION_GLOBALFAILURE, jn, jd, tr);
1532 _eXosip_report_event(excontext, je);
1533
1534 } else if (js != NULL && (MSG_IS_RESPONSE_FOR(sip, "SUBSCRIBE") || MSG_IS_RESPONSE_FOR(sip, "REFER"))) {
1535 eXosip_event_t *je;
1536
1537 je = _eXosip_event_init_for_subscription(EXOSIP_SUBSCRIPTION_GLOBALFAILURE, js, jd, tr);
1538 _eXosip_report_event(excontext, je);
1539
1540 } else if (jc != NULL) {
1541 _eXosip_report_call_event(excontext, EXOSIP_CALL_MESSAGE_GLOBALFAILURE, jc, jd, tr);
1542 return;
1543
1544 } else if (jc == NULL && js == NULL && jn == NULL) {
1545 eXosip_event_t *je;
1546
1547 /* For all requests outside of calls */
1548 je = _eXosip_event_init_for_message(EXOSIP_MESSAGE_GLOBALFAILURE, tr);
1549 _eXosip_report_event(excontext, je);
1550 return;
1551 }
1552
1553 if (jd == NULL)
1554 return;
1555
1556 if (MSG_IS_RESPONSE_FOR(sip, "INVITE") || MSG_IS_RESPONSE_FOR(sip, "REFER") || MSG_IS_RESPONSE_FOR(sip, "SUBSCRIBE")) {
1557 _eXosip_delete_early_dialog(excontext, jd);
1558 }
1559 }
1560
1561 #else
1562
1563 static void cb_rcv3456xx(int type, osip_transaction_t *tr, osip_message_t *sip, int invite_event, int call_event, int outcall_event);
1564
cb_rcv3456xx(int type,osip_transaction_t * tr,osip_message_t * sip,int invite_event,int call_event,int outcall_event)1565 static void cb_rcv3456xx(int type, osip_transaction_t *tr, osip_message_t *sip, int invite_event, int call_event, int outcall_event) {
1566 struct eXosip_t *excontext = (struct eXosip_t *) osip_transaction_get_reserved1(tr);
1567 eXosip_call_t *jc = (eXosip_call_t *) osip_transaction_get_reserved2(tr);
1568 eXosip_dialog_t *jd = (eXosip_dialog_t *) osip_transaction_get_reserved3(tr);
1569
1570 OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_INFO3, NULL, "[eXosip] [tid=%i] [cb_rcv3456xx]\n", tr->transactionid));
1571
1572 if (MSG_IS_RESPONSE_FOR(sip, "REGISTER")) {
1573 rcvregister_failure(tr, sip);
1574 return;
1575 }
1576
1577 if (MSG_IS_RESPONSE_FOR(sip, "INVITE")) {
1578 _eXosip_report_call_event(excontext, invite_event, jc, jd, tr);
1579
1580 } else if (jc != NULL) {
1581 _eXosip_report_call_event(excontext, call_event, jc, jd, tr);
1582 return;
1583
1584 } else if (jc == NULL) {
1585 eXosip_event_t *je;
1586
1587 /* For all requests outside of calls */
1588 je = _eXosip_event_init_for_message(outcall_event, tr);
1589 _eXosip_report_event(excontext, je);
1590 return;
1591 }
1592
1593 if (jd == NULL)
1594 return;
1595
1596 if (MSG_IS_RESPONSE_FOR(sip, "INVITE")) {
1597 _eXosip_delete_early_dialog(excontext, jd);
1598 }
1599 }
1600
cb_rcv3xx(int type,osip_transaction_t * tr,osip_message_t * sip)1601 static void cb_rcv3xx(int type, osip_transaction_t *tr, osip_message_t *sip) {
1602 cb_rcv3456xx(type, tr, sip, EXOSIP_CALL_REDIRECTED, EXOSIP_CALL_MESSAGE_REDIRECTED, EXOSIP_MESSAGE_REDIRECTED);
1603 }
1604
cb_rcv4xx(int type,osip_transaction_t * tr,osip_message_t * sip)1605 static void cb_rcv4xx(int type, osip_transaction_t *tr, osip_message_t *sip) {
1606 cb_rcv3456xx(type, tr, sip, EXOSIP_CALL_REQUESTFAILURE, EXOSIP_CALL_MESSAGE_REQUESTFAILURE, EXOSIP_MESSAGE_REQUESTFAILURE);
1607 }
1608
cb_rcv5xx(int type,osip_transaction_t * tr,osip_message_t * sip)1609 static void cb_rcv5xx(int type, osip_transaction_t *tr, osip_message_t *sip) {
1610 cb_rcv3456xx(type, tr, sip, EXOSIP_CALL_SERVERFAILURE, EXOSIP_CALL_MESSAGE_SERVERFAILURE, EXOSIP_MESSAGE_SERVERFAILURE);
1611 }
1612
cb_rcv6xx(int type,osip_transaction_t * tr,osip_message_t * sip)1613 static void cb_rcv6xx(int type, osip_transaction_t *tr, osip_message_t *sip) {
1614 cb_rcv3456xx(type, tr, sip, EXOSIP_CALL_GLOBALFAILURE, EXOSIP_CALL_MESSAGE_GLOBALFAILURE, EXOSIP_MESSAGE_GLOBALFAILURE);
1615 }
1616
1617 #endif
1618
cb_snd123456xx(int type,osip_transaction_t * tr,osip_message_t * sip)1619 static void cb_snd123456xx(int type, osip_transaction_t *tr, osip_message_t *sip) {
1620 struct eXosip_t *excontext = (struct eXosip_t *) osip_transaction_get_reserved1(tr);
1621 eXosip_call_t *jc = (eXosip_call_t *) osip_transaction_get_reserved2(tr);
1622 eXosip_dialog_t *jd = (eXosip_dialog_t *) osip_transaction_get_reserved3(tr);
1623
1624 OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_INFO3, NULL, "[eXosip] [tid=%i] [cb_snd123456xx]\n", tr->transactionid));
1625
1626 if (jd == NULL)
1627 return;
1628
1629 if (type == OSIP_IST_STATUS_1XX_SENT || type == OSIP_NIST_STATUS_1XX_SENT) {
1630 return;
1631 }
1632
1633 if (type == OSIP_IST_STATUS_2XX_SENT || type == OSIP_NIST_STATUS_2XX_SENT) {
1634 return;
1635 }
1636
1637 if (MSG_IS_RESPONSE_FOR(sip, "INVITE") || MSG_IS_RESPONSE_FOR(sip, "REFER") || MSG_IS_RESPONSE_FOR(sip, "SUBSCRIBE")) {
1638 _eXosip_delete_early_dialog(excontext, jd);
1639 }
1640
1641 if (MSG_IS_RESPONSE_FOR(sip, "INVITE")) {
1642 /* only close calls if this is the initial INVITE */
1643 if (jc != NULL && tr == jc->c_inc_tr) {
1644 _eXosip_report_call_event(excontext, EXOSIP_CALL_CLOSED, jc, jd, tr);
1645 }
1646 }
1647 }
1648
1649 #ifndef MINISIZE
1650
cb_rcvinvite(int type,osip_transaction_t * tr,osip_message_t * sip)1651 static void cb_rcvinvite(int type, osip_transaction_t *tr, osip_message_t *sip) {
1652 OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_INFO3, NULL, "[eXosip] [tid=%i] [cb_rcvinvite]\n", tr->transactionid));
1653 }
1654
cb_rcvack(int type,osip_transaction_t * tr,osip_message_t * sip)1655 static void cb_rcvack(int type, osip_transaction_t *tr, osip_message_t *sip) {
1656 OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_INFO3, NULL, "[eXosip] [tid=%i] [cb_rcvack]\n", tr->transactionid));
1657 }
1658
cb_rcvack2(int type,osip_transaction_t * tr,osip_message_t * sip)1659 static void cb_rcvack2(int type, osip_transaction_t *tr, osip_message_t *sip) {
1660 OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_INFO3, NULL, "[eXosip] [tid=%i] [cb_rcvack2]\n", tr->transactionid));
1661 }
1662
cb_sndinvite(int type,osip_transaction_t * tr,osip_message_t * sip)1663 static void cb_sndinvite(int type, osip_transaction_t *tr, osip_message_t *sip) {
1664 OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_INFO3, NULL, "[eXosip] [tid=%i] [cb_sndinvite]\n", tr->transactionid));
1665 }
1666
cb_sndack(int type,osip_transaction_t * tr,osip_message_t * sip)1667 static void cb_sndack(int type, osip_transaction_t *tr, osip_message_t *sip) {
1668 OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_INFO3, NULL, "[eXosip] [tid=%i] [cb_sndack]\n", tr->transactionid));
1669 }
1670
cb_sndregister(int type,osip_transaction_t * tr,osip_message_t * sip)1671 static void cb_sndregister(int type, osip_transaction_t *tr, osip_message_t *sip) {
1672 OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_INFO3, NULL, "[eXosip] [tid=%i] [cb_sndregister]\n", tr->transactionid));
1673 }
1674
cb_sndbye(int type,osip_transaction_t * tr,osip_message_t * sip)1675 static void cb_sndbye(int type, osip_transaction_t *tr, osip_message_t *sip) {
1676 OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_INFO3, NULL, "[eXosip] [tid=%i] [cb_sndbye]\n", tr->transactionid));
1677 }
1678
cb_sndcancel(int type,osip_transaction_t * tr,osip_message_t * sip)1679 static void cb_sndcancel(int type, osip_transaction_t *tr, osip_message_t *sip) {
1680 OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_INFO3, NULL, "[eXosip] [tid=%i] [cb_sndcancel]\n", tr->transactionid));
1681 }
1682
cb_sndinfo(int type,osip_transaction_t * tr,osip_message_t * sip)1683 static void cb_sndinfo(int type, osip_transaction_t *tr, osip_message_t *sip) {
1684 OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_INFO3, NULL, "[eXosip] [tid=%i] [cb_sndinfo]\n", tr->transactionid));
1685 }
1686
cb_sndoptions(int type,osip_transaction_t * tr,osip_message_t * sip)1687 static void cb_sndoptions(int type, osip_transaction_t *tr, osip_message_t *sip) {
1688 OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_INFO3, NULL, "[eXosip] [tid=%i] [cb_sndoptions]\n", tr->transactionid));
1689 }
1690
cb_sndnotify(int type,osip_transaction_t * tr,osip_message_t * sip)1691 static void cb_sndnotify(int type, osip_transaction_t *tr, osip_message_t *sip) {
1692 OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_INFO3, NULL, "[eXosip] [tid=%i] [cb_sndnotify]\n", tr->transactionid));
1693 }
1694
cb_sndsubscribe(int type,osip_transaction_t * tr,osip_message_t * sip)1695 static void cb_sndsubscribe(int type, osip_transaction_t *tr, osip_message_t *sip) {
1696 OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_INFO3, NULL, "[eXosip] [tid=%i] [cb_sndsubscribe]\n", tr->transactionid));
1697 }
1698
cb_sndunkrequest(int type,osip_transaction_t * tr,osip_message_t * sip)1699 static void cb_sndunkrequest(int type, osip_transaction_t *tr, osip_message_t *sip) {
1700 OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_INFO3, NULL, "[eXosip] [tid=%i] [cb_sndunkrequest]\n", tr->transactionid));
1701 }
1702
cb_rcvresp_retransmission(int type,osip_transaction_t * tr,osip_message_t * sip)1703 static void cb_rcvresp_retransmission(int type, osip_transaction_t *tr, osip_message_t *sip) {
1704 OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_INFO1, NULL, "[eXosip] [tid=%i] [cb_rcvresp_retransmission]\n", tr->transactionid));
1705 }
1706
cb_sndreq_retransmission(int type,osip_transaction_t * tr,osip_message_t * sip)1707 static void cb_sndreq_retransmission(int type, osip_transaction_t *tr, osip_message_t *sip) {
1708 OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_INFO1, NULL, "[eXosip] [tid=%i] [cb_sndreq_retransmission]\n", tr->transactionid));
1709 }
1710
cb_sndresp_retransmission(int type,osip_transaction_t * tr,osip_message_t * sip)1711 static void cb_sndresp_retransmission(int type, osip_transaction_t *tr, osip_message_t *sip) {
1712 OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_INFO1, NULL, "[eXosip] [tid=%i] [cb_sndresp_retransmission]\n", tr->transactionid));
1713 }
1714
cb_rcvreq_retransmission(int type,osip_transaction_t * tr,osip_message_t * sip)1715 static void cb_rcvreq_retransmission(int type, osip_transaction_t *tr, osip_message_t *sip) {
1716 OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_INFO1, NULL, "[eXosip] [tid=%i] [cb_rcvreq_retransmission]\n", tr->transactionid));
1717 }
1718
1719 #endif
1720
cb_transport_error(int type,osip_transaction_t * tr,int error)1721 static void cb_transport_error(int type, osip_transaction_t *tr, int error) {
1722 struct eXosip_t *excontext = (struct eXosip_t *) osip_transaction_get_reserved1(tr);
1723
1724 #ifndef MINISIZE
1725 eXosip_subscribe_t *js = (eXosip_subscribe_t *) osip_transaction_get_reserved5(tr);
1726 eXosip_notify_t *jn = (eXosip_notify_t *) osip_transaction_get_reserved4(tr);
1727 #endif
1728
1729 OSIP_TRACE(osip_trace(__FILE__, __LINE__, OSIP_INFO1, NULL, "[eXosip] [tid=%i] [cb_transport_error]\n", tr->transactionid));
1730
1731 if (type == OSIP_ICT_TRANSPORT_ERROR) {
1732 eXosip_call_t *jc = (eXosip_call_t *) osip_transaction_get_reserved2(tr);
1733 eXosip_dialog_t *jd = (eXosip_dialog_t *) osip_transaction_get_reserved3(tr);
1734
1735 if (jc == NULL && jd == NULL)
1736 return;
1737
1738 _eXosip_report_call_event(excontext, EXOSIP_CALL_NOANSWER, jc, jd, tr);
1739 }
1740
1741 if (type == OSIP_NICT_TRANSPORT_ERROR) {
1742 osip_naptr_t *naptr_record = tr->naptr_record;
1743 if (naptr_record != NULL && naptr_record->naptr_state == OSIP_NAPTR_STATE_SRVDONE && (MSG_IS_REGISTER(tr->orig_request) || MSG_IS_OPTIONS(tr->orig_request))) {
1744
1745 if (osip_strcasecmp(excontext->eXtl_transport.proto_name, "UDP") == 0)
1746 eXosip_dnsutils_rotate_srv(&naptr_record->sipudp_record);
1747 else if (osip_strcasecmp(excontext->eXtl_transport.proto_name, "TCP") == 0)
1748 eXosip_dnsutils_rotate_srv(&naptr_record->siptcp_record);
1749 else if (osip_strcasecmp(excontext->eXtl_transport.proto_name, "TLS") == 0)
1750 eXosip_dnsutils_rotate_srv(&naptr_record->siptls_record);
1751 else if (osip_strcasecmp(excontext->eXtl_transport.proto_name, "DTLS-UDP") == 0)
1752 eXosip_dnsutils_rotate_srv(&naptr_record->sipdtls_record);
1753 }
1754 }
1755 #ifndef MINISIZE
1756
1757 if (jn == NULL && js == NULL)
1758 return;
1759
1760 if (jn != NULL && MSG_IS_NOTIFY(tr->orig_request) && type == OSIP_NICT_TRANSPORT_ERROR) {
1761 /* delete the dialog! */
1762 REMOVE_ELEMENT(excontext->j_notifies, jn);
1763 _eXosip_notify_free(excontext, jn);
1764 }
1765
1766 if (js != NULL && (MSG_IS_SUBSCRIBE(tr->orig_request) || MSG_IS_REFER(tr->orig_request)) && type == OSIP_NICT_TRANSPORT_ERROR) {
1767 /* delete the dialog! */
1768 REMOVE_ELEMENT(excontext->j_subscribes, js);
1769 _eXosip_subscription_free(excontext, js);
1770 }
1771
1772 #endif
1773 }
1774
_eXosip_set_callbacks(osip_t * osip)1775 int _eXosip_set_callbacks(osip_t *osip) {
1776 /* register all callbacks */
1777
1778 osip_set_cb_send_message(osip, &cb_snd_message);
1779
1780 osip_set_kill_transaction_callback(osip, OSIP_ICT_KILL_TRANSACTION, &cb_xixt_kill_transaction);
1781 osip_set_kill_transaction_callback(osip, OSIP_IST_KILL_TRANSACTION, &cb_xixt_kill_transaction);
1782 osip_set_kill_transaction_callback(osip, OSIP_NICT_KILL_TRANSACTION, &cb_xixt_kill_transaction);
1783 osip_set_kill_transaction_callback(osip, OSIP_NIST_KILL_TRANSACTION, &cb_xixt_kill_transaction);
1784
1785 osip_set_message_callback(osip, OSIP_ICT_STATUS_1XX_RECEIVED, &cb_rcv1xx);
1786 osip_set_message_callback(osip, OSIP_ICT_STATUS_2XX_RECEIVED, &cb_rcv2xx);
1787 osip_set_message_callback(osip, OSIP_ICT_STATUS_3XX_RECEIVED, &cb_rcv3xx);
1788 osip_set_message_callback(osip, OSIP_ICT_STATUS_4XX_RECEIVED, &cb_rcv4xx);
1789 osip_set_message_callback(osip, OSIP_ICT_STATUS_5XX_RECEIVED, &cb_rcv5xx);
1790 osip_set_message_callback(osip, OSIP_ICT_STATUS_6XX_RECEIVED, &cb_rcv6xx);
1791
1792 osip_set_message_callback(osip, OSIP_IST_STATUS_1XX_SENT, &cb_snd123456xx);
1793 osip_set_message_callback(osip, OSIP_IST_STATUS_2XX_SENT, &cb_snd123456xx);
1794 osip_set_message_callback(osip, OSIP_IST_STATUS_3XX_SENT, &cb_snd123456xx);
1795 osip_set_message_callback(osip, OSIP_IST_STATUS_4XX_SENT, &cb_snd123456xx);
1796 osip_set_message_callback(osip, OSIP_IST_STATUS_5XX_SENT, &cb_snd123456xx);
1797 osip_set_message_callback(osip, OSIP_IST_STATUS_6XX_SENT, &cb_snd123456xx);
1798
1799 osip_set_message_callback(osip, OSIP_NICT_STATUS_1XX_RECEIVED, &cb_rcv1xx);
1800 osip_set_message_callback(osip, OSIP_NICT_STATUS_2XX_RECEIVED, &cb_rcv2xx);
1801 osip_set_message_callback(osip, OSIP_NICT_STATUS_3XX_RECEIVED, &cb_rcv3xx);
1802 osip_set_message_callback(osip, OSIP_NICT_STATUS_4XX_RECEIVED, &cb_rcv4xx);
1803 osip_set_message_callback(osip, OSIP_NICT_STATUS_5XX_RECEIVED, &cb_rcv5xx);
1804 osip_set_message_callback(osip, OSIP_NICT_STATUS_6XX_RECEIVED, &cb_rcv6xx);
1805
1806 osip_set_message_callback(osip, OSIP_NIST_STATUS_1XX_SENT, &cb_snd123456xx);
1807 osip_set_message_callback(osip, OSIP_NIST_STATUS_2XX_SENT, &cb_snd123456xx);
1808 osip_set_message_callback(osip, OSIP_NIST_STATUS_3XX_SENT, &cb_snd123456xx);
1809 osip_set_message_callback(osip, OSIP_NIST_STATUS_4XX_SENT, &cb_snd123456xx);
1810 osip_set_message_callback(osip, OSIP_NIST_STATUS_5XX_SENT, &cb_snd123456xx);
1811 osip_set_message_callback(osip, OSIP_NIST_STATUS_6XX_SENT, &cb_snd123456xx);
1812
1813 osip_set_message_callback(osip, OSIP_NIST_CANCEL_RECEIVED, &cb_rcvcancel);
1814 osip_set_message_callback(osip, OSIP_NIST_REGISTER_RECEIVED, &cb_rcvregister);
1815 osip_set_message_callback(osip, OSIP_NIST_BYE_RECEIVED, &cb_rcvrequest);
1816 osip_set_message_callback(osip, OSIP_NIST_INFO_RECEIVED, &cb_rcvrequest);
1817 osip_set_message_callback(osip, OSIP_NIST_OPTIONS_RECEIVED, &cb_rcvrequest);
1818 osip_set_message_callback(osip, OSIP_NIST_SUBSCRIBE_RECEIVED, &cb_rcvrequest);
1819 osip_set_message_callback(osip, OSIP_NIST_NOTIFY_RECEIVED, &cb_rcvrequest);
1820 osip_set_message_callback(osip, OSIP_NIST_UNKNOWN_REQUEST_RECEIVED, &cb_rcvrequest);
1821
1822 osip_set_transport_error_callback(osip, OSIP_ICT_TRANSPORT_ERROR, &cb_transport_error);
1823 osip_set_transport_error_callback(osip, OSIP_IST_TRANSPORT_ERROR, &cb_transport_error);
1824 osip_set_transport_error_callback(osip, OSIP_NICT_TRANSPORT_ERROR, &cb_transport_error);
1825 osip_set_transport_error_callback(osip, OSIP_NIST_TRANSPORT_ERROR, &cb_transport_error);
1826
1827 #ifndef MINISIZE
1828 /* those methods are only used for log purpose except cb_transport_error which only apply to complete version */
1829 osip_set_message_callback(osip, OSIP_ICT_STATUS_2XX_RECEIVED_AGAIN, &cb_rcvresp_retransmission);
1830 osip_set_message_callback(osip, OSIP_ICT_STATUS_3456XX_RECEIVED_AGAIN, &cb_rcvresp_retransmission);
1831 osip_set_message_callback(osip, OSIP_ICT_INVITE_SENT_AGAIN, &cb_sndreq_retransmission);
1832 osip_set_message_callback(osip, OSIP_IST_STATUS_2XX_SENT_AGAIN, &cb_sndresp_retransmission);
1833 osip_set_message_callback(osip, OSIP_IST_STATUS_3456XX_SENT_AGAIN, &cb_sndresp_retransmission);
1834 osip_set_message_callback(osip, OSIP_IST_INVITE_RECEIVED_AGAIN, &cb_rcvreq_retransmission);
1835 osip_set_message_callback(osip, OSIP_NICT_STATUS_2XX_RECEIVED_AGAIN, &cb_rcvresp_retransmission);
1836 osip_set_message_callback(osip, OSIP_NICT_STATUS_3456XX_RECEIVED_AGAIN, &cb_rcvresp_retransmission);
1837 osip_set_message_callback(osip, OSIP_NICT_REQUEST_SENT_AGAIN, &cb_sndreq_retransmission);
1838 osip_set_message_callback(osip, OSIP_NIST_STATUS_2XX_SENT_AGAIN, &cb_sndresp_retransmission);
1839 osip_set_message_callback(osip, OSIP_NIST_STATUS_3456XX_SENT_AGAIN, &cb_sndresp_retransmission);
1840 osip_set_message_callback(osip, OSIP_NIST_REQUEST_RECEIVED_AGAIN, &cb_rcvreq_retransmission);
1841
1842 osip_set_message_callback(osip, OSIP_ICT_INVITE_SENT, &cb_sndinvite);
1843 osip_set_message_callback(osip, OSIP_ICT_ACK_SENT, &cb_sndack);
1844 osip_set_message_callback(osip, OSIP_NICT_REGISTER_SENT, &cb_sndregister);
1845 osip_set_message_callback(osip, OSIP_NICT_BYE_SENT, &cb_sndbye);
1846 osip_set_message_callback(osip, OSIP_NICT_CANCEL_SENT, &cb_sndcancel);
1847 osip_set_message_callback(osip, OSIP_NICT_INFO_SENT, &cb_sndinfo);
1848 osip_set_message_callback(osip, OSIP_NICT_OPTIONS_SENT, &cb_sndoptions);
1849 osip_set_message_callback(osip, OSIP_NICT_SUBSCRIBE_SENT, &cb_sndsubscribe);
1850 osip_set_message_callback(osip, OSIP_NICT_NOTIFY_SENT, &cb_sndnotify);
1851 osip_set_message_callback(osip, OSIP_NICT_UNKNOWN_REQUEST_SENT, &cb_sndunkrequest);
1852
1853 osip_set_message_callback(osip, OSIP_IST_INVITE_RECEIVED, &cb_rcvinvite);
1854 osip_set_message_callback(osip, OSIP_IST_ACK_RECEIVED, &cb_rcvack);
1855 osip_set_message_callback(osip, OSIP_IST_ACK_RECEIVED_AGAIN, &cb_rcvack2);
1856 #endif
1857 return OSIP_SUCCESS;
1858 }
1859