📄 osip.c
字号:
{ transactions = &osip->osip_nist_transactions;#ifdef OSIP_MT mut = nist_fastmutex;#endif } } else { if (0 == strcmp (evt->sip->cseq->method, "INVITE") || 0 == strcmp (evt->sip->cseq->method, "ACK")) { transactions = &osip->osip_ict_transactions;#ifdef OSIP_MT mut = ict_fastmutex;#endif } else { transactions = &osip->osip_nict_transactions;#ifdef OSIP_MT mut = nict_fastmutex;#endif } } } if (transactions == NULL) return NULL; /* not a message??? */#ifdef OSIP_MT osip_mutex_lock (mut);#endif transaction = osip_transaction_find (transactions, evt); if (consume == 1) { /* we add the event before releasing the mutex!! */ if (transaction != NULL) { osip_transaction_add_event (transaction, evt);#ifdef OSIP_MT osip_mutex_unlock (mut);#endif return transaction; } }#ifdef OSIP_MT osip_mutex_unlock (mut);#endif return transaction;}osip_transaction_t *osip_create_transaction (osip_t * osip, osip_event_t * evt){ osip_transaction_t *transaction; int i; osip_fsm_type_t ctx_type; if (evt == NULL) return NULL; if (evt->sip == NULL) return NULL; /* make sure the request's method reflect the cseq value. */ if (MSG_IS_REQUEST (evt->sip)) { /* delete request where cseq method does not match the method in request-line */ if (evt->sip->cseq == NULL || evt->sip->cseq->method == NULL || evt->sip->sip_method == NULL) { return NULL; } if (0 != strcmp (evt->sip->cseq->method, evt->sip->sip_method)) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_WARNING, NULL, "core module: Discard invalid message with method!=cseq!\n")); return NULL; } } if (MSG_IS_ACK (evt->sip)) /* ACK never create transactions */ return NULL; if (EVT_IS_INCOMINGREQ (evt)) { /* we create a new context for this incoming request */ if (0 == strcmp (evt->sip->cseq->method, "INVITE")) ctx_type = IST; else ctx_type = NIST; } else if (EVT_IS_OUTGOINGREQ (evt)) { if (0 == strcmp (evt->sip->cseq->method, "INVITE")) ctx_type = ICT; else ctx_type = NICT; } else { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "Cannot build a transction for this message!\n")); return NULL; } i = osip_transaction_init (&transaction, ctx_type, osip, evt->sip); if (i == -1) { return NULL; } evt->transactionid = transaction->transactionid; return transaction;}osip_transaction_t *osip_transaction_find (osip_list_t * transactions, osip_event_t * evt){ osip_list_iterator_t iterator; osip_transaction_t *transaction; osip_t *osip = NULL; transaction = (osip_transaction_t *) osip_list_get_first (transactions, &iterator); if (transaction != NULL) osip = (osip_t *) transaction->config; if (osip == NULL) return NULL; if (EVT_IS_INCOMINGREQ (evt)) {#ifdef HAVE_DICT_DICT_H /* search in hastable! */ osip_generic_param_t *b_request; osip_via_t *topvia_request; topvia_request = osip_list_get (evt->sip->vias, 0); if (topvia_request == NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "Remote UA is not compliant: missing a Via header!\n")); return NULL; } osip_via_param_get_byname (topvia_request, "branch", &b_request); if (b_request != NULL && b_request->gvalue != NULL) { if (MSG_IS_INVITE (evt->sip) || MSG_IS_ACK (evt->sip)) { transaction = (osip_transaction_t *) dict_search (osip->osip_ist_hastable, b_request->gvalue); OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO2, NULL, "Find matching Via header for INVITE(ACK) REQUEST!\n")); if (transaction != NULL) return transaction; } else { transaction = (osip_transaction_t *) dict_search (osip->osip_nist_hastable, b_request->gvalue); OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO2, NULL, "Find matching Via header for NON-INVITE REQUEST!\n")); if (transaction != NULL) return transaction; } }#endif transaction = (osip_transaction_t *) osip_list_get_first (transactions, &iterator); while (osip_list_iterator_has_elem (iterator)) { if (0 == __osip_transaction_matching_request_osip_to_xist_17_2_3 (transaction, evt->sip)) return transaction; transaction = (osip_transaction_t *) osip_list_get_next (&iterator); } } else if (EVT_IS_INCOMINGRESP (evt)) {#ifdef HAVE_DICT_DICT_H /* search in hastable! */ osip_generic_param_t *b_request; osip_via_t *topvia_request; topvia_request = osip_list_get (evt->sip->vias, 0); if (topvia_request == NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "Remote UA is not compliant: missing a Via header!\n")); return NULL; } osip_via_param_get_byname (topvia_request, "branch", &b_request); if (b_request != NULL && b_request->gvalue != NULL) { if (MSG_IS_RESPONSE_FOR (evt->sip, "INVITE")) { transaction = (osip_transaction_t *) dict_search (osip->osip_ict_hastable, b_request->gvalue); OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO2, NULL, "Find matching Via header for INVITE ANSWER!\n")); if (transaction != NULL) return transaction; } else { transaction = (osip_transaction_t *) dict_search (osip->osip_nict_hastable, b_request->gvalue); OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO2, NULL, "Find matching Via header for NON-INVITE ANSWER!\n")); if (transaction != NULL) return transaction; } }#endif transaction = (osip_transaction_t *) osip_list_get_first (transactions, &iterator); while (osip_list_iterator_has_elem (iterator)) { if (0 == __osip_transaction_matching_response_osip_to_xict_17_1_3 (transaction, evt->sip)) return transaction; transaction = (osip_transaction_t *) osip_list_get_next (&iterator); } } else /* handle OUTGOING message */ { /* THE TRANSACTION ID MUST BE SET */ transaction = (osip_transaction_t *) osip_list_get_first (transactions, &iterator); while (osip_list_iterator_has_elem (iterator)) { if (transaction->transactionid == evt->transactionid) return transaction; transaction = (osip_transaction_t *) osip_list_get_next (&iterator); } } return NULL;}static int ref_count = 0;#ifdef OSIP_MTstatic struct osip_mutex *ref_mutex = NULL;#endifstatic intincrease_ref_count (void){#ifdef OSIP_MT if (ref_count == 0) ref_mutex = osip_mutex_init (); /* Here we should assert() that the mutex was really generated. */ osip_mutex_lock (ref_mutex);#endif if (ref_count == 0) __osip_global_init (); ref_count++;#ifdef OSIP_MT osip_mutex_unlock (ref_mutex);#endif return 0;}static voiddecrease_ref_count (void){#ifdef OSIP_MT osip_mutex_lock (ref_mutex);#endif /* assert (ref_count > 0); */ ref_count--; if (ref_count == 0) {#ifdef OSIP_MT osip_mutex_unlock (ref_mutex); osip_mutex_destroy (ref_mutex);#endif __osip_global_free (); return; }#ifdef OSIP_MT osip_mutex_unlock (ref_mutex);#endif}intosip_init (osip_t ** osip){ if (increase_ref_count () != 0) return -1; *osip = (osip_t *) osip_malloc (sizeof (osip_t)); if (*osip == NULL) return -1; /* allocation failed */ memset (*osip, 0, sizeof (osip_t)); osip_list_init (&(*osip)->osip_ict_transactions); osip_list_init (&(*osip)->osip_ist_transactions); osip_list_init (&(*osip)->osip_nict_transactions); osip_list_init (&(*osip)->osip_nist_transactions); osip_list_init (&(*osip)->ixt_retransmissions);#if defined(HAVE_DICT_DICT_H) (*osip)->osip_ict_hastable = hashtable_dict_new ((dict_cmp_func) strcmp, (dict_hsh_func) s_hash, NULL, NULL, HSIZE); (*osip)->osip_ist_hastable = hashtable_dict_new ((dict_cmp_func) strcmp, (dict_hsh_func) s_hash, NULL, NULL, HSIZE); (*osip)->osip_nict_hastable = hashtable_dict_new ((dict_cmp_func) strcmp, (dict_hsh_func) s_hash, NULL, NULL, HSIZE); (*osip)->osip_nist_hastable = hashtable_dict_new ((dict_cmp_func) strcmp, (dict_hsh_func) s_hash, NULL, NULL, HSIZE);#elif defined(HAVE_DICT_DICT_H_HASHTABLE) (*osip)->osip_ict_hastable = rb_tree_new ((dict_cmp_func) strcmp, NULL, NULL); (*osip)->osip_ist_hastable = rb_tree_new ((dict_cmp_func) strcmp, NULL, NULL); (*osip)->osip_nict_hastable = rb_tree_new ((dict_cmp_func) strcmp, NULL, NULL); (*osip)->osip_nist_hastable = rb_tree_new ((dict_cmp_func) strcmp, NULL, NULL);#endif return 0;}voidosip_release (osip_t * osip){ osip_free (osip); decrease_ref_count ();}voidosip_set_application_context (osip_t * osip, void *pointer){ osip->application_context = pointer;}void *osip_get_application_context (osip_t * osip){ if (osip == NULL) return NULL; return osip->application_context;}intosip_ict_execute (osip_t * osip){ osip_transaction_t *transaction; osip_event_t *se; int more_event; osip_list_iterator_t iterator; void **array; int len; int index = 0; /* list must be copied because osip_transaction_execute() may change it */#ifdef OSIP_MT osip_mutex_lock (ict_fastmutex);#endif len = osip_list_size (&osip->osip_ict_transactions); if (0 >= len) {#ifdef OSIP_MT osip_mutex_unlock (ict_fastmutex);#endif return 0; } array = osip_malloc (sizeof (void *) * len); if (array==NULL) {#ifdef OSIP_MT osip_mutex_unlock (ict_fastmutex);#endif return 0; } transaction = (osip_transaction_t *) osip_list_get_first (&osip->osip_ict_transactions, &iterator); while (osip_list_iterator_has_elem (iterator)) { array[index++] = transaction; transaction = (osip_transaction_t *) osip_list_get_next (&iterator); }#ifdef OSIP_MT osip_mutex_unlock (ict_fastmutex);#endif for (index = 0; index < len; ++index) { transaction = (osip_transaction_t *) array[index]; more_event = 1; do { se = (osip_event_t *) osip_fifo_tryget (transaction->transactionff); if (se == NULL) /* no more event for this transaction */ more_event = 0; else osip_transaction_execute (transaction, se); } while (more_event == 1); } osip_free (array); return 0;}intosip_ist_execute (osip_t * osip){ osip_transaction_t *transaction; osip_event_t *se; int more_event; osip_list_iterator_t iterator; void **array; int len; int index = 0; /* list must be copied because osip_transaction_execute() may change it */#ifdef OSIP_MT osip_mutex_lock (ist_fastmutex);#endif len = osip_list_size (&osip->osip_ist_transactions); if (0 >= len) {#ifdef OSIP_MT osip_mutex_unlock (ist_fastmutex);#endif return 0; } array = osip_malloc (sizeof (void *) * len); if (array==NULL) {#ifdef OSIP_MT osip_mutex_unlock (ist_fastmutex);#endif return 0; } transaction = (osip_transaction_t *) osip_list_get_first (&osip->osip_ist_transactions, &iterator); while (osip_list_iterator_has_elem (iterator)) { array[index++] = transaction; transaction = (osip_transaction_t *) osip_list_get_next (&iterator); }#ifdef OSIP_MT osip_mutex_unlock (ist_fastmutex);#endif for (index = 0; index < len; ++index) { transaction = (osip_transaction_t *) array[index]; more_event = 1; do { se = (osip_event_t *) osip_fifo_tryget (transaction->transactionff); if (se == NULL) /* no more event for this transaction */ more_event = 0; else osip_transaction_execute (transaction, se); } while (more_event == 1); } osip_free (array); return 0;}intosip_nict_execute (osip_t * osip){ osip_transaction_t *transaction; osip_event_t *se; int more_event; osip_list_iterator_t iterator; void **array; int len; int index = 0; /* list must be copied because osip_transaction_execute() may change it */#ifdef OSIP_MT osip_mutex_lock (nict_fastmutex);#endif len = osip_list_size (&osip->osip_nict_transactions); if (0 >= len) {#ifdef OSIP_MT osip_mutex_unlock (nict_fastmutex);#endif return 0; } array = osip_malloc (sizeof (void *) * len); if (array==NULL) {#ifdef OSIP_MT osip_mutex_unlock (nict_fastmutex);#endif return 0; } transaction = (osip_transaction_t *) osip_list_get_first (&osip->osip_nict_transactions, &iterator); while (osip_list_iterator_has_elem (iterator)) { array[index++] = transaction; transaction = (osip_transaction_t *) osip_list_get_next (&iterator); }#ifdef OSIP_MT osip_mutex_unlock (nict_fastmutex);#endif for (index = 0; index < len; ++index) { transaction = (osip_transaction_t *) array[index]; more_event = 1; do { se = (osip_event_t *) osip_fifo_tryget (transaction->transactionff); if (se == NULL) /* no more event for this transaction */ more_event = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -