udp.c
来自「libosip2-3版本的osip源代码」· C语言 代码 · 共 1,949 行 · 第 1/5 页
C
1,949 行
osip_transaction_set_your_instance (transaction, __eXosip_new_jinfo (NULL, jd, NULL, jn)); evt_answer = osip_new_outgoing_sipmessage (answer); evt_answer->transactionid = transaction->transactionid; osip_transaction_add_event (transaction, evt_answer); ADD_ELEMENT (eXosip.j_notifies, jn); __eXosip_wakeup (); jn->n_inc_tr = transaction; eXosip_update (); __eXosip_wakeup ();}static voideXosip_process_subscribe_within_call (eXosip_notify_t * jn, eXosip_dialog_t * jd, osip_transaction_t * transaction, osip_event_t * evt){ _eXosip_notify_set_refresh_interval (jn, evt->sip); osip_transaction_set_your_instance (transaction, __eXosip_new_jinfo (NULL, jd, NULL, jn)); /* if subscribe request contains expires="0", close the subscription */ { time_t now = time (NULL); if (jn->n_ss_expires - now <= 0) { jn->n_ss_status = EXOSIP_SUBCRSTATE_TERMINATED; jn->n_ss_reason = TIMEOUT; } } osip_list_add (jd->d_inc_trs, transaction, 0); __eXosip_wakeup (); return;}static voideXosip_process_notify_within_dialog (eXosip_subscribe_t * js, eXosip_dialog_t * jd, osip_transaction_t * transaction, osip_event_t * evt){ osip_message_t *answer; osip_event_t *sipevent; osip_header_t *sub_state;#ifdef SUPPORT_MSN osip_header_t *expires;#endif int i; if (jd == NULL) { osip_list_add (eXosip.j_transactions, transaction, 0); eXosip_send_default_answer (jd, transaction, evt, 500, "Internal SIP Error", "No dialog for this NOTIFY", __LINE__); return; } /* if subscription-state has a reason state set to terminated, we close the dialog */#ifndef SUPPORT_MSN osip_message_header_get_byname (evt->sip, "subscription-state", 0, &sub_state); if (sub_state == NULL || sub_state->hvalue == NULL) { osip_list_add (eXosip.j_transactions, transaction, 0); eXosip_send_default_answer (jd, transaction, evt, 400, NULL, NULL, __LINE__); return; }#endif i = _eXosip_build_response_default (&answer, jd->d_dialog, 200, evt->sip); if (i != 0) { osip_list_add (eXosip.j_transactions, transaction, 0); eXosip_send_default_answer (jd, transaction, evt, 500, "Internal SIP Error", "Failed to build Answer for NOTIFY", __LINE__); return; }#ifdef SUPPORT_MSN osip_message_header_get_byname (evt->sip, "expires", 0, &expires); if (expires != NULL && expires->hvalue != NULL && 0 == osip_strcasecmp (expires->hvalue, "0")) { /* 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); 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)); 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); 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 -1; 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 -1; OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO1, NULL, "subscribe transaction found\n")); /* some checks to avoid crashing on bad requests */ if (notify == NULL || notify->cseq == NULL || notify->cseq->method == NULL || notify->to == NULL) return -1; if (0 != osip_call_id_match (out_sub->callid, notify->call_id)) return -1; { /* 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;}static voideXosip_process_message_outside_of_dialog (osip_transaction_t * transaction, osip_event_t * evt){ osip_list_add (eXosip.j_transactions, transaction, 0); __eXosip_wakeup (); /* needed? */ return;}static voideXosip_process_refer_outside_of_dialog (osip_transaction_t * transaction, osip_event_t * evt){ osip_list_add (eXosip.j_transactions, transaction, 0); __eXosip_wakeup (); /* needed? */ return;}static 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); osip_transaction_set_your_instance (transaction, __eXosip_new_jinfo (jc, jd, NULL, NULL)); __eXosip_wakeup (); return;}static voideXosip_process_newrequest (osip_event_t * evt, int socket){ osip_transaction_t *transaction; osip_event_t *evt_answer; osip_message_t *answer; int i; int ctx_type; eXosip_call_t *jc; eXosip_subscribe_t *js; eXosip_notify_t *jn; 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 (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 (); } } 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; } 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_TERMINATED)
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?