More ticket #341: renamed pjsip_transport_send_raw() to pjsip_tpmgr_send_raw(), and added pjsip_endpt_send_raw() and pjsip_endpt_send_raw_to_uri()
git-svn-id: https://svn.pjsip.org/repos/pjproject/trunk@1388 74dad513-b988-da41-8d7b-12977e46ad98
This commit is contained in:
parent
4ea2afafd0
commit
fd1204c1a9
4 changed files with 318 additions and 39 deletions
|
@ -1058,10 +1058,20 @@ PJ_DECL(pj_status_t) pjsip_transport_send( pjsip_transport *tr,
|
|||
|
||||
|
||||
/**
|
||||
* This is a low-level function to send raw data using the specified transport
|
||||
* to the specified destination.
|
||||
* This is a low-level function to send raw data to a destination.
|
||||
*
|
||||
* @param tr The SIP transport to be used.
|
||||
* See also #pjsip_endpt_send_raw() and #pjsip_endpt_send_raw_to_uri().
|
||||
*
|
||||
* @param mgr Transport manager.
|
||||
* @param tp_type Transport type.
|
||||
* @param sel Optional pointer to transport selector instance if
|
||||
* application wants to use a specific transport instance
|
||||
* rather then letting transport manager finds the suitable
|
||||
* transport.
|
||||
* @param tdata Optional transmit data buffer to be used. If this value
|
||||
* is NULL, this function will create one internally. If
|
||||
* tdata is specified, this function will decrement the
|
||||
* reference counter upon completion.
|
||||
* @param raw_data The data to be sent.
|
||||
* @param data_len The length of the data.
|
||||
* @param addr Destination address.
|
||||
|
@ -1079,14 +1089,16 @@ PJ_DECL(pj_status_t) pjsip_transport_send( pjsip_transport *tr,
|
|||
* indicates immediate failure, and in this case the
|
||||
* callback will not be called.
|
||||
*/
|
||||
PJ_DECL(pj_status_t) pjsip_transport_send_raw(pjsip_transport *tr,
|
||||
const void *raw_data,
|
||||
pj_size_t data_len,
|
||||
const pj_sockaddr_t *addr,
|
||||
int addr_len,
|
||||
void *token,
|
||||
pjsip_tp_send_callback cb);
|
||||
|
||||
PJ_DECL(pj_status_t) pjsip_tpmgr_send_raw(pjsip_tpmgr *mgr,
|
||||
pjsip_transport_type_e tp_type,
|
||||
const pjsip_tpselector *sel,
|
||||
pjsip_tx_data *tdata,
|
||||
const void *raw_data,
|
||||
pj_size_t data_len,
|
||||
const pj_sockaddr_t *addr,
|
||||
int addr_len,
|
||||
void *token,
|
||||
pjsip_tp_send_callback cb);
|
||||
|
||||
/**
|
||||
* @}
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#define __PJSIP_SIP_MISC_H__
|
||||
|
||||
#include <pjsip/sip_msg.h>
|
||||
#include <pjsip/sip_transport.h>
|
||||
#include <pjsip/sip_resolve.h>
|
||||
|
||||
PJ_BEGIN_DECL
|
||||
|
@ -219,7 +220,6 @@ PJ_DECL(pj_status_t) pjsip_get_request_dest(const pjsip_tx_data *tdata,
|
|||
PJ_DECL(pj_status_t) pjsip_process_route_set(pjsip_tx_data *tdata,
|
||||
pjsip_host_info *dest_info );
|
||||
|
||||
|
||||
/**
|
||||
* This structure holds the state of outgoing stateless request.
|
||||
*/
|
||||
|
@ -258,8 +258,10 @@ typedef struct pjsip_send_state
|
|||
pj_bool_t *cont);
|
||||
} pjsip_send_state;
|
||||
|
||||
typedef void (*pjsip_endpt_callback)(pjsip_send_state*, pj_ssize_t sent,
|
||||
pj_bool_t *cont);
|
||||
|
||||
typedef void (*pjsip_send_callback)(pjsip_send_state*, pj_ssize_t sent,
|
||||
pj_bool_t *cont);
|
||||
|
||||
/**
|
||||
* Send outgoing request statelessly The function will take care of which
|
||||
* destination and transport to use based on the information in the message,
|
||||
|
@ -281,7 +283,81 @@ PJ_DECL(pj_status_t)
|
|||
pjsip_endpt_send_request_stateless( pjsip_endpoint *endpt,
|
||||
pjsip_tx_data *tdata,
|
||||
void *token,
|
||||
pjsip_endpt_callback cb);
|
||||
pjsip_send_callback cb);
|
||||
|
||||
/**
|
||||
* This is a low-level function to send raw data to a destination.
|
||||
*
|
||||
* See also #pjsip_endpt_send_raw_to_uri().
|
||||
*
|
||||
* @param endpt The SIP endpoint instance.
|
||||
* @param tp_type Transport type.
|
||||
* @param sel Optional pointer to transport selector instance if
|
||||
* application wants to use a specific transport instance
|
||||
* rather then letting transport manager finds the suitable
|
||||
* transport..
|
||||
* @param raw_data The data to be sent.
|
||||
* @param data_len The length of the data.
|
||||
* @param addr Destination address.
|
||||
* @param addr_len Length of destination address.
|
||||
* @param token Arbitrary token to be returned back to callback.
|
||||
* @param cb Optional callback to be called to notify caller about
|
||||
* the completion status of the pending send operation.
|
||||
*
|
||||
* @return If the message has been sent successfully, this function
|
||||
* will return PJ_SUCCESS and the callback will not be
|
||||
* called. If message cannot be sent immediately, this
|
||||
* function will return PJ_EPENDING, and application will
|
||||
* be notified later about the completion via the callback.
|
||||
* Any statuses other than PJ_SUCCESS or PJ_EPENDING
|
||||
* indicates immediate failure, and in this case the
|
||||
* callback will not be called.
|
||||
*/
|
||||
PJ_DECL(pj_status_t) pjsip_endpt_send_raw(pjsip_endpoint *endpt,
|
||||
pjsip_transport_type_e tp_type,
|
||||
const pjsip_tpselector *sel,
|
||||
const void *raw_data,
|
||||
pj_size_t data_len,
|
||||
const pj_sockaddr_t *addr,
|
||||
int addr_len,
|
||||
void *token,
|
||||
pjsip_tp_send_callback cb);
|
||||
|
||||
/**
|
||||
* Send raw data to the specified destination URI. The actual destination
|
||||
* address will be calculated from the URI, using normal SIP URI to host
|
||||
* resolution.
|
||||
*
|
||||
* See also #pjsip_endpt_send_raw().
|
||||
*
|
||||
* @param endpt The SIP endpoint instance.
|
||||
* @param dst_uri Destination address URI.
|
||||
* @param sel Optional pointer to transport selector instance if
|
||||
* application wants to use a specific transport instance
|
||||
* rather then letting transport manager finds the suitable
|
||||
* transport..
|
||||
* @param raw_data The data to be sent.
|
||||
* @param data_len The length of the data.
|
||||
* @param token Arbitrary token to be returned back to callback.
|
||||
* @param cb Optional callback to be called to notify caller about
|
||||
* the completion status of the pending send operation.
|
||||
*
|
||||
* @return If the message has been sent successfully, this function
|
||||
* will return PJ_SUCCESS and the callback will not be
|
||||
* called. If message cannot be sent immediately, this
|
||||
* function will return PJ_EPENDING, and application will
|
||||
* be notified later about the completion via the callback.
|
||||
* Any statuses other than PJ_SUCCESS or PJ_EPENDING
|
||||
* indicates immediate failure, and in this case the
|
||||
* callback will not be called.
|
||||
*/
|
||||
PJ_DECL(pj_status_t) pjsip_endpt_send_raw_to_uri(pjsip_endpoint *endpt,
|
||||
const pj_str_t *dst_uri,
|
||||
const pjsip_tpselector *sel,
|
||||
const void *raw_data,
|
||||
pj_size_t data_len,
|
||||
void *token,
|
||||
pjsip_tp_send_callback cb);
|
||||
|
||||
/**
|
||||
* This structure describes destination information to send response.
|
||||
|
@ -357,7 +433,7 @@ PJ_DECL(pj_status_t) pjsip_endpt_send_response( pjsip_endpoint *endpt,
|
|||
pjsip_response_addr *res_addr,
|
||||
pjsip_tx_data *tdata,
|
||||
void *token,
|
||||
pjsip_endpt_callback cb);
|
||||
pjsip_send_callback cb);
|
||||
|
||||
/**
|
||||
* This is a convenient function which wraps #pjsip_get_response_addr() and
|
||||
|
@ -380,7 +456,7 @@ PJ_DECL(pj_status_t) pjsip_endpt_send_response2(pjsip_endpoint *endpt,
|
|||
pjsip_rx_data *rdata,
|
||||
pjsip_tx_data *tdata,
|
||||
void *token,
|
||||
pjsip_endpt_callback cb);
|
||||
pjsip_send_callback cb);
|
||||
|
||||
/**
|
||||
* This composite function sends response message statelessly to an incoming
|
||||
|
|
|
@ -603,31 +603,77 @@ PJ_DEF(pj_status_t) pjsip_transport_send( pjsip_transport *tr,
|
|||
}
|
||||
|
||||
|
||||
/* Send raw data */
|
||||
PJ_DEF(pj_status_t) pjsip_transport_send_raw(pjsip_transport *tr,
|
||||
const void *raw_data,
|
||||
pj_size_t data_len,
|
||||
const pj_sockaddr_t *addr,
|
||||
int addr_len,
|
||||
void *token,
|
||||
pjsip_tp_send_callback cb)
|
||||
/* send_raw() callback */
|
||||
static void send_raw_callback(pjsip_transport *transport,
|
||||
void *token,
|
||||
pj_ssize_t size)
|
||||
{
|
||||
pjsip_tx_data *tdata;
|
||||
pjsip_tx_data *tdata = (pjsip_tx_data*) token;
|
||||
|
||||
/* Mark pending off so that app can resend/reuse txdata from inside
|
||||
* the callback.
|
||||
*/
|
||||
tdata->is_pending = 0;
|
||||
|
||||
/* Call callback, if any. */
|
||||
if (tdata->cb) {
|
||||
(*tdata->cb)(tdata->token, tdata, size);
|
||||
}
|
||||
|
||||
/* Decrement tdata reference count. */
|
||||
pjsip_tx_data_dec_ref(tdata);
|
||||
|
||||
/* Decrement transport reference count */
|
||||
pjsip_transport_dec_ref(transport);
|
||||
}
|
||||
|
||||
|
||||
/* Send raw data */
|
||||
PJ_DEF(pj_status_t) pjsip_tpmgr_send_raw(pjsip_tpmgr *mgr,
|
||||
pjsip_transport_type_e tp_type,
|
||||
const pjsip_tpselector *sel,
|
||||
pjsip_tx_data *tdata,
|
||||
const void *raw_data,
|
||||
pj_size_t data_len,
|
||||
const pj_sockaddr_t *addr,
|
||||
int addr_len,
|
||||
void *token,
|
||||
pjsip_tp_send_callback cb)
|
||||
{
|
||||
pjsip_transport *tr;
|
||||
pj_status_t status;
|
||||
|
||||
status = pjsip_endpt_create_tdata(tr->endpt, &tdata);
|
||||
/* Acquire the transport */
|
||||
status = pjsip_tpmgr_acquire_transport(mgr, tp_type, addr, addr_len,
|
||||
sel, &tr);
|
||||
if (status != PJ_SUCCESS)
|
||||
return status;
|
||||
|
||||
/* Add reference counter. */
|
||||
pjsip_tx_data_add_ref(tdata);
|
||||
|
||||
/* Create transmit data buffer if one is not specified */
|
||||
if (tdata == NULL) {
|
||||
status = pjsip_endpt_create_tdata(tr->endpt, &tdata);
|
||||
if (status != PJ_SUCCESS) {
|
||||
pjsip_transport_dec_ref(tr);
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Add reference counter. */
|
||||
pjsip_tx_data_add_ref(tdata);
|
||||
}
|
||||
|
||||
/* Allocate buffer */
|
||||
tdata->buf.start = (char*) pj_pool_alloc(tdata->pool, data_len);
|
||||
tdata->buf.end = tdata->buf.start + data_len;
|
||||
if (tdata->buf.start == NULL ||
|
||||
(tdata->buf.end - tdata->buf.start) < (int)data_len)
|
||||
{
|
||||
/* Note: data_len may be zero, so allocate +1 */
|
||||
tdata->buf.start = (char*) pj_pool_alloc(tdata->pool, data_len+1);
|
||||
tdata->buf.end = tdata->buf.start + data_len + 1;
|
||||
}
|
||||
|
||||
/* Copy data */
|
||||
pj_memcpy(tdata->buf.start, raw_data, data_len);
|
||||
/* Copy data, if any! (application may send zero len packet) */
|
||||
if (data_len) {
|
||||
pj_memcpy(tdata->buf.start, raw_data, data_len);
|
||||
}
|
||||
tdata->buf.cur = tdata->buf.start + data_len;
|
||||
|
||||
/* Save callback data. */
|
||||
|
@ -637,13 +683,14 @@ PJ_DEF(pj_status_t) pjsip_transport_send_raw(pjsip_transport *tr,
|
|||
/* Mark as pending. */
|
||||
tdata->is_pending = 1;
|
||||
|
||||
/* Send to transoprt */
|
||||
/* Send to transport */
|
||||
status = tr->send_msg(tr, tdata, addr, addr_len,
|
||||
tdata, &transport_send_callback);
|
||||
tdata, &send_raw_callback);
|
||||
|
||||
if (status != PJ_EPENDING) {
|
||||
/* callback will not be called, so destroy tdata now. */
|
||||
pjsip_tx_data_dec_ref(tdata);
|
||||
pjsip_transport_dec_ref(tr);
|
||||
}
|
||||
|
||||
return status;
|
||||
|
|
|
@ -996,7 +996,7 @@ PJ_DEF(pj_status_t)
|
|||
pjsip_endpt_send_request_stateless(pjsip_endpoint *endpt,
|
||||
pjsip_tx_data *tdata,
|
||||
void *token,
|
||||
pjsip_endpt_callback cb)
|
||||
pjsip_send_callback cb)
|
||||
{
|
||||
pjsip_host_info dest_info;
|
||||
pjsip_send_state *stateless_data;
|
||||
|
@ -1024,6 +1024,150 @@ pjsip_endpt_send_request_stateless(pjsip_endpoint *endpt,
|
|||
return PJ_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Send raw data to a destination.
|
||||
*/
|
||||
PJ_DEF(pj_status_t) pjsip_endpt_send_raw( pjsip_endpoint *endpt,
|
||||
pjsip_transport_type_e tp_type,
|
||||
const pjsip_tpselector *sel,
|
||||
const void *raw_data,
|
||||
pj_size_t data_len,
|
||||
const pj_sockaddr_t *addr,
|
||||
int addr_len,
|
||||
void *token,
|
||||
pjsip_tp_send_callback cb)
|
||||
{
|
||||
return pjsip_tpmgr_send_raw(pjsip_endpt_get_tpmgr(endpt), tp_type, sel,
|
||||
NULL, raw_data, data_len, addr, addr_len,
|
||||
token, cb);
|
||||
}
|
||||
|
||||
|
||||
/* Callback data for sending raw data */
|
||||
struct send_raw_data
|
||||
{
|
||||
pjsip_endpoint *endpt;
|
||||
pjsip_tx_data *tdata;
|
||||
pjsip_tpselector *sel;
|
||||
void *app_token;
|
||||
pjsip_tp_send_callback app_cb;
|
||||
};
|
||||
|
||||
|
||||
/* Resolver callback for sending raw data. */
|
||||
static void send_raw_resolver_callback( pj_status_t status,
|
||||
void *token,
|
||||
const pjsip_server_addresses *addr)
|
||||
{
|
||||
struct send_raw_data *sraw_data = (struct send_raw_data*) token;
|
||||
|
||||
if (status != PJ_SUCCESS) {
|
||||
if (sraw_data->app_cb) {
|
||||
(*sraw_data->app_cb)(sraw_data->app_token, sraw_data->tdata,
|
||||
-status);
|
||||
}
|
||||
} else {
|
||||
pj_size_t data_len;
|
||||
|
||||
pj_assert(addr->count != 0);
|
||||
|
||||
data_len = sraw_data->tdata->buf.cur - sraw_data->tdata->buf.start;
|
||||
status = pjsip_tpmgr_send_raw(pjsip_endpt_get_tpmgr(sraw_data->endpt),
|
||||
addr->entry[0].type,
|
||||
sraw_data->sel, sraw_data->tdata,
|
||||
sraw_data->tdata->buf.start, data_len,
|
||||
&addr->entry[0].addr,
|
||||
addr->entry[0].addr_len,
|
||||
sraw_data->app_token,
|
||||
sraw_data->app_cb);
|
||||
if (status == PJ_SUCCESS) {
|
||||
(*sraw_data->app_cb)(sraw_data->app_token, sraw_data->tdata,
|
||||
data_len);
|
||||
} else if (status != PJ_EPENDING) {
|
||||
(*sraw_data->app_cb)(sraw_data->app_token, sraw_data->tdata,
|
||||
-status);
|
||||
}
|
||||
}
|
||||
|
||||
if (sraw_data->sel) {
|
||||
pjsip_tpselector_dec_ref(sraw_data->sel);
|
||||
}
|
||||
pjsip_tx_data_dec_ref(sraw_data->tdata);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Send raw data to the specified destination URI.
|
||||
*/
|
||||
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 = get_dest_info(uri, 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);
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Determine which address (and transport) to use to send response message
|
||||
* based on the received request. This function follows the specification
|
||||
|
@ -1215,7 +1359,7 @@ PJ_DEF(pj_status_t) pjsip_endpt_send_response( pjsip_endpoint *endpt,
|
|||
pjsip_response_addr *res_addr,
|
||||
pjsip_tx_data *tdata,
|
||||
void *token,
|
||||
pjsip_endpt_callback cb)
|
||||
pjsip_send_callback cb)
|
||||
{
|
||||
/* Determine which transports and addresses to send the response,
|
||||
* based on Section 18.2.2 of RFC 3261.
|
||||
|
@ -1264,7 +1408,7 @@ PJ_DEF(pj_status_t) pjsip_endpt_send_response2( pjsip_endpoint *endpt,
|
|||
pjsip_rx_data *rdata,
|
||||
pjsip_tx_data *tdata,
|
||||
void *token,
|
||||
pjsip_endpt_callback cb)
|
||||
pjsip_send_callback cb)
|
||||
{
|
||||
pjsip_response_addr res_addr;
|
||||
pj_status_t status;
|
||||
|
|
Loading…
Reference in a new issue