source: verona/libeXosip2/src/jcallback.c @ 416:2db037c7ce5f

Last change on this file since 416:2db037c7ce5f was 416:2db037c7ce5f, checked in by Vadim Lebedev <vadim@…>, 17 months ago

fixes for socks transport

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