PJ_DEF(pj_status_t) pjsip_endpt_create_request(  pjsip_endpoint *endpt, 
						 const pjsip_method *method,
						 const pj_str_t *param_target,
						 const pj_str_t *param_from,
						 const pj_str_t *param_to, 
						 const pj_str_t *param_contact,
						 const pj_str_t *param_call_id,
						 int param_cseq, 
						 const pj_str_t *param_text,
						 pjsip_tx_data **p_tdata)
{
    pjsip_uri *target;
    pjsip_tx_data *tdata;
    pjsip_from_hdr *from;
    pjsip_to_hdr *to;
    pjsip_contact_hdr *contact;
    pjsip_cseq_hdr *cseq = NULL;    /* = NULL, warning in VC6 */
    pjsip_cid_hdr *call_id;
    pj_str_t tmp;
    pj_status_t status;
    const pj_str_t STR_CONTACT = { "Contact", 7 };
    PJ_USE_EXCEPTION;

    status = pjsip_endpt_create_tdata(endpt, &tdata);
    if (status != PJ_SUCCESS)
	return status;

    /* Init reference counter to 1. */
    pjsip_tx_data_add_ref(tdata);

    PJ_TRY {
	/* Request target. */
	pj_strdup_with_null(tdata->pool, &tmp, param_target);
	target = pjsip_parse_uri( tdata->pool, tmp.ptr, tmp.slen, 0);
	if (target == NULL) {
	    status = PJSIP_EINVALIDREQURI;
	    goto on_error;
	}

	/* From */
	from = pjsip_from_hdr_create(tdata->pool);
	pj_strdup_with_null(tdata->pool, &tmp, param_from);
	from->uri = pjsip_parse_uri( tdata->pool, tmp.ptr, tmp.slen, 
				     PJSIP_PARSE_URI_AS_NAMEADDR);
	if (from->uri == NULL) {
	    status = PJSIP_EINVALIDHDR;
	    goto on_error;
	}
	pj_create_unique_string(tdata->pool, &from->tag);

	/* To */
	to = pjsip_to_hdr_create(tdata->pool);
	pj_strdup_with_null(tdata->pool, &tmp, param_to);
	to->uri = pjsip_parse_uri( tdata->pool, tmp.ptr, tmp.slen, 
				   PJSIP_PARSE_URI_AS_NAMEADDR);
	if (to->uri == NULL) {
	    status = PJSIP_EINVALIDHDR;
	    goto on_error;
	}

	/* Contact. */
	if (param_contact) {
	    pj_strdup_with_null(tdata->pool, &tmp, param_contact);
	    contact = (pjsip_contact_hdr*)
		      pjsip_parse_hdr(tdata->pool, &STR_CONTACT, tmp.ptr, 
				      tmp.slen, NULL);
	    if (contact == NULL) {
		status = PJSIP_EINVALIDHDR;
		goto on_error;
	    }
	} else {
	    contact = NULL;
	}

	/* Call-ID */
	call_id = pjsip_cid_hdr_create(tdata->pool);
	if (param_call_id != NULL && param_call_id->slen)
	    pj_strdup(tdata->pool, &call_id->id, param_call_id);
	else
	    pj_create_unique_string(tdata->pool, &call_id->id);

	/* CSeq */
	cseq = pjsip_cseq_hdr_create(tdata->pool);
	if (param_cseq >= 0)
	    cseq->cseq = param_cseq;
	else
	    cseq->cseq = pj_rand() & 0xFFFF;

	/* Method */
	pjsip_method_copy(tdata->pool, &cseq->method, method);

	/* Create the request. */
	init_request_throw( endpt, tdata, &cseq->method, target, from, to, 
                            contact, call_id, cseq, param_text);
    }
    PJ_CATCH_ANY {
	status = PJ_ENOMEM;
	goto on_error;
    }
    PJ_END

    *p_tdata = tdata;
    return PJ_SUCCESS;

on_error:
    pjsip_tx_data_dec_ref(tdata);
    return status;
}
PJ_DEF(pj_status_t) pjsip_endpt_create_request(  pjsip_endpoint *endpt, 
						 const pjsip_method *method,
						 const pj_str_t *param_target,
						 const pj_str_t *param_from,
						 const pj_str_t *param_to, 
						 const pj_str_t *param_contact,
						 const pj_str_t *param_call_id,
						 int param_cseq, 
						 const pj_str_t *param_text,
						 pjsip_tx_data **p_tdata)
{
    pjsip_uri *target;
    pjsip_tx_data *tdata;
    pjsip_from_hdr *from;
    pjsip_to_hdr *to;
    pjsip_contact_hdr *contact;
    pjsip_cseq_hdr *cseq = NULL;     
    pjsip_cid_hdr *call_id;
    pj_str_t tmp;
    pj_status_t status;
    const pj_str_t STR_CONTACT = { "Contact", 7 };
    PJ_USE_EXCEPTION;

    status = pjsip_endpt_create_tdata(endpt, &tdata);
    if (status != PJ_SUCCESS)
	return status;

     
    pjsip_tx_data_add_ref(tdata);

    PJ_TRY {
	 
	pj_strdup_with_null(tdata->pool, &tmp, param_target);
	target = pjsip_parse_uri( tdata->pool, tmp.ptr, tmp.slen, 0);
	if (target == NULL) {
	    status = PJSIP_EINVALIDREQURI;
	    goto on_error;
	}

	 
	from = pjsip_from_hdr_create(tdata->pool);
	pj_strdup_with_null(tdata->pool, &tmp, param_from);
	from->uri = pjsip_parse_uri( tdata->pool, tmp.ptr, tmp.slen, 
				     PJSIP_PARSE_URI_AS_NAMEADDR);
	if (from->uri == NULL) {
	    status = PJSIP_EINVALIDHDR;
	    goto on_error;
	}
	pj_create_unique_string(tdata->pool, &from->tag);

	 
	to = pjsip_to_hdr_create(tdata->pool);
	pj_strdup_with_null(tdata->pool, &tmp, param_to);
	to->uri = pjsip_parse_uri( tdata->pool, tmp.ptr, tmp.slen, 
				   PJSIP_PARSE_URI_AS_NAMEADDR);
	if (to->uri == NULL) {
	    status = PJSIP_EINVALIDHDR;
	    goto on_error;
	}

	 
	if (param_contact) {
	    pj_strdup_with_null(tdata->pool, &tmp, param_contact);
	    contact = (pjsip_contact_hdr*)
		      pjsip_parse_hdr(tdata->pool, &STR_CONTACT, tmp.ptr, 
				      tmp.slen, NULL);
	    if (contact == NULL) {
		status = PJSIP_EINVALIDHDR;
		goto on_error;
	    }
	} else {
	    contact = NULL;
	}

	 
	call_id = pjsip_cid_hdr_create(tdata->pool);
	if (param_call_id != NULL && param_call_id->slen)
	    pj_strdup(tdata->pool, &call_id->id, param_call_id);
	else
	    pj_create_unique_string(tdata->pool, &call_id->id);

	 
	cseq = pjsip_cseq_hdr_create(tdata->pool);
	if (param_cseq >= 0)
	    cseq->cseq = param_cseq;
	else
	    cseq->cseq = pj_rand() & 0xFFFF;

	 
	pjsip_method_copy(tdata->pool, &cseq->method, method);

	 
	init_request_throw( endpt, tdata, &cseq->method, target, from, to, 
                            contact, call_id, cseq, param_text);
    }
    PJ_CATCH_ANY {
	status = PJ_ENOMEM;
	goto on_error;
    }
    PJ_END

    *p_tdata = tdata;
    return PJ_SUCCESS;

on_error:
    pjsip_tx_data_dec_ref(tdata);
    return status;
}