📄 udp.c
字号:
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) { 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; }#endif#ifndef MINISIZE if (MSG_IS_SUBSCRIBE (evt->sip)) { eXosip_process_new_subscribe (transaction, evt); return; }#endif /* default answer */ osip_list_add (&eXosip.j_transactions, transaction, 0); __eXosip_wakeup (); /* needed? */}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; }#ifndef MINISIZE 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); OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO1, NULL, "ACK restransmission sent.\r\n")); } } osip_event_free (evt); return; }#endif if (jc != NULL) { /* match answer with dialog */ osip_dialog_t *dlg;#ifndef MINISIZE osip_transaction_t *last_tr;#endif int i; /* we match an existing dialog: send a retransmission of ACK */ i = osip_dialog_init_as_uac (&dlg, evt->sip); if (i != 0 || dlg == NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "Cannot build dialog for 200ok.\r\n")); osip_event_free (evt); return; } OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO1, NULL, "sending ACK for 2xx out of transaction.\r\n")); { osip_message_t *bye; char *transport = _eXosip_transport_protocol (evt->sip);#ifndef MINISIZE /* Don't send ACK in MINISIZE mode to save code size */ osip_message_t *ack; if (transport == NULL) i = _eXosip_build_request_within_dialog (&ack, "ACK", dlg, "UDP"); else i = _eXosip_build_request_within_dialog (&ack, "ACK", dlg, transport); if (i != 0) { osip_dialog_free (dlg); osip_event_free (evt); return; } /* copy all credentials from INVITE! */ last_tr = jc->c_out_tr; if (last_tr != NULL) { int pos = 0; int i; osip_proxy_authorization_t *pa = NULL; i = osip_message_get_proxy_authorization (last_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 (last_tr->orig_request, pos, &pa); } } cb_snd_message (NULL, ack, NULL, 0, -1); osip_message_free (ack);#endif /* in some case, PRACK and UPDATE may have been sent so we have to send a cseq which is above the previous one. */ dlg->local_cseq = dlg->local_cseq + 4; /* ready to send a BYE */ if (transport == NULL) i = generating_bye (&bye, dlg, "UDP"); else i = generating_bye (&bye, dlg, transport); cb_snd_message (NULL, bye, NULL, 0, -1); osip_message_free (bye); } osip_dialog_free (dlg); osip_event_free (evt); return; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -