📄 udp.c
字号:
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 /* 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; } /* we don't match any existing dialog: send a ACK & send a BYE */ osip_event_free (evt);}int_eXosip_handle_incoming_message (char *buf, size_t len, int socket, char *host, int port){ osip_event_t *sipevent; int i; sipevent = osip_parse (buf, len); if (sipevent != NULL && sipevent->sip != NULL) { } else { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "Could not parse SIP message\n")); osip_event_free (sipevent); return -1; } OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO1, NULL, "Message received from: %s:%i\n", host, port)); osip_message_fix_last_via_header (sipevent->sip, host, port); i = osip_find_transaction_and_add_event (eXosip.j_osip, sipevent); if (i != 0) { /* this event has no transaction, */ OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO1, NULL, "This is a request\n", buf)); eXosip_lock (); if (MSG_IS_REQUEST (sipevent->sip)) eXosip_process_newrequest (sipevent, socket); else if (MSG_IS_RESPONSE (sipevent->sip)) eXosip_process_response_out_of_transaction (sipevent); eXosip_unlock (); } else { /* handled by oSIP ! */ return 0; } return 0;}#if defined (WIN32) || defined (_WIN32_WCE)#define eXFD_SET(A, B) FD_SET((unsigned int) A, B)#else#define eXFD_SET(A, B) FD_SET(A, B)#endif/* if second==-1 && useconds==-1 -> wait for ever if max_message_nb<=0 -> infinite loop.... */inteXosip_read_message (int max_message_nb, int sec_max, int usec_max){ fd_set osip_fdset; struct timeval tv; tv.tv_sec = sec_max; tv.tv_usec = usec_max; while (max_message_nb != 0 && eXosip.j_stop_ua == 0) { int i; int max=0;#ifdef OSIP_MT int wakeup_socket = jpipe_get_read_descr (eXosip.j_socketctl);#endif FD_ZERO (&osip_fdset); eXtl_udp.tl_set_fdset(&osip_fdset, &max); eXtl_tcp.tl_set_fdset(&osip_fdset, &max);#ifdef HAVE_OPENSSL_SSL_H eXtl_dtls.tl_set_fdset(&osip_fdset, &max); eXtl_tls.tl_set_fdset(&osip_fdset, &max);#endif#ifdef OSIP_MT eXFD_SET (wakeup_socket, &osip_fdset); if (wakeup_socket > max) max = wakeup_socket;#endif if ((sec_max == -1) || (usec_max == -1)) i = select (max + 1, &osip_fdset, NULL, NULL, NULL); else i = select (max + 1, &osip_fdset, NULL, NULL, &tv);#if defined (_WIN32_WCE) /* TODO: fix me for wince */ /* if (i == -1) continue; */#else if ((i == -1) && (errno == EINTR || errno == EAGAIN)) continue;#endif#ifdef OSIP_MT if ((i > 0) && FD_ISSET (wakeup_socket, &osip_fdset)) { char buf2[500]; jpipe_read (eXosip.j_socketctl, buf2, 499); }#endif if (0 == i || eXosip.j_stop_ua != 0) { } else if (-1 == i) {#if !defined (_WIN32_WCE) /* TODO: fix me for wince */ return -2; /* error */#endif } else { eXtl_udp.tl_read_message(&osip_fdset); eXtl_tcp.tl_read_message(&osip_fdset);#ifdef HAVE_OPENSSL_SSL_H eXtl_dtls.tl_read_message(&osip_fdset); eXtl_tls.tl_read_message(&osip_fdset);#endif } max_message_nb--; } return 0;}#ifndef MINISIZEvoideXosip_release_unused_transactions(void){ eXosip_dialog_t *jd; eXosip_dialog_t *jdnext; eXosip_subscribe_t *js; eXosip_subscribe_t *jsnext; eXosip_notify_t *jn; eXosip_notify_t *jnnext; for (js = eXosip.j_subscribes; js != NULL;) { jsnext = js->next; for (jd = js->s_dialogs; jd != NULL;) { jdnext = jd->next; eXosip_release_finished_transactions_for_subscription (jd); jd = jdnext; } js = jsnext; } for (jn = eXosip.j_notifies; jn != NULL;) { jnnext = jn->next;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -