Compare commits

...

7 Commits

Author SHA1 Message Date
Andreas Eversberg a6c239117f Add option to bind TCP interfact to given interface.
Change-Id: Ied5fef684310b211696e6cac8d0972529e676abd
2024-06-20 16:04:25 +02:00
Andreas Eversberg 44032cc4af Create "Require" header only if not already exists
Application may now add "Require" header with value(s). PJSip will
only append values, if the header already exists. Otherwise PJSip will
create and add the header.

Change-Id: I87dc4e9097cab3171ba629229aa2ba5257a10301
2024-06-20 08:30:49 +02:00
Andreas Eversberg c4223013e2 PJSIP: Allow to set cnonce and nonce count by application
Change-Id: I2cd3ca45b21753e8b9a556834772b1ab6b1fa34f
2024-05-30 15:38:09 +02:00
Andreas Eversberg 7389e8413e PJSIP: Allow SIP uri scheme "tel:" in addition to "sip:" / "sips:"
Change-Id: Id157c4d6acf0c96b70021305907aa3e5185af8a7
2024-05-13 10:53:52 +02:00
Andreas Eversberg 8456b90904 PJSIP: Add functions to change TCP transport on the fly
Related: SY#6888
Change-Id: I41dbbd89187fcfc26198ad9dbe19b89b99ee9c32
2024-05-07 15:29:51 +02:00
Pau Espin ab1be367de PATCH: 0000-remove-third-party.patch 2024-04-26 17:43:38 +02:00
Pau Espin 8a766a7b04 PATCH: 0000-configure-ssl-library-path.patch 2024-04-26 17:43:01 +02:00
13 changed files with 260 additions and 124 deletions

View File

@ -9164,7 +9164,11 @@ else $as_nop
if test "x$with_ssl" != "xno" -a "x$with_ssl" != "x"; then
CFLAGS="$CFLAGS -I$with_ssl/include"
CPPFLAGS="$CPPFLAGS -I$with_ssl/include"
if test -d $with_ssl/lib; then
LDFLAGS="$LDFLAGS -L$with_ssl/lib"
else
LDFLAGS="$LDFLAGS -L$with_ssl"
fi
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: Using SSL prefix... $with_ssl" >&5
printf "%s\n" "Using SSL prefix... $with_ssl" >&6; }
fi

View File

@ -1947,7 +1947,11 @@ AC_ARG_ENABLE(ssl,
if test "x$with_ssl" != "xno" -a "x$with_ssl" != "x"; then
CFLAGS="$CFLAGS -I$with_ssl/include"
CPPFLAGS="$CPPFLAGS -I$with_ssl/include"
if test -d $with_ssl/lib; then
LDFLAGS="$LDFLAGS -L$with_ssl/lib"
else
LDFLAGS="$LDFLAGS -L$with_ssl"
fi
AC_MSG_RESULT([Using SSL prefix... $with_ssl])
fi

View File

@ -1,4 +1,3 @@
export PJDIR := @ac_pjdir@
include $(PJDIR)/version.mak
export PJ_DIR := $(PJDIR)
@ -42,21 +41,6 @@ export APP_THIRD_PARTY_EXT :=
export APP_THIRD_PARTY_LIBS :=
export APP_THIRD_PARTY_LIB_FILES :=
ifneq (@ac_no_srtp@,1)
ifneq (@ac_external_srtp@,0)
# External SRTP library
APP_THIRD_PARTY_EXT += -l@ac_external_srtp_lib@
else
APP_THIRD_PARTY_LIB_FILES += $(PJ_DIR)/third_party/lib/libsrtp-$(LIB_SUFFIX)
ifeq ($(PJ_SHARED_LIBRARIES),)
APP_THIRD_PARTY_LIBS += -lsrtp-$(TARGET_NAME)
else
APP_THIRD_PARTY_LIBS += -lsrtp
APP_THIRD_PARTY_LIB_FILES += $(PJ_DIR)/third_party/lib/libsrtp.$(SHLIB_SUFFIX).$(PJ_VERSION_MAJOR) $(PJ_DIR)/third_party/lib/libsrtp.$(SHLIB_SUFFIX)
endif
endif
endif
ifeq (@ac_pjmedia_resample@,libresample)
APP_THIRD_PARTY_LIB_FILES += $(PJ_DIR)/third_party/lib/libresample-$(LIB_SUFFIX)
ifeq ($(PJ_SHARED_LIBRARIES),)
@ -73,102 +57,6 @@ APP_THIRD_PARTY_LIB_FILES += $(PJ_DIR)/third_party/lib/libresample.$(SHLIB_SUFFI
endif
endif
ifneq (@ac_no_gsm_codec@,1)
ifeq (@ac_external_gsm@,1)
# External GSM library
APP_THIRD_PARTY_EXT += -lgsm
else
APP_THIRD_PARTY_LIB_FILES += $(PJ_DIR)/third_party/lib/libgsmcodec-$(LIB_SUFFIX)
ifeq ($(PJ_SHARED_LIBRARIES),)
APP_THIRD_PARTY_LIBS += -lgsmcodec-$(TARGET_NAME)
else
APP_THIRD_PARTY_LIBS += -lgsmcodec
APP_THIRD_PARTY_LIB_FILES += $(PJ_DIR)/third_party/lib/libgsmcodec.$(SHLIB_SUFFIX).$(PJ_VERSION_MAJOR) $(PJ_DIR)/third_party/lib/libgsmcodec.$(SHLIB_SUFFIX)
endif
endif
endif
ifneq (@ac_no_speex_codec@,1)
ifeq (@ac_external_speex@,1)
APP_THIRD_PARTY_EXT += -lspeex -lspeexdsp
else
APP_THIRD_PARTY_LIB_FILES += $(PJ_DIR)/third_party/lib/libspeex-$(LIB_SUFFIX)
ifeq ($(PJ_SHARED_LIBRARIES),)
APP_THIRD_PARTY_LIBS += -lspeex-$(TARGET_NAME)
else
APP_THIRD_PARTY_LIBS += -lspeex
APP_THIRD_PARTY_LIB_FILES += $(PJ_DIR)/third_party/lib/libspeex.$(SHLIB_SUFFIX).$(PJ_VERSION_MAJOR) $(PJ_DIR)/third_party/lib/libspeex.$(SHLIB_SUFFIX)
endif
endif
endif
ifneq (@ac_no_ilbc_codec@,1)
APP_THIRD_PARTY_LIB_FILES += $(PJ_DIR)/third_party/lib/libilbccodec-$(LIB_SUFFIX)
ifeq ($(PJ_SHARED_LIBRARIES),)
APP_THIRD_PARTY_LIBS += -lilbccodec-$(TARGET_NAME)
else
APP_THIRD_PARTY_LIBS += -lilbccodec
APP_THIRD_PARTY_LIB_FILES += $(PJ_DIR)/third_party/lib/libilbccodec.$(SHLIB_SUFFIX).$(PJ_VERSION_MAJOR) $(PJ_DIR)/third_party/lib/libilbccodec.$(SHLIB_SUFFIX)
endif
endif
ifneq (@ac_no_g7221_codec@,1)
APP_THIRD_PARTY_LIB_FILES += $(PJ_DIR)/third_party/lib/libg7221codec-$(LIB_SUFFIX)
ifeq ($(PJ_SHARED_LIBRARIES),)
APP_THIRD_PARTY_LIBS += -lg7221codec-$(TARGET_NAME)
else
APP_THIRD_PARTY_LIBS += -lg7221codec
APP_THIRD_PARTY_LIB_FILES += $(PJ_DIR)/third_party/lib/libg7221codec.$(SHLIB_SUFFIX).$(PJ_VERSION_MAJOR) $(PJ_DIR)/third_party/lib/libg7221codec.$(SHLIB_SUFFIX)
endif
endif
ifeq (@ac_external_pa@,1)
# External PA
APP_THIRD_PARTY_EXT += -lportaudio
endif
ifneq (@ac_no_yuv@,1)
ifeq (@ac_external_yuv@,1)
APP_THIRD_PARTY_EXT += -lyuv
else
APP_THIRD_PARTY_LIB_FILES += $(PJ_DIR)/third_party/lib/libyuv-$(LIB_SUFFIX)
ifeq ($(PJ_SHARED_LIBRARIES),)
APP_THIRD_PARTY_LIBS += -lyuv-$(TARGET_NAME)
else
APP_THIRD_PARTY_LIBS += -lyuv
APP_THIRD_PARTY_LIB_FILES += $(PJ_DIR)/third_party/lib/libyuv.$(SHLIB_SUFFIX).$(PJ_VERSION_MAJOR) $(PJ_DIR)/third_party/lib/libyuv.$(SHLIB_SUFFIX)
endif
endif
endif
ifneq (@ac_no_webrtc@,1)
ifeq (@ac_external_webrtc@,1)
APP_THIRD_PARTY_EXT += -lwebrtc
else
APP_THIRD_PARTY_LIB_FILES += $(PJ_DIR)/third_party/lib/libwebrtc-$(LIB_SUFFIX)
ifeq ($(PJ_SHARED_LIBRARIES),)
APP_THIRD_PARTY_LIBS += -lwebrtc-$(TARGET_NAME)
else
APP_THIRD_PARTY_LIBS += -lwebrtc
APP_THIRD_PARTY_LIB_FILES += $(PJ_DIR)/third_party/lib/libwebrtc.$(SHLIB_SUFFIX).$(PJ_VERSION_MAJOR) $(PJ_DIR)/third_party/lib/libwebrtc.$(SHLIB_SUFFIX)
endif
endif
endif
ifneq (@ac_no_webrtc_aec3@,1)
ifeq (@ac_external_webrtc_aec3@,1)
APP_THIRD_PARTY_EXT += -lwebrtc-aec3
else
APP_THIRD_PARTY_LIB_FILES += $(PJ_DIR)/third_party/lib/libwebrtc-aec3-$(LIB_SUFFIX)
ifeq ($(PJ_SHARED_LIBRARIES),)
APP_THIRD_PARTY_LIBS += -lwebrtc-aec3-$(TARGET_NAME)
else
APP_THIRD_PARTY_LIBS += -lwebrtc-aec3
APP_THIRD_PARTY_LIB_FILES += $(PJ_DIR)/third_party/lib/libwebrtc-aec3.$(SHLIB_SUFFIX).$(PJ_VERSION_MAJOR) $(PJ_DIR)/third_party/lib/libwebrtc.$(SHLIB_SUFFIX)
endif
endif
endif
# Additional flags
@ac_build_mak_vars@

View File

@ -585,6 +585,7 @@ PJ_DECL(pj_status_t) pj_activesock_start_connect(pj_activesock_t *asock,
const pj_sockaddr_t *remaddr,
int addr_len);
PJ_DEF(pj_ioqueue_t) *pj_activesock_get_ioqueue(pj_activesock_t *asock);
#endif /* PJ_HAS_TCP */

View File

@ -980,5 +980,10 @@ static void ioqueue_on_connect_complete(pj_ioqueue_key_t *key,
}
}
PJ_DEF(pj_ioqueue_t) *pj_activesock_get_ioqueue(pj_activesock_t *asock)
{
return asock->ioqueue;
}
#endif /* PJ_HAS_TCP */

View File

@ -118,6 +118,8 @@ struct pjsip_cred_info
int data_type; /**< Type of data (0 for plaintext passwd). */
pj_str_t data; /**< The data, which can be a plaintext
password or a hashed digest. */
pj_str_t cnonce; /**< Optional pre-defined cnonce value */
pj_uint32_t nc; /**< nc to be used with optional cnonce. */
/** Extended data */
union {

View File

@ -935,6 +935,12 @@ struct pjsip_transport
*/
pj_status_t (*destroy)(pjsip_transport *transport);
pj_status_t (*create_new_sock)(struct pjsip_transport *base,
pj_sockaddr *local_addr);
pj_status_t (*connect_new_sock)(struct pjsip_transport *base,
pj_sockaddr *local_addr,
pj_sockaddr *remote_addr);
/*
* Application may extend this structure..
*/

View File

@ -62,6 +62,12 @@ typedef struct pjsip_tcp_transport_cfg
*/
pj_sockaddr bind_addr;
/**
* Optional interface to bind the socket to. Default is to bind to
* any interface.
*/
const char *bind_if;
/**
* Should SO_REUSEADDR be used for the listener socket.
* Default value is PJSIP_TCP_TRANSPORT_REUSEADDR.

View File

@ -388,6 +388,13 @@ PJ_DECL(pjsip_sip_uri*) pjsip_sip_uri_create( pj_pool_t *pool,
PJ_DECL(void) pjsip_sip_uri_set_secure( pjsip_sip_uri *uri,
pj_bool_t secure );
/**
* Change the SIP URI scheme to tel.
* This would not change anything except the scheme.
* @param uri The URI
*/
PJ_DECL(void) pjsip_sip_uri_set_tel( pjsip_sip_uri *uri );
/**
* Initialize SIP URL (all fields are set to NULL or zero).
* @param url The URL.

View File

@ -810,6 +810,7 @@ PJ_DEF(pj_status_t) pjsip_100rel_tx_response(pjsip_inv_session *inv,
char rseq_str[32];
pj_str_t rseq;
tx_data_list_t *tl;
pj_bool_t req_created = PJ_FALSE;
/* Create UAS state if we don't have one */
if (dd->uas_state == NULL) {
@ -827,9 +828,15 @@ PJ_DEF(pj_status_t) pjsip_100rel_tx_response(pjsip_inv_session *inv,
PJ_EINVALIDOP);
/* Add Require header */
req_hdr = (pjsip_require_hdr*)
pjsip_msg_find_hdr(tdata->msg, PJSIP_H_REQUIRE, NULL);
if (!req_hdr) {
req_hdr = pjsip_require_hdr_create(tdata->pool);
req_hdr->count = 1;
req_hdr->values[0] = tag_100rel;
PJ_ASSERT_RETURN(req_hdr, PJ_FALSE);
req_created = PJ_TRUE;
}
req_hdr->values[req_hdr->count++] = tag_100rel;
if (req_created)
pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)req_hdr);
/* Add RSeq header */

View File

@ -702,7 +702,7 @@ static pjsip_cached_auth *find_cached_auth( pjsip_auth_clt_sess *sess,
}
/* Find credential to use for the specified realm and auth scheme. */
static const pjsip_cred_info* auth_find_cred( const pjsip_auth_clt_sess *sess,
static pjsip_cred_info* auth_find_cred( const pjsip_auth_clt_sess *sess,
const pj_str_t *realm,
const pj_str_t *auth_scheme)
{
@ -789,6 +789,8 @@ PJ_DEF(pj_status_t) pjsip_auth_clt_clone( pj_pool_t *pool,
&rhs->cred_info[i].username);
sess->cred_info[i].data_type = rhs->cred_info[i].data_type;
pj_strdup(pool, &sess->cred_info[i].data, &rhs->cred_info[i].data);
pj_strdup(pool, &sess->cred_info[i].cnonce, &rhs->cred_info[i].cnonce);
sess->cred_info[i].nc = rhs->cred_info[i].nc;
}
/* TODO note:
@ -860,6 +862,8 @@ PJ_DEF(pj_status_t) pjsip_auth_clt_set_credentials( pjsip_auth_clt_sess *sess,
pj_strdup(sess->pool, &sess->cred_info[i].realm, &c[i].realm);
pj_strdup(sess->pool, &sess->cred_info[i].username, &c[i].username);
pj_strdup(sess->pool, &sess->cred_info[i].data, &c[i].data);
pj_strdup(sess->pool, &sess->cred_info[i].cnonce, &c[i].cnonce);
sess->cred_info[i].nc = c[i].nc;
}
sess->cred_cnt = cred_cnt;
}
@ -905,7 +909,7 @@ PJ_DEF(pj_status_t) pjsip_auth_clt_get_prefs(pjsip_auth_clt_sess *sess,
static pj_status_t auth_respond( pj_pool_t *req_pool,
const pjsip_www_authenticate_hdr *hdr,
const pjsip_uri *uri,
const pjsip_cred_info *cred_info,
pjsip_cred_info *cred_info,
const pjsip_method *method,
pj_pool_t *sess_pool,
pjsip_cached_auth *cached_auth,
@ -953,9 +957,14 @@ static pj_status_t auth_respond( pj_pool_t *req_pool,
pj_str_t *cnonce = NULL;
pj_uint32_t nc = 1;
/* Cnonce and nc may be given by application. */
if (cred_info->cnonce.slen) {
cnonce = &cred_info->cnonce;
nc = cred_info->nc;
}
/* Update the session (nonce-count etc) if required. */
# if PJSIP_AUTH_QOP_SUPPORT
{
else {
if (cached_auth) {
update_digest_session( cached_auth, hdr );
@ -1272,7 +1281,7 @@ static pj_status_t process_auth( pj_pool_t *req_pool,
pjsip_cached_auth *cached_auth,
pjsip_authorization_hdr **h_auth)
{
const pjsip_cred_info *cred;
pjsip_cred_info *cred;
pjsip_authorization_hdr *sent_auth = NULL;
pjsip_hdr *hdr;
pj_status_t status;

View File

@ -57,6 +57,7 @@ struct tcp_listener
pjsip_tpmgr *tpmgr;
pj_activesock_t *asock;
pj_sockaddr bound_addr;
const char *bind_if;
pj_qos_type qos_type;
pj_qos_params qos_params;
pj_sockopt_params sockopt_params;
@ -105,6 +106,7 @@ struct tcp_transport
pj_sock_t sock;
pj_activesock_t *asock;
pj_bool_t has_pending_connect;
pj_sock_t new_sock;
/* Keep-alive timer. */
pj_timer_entry ka_timer;
@ -403,6 +405,7 @@ PJ_DEF(pj_status_t) pjsip_tcp_transport_start3(
sizeof(cfg->qos_params));
pj_memcpy(&listener->sockopt_params, &cfg->sockopt_params,
sizeof(cfg->sockopt_params));
listener->bind_if = cfg->bind_if;
pj_ansi_strxcpy(listener->factory.obj_name, "tcptp",
sizeof(listener->factory.obj_name));
@ -607,6 +610,13 @@ static void tcp_keep_alive_timer(pj_timer_heap_t *th, pj_timer_entry *e);
/* Clean up TCP resources */
static void tcp_on_destroy(void *arg);
/* Change transport addresses */
static pj_status_t tcp_create_new_sock(struct pjsip_transport *base,
pj_sockaddr *local_addr);
static pj_status_t tcp_connect_new_sock(struct pjsip_transport *base,
pj_sockaddr *local_addr,
pj_sockaddr *remote_addr);
/*
* Common function to create TCP transport, called when pending accept() and
* pending connect() complete.
@ -642,6 +652,7 @@ static pj_status_t tcp_create( struct tcp_listener *listener,
tcp = PJ_POOL_ZALLOC_T(pool, struct tcp_transport);
tcp->is_server = is_server;
tcp->sock = sock;
tcp->new_sock = PJ_INVALID_SOCKET;
/*tcp->listener = listener;*/
pj_list_init(&tcp->delayed_list);
tcp->base.pool = pool;
@ -685,6 +696,9 @@ static pj_status_t tcp_create( struct tcp_listener *listener,
tcp->base.destroy = &tcp_destroy_transport;
tcp->base.factory = &listener->factory;
tcp->base.initial_timeout = listener->initial_timeout;
tcp->base.create_new_sock = tcp_create_new_sock;
tcp->base.connect_new_sock = tcp_connect_new_sock;
/* Create group lock */
status = pj_grp_lock_create_w_handler(pool, NULL, tcp, &tcp_on_destroy,
@ -859,6 +873,10 @@ static pj_status_t tcp_destroy(pjsip_transport *transport,
tcp->sock = PJ_INVALID_SOCKET;
}
if (tcp->new_sock != PJ_INVALID_SOCKET)
pj_sock_close(tcp->new_sock);
if (tcp->grp_lock) {
pj_grp_lock_t *grp_lock = tcp->grp_lock;
tcp->grp_lock = NULL;
@ -1021,6 +1039,18 @@ static pj_status_t lis_create_transport(pjsip_tpfactory *factory,
pj_sockaddr_cp(&local_addr, &listener->bound_addr);
pj_sockaddr_set_port(&local_addr, 0);
/* Bind to listener's interface, if set. */
if (listener->bind_if && listener->bind_if[0]) {
struct ifreq ifr;
memset(&ifr, 0, sizeof(ifr));
snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), listener->bind_if);
status = setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, (void *)&ifr, sizeof(ifr));
if (status < 0) {
PJ_PERROR(4, (listener->factory.obj_name, status,
"Warning: cannot bind to interface %s", listener->bind_if));
}
}
status = pj_sock_bind(sock, &local_addr,
pj_sockaddr_get_len(&local_addr));
if (status != PJ_SUCCESS) {
@ -1766,5 +1796,148 @@ PJ_DEF(pj_status_t) pjsip_tcp_transport_restart(pjsip_tpfactory *factory,
return status;
}
static pj_status_t tcp_create_new_sock(struct pjsip_transport *base,
pj_sockaddr *local_addr)
{
struct tcp_transport *tcp = (struct tcp_transport*) base;
struct tcp_listener *listener = (struct tcp_listener *)base->factory;
int af = pjsip_transport_type_get_af(listener->factory.type);
pj_sock_t new_sock;
pj_status_t status;
pj_sockaddr addr;
/* Close old socket */
if (tcp->new_sock != PJ_INVALID_SOCKET) {
pj_sock_close(tcp->new_sock);
tcp->new_sock = PJ_INVALID_SOCKET;
}
/* Create new socket */
status = pj_sock_socket(af,
pj_SOCK_STREAM() | pj_SOCK_CLOEXEC(),
0, &new_sock);
if (status != PJ_SUCCESS)
return status;
if (!local_addr) {
local_addr = &addr;
pj_bzero(&addr, sizeof(*local_addr));
pj_sockaddr_cp(&addr, &listener->bound_addr);
pj_sockaddr_set_port(&addr, 0);
}
/* Apply QoS, if specified */
status = pj_sock_apply_qos2(new_sock, listener->qos_type,
&listener->qos_params,
2, listener->factory.obj_name,
"outgoing SIP TCP socket");
/* Apply socket options, if specified */
if (listener->sockopt_params.cnt) {
status = pj_sock_setsockopt_params(new_sock, &listener->sockopt_params);
if (status != PJ_SUCCESS) {
PJ_PERROR(4, (listener->factory.obj_name, status,
"Warning: error applying socket options"));
}
}
if (1) {
int enabled = 1;
status = pj_sock_setsockopt(new_sock, pj_SOL_SOCKET(), pj_SO_REUSEADDR(),
&enabled, sizeof(enabled));
if (status != PJ_SUCCESS) {
PJ_PERROR(4, (listener->factory.obj_name, status,
"Warning: error applying SO_REUSEADDR"));
}
}
/* Bind to listener's interface, if set. */
if (listener->bind_if && listener->bind_if[0]) {
struct ifreq ifr;
memset(&ifr, 0, sizeof(ifr));
snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), listener->bind_if);
status = setsockopt(new_sock, SOL_SOCKET, SO_BINDTODEVICE, (void *)&ifr, sizeof(ifr));
if (status < 0) {
PJ_PERROR(4, (listener->factory.obj_name, status,
"Warning: cannot bind to interface %s", listener->bind_if));
}
}
/* Bind new socket */
status = pj_sock_bind(new_sock, local_addr,
pj_sockaddr_get_len(local_addr));
if (status != PJ_SUCCESS) {
pj_sock_close(new_sock);
return status;
}
/* Store and return */
tcp->new_sock = new_sock;
return PJ_SUCCESS;
}
/* Change transport addresses */
static pj_status_t tcp_connect_new_sock(struct pjsip_transport *base,
pj_sockaddr *local_addr,
pj_sockaddr *remote_addr)
{
struct tcp_transport *tcp = (struct tcp_transport*) base;
pj_activesock_t *asock = tcp->asock;
pj_activesock_t *new_asock;
pj_activesock_cfg asock_cfg;
pj_activesock_cb tcp_callback;
pj_status_t status;
int addr_len;
PJ_ASSERT_RETURN(tcp->new_sock != PJ_INVALID_SOCKET, PJ_EINVAL);
/* Get the local addess */
addr_len = sizeof(*local_addr);
status = pj_sock_getsockname(tcp->new_sock, &local_addr, &addr_len);
if (status != PJ_SUCCESS) {
pj_activesock_close(new_asock);
return status;
}
/* Create active socket */
pj_activesock_cfg_default(&asock_cfg);
asock_cfg.async_cnt = 1;
asock_cfg.grp_lock = tcp->grp_lock;
pj_bzero(&tcp_callback, sizeof(tcp_callback));
tcp_callback.on_data_read = &on_data_read;
tcp_callback.on_data_sent = &on_data_sent;
tcp_callback.on_connect_complete = &on_connect_complete;
status = pj_activesock_create(tcp->base.pool, tcp->new_sock, pj_SOCK_STREAM(), &asock_cfg,
pj_activesock_get_ioqueue(asock), &tcp_callback, tcp, &new_asock);
if (status != PJ_SUCCESS) {
pj_sock_close(tcp->new_sock);
tcp->new_sock = PJ_INVALID_SOCKET;
return status;
}
/* Start asynchronous connect() operation */
status = pj_activesock_start_connect(new_asock, tcp->base.pool, remote_addr, pj_sockaddr_get_len(remote_addr));
if (status != PJ_SUCCESS && status != PJ_EPENDING) {
pj_activesock_close(new_asock);
return status;
}
/* Close old socket and assign the new one. */
pj_activesock_close(tcp->asock);
tcp->sock = tcp->new_sock;
tcp->new_sock = PJ_INVALID_SOCKET;
tcp->asock = new_asock;
/* Check if socket is already connected. */
tcp->has_pending_connect = PJ_TRUE;
if (status == PJ_SUCCESS) {
on_connect_complete(tcp->asock, PJ_SUCCESS);
}
return PJ_SUCCESS;
}
#endif /* PJ_HAS_TCP */

View File

@ -144,12 +144,14 @@ PJ_DEF(pj_ssize_t) pjsip_param_print_on( const pjsip_param *param_list,
static const pj_str_t *pjsip_url_get_scheme( const pjsip_sip_uri* );
static const pj_str_t *pjsips_url_get_scheme( const pjsip_sip_uri* );
static const pj_str_t *pjtel_url_get_scheme( const pjsip_sip_uri* );
static const pj_str_t *pjsip_name_addr_get_scheme( const pjsip_name_addr * );
static void *pjsip_get_uri( pjsip_uri *uri );
static void *pjsip_name_addr_get_uri( pjsip_name_addr *name );
static pj_str_t sip_str = { "sip", 3 };
static pj_str_t sips_str = { "sips", 4 };
static pj_str_t tel_str = { "tel", 3 };
static pjsip_name_addr* pjsip_name_addr_clone( pj_pool_t *pool,
const pjsip_name_addr *rhs);
@ -195,6 +197,15 @@ static pjsip_uri_vptr sips_url_vptr =
(P_CLONE) &pjsip_url_clone
};
static pjsip_uri_vptr tel_url_vptr =
{
(P_GET_SCHEME) &pjtel_url_get_scheme,
(P_GET_URI) &pjsip_get_uri,
(P_PRINT_URI) &pjsip_url_print,
(P_CMP_URI) &pjsip_url_compare,
(P_CLONE) &pjsip_url_clone
};
static pjsip_uri_vptr name_addr_vptr =
{
(P_GET_SCHEME) &pjsip_name_addr_get_scheme,
@ -216,6 +227,12 @@ static const pj_str_t *pjsips_url_get_scheme(const pjsip_sip_uri *url)
return &sips_str;
}
static const pj_str_t *pjtel_url_get_scheme(const pjsip_sip_uri *url)
{
PJ_UNUSED_ARG(url);
return &tel_str;
}
static void *pjsip_get_uri( pjsip_uri *uri )
{
return uri;
@ -232,6 +249,11 @@ PJ_DEF(void) pjsip_sip_uri_set_secure( pjsip_sip_uri *url,
url->vptr = secure ? &sips_url_vptr : &sip_url_vptr;
}
PJ_DEF(void) pjsip_sip_uri_set_tel( pjsip_sip_uri *url )
{
url->vptr = &tel_url_vptr;
}
PJ_DEF(void) pjsip_sip_uri_init(pjsip_sip_uri *url, pj_bool_t secure)
{
pj_bzero(url, sizeof(*url));
@ -527,6 +549,8 @@ static pjsip_sip_uri* pjsip_url_clone(pj_pool_t *pool, const pjsip_sip_uri *rhs)
return NULL;
pjsip_sip_uri_init(url, IS_SIPS(rhs));
if (PJSIP_URI_SCHEME_IS_TEL(rhs))
pjsip_sip_uri_set_tel(url);
pjsip_sip_uri_assign(pool, url, rhs);
return url;
}