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 + -
显示快捷键?