📄 excall_api.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 "eXosip2.h"extern eXosip_t eXosip;static int eXosip_create_transaction (eXosip_call_t * jc, eXosip_dialog_t * jd, osip_message_t * request);static int eXosip_create_cancel_transaction (eXosip_call_t * jc, eXosip_dialog_t * jd, osip_message_t * request);static int _eXosip_call_reuse_contact (osip_message_t * invite, osip_message_t * msg);static inteXosip_create_transaction (eXosip_call_t * jc, eXosip_dialog_t * jd, osip_message_t * request){ osip_event_t *sipevent; osip_transaction_t *tr; int i; i = _eXosip_transaction_init (&tr, NICT, eXosip.j_osip, request); if (i != 0) { /* TODO: release the j_call.. */ osip_message_free (request); return i; } if (jd != NULL) osip_list_add (jd->d_out_trs, tr, 0); sipevent = osip_new_outgoing_sipmessage (request); sipevent->transactionid = tr->transactionid;#ifndef MINISIZE osip_transaction_set_your_instance (tr, __eXosip_new_jinfo (jc, jd, NULL, NULL));#else osip_transaction_set_your_instance (tr, __eXosip_new_jinfo (jc, jd));#endif osip_transaction_add_event (tr, sipevent); __eXosip_wakeup (); return OSIP_SUCCESS;}static inteXosip_create_cancel_transaction (eXosip_call_t * jc, eXosip_dialog_t * jd, osip_message_t * request){ osip_event_t *sipevent; osip_transaction_t *tr; int i; i = _eXosip_transaction_init (&tr, NICT, eXosip.j_osip, request); if (i != 0) { /* TODO: release the j_call.. */ osip_message_free (request); return i; } osip_list_add (&eXosip.j_transactions, tr, 0); sipevent = osip_new_outgoing_sipmessage (request); sipevent->transactionid = tr->transactionid; osip_transaction_add_event (tr, sipevent); __eXosip_wakeup (); return OSIP_SUCCESS;}static int_eXosip_call_reuse_contact (osip_message_t * invite, osip_message_t * msg){ osip_contact_t *co_invite = NULL; osip_contact_t *co_msg = NULL; int i; i = osip_message_get_contact (invite, 0, &co_invite); if (i < 0 || co_invite == NULL || co_invite->url == NULL) { return i; } i = osip_message_get_contact (msg, 0, &co_msg); if (i >= 0 && co_msg != NULL) { osip_list_remove (&msg->contacts, 0); osip_contact_free (co_msg); } co_msg = NULL; i = osip_contact_clone (co_invite, &co_msg); if (i >= 0 && co_msg != NULL) { osip_list_add (&msg->contacts, co_msg, 0); return OSIP_SUCCESS; } return i;}int_eXosip_call_transaction_find (int tid, eXosip_call_t ** jc, eXosip_dialog_t ** jd, osip_transaction_t ** tr){ for (*jc = eXosip.j_calls; *jc != NULL; *jc = (*jc)->next) { if ((*jc)->c_inc_tr != NULL && (*jc)->c_inc_tr->transactionid == tid) { *tr = (*jc)->c_inc_tr; *jd = (*jc)->c_dialogs; return OSIP_SUCCESS; } if ((*jc)->c_out_tr != NULL && (*jc)->c_out_tr->transactionid == tid) { *tr = (*jc)->c_out_tr; *jd = (*jc)->c_dialogs; return OSIP_SUCCESS; } for (*jd = (*jc)->c_dialogs; *jd != NULL; *jd = (*jd)->next) { osip_transaction_t *transaction; int pos = 0; while (!osip_list_eol ((*jd)->d_inc_trs, pos)) { transaction = (osip_transaction_t *) osip_list_get ((*jd)->d_inc_trs, pos); if (transaction != NULL && transaction->transactionid == tid) { *tr = transaction; return OSIP_SUCCESS; } pos++; } pos = 0; while (!osip_list_eol ((*jd)->d_out_trs, pos)) { transaction = (osip_transaction_t *) osip_list_get ((*jd)->d_out_trs, pos); if (transaction != NULL && transaction->transactionid == tid) { *tr = transaction; return OSIP_SUCCESS; } pos++; } } } *jd = NULL; *jc = NULL; return OSIP_NOTFOUND;}inteXosip_call_set_reference (int id, void *reference){ eXosip_dialog_t *jd = NULL; eXosip_call_t *jc = NULL; if (id > 0) { eXosip_call_dialog_find (id, &jc, &jd); if (jc == NULL) { eXosip_call_find (id, &jc); } } if (jc == NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: No call here?\n")); return OSIP_NOTFOUND; } jc->external_reference = reference; return OSIP_SUCCESS;}void*
eXosip_call_get_reference (int cid)
{
eXosip_call_t* jc = NULL;
eXosip_call_find (cid, &jc);
if (jc == NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: No call here?\n")); return NULL; } return jc->external_reference;}/* this method can't be called unless the previous INVITE transaction is over. */inteXosip_call_build_initial_invite (osip_message_t ** invite, const char *to, const char *from, const char *route, const char *subject){ int i; osip_to_t *_to = NULL; osip_header_t *subject_header; *invite = NULL; if (to != NULL && *to == '\0') return OSIP_BADPARAMETER; if (route != NULL && *route == '\0') route = NULL; if (subject != NULL && *subject == '\0') subject = NULL; i = osip_to_init (&_to); if (i != 0) return i; i = osip_to_parse (_to, to); if (i != 0) { osip_to_free (_to); return i; } i = generating_request_out_of_dialog (invite, "INVITE", to, eXosip.transport, from, route); osip_to_free (_to); if (i != 0) return i; _eXosip_dialog_add_contact (*invite, NULL); subject_header=NULL; osip_message_get_subject (*invite, 0, &subject_header); if (subject_header==NULL && subject != NULL) osip_message_set_subject (*invite, subject); return OSIP_SUCCESS;}inteXosip_call_send_initial_invite (osip_message_t * invite){ eXosip_call_t *jc; osip_transaction_t *transaction; osip_event_t *sipevent; int i; if (invite == NULL) { osip_message_free (invite); return OSIP_BADPARAMETER; } i = eXosip_call_init (&jc); if (i != 0) { osip_message_free (invite); return i; } i = _eXosip_transaction_init (&transaction, ICT, eXosip.j_osip, invite); if (i != 0) { eXosip_call_free (jc); osip_message_free (invite); return i; } jc->c_out_tr = transaction; sipevent = osip_new_outgoing_sipmessage (invite); sipevent->transactionid = transaction->transactionid;#ifndef MINISIZE osip_transaction_set_your_instance (transaction, __eXosip_new_jinfo (jc, NULL, NULL, NULL));#else osip_transaction_set_your_instance (transaction, __eXosip_new_jinfo (jc, NULL));#endif osip_transaction_add_event (transaction, sipevent); jc->external_reference = NULL; ADD_ELEMENT (eXosip.j_calls, jc); eXosip_update (); /* fixed? */ __eXosip_wakeup (); return jc->c_id;}inteXosip_call_build_ack (int did, osip_message_t ** _ack){ eXosip_dialog_t *jd = NULL; eXosip_call_t *jc = NULL; osip_transaction_t *tr = NULL; osip_message_t *ack; char *transport; int i; *_ack = NULL; if (did <= 0) return OSIP_BADPARAMETER; if (did > 0) { eXosip_call_dialog_find (did, &jc, &jd); } if (jc == NULL || jd == NULL || jd->d_dialog == NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: No call here?\n")); return OSIP_NOTFOUND; } tr = eXosip_find_last_invite (jc, jd); if (tr == NULL || tr->orig_request == NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: No transaction for call?\n")); return OSIP_NOTFOUND; } if (0 != osip_strcasecmp (tr->orig_request->sip_method, "INVITE")) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: ACK are only sent for invite transactions\n")); return OSIP_BADPARAMETER; } transport = NULL; transport = _eXosip_transport_protocol (tr->orig_request); if (transport == NULL) i = _eXosip_build_request_within_dialog (&ack, "ACK", jd->d_dialog, "UDP"); else i = _eXosip_build_request_within_dialog (&ack, "ACK", jd->d_dialog, transport); if (i != 0) { return i; } _eXosip_call_reuse_contact (tr->orig_request, ack); /* Fix CSeq Number when request has been exchanged during INVITE transactions */ if (tr->orig_request->cseq != NULL && tr->orig_request->cseq->number != NULL) { if (ack != NULL && ack->cseq != NULL && ack->cseq->number != NULL) { osip_free (ack->cseq->number); ack->cseq->number = osip_strdup (tr->orig_request->cseq->number); } } /* copy all credentials from INVITE! */ { int pos = 0; osip_proxy_authorization_t *pa = NULL; i = osip_message_get_proxy_authorization (tr->orig_request, pos, &pa); while (i >= 0 && pa != NULL) { osip_proxy_authorization_t *pa2; i = osip_proxy_authorization_clone (pa, &pa2); if (i != 0) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "Error in credential from INVITE\n")); break; } osip_list_add (&ack->proxy_authorizations, pa2, -1); pa = NULL; pos++; i = osip_message_get_proxy_authorization (tr->orig_request, pos, &pa); } } *_ack = ack; return OSIP_SUCCESS;}inteXosip_call_send_ack (int did, osip_message_t * ack){ eXosip_dialog_t *jd = NULL; eXosip_call_t *jc = NULL; int i; osip_route_t *route; char *host; int port; if (did <= 0) return OSIP_BADPARAMETER; if (did > 0) { eXosip_call_dialog_find (did, &jc, &jd); } if (jc == NULL || jd == NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: No call here?\n")); if (ack != NULL) osip_message_free (ack); return OSIP_NOTFOUND; } if (ack == NULL) { i = eXosip_call_build_ack (did, &ack); if (i != 0) { return i; } } osip_message_get_route (ack, 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 (ack->req_uri, "maddr", &maddr_param); host = NULL; if (maddr_param != NULL && maddr_param->gvalue != NULL) host = maddr_param->gvalue; port = 5060; if (ack->req_uri->port != NULL) port = osip_atoi (ack->req_uri->port); if (host == NULL) host = ack->req_uri->host; } i = cb_snd_message (NULL, ack, host, port, -1); if (jd->d_ack != NULL) osip_message_free (jd->d_ack); jd->d_ack = ack; if (i < 0) return i; /* TODO: could be 1 for icmp... */ return OSIP_SUCCESS;}inteXosip_call_build_request (int jid, const char *method, osip_message_t ** request){ eXosip_dialog_t *jd = NULL; eXosip_call_t *jc = NULL; osip_transaction_t *transaction; int i; *request = NULL; if (jid <= 0) return OSIP_BADPARAMETER; if (method == NULL || method[0] == '\0') return OSIP_BADPARAMETER; if (jid > 0) { eXosip_call_dialog_find (jid, &jc, &jd); } if (jd == NULL || jd->d_dialog == NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: No call here?\n")); return OSIP_NOTFOUND;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -