udp.c

来自「libosip2-3版本的osip源代码」· C语言 代码 · 共 1,949 行 · 第 1/5 页

C
1,949
字号
            {              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_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))        {          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 if (MSG_IS_REFER (evt->sip))        {          eXosip_process_refer (jc, jd, transaction, evt);      } else if (MSG_IS_OPTIONS (evt->sip))        {          eXosip_process_options (jc, jd, transaction, evt);      } else if (MSG_IS_INFO (evt->sip))        {          eXosip_process_info (jc, jd, transaction, evt);      } else if (MSG_IS_NOTIFY (evt->sip))        {          eXosip_process_notify_for_refer (jc, jd, transaction, evt);      } else if (MSG_IS_PRACK (evt->sip))        {          eXosip_process_prack (jc, jd, transaction, evt);      } else if (MSG_IS_MESSAGE (evt->sip))        {          eXosip_process_message_within_dialog (jc, jd, transaction, evt);      } else if (MSG_IS_SUBSCRIBE (evt->sip))        {          osip_list_add (eXosip.j_transactions, transaction, 0);          eXosip_send_default_answer (jd, transaction, evt, 489, NULL,                                      "Bad Event", __LINE__);      } else        {#if 0          osip_list_add (eXosip.j_transactions, transaction, 0);          eXosip_send_default_answer (jd, transaction, evt, 405, NULL,                                      "Method Not Allowed", __LINE__);#else          eXosip_process_message_within_dialog (jc, jd, transaction, evt);#endif        }      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__);      return;                   /* fixed */    }  if (MSG_IS_OPTIONS (evt->sip))    {      eXosip_process_new_options (transaction, evt);      return;  } else 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;    }  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;    }  if (MSG_IS_MESSAGE (evt->sip))    {      eXosip_process_message_outside_of_dialog (transaction, evt);      return;    }  if (MSG_IS_REFER (evt->sip))    {      eXosip_process_refer_outside_of_dialog (transaction, evt);      return;    }  if (MSG_IS_SUBSCRIBE (evt->sip))    {      eXosip_process_new_subscribe (transaction, evt);      return;    }  /* default answer */  osip_list_add (eXosip.j_transactions, transaction, 0);#if 0  eXosip_send_default_answer (NULL, transaction, evt, 501, NULL, NULL, __LINE__);#endif}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;	  }	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);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?