예제 #1
0
int
_eXosip_insubscription_answer_3456xx (struct eXosip_t *excontext, eXosip_notify_t * jn, eXosip_dialog_t * jd, int code)
{
  osip_event_t *evt_answer;
  osip_message_t *response;
  int i;
  osip_transaction_t *tr;

  tr = _eXosip_find_last_inc_subscribe (jn, jd);
  if (tr == NULL) {
    OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: cannot find transaction to answer"));
    return OSIP_NOTFOUND;
  }
  if (jd == NULL)
    i = _eXosip_build_response_default (excontext, &response, NULL, code, tr->orig_request);
  else
    i = _eXosip_build_response_default (excontext, &response, jd->d_dialog, code, tr->orig_request);
  if (i != 0) {
    OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO1, NULL, "ERROR: Could not create response for subscribe\n"));
    return i;
  }

  if ((300 <= code) && (code <= 399)) {
    /* Should add contact fields */
    /* ... */
  }

  evt_answer = osip_new_outgoing_sipmessage (response);
  evt_answer->transactionid = tr->transactionid;

  osip_transaction_add_event (tr, evt_answer);
  _eXosip_wakeup (excontext);
  return OSIP_SUCCESS;
}
예제 #2
0
int
eXosip_subscribe_send_refresh_request (struct eXosip_t *excontext, int did, osip_message_t * sub)
{
  eXosip_dialog_t *jd = NULL;
  eXosip_subscribe_t *js = NULL;

  osip_transaction_t *transaction;
  osip_event_t *sipevent;
  int i;

  if (did <= 0)
    return OSIP_BADPARAMETER;

  if (did > 0) {
    _eXosip_subscribe_dialog_find (excontext, did, &js, &jd);
  }
  if (jd == NULL) {
    OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: No subscribe here?\n"));
    osip_message_free (sub);
    return OSIP_NOTFOUND;
  }

  transaction = NULL;
  transaction = _eXosip_find_last_out_subscribe (js, jd);

  if (transaction != NULL) {
    if (transaction->state != NICT_TERMINATED && transaction->state != NIST_TERMINATED && transaction->state != NICT_COMPLETED && transaction->state != NIST_COMPLETED) {
      osip_message_free (sub);
      return OSIP_WRONG_STATE;
    }
    transaction = NULL;
  }

  transaction = NULL;
  i = _eXosip_transaction_init (excontext, &transaction, NICT, excontext->j_osip, sub);

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

  js->s_reg_period = 3600;
  _eXosip_subscribe_set_refresh_interval (js, sub);
  osip_list_add (jd->d_out_trs, transaction, 0);

  sipevent = osip_new_outgoing_sipmessage (sub);
  sipevent->transactionid = transaction->transactionid;

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

  osip_transaction_add_event (transaction, sipevent);
  _eXosip_wakeup (excontext);
  return OSIP_SUCCESS;
}
예제 #3
0
int eXosip_options_send_answer(struct eXosip_t *excontext, int tid, int status, osip_message_t * answer)
{
	osip_transaction_t *tr = NULL;
	osip_event_t *evt_answer;
	int i = -1;

	if (tid <= 0)
		return OSIP_BADPARAMETER;
	if (status <= 100 || status > 699)
		return OSIP_BADPARAMETER;
	if (answer == NULL && status > 100 && status < 200)
		return OSIP_BADPARAMETER;

	if (tid > 0) {
		_eXosip_transaction_find(excontext, tid, &tr);
	}
	if (tr == NULL) {
		OSIP_TRACE(osip_trace
				   (__FILE__, __LINE__, OSIP_ERROR, NULL,
					"eXosip: No OPTIONS transaction found\n"));
		osip_message_free(answer);
		return OSIP_NOTFOUND;
	}

	/* is the transaction already answered? */
	if (tr->state == NIST_COMPLETED || tr->state == NIST_TERMINATED) {
		OSIP_TRACE(osip_trace
				   (__FILE__, __LINE__, OSIP_ERROR, NULL,
					"eXosip: transaction already answered\n"));
		osip_message_free(answer);
		return OSIP_WRONG_STATE;
	}

	if (answer == NULL) {
		i = -1;
		if (status > 199 && status < 300)
			i = _eXosip_build_response_default(excontext, &answer, NULL, status,
											   tr->orig_request);
		else if (status > 300 && status <= 699)
			i = _eXosip_build_response_default(excontext, &answer, NULL, status,
											   tr->orig_request);
		if (i != 0)
			return i;
	}

	evt_answer = osip_new_outgoing_sipmessage(answer);
	evt_answer->transactionid = tr->transactionid;

	osip_transaction_add_event(tr, evt_answer);
	_eXosip_wakeup(excontext);
	return OSIP_SUCCESS;
}
예제 #4
0
int
_eXosip_insubscription_answer_1xx (struct eXosip_t *excontext, eXosip_notify_t * jn, eXosip_dialog_t * jd, int code)
{
  osip_event_t *evt_answer;
  osip_message_t *response;
  int i;
  osip_transaction_t *tr;

  tr = _eXosip_find_last_inc_subscribe (jn, jd);
  if (tr == NULL) {
    OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: cannot find transaction to answer"));
    return OSIP_NOTFOUND;
  }

  if (jd == NULL)
    i = _eXosip_build_response_default (excontext, &response, NULL, code, tr->orig_request);
  else
    i = _eXosip_build_response_default (excontext, &response, jd->d_dialog, code, tr->orig_request);

  if (i != 0) {
    OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "ERROR: Could not create response for subscribe\n"));
    return i;
  }

  if (code > 100) {
    /* request that estabish a dialog: */
    /* 12.1.1 UAS Behavior */
    i = _eXosip_complete_answer_that_establish_a_dialog (excontext, response, tr->orig_request);
    if (i != 0) {
    }

    if (jd == NULL) {
      i = _eXosip_dialog_init_as_uas (&jd, tr->orig_request, response);
      if (i != 0) {
        OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: cannot create dialog!\n"));
      }
      else
        ADD_ELEMENT (jn->n_dialogs, jd);
    }
  }

  evt_answer = osip_new_outgoing_sipmessage (response);
  evt_answer->transactionid = tr->transactionid;

  osip_transaction_add_event (tr, evt_answer);
  _eXosip_wakeup (excontext);
  return i;
}
예제 #5
0
int eXosip_options_send_request(struct eXosip_t *excontext, osip_message_t * options)
{
	osip_transaction_t *transaction;
	osip_event_t *sipevent;
	int i;

	i = _eXosip_transaction_init(excontext, &transaction, NICT, excontext->j_osip, options);
	if (i != 0) {
		osip_message_free(options);
		return i;
	}

	osip_list_add(&excontext->j_transactions, transaction, 0);

	sipevent = osip_new_outgoing_sipmessage(options);
	sipevent->transactionid = transaction->transactionid;

	osip_transaction_add_event(transaction, sipevent);

	_eXosip_wakeup(excontext);
	return OSIP_SUCCESS;
}
예제 #6
0
int
eXosip_subscribe_send_initial_request (struct eXosip_t *excontext, osip_message_t * subscribe)
{
  eXosip_subscribe_t *js = NULL;
  osip_transaction_t *transaction;
  osip_event_t *sipevent;
  int i;

  i = _eXosip_subscribe_init (&js);
  if (i != 0) {
    OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: cannot subscribe."));
    osip_message_free (subscribe);
    return i;
  }

  i = _eXosip_transaction_init (excontext, &transaction, NICT, excontext->j_osip, subscribe);
  if (i != 0) {
    _eXosip_subscribe_free (excontext, js);
    osip_message_free (subscribe);
    return i;
  }

  js->s_reg_period = 3600;
  _eXosip_subscribe_set_refresh_interval (js, subscribe);
  js->s_out_tr = transaction;

  sipevent = osip_new_outgoing_sipmessage (subscribe);
  sipevent->transactionid = transaction->transactionid;

  osip_transaction_set_reserved5 (transaction, js);
  osip_transaction_add_event (transaction, sipevent);

  ADD_ELEMENT (excontext->j_subscribes, js);
  _eXosip_update (excontext);   /* fixed? */
  _eXosip_wakeup (excontext);
  return js->s_id;
}
예제 #7
0
int
eXosip_publish (struct eXosip_t *excontext, osip_message_t * message, const char *to)
{
  osip_transaction_t *transaction;
  osip_event_t *sipevent;
  int i;
  eXosip_pub_t *pub = NULL;

  if (message == NULL)
    return OSIP_BADPARAMETER;
  if (message->cseq == NULL || message->cseq->number == NULL) {
    osip_message_free (message);
    return OSIP_SYNTAXERROR;
  }
  if (to == NULL) {
    osip_message_free (message);
    return OSIP_BADPARAMETER;
  }

  i = _eXosip_pub_find_by_aor (excontext, &pub, to);
  if (i != 0 || pub == NULL) {
    osip_header_t *expires;

    osip_message_get_expires (message, 0, &expires);
    if (expires == NULL || expires->hvalue == NULL) {
      OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: missing expires header in PUBLISH!"));
      osip_message_free (message);
      return OSIP_SYNTAXERROR;
    }
    else {
      /* start a new publication context */
      i = _eXosip_pub_init (&pub, to, expires->hvalue);
      if (i != 0) {
        osip_message_free (message);
        return i;
      }
      ADD_ELEMENT (excontext->j_pub, pub);
    }
  }
  else {
    if (pub->p_sip_etag[0] != '\0') {
      /* increase cseq */
      osip_message_set_header (message, "SIP-If-Match", pub->p_sip_etag);
    }

    {
      osip_header_t *expires;

      osip_message_get_expires (message, 0, &expires);
      if (expires == NULL || expires->hvalue == NULL) {
        OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: missing expires header in PUBLISH!"));
        osip_message_free (message);
        return OSIP_SYNTAXERROR;
      }
      pub->p_period = atoi (expires->hvalue);
    }

    if (pub->p_last_tr != NULL && pub->p_last_tr->cseq != NULL && pub->p_last_tr->cseq->number != NULL) {
      int osip_cseq_num = osip_atoi (pub->p_last_tr->cseq->number);
      int length = (int) strlen (pub->p_last_tr->cseq->number);

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

  i = _eXosip_transaction_init (excontext, &transaction, NICT, excontext->j_osip, message);
  if (i != 0) {
    osip_message_free (message);
    return i;
  }

  if (pub->p_last_tr != NULL)
    osip_list_add (&excontext->j_transactions, pub->p_last_tr, 0);
  pub->p_last_tr = transaction;

  sipevent = osip_new_outgoing_sipmessage (message);
  sipevent->transactionid = transaction->transactionid;

  osip_transaction_add_event (transaction, sipevent);
  _eXosip_wakeup (excontext);
  return transaction->transactionid;
}
예제 #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_answer_invite_123456xx (struct eXosip_t *excontext, eXosip_call_t * jc, eXosip_dialog_t * jd, int code, osip_message_t ** answer, int send)
{
  int i;
  osip_transaction_t *tr;

  *answer = NULL;
  tr = _eXosip_find_last_inc_invite (jc, jd);

  if (tr == NULL || tr->orig_request == NULL) {
    OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: cannot find transaction to answer\n"));
    return OSIP_NOTFOUND;
  }

  if (code >= 200 && code < 300 && jd != NULL && jd->d_dialog == NULL) {        /* element previously removed */
    OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: cannot answer this closed transaction\n"));
    return OSIP_WRONG_STATE;
  }

  /* is the transaction already answered? */
  if (tr->state == IST_COMPLETED || tr->state == IST_CONFIRMED || tr->state == IST_TERMINATED) {
    OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: transaction already answered\n"));
    return OSIP_WRONG_STATE;
  }

  if (jd == NULL)
    i = _eXosip_build_response_default (excontext, answer, NULL, code, tr->orig_request);
  else
    i = _eXosip_build_response_default (excontext, answer, jd->d_dialog, code, tr->orig_request);

  if (i != 0) {
    OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO1, NULL, "ERROR: Could not create response for invite\n"));
    *answer = NULL;
    return i;
  }

  /* request that estabish a dialog: */
  /* 12.1.1 UAS Behavior */
  if (code > 100 && code < 300) {
    i = _eXosip_complete_answer_that_establish_a_dialog (excontext, *answer, tr->orig_request);
    if (i != 0) {
      osip_message_free (*answer);
      *answer = NULL;
      return i;
    }
  }


  if (send == 1) {
    osip_event_t *evt_answer;

    if (code >= 200 && code < 300 && jd != NULL) {
      _eXosip_dialog_set_200ok (jd, *answer);
      /* wait for a ACK */
      osip_dialog_set_state (jd->d_dialog, DIALOG_CONFIRMED);
    }

    evt_answer = osip_new_outgoing_sipmessage (*answer);
    evt_answer->transactionid = tr->transactionid;

    osip_transaction_add_event (tr, evt_answer);
    _eXosip_wakeup (excontext);
    *answer = NULL;
  }

  return OSIP_SUCCESS;
}