jcallback.c
来自「libosip2-3版本的osip源代码」· C语言 代码 · 共 2,180 行 · 第 1/5 页
C
2,180 行
/* eXosip - This is the eXtended osip library. Copyright (C) 2002, 2003 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 (int type, osip_transaction_t * tr, osip_message_t * sip);static void cb_ict_kill_transaction (int type, osip_transaction_t * tr);static void cb_ist_kill_transaction (int type, osip_transaction_t * tr);static void cb_nict_kill_transaction (int type, osip_transaction_t * tr);static void cb_nist_kill_transaction (int type, osip_transaction_t * tr);static 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_rcvregister (int type, osip_transaction_t * tr, osip_message_t * sip);static void cb_rcvcancel (int type, osip_transaction_t * tr, osip_message_t * sip);static void cb_rcvrequest (int type, osip_transaction_t * tr, osip_message_t * sip);static 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);static 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);static void cb_rcv2xx_4subscribe (osip_transaction_t * tr, osip_message_t * sip);static 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_snd1xx (int type, osip_transaction_t * tr, osip_message_t * sip);static void cb_snd2xx (int type, osip_transaction_t * tr, osip_message_t * sip);static void cb_snd3xx (int type, osip_transaction_t * tr, osip_message_t * sip);static void cb_snd4xx (int type, osip_transaction_t * tr, osip_message_t * sip);static void cb_snd5xx (int type, osip_transaction_t * tr, osip_message_t * sip);static void cb_snd6xx (int type, osip_transaction_t * tr, osip_message_t * sip);static 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);static 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; if (eXosip.net_interfaces[0].net_socket == 0 && eXosip.net_interfaces[1].net_socket == 0) return -1; if(eXosip.dontsend_101 != 0 && sip->status_code == 101) return 0; 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 { port = 5060; if (sip->req_uri->port != NULL) port = osip_atoi (sip->req_uri->port); 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) host = maddr->gvalue; else if (received != 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 = cb_udp_snd_message (tr, sip, host, port, out_socket); } else { i = cb_tcp_snd_message (tr, sip, host, port, out_socket); } if (i != 0) { return -1; } return 0;}intcb_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]; 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; } 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; 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++; } } /* 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; freeaddrinfo (addrinfo); /* remove preloaded route if there is no tag in the To header (sip.iptel.org is refusing this: I can't understand why...) */ if (eXosip.remove_preloadedroute==1) { 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); } } else { i = osip_message_to_str (sip, &message, &length); } if (i != 0 || length <= 0) { return -1; } switch (addr.ss_family) { case AF_INET: inet_ntop (addr.ss_family, &(((struct sockaddr_in *) &addr)->sin_addr), ipbuf, sizeof (ipbuf)); break; case AF_INET6: inet_ntop (addr.ss_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 { /* 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)); return 0; /* retry for next retransmission! */ } /* 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 port = 5060;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?