예제 #1
0
int
_eXosip_pub_update (struct eXosip_t *excontext, eXosip_pub_t ** pub, osip_transaction_t * tr, osip_message_t * answer)
{
  eXosip_pub_t *jpub;

  *pub = NULL;

  for (jpub = excontext->j_pub; jpub != NULL; jpub = jpub->next) {
    if (jpub->p_last_tr == NULL) {      /*bug? */
    }
    else if (tr == jpub->p_last_tr) {
      /* update the sip_etag parameter */
      if (answer == NULL) {     /* bug? */
      }
      else if (MSG_IS_STATUS_2XX (answer)) {
        osip_header_t *sip_etag = NULL;

        osip_message_header_get_byname (answer, "SIP-ETag", 0, &sip_etag);
        if (sip_etag != NULL && sip_etag->hvalue != NULL)
          snprintf (jpub->p_sip_etag, 64, "%s", sip_etag->hvalue);
      }
      *pub = jpub;
      return OSIP_SUCCESS;
    }
  }
  return OSIP_NOTFOUND;
}
예제 #2
0
/* returns -1 on error. */
int
osip_message_replace_header (osip_message_t * sip, const char *hname,
			     const char *hvalue)
{
  osip_header_t *h, *oldh;
  int i, oldpos = -1;

  if (sip == NULL || hname == NULL)
    return OSIP_BADPARAMETER;

  oldpos = osip_message_header_get_byname(sip, hname, 0, &oldh);

  i = osip_header_init (&h);
  if (i != 0)
    return i;

  h->hname = (char *) osip_malloc (strlen (hname) + 1);

  if (h->hname == NULL)
    {
      osip_header_free (h);
      return OSIP_NOMEM;
    }
  osip_clrncpy (h->hname, hname, strlen (hname));

  if (hvalue != NULL)
    {                           /* some headers can be null ("subject:") */
      h->hvalue = (char *) osip_malloc (strlen (hvalue) + 1);
      if (h->hvalue == NULL)
	{
	  osip_header_free (h);
	  return OSIP_NOMEM;
	}
      osip_clrncpy (h->hvalue, hvalue, strlen (hvalue));
    } else
      h->hvalue = NULL;

  if (oldpos != -1)
    {
      osip_list_remove(&sip->headers, oldpos);
      osip_header_free(oldh);
    }

  sip->message_property = 2;
  osip_list_add (&sip->headers, h, -1);
  return OSIP_SUCCESS;                     /* ok */
}
void sal_exosip_subscription_recv(Sal *sal, eXosip_event_t *ev){	
	/*workaround a bug in eXosip: incoming SUBSCRIBES within dialog with expires: 0 are
	 recognized as new incoming subscribes*/
	SalOp *op=sal_find_in_subscribe_by_call_id(sal,ev->request->call_id);
	if (op){
		osip_header_t *h;
		osip_message_header_get_byname(ev->request,"expires",0,&h);
		if (h && h->hvalue && atoi(h->hvalue)==0){
			ms_warning("This susbscribe is not a new one but terminates an old one.");
			ev->did=op->did;
			ev->nid=op->nid;
			sal_exosip_subscription_closed(sal,ev);
		}else {
			osip_message_t *msg=NULL;
			ms_warning("Probably a refresh subscribe");
			eXosip_lock();
			eXosip_insubscription_build_answer(ev->tid,202,&msg);
			eXosip_insubscription_send_answer(ev->tid,202,msg);
			eXosip_unlock();
		}
	}else _sal_exosip_subscription_recv(sal,ev);
}
예제 #4
0
int
_eXosip_build_response_default (osip_message_t ** dest,
                                osip_dialog_t * dialog, int status,
                                osip_message_t * request)
{
  osip_generic_param_t *tag;
  osip_message_t *response;
  int pos;
  int i;

  *dest = NULL;
  if (request == NULL)
    return -1;

  i = osip_message_init (&response);
  if (i != 0)
    return -1;
  /* initialise osip_message_t structure */
  /* yet done... */

  response->sip_version = (char *) osip_malloc (8 * sizeof (char));
  sprintf (response->sip_version, "SIP/2.0");
  osip_message_set_status_code (response, status);

  /* handle some internal reason definitions. */
  if (MSG_IS_NOTIFY (request) && status == 481)
    {
      response->reason_phrase = osip_strdup ("Subcription Does Not Exist");
  } else if (MSG_IS_SUBSCRIBE (request) && status == 202)
    {
      response->reason_phrase = osip_strdup ("Accepted subscription");
  } else
    {
      response->reason_phrase = osip_strdup (osip_message_get_reason (status));
      if (response->reason_phrase == NULL)
        {
          if (response->status_code == 101)
            response->reason_phrase = osip_strdup ("Dialog Establishement");
          else
            response->reason_phrase = osip_strdup ("Unknown code");
        }
      response->req_uri = NULL;
      response->sip_method = NULL;
    }

  i = osip_to_clone (request->to, &(response->to));
  if (i != 0)
    goto grd_error_1;

  i = osip_to_get_tag (response->to, &tag);
  if (i != 0)
    {                           /* we only add a tag if it does not already contains one! */
      if ((dialog != NULL) && (dialog->local_tag != NULL))
        /* it should contain the local TAG we created */
        {
          osip_to_set_tag (response->to, osip_strdup (dialog->local_tag));
      } else
        {
          if (status != 100)
            osip_to_set_tag (response->to, osip_to_tag_new_random ());
        }
    }

  i = osip_from_clone (request->from, &(response->from));
  if (i != 0)
    goto grd_error_1;

  pos = 0;
  while (!osip_list_eol (request->vias, pos))
    {
      osip_via_t *via;
      osip_via_t *via2;

      via = (osip_via_t *) osip_list_get (request->vias, pos);
      i = osip_via_clone (via, &via2);
      if (i != -0)
        goto grd_error_1;
      osip_list_add (response->vias, via2, -1);
      pos++;
    }

  i = osip_call_id_clone (request->call_id, &(response->call_id));
  if (i != 0)
    goto grd_error_1;
  i = osip_cseq_clone (request->cseq, &(response->cseq));
  if (i != 0)
    goto grd_error_1;

  if (MSG_IS_SUBSCRIBE (request))
    {
      osip_header_t *exp;
      osip_header_t *evt_hdr;

      osip_message_header_get_byname (request, "event", 0, &evt_hdr);
      if (evt_hdr != NULL && evt_hdr->hvalue != NULL)
        osip_message_set_header (response, "Event", evt_hdr->hvalue);
      else
        osip_message_set_header (response, "Event", "presence");
      i = osip_message_get_expires (request, 0, &exp);
      if (exp == NULL)
        {
          osip_header_t *cp;

          i = osip_header_clone (exp, &cp);
          if (cp != NULL)
            osip_list_add (response->headers, cp, 0);
        }
    }

  osip_message_set_allow (response, "INVITE");
  osip_message_set_allow (response, "ACK");
  osip_message_set_allow (response, "OPTIONS");
  osip_message_set_allow (response, "CANCEL");
  osip_message_set_allow (response, "BYE");
  osip_message_set_allow (response, "SUBSCRIBE");
  osip_message_set_allow (response, "NOTIFY");
  osip_message_set_allow (response, "MESSAGE");
  osip_message_set_allow (response, "INFO");
  osip_message_set_allow (response, "REFER");
  osip_message_set_allow (response, "UPDATE");

  *dest = response;
  return 0;

grd_error_1:
  osip_message_free (response);
  return -1;
}
예제 #5
0
int
eXosip_call_build_prack (int tid, osip_message_t ** prack)
{
  eXosip_dialog_t *jd = NULL;
  eXosip_call_t *jc = NULL;
  osip_transaction_t *tr = NULL;

  osip_header_t *rseq;
  char *transport;
  int i;

  *prack = NULL;

  if (tid < 0)
    return OSIP_BADPARAMETER;

  if (tid > 0)
    {
      _eXosip_call_transaction_find (tid, &jc, &jd, &tr);
    }
  if (jc == NULL || jd == NULL || jd->d_dialog == NULL
      || tr == NULL || tr->orig_request == NULL
      || tr->orig_request->sip_method == NULL)
    {
      OSIP_TRACE (osip_trace
                  (__FILE__, __LINE__, OSIP_ERROR, NULL,
                   "eXosip: No call here or no transaction for call\n"));
      return OSIP_NOTFOUND;
    }

  if (0 != osip_strcasecmp (tr->orig_request->sip_method, "INVITE"))
    return OSIP_BADPARAMETER;

  /* PRACK are only send in the PROCEEDING state */
  if (tr->state != ICT_PROCEEDING)
    return OSIP_WRONG_STATE;

  if (tr->orig_request->cseq == NULL
      || tr->orig_request->cseq->number == NULL
      || tr->orig_request->cseq->method == NULL)
    return OSIP_SYNTAXERROR;

  transport = NULL;
  if (tr != NULL && tr->orig_request != NULL)
    transport = _eXosip_transport_protocol (tr->orig_request);

  if (transport == NULL)
    i = _eXosip_build_request_within_dialog (prack, "PRACK", jd->d_dialog, "UDP");
  else
    i =
      _eXosip_build_request_within_dialog (prack, "PRACK", jd->d_dialog,
                                           transport);

  if (i != 0)
    return i;

  osip_message_header_get_byname (tr->last_response, "RSeq", 0, &rseq);
  if (rseq != NULL && rseq->hvalue != NULL)
    {
      char tmp[128];

      memset (tmp, '\0', sizeof (tmp));
      snprintf (tmp, 127, "%s %s %s", rseq->hvalue,
                tr->orig_request->cseq->number, tr->orig_request->cseq->method);
      osip_message_set_header (*prack, "RAck", tmp);
    }

  return OSIP_SUCCESS;
}
예제 #6
0
static int
_eXosip_register_build_register (eXosip_reg_t * jr, osip_message_t ** _reg)
{
    osip_message_t *reg = NULL;
    int i;

    reg = NULL;
    *_reg = NULL;

    if (jr->r_last_tr != NULL)
    {
        if (jr->r_last_tr->state != NICT_TERMINATED
                && jr->r_last_tr->state != NICT_COMPLETED)
            return -1;
        else
        {
            osip_message_t *last_response = NULL;
            osip_transaction_t *tr;

            osip_message_clone (jr->r_last_tr->orig_request, &reg);
            if (reg == NULL)
                return -1;
            /* reg = jr->r_last_tr->orig_request; */
            if (jr->r_last_tr->last_response != NULL)
            {
                osip_message_clone (jr->r_last_tr->last_response, &last_response);
                if (last_response == NULL)
                {
                    osip_message_free (reg);
                    return -1;
                }
            }

            __eXosip_delete_jinfo (jr->r_last_tr);
            tr = jr->r_last_tr;
            jr->r_last_tr = NULL;
            osip_list_add (eXosip.j_transactions, tr, 0);

            /* modify the REGISTER request */
            {
                int osip_cseq_num = osip_atoi (reg->cseq->number);
                int length = strlen (reg->cseq->number);


                osip_list_special_free(&reg->authorizations, (void *(*)(void *)) &osip_authorization_free);
                osip_list_special_free(&reg->proxy_authorizations, (void *(*)(void *)) &osip_proxy_authorization_free);


                if (-1 == eXosip_update_top_via (reg))
                {
                    osip_message_free (reg);
                    if (last_response != NULL)
                        osip_message_free (last_response);
                    return -1;
                }

                osip_cseq_num++;
                osip_free (reg->cseq->number);
                reg->cseq->number = (char *) osip_malloc (length + 2);      /* +2 like for 9 to 10 */
                sprintf (reg->cseq->number, "%i", osip_cseq_num);

                {
                    osip_header_t *exp;

                    osip_message_header_get_byname (reg, "expires", 0, &exp);
                    if (exp!=NULL)
                    {
                        if (exp->hvalue!=NULL)
                            osip_free (exp->hvalue);
                        exp->hvalue = (char *) osip_malloc (10);
                        snprintf (exp->hvalue, 9, "%i", jr->r_reg_period);
                    }
                }

                osip_message_force_update (reg);
            }

            if (last_response != NULL)
            {
                if (last_response->status_code==401 || last_response->status_code==407)
                {
                    eXosip_add_authentication_information (reg, last_response);
                }
                else
                    eXosip_add_authentication_information (reg, NULL);
                osip_message_free (last_response);
            }
        }
    }
    if (reg == NULL)
    {
        i = generating_register (jr, &reg, eXosip.transport,
                                 jr->r_aor, jr->r_registrar, jr->r_contact,
                                 jr->r_reg_period);
        if (i != 0)
        {
            return -2;
        }
    }

    *_reg = reg;
    return 0;
}
예제 #7
0
static int
_eXosip_register_build_register(eXosip_reg_t * jr, osip_message_t ** _reg)
{
	osip_message_t *reg = NULL;
	int i;

	*_reg = NULL;

	if (jr == NULL)
		return OSIP_BADPARAMETER;

	if (jr->r_last_tr != NULL) {
		if (jr->r_last_tr->state != NICT_TERMINATED
			&& jr->r_last_tr->state != NICT_COMPLETED)
			return OSIP_WRONG_STATE;
		else {
			osip_message_t *last_response = NULL;
			osip_transaction_t *tr;

			i = osip_message_clone(jr->r_last_tr->orig_request, &reg);
			if (i != 0)
				return i;
			if (jr->r_last_tr->last_response != NULL) {
				i = osip_message_clone(jr->r_last_tr->last_response,
									   &last_response);
				if (i != 0) {
					osip_message_free(reg);
					return i;
				}
			}

			__eXosip_delete_jinfo(jr->r_last_tr);
			tr = jr->r_last_tr;
			jr->r_last_tr = NULL;
			osip_list_add(&eXosip.j_transactions, tr, 0);

			/* modify the REGISTER request */
			{
				int osip_cseq_num = osip_atoi(reg->cseq->number);
				int length = strlen(reg->cseq->number);


				osip_list_special_free(&reg->authorizations, (void (*)(void *))
									   &osip_authorization_free);
				osip_list_special_free(&reg->proxy_authorizations,
									   (void (*)(void *))
									   &osip_proxy_authorization_free);


				i = eXosip_update_top_via(reg);
				if (i != 0) {
					osip_message_free(reg);
					if (last_response != NULL)
						osip_message_free(last_response);
					return i;
				}

				osip_cseq_num++;
				osip_free(reg->cseq->number);
				reg->cseq->number = (char *) osip_malloc(length + 2);	/* +2 like for 9 to 10 */
				if (reg->cseq->number == NULL) {
					osip_message_free(reg);
					if (last_response != NULL)
						osip_message_free(last_response);
					return OSIP_NOMEM;
				}
				snprintf(reg->cseq->number, length + 2, "%i", osip_cseq_num);


				if (last_response != NULL && last_response->status_code == 423) {
					/* increase expires value to "min-expires" value */
					osip_header_t *exp;
					osip_header_t *min_exp;

					osip_message_header_get_byname(reg, "expires", 0, &exp);
					osip_message_header_get_byname(last_response, "min-expires", 0,
												   &min_exp);
					if (exp != NULL && exp->hvalue != NULL && min_exp != NULL
						&& min_exp->hvalue != NULL) {
						osip_free(exp->hvalue);
						exp->hvalue = osip_strdup(min_exp->hvalue);
						jr->r_reg_period = atoi(min_exp->hvalue);
					} else {
						osip_message_free(reg);
						if (last_response != NULL)
							osip_message_free(last_response);
						OSIP_TRACE(osip_trace
								   (__FILE__, __LINE__, OSIP_ERROR, NULL,
									"eXosip: missing Min-Expires or Expires in REGISTER\n"));
						return OSIP_SYNTAXERROR;
					}
				} else {
					osip_header_t *exp;

					osip_message_header_get_byname(reg, "expires", 0, &exp);
					if (exp != NULL) {
						if (exp->hvalue != NULL)
							osip_free(exp->hvalue);
						exp->hvalue = (char *) osip_malloc(10);
						if (exp->hvalue == NULL) {
							osip_message_free(reg);
							if (last_response != NULL)
								osip_message_free(last_response);
							return OSIP_NOMEM;
						}
						snprintf(exp->hvalue, 9, "%i", jr->r_reg_period);
					}
				}

				osip_message_force_update(reg);
			}

			if (last_response != NULL) {
				if (last_response->status_code == 401
					|| last_response->status_code == 407) {
					eXosip_add_authentication_information(reg, last_response);
				} else
					eXosip_add_authentication_information(reg, NULL);
				osip_message_free(last_response);
			}
		}
	}
	if (reg == NULL) {
		i = generating_register(jr, &reg, eXosip.transport,
								jr->r_aor, jr->r_registrar, jr->r_contact,
								jr->r_reg_period);
		if (i != 0)
			return i;
	}

	*_reg = reg;
	return OSIP_SUCCESS;
}
예제 #8
0
int
_eXosip_subscribe_send_request_with_credential (struct eXosip_t *excontext, eXosip_subscribe_t * js, eXosip_dialog_t * jd, osip_transaction_t * out_tr)
{
  osip_transaction_t *tr = NULL;
  osip_message_t *msg = NULL;
  osip_event_t *sipevent;

  int cseq;
  osip_via_t *via;
  int i;

  if (js == NULL)
    return OSIP_BADPARAMETER;
  if (jd != NULL) {
    if (jd->d_out_trs == NULL)
      return OSIP_BADPARAMETER;
  }

  if (out_tr == NULL) {
    out_tr = _eXosip_find_last_out_subscribe (js, jd);
  }

  if (out_tr == NULL || out_tr->orig_request == NULL || out_tr->last_response == NULL)
    return OSIP_NOTFOUND;

  i = osip_message_clone (out_tr->orig_request, &msg);
  if (i != 0) {
    OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: could not clone msg for authentication\n"));
    return i;
  }

  {
    osip_generic_param_t *tag = NULL;

    osip_to_get_tag (msg->to, &tag);
    if (NULL == tag && jd != NULL && jd->d_dialog != NULL && jd->d_dialog->remote_tag != NULL) {
      osip_to_set_tag (msg->to, osip_strdup (jd->d_dialog->remote_tag));
    }
  }

  via = (osip_via_t *) osip_list_get (&msg->vias, 0);
  if (via == NULL || msg->cseq == NULL || msg->cseq->number == NULL) {
    osip_message_free (msg);
    OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: missing via or cseq header\n"));
    return OSIP_SYNTAXERROR;
  }

  /* increment cseq */
  cseq = atoi (msg->cseq->number);
  osip_free (msg->cseq->number);
  msg->cseq->number = _eXosip_strdup_printf ("%i", cseq + 1);
  if (msg->cseq->number == NULL) {
    osip_message_free (msg);
    return OSIP_NOMEM;
  }

  if (jd != NULL && jd->d_dialog != NULL) {
    jd->d_dialog->local_cseq++;
  }

  i = _eXosip_update_top_via (msg);
  if (i != 0) {
    osip_message_free (msg);
    return i;
  }

  osip_list_special_free (&msg->authorizations, (void (*)(void *)) &osip_authorization_free);
  osip_list_special_free (&msg->proxy_authorizations, (void (*)(void *)) &osip_proxy_authorization_free);

  if (out_tr->last_response->status_code == 401 || out_tr->last_response->status_code == 407) {
    _eXosip_add_authentication_information (excontext, msg, out_tr->last_response);
  }
  else
    _eXosip_add_authentication_information (excontext, msg, NULL);


  if (out_tr != NULL && out_tr->last_response != NULL && out_tr->last_response->status_code == 423) {
    /* increase expires value to "min-expires" value */
    osip_header_t *exp;
    osip_header_t *min_exp;

    osip_message_header_get_byname (msg, "expires", 0, &exp);
    osip_message_header_get_byname (out_tr->last_response, "min-expires", 0, &min_exp);
    if (exp != NULL && exp->hvalue != NULL && min_exp != NULL && min_exp->hvalue != NULL) {
      osip_free (exp->hvalue);
      exp->hvalue = osip_strdup (min_exp->hvalue);
    }
    else {
      osip_message_free (msg);
      OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: missing Min-Expires or Expires in PUBLISH\n"));
      return OSIP_SYNTAXERROR;
    }
  }


  osip_message_force_update (msg);

  i = _eXosip_transaction_init (excontext, &tr, NICT, excontext->j_osip, msg);

  if (i != 0) {
    osip_message_free (msg);
    return i;
  }

  if (out_tr == js->s_out_tr) {
    /* replace with the new tr */
    osip_list_add (&excontext->j_transactions, js->s_out_tr, 0);
    js->s_out_tr = tr;
  }
  else {
    /* add the new tr for the current dialog */
    osip_list_add (jd->d_out_trs, tr, 0);
  }

  sipevent = osip_new_outgoing_sipmessage (msg);

  osip_transaction_set_reserved5 (tr, js);
  osip_transaction_set_reserved3 (tr, jd);

  osip_transaction_add_event (tr, sipevent);

  _eXosip_update (excontext);   /* fixed? */
  _eXosip_wakeup (excontext);
  return OSIP_SUCCESS;
}
예제 #9
0
int
_eXosip_subscribe_automatic_refresh (struct eXosip_t *excontext, eXosip_subscribe_t * js, eXosip_dialog_t * jd, osip_transaction_t * out_tr)
{
  osip_message_t *sub = NULL;
  osip_header_t *expires;
  int i;

  if (js == NULL || jd == NULL || out_tr == NULL || out_tr->orig_request == NULL)
    return OSIP_BADPARAMETER;

  i = eXosip_subscribe_build_refresh_request (excontext, jd->d_id, &sub);
  if (i != 0)
    return i;

  i = osip_message_get_expires (out_tr->orig_request, 0, &expires);
  if (expires != NULL && expires->hvalue != NULL) {
    osip_message_set_expires (sub, expires->hvalue);
  }

  {
    int pos = 0;
    osip_accept_t *_accept = NULL;

    i = osip_message_get_accept (out_tr->orig_request, pos, &_accept);
    while (i >= 0 && _accept != NULL) {
      osip_accept_t *_accept2;

      i = osip_accept_clone (_accept, &_accept2);
      if (i != 0) {
        OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "Error in Accept header\n"));
        break;
      }
      osip_list_add (&sub->accepts, _accept2, -1);
      _accept = NULL;
      pos++;
      i = osip_message_get_accept (out_tr->orig_request, pos, &_accept);
    }
  }

  {
    int pos = 0;
    osip_header_t *_event = NULL;

    pos = osip_message_header_get_byname (out_tr->orig_request, "Event", 0, &_event);
    while (pos >= 0 && _event != NULL) {
      osip_header_t *_event2;

      i = osip_header_clone (_event, &_event2);
      if (i != 0) {
        OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "Error in Event header\n"));
        break;
      }
      osip_list_add (&sub->headers, _event2, -1);
      _event = NULL;
      pos++;
      pos = osip_message_header_get_byname (out_tr->orig_request, "Event", pos, &_event);
    }
  }

  i = eXosip_subscribe_send_refresh_request (excontext, jd->d_id, sub);
  return i;
}
예제 #10
0
int
_eXosip_build_response_default (struct eXosip_t *excontext, osip_message_t ** dest, osip_dialog_t * dialog, int status, osip_message_t * request)
{
  osip_generic_param_t *tag;
  osip_message_t *response;
  int i;

  *dest = NULL;
  if (request == NULL)
    return OSIP_BADPARAMETER;

  i = osip_message_init (&response);
  if (i != 0)
    return i;
  /* initialise osip_message_t structure */
  /* yet done... */

  response->sip_version = (char *) osip_malloc (8 * sizeof (char));
  if (response->sip_version == NULL) {
    osip_message_free (response);
    return OSIP_NOMEM;
  }
  sprintf (response->sip_version, "SIP/2.0");
  osip_message_set_status_code (response, status);

#ifndef MINISIZE
  /* handle some internal reason definitions. */
  if (MSG_IS_NOTIFY (request) && status == 481) {
    response->reason_phrase = osip_strdup ("Subscription Does Not Exist");
  }
  else if (MSG_IS_SUBSCRIBE (request) && status == 202) {
    response->reason_phrase = osip_strdup ("Accepted subscription");
  }
  else {
    response->reason_phrase = osip_strdup (osip_message_get_reason (status));
    if (response->reason_phrase == NULL) {
      if (response->status_code == 101)
        response->reason_phrase = osip_strdup ("Dialog Establishement");
      else
        response->reason_phrase = osip_strdup ("Unknown code");
    }
    response->req_uri = NULL;
    response->sip_method = NULL;
  }
#else
  response->reason_phrase = osip_strdup (osip_message_get_reason (status));
  if (response->reason_phrase == NULL) {
    if (response->status_code == 101)
      response->reason_phrase = osip_strdup ("Dialog Establishement");
    else
      response->reason_phrase = osip_strdup ("Unknown code");
  }
  response->req_uri = NULL;
  response->sip_method = NULL;
#endif

  if (response->reason_phrase == NULL) {
    osip_message_free (response);
    return OSIP_NOMEM;
  }

  i = osip_to_clone (request->to, &(response->to));
  if (i != 0) {
    osip_message_free (response);
    return i;
  }

  i = osip_to_get_tag (response->to, &tag);
  if (i != 0) {                 /* we only add a tag if it does not already contains one! */
    if ((dialog != NULL) && (dialog->local_tag != NULL))
      /* it should contain the local TAG we created */
    {
      osip_to_set_tag (response->to, osip_strdup (dialog->local_tag));
    }
    else {
      if (status != 100)
        osip_to_set_tag (response->to, _eXosip_malloc_new_random ());
    }
  }

  i = osip_from_clone (request->from, &(response->from));
  if (i != 0) {
    osip_message_free (response);
    return i;
  }

  {
    osip_list_iterator_t it;
    osip_via_t *via = (osip_via_t*)osip_list_get_first(&request->vias, &it);

    while (via != NULL) {
      osip_via_t *via2;

      i = osip_via_clone (via, &via2);
      if (i != 0) {
        osip_message_free (response);
        return i;
      }
      osip_list_add (&response->vias, via2, -1);
      via = (osip_via_t *)osip_list_get_next(&it);
    }
  }

  i = osip_call_id_clone (request->call_id, &(response->call_id));
  if (i != 0) {
    osip_message_free (response);
    return i;
  }
  i = osip_cseq_clone (request->cseq, &(response->cseq));
  if (i != 0) {
    osip_message_free (response);
    return i;
  }
#ifndef MINISIZE
  if (MSG_IS_SUBSCRIBE (request)) {
    osip_header_t *exp;
    osip_header_t *evt_hdr;

    osip_message_header_get_byname (request, "event", 0, &evt_hdr);
    if (evt_hdr != NULL && evt_hdr->hvalue != NULL)
      osip_message_set_header (response, "Event", evt_hdr->hvalue);
    else
      osip_message_set_header (response, "Event", "presence");
    i = osip_message_get_expires (request, 0, &exp);
    if (exp == NULL) {
      osip_header_t *cp;

      i = osip_header_clone (exp, &cp);
      if (cp != NULL)
        osip_list_add (&response->headers, cp, 0);
    }
  }
#endif

  osip_message_set_user_agent (response, excontext->user_agent);

  *dest = response;
  return OSIP_SUCCESS;
}
int
eXosip_insubscription_automatic (eXosip_event_t * evt)
{
  eXosip_dialog_t *jd = NULL;
  eXosip_notify_t *jn = NULL;

  osip_header_t *event_header;
  if (evt->did <= 0 || evt->nid <= 0)
    return OSIP_BADPARAMETER;
  if (evt->request == NULL)
    return OSIP_BADPARAMETER;

  eXosip_notify_dialog_find (evt->did, &jn, &jd);
  if (jd == NULL || jn == NULL)
    {
      OSIP_TRACE (osip_trace
                  (__FILE__, __LINE__, OSIP_ERROR, NULL,
                   "eXosip: No incoming subscription here?\n"));
      return OSIP_NOTFOUND;
    }

  osip_message_header_get_byname (evt->request, "event", 0, &event_header);
  if (event_header == NULL || event_header->hvalue == NULL)
    {
      eXosip_insubscription_send_answer (evt->tid, 400, NULL);
      return OSIP_SUCCESS;
    }

  /* this event should be handled internally */
  if (osip_strcasecmp (event_header->hvalue, "dialog") == 0)
    {
      /* send 200 ok to SUBSCRIBEs */

      if (evt->type == EXOSIP_IN_SUBSCRIPTION_NEW)
        {
          osip_message_t *answer;
          int i;

          i = eXosip_insubscription_build_answer (evt->tid, 202, &answer);
          if (i == 0)
            {
              i = eXosip_insubscription_send_answer (evt->tid, 202, answer);
            }
          if (i != 0)
            {
              i = eXosip_insubscription_send_answer (evt->tid, 400, NULL);
              return OSIP_SUCCESS;
            }

          /* send initial notify */
          i =
            _eXosip_insubscription_auto_send_notify (evt->did,
                                                     EXOSIP_SUBCRSTATE_ACTIVE,
                                                     PROBATION);
          if (i != 0)
            {
              /* delete subscription... */
              return OSIP_SUCCESS;
            }
        }
  } else
    {
      if (evt->type == EXOSIP_IN_SUBSCRIPTION_NEW)
        {
          eXosip_insubscription_send_answer (evt->tid, 489, NULL);
        }
    }

  return OSIP_SUCCESS;
}