udp.c
来自「libosip2-3版本的osip源代码」· C语言 代码 · 共 1,949 行 · 第 1/5 页
C
1,949 行
{ 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_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_REFER (evt->sip)) { eXosip_process_refer (jc, jd, transaction, evt); } else if (MSG_IS_OPTIONS (evt->sip)) { eXosip_process_options (jc, jd, transaction, evt); } else if (MSG_IS_INFO (evt->sip)) { eXosip_process_info (jc, jd, transaction, evt); } else if (MSG_IS_NOTIFY (evt->sip)) { eXosip_process_notify_for_refer (jc, jd, transaction, evt); } else if (MSG_IS_PRACK (evt->sip)) { eXosip_process_prack (jc, jd, transaction, evt); } else if (MSG_IS_MESSAGE (evt->sip)) { eXosip_process_message_within_dialog (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 {#if 0 osip_list_add (eXosip.j_transactions, transaction, 0); eXosip_send_default_answer (jd, transaction, evt, 405, NULL, "Method Not Allowed", __LINE__);#else eXosip_process_message_within_dialog (jc, jd, transaction, evt);#endif } 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_OPTIONS (evt->sip)) { eXosip_process_new_options (transaction, evt); return; } else 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; } 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) { if (osip_dialog_match_as_uas (jd->d_dialog, evt->sip) == 0) break; } } if (jd != NULL) break; } if (jn != 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)) { 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_SUBSCRIBE (evt->sip)) { /* the previous transaction MUST be freed */ old_trn = eXosip_find_last_inc_subscribe (jn, jd); /* shouldn't we wait for the COMPLETED state? */ if (old_trn != NULL && old_trn->state != NIST_TERMINATED && old_trn->state != NIST_COMPLETED) { /* retry later? */ osip_list_add (eXosip.j_transactions, transaction, 0); eXosip_send_default_answer (jd, transaction, evt, 500, "Retry Later", "A SUBSCRIBE 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_subscribe_within_call (jn, jd, transaction, evt); } else { osip_list_add (eXosip.j_transactions, transaction, 0); eXosip_send_default_answer (jd, transaction, evt, 501, NULL, NULL, __LINE__); } return; } if (MSG_IS_MESSAGE (evt->sip)) { eXosip_process_message_outside_of_dialog (transaction, evt); return; } if (MSG_IS_REFER (evt->sip)) { eXosip_process_refer_outside_of_dialog (transaction, evt); return; } if (MSG_IS_SUBSCRIBE (evt->sip)) { eXosip_process_new_subscribe (transaction, evt); return; } /* default answer */ osip_list_add (eXosip.j_transactions, transaction, 0);#if 0 eXosip_send_default_answer (NULL, transaction, evt, 501, NULL, NULL, __LINE__);#endif}static voideXosip_process_response_out_of_transaction (osip_event_t * evt){ eXosip_call_t *jc = NULL; eXosip_dialog_t *jd = NULL; time_t now; now = time (NULL); if (evt->sip==NULL || evt->sip->cseq==NULL || evt->sip->cseq->number==NULL || evt->sip->to==NULL || evt->sip->from==NULL) { osip_event_free (evt); return; } /* search for existing dialog: match branch & to tag */ for (jc = eXosip.j_calls; jc != NULL; jc = jc->next) { /* search for calls with only ONE outgoing transaction */ if (jc->c_id >= 1 && jc->c_dialogs != NULL && jc->c_out_tr!=NULL) { for (jd = jc->c_dialogs; jd != NULL; jd = jd->next) { /* only initial request are concerned with this */ if (jd->d_id >=1 && jd->d_dialog != NULL) { /* match answer with dialog */ osip_generic_param_t *tag; osip_from_get_tag (evt->sip->to, &tag); if (jd->d_dialog->remote_tag == NULL || tag == NULL) continue; if (jd->d_dialog->remote_tag != NULL && tag != NULL && tag->gvalue != NULL && 0 == strcmp (jd->d_dialog->remote_tag, tag->gvalue)) break; } } if (jd!=NULL) break; /* found a matching dialog! */ /* check if the transaction match this from tag */ if (jc->c_out_tr->orig_request!=NULL && jc->c_out_tr->orig_request->from!=NULL) { osip_generic_param_t *tag_invite; osip_generic_param_t *tag; osip_from_get_tag (jc->c_out_tr->orig_request->from, &tag_invite); osip_from_get_tag (evt->sip->from, &tag); if (tag_invite == NULL || tag == NULL) continue; if (tag_invite->gvalue != NULL && tag->gvalue != NULL && 0 == strcmp (tag_invite->gvalue, tag->gvalue)) break; } } } if (jc==NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO1, NULL, "Incoming 2xx has no relations with current calls: Message discarded.\r\n")); osip_event_free (evt); return; } if (jc!=NULL && jd!=NULL) { /* we have to restransmit the ACK (if already available) */ OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO1, NULL, "2xx restransmission receveid.\r\n")); /* check if the 2xx is for the same ACK */ if (jd->d_ack!=NULL && jd->d_ack->cseq!=NULL && jd->d_ack->cseq->number!=NULL) { if (0==osip_strcasecmp(jd->d_ack->cseq->number, evt->sip->cseq->number)) { cb_snd_message (NULL, jd->d_ack, NULL,0, -1);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?