From 6e7c99b00209bbdb5403cec88f6b7ad01e25526c Mon Sep 17 00:00:00 2001 From: Benny Prijono Date: Tue, 28 Sep 2010 07:43:18 +0000 Subject: Closed #1139 (Support for tel: URI in PJSUA-LIB): - added new PJSUA API: pjsua_verify_url() which can be used for tel: URI - modified and tested according to spec - added new PJSIP error code, PJSIP_ENOROUTESET, to indicate that route set is needed to send to tel: URI - added couple of unit tests (we can't cover the whole tel: URI scenario yet) git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@3323 74dad513-b988-da41-8d7b-12977e46ad98 --- pjsip-apps/src/pjsua/pjsua_app.c | 12 ++++---- pjsip-apps/src/samples/simple_pjsua.c | 2 +- pjsip-apps/src/symbian_ua/ua.cpp | 2 +- pjsip-apps/src/symbian_ua_gui/src/symbian_ua.cpp | 2 +- pjsip/include/pjsip/sip_errno.h | 5 ++++ pjsip/include/pjsua-lib/pjsua.h | 18 ++++++++++- pjsip/src/pjsip/sip_errno.c | 1 + pjsip/src/pjsip/sip_util.c | 5 +++- pjsip/src/pjsua-lib/pjsua_acc.c | 35 +++++++++++----------- pjsip/src/pjsua-lib/pjsua_core.c | 29 ++++++++++++++++-- tests/pjsua/scripts-call/400_tel_uri.py | 12 ++++++++ .../235_reg_good_tel_uri_enocredential.py | 15 ++++++++++ 12 files changed, 107 insertions(+), 31 deletions(-) create mode 100644 tests/pjsua/scripts-call/400_tel_uri.py create mode 100644 tests/pjsua/scripts-recvfrom/235_reg_good_tel_uri_enocredential.py diff --git a/pjsip-apps/src/pjsua/pjsua_app.c b/pjsip-apps/src/pjsua/pjsua_app.c index 1fbea781..ead85940 100644 --- a/pjsip-apps/src/pjsua/pjsua_app.c +++ b/pjsip-apps/src/pjsua/pjsua_app.c @@ -919,7 +919,7 @@ static pj_status_t parse_args(int argc, char *argv[], break; case OPT_ID: /* id */ - if (pjsua_verify_sip_url(pj_optarg) != 0) { + if (pjsua_verify_url(pj_optarg) != 0) { PJ_LOG(1,(THIS_FILE, "Error: invalid SIP URL '%s' " "in local id argument", pj_optarg)); @@ -1037,7 +1037,7 @@ static pj_status_t parse_args(int argc, char *argv[], break; case OPT_ADD_BUDDY: /* Add to buddy list. */ - if (pjsua_verify_sip_url(pj_optarg) != 0) { + if (pjsua_verify_url(pj_optarg) != 0) { PJ_LOG(1,(THIS_FILE, "Error: invalid URL '%s' in " "--add-buddy option", pj_optarg)); @@ -1421,7 +1421,7 @@ static pj_status_t parse_args(int argc, char *argv[], if (pj_optind != argc) { pj_str_t uri_arg; - if (pjsua_verify_sip_url(argv[pj_optind]) != PJ_SUCCESS) { + if (pjsua_verify_url(argv[pj_optind]) != PJ_SUCCESS) { PJ_LOG(1,(THIS_FILE, "Invalid SIP URI %s", argv[pj_optind])); return -1; } @@ -3276,7 +3276,7 @@ static void ui_input_url(const char *title, char *buf, int len, } else { pj_status_t status; - if ((status=pjsua_verify_sip_url(buf)) != PJ_SUCCESS) { + if ((status=pjsua_verify_url(buf)) != PJ_SUCCESS) { pjsua_perror(THIS_FILE, "Invalid URL", status); return; } @@ -3811,8 +3811,8 @@ void console_app_main(const pj_str_t *uri_to_call) if (!simple_input("Enter buddy's URI:", buf, sizeof(buf))) break; - if (pjsua_verify_sip_url(buf) != PJ_SUCCESS) { - printf("Invalid SIP URI '%s'\n", buf); + if (pjsua_verify_url(buf) != PJ_SUCCESS) { + printf("Invalid URI '%s'\n", buf); break; } diff --git a/pjsip-apps/src/samples/simple_pjsua.c b/pjsip-apps/src/samples/simple_pjsua.c index ab2d0174..b9580476 100644 --- a/pjsip-apps/src/samples/simple_pjsua.c +++ b/pjsip-apps/src/samples/simple_pjsua.c @@ -117,7 +117,7 @@ int main(int argc, char *argv[]) /* If argument is specified, it's got to be a valid SIP URL */ if (argc > 1) { - status = pjsua_verify_sip_url(argv[1]); + status = pjsua_verify_url(argv[1]); if (status != PJ_SUCCESS) error_exit("Invalid URL in argv", status); } diff --git a/pjsip-apps/src/symbian_ua/ua.cpp b/pjsip-apps/src/symbian_ua/ua.cpp index f38d2e64..a59b95a9 100644 --- a/pjsip-apps/src/symbian_ua/ua.cpp +++ b/pjsip-apps/src/symbian_ua/ua.cpp @@ -733,7 +733,7 @@ static void HandleMainMenu(TKeyCode kc) { break; } - if (pjsua_verify_sip_url(SIP_DST_URI) == PJ_SUCCESS) { + if (pjsua_verify_url(SIP_DST_URI) == PJ_SUCCESS) { pj_str_t dst = pj_str(SIP_DST_URI); pjsua_call_make_call(g_acc_id, &dst, 0, NULL, NULL, &g_call_id); diff --git a/pjsip-apps/src/symbian_ua_gui/src/symbian_ua.cpp b/pjsip-apps/src/symbian_ua_gui/src/symbian_ua.cpp index bf3f7a36..b384c20e 100644 --- a/pjsip-apps/src/symbian_ua_gui/src/symbian_ua.cpp +++ b/pjsip-apps/src/symbian_ua_gui/src/symbian_ua.cpp @@ -482,7 +482,7 @@ int symbian_ua_set_account(const char *domain, const char *username, int symbian_ua_makecall(const char* dest_url) { - if (pjsua_verify_sip_url(dest_url) == PJ_SUCCESS) { + if (pjsua_verify_url(dest_url) == PJ_SUCCESS) { pj_str_t dst = pj_str((char*)dest_url); pjsua_call_make_call(g_acc_id, &dst, 0, NULL, NULL, &g_call_id); diff --git a/pjsip/include/pjsip/sip_errno.h b/pjsip/include/pjsip/sip_errno.h index 15f842a9..8e075f28 100644 --- a/pjsip/include/pjsip/sip_errno.h +++ b/pjsip/include/pjsip/sip_errno.h @@ -96,6 +96,11 @@ PJ_BEGIN_DECL * SIP object is not initialized. */ #define PJSIP_ENOTINITIALIZED (PJSIP_ERRNO_START_PJSIP + 4) /* 171004 */ +/** + * @hideinitializer + * Missing route set (for tel: URI) + */ +#define PJSIP_ENOROUTESET (PJSIP_ERRNO_START_PJSIP + 5) /* 171005 */ /************************************************************ diff --git a/pjsip/include/pjsua-lib/pjsua.h b/pjsip/include/pjsua-lib/pjsua.h index 3aa03b93..10e1b0fe 100644 --- a/pjsip/include/pjsua-lib/pjsua.h +++ b/pjsip/include/pjsua-lib/pjsua.h @@ -1540,15 +1540,31 @@ PJ_DECL(pj_status_t) pjsua_cancel_stun_resolution(void *token, /** * This is a utility function to verify that valid SIP url is given. If the - * URL is valid, PJ_SUCCESS will be returned. + * URL is a valid SIP/SIPS scheme, PJ_SUCCESS will be returned. * * @param url The URL, as NULL terminated string. * * @return PJ_SUCCESS on success, or the appropriate error code. + * + * @see pjsua_verify_url() */ PJ_DECL(pj_status_t) pjsua_verify_sip_url(const char *url); +/** + * This is a utility function to verify that valid URI is given. Unlike + * pjsua_verify_sip_url(), this function will return PJ_SUCCESS if tel: URI + * is given. + * + * @param url The URL, as NULL terminated string. + * + * @return PJ_SUCCESS on success, or the appropriate error code. + * + * @see pjsua_verify_sip_url() + */ +PJ_DECL(pj_status_t) pjsua_verify_url(const char *url); + + /** * Schedule a timer entry. Note that the timer callback may be executed * by different thread, depending on whether worker thread is enabled or diff --git a/pjsip/src/pjsip/sip_errno.c b/pjsip/src/pjsip/sip_errno.c index 0c15206a..afef2a19 100644 --- a/pjsip/src/pjsip/sip_errno.c +++ b/pjsip/src/pjsip/sip_errno.c @@ -39,6 +39,7 @@ static const struct PJ_BUILD_ERR( PJSIP_ETYPEEXISTS , "Object with the same type exists" ), PJ_BUILD_ERR( PJSIP_ESHUTDOWN, "SIP stack shutting down" ), PJ_BUILD_ERR( PJSIP_ENOTINITIALIZED,"SIP object is not initialized." ), + PJ_BUILD_ERR( PJSIP_ENOROUTESET, "Missing route set (for tel: URI)" ), /* Messaging errors */ PJ_BUILD_ERR( PJSIP_EINVALIDMSG, "Invalid message/syntax error" ), diff --git a/pjsip/src/pjsip/sip_util.c b/pjsip/src/pjsip/sip_util.c index 2b0933a3..b57c9485 100644 --- a/pjsip/src/pjsip/sip_util.c +++ b/pjsip/src/pjsip/sip_util.c @@ -835,9 +835,12 @@ static pj_status_t get_dest_info(const pjsip_uri *target_uri, dest_info->flag = pjsip_transport_get_flag_from_type(dest_info->type); } else { + /* Should have never reached here; app should have configured route + * set when sending to tel: URI pj_assert(!"Unsupported URI scheme!"); + */ PJ_TODO(SUPPORT_REQUEST_ADDR_RESOLUTION_FOR_TEL_URI); - return PJSIP_EINVALIDSCHEME; + return PJSIP_ENOROUTESET; } /* Handle IPv6 (http://trac.pjsip.org/repos/ticket/861) */ diff --git a/pjsip/src/pjsua-lib/pjsua_acc.c b/pjsip/src/pjsua-lib/pjsua_acc.c index abb61b15..fdd37a51 100644 --- a/pjsip/src/pjsua-lib/pjsua_acc.c +++ b/pjsip/src/pjsua-lib/pjsua_acc.c @@ -119,7 +119,7 @@ static pj_status_t initialize_acc(unsigned acc_id) pjsua_acc_config *acc_cfg = &pjsua_var.acc[acc_id].cfg; pjsua_acc *acc = &pjsua_var.acc[acc_id]; pjsip_name_addr *name_addr; - pjsip_sip_uri *sip_uri, *sip_reg_uri; + pjsip_sip_uri *sip_reg_uri; pj_status_t status; unsigned i; @@ -136,18 +136,27 @@ static pj_status_t initialize_acc(unsigned acc_id) } /* Local URI MUST be a SIP or SIPS: */ - if (!PJSIP_URI_SCHEME_IS_SIP(name_addr) && !PJSIP_URI_SCHEME_IS_SIPS(name_addr)) { - pjsua_perror(THIS_FILE, "Invalid local URI", - PJSIP_EINVALIDSCHEME); - return PJSIP_EINVALIDSCHEME; - } + acc->display = name_addr->display; + acc->user_part = name_addr->display; + acc->srv_domain = pj_str(""); + acc->srv_port = 0; + } else { + pjsip_sip_uri *sip_uri; + /* Get the SIP URI object: */ + sip_uri = (pjsip_sip_uri*) pjsip_uri_get_uri(name_addr); - /* Get the SIP URI object: */ - sip_uri = (pjsip_sip_uri*) pjsip_uri_get_uri(name_addr); + /* Save the user and domain part. These will be used when finding an + * account for incoming requests. + */ + acc->display = name_addr->display; + acc->user_part = sip_uri->user; + acc->srv_domain = sip_uri->host; + acc->srv_port = 0; + } /* Parse registrar URI, if any */ @@ -177,14 +186,6 @@ static pj_status_t initialize_acc(unsigned acc_id) sip_reg_uri = NULL; } - /* Save the user and domain part. These will be used when finding an - * account for incoming requests. - */ - acc->display = name_addr->display; - acc->user_part = sip_uri->user; - acc->srv_domain = sip_uri->host; - acc->srv_port = 0; - if (sip_reg_uri) { acc->srv_port = sip_reg_uri->port; } @@ -2160,7 +2161,7 @@ PJ_DEF(pj_status_t) pjsua_acc_create_uac_contact( pj_pool_t *pool, /* For non-SIP scheme, route set should be configured */ if (!PJSIP_URI_SCHEME_IS_SIP(uri) && !PJSIP_URI_SCHEME_IS_SIPS(uri)) - return PJSIP_EINVALIDREQURI; + return PJSIP_ENOROUTESET; sip_uri = (pjsip_sip_uri*)pjsip_uri_get_uri(uri); } diff --git a/pjsip/src/pjsua-lib/pjsua_core.c b/pjsip/src/pjsua-lib/pjsua_core.c index 9fb0a5d0..0dcd0f2a 100644 --- a/pjsip/src/pjsua-lib/pjsua_core.c +++ b/pjsip/src/pjsua-lib/pjsua_core.c @@ -2404,6 +2404,29 @@ PJ_DEF(pj_status_t) pjsua_get_nat_type(pj_stun_nat_type *type) return pjsua_var.nat_status; } +/* + * Verify that valid url is given. + */ +PJ_DEF(pj_status_t) pjsua_verify_url(const char *c_url) +{ + pjsip_uri *p; + pj_pool_t *pool; + char *url; + int len = (c_url ? pj_ansi_strlen(c_url) : 0); + + if (!len) return PJSIP_EINVALIDURI; + + pool = pj_pool_create(&pjsua_var.cp.factory, "check%p", 1024, 0, NULL); + if (!pool) return PJ_ENOMEM; + + url = (char*) pj_pool_alloc(pool, len+1); + pj_ansi_strcpy(url, c_url); + + p = pjsip_parse_uri(pool, url, len, 0); + + pj_pool_release(pool); + return p ? 0 : PJSIP_EINVALIDURI; +} /* * Verify that valid SIP url is given. @@ -2415,10 +2438,10 @@ PJ_DEF(pj_status_t) pjsua_verify_sip_url(const char *c_url) char *url; int len = (c_url ? pj_ansi_strlen(c_url) : 0); - if (!len) return -1; + if (!len) return PJSIP_EINVALIDURI; pool = pj_pool_create(&pjsua_var.cp.factory, "check%p", 1024, 0, NULL); - if (!pool) return -1; + if (!pool) return PJ_ENOMEM; url = (char*) pj_pool_alloc(pool, len+1); pj_ansi_strcpy(url, c_url); @@ -2431,7 +2454,7 @@ PJ_DEF(pj_status_t) pjsua_verify_sip_url(const char *c_url) } pj_pool_release(pool); - return p ? 0 : -1; + return p ? 0 : PJSIP_EINVALIDURI; } /* diff --git a/tests/pjsua/scripts-call/400_tel_uri.py b/tests/pjsua/scripts-call/400_tel_uri.py new file mode 100644 index 00000000..2b64c30c --- /dev/null +++ b/tests/pjsua/scripts-call/400_tel_uri.py @@ -0,0 +1,12 @@ +# $Id$ +# +from inc_cfg import * + +# Simple call +test_param = TestParam( + "tel: URI in From", + [ + InstanceParam("callee", "--null-audio --max-calls=1 --id tel:+111"), + InstanceParam("caller", "--null-audio --max-calls=1") + ] + ) diff --git a/tests/pjsua/scripts-recvfrom/235_reg_good_tel_uri_enocredential.py b/tests/pjsua/scripts-recvfrom/235_reg_good_tel_uri_enocredential.py new file mode 100644 index 00000000..3725bf72 --- /dev/null +++ b/tests/pjsua/scripts-recvfrom/235_reg_good_tel_uri_enocredential.py @@ -0,0 +1,15 @@ +# $Id$ +import inc_sip as sip +import inc_sdp as sdp + +pjsua = "--null-audio --id=tel:+12345 --registrar sip:127.0.0.1:$PORT" + +req1 = sip.RecvfromTransaction("", 401, + include=["REGISTER sip"], + exclude=["Authorization"], + resp_hdr=["WWW-Authenticate: Digest realm=\"python\", nonce=\"1234\""], + expect="PJSIP_ENOCREDENTIAL" + ) + +recvfrom_cfg = sip.RecvfromCfg("Failed registration with tel: URI test", + pjsua, [req1]) -- cgit v1.2.3