📄 udp.c
字号:
/* The From tag of outgoing request must match the To tag of incoming notify: */ osip_generic_param_t *tag_from; osip_generic_param_t *tag_to; osip_from_param_get_byname (out_sub->from, "tag", &tag_from); osip_from_param_get_byname (notify->to, "tag", &tag_to); if (tag_to == NULL || tag_to->gvalue == NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "Uncompliant user agent: no tag in from of outgoing request\n")); return -1; } if (tag_from == NULL || tag_to->gvalue == NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "Uncompliant user agent: no tag in to of incoming request\n")); return -1; } if (0 != strcmp (tag_from->gvalue, tag_to->gvalue)) return -1; } return 0;}#endifstatic voideXosip_process_message_within_dialog (eXosip_call_t * jc, eXosip_dialog_t * jd, osip_transaction_t * transaction, osip_event_t * evt){ osip_list_add (jd->d_inc_trs, transaction, 0);#ifndef MINISIZE osip_transaction_set_your_instance (transaction, __eXosip_new_jinfo (jc, jd, NULL, NULL));#else osip_transaction_set_your_instance (transaction, __eXosip_new_jinfo (jc, jd));#endif __eXosip_wakeup (); return;}static voideXosip_process_newrequest (osip_event_t * evt, int socket){ osip_transaction_t *transaction;#ifndef MINISIZE osip_event_t *evt_answer; osip_message_t *answer;#endif int i; int ctx_type; eXosip_call_t *jc;#ifndef MINISIZE eXosip_subscribe_t *js; eXosip_notify_t *jn;#endif eXosip_dialog_t *jd; if (MSG_IS_INVITE (evt->sip)) { ctx_type = IST; } else if (MSG_IS_ACK (evt->sip)) { /* this should be a ACK for 2xx (but could be a late ACK!) */ ctx_type = -1; } else if (MSG_IS_REQUEST (evt->sip)) { ctx_type = NIST; } else { /* We should handle late response and 200 OK before coming here. */ ctx_type = -1; osip_event_free (evt); return; } transaction = NULL; if (ctx_type != -1) { i = _eXosip_transaction_init (&transaction, (osip_fsm_type_t) ctx_type, eXosip.j_osip, evt->sip); if (i != 0) { osip_event_free (evt); return; } osip_transaction_set_in_socket (transaction, socket); osip_transaction_set_out_socket (transaction, socket); evt->transactionid = transaction->transactionid; osip_transaction_set_your_instance (transaction, NULL); osip_transaction_add_event (transaction, evt); } if (MSG_IS_CANCEL (evt->sip)) { /* special handling for CANCEL */ /* in the new spec, if the CANCEL has a Via branch, then it is the same as the one in the original INVITE */ eXosip_process_cancel (transaction, evt); return; } jd = NULL; /* first, look for a Dialog in the map of element */ for (jc = eXosip.j_calls; jc != NULL; jc = jc->next) { for (jd = jc->c_dialogs; jd != NULL; jd = jd->next) { if (jd->d_dialog != NULL) { if (osip_dialog_match_as_uas (jd->d_dialog, evt->sip) == 0) break; } } if (jd != NULL) break; } /* check CSeq */ if (jd!=NULL && transaction!=NULL && evt->sip!=NULL && evt->sip->cseq!=NULL && evt->sip->cseq->number!=NULL) { if (jd->d_dialog!=NULL && jd->d_dialog->remote_cseq>0) { int cseq = osip_atoi (evt->sip->cseq->number); if (cseq==jd->d_dialog->remote_cseq) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: receive a request with same cseq??\n")); osip_transaction_free(transaction); return; } if (cseq<=jd->d_dialog->remote_cseq) { eXosip_send_default_answer (jd, transaction, evt, 500, NULL, "Wrong Lower CSeq", __LINE__); return; } } }#ifndef MINISIZE if (ctx_type == IST) { i = _eXosip_build_response_default (&answer, NULL, 100, evt->sip); if (i != 0) { __eXosip_delete_jinfo (transaction); osip_transaction_free (transaction); return; } osip_message_set_content_length (answer, "0"); /* send message to transaction layer */ evt_answer = osip_new_outgoing_sipmessage (answer); evt_answer->transactionid = transaction->transactionid; /* add the REQUEST & the 100 Trying */ osip_transaction_add_event (transaction, evt_answer); __eXosip_wakeup (); }#endif if (jd != NULL) { osip_transaction_t *old_trn; /* it can be: 1: a new INVITE offer. 2: a REFER request from one of the party. 2: a BYE request from one of the party. 3: a REQUEST with a wrong CSeq. 4: a NOT-SUPPORTED method with a wrong CSeq. */ if (transaction==NULL) { /* cannot answer ACK transaction */ } else if (!MSG_IS_BYE (evt->sip)) { /* reject all requests for a closed dialog */ old_trn = eXosip_find_last_inc_transaction (jc, jd, "BYE"); if (old_trn == NULL) old_trn = eXosip_find_last_out_transaction (jc, jd, "BYE"); if (old_trn != NULL) { osip_list_add (eXosip.j_transactions, transaction, 0); eXosip_send_default_answer (jd, transaction, evt, 481, NULL, NULL, __LINE__); return; } } if (MSG_IS_INVITE (evt->sip)) { /* the previous transaction MUST be freed */ old_trn = eXosip_find_last_inc_invite (jc, jd); if (old_trn != NULL && old_trn->state != IST_COMPLETED && old_trn->state != IST_TERMINATED) { osip_list_add (eXosip.j_transactions, transaction, 0); eXosip_send_default_answer (jd, transaction, evt, 500, "Retry Later", "An INVITE is not terminated", __LINE__); return; } old_trn = eXosip_find_last_out_invite (jc, jd); if (old_trn != NULL && old_trn->state != ICT_COMPLETED && old_trn->state != ICT_TERMINATED) { osip_list_add (eXosip.j_transactions, transaction, 0); eXosip_send_default_answer (jd, transaction, evt, 491, NULL, NULL, __LINE__); return; } osip_dialog_update_osip_cseq_as_uas (jd->d_dialog, evt->sip); osip_dialog_update_route_set_as_uas (jd->d_dialog, evt->sip); eXosip_process_reinvite (jc, jd, transaction, evt); } else if (MSG_IS_BYE (evt->sip)) { old_trn = eXosip_find_last_inc_transaction (jc, jd, "BYE"); if (old_trn != NULL) /* && old_trn->state!=NIST_TERMINATED) */ { /* this situation should NEVER occur?? (we can't receive two different BYE for one call! */ osip_list_add (eXosip.j_transactions, transaction, 0); eXosip_send_default_answer (jd, transaction, evt, 500, "Call Already Terminated", "A pending BYE has already terminate this call", __LINE__); return; } /* osip_transaction_free(old_trn); */ eXosip_process_bye (jc, jd, transaction, evt); } else if (MSG_IS_ACK (evt->sip)) { eXosip_process_ack (jc, jd, evt); } else if (MSG_IS_PRACK (evt->sip)) { eXosip_process_prack (jc, jd, transaction, evt); } else if (MSG_IS_SUBSCRIBE (evt->sip)) { osip_list_add (eXosip.j_transactions, transaction, 0); eXosip_send_default_answer (jd, transaction, evt, 489, NULL, "Bad Event", __LINE__); } else { eXosip_process_message_within_dialog (jc, jd, transaction, evt); } return; } if (MSG_IS_ACK (evt->sip)) { /* no transaction has been found for this ACK! */ osip_event_free (evt); return; } if (MSG_IS_INFO (evt->sip)) { osip_list_add (eXosip.j_transactions, transaction, 0); eXosip_send_default_answer (jd, transaction, evt, 481, NULL, NULL, __LINE__); return; /* fixed */ } if (MSG_IS_INVITE (evt->sip)) { eXosip_process_new_invite (transaction, evt); return; } else if (MSG_IS_BYE (evt->sip)) { osip_list_add (eXosip.j_transactions, transaction, 0); eXosip_send_default_answer (jd, transaction, evt, 481, NULL, NULL, __LINE__); return; }#ifndef MINISIZE js = NULL; /* first, look for a Dialog in the map of element */ for (js = eXosip.j_subscribes; js != NULL; js = js->next) { for (jd = js->s_dialogs; jd != NULL; jd = jd->next) { if (jd->d_dialog != NULL) { if (osip_dialog_match_as_uas (jd->d_dialog, evt->sip) == 0) break; } } if (jd != NULL) break; } if (js != NULL) { /* dialog found */ osip_transaction_t *old_trn; /* it can be: 1: a new INVITE offer. 2: a REFER request from one of the party. 2: a BYE request from one of the party. 3: a REQUEST with a wrong CSeq. 4: a NOT-SUPPORTED method with a wrong CSeq. */ if (MSG_IS_MESSAGE (evt->sip)) { /* eXosip_process_imessage_within_subscribe_dialog(transaction, evt); */ osip_list_add (eXosip.j_transactions, transaction, 0); eXosip_send_default_answer (jd, transaction, evt, SIP_NOT_IMPLEMENTED, NULL, "MESSAGEs within dialogs are not implemented.", __LINE__); return; } else if (MSG_IS_NOTIFY (evt->sip)) { /* the previous transaction MUST be freed */ old_trn = eXosip_find_last_inc_notify (js, jd); /* shouldn't we wait for the COMPLETED state? */ if (old_trn != NULL && old_trn->state != NIST_TERMINATED) { /* retry later? */ osip_list_add (eXosip.j_transactions, transaction, 0); eXosip_send_default_answer (jd, transaction, evt, 500, "Retry Later", "A pending NOTIFY is not terminated", __LINE__); return; } osip_dialog_update_osip_cseq_as_uas (jd->d_dialog, evt->sip); osip_dialog_update_route_set_as_uas (jd->d_dialog, evt->sip); eXosip_process_notify_within_dialog (js, jd, transaction, evt); } else { osip_list_add (eXosip.j_transactions, transaction, 0); eXosip_send_default_answer (jd, transaction, evt, 501, NULL, "Just Not Implemented", __LINE__); } return; } if (MSG_IS_NOTIFY (evt->sip)) { /* let's try to check if the NOTIFY is related to an existing subscribe */ js = NULL; /* first, look for a Dialog in the map of element */ for (js = eXosip.j_subscribes; js != NULL; js = js->next) { if (eXosip_match_notify_for_subscribe (js, evt->sip) == 0) { i = eXosip_dialog_init_as_uac (&jd, evt->sip); if (i != 0) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: cannot establish a dialog\n")); return; } /* update local cseq from subscribe request */ if (js->s_out_tr != NULL && js->s_out_tr->cseq != NULL && js->s_out_tr->cseq->number != NULL) { jd->d_dialog->local_cseq = atoi (js->s_out_tr->cseq->number); OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO2, NULL, "eXosip: local cseq has been updated\n")); } ADD_ELEMENT (js->s_dialogs, jd); eXosip_update (); eXosip_process_notify_within_dialog (js, jd, transaction, evt); return; } } osip_list_add (eXosip.j_transactions, transaction, 0); eXosip_send_default_answer (NULL, transaction, evt, 481, NULL, NULL, __LINE__); return; } jn = NULL; /* first, look for a Dialog in the map of element */ for (jn = eXosip.j_notifies; jn != NULL; jn = jn->next) { for (jd = jn->n_dialogs; jd != NULL; jd = jd->next) { if (jd->d_dialog != NULL) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -