PJ_DEF(pj_status_t) pjsip_endpt_send_raw_to_uri(pjsip_endpoint *endpt,
						const pj_str_t *p_dst_uri,
						const pjsip_tpselector *sel,
						const void *raw_data,
						pj_size_t data_len,
						void *token,
						pjsip_tp_send_callback cb)
{
    pjsip_tx_data *tdata;
    struct send_raw_data *sraw_data;
    pj_str_t dst_uri;
    pjsip_uri *uri;
    pjsip_host_info dest_info;
    pj_status_t status;

    /* Allocate buffer */
    status = pjsip_endpt_create_tdata(endpt, &tdata);
    if (status != PJ_SUCCESS)
	return status;

    pjsip_tx_data_add_ref(tdata);

    /* Duplicate URI since parser requires URI to be NULL terminated */
    pj_strdup_with_null(tdata->pool, &dst_uri, p_dst_uri);

    /* Parse URI */
    uri = pjsip_parse_uri(tdata->pool, dst_uri.ptr, dst_uri.slen, 0);
    if (uri == NULL) {
	pjsip_tx_data_dec_ref(tdata);
	return PJSIP_EINVALIDURI;
    }

    /* Build destination info. */
    status = pjsip_get_dest_info(uri, NULL, tdata->pool, &dest_info);
    if (status != PJ_SUCCESS) {
	pjsip_tx_data_dec_ref(tdata);
	return status;
    }

    /* Copy data (note: data_len may be zero!) */
    tdata->buf.start = (char*) pj_pool_alloc(tdata->pool, data_len+1);
    tdata->buf.end = tdata->buf.start + data_len + 1;
    if (data_len)
	pj_memcpy(tdata->buf.start, raw_data, data_len);
    tdata->buf.cur = tdata->buf.start + data_len;

    /* Init send_raw_data */
    sraw_data = PJ_POOL_ZALLOC_T(tdata->pool, struct send_raw_data);
    sraw_data->endpt = endpt;
    sraw_data->tdata = tdata;
    sraw_data->app_token = token;
    sraw_data->app_cb = cb;

    if (sel) {
	sraw_data->sel = PJ_POOL_ALLOC_T(tdata->pool, pjsip_tpselector);
	pj_memcpy(sraw_data->sel, sel, sizeof(pjsip_tpselector));
	pjsip_tpselector_add_ref(sraw_data->sel);
    }

    /* Copy the destination host name to TX data */
    pj_strdup(tdata->pool, &tdata->dest_info.name, &dest_info.addr.host);

    /* Resolve destination host.
     * The processing then resumed when the resolving callback is called.
     */
    pjsip_endpt_resolve( endpt, tdata->pool, &dest_info, sraw_data,
			 &send_raw_resolver_callback);
    return PJ_SUCCESS;
}
PJ_DEF(pj_status_t) pjsip_endpt_send_raw_to_uri(pjsip_endpoint *endpt,
						const pj_str_t *p_dst_uri,
						const pjsip_tpselector *sel,
						const void *raw_data,
						pj_size_t data_len,
						void *token,
						pjsip_tp_send_callback cb)
{
    pjsip_tx_data *tdata;
    struct send_raw_data *sraw_data;
    pj_str_t dst_uri;
    pjsip_uri *uri;
    pjsip_host_info dest_info;
    pj_status_t status;

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

    pjsip_tx_data_add_ref(tdata);

     
    pj_strdup_with_null(tdata->pool, &dst_uri, p_dst_uri);

     
    uri = pjsip_parse_uri(tdata->pool, dst_uri.ptr, dst_uri.slen, 0);
    if (uri == NULL) {
	pjsip_tx_data_dec_ref(tdata);
	return PJSIP_EINVALIDURI;
    }

     
    status = pjsip_get_dest_info(uri, NULL, tdata->pool, &dest_info);
    if (status != PJ_SUCCESS) {
	pjsip_tx_data_dec_ref(tdata);
	return status;
    }

     
    tdata->buf.start = (char*) pj_pool_alloc(tdata->pool, data_len+1);
    tdata->buf.end = tdata->buf.start + data_len + 1;
    if (data_len)
	pj_memcpy(tdata->buf.start, raw_data, data_len);
    tdata->buf.cur = tdata->buf.start + data_len;

     
    sraw_data = PJ_POOL_ZALLOC_T(tdata->pool, struct send_raw_data);
    sraw_data->endpt = endpt;
    sraw_data->tdata = tdata;
    sraw_data->app_token = token;
    sraw_data->app_cb = cb;

    if (sel) {
	sraw_data->sel = PJ_POOL_ALLOC_T(tdata->pool, pjsip_tpselector);
	pj_memcpy(sraw_data->sel, sel, sizeof(pjsip_tpselector));
	pjsip_tpselector_add_ref(sraw_data->sel);
    }

     
    pj_strdup(tdata->pool, &tdata->dest_info.name, &dest_info.addr.host);

     
    pjsip_endpt_resolve( endpt, tdata->pool, &dest_info, sraw_data,
			 &send_raw_resolver_callback);
    return PJ_SUCCESS;
}