📄 exosip.c
字号:
/* eXosip - This is the eXtended osip library. Copyright (C) 2002,2003,2004,2005 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"#include <eXosip2/eXosip.h>#ifndef WIN32#include <memory.h>#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <unistd.h>#endif/* Private functions */static jauthinfo_t *eXosip_find_authentication_info (const char *username, const char *realm);eXosip_t eXosip;void__eXosip_wakeup (void){ jpipe_write (eXosip.j_socketctl, "w", 1);}void__eXosip_wakeup_event (void){ jpipe_write (eXosip.j_socketctl_event, "w", 1);}inteXosip_lock (void){ return osip_mutex_lock ((struct osip_mutex *) eXosip.j_mutexlock);}inteXosip_unlock (void){ return osip_mutex_unlock ((struct osip_mutex *) eXosip.j_mutexlock);}int_eXosip_transaction_init (osip_transaction_t ** transaction, osip_fsm_type_t ctx_type, osip_t * osip, osip_message_t * message){#ifdef SRV_RECORD osip_srv_record_t record;#endif int i; i = osip_transaction_init (transaction, ctx_type, osip, message); if (i != 0) { return i; }#ifdef SRV_RECORD i = _eXosip_srv_lookup(*transaction, message, &record); if (i<0) { return 0; } osip_transaction_set_srv_record(*transaction, &record);#endif return 0;}inteXosip_transaction_find (int tid, osip_transaction_t ** transaction){ int pos = 0; *transaction = NULL; while (!osip_list_eol (eXosip.j_transactions, pos)) { osip_transaction_t *tr; tr = (osip_transaction_t *) osip_list_get (eXosip.j_transactions, pos); if (tr->transactionid == tid) { *transaction = tr; return 0; } pos++; } return -1;}static int_eXosip_retry_with_auth (eXosip_dialog_t * jd, osip_transaction_t ** ptr, int *retry){ osip_transaction_t *out_tr = NULL; osip_transaction_t *tr = NULL; osip_message_t *msg = NULL; osip_event_t *sipevent; jinfo_t *ji = NULL; int cseq; osip_via_t *via; int i; if (!ptr) return -1; if (jd != NULL) { if (jd->d_out_trs == NULL) return -1; } out_tr = *ptr; if (out_tr == NULL || out_tr->orig_request == NULL || out_tr->last_response == NULL) return -1; if (retry && (*retry >= 3)) return -1; osip_message_clone (out_tr->orig_request, &msg); if (msg == NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: could not clone msg for authentication\n")); return -1; } via = (osip_via_t *) osip_list_get (&msg->vias, 0); if (via == NULL || msg->cseq == NULL || msg->cseq->number == NULL) { osip_message_free (msg); OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: missing via or cseq header\n")); return -1; } /* increment cseq */ cseq = atoi (msg->cseq->number); osip_free (msg->cseq->number); msg->cseq->number = strdup_printf ("%i", cseq + 1); if (jd != NULL && jd->d_dialog != NULL) { jd->d_dialog->local_cseq++; } i = eXosip_update_top_via(msg); if (i!=0) { osip_message_free (msg); OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: unsupported protocol\n")); return -1; } if (eXosip_add_authentication_information (msg, out_tr->last_response) < 0) { osip_message_free (msg); return -1; } osip_message_force_update (msg); if (MSG_IS_INVITE (msg)) i = _eXosip_transaction_init (&tr, ICT, eXosip.j_osip, msg); else i = _eXosip_transaction_init (&tr, NICT, eXosip.j_osip, msg); if (i != 0) { osip_message_free (msg); return -1; } /* replace with the new tr */ if (MSG_IS_PUBLISH(msg)) { /* old transaction is put in the garbage list */ osip_list_add (eXosip.j_transactions, out_tr, 0); /* new transaction is put in the publish context */ *ptr = tr; } else osip_list_add (eXosip.j_transactions, tr, 0); sipevent = osip_new_outgoing_sipmessage (msg); ji = osip_transaction_get_your_instance (out_tr); osip_transaction_set_your_instance (out_tr, NULL); osip_transaction_set_your_instance (tr, ji); osip_transaction_add_event (tr, sipevent); if (retry) (*retry)++; eXosip_update (); /* fixed? */ __eXosip_wakeup (); return 0;}static int_eXosip_retry_register_with_auth (eXosip_event_t * je){ eXosip_reg_t *jr = NULL; if (eXosip_reg_find_id (&jr, je->rid) < 0) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: registration not found\n")); return -1; } if (jr->r_retry < 3) { jr->r_retry++; return eXosip_register_send_register (jr->r_id, NULL); } return -1;}static int_eXosip_retry_invite_with_auth (eXosip_event_t * je){ eXosip_dialog_t *jd = NULL; eXosip_call_t *jc = NULL; int *retry = NULL; osip_transaction_t *tr=NULL; _eXosip_call_transaction_find (je->tid, &jc, &jd, &tr); if (jc==NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: call dialog not found\n")); return -1; } if (jd && jd->d_dialog) retry = &jd->d_retry; else retry = &jc->c_retry; if (*retry < 3) { (*retry)++; return _eXosip_call_send_request_with_credential(jc, jd, tr); } return -1;}static int_eXosip_redirect_invite (eXosip_event_t * je){ eXosip_dialog_t *jd = NULL; eXosip_call_t *jc = NULL; osip_transaction_t *tr=NULL; _eXosip_call_transaction_find (je->tid, &jc, &jd, &tr); if (jc==NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: call dialog not found\n")); return -1; } return _eXosip_call_redirect_request (jc, jd, tr);}static int_eXosip_retry_subscribe_with_auth (eXosip_event_t * je){ eXosip_dialog_t *jd = NULL; eXosip_subscribe_t *js = NULL; int *retry = NULL; osip_transaction_t *tr=NULL; if (_eXosip_subscribe_transaction_find (je->tid, &js, &jd, &tr) < 0) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: subscribe dialog not found\n")); return -1; } if (jd && jd->d_dialog) retry = &jd->d_retry; else retry = &js->s_retry; if (*retry < 3) { (*retry)++; return _eXosip_subscribe_send_request_with_credential(js, jd, tr); } return -1;}static int_eXosip_retry_publish_with_auth (eXosip_event_t * je){ eXosip_pub_t *jp = NULL; if (_eXosip_pub_find_by_tid (&jp, je->tid) < 0) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: publish transaction not found\n")); return -1; } return _eXosip_retry_with_auth (NULL, &jp->p_last_tr, NULL);}static int_eXosip_retry_notify_with_auth (eXosip_event_t * je){ /* TODO untested */ eXosip_dialog_t *jd = NULL; eXosip_notify_t *jn = NULL; osip_transaction_t *tr=NULL; if (_eXosip_insubscription_transaction_find (je->tid, &jn, &jd, &tr) < 0) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: notify dialog not found\n")); return -1; } return _eXosip_insubscription_send_request_with_credential (jn, jd, tr);}static inteXosip_retry_with_auth (eXosip_event_t * je){ if (!je || !je->request || !je->response) return -1; if (je->rid>0) { return _eXosip_retry_register_with_auth (je); } else if (je->cid>0) { return _eXosip_retry_invite_with_auth (je); } else if (je->sid>0) { return _eXosip_retry_subscribe_with_auth (je); } else if (je->nid>0) { return _eXosip_retry_notify_with_auth (je); } else if (MSG_IS_PUBLISH (je->request)) return _eXosip_retry_publish_with_auth (je); else { osip_transaction_t *tr=NULL; eXosip_transaction_find(je->tid, &tr); if (tr!=NULL) { return _eXosip_retry_with_auth (NULL, &tr, NULL); } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -