Changed transaction to refrect new transport changes

git-svn-id: https://svn.pjsip.org/repos/pjproject/trunk@58 74dad513-b988-da41-8d7b-12977e46ad98
This commit is contained in:
Benny Prijono 2005-11-19 20:28:08 +00:00
parent 4d1a54e7b5
commit 14f51a5656
11 changed files with 159 additions and 39 deletions

View File

@ -47,6 +47,12 @@ Package=<5>
Package=<4>
{{{
Begin Project Dependency
Project_Dep_Name pjlib
End Project Dependency
Begin Project Dependency
Project_Dep_Name pjlib_util
End Project Dependency
}}}
###############################################################################

View File

@ -207,6 +207,10 @@ SOURCE=..\include\pjsip\sip_transport.h
# End Source File
# Begin Source File
SOURCE=..\include\pjsip\sip_transport_udp.h
# End Source File
# Begin Source File
SOURCE=..\include\pjsip\sip_types.h
# End Source File
# Begin Source File

View File

@ -332,7 +332,7 @@ struct pjsip_tx_data
/** Transport manager internal. */
void *token;
void (*cb)(void*, pjsip_tx_data*, pj_status_t);
void (*cb)(void*, pjsip_tx_data*, pj_ssize_t);
};

View File

@ -0,0 +1,68 @@
/* $Id: $ */
/*
* Copyright (C) 2003-2006 Benny Prijono <benny@prijono.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __PJSIP_TRANSPORT_UDP_H__
#define __PJSIP_TRANSPORT_UDP_H__
#include <pjsip/sip_transport.h>
PJ_DECL
/**
* Start UDP transport.
*
* @param endpt The SIP endpoint.
* @param local Local address to bind.
* @param pub_addr Public address to advertise.
* @param async_cnt Number of simultaneous async operations.
* @param p_transport Pointer to receive the transport.
*
* @return PJ_SUCCESS when the transport has been successfully
* started and registered to transport manager, or
* the appropriate error code.
*/
PJ_DECL(pj_status_t) pjsip_udp_transport_start(pjsip_endpoint *endpt,
const pj_sockaddr_in *local,
const pj_sockaddr_in *pub_addr,
unsigned async_cnt,
pjsip_transport **p_transport);
/**
* Attach UDP socket as a new transport and start the transport.
*
* @param endpt The SIP endpoint.
* @param sock UDP socket to use.
* @param pub_addr Public address to advertise.
* @param async_cnt Number of simultaneous async operations.
* @param p_transport Pointer to receive the transport.
*
* @return PJ_SUCCESS when the transport has been successfully
* started and registered to transport manager, or
* the appropriate error code.
*/
PJ_DECL(pj_status_t) pjsip_udp_transport_attach(pjsip_endpoint *endpt,
pj_sock_t sock,
const pj_sockaddr_in *pub_addr,
unsigned async_cnt,
pjsip_transport **p_transport);
PJ_END_DECL
#endif /* __PJSIP_TRANSPORT_UDP_H__ */

View File

@ -717,6 +717,7 @@ static void tsx_resolver_callback(pj_status_t status,
{
pjsip_transaction *tsx = token;
struct tsx_lock_data lck;
pjsip_transport *tp;
PJ_LOG(4, (tsx->obj_name, "resolver job complete, status=%d", status));
@ -741,10 +742,10 @@ static void tsx_resolver_callback(pj_status_t status,
pj_ntohs(addr->entry[0].addr.sin_port)));
tsx->transport_state = PJSIP_TSX_TRANSPORT_STATE_CONNECTING;
pjsip_endpt_get_transport(tsx->endpt, tsx->pool,
addr->entry[0].type, &addr->entry[0].addr,
tsx,
&tsx_transport_callback);
status = pjsip_endpt_alloc_transport( tsx->endpt, addr->entry[0].type,
&addr->entry[0].addr,
&tp);
tsx_transport_callback(tp, tsx, status);
/* Unlock transaction */
unlock_tsx(tsx, &lck);
@ -940,8 +941,7 @@ PJ_DEF(pj_status_t) pjsip_tsx_init_uas( pjsip_transaction *tsx,
tsx->current_addr = 0;
tsx->remote_addr.count = 1;
tsx->remote_addr.entry[0].type =
pjsip_transport_get_type(tsx->transport);
tsx->remote_addr.entry[0].type = tsx->transport->type;
pj_memcpy(&tsx->remote_addr.entry[0].addr,
&rdata->pkt_info.addr, rdata->pkt_info.addr_len);
@ -1180,6 +1180,20 @@ PJ_DEF(void) pjsip_tsx_terminate( pjsip_transaction *tsx, int code )
unlock_tsx(tsx, &lck);
}
/*
* Transport send completion callback.
*/
static void tsx_on_send_complete(void *token, pjsip_tx_data *tdata,
pj_ssize_t bytes_sent)
{
PJ_UNUSED_ARG(token);
PJ_UNUSED_ARG(tdata);
if (bytes_sent <= 0) {
PJ_TODO(HANDLE_TRANSPORT_ERROR);
}
}
/*
* Send message to the transport.
* If transport is not yet available, then do nothing. The message will be
@ -1193,7 +1207,6 @@ static pj_status_t tsx_send_msg( pjsip_transaction *tsx,
PJ_LOG(5,(tsx->obj_name, "sending msg (tdata=%p)", tdata));
if (tsx->transport_state == PJSIP_TSX_TRANSPORT_STATE_FINAL) {
pj_ssize_t sent;
pjsip_event before_tx_event;
pj_assert(tsx->transport != NULL);
@ -1227,11 +1240,11 @@ static pj_status_t tsx_send_msg( pjsip_transaction *tsx,
pjsip_endpt_send_tsx_event( tsx->endpt, &before_tx_event );
tsx->has_unsent_msg = 0;
status = pjsip_transport_send_msg(
tsx->transport, tdata,
&tsx->remote_addr.entry[tsx->current_addr].addr,
&sent);
if (status != PJ_SUCCESS) {
status = pjsip_transport_send(tsx->transport, tdata,
&tsx->remote_addr.entry[tsx->current_addr].addr,
tsx, &tsx_on_send_complete);
if (status != PJ_SUCCESS && status != PJ_EPENDING) {
PJ_TODO(HANDLE_TRANSPORT_ERROR);
goto on_error;
}
} else {

View File

@ -172,7 +172,7 @@ PJ_DEF(pj_status_t) pjsip_tx_data_create( pjsip_tpmgr *mgr,
return status;
}
pj_ioqueue_op_key_init(&tdata->op_key, sizeof(tdata->op_key));
pj_ioqueue_op_key_init(&tdata->op_key.key, sizeof(tdata->op_key));
*p_tdata = tdata;
return PJ_SUCCESS;
@ -244,7 +244,7 @@ typedef struct transport_key
static void transport_send_callback(pjsip_transport *transport,
void *token,
pj_status_t status)
pj_ssize_t size)
{
pjsip_tx_data *tdata = token;
@ -257,7 +257,7 @@ static void transport_send_callback(pjsip_transport *transport,
/* Call callback, if any. */
if (tdata->cb) {
(*tdata->cb)(tdata->token, tdata, status);
(*tdata->cb)(tdata->token, tdata, size);
}
/* Decrement reference count. */
@ -273,7 +273,7 @@ PJ_DEF(pj_status_t) pjsip_transport_send( pjsip_transport *tr,
void *token,
void (*cb)(void *token,
pjsip_tx_data *tdata,
pj_status_t))
pj_ssize_t))
{
pj_status_t status;
@ -317,10 +317,8 @@ PJ_DEF(pj_status_t) pjsip_transport_send( pjsip_transport *tr,
tdata->is_pending = 1;
/* Send to transport. */
status = (*tr->send_msg)(tr, tdata->buf.start,
tdata->buf.cur - tdata->buf.start,
&tdata->op_key,
addr, tdata, &transport_send_callback);
status = (*tr->send_msg)(tr, tdata, addr, (void*)tdata,
&transport_send_callback);
if (status != PJ_EPENDING) {
tdata->is_pending = 0;

View File

@ -109,6 +109,7 @@ static void on_read_complete( pj_ioqueue_key_t *key,
/* Read next packet. */
bytes_read = sizeof(rdata->pkt_info.packet);
rdata->pkt_info.addr_len = sizeof(rdata->pkt_info.addr);
status = pj_ioqueue_recvfrom(key, op_key,
rdata->pkt_info.packet,
&bytes_read, flags,
@ -160,6 +161,8 @@ static void on_write_complete( pj_ioqueue_key_t *key,
struct udp_transport *tp = pj_ioqueue_get_user_data(key);
pjsip_tx_data_op_key *tdata_op_key = (pjsip_tx_data_op_key*)op_key;
tdata_op_key->tdata = NULL;
if (tdata_op_key->callback) {
tdata_op_key->callback(&tp->base, tdata_op_key->token, bytes_sent);
}
@ -183,7 +186,8 @@ static pj_status_t transport_send_msg( pjsip_transport *transport,
pj_ssize_t size;
PJ_ASSERT_RETURN(transport && tdata, PJ_EINVAL);
PJ_ASSERT_RETURN(tdata->op_key.tdata == NULL, PJSIP_EPENDINGTX);
/* Init op key. */
tdata->op_key.tdata = tdata;
tdata->op_key.token = token;
@ -239,21 +243,22 @@ static pj_status_t transport_destroy( pjsip_transport *transport )
/*
* pjsip_udp_transport_start()
* pjsip_udp_transport_attach()
*
* Start an UDP transport/listener.
* Attach UDP socket and start transport.
*/
PJ_DEF(pj_status_t) pjsip_udp_transport_start( pjsip_endpoint *endpt,
const pj_sockaddr_in *local,
const pj_sockaddr_in *pub_addr,
unsigned async_cnt,
pjsip_transport **p_transport)
PJ_DEF(pj_status_t) pjsip_udp_transport_attach( pjsip_endpoint *endpt,
pj_sock_t sock,
const pj_sockaddr_in *pub_addr,
unsigned async_cnt,
pjsip_transport **p_transport)
{
pj_pool_t *pool;
struct udp_transport *tp;
pj_ioqueue_t *ioqueue;
pj_ioqueue_callback ioqueue_cb;
unsigned i;
int addrlen;
pj_status_t status;
/* Create pool. */
@ -272,7 +277,12 @@ PJ_DEF(pj_status_t) pjsip_udp_transport_start( pjsip_endpoint *endpt,
tp->base.flag = pjsip_transport_get_flag_from_type(PJSIP_TRANSPORT_UDP);
/* Init addresses. */
pj_memcpy(&tp->base.local_addr, local, sizeof(pj_sockaddr_in));
addrlen = sizeof(tp->base.local_addr);
status = pj_sock_getsockname(sock, &tp->base.local_addr, &addrlen);
if (status != PJ_SUCCESS) {
pjsip_endpt_destroy_pool(endpt, pool);
return status;
}
pj_memcpy(&tp->base.public_addr, pub_addr, sizeof(pj_sockaddr_in));
tp->base.rem_addr.sin_family = PJ_AF_INET;
@ -286,15 +296,8 @@ PJ_DEF(pj_status_t) pjsip_udp_transport_start( pjsip_endpoint *endpt,
if (status != PJ_SUCCESS)
goto on_error;
/* Create socket. */
status = pj_sock_socket(PJ_AF_INET, PJ_SOCK_DGRAM, 0, &tp->sock);
if (status != PJ_SUCCESS)
goto on_error;
/* Bind socket. */
status = pj_sock_bind(tp->sock, local, sizeof(pj_sockaddr_in));
if (status != PJ_SUCCESS)
goto on_error;
/* Attach socket. */
tp->sock = sock;
/* Register to ioqueue. */
ioqueue = pjsip_endpt_get_ioqueue(endpt);
@ -376,4 +379,32 @@ on_error:
return status;
}
/*
* pjsip_udp_transport_start()
*
* Start an UDP transport/listener.
*/
PJ_DEF(pj_status_t) pjsip_udp_transport_start( pjsip_endpoint *endpt,
const pj_sockaddr_in *local,
const pj_sockaddr_in *pub_addr,
unsigned async_cnt,
pjsip_transport **p_transport)
{
pj_sock_t sock;
pj_status_t status;
status = pj_sock_socket(PJ_AF_INET, PJ_SOCK_DGRAM, 0, &sock);
if (status != PJ_SUCCESS)
return status;
status = pj_sock_bind(sock, local, sizeof(*local));
if (status != PJ_SUCCESS) {
pj_sock_close(sock);
return status;
}
return pjsip_udp_transport_attach( endpt, sock, pub_addr, async_cnt,
p_transport );
}