📄 udp.c
字号:
osip_list_add (&eXosip.j_transactions, transaction, 0); REMOVE_ELEMENT (eXosip.j_subscribes, js); eXosip_subscribe_free (js); __eXosip_wakeup (); return; } else { osip_transaction_set_your_instance (transaction, __eXosip_new_jinfo (NULL, jd, js, NULL)); js->s_ss_status = EXOSIP_SUBCRSTATE_ACTIVE; }#else /* modify the status of user */ if (0 == osip_strncasecmp (sub_state->hvalue, "active", 6)) { js->s_ss_status = EXOSIP_SUBCRSTATE_ACTIVE; } else if (0 == osip_strncasecmp (sub_state->hvalue, "pending", 7)) { js->s_ss_status = EXOSIP_SUBCRSTATE_PENDING; } if (0 == osip_strncasecmp (sub_state->hvalue, "terminated", 10)) { /* delete the dialog! */ js->s_ss_status = EXOSIP_SUBCRSTATE_TERMINATED; { eXosip_event_t *je; je = eXosip_event_init_for_subscribe (EXOSIP_SUBSCRIPTION_NOTIFY, js, jd, transaction); if (je->request == NULL && evt->sip != NULL) { i = osip_message_clone (evt->sip, &je->request); if (i != 0) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "failed to clone request for event\n")); } } eXosip_event_add (je); } sipevent = osip_new_outgoing_sipmessage (answer); sipevent->transactionid = transaction->transactionid; osip_transaction_add_event (transaction, sipevent); osip_list_add (&eXosip.j_transactions, transaction, 0); REMOVE_ELEMENT (eXosip.j_subscribes, js); eXosip_subscribe_free (js); __eXosip_wakeup (); return; } else { osip_transaction_set_your_instance (transaction, __eXosip_new_jinfo (NULL, jd, js, NULL)); }#endif osip_list_add (jd->d_inc_trs, transaction, 0); sipevent = osip_new_outgoing_sipmessage (answer); sipevent->transactionid = transaction->transactionid; osip_transaction_add_event (transaction, sipevent); __eXosip_wakeup (); return;}static inteXosip_match_notify_for_subscribe (eXosip_subscribe_t * js, osip_message_t * notify){ osip_transaction_t *out_sub; if (js == NULL) return OSIP_BADPARAMETER; OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO1, NULL, "Trying to match notify with subscribe\n")); out_sub = eXosip_find_last_out_subscribe (js, NULL); if (out_sub == NULL || out_sub->orig_request == NULL) return OSIP_NOTFOUND; OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO1, NULL, "subscribe transaction found\n")); /* some checks to avoid crashing on bad requests */ if (notify == NULL) return OSIP_BADPARAMETER; if (notify->cseq == NULL || notify->cseq->method == NULL || notify->to == NULL) return OSIP_SYNTAXERROR; if (0 != osip_call_id_match (out_sub->callid, notify->call_id)) return OSIP_UNDEFINED_ERROR; { /* 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 OSIP_SYNTAXERROR; } 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 OSIP_SYNTAXERROR; } if (0 != strcmp (tag_from->gvalue, tag_to->gvalue)) return OSIP_UNDEFINED_ERROR; } return OSIP_SUCCESS;}#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 (transaction != NULL) /* NOT for ACK */ osip_dialog_update_osip_cseq_as_uas (jd->d_dialog, evt->sip); 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)) { osip_generic_param_t *tag_to = NULL; if (evt->sip->to != NULL) osip_from_param_get_byname (evt->sip->to, "tag", &tag_to); if (tag_to == NULL || tag_to->gvalue == NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "Uncompliant user agent: missing a tag in To of incoming BYE\n")); osip_list_add (&eXosip.j_transactions, transaction, 0); eXosip_send_default_answer (jd, transaction, evt, 481, "Missing tags in BYE", "Missing tags in BYE", __LINE__); return; } 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 { 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__);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -