📄 jcallback.c
字号:
/* eXosip - This is the eXtended osip library. Copyright (C) 2002,2003,2004,2005,2006,2007 Aymeric MOIZARD - jack@atosc.org eXosip is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. eXosip is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA*/#ifdef ENABLE_MPATROL#include <mpatrol.h>#endif#include <stdlib.h>#ifdef _WIN32_WCE#include <winsock2.h>#include "inet_ntop.h"#elif WIN32#include <windowsx.h>#include <winsock2.h>#include <Ws2tcpip.h>#include "inet_ntop.h"#else#include <sys/wait.h>#include <sys/types.h>#include <unistd.h>#include <assert.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <sys/types.h>#include <sys/socket.h>#include <netdb.h>#endif#include <eXosip2/eXosip.h>#include "eXosip2.h"extern eXosip_t eXosip;/* Private functions */static void rcvregister_failure (osip_transaction_t * tr, osip_message_t * sip);static void cb_xixt_kill_transaction (int type, osip_transaction_t * tr);#ifndef MINISIZEstatic void cb_rcvinvite (int type, osip_transaction_t * tr, osip_message_t * sip);static void cb_rcvack (int type, osip_transaction_t * tr, osip_message_t * sip);static void cb_rcvack2 (int type, osip_transaction_t * tr, osip_message_t * sip);static void cb_rcvcancel (int type, osip_transaction_t * tr, osip_message_t * sip);#endifstatic void cb_rcvregister (int type, osip_transaction_t * tr, osip_message_t * sip);static void cb_rcvrequest (int type, osip_transaction_t * tr, osip_message_t * sip);#ifndef MINISIZEstatic void cb_sndinvite (int type, osip_transaction_t * tr, osip_message_t * sip);static void cb_sndack (int type, osip_transaction_t * tr, osip_message_t * sip);static void cb_sndregister (int type, osip_transaction_t * tr, osip_message_t * sip);static void cb_sndbye (int type, osip_transaction_t * tr, osip_message_t * sip);static void cb_sndcancel (int type, osip_transaction_t * tr, osip_message_t * sip);static void cb_sndinfo (int type, osip_transaction_t * tr, osip_message_t * sip);static void cb_sndoptions (int type, osip_transaction_t * tr, osip_message_t * sip);static void cb_sndnotify (int type, osip_transaction_t * tr, osip_message_t * sip);static void cb_sndsubscribe (int type, osip_transaction_t * tr, osip_message_t * sip);static void cb_sndunkrequest (int type, osip_transaction_t * tr, osip_message_t * sip);#endifstatic void cb_rcv1xx (int type, osip_transaction_t * tr, osip_message_t * sip);static void cb_rcv2xx_4invite (osip_transaction_t * tr, osip_message_t * sip);#ifndef MINISIZEstatic void cb_rcv2xx_4subscribe (osip_transaction_t * tr, osip_message_t * sip);#endifstatic void cb_rcv2xx (int type, osip_transaction_t * tr, osip_message_t * sip);static void cb_rcv3xx (int type, osip_transaction_t * tr, osip_message_t * sip);static void cb_rcv4xx (int type, osip_transaction_t * tr, osip_message_t * sip);static void cb_rcv5xx (int type, osip_transaction_t * tr, osip_message_t * sip);static void cb_rcv6xx (int type, osip_transaction_t * tr, osip_message_t * sip);static void cb_snd123456xx (int type, osip_transaction_t * tr, osip_message_t * sip);#ifndef MINISIZEstatic void cb_rcvresp_retransmission (int type, osip_transaction_t * tr, osip_message_t * sip);static void cb_sndreq_retransmission (int type, osip_transaction_t * tr, osip_message_t * sip);static void cb_sndresp_retransmission (int type, osip_transaction_t * tr, osip_message_t * sip);static void cb_rcvreq_retransmission (int type, osip_transaction_t * tr, osip_message_t * sip);#endifstatic void cb_transport_error (int type, osip_transaction_t * tr, int error);intcb_snd_message (osip_transaction_t * tr, osip_message_t * sip, char *host, int port, int out_socket){ int i; osip_via_t *via;#ifndef MINISIZE if(eXosip.dontsend_101 != 0 && sip->status_code == 101) return 0;#else if(sip->status_code == 101) return 0;#endif via = (osip_via_t *) osip_list_get (&sip->vias, 0); if (via == NULL || via->protocol == NULL) return -1; if (host == NULL) { if (MSG_IS_REQUEST(sip)) { osip_route_t *route; osip_message_get_route (sip, 0, &route); if (route != NULL) { osip_uri_param_t *lr_param = NULL; osip_uri_uparam_get_byname (route->url, "lr", &lr_param); if (lr_param == NULL) route = NULL; } if (route != NULL) { port = 5060; if (route->url->port != NULL) port = osip_atoi (route->url->port); host = route->url->host; } else { /* search for maddr parameter */ osip_uri_param_t *maddr_param = NULL; osip_uri_uparam_get_byname (sip->req_uri, "maddr", &maddr_param); host=NULL; if (maddr_param!=NULL && maddr_param->gvalue!=NULL) host = maddr_param->gvalue; port = 5060; if (sip->req_uri->port != NULL) port = osip_atoi (sip->req_uri->port); if (host==NULL) host = sip->req_uri->host; } } else { osip_generic_param_t *maddr; osip_generic_param_t *received; osip_generic_param_t *rport; osip_via_param_get_byname (via, "maddr", &maddr); osip_via_param_get_byname (via, "received", &received); osip_via_param_get_byname (via, "rport", &rport); if (maddr != NULL && maddr->gvalue!=NULL) host = maddr->gvalue; else if (received != NULL && received->gvalue!=NULL) host = received->gvalue; else host = via->host; if (rport == NULL || rport->gvalue == NULL) { if (via->port != NULL) port = osip_atoi (via->port); else port = 5060; } else port = osip_atoi (rport->gvalue); } } i = -1; if (osip_strcasecmp (via->protocol, "udp") == 0) { i = eXtl_udp.tl_send_message (tr, sip, host, port, out_socket); } else if (osip_strcasecmp (via->protocol, "tcp") == 0) { i = eXtl_tcp.tl_send_message (tr, sip, host, port, out_socket); }#ifdef HAVE_OPENSSL_SSL_H else if (osip_strcasecmp (via->protocol, "tls") == 0) { i = eXtl_tls.tl_send_message (tr, sip, host, port, out_socket); } else if (osip_strcasecmp (via->protocol, "dtls-udp") == 0) { i = eXtl_dtls.tl_send_message (tr, sip, host, port, out_socket); }#endif if (i != 0) { return -1; } return 0;}#if 0intcb_udp_snd_message (osip_transaction_t * tr, osip_message_t * sip, char *host, int port, int out_socket){ int len = 0; size_t length = 0; struct addrinfo *addrinfo; struct __eXosip_sockaddr addr; char *message;#ifdef INET6_ADDRSTRLEN char ipbuf[INET6_ADDRSTRLEN];#else char ipbuf[46];#endif int i; struct eXosip_net *net; if (eXosip.net_interfaces[0].net_socket == 0) return -1; net = &eXosip.net_interfaces[0];#ifndef MINISIZE if (eXosip.http_port) { i = osip_message_to_str (sip, &message, &length); if (i != 0 || length <= 0) { return -1; } if (0 > _eXosip_sendto (net->net_socket, (const void *) message, length, 0, (struct sockaddr *) &addr, len)) { /* should reopen connection! */ osip_free (message); return -1; } return 0; }#endif if (host == NULL) { host = sip->req_uri->host; if (sip->req_uri->port != NULL) port = osip_atoi (sip->req_uri->port); else port = 5060; } i=-1;#ifndef MINISIZE if (tr!=NULL && tr->record.name[0]!='\0' && tr->record.srventry[0].srv[0]!='\0') { /* always choose the first here. if a network error occur, remove first entry and replace with next entries. */ osip_srv_entry_t *srv; int n=0; for (srv = &tr->record.srventry[0]; n<10 && tr->record.srventry[0].srv[0]; srv = &tr->record.srventry[0]) { i = eXosip_get_addrinfo (&addrinfo, srv->srv, srv->port, IPPROTO_UDP); if (i == 0) { host = srv->srv; port = srv->port; break; } memmove(&tr->record.srventry[0], &tr->record.srventry[1], 9*sizeof(osip_srv_entry_t)); memset(&tr->record.srventry[9], 0, sizeof(osip_srv_entry_t)); i=-1; /* copy next element */ n++; } }#endif /* if SRV was used, distination may be already found */ if (i != 0) { i = eXosip_get_addrinfo (&addrinfo, host, port, IPPROTO_UDP); } if (i != 0) { return -1; } memcpy (&addr, addrinfo->ai_addr, addrinfo->ai_addrlen); len = addrinfo->ai_addrlen; eXosip_freeaddrinfo (addrinfo); /* remove preloaded route if there is no tag in the To header */ { osip_route_t *route=NULL; osip_generic_param_t *tag=NULL; osip_message_get_route (sip, 0, &route); osip_to_get_tag (sip->to, &tag); if (tag==NULL && route != NULL && route->url != NULL) { osip_list_remove(&sip->routes, 0); } i = osip_message_to_str (sip, &message, &length); if (tag==NULL && route != NULL && route->url != NULL) { osip_list_add(&sip->routes, route, 0); } } if (i != 0 || length <= 0) { return -1; } switch ( ((struct sockaddr *)&addr)->sa_family ) { case AF_INET: inet_ntop (((struct sockaddr *)&addr)->sa_family, &(((struct sockaddr_in *) &addr)->sin_addr), ipbuf, sizeof (ipbuf)); break; case AF_INET6: inet_ntop (((struct sockaddr *)&addr)->sa_family, &(((struct sockaddr_in6 *) &addr)->sin6_addr), ipbuf, sizeof (ipbuf)); break; default: strncpy (ipbuf, "(unknown)", sizeof (ipbuf)); break; } OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO1, NULL, "Message sent: \n%s (to dest=%s:%i)\n", message, ipbuf, port));#ifdef WIN32 if (length>412) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO1, NULL, "Message suite: \n%s (to dest=%s:%i)\n", message+412, ipbuf, port)); } if (length>(412*2)) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO1, NULL, "Message suite: \n%s (to dest=%s:%i)\n", message+(412*2), ipbuf, port)); }#endif if (0 > _eXosip_sendto (net->net_socket, (const void *) message, length, 0, (struct sockaddr *) &addr, len)) {#ifdef WIN32 if (WSAECONNREFUSED == WSAGetLastError ())#else if (ECONNREFUSED == errno)#endif { /* This can be considered as an error, but for the moment, I prefer that the application continue to try sending message again and again... so we are not in a error case. Nevertheless, this error should be announced! ALSO, UAS may not have any other options than retry always on the same port. */ osip_free (message); return 1; } else {#ifndef MINISIZE /* delete first SRV entry that is not reachable */ if (tr->record.name[0]!='\0' && tr->record.srventry[0].srv[0]!='\0') { memmove(&tr->record.srventry[0], &tr->record.srventry[1], 9*sizeof(osip_srv_entry_t)); memset(&tr->record.srventry[9], 0, sizeof(osip_srv_entry_t)); osip_free (message); return 0; /* retry for next retransmission! */ }#endif /* SIP_NETWORK_ERROR; */ osip_free (message); return -1; } } if (eXosip.keep_alive > 0) { if (MSG_IS_REGISTER (sip)) { eXosip_reg_t *reg = NULL; if (_eXosip_reg_find (®, tr) == 0) { memcpy (&(reg->addr), &addr, len); reg->len = len; } } } osip_free (message); return 0;}intcb_tcp_snd_message (osip_transaction_t * tr, osip_message_t * sip, char *host, int port, int out_socket){ size_t length = 0; char *message; int i; struct eXosip_net *net; if (eXosip.net_interfaces[1].net_socket == 0) return -1; if (host == NULL) { host = sip->req_uri->host; if (sip->req_uri->port != NULL) port = osip_atoi (sip->req_uri->port); else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -