summaryrefslogtreecommitdiff
path: root/pjsip/src
diff options
context:
space:
mode:
Diffstat (limited to 'pjsip/src')
-rw-r--r--pjsip/src/pjsip-simple/event_notify.c2
-rw-r--r--pjsip/src/pjsip-simple/messaging.c2
-rw-r--r--pjsip/src/pjsip-ua/sip_dialog.c2
-rw-r--r--pjsip/src/pjsip-ua/sip_reg.c2
-rw-r--r--pjsip/src/pjsip-ua/sip_ua.c2
-rw-r--r--pjsip/src/pjsip/sip_endpoint.c59
-rw-r--r--pjsip/src/pjsip/sip_errno.c125
-rw-r--r--pjsip/src/pjsip/sip_parser.c82
-rw-r--r--pjsip/src/pjsip/sip_transaction.c8
-rw-r--r--pjsip/src/pjsip/sip_transport.c2
-rw-r--r--pjsip/src/pjsip/sip_uri.c289
-rw-r--r--pjsip/src/pjsip/sip_util.c (renamed from pjsip/src/pjsip/sip_misc.c)2
-rw-r--r--pjsip/src/test-pjsip/main.c6
-rw-r--r--pjsip/src/test-pjsip/msg.c (renamed from pjsip/src/test-pjsip/parse_msg.c)117
-rw-r--r--pjsip/src/test-pjsip/test.c47
-rw-r--r--pjsip/src/test-pjsip/test.h9
-rw-r--r--pjsip/src/test-pjsip/uri.c (renamed from pjsip/src/test-pjsip/parse_uri.c)162
17 files changed, 562 insertions, 356 deletions
diff --git a/pjsip/src/pjsip-simple/event_notify.c b/pjsip/src/pjsip-simple/event_notify.c
index 004a37df..4879f884 100644
--- a/pjsip/src/pjsip-simple/event_notify.c
+++ b/pjsip/src/pjsip-simple/event_notify.c
@@ -18,7 +18,7 @@
*/
#include <pjsip_simple/event_notify.h>
#include <pjsip/sip_msg.h>
-#include <pjsip/sip_misc.h>
+#include <pjsip/sip_util.h>
#include <pjsip/sip_endpoint.h>
#include <pjsip/sip_module.h>
#include <pjsip/sip_transaction.h>
diff --git a/pjsip/src/pjsip-simple/messaging.c b/pjsip/src/pjsip-simple/messaging.c
index 9668f42f..d43acc0c 100644
--- a/pjsip/src/pjsip-simple/messaging.c
+++ b/pjsip/src/pjsip-simple/messaging.c
@@ -22,7 +22,7 @@
#include <pjsip/sip_transaction.h>
#include <pjsip/sip_event.h>
#include <pjsip/sip_module.h>
-#include <pjsip/sip_misc.h>
+#include <pjsip/sip_util.h>
#include <pj/string.h>
#include <pj/pool.h>
#include <pj/guid.h>
diff --git a/pjsip/src/pjsip-ua/sip_dialog.c b/pjsip/src/pjsip-ua/sip_dialog.c
index 1b23bc42..ac110412 100644
--- a/pjsip/src/pjsip-ua/sip_dialog.c
+++ b/pjsip/src/pjsip-ua/sip_dialog.c
@@ -24,7 +24,7 @@
#include <pjsip/sip_types.h>
#include <pjsip/sip_endpoint.h>
#include <pjsip/sip_uri.h>
-#include <pjsip/sip_misc.h>
+#include <pjsip/sip_util.h>
#include <pjsip/sip_module.h>
#include <pjsip/sip_event.h>
#include <pjsip/sip_parser.h>
diff --git a/pjsip/src/pjsip-ua/sip_reg.c b/pjsip/src/pjsip-ua/sip_reg.c
index 12a670c5..e7bf9bd6 100644
--- a/pjsip/src/pjsip-ua/sip_reg.c
+++ b/pjsip/src/pjsip-ua/sip_reg.c
@@ -22,7 +22,7 @@
#include <pjsip/sip_module.h>
#include <pjsip/sip_transaction.h>
#include <pjsip/sip_event.h>
-#include <pjsip/sip_misc.h>
+#include <pjsip/sip_util.h>
#include <pjsip/sip_auth_msg.h>
#include <pj/pool.h>
#include <pj/string.h>
diff --git a/pjsip/src/pjsip-ua/sip_ua.c b/pjsip/src/pjsip-ua/sip_ua.c
index bbe362a6..11f7670c 100644
--- a/pjsip/src/pjsip-ua/sip_ua.c
+++ b/pjsip/src/pjsip-ua/sip_ua.c
@@ -21,7 +21,7 @@
#include <pjsip_mod_ua/sip_ua_private.h>
#include <pjsip/sip_module.h>
#include <pjsip/sip_event.h>
-#include <pjsip/sip_misc.h>
+#include <pjsip/sip_util.h>
#include <pjsip/sip_endpoint.h>
#include <pjsip/sip_transaction.h>
#include <pj/list.h>
diff --git a/pjsip/src/pjsip/sip_endpoint.c b/pjsip/src/pjsip/sip_endpoint.c
index 0d80b994..d68d35d0 100644
--- a/pjsip/src/pjsip/sip_endpoint.c
+++ b/pjsip/src/pjsip/sip_endpoint.c
@@ -22,7 +22,7 @@
#include <pjsip/sip_event.h>
#include <pjsip/sip_resolve.h>
#include <pjsip/sip_module.h>
-#include <pjsip/sip_misc.h>
+#include <pjsip/sip_util.h>
#include <pjsip/sip_errno.h>
#include <pj/except.h>
#include <pj/log.h>
@@ -106,13 +106,6 @@ static void endpt_transport_callback(pjsip_endpoint*,
/*
- * Create transaction.
- * Defined in sip_transaction.c
- */
-pj_status_t pjsip_tsx_create( pj_pool_t *pool, pjsip_endpoint *endpt,
- pjsip_transaction **tsx );
-
-/*
* This is the global handler for memory allocation failure, for pools that
* are created by the endpoint (by default, all pools ARE allocated by
* endpoint). The error is handled by throwing exception, and hopefully,
@@ -294,7 +287,7 @@ void pjsip_endpt_send_tsx_event( pjsip_endpoint *endpt, pjsip_event *evt )
/*
* Get "Allow" header.
*/
-PJ_DECL(const pjsip_allow_hdr*) pjsip_endpt_get_allow_hdr( pjsip_endpoint *endpt )
+PJ_DEF(const pjsip_allow_hdr*) pjsip_endpt_get_allow_hdr( pjsip_endpoint *endpt )
{
return endpt->allow_hdr;
}
@@ -671,7 +664,7 @@ PJ_DEF(void) pjsip_endpt_register_tsx( pjsip_endpoint *endpt,
/*
* Find transaction by the key.
*/
-PJ_DECL(pjsip_transaction*) pjsip_endpt_find_tsx( pjsip_endpoint *endpt,
+PJ_DEF(pjsip_transaction*) pjsip_endpt_find_tsx( pjsip_endpoint *endpt,
const pj_str_t *key )
{
pjsip_transaction *tsx;
@@ -980,7 +973,7 @@ PJ_DEF(pj_ioqueue_t*) pjsip_endpt_get_ioqueue(pjsip_endpoint *endpt)
/*
* Find/create transport.
*/
-PJ_DECL(pj_status_t) pjsip_endpt_alloc_transport( pjsip_endpoint *endpt,
+PJ_DEF(pj_status_t) pjsip_endpt_alloc_transport( pjsip_endpoint *endpt,
pjsip_transport_type_e type,
const pj_sockaddr_in *remote,
pjsip_transport **p_transport)
@@ -991,6 +984,50 @@ PJ_DECL(pj_status_t) pjsip_endpt_alloc_transport( pjsip_endpoint *endpt,
}
+/*
+ * Report error.
+ */
+PJ_DEF(void) pjsip_endpt_log_error( pjsip_endpoint *endpt,
+ const char *sender,
+ pj_status_t error_code,
+ const char *format,
+ ... )
+{
+ char newformat[256];
+ int len;
+ va_list marker;
+
+ va_start(marker, format);
+
+ PJ_UNUSED_ARG(endpt);
+
+ len = pj_native_strlen(format);
+ if (len < sizeof(newformat)-30) {
+ pj_str_t errstr;
+
+ pj_native_strcpy(newformat, format);
+ pj_snprintf(newformat+len, sizeof(newformat)-len-1,
+ ": [err %d] ", error_code);
+ len += pj_native_strlen(newformat+len);
+
+ errstr = pjsip_strerror(error_code, newformat+len,
+ sizeof(newformat)-len-1);
+
+ len += errstr.slen;
+ newformat[len] = '\0';
+
+ pj_log(sender, 1, newformat, marker);
+ } else {
+ pj_log(sender, 1, format, marker);
+ }
+
+ va_end(marker);
+}
+
+
+/*
+ * Dump endpoint.
+ */
PJ_DEF(void) pjsip_endpt_dump( pjsip_endpoint *endpt, pj_bool_t detail )
{
#if PJ_LOG_MAX_LEVEL >= 3
diff --git a/pjsip/src/pjsip/sip_errno.c b/pjsip/src/pjsip/sip_errno.c
new file mode 100644
index 00000000..7e24f3ee
--- /dev/null
+++ b/pjsip/src/pjsip/sip_errno.c
@@ -0,0 +1,125 @@
+/* $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
+ */
+#include <pjsip/sip_errno.h>
+#include <pjsip/sip_msg.h>
+#include <pj/string.h>
+#include <pj/errno.h>
+
+/* PJSIP's own error codes/messages
+ * MUST KEEP THIS ARRAY SORTED!!
+ */
+static const struct
+{
+ int code;
+ const char *msg;
+} err_str[] =
+{
+ /* Generic SIP errors */
+ { PJSIP_EBUSY, "Object is busy" },
+ { PJSIP_ETYPEEXISTS , "Object with the same type exists" },
+
+ /* Messaging errors */
+ { PJSIP_EINVALIDMSG, "Invalid message/syntax error" },
+ { PJSIP_EINVALIDSCHEME, "Invalid URI scheme" },
+ { PJSIP_EMSGTOOLONG, "Message too long" },
+ { PJSIP_EPARTIALMSG, "Partial message" },
+ { PJSIP_EMISSINGHDR, "Missing required header(s)" },
+ { PJSIP_EINVALIDVIA, "Invalid Via header" },
+ { PJSIP_EMULTIPLEVIA, "Multiple Via headers in response" },
+
+ /* Transport errors */
+ { PJSIP_EUNSUPTRANSPORT, "Unsupported transport"},
+ { PJSIP_EPENDINGTX, "Transmit buffer already pending"},
+ { PJSIP_ERXOVERFLOW, "Rx buffer overflow"},
+
+ /* Transaction errors */
+ { PJSIP_ETSXDESTROYED, "Transaction has been destroyed"},
+};
+
+
+/*
+ * pjsip_strerror()
+ */
+PJ_DEF(pj_str_t) pjsip_strerror( pj_status_t statcode,
+ char *buf, pj_size_t bufsize )
+{
+ pj_str_t errstr;
+
+ if (statcode >= PJSIP_ERRNO_START && statcode < PJSIP_ERRNO_START+800)
+ {
+ /* Status code. */
+ const pj_str_t *status_text =
+ pjsip_get_status_text(PJSIP_ERRNO_TO_SIP_STATUS(statcode));
+
+ errstr.ptr = buf;
+ pj_strncpy_with_null(&errstr, status_text, bufsize);
+ return errstr;
+ }
+ else if (statcode >= PJSIP_ERRNO_START_PJSIP &&
+ statcode < PJSIP_ERRNO_START_PJSIP + 1000)
+ {
+ /* Find the error in the table.
+ * Use binary search!
+ */
+ int first = 0;
+ int n = PJ_ARRAY_SIZE(err_str);
+
+ while (n > 0) {
+ int half = n/2;
+ int mid = first + half;
+
+ if (err_str[mid].code < statcode) {
+ first = mid+1;
+ n -= (half+1);
+ } else if (err_str[mid].code > statcode) {
+ n = half;
+ } else {
+ first = mid;
+ break;
+ }
+ }
+
+
+ if (PJ_ARRAY_SIZE(err_str) && err_str[first].code == statcode) {
+ pj_str_t msg;
+
+ msg.ptr = (char*)err_str[first].msg;
+ msg.slen = pj_native_strlen(err_str[first].msg);
+
+ errstr.ptr = buf;
+ pj_strncpy_with_null(&errstr, &msg, bufsize);
+ return errstr;
+
+ } else {
+ /* Error not found. */
+ errstr.ptr = buf;
+ errstr.slen = pj_snprintf(buf, bufsize,
+ "Unknown error %d",
+ statcode);
+
+ return errstr;
+ }
+ }
+ else {
+ /* Not our code. Give it to PJLIB. */
+ return pj_strerror(statcode, buf, bufsize);
+ }
+
+}
+
diff --git a/pjsip/src/pjsip/sip_parser.c b/pjsip/src/pjsip/sip_parser.c
index 01013363..7b869492 100644
--- a/pjsip/src/pjsip/sip_parser.c
+++ b/pjsip/src/pjsip/sip_parser.c
@@ -23,6 +23,7 @@
#include <pjsip/sip_errno.h>
#include <pjsip/sip_transport.h> /* rdata structure */
#include <pjlib-util/scanner.h>
+#include <pjlib-util/string.h>
#include <pj/except.h>
#include <pj/log.h>
#include <pj/hash.h>
@@ -32,16 +33,20 @@
#include <pj/ctype.h>
#include <pj/assert.h>
-#define RESERVED ";/?:@&=+$,"
-#define MARK "-_.!~*'()"
-#define ESCAPED "%"
-#define USER "&=+$,;?/"
-#define PASS "&=+$,"
-#define TOKEN "-.!%*_=`'~+" /* '+' is because of application/pidf+xml
- * in Content-Type! */
-#define HOST "_-."
-#define HEX_DIGIT "abcdefABCDEF"
-#define PARAM_CHAR "[]/:&+$" MARK "%"
+#define ALNUM
+#define RESERVED ";/?:@&=+$,"
+#define MARK "-_.!~*'()"
+#define UNRESERVED ALNUM MARK
+#define ESCAPED "%"
+#define USER_UNRESERVED "&=+$,;?/"
+#define PASS "&=+$,"
+#define TOKEN "-.!%*_=`'~+" /* '+' is because of app/pidf+xml
+ * in Content-Type! */
+#define HOST "_-."
+#define HEX_DIGIT "abcdefABCDEF"
+#define PARAM_CHAR "[]/:&+$" UNRESERVED ESCAPED
+#define HNV_UNRESERVED "[]/?:+$"
+#define HDR_CHAR HNV_UNRESERVED UNRESERVED ESCAPED
#define PJSIP_VERSION "SIP/2.0"
#define PJSIP_SYN_ERR_EXCEPTION 1
@@ -92,6 +97,7 @@ pj_cis_t pjsip_HOST_SPEC, /* For scanning host part. */
pjsip_HEX_SPEC, /* Hexadecimal digits. */
pjsip_PARAM_CHAR_SPEC, /* For scanning pname (or pvalue when
* it's not quoted.) */
+ pjsip_HDR_CHAR_SPEC, /* Chars in hname or hvalue */
pjsip_PROBE_USER_HOST_SPEC, /* Hostname characters. */
pjsip_PASSWD_SPEC, /* Password. */
pjsip_USER_SPEC, /* User */
@@ -109,6 +115,9 @@ static pjsip_msg * int_parse_msg( pjsip_parse_ctx *ctx,
static void int_parse_param( pj_scanner *scanner,
pj_str_t *pname,
pj_str_t *pvalue);
+static void int_parse_hparam( pj_scanner *scanner,
+ pj_str_t *hname,
+ pj_str_t *hvalue );
static void int_parse_req_line( pj_scanner *scanner,
pj_pool_t *pool,
pjsip_request_line *req_line);
@@ -271,9 +280,13 @@ static pj_status_t init_parser()
PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
pj_cis_add_str(&pjsip_PARAM_CHAR_SPEC, PARAM_CHAR);
+ status = pj_cis_dup(&pjsip_HDR_CHAR_SPEC, &pjsip_ALNUM_SPEC);
+ PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
+ pj_cis_add_str(&pjsip_HDR_CHAR_SPEC, HDR_CHAR);
+
status = pj_cis_dup(&pjsip_USER_SPEC, &pjsip_ALNUM_SPEC);
PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
- pj_cis_add_str( &pjsip_USER_SPEC, MARK ESCAPED USER );
+ pj_cis_add_str( &pjsip_USER_SPEC, ESCAPED USER_UNRESERVED );
status = pj_cis_dup(&pjsip_PASSWD_SPEC, &pjsip_ALNUM_SPEC);
PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
@@ -858,6 +871,7 @@ void pjsip_parse_param_imp( pj_scanner *scanner,
{
/* pname */
pj_scan_get(scanner, &pjsip_PARAM_CHAR_SPEC, pname);
+ pj_str_unescape(pname);
/* pvalue, if any */
if (*scanner->curptr == '=') {
@@ -871,6 +885,7 @@ void pjsip_parse_param_imp( pj_scanner *scanner,
}
} else {
pj_scan_get(scanner, &pjsip_PARAM_CHAR_SPEC, pvalue);
+ pj_str_unescape(pvalue);
}
} else {
pvalue->ptr = NULL;
@@ -889,15 +904,39 @@ static void int_parse_param( pj_scanner *scanner,
pjsip_parse_param_imp(scanner, pname, pvalue, 0);
}
+/* Parse header parameter. */
+static void int_parse_hparam( pj_scanner *scanner,
+ pj_str_t *hname, pj_str_t *hvalue )
+{
+ /* Get '?' or '&' character. */
+ pj_scan_get_char(scanner);
+
+ /* hname */
+ pj_scan_get(scanner, &pjsip_HDR_CHAR_SPEC, hname);
+ pj_str_unescape(hname);
+
+ /* pvalue, if any */
+ if (*scanner->curptr == '=') {
+ pj_scan_get_char(scanner);
+ pj_scan_get(scanner, &pjsip_HDR_CHAR_SPEC, hvalue);
+ pj_str_unescape(hvalue);
+ } else {
+ hvalue->ptr = NULL;
+ hvalue->slen = 0;
+ }
+}
+
/* Parse host:port in URI. */
static void int_parse_uri_host_port( pj_scanner *scanner,
pj_str_t *host, int *p_port)
{
pj_scan_get( scanner, &pjsip_HOST_SPEC, host);
+ /* RFC3261 section 19.1.2: host don't need to be unescaped */
if (*scanner->curptr == ':') {
pj_str_t port;
pj_scan_get_char(scanner);
pj_scan_get(scanner, &pjsip_DIGIT_SPEC, &port);
+ pj_str_unescape(&port);
*p_port = pj_strtoul(&port);
} else {
*p_port = 0;
@@ -926,9 +965,12 @@ static void int_parse_user_pass( pj_scanner *scanner,
pj_str_t *user, pj_str_t *pass)
{
pj_scan_get( scanner, &pjsip_USER_SPEC, user);
+ pj_str_unescape(user);
+
if ( *scanner->curptr == ':') {
pj_scan_get_char( scanner );
pj_scan_get( scanner, &pjsip_PASSWD_SPEC, pass);
+ pj_str_unescape(pass);
} else {
pass->ptr = NULL;
pass->slen = 0;
@@ -945,6 +987,9 @@ static pjsip_uri *int_parse_uri_or_name_addr( pj_scanner *scanner, pj_pool_t *po
pjsip_uri *uri;
int is_name_addr = 0;
+ /* Exhaust any whitespaces. */
+ pj_scan_skip_whitespace(scanner);
+
if (*scanner->curptr=='"' || *scanner->curptr=='<') {
uri = (pjsip_uri*)int_parse_name_addr( scanner, pool );
is_name_addr = 1;
@@ -1034,6 +1079,7 @@ static pjsip_url *int_parse_sip_url( pj_scanner *scanner,
pjsip_url *url;
int colon;
int skip_ws = scanner->skip_ws;
+ int hsep = '?';
scanner->skip_ws = 0;
pj_scan_get(scanner, &pjsip_TOKEN_SPEC, &scheme);
@@ -1089,14 +1135,20 @@ static pjsip_url *int_parse_sip_url( pj_scanner *scanner,
url->lr_param = 1;
} else {
- concat_param(&url->other_param, pool, &pname, &pvalue);
+ pjsip_param *p = pj_pool_alloc(pool, sizeof(pjsip_param));
+ p->name = pname;
+ p->value = pvalue;
+ pj_list_insert_before(&url->other_param, p);
}
}
/* Get header params. */
- if (parse_params && *scanner->curptr == '?') {
- pj_scan_get_until(scanner, &pjsip_NEWLINE_OR_EOF_SPEC,
- &url->header_param);
+ while (parse_params && *scanner->curptr == hsep) {
+ pjsip_param *param;
+ param = pj_pool_alloc(pool, sizeof(pjsip_param));
+ int_parse_hparam(scanner, &param->name, &param->value);
+ pj_list_insert_before(&url->header_param, param);
+ hsep = '&';
}
scanner->skip_ws = skip_ws;
diff --git a/pjsip/src/pjsip/sip_transaction.c b/pjsip/src/pjsip/sip_transaction.c
index f4818817..bc4f21ff 100644
--- a/pjsip/src/pjsip/sip_transaction.c
+++ b/pjsip/src/pjsip/sip_transaction.c
@@ -19,7 +19,7 @@
#include <pjsip/sip_transaction.h>
#include <pjsip/sip_transport.h>
#include <pjsip/sip_config.h>
-#include <pjsip/sip_misc.h>
+#include <pjsip/sip_util.h>
#include <pjsip/sip_event.h>
#include <pjsip/sip_endpoint.h>
#include <pjsip/sip_errno.h>
@@ -345,9 +345,9 @@ PJ_DEF(pj_status_t) pjsip_tsx_create_key( pj_pool_t *pool, pj_str_t *key,
/*
* Create new transaction.
*/
-pj_status_t pjsip_tsx_create( pj_pool_t *pool,
- pjsip_endpoint *endpt,
- pjsip_transaction **p_tsx)
+PJ_DEF(pj_status_t) pjsip_tsx_create( pj_pool_t *pool,
+ pjsip_endpoint *endpt,
+ pjsip_transaction **p_tsx)
{
pjsip_transaction *tsx;
pj_status_t status;
diff --git a/pjsip/src/pjsip/sip_transport.c b/pjsip/src/pjsip/sip_transport.c
index 307f9e5e..a32fb683 100644
--- a/pjsip/src/pjsip/sip_transport.c
+++ b/pjsip/src/pjsip/sip_transport.c
@@ -647,7 +647,7 @@ PJ_DEF(pj_ssize_t) pjsip_tpmgr_receive_packet( pjsip_tpmgr *mgr,
&msg_fragment_size);
if (msg_status != PJ_SUCCESS) {
if (remaining_len == PJSIP_MAX_PKT_LEN) {
- mgr->msg_cb(mgr->endpt, PJSIP_EOVERFLOW, rdata);
+ mgr->msg_cb(mgr->endpt, PJSIP_ERXOVERFLOW, rdata);
/* Exhaust all data. */
return rdata->pkt_info.len;
} else {
diff --git a/pjsip/src/pjsip/sip_uri.c b/pjsip/src/pjsip/sip_uri.c
index bd49db97..b292fea0 100644
--- a/pjsip/src/pjsip/sip_uri.c
+++ b/pjsip/src/pjsip/sip_uri.c
@@ -18,11 +18,59 @@
*/
#include <pjsip/sip_uri.h>
#include <pjsip/sip_msg.h>
+#include <pjsip/sip_parser.h>
#include <pjsip/print_util.h>
+#include <pjsip/sip_errno.h>
+#include <pjlib-util/string.h>
#include <pj/string.h>
#include <pj/pool.h>
#include <pj/assert.h>
+/*
+ * Generic parameter manipulation.
+ */
+PJ_DEF(pjsip_param*) pjsip_param_find( pjsip_param *param_list,
+ const pj_str_t *name )
+{
+ pjsip_param *p = param_list->next;
+ while (p != param_list) {
+ if (pj_stricmp(&p->name, name)==0)
+ return p;
+ p = p->next;
+ }
+ return NULL;
+}
+
+PJ_DEF(const pjsip_param*) pjsip_param_cfind( const pjsip_param *param_list,
+ const pj_str_t *name )
+{
+ const pjsip_param *p = param_list->next;
+ while (p != param_list) {
+ if (pj_stricmp(&p->name, name)==0)
+ return p;
+ p = p->next;
+ }
+ return NULL;
+}
+
+PJ_DEF(void) pjsip_param_clone( pj_pool_t *pool, pjsip_param *dst_list,
+ const pjsip_param *src_list)
+{
+ const pjsip_param *p = src_list->next;
+
+ pj_list_init(dst_list);
+ while (p != src_list) {
+ pjsip_param *new_param = pj_pool_alloc(pool, sizeof(pjsip_param));
+ pj_strdup(pool, &new_param->name, &p->name);
+ pj_strdup(pool, &new_param->value, &p->value);
+ pj_list_insert_before(dst_list, new_param);
+ p = p->next;
+ }
+}
+
+/*
+ * URI stuffs
+ */
#define IS_SIPS(url) ((url)->vptr==&sips_url_vptr)
static const pj_str_t *pjsip_url_get_scheme( const pjsip_url* );
@@ -109,6 +157,8 @@ PJ_DEF(void) pjsip_url_init(pjsip_url *url, int secure)
pj_memset(url, 0, sizeof(*url));
url->ttl_param = -1;
url->vptr = secure ? &sips_url_vptr : &sip_url_vptr;
+ pj_list_init(&url->other_param);
+ pj_list_init(&url->header_param);
}
PJ_DEF(pjsip_url*) pjsip_url_create( pj_pool_t *pool, int secure )
@@ -123,37 +173,25 @@ static int pjsip_url_print( pjsip_uri_context_e context,
char *buf, pj_size_t size)
{
int printed;
- pj_size_t size_required;
char *startbuf = buf;
+ char *endbuf = buf+size;
const pj_str_t *scheme;
- *buf = '\0';
+ pjsip_param *param;
+ char hparam_char = '?';
- /* Check the buffer length. */
- size_required = 6 + url->host.slen + 10 +
- url->user.slen + url->passwd.slen + 2 +
- url->user_param.slen + 6 +
- url->method_param.slen + 8 +
- url->transport_param.slen + 11 +
- 9 + 5 +
- url->maddr_param.slen + 7 +
- 3 +
- url->other_param.slen +
- url->header_param.slen;
- if (size < size_required) {
- return -1;
- }
+ *buf = '\0';
/* Print scheme ("sip:" or "sips:") */
scheme = pjsip_uri_get_scheme(url);
- copy_advance_no_check(buf, *scheme);
+ copy_advance_check(buf, *scheme);
*buf++ = ':';
/* Print "user:password@", if any. */
if (url->user.slen) {
- copy_advance_no_check(buf, url->user);
+ copy_advance_escape(buf, url->user, pjsip_USER_SPEC);
if (url->passwd.slen) {
*buf++ = ':';
- copy_advance_no_check(buf, url->passwd);
+ copy_advance_escape(buf, url->passwd, pjsip_PASSWD_SPEC);
}
*buf++ = '@';
@@ -161,7 +199,7 @@ static int pjsip_url_print( pjsip_uri_context_e context,
/* Print host. */
pj_assert(url->host.slen != 0);
- copy_advance_no_check(buf, url->host);
+ copy_advance_check(buf, url->host);
/* Only print port if it is explicitly specified.
* Port is not allowed in To and From header.
@@ -170,29 +208,31 @@ static int pjsip_url_print( pjsip_uri_context_e context,
* number exactly as it was sent. We don't remember whether an
* UA has sent us port, so we'll just send the port indiscrimately
*/
- PJ_TODO(SHOULD_DISALLOW_URI_PORT_IN_FROM_TO_HEADER)
- if (url->port /*&& context != PJSIP_URI_IN_FROMTO_HDR*/) {
+ //PJ_TODO(SHOULD_DISALLOW_URI_PORT_IN_FROM_TO_HEADER)
+ if (url->port && context != PJSIP_URI_IN_FROMTO_HDR) {
*buf++ = ':';
printed = pj_utoa(url->port, buf);
buf += printed;
}
/* User param is allowed in all contexes */
- copy_advance_pair_no_check(buf, ";user=", 6, url->user_param);
+ copy_advance_pair_check(buf, ";user=", 6, url->user_param);
/* Method param is only allowed in external/other context. */
if (context == PJSIP_URI_IN_OTHER) {
- copy_advance_pair_no_check(buf, ";method=", 8, url->method_param);
+ copy_advance_pair_escape(buf, ";method=", 8, url->method_param,
+ pjsip_PARAM_CHAR_SPEC);
}
/* Transport is not allowed in From/To header. */
if (context != PJSIP_URI_IN_FROMTO_HDR) {
- copy_advance_pair_no_check(buf, ";transport=", 11, url->transport_param);
+ copy_advance_pair_escape(buf, ";transport=", 11, url->transport_param,
+ pjsip_PARAM_CHAR_SPEC);
}
/* TTL param is not allowed in From, To, Route, and Record-Route header. */
if (url->ttl_param >= 0 && context != PJSIP_URI_IN_FROMTO_HDR &&
- context != PJSIP_URI_IN_ROUTING_HDR)
+ context != PJSIP_URI_IN_ROUTING_HDR && (endbuf-buf) > 15)
{
pj_memcpy(buf, ";ttl=", 5);
printed = pj_utoa(url->ttl_param, buf+5);
@@ -201,7 +241,8 @@ static int pjsip_url_print( pjsip_uri_context_e context,
/* maddr param is not allowed in From and To header. */
if (context != PJSIP_URI_IN_FROMTO_HDR) {
- copy_advance_pair_no_check(buf, ";maddr=", 7, url->maddr_param);
+ copy_advance_pair_escape(buf, ";maddr=", 7, url->maddr_param,
+ pjsip_PARAM_CHAR_SPEC);
}
/* lr param is not allowed in From, To, and Contact header. */
@@ -209,86 +250,166 @@ static int pjsip_url_print( pjsip_uri_context_e context,
context != PJSIP_URI_IN_CONTACT_HDR)
{
pj_str_t lr = { ";lr", 3 };
- copy_advance_no_check(buf, lr);
+ copy_advance_check(buf, lr);
}
/* Other param. */
- if (url->other_param.slen) {
- copy_advance_no_check(buf, url->other_param);
+ param = url->other_param.next;
+ while (param != &url->other_param) {
+ *buf++ = ';';
+ copy_advance_escape(buf, param->name, pjsip_PARAM_CHAR_SPEC);
+ if (param->value.slen) {
+ *buf++ = '=';
+ copy_advance_escape(buf, param->value, pjsip_PARAM_CHAR_SPEC);
+ }
+ param = param->next;
}
/* Header param. */
- if (url->header_param.slen) {
- copy_advance_no_check(buf, url->header_param);
+ param = url->header_param.next;
+ while (param != &url->header_param) {
+ *buf++ = hparam_char;
+ copy_advance_escape(buf, param->name, pjsip_HDR_CHAR_SPEC);
+ if (param->value.slen) {
+ *buf++ = '=';
+ copy_advance_escape(buf, param->value, pjsip_HDR_CHAR_SPEC);
+ }
+ param = param->next;
+ hparam_char = '&';
}
*buf = '\0';
return buf-startbuf;
}
-static int pjsip_url_compare( pjsip_uri_context_e context,
- const pjsip_url *url1, const pjsip_url *url2)
+static pj_status_t pjsip_url_compare( pjsip_uri_context_e context,
+ const pjsip_url *url1,
+ const pjsip_url *url2)
{
- /* The easiest (and probably the most efficient) way to compare two URLs
- are to print them, and compare them bytes per bytes. This technique
- works quite well with RFC3261, as the RFC (unlike RFC2543) defines that
- components specified in one URL does NOT match its default value if
- it is not specified in the second URL. For example, parameter "user=ip"
- does NOT match if it is omited in second URL.
-
- HOWEVER, THE SAME CAN NOT BE APPLIED FOR other-param NOR header-param.
- For these, each of the parameters must be compared one by one. Parameter
- that exists in one URL will match the comparison. But parameter that
- exists in both URLs and doesn't match wont match the URL comparison.
-
- The solution for this is to compare 'standard' URL components with
- bytes-to-bytes comparison, and compare other-param and header-param with
- more intelligent comparison.
+ const pjsip_param *p1;
+
+ /*
+ * Compare two SIP URL's according to Section 19.1.4 of RFC 3261.
*/
- char str_url1[PJSIP_MAX_URL_SIZE];
- char str_url2[PJSIP_MAX_URL_SIZE];
- int len1, len2;
- /* Must compare scheme first, as the second URI may not be SIP URL. */
- if (pj_stricmp(pjsip_uri_get_scheme(url1), pjsip_uri_get_scheme(url2)))
- return -1;
+ /* SIP and SIPS URI are never equivalent.
+ * Note: just compare the vptr to avoid string comparison.
+ * Pretty neat huh!!
+ */
+ if (url1->vptr != url2->vptr)
+ return PJSIP_ECMPSCHEME;
- len1 = pjsip_url_print(context, url1, str_url1, sizeof(str_url1));
- if (len1 < 1) {
- pj_assert(0);
- return -1;
+ /* Comparison of the userinfo of SIP and SIPS URIs is case-sensitive.
+ * This includes userinfo containing passwords or formatted as
+ * telephone-subscribers.
+ */
+ if (pj_strcmp(&url1->user, &url2->user) != 0)
+ return PJSIP_ECMPUSER;
+ if (pj_strcmp(&url1->passwd, &url2->passwd) != 0)
+ return PJSIP_ECMPPASSWD;
+
+ /* Comparison of all other components of the URI is
+ * case-insensitive unless explicitly defined otherwise.
+ */
+
+ /* The ordering of parameters and header fields is not significant
+ * in comparing SIP and SIPS URIs.
+ */
+
+ /* Characters other than those in the “reserved” set (see RFC 2396 [5])
+ * are equivalent to their “encoding.
+ */
+
+ /* An IP address that is the result of a DNS lookup of a host name
+ * does not match that host name.
+ */
+ if (pj_stricmp(&url1->host, &url2->host) != 0)
+ return PJSIP_ECMPHOST;
+
+ /* A URI omitting any component with a default value will not match a URI
+ * explicitly containing that component with its default value.
+ * For instance, a URI omitting the optional port component will not match
+ * a URI explicitly declaring port 5060.
+ * The same is true for the transport-parameter, ttl-parameter,
+ * user-parameter, and method components.
+ */
+
+ /* Port is not allowed in To and From header.
+ */
+ if (context != PJSIP_URI_IN_FROMTO_HDR) {
+ if (url1->port != url2->port)
+ return PJSIP_ECMPPORT;
}
- len2 = pjsip_url_print(context, url2, str_url2, sizeof(str_url2));
- if (len2 < 1) {
- pj_assert(0);
- return -1;
+ /* Transport is not allowed in From/To header. */
+ if (context != PJSIP_URI_IN_FROMTO_HDR) {
+ if (pj_stricmp(&url1->transport_param, &url2->transport_param) != 0)
+ return PJSIP_ECMPTRANSPORTPRM;
}
-
- if (len1 != len2) {
- /* Not equal. */
- return -1;
+ /* TTL param is not allowed in From, To, Route, and Record-Route header. */
+ if (context != PJSIP_URI_IN_FROMTO_HDR &&
+ context != PJSIP_URI_IN_ROUTING_HDR)
+ {
+ if (url1->ttl_param != url2->ttl_param)
+ return PJSIP_ECMPTTLPARAM;
}
-
- if (pj_native_strcmp(str_url1, str_url2)) {
- /* Not equal */
- return -1;
+ /* User param is allowed in all contexes */
+ if (pj_stricmp(&url1->user_param, &url2->user_param) != 0)
+ return PJSIP_ECMPUSERPARAM;
+ /* Method param is only allowed in external/other context. */
+ if (context == PJSIP_URI_IN_OTHER) {
+ if (pj_stricmp(&url1->method_param, &url2->method_param) != 0)
+ return PJSIP_ECMPMETHODPARAM;
+ }
+ /* maddr param is not allowed in From and To header. */
+ if (context != PJSIP_URI_IN_FROMTO_HDR) {
+ if (pj_stricmp(&url1->maddr_param, &url2->maddr_param) != 0)
+ return PJSIP_ECMPMADDRPARAM;
}
- /* TODO: compare other-param and header-param in more intelligent manner. */
- PJ_TODO(HPARAM_AND_OTHER_PARAM_COMPARISON_IN_URL_COMPARISON)
+ /* lr parameter is ignored (?) */
+ /* lr param is not allowed in From, To, and Contact header. */
- if (pj_strcmp(&url1->other_param, &url2->other_param)) {
- /* Not equal. */
- return -1;
+
+ /* All other uri-parameters appearing in only one URI are ignored when
+ * comparing the URIs.
+ */
+ p1 = url1->other_param.next;
+ while (p1 != &url1->other_param) {
+ const pjsip_param *p2;
+ p2 = pjsip_param_cfind(&url2->other_param, &p1->name);
+ if (p2 ) {
+ if (pj_stricmp(&p1->value, &p2->value) != 0)
+ return PJSIP_ECMPOTHERPARAM;
+ }
+
+ p1 = p1->next;
}
- if (pj_strcmp(&url1->header_param, &url2->header_param)) {
- /* Not equal. */
- return -1;
+
+ /* URI header components are never ignored. Any present header component
+ * MUST be present in both URIs and match for the URIs to match.
+ * The matching rules are defined for each header field in Section 20.
+ */
+ p1 = url1->header_param.next;
+ while (p1 != &url1->header_param) {
+ const pjsip_param *p2;
+ p2 = pjsip_param_cfind(&url2->header_param, &p1->name);
+ if (p2) {
+ /* It seems too much to compare two header params according to
+ * the rule of each header. We'll just compare them string to
+ * string..
+ */
+ PJ_TODO(MORE_COMPLIANT_HEADER_PARAM_COMPARISON_IN_URL);
+
+ if (pj_stricmp(&p1->value, &p2->value) != 0)
+ return PJSIP_ECMPHEADERPARAM;
+ } else {
+ return PJSIP_ECMPHEADERPARAM;
+ }
+ p1 = p1->next;
}
- /* Seems to be equal, isn't it. */
- return 0;
-
+ /* Equal!! Pheuww.. */
+ return PJ_SUCCESS;
}
@@ -304,8 +425,8 @@ PJ_DEF(void) pjsip_url_assign(pj_pool_t *pool, pjsip_url *url,
pj_strdup( pool, &url->transport_param, &rhs->transport_param);
url->ttl_param = rhs->ttl_param;
pj_strdup( pool, &url->maddr_param, &rhs->maddr_param);
- pj_strdup( pool, &url->other_param, &rhs->other_param);
- pj_strdup( pool, &url->header_param, &rhs->header_param);
+ pjsip_param_clone(pool, &url->other_param, &rhs->other_param);
+ pjsip_param_clone(pool, &url->header_param, &rhs->header_param);
url->lr_param = rhs->lr_param;
}
diff --git a/pjsip/src/pjsip/sip_misc.c b/pjsip/src/pjsip/sip_util.c
index c134da88..5f59a12e 100644
--- a/pjsip/src/pjsip/sip_misc.c
+++ b/pjsip/src/pjsip/sip_util.c
@@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <pjsip/sip_misc.h>
+#include <pjsip/sip_util.h>
#include <pjsip/sip_transport.h>
#include <pjsip/sip_msg.h>
#include <pjsip/sip_endpoint.h>
diff --git a/pjsip/src/test-pjsip/main.c b/pjsip/src/test-pjsip/main.c
index 75b3792e..3c819be8 100644
--- a/pjsip/src/test-pjsip/main.c
+++ b/pjsip/src/test-pjsip/main.c
@@ -16,3 +16,9 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#include "test.h"
+
+int main(void)
+{
+ return test_main();
+}
diff --git a/pjsip/src/test-pjsip/parse_msg.c b/pjsip/src/test-pjsip/msg.c
index 94ac25ce..b546a756 100644
--- a/pjsip/src/test-pjsip/parse_msg.c
+++ b/pjsip/src/test-pjsip/msg.c
@@ -16,19 +16,9 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <pjsip/sip_msg.h>
-#include <pjsip/sip_parser.h>
-#include <pj/os.h>
-#include <pj/pool.h>
-#include <pj/string.h>
-#include <stdlib.h>
-#include <stdio.h>
#include "test.h"
-
-#define ERR_SYNTAX_ERR (-2)
-#define ERR_NOT_EQUAL (-3)
-#define ERR_SYSTEM (-4)
-
+#include <pjsip_core.h>
+#include <pjlib.h>
static pjsip_msg *create_msg0(pj_pool_t *pool);
@@ -66,66 +56,31 @@ struct test_msg
}
};
-static pj_caching_pool cp;
-static pj_pool_factory *pf = &cp.factory;
static pj_uint32_t parse_len, parse_time, print_time;
-static void pool_error(pj_pool_t *pool, pj_size_t sz)
-{
- PJ_UNUSED_ARG(pool)
- PJ_UNUSED_ARG(sz)
-
- pj_assert(0);
- exit(1);
-}
-
-static const char *STATUS_STR(pj_status_t status)
-{
- switch (status) {
- case 0: return "OK";
- case ERR_SYNTAX_ERR: return "Syntax Error";
- case ERR_NOT_EQUAL: return "Not Equal";
- case ERR_SYSTEM: return "System Error";
- }
- return "???";
-}
-
-static pj_status_t test_entry( struct test_msg *entry )
+static pj_status_t test_entry( pj_pool_t *pool, struct test_msg *entry )
{
pjsip_msg *parsed_msg, *ref_msg;
- pj_pool_t *pool;
pj_status_t status = PJ_SUCCESS;
int len;
pj_str_t str1, str2;
pjsip_hdr *hdr1, *hdr2;
- pj_hr_timestamp t1, t2;
+ pj_timestamp t1, t2;
char *msgbuf;
enum { BUFLEN = 512 };
- pool = pj_pool_create( pf, "",
- PJSIP_POOL_LEN_RDATA*2, PJSIP_POOL_INC_RDATA,
- &pool_error);
-
- if (entry->len == 0) {
- entry->len = strlen(entry->msg);
- }
-
/* Parse message. */
parse_len += entry->len;
- pj_hr_gettimestamp(&t1);
+ pj_get_timestamp(&t1);
parsed_msg = pjsip_parse_msg(pool, entry->msg, entry->len, NULL);
if (parsed_msg == NULL) {
- status = ERR_SYNTAX_ERR;
+ status = -10;
goto on_return;
}
- pj_hr_gettimestamp(&t2);
+ pj_get_timestamp(&t2);
parse_time += t2.u32.lo - t1.u32.lo;
-#if IS_PROFILING
- goto print_msg;
-#endif
-
/* Create reference message. */
ref_msg = entry->creator(pool);
@@ -135,7 +90,7 @@ static pj_status_t test_entry( struct test_msg *entry )
/* Compare message type. */
if (parsed_msg->type != ref_msg->type) {
- status = ERR_NOT_EQUAL;
+ status = -20;
goto on_return;
}
@@ -145,7 +100,7 @@ static pj_status_t test_entry( struct test_msg *entry )
pjsip_method *m2 = &ref_msg->line.req.method;
if (m1->id != m2->id || pj_strcmp(&m1->name, &m2->name)) {
- status = ERR_NOT_EQUAL;
+ status = -30;
goto on_return;
}
} else {
@@ -159,26 +114,20 @@ static pj_status_t test_entry( struct test_msg *entry )
while (hdr1 != &parsed_msg->hdr && hdr2 != &ref_msg->hdr) {
len = hdr1->vptr->print_on(hdr1, str1.ptr, BUFLEN);
if (len < 1) {
- status = ERR_SYSTEM;
+ status = -40;
goto on_return;
}
str1.slen = len;
len = hdr2->vptr->print_on(hdr2, str2.ptr, BUFLEN);
if (len < 1) {
- status = ERR_SYSTEM;
+ status = -50;
goto on_return;
}
str2.slen = len;
- if (!SILENT) {
- printf("hdr1='%.*s'\n"
- "hdr2='%.*s'\n\n",
- str1.slen, str1.ptr,
- str2.slen, str2.ptr);
- }
if (pj_strcmp(&str1, &str2) != 0) {
- status = ERR_NOT_EQUAL;
+ status = -60;
goto on_return;
}
@@ -187,62 +136,42 @@ static pj_status_t test_entry( struct test_msg *entry )
}
if (hdr1 != &parsed_msg->hdr || hdr2 != &ref_msg->hdr) {
- status = ERR_NOT_EQUAL;
+ status = -70;
goto on_return;
}
/* Print message. */
-#if IS_PROFILING
-print_msg:
-#endif
msgbuf = pj_pool_alloc(pool, PJSIP_MAX_PKT_LEN);
if (msgbuf == NULL) {
- status = ERR_SYSTEM;
+ status = -80;
goto on_return;
}
- pj_hr_gettimestamp(&t1);
+ pj_get_timestamp(&t1);
len = pjsip_msg_print(parsed_msg, msgbuf, PJSIP_MAX_PKT_LEN);
if (len < 1) {
- status = ERR_SYSTEM;
+ status = -90;
goto on_return;
}
- pj_hr_gettimestamp(&t2);
+ pj_get_timestamp(&t2);
print_time += t2.u32.lo - t1.u32.lo;
status = PJ_SUCCESS;
on_return:
- pj_pool_release(pool);
return status;
}
-static void warm_up()
-{
- pj_pool_t *pool;
- pool = pj_pool_create( pf, "",
- PJSIP_POOL_LEN_RDATA*2, PJSIP_POOL_INC_RDATA,
- &pool_error);
- pj_pool_release(pool);
-}
-
-pj_status_t test_msg(void)
+pj_status_t msg_test(void)
{
pj_status_t status;
- unsigned i;
+ pj_pool_t *pool;
- pj_caching_pool_init(&cp, &pj_pool_factory_default_policy, 0);
- warm_up();
+ pool = pjsip_endpt_create_pool(endpt, NULL, 4000, 4000);
- for (i=0; i<LOOP; ++i) {
- status = test_entry( &test_array[0] );
- }
- printf("%s\n", STATUS_STR(status));
+ status = test_entry( pool, &test_array[0] );
- printf("Total bytes: %u, parse time=%f/char, print time=%f/char\n",
- parse_len,
- parse_time*1.0/parse_len,
- print_time*1.0/parse_len);
- return PJ_SUCCESS;
+ pjsip_endpt_destroy(endpt);
+ return status;
}
/*****************************************************************************/
diff --git a/pjsip/src/test-pjsip/test.c b/pjsip/src/test-pjsip/test.c
index 4a69b582..80d08881 100644
--- a/pjsip/src/test-pjsip/test.c
+++ b/pjsip/src/test-pjsip/test.c
@@ -46,20 +46,59 @@ void app_perror(const char *msg, pj_status_t rc)
}
+pj_status_t register_static_modules(pj_size_t *count, pjsip_module **modules)
+{
+ *count = 0;
+ return PJ_SUCCESS;
+}
-
-int main()
+int test_main(void)
{
pj_status_t rc;
+ pj_caching_pool caching_pool;
+ const char *filename;
+ int line;
+
+ pj_log_set_level(3);
+ pj_log_set_decor(PJ_LOG_HAS_NEWLINE | PJ_LOG_HAS_TIME |
+ PJ_LOG_HAS_MICRO_SEC);
if ((rc=pj_init()) != PJ_SUCCESS) {
app_perror("pj_init", rc);
+ return rc;
+ }
+
+ pj_dump_config();
+
+ pj_caching_pool_init( &caching_pool, &pj_pool_factory_default_policy, 0 );
+
+ rc = pjsip_endpt_create(&caching_pool.factory, "endpt", &endpt);
+ if (rc != PJ_SUCCESS) {
+ app_perror("pjsip_endpt_create", rc);
+ pj_caching_pool_destroy(&caching_pool);
+ return rc;
}
- DO_TEST(parse_uri());
- DO_TEST(parse_msg());
+ PJ_LOG(3,("",""));
+
+ DO_TEST(uri_test());
on_return:
+
+ pjsip_endpt_destroy(endpt);
+ pj_caching_pool_destroy(&caching_pool);
+
+ PJ_LOG(3,("test", ""));
+
+ pj_thread_get_stack_info(pj_thread_this(), &filename, &line);
+ PJ_LOG(3,("test", "Stack max usage: %u, deepest: %s:%u",
+ pj_thread_get_stack_max_usage(pj_thread_this()),
+ filename, line));
+ if (rc == 0)
+ PJ_LOG(3,("test", "Looks like everything is okay!.."));
+ else
+ PJ_LOG(3,("test", "Test completed with error(s)"));
+
return 0;
}
diff --git a/pjsip/src/test-pjsip/test.h b/pjsip/src/test-pjsip/test.h
index 225c8be7..60b67c5e 100644
--- a/pjsip/src/test-pjsip/test.h
+++ b/pjsip/src/test-pjsip/test.h
@@ -21,15 +21,12 @@
#include <pjsip/sip_types.h>
-#define SILENT 1
-#define IS_PROFILING 1
-#define LOOP 2000
-
extern pjsip_endpoint *endpt;
-pj_status_t parse_uri(void);
-pj_status_t parse_msg(void);
+pj_status_t uri_test(void);
+pj_status_t msg_test(void);
+int test_main(void);
void app_perror(const char *msg, pj_status_t status);
diff --git a/pjsip/src/test-pjsip/parse_uri.c b/pjsip/src/test-pjsip/uri.c
index cfb3afd7..a61382f0 100644
--- a/pjsip/src/test-pjsip/parse_uri.c
+++ b/pjsip/src/test-pjsip/uri.c
@@ -16,17 +16,10 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-#include <pjsip/sip_parser.h>
-#include <pjsip/sip_uri.h>
-#include <pj/os.h>
-#include <pj/pool.h>
-#include <pj/string.h>
-#include <stdlib.h>
-#include <stdio.h>
#include "test.h"
+#include <pjsip_core.h>
+#include <pjlib.h>
-#define ERR_SYNTAX_ERR (-2)
-#define ERR_NOT_EQUAL (-3)
#define ALPHANUM "abcdefghijklmnopqrstuvwxyz" \
"ABCDEFGHIJKLMNOPQRSTUVWXYZ" \
@@ -38,18 +31,7 @@
#define POOL_SIZE 4096
-static const char *STATUS_STR(pj_status_t status)
-{
- switch (status) {
- case 0: return "OK";
- case ERR_SYNTAX_ERR: return "Syntax Error";
- case ERR_NOT_EQUAL: return "Not Equal";
- }
- return "???";
-}
-
static pj_uint32_t parse_len, parse_time, print_time;
-static pj_caching_pool cp;
/* URI creator functions. */
@@ -74,6 +56,9 @@ static pjsip_uri *create_uri18( pj_pool_t *pool );
static pjsip_uri *create_uri19( pj_pool_t *pool );
static pjsip_uri *create_dummy( pj_pool_t *pool );
+#define ERR_NOT_EQUAL -1001
+#define ERR_SYNTAX_ERR -1002
+
struct uri_test
{
pj_status_t status;
@@ -239,12 +224,7 @@ struct uri_test
ERR_SYNTAX_ERR,
"",
&create_dummy,
- },
- {
- PJ_SUCCESS,
- "",
- NULL,
- },
+ }
};
static pjsip_uri *create_uri1(pj_pool_t *pool)
@@ -476,47 +456,37 @@ static pjsip_uri *create_uri18(pj_pool_t *pool)
static pjsip_uri *create_dummy(pj_pool_t *pool)
{
- PJ_UNUSED_ARG(pool)
+ PJ_UNUSED_ARG(pool);
return NULL;
}
/*****************************************************************************/
-static void pool_error(pj_pool_t *pool, pj_size_t sz)
-{
- PJ_UNUSED_ARG(pool)
- PJ_UNUSED_ARG(sz)
-
- pj_assert(0);
- exit(1);
-}
-
/*
* Test one test entry.
*/
-static pj_status_t test_entry(struct uri_test *entry)
+static pj_status_t do_uri_test(pj_pool_t *pool, struct uri_test *entry)
{
pj_status_t status;
- pj_pool_t *pool;
int len;
pjsip_uri *parsed_uri, *ref_uri;
pj_str_t s1 = {NULL, 0}, s2 = {NULL, 0};
- pj_hr_timestamp t1, t2;
+ pj_timestamp t1, t2;
- pool = (*cp.factory.create_pool)( &cp.factory, "", POOL_SIZE, 0, &pool_error);
+ entry->len = pj_native_strlen(entry->str);
/* Parse URI text. */
- pj_hr_gettimestamp(&t1);
+ pj_get_timestamp(&t1);
parse_len += entry->len;
parsed_uri = pjsip_parse_uri(pool, entry->str, entry->len, 0);
if (!parsed_uri) {
/* Parsing failed. If the entry says that this is expected, then
* return OK.
*/
- status = entry->status==ERR_SYNTAX_ERR ? PJ_SUCCESS : ERR_SYNTAX_ERR;
+ status = entry->status==ERR_SYNTAX_ERR ? PJ_SUCCESS : -10;
goto on_return;
}
- pj_hr_gettimestamp(&t2);
+ pj_get_timestamp(&t2);
parse_time += t2.u32.lo - t1.u32.lo;
/* Create the reference URI. */
@@ -526,32 +496,32 @@ static pj_status_t test_entry(struct uri_test *entry)
s1.ptr = pj_pool_alloc(pool, PJSIP_MAX_URL_SIZE);
s2.ptr = pj_pool_alloc(pool, PJSIP_MAX_URL_SIZE);
- pj_hr_gettimestamp(&t1);
+ pj_get_timestamp(&t1);
len = pjsip_uri_print( PJSIP_URI_IN_OTHER, parsed_uri, s1.ptr, PJSIP_MAX_URL_SIZE);
if (len < 1) {
- status = -1;
+ status = -20;
goto on_return;
}
s1.slen = len;
len = pjsip_uri_print( PJSIP_URI_IN_OTHER, ref_uri, s2.ptr, PJSIP_MAX_URL_SIZE);
if (len < 1) {
- status = -1;
+ status = -30;
goto on_return;
}
s2.slen = len;
- pj_hr_gettimestamp(&t2);
+ pj_get_timestamp(&t2);
print_time += t2.u32.lo - t1.u32.lo;
/* Full comparison of parsed URI with reference URI. */
if (pjsip_uri_cmp(PJSIP_URI_IN_OTHER, parsed_uri, ref_uri) != 0) {
/* Not equal. See if this is the expected status. */
- status = entry->status==ERR_NOT_EQUAL ? PJ_SUCCESS : ERR_NOT_EQUAL;
+ status = entry->status==ERR_NOT_EQUAL ? PJ_SUCCESS : -40;
goto on_return;
} else {
/* Equal. See if this is the expected status. */
- status = entry->status==PJ_SUCCESS ? PJ_SUCCESS : -1;
+ status = entry->status==PJ_SUCCESS ? PJ_SUCCESS : -50;
if (status != PJ_SUCCESS) {
goto on_return;
}
@@ -560,101 +530,31 @@ static pj_status_t test_entry(struct uri_test *entry)
/* Compare text. */
if (pj_strcmp(&s1, &s2) != 0) {
/* Not equal. */
- status = ERR_NOT_EQUAL;
+ status = -60;
}
on_return:
- if (!SILENT) {
- printf("%.2d %s (expected status=%s)\n"
- " str=%s\n"
- " uri=%.*s\n"
- " ref=%.*s\n\n",
- entry-uri_test_array,
- STATUS_STR(status),
- STATUS_STR(entry->status),
- entry->str,
- (int)s1.slen, s1.ptr, (int)s2.slen, s2.ptr);
- }
-
- pj_pool_release(pool);
return status;
}
-static void warm_up(pj_pool_factory *pf)
+pj_status_t uri_test()
{
+ unsigned i;
pj_pool_t *pool;
- struct uri_test *entry;
-
- pool = pj_pool_create(pf, "", POOL_SIZE, 0, &pool_error);
- pjsip_parse_uri(pool, "sip:host", 8, 0);
- entry = &uri_test_array[0];
- while (entry->creator) {
- entry->len = strlen(entry->str);
- ++entry;
- }
- pj_pool_release(pool);
-}
-
-//#if !IS_PROFILING
-#if 1
-pj_status_t test_uri()
-{
- struct uri_test *entry;
- int i=0, err=0;
pj_status_t status;
- pj_hr_timestamp t1, t2;
- pj_uint32_t total_time;
-
- pj_caching_pool_init(&cp, &pj_pool_factory_default_policy, 0);
- warm_up(&cp.factory);
-
- pj_hr_gettimestamp(&t1);
- for (i=0; i<LOOP; ++i) {
- entry = &uri_test_array[0];
- while (entry->creator) {
- status = test_entry(entry);
- if (status != PJ_SUCCESS) {
- ++err;
- }
- ++entry;
- }
- }
- pj_hr_gettimestamp(&t2);
- total_time = t2.u32.lo - t1.u32.lo;
-
- printf("Error=%d\n", err);
- printf("Total parse len: %u bytes\n", parse_len);
- printf("Total parse time: %u (%f/char), print time: %u (%f/char)\n",
- parse_time, parse_time*1.0/parse_len,
- print_time, print_time*1.0/parse_len);
- printf("Total time: %u (%f/char)\n", total_time, total_time*1.0/parse_len);
- return err;
-}
-
-#else
-
-pj_status_t test_uri()
-{
- struct uri_test *entry;
- unsigned i;
-
- warm_up();
- pj_caching_pool_init(&cp, 1024*1024);
- for (i=0; i<LOOP; ++i) {
- entry = &uri_test_array[0];
- while (entry->creator) {
- pj_pool_t *pool;
- pjsip_uri *uri1, *uri2;
+ pool = pjsip_endpt_create_pool(endpt, "", 4000, 4000);
- pool = pj_pool_create( &cp.factory, "", POOL_SIZE, 0, &pool_error);
- uri1 = pjsip_parse_uri(pool, entry->str, strlen(entry->str));
- pj_pool_release(pool);
- ++entry;
+ for (i=0; i<PJ_ARRAY_SIZE(uri_test_array); ++i) {
+ status = do_uri_test(pool, &uri_test_array[i]);
+ if (status != PJ_SUCCESS) {
+ PJ_LOG(3,("uri_test", " error %d when testing entry %d",
+ status, i));
+ break;
}
}
- return 0;
+ pjsip_endpt_destroy_pool(endpt, pool);
+ return status;
}
-#endif