diff options
author | Benny Prijono <bennylp@teluu.com> | 2007-06-23 07:26:54 +0000 |
---|---|---|
committer | Benny Prijono <bennylp@teluu.com> | 2007-06-23 07:26:54 +0000 |
commit | dd49a84c46ef7ea0cb755bfa8e78e6395f544c4e (patch) | |
tree | abece2181d854eb6f19ad6a1b7bee7fb0849c7a7 /pjsip/src | |
parent | de1e9a2df94e4a20bbf41f5edd241bfbdacd9b7f (diff) |
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: http://svn.pjsip.org/repos/pjproject/trunk@1388 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjsip/src')
-rw-r--r-- | pjsip/src/pjsip/sip_transport.c | 83 | ||||
-rw-r--r-- | pjsip/src/pjsip/sip_util.c | 150 |
2 files changed, 212 insertions, 21 deletions
diff --git a/pjsip/src/pjsip/sip_transport.c b/pjsip/src/pjsip/sip_transport.c index 331bc5f7..2305b53f 100644 --- a/pjsip/src/pjsip/sip_transport.c +++ b/pjsip/src/pjsip/sip_transport.c @@ -603,31 +603,77 @@ PJ_DEF(pj_status_t) pjsip_transport_send( pjsip_transport *tr, } +/* send_raw() callback */ +static void send_raw_callback(pjsip_transport *transport, + void *token, + pj_ssize_t size) +{ + 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_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_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_tx_data *tdata; + 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; diff --git a/pjsip/src/pjsip/sip_util.c b/pjsip/src/pjsip/sip_util.c index 4aad8c2a..6b74d0c5 100644 --- a/pjsip/src/pjsip/sip_util.c +++ b/pjsip/src/pjsip/sip_util.c @@ -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; |