blob: c647764c13abfee72d5e1bede8f4d25a3f83063d [file] [log] [blame]
Alexandre Lision94f06ba2013-12-09 16:28:33 -05001/* $Id$ */
Tristan Matthews0a329cc2013-07-17 13:20:14 -04002/*
3 * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
4 * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20#include "test.h"
21#include <pjsip.h>
22#include <pjlib.h>
23
24#define THIS_FILE "uri_test.c"
25
26
27#define ALPHANUM "abcdefghijklmnopqrstuvwxyz" \
28 "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \
29 "0123456789"
30#define MARK "-_.!~*'()"
31#define USER_CHAR ALPHANUM MARK "&=+$,;?/"
32#define PASS_CHAR ALPHANUM MARK "&=+$,"
33#define PARAM_CHAR ALPHANUM MARK "[]/:&+$"
34
35#define POOL_SIZE 8000
36#if defined(PJ_DEBUG) && PJ_DEBUG!=0
37# define LOOP_COUNT 10000
38#else
39# define LOOP_COUNT 40000
40#endif
41#define AVERAGE_URL_LEN 80
42#define THREAD_COUNT 4
43
44static struct
45{
46 pj_highprec_t parse_len, print_len, cmp_len;
47 pj_timestamp parse_time, print_time, cmp_time;
48} var;
49
50
51/* URI creator functions. */
52static pjsip_uri *create_uri0( pj_pool_t *pool );
53static pjsip_uri *create_uri1( pj_pool_t *pool );
54static pjsip_uri *create_uri2( pj_pool_t *pool );
55static pjsip_uri *create_uri3( pj_pool_t *pool );
56static pjsip_uri *create_uri4( pj_pool_t *pool );
57static pjsip_uri *create_uri5( pj_pool_t *pool );
58static pjsip_uri *create_uri6( pj_pool_t *pool );
59static pjsip_uri *create_uri7( pj_pool_t *pool );
60static pjsip_uri *create_uri8( pj_pool_t *pool );
61static pjsip_uri *create_uri9( pj_pool_t *pool );
62static pjsip_uri *create_uri10( pj_pool_t *pool );
63static pjsip_uri *create_uri11( pj_pool_t *pool );
64static pjsip_uri *create_uri12( pj_pool_t *pool );
65static pjsip_uri *create_uri13( pj_pool_t *pool );
66static pjsip_uri *create_uri14( pj_pool_t *pool );
67static pjsip_uri *create_uri15( pj_pool_t *pool );
68static pjsip_uri *create_uri16( pj_pool_t *pool );
69static pjsip_uri *create_uri17( pj_pool_t *pool );
70static pjsip_uri *create_uri18( pj_pool_t *pool );
71static pjsip_uri *create_uri25( pj_pool_t *pool );
72static pjsip_uri *create_uri26( pj_pool_t *pool );
73static pjsip_uri *create_uri27( pj_pool_t *pool );
74static pjsip_uri *create_uri28( pj_pool_t *pool );
75static pjsip_uri *create_uri29( pj_pool_t *pool );
76static pjsip_uri *create_uri30( pj_pool_t *pool );
77static pjsip_uri *create_uri31( pj_pool_t *pool );
78static pjsip_uri *create_uri32( pj_pool_t *pool );
79static pjsip_uri *create_uri33( pj_pool_t *pool );
80static pjsip_uri *create_uri34( pj_pool_t *pool );
81static pjsip_uri *create_uri35( pj_pool_t *pool );
82static pjsip_uri *create_uri36( pj_pool_t *pool );
83static pjsip_uri *create_uri37( pj_pool_t *pool );
84static pjsip_uri *create_uri38( pj_pool_t *pool );
85static pjsip_uri *create_uri39( pj_pool_t *pool );
86static pjsip_uri *create_dummy( pj_pool_t *pool );
87
88#define ERR_NOT_EQUAL -1001
89#define ERR_SYNTAX_ERR -1002
90
91struct uri_test
92{
93 pj_status_t status;
94 char str[PJSIP_MAX_URL_SIZE];
95 pjsip_uri *(*creator)(pj_pool_t *pool);
96 const char *printed;
97 pj_size_t len;
98} uri_test_array[] =
99{
100 {
101 PJ_SUCCESS,
102 "sip:localhost",
103 &create_uri0
104 },
105 {
106 PJ_SUCCESS,
107 "sip:user@localhost",
108 &create_uri1
109 },
110 {
111 PJ_SUCCESS,
112 "sip:user:password@localhost:5060",
113 &create_uri2, },
114 {
115 /* Port is specified should not match unspecified port. */
116 ERR_NOT_EQUAL,
117 "sip:localhost:5060",
118 &create_uri3
119 },
120 {
121 /* All recognized parameters. */
122 PJ_SUCCESS,
123 "sip:localhost;transport=tcp;user=ip;ttl=255;lr;maddr=127.0.0.1;method=ACK",
124 &create_uri4
125 },
126 {
127 /* Params mixed with other params and header params. */
128 PJ_SUCCESS,
129 "sip:localhost;pickup=hurry;user=phone;message=I%20am%20sorry"
130 "?Subject=Hello%20There&Server=SIP%20Server",
131 &create_uri5
132 },
133 {
134 /* SIPS. */
135 PJ_SUCCESS,
136 "sips:localhost",
137 &create_uri6,
138 },
139 {
140 /* Name address */
141 PJ_SUCCESS,
142 "<sip:localhost>",
143 &create_uri7
144 },
145 {
146 /* Name address with display name and SIPS scheme with some redundant
147 * whitespaced.
148 */
149 PJ_SUCCESS,
150 " Power Administrator <sips:localhost>",
151 &create_uri8
152 },
153 {
154 /* Name address. */
155 PJ_SUCCESS,
156 " \"User\" <sip:user@localhost:5071>",
157 &create_uri9
158 },
159 {
160 /* Escaped sequence in display name (display=Strange User\"\\\"). */
161 PJ_SUCCESS,
162 " \"Strange User\\\"\\\\\\\"\" <sip:localhost>",
163 &create_uri10,
164 },
165 {
166 /* Errorneous escaping in display name. */
167 ERR_SYNTAX_ERR,
168 " \"Rogue User\\\" <sip:localhost>",
169 &create_uri11,
170 },
171 {
172 /* Dangling quote in display name, but that should be OK. */
173 PJ_SUCCESS,
174 "Strange User\" <sip:localhost>",
175 &create_uri12,
176 },
177 {
178 /* Special characters in parameter value must be quoted. */
179 PJ_SUCCESS,
180 "sip:localhost;pvalue=\"hello world\"",
181 &create_uri13,
182 },
183 {
184 /* Excercise strange character sets allowed in display, user, password,
185 * host, and port.
186 */
187 PJ_SUCCESS,
188 "This is -. !% *_+`'~ me <sip:a19A&=+$,;?/%2c:%40a&Zz=+$,@"
189 "my_proxy09.MY-domain.com:9801>",
190 &create_uri14,
191 },
192 {
193 /* Another excercise to the allowed character sets to the hostname. */
194 PJ_SUCCESS,
195 "sip:" ALPHANUM "-_.com",
196 &create_uri15,
197 },
198 {
199 /* Another excercise to the allowed character sets to the username
200 * and password.
201 */
202 PJ_SUCCESS,
203 "sip:" USER_CHAR ":" PASS_CHAR "@host",
204 &create_uri16,
205 },
206 {
207 /* Excercise to the pname and pvalue, and mixup of other-param
208 * between 'recognized' params.
209 */
210 PJ_SUCCESS,
211 "sip:host;user=ip;" PARAM_CHAR "%21=" PARAM_CHAR "%21"
212 ";lr;other=1;transport=sctp;other2",
213 &create_uri17,
214 },
215 {
216 /* 18: This should trigger syntax error. */
217 ERR_SYNTAX_ERR,
218 "sip:",
219 &create_dummy,
220 },
221 {
222 /* 19: Syntax error: whitespace after scheme. */
223 ERR_SYNTAX_ERR,
224 "sip :host",
225 &create_dummy,
226 },
227 {
228 /* 20: Syntax error: whitespace before hostname. */
229 ERR_SYNTAX_ERR,
230 "sip: host",
231 &create_dummy,
232 },
233 {
234 /* 21: Syntax error: invalid port. */
235 ERR_SYNTAX_ERR,
236 "sip:user:password",
237 &create_dummy,
238 },
239 {
240 /* 22: Syntax error: no host. */
241 ERR_SYNTAX_ERR,
242 "sip:user@",
243 &create_dummy,
244 },
245 {
246 /* 23: Syntax error: no user/host. */
247 ERR_SYNTAX_ERR,
248 "sip:@",
249 &create_dummy,
250 },
251 {
252 /* 24: Syntax error: empty string. */
253 ERR_SYNTAX_ERR,
254 "",
255 &create_dummy,
256 },
257 {
258 /* 25: Simple tel: URI with global context */
259 PJ_SUCCESS,
260 "tel:+1-201-555-0123",
261 &create_uri25,
262 "tel:+1-201-555-0123"
263 },
264 {
265 /* 26: Simple tel: URI with local context */
266 PJ_SUCCESS,
267 "tel:7042;phone-context=example.com",
268 &create_uri26,
269 "tel:7042;phone-context=example.com"
270 },
271 {
272 /* 27: Simple tel: URI with local context */
273 PJ_SUCCESS,
274 "tel:863-1234;phone-context=+1-914-555",
275 &create_uri27,
276 "tel:863-1234;phone-context=+1-914-555"
277 },
278 {
279 /* 28: Comparison between local and global number */
280 ERR_NOT_EQUAL,
281 "tel:+1",
282 &create_uri28,
283 "tel:+1"
284 },
285 {
286 /* 29: tel: with some visual chars and spaces */
287 PJ_SUCCESS,
288 "tel:(44).1234-*#+Deaf",
289 &create_uri29,
290 "tel:(44).1234-*#+Deaf"
291 },
292 {
293 /* 30: isub parameters */
294 PJ_SUCCESS,
295 "tel:+1;isub=/:@&$,-_.!~*'()[]/:&$aA1%21+=",
296 &create_uri30,
297 "tel:+1;isub=/:@&$,-_.!~*'()[]/:&$aA1!+%3d"
298 },
299 {
300 /* 31: extension number parsing and encoding */
301 PJ_SUCCESS,
302 "tel:+1;ext=+123",
303 &create_uri31,
304 "tel:+1;ext=%2b123"
305 },
306 {
307 /* 32: context parameter parsing and encoding */
308 PJ_SUCCESS,
309 "tel:911;phone-context=+1-911",
310 &create_uri32,
311 "tel:911;phone-context=+1-911"
312 },
313 {
314 /* 33: case-insensitive comparison */
315 PJ_SUCCESS,
316 "tel:911;phone-context=emergency.example.com",
317 &create_uri33,
318 "tel:911;phone-context=emergency.example.com"
319 },
320 {
321 /* 34: parameter only appears in one URL */
322 ERR_NOT_EQUAL,
323 "tel:911;p1=p1;p2=p2",
324 &create_uri34,
325 "tel:911;p1=p1;p2=p2"
326 },
327 {
328 /* 35: IPv6 in host and maddr parameter */
329 PJ_SUCCESS,
330 "sip:user@[::1];maddr=[::01]",
331 &create_uri35,
332 "sip:user@[::1];maddr=[::01]"
333 },
334 {
335 /* 36: IPv6 in host and maddr, without username */
336 PJ_SUCCESS,
337 "sip:[::1];maddr=[::01]",
338 &create_uri36,
339 "sip:[::1];maddr=[::01]"
340 },
341 {
342 /* 37: Non-ASCII UTF-8 in display name, with quote */
343 PJ_SUCCESS,
344 "\"\xC0\x81\" <sip:localhost>",
345 &create_uri37,
346 "\"\xC0\x81\" <sip:localhost>"
347 },
348 {
349 /* 38: Non-ASCII UTF-8 in display name, without quote */
350 PJ_SUCCESS,
351 "\xC0\x81 <sip:localhost>",
352 &create_uri38,
353 "\"\xC0\x81\" <sip:localhost>"
354 },
355 {
356 /* Even number of backslash before end quote in display name. */
357 PJ_SUCCESS,
358 "\"User\\\\\" <sip:localhost>",
359 &create_uri39,
360 }
361
362};
363
364static pjsip_uri *create_uri0(pj_pool_t *pool)
365{
366 /* "sip:localhost" */
367 pjsip_sip_uri *url = pjsip_sip_uri_create(pool, 0);
368
369 pj_strdup2(pool, &url->host, "localhost");
370 return (pjsip_uri*)url;
371}
372
373static pjsip_uri *create_uri1(pj_pool_t *pool)
374{
375 /* "sip:user@localhost" */
376 pjsip_sip_uri *url = pjsip_sip_uri_create(pool, 0);
377
378 pj_strdup2( pool, &url->user, "user");
379 pj_strdup2( pool, &url->host, "localhost");
380
381 return (pjsip_uri*) url;
382}
383
384static pjsip_uri *create_uri2(pj_pool_t *pool)
385{
386 /* "sip:user:password@localhost:5060" */
387 pjsip_sip_uri *url = pjsip_sip_uri_create(pool, 0);
388
389 pj_strdup2( pool, &url->user, "user");
390 pj_strdup2( pool, &url->passwd, "password");
391 pj_strdup2( pool, &url->host, "localhost");
392 url->port = 5060;
393
394 return (pjsip_uri*) url;
395}
396
397static pjsip_uri *create_uri3(pj_pool_t *pool)
398{
399 /* Like: "sip:localhost:5060", but without the port. */
400 pjsip_sip_uri *url = pjsip_sip_uri_create(pool, 0);
401
402 pj_strdup2(pool, &url->host, "localhost");
403 return (pjsip_uri*)url;
404}
405
406static pjsip_uri *create_uri4(pj_pool_t *pool)
407{
408 /* "sip:localhost;transport=tcp;user=ip;ttl=255;lr;maddr=127.0.0.1;method=ACK" */
409 pjsip_sip_uri *url = pjsip_sip_uri_create(pool, 0);
410
411 pj_strdup2(pool, &url->host, "localhost");
412 pj_strdup2(pool, &url->transport_param, "tcp");
413 pj_strdup2(pool, &url->user_param, "ip");
414 url->ttl_param = 255;
415 url->lr_param = 1;
416 pj_strdup2(pool, &url->maddr_param, "127.0.0.1");
417 pj_strdup2(pool, &url->method_param, "ACK");
418
419 return (pjsip_uri*)url;
420}
421
422#define param_add(list,pname,pvalue) \
423 do { \
424 pjsip_param *param; \
425 param=PJ_POOL_ALLOC_T(pool, pjsip_param); \
426 param->name = pj_str(pname); \
427 param->value = pj_str(pvalue); \
428 pj_list_insert_before(&list, param); \
429 } while (0)
430
431static pjsip_uri *create_uri5(pj_pool_t *pool)
432{
433 /* "sip:localhost;pickup=hurry;user=phone;message=I%20am%20sorry"
434 "?Subject=Hello%20There&Server=SIP%20Server"
435 */
436 pjsip_sip_uri *url = pjsip_sip_uri_create(pool, 0);
437
438 pj_strdup2(pool, &url->host, "localhost");
439 pj_strdup2(pool, &url->user_param, "phone");
440
441 //pj_strdup2(pool, &url->other_param, ";pickup=hurry;message=I%20am%20sorry");
442 param_add(url->other_param, "pickup", "hurry");
443 param_add(url->other_param, "message", "I am sorry");
444
445 //pj_strdup2(pool, &url->header_param, "?Subject=Hello%20There&Server=SIP%20Server");
446 param_add(url->header_param, "Subject", "Hello There");
447 param_add(url->header_param, "Server", "SIP Server");
448 return (pjsip_uri*)url;
449
450}
451
452static pjsip_uri *create_uri6(pj_pool_t *pool)
453{
454 /* "sips:localhost" */
455 pjsip_sip_uri *url = pjsip_sip_uri_create(pool, 1);
456
457 pj_strdup2(pool, &url->host, "localhost");
458 return (pjsip_uri*)url;
459}
460
461static pjsip_uri *create_uri7(pj_pool_t *pool)
462{
463 /* "<sip:localhost>" */
464 pjsip_name_addr *name_addr = pjsip_name_addr_create(pool);
465 pjsip_sip_uri *url;
466
467 url = pjsip_sip_uri_create(pool, 0);
468 name_addr->uri = (pjsip_uri*) url;
469
470 pj_strdup2(pool, &url->host, "localhost");
471 return (pjsip_uri*)name_addr;
472}
473
474static pjsip_uri *create_uri8(pj_pool_t *pool)
475{
476 /* " Power Administrator <sips:localhost>" */
477 pjsip_name_addr *name_addr = pjsip_name_addr_create(pool);
478 pjsip_sip_uri *url;
479
480 url = pjsip_sip_uri_create(pool, 1);
481 name_addr->uri = (pjsip_uri*) url;
482
483 pj_strdup2(pool, &name_addr->display, "Power Administrator");
484 pj_strdup2(pool, &url->host, "localhost");
485 return (pjsip_uri*)name_addr;
486}
487
488static pjsip_uri *create_uri9(pj_pool_t *pool)
489{
490 /* " \"User\" <sip:user@localhost:5071>" */
491 pjsip_name_addr *name_addr = pjsip_name_addr_create(pool);
492 pjsip_sip_uri *url;
493
494 url = pjsip_sip_uri_create(pool, 0);
495 name_addr->uri = (pjsip_uri*) url;
496
497 pj_strdup2(pool, &name_addr->display, "User");
498 pj_strdup2(pool, &url->user, "user");
499 pj_strdup2(pool, &url->host, "localhost");
500 url->port = 5071;
501 return (pjsip_uri*)name_addr;
502}
503
504static pjsip_uri *create_uri10(pj_pool_t *pool)
505{
506 /* " \"Strange User\\\"\\\\\\\"\" <sip:localhost>" */
507 pjsip_name_addr *name_addr = pjsip_name_addr_create(pool);
508 pjsip_sip_uri *url;
509
510 url = pjsip_sip_uri_create(pool, 0);
511 name_addr->uri = (pjsip_uri*) url;
512
513 pj_strdup2(pool, &name_addr->display, "Strange User\\\"\\\\\\\"");
514 pj_strdup2(pool, &url->host, "localhost");
515 return (pjsip_uri*)name_addr;
516}
517
518static pjsip_uri *create_uri11(pj_pool_t *pool)
519{
520 /* " \"Rogue User\\\" <sip:localhost>" */
521 pjsip_name_addr *name_addr = pjsip_name_addr_create(pool);
522 pjsip_sip_uri *url;
523
524 url = pjsip_sip_uri_create(pool, 0);
525 name_addr->uri = (pjsip_uri*) url;
526
527 pj_strdup2(pool, &name_addr->display, "Rogue User\\");
528 pj_strdup2(pool, &url->host, "localhost");
529 return (pjsip_uri*)name_addr;
530}
531
532static pjsip_uri *create_uri12(pj_pool_t *pool)
533{
534 /* "Strange User\" <sip:localhost>" */
535 pjsip_name_addr *name_addr = pjsip_name_addr_create(pool);
536 pjsip_sip_uri *url;
537
538 url = pjsip_sip_uri_create(pool, 0);
539 name_addr->uri = (pjsip_uri*) url;
540
541 pj_strdup2(pool, &name_addr->display, "Strange User\"");
542 pj_strdup2(pool, &url->host, "localhost");
543 return (pjsip_uri*)name_addr;
544}
545
546static pjsip_uri *create_uri13(pj_pool_t *pool)
547{
548 /* "sip:localhost;pvalue=\"hello world\"" */
549 pjsip_sip_uri *url;
550 url = pjsip_sip_uri_create(pool, 0);
551 pj_strdup2(pool, &url->host, "localhost");
552 //pj_strdup2(pool, &url->other_param, ";pvalue=\"hello world\"");
553 param_add(url->other_param, "pvalue", "\"hello world\"");
554 return (pjsip_uri*)url;
555}
556
557static pjsip_uri *create_uri14(pj_pool_t *pool)
558{
559 /* "This is -. !% *_+`'~ me <sip:a19A&=+$,;?/%2c:%40a&Zz=+$,@my_proxy09.my-domain.com:9801>" */
560 pjsip_name_addr *name_addr = pjsip_name_addr_create(pool);
561 pjsip_sip_uri *url;
562
563 url = pjsip_sip_uri_create(pool, 0);
564 name_addr->uri = (pjsip_uri*) url;
565
566 pj_strdup2(pool, &name_addr->display, "This is -. !% *_+`'~ me");
567 pj_strdup2(pool, &url->user, "a19A&=+$,;?/,");
568 pj_strdup2(pool, &url->passwd, "@a&Zz=+$,");
569 pj_strdup2(pool, &url->host, "my_proxy09.MY-domain.com");
570 url->port = 9801;
571 return (pjsip_uri*)name_addr;
572}
573
574static pjsip_uri *create_uri15(pj_pool_t *pool)
575{
576 /* "sip:abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.com" */
577 pjsip_sip_uri *url;
578 url = pjsip_sip_uri_create(pool, 0);
579 pj_strdup2(pool, &url->host, ALPHANUM "-_.com");
580 return (pjsip_uri*)url;
581}
582
583static pjsip_uri *create_uri16(pj_pool_t *pool)
584{
585 /* "sip:" USER_CHAR ":" PASS_CHAR "@host" */
586 pjsip_sip_uri *url;
587 url = pjsip_sip_uri_create(pool, 0);
588 pj_strdup2(pool, &url->user, USER_CHAR);
589 pj_strdup2(pool, &url->passwd, PASS_CHAR);
590 pj_strdup2(pool, &url->host, "host");
591 return (pjsip_uri*)url;
592}
593
594static pjsip_uri *create_uri17(pj_pool_t *pool)
595{
596 /* "sip:host;user=ip;" PARAM_CHAR "%21=" PARAM_CHAR "%21;lr;other=1;transport=sctp;other2" */
597 pjsip_sip_uri *url;
598 url = pjsip_sip_uri_create(pool, 0);
599 pj_strdup2(pool, &url->host, "host");
600 pj_strdup2(pool, &url->user_param, "ip");
601 pj_strdup2(pool, &url->transport_param, "sctp");
602 param_add(url->other_param, PARAM_CHAR "!", PARAM_CHAR "!");
603 param_add(url->other_param, "other", "1");
604 param_add(url->other_param, "other2", "");
605 url->lr_param = 1;
606 return (pjsip_uri*)url;
607}
608
609
610static pjsip_uri *create_uri25(pj_pool_t *pool)
611{
612 /* "tel:+1-201-555-0123" */
613 pjsip_tel_uri *uri = pjsip_tel_uri_create(pool);
614
615 uri->number = pj_str("+1-201-555-0123");
616 return (pjsip_uri*)uri;
617}
618
619static pjsip_uri *create_uri26(pj_pool_t *pool)
620{
621 /* tel:7042;phone-context=example.com */
622 pjsip_tel_uri *uri = pjsip_tel_uri_create(pool);
623
624 uri->number = pj_str("7042");
625 uri->context = pj_str("example.com");
626 return (pjsip_uri*)uri;
627}
628
629static pjsip_uri *create_uri27(pj_pool_t *pool)
630{
631 /* "tel:863-1234;phone-context=+1-914-555" */
632 pjsip_tel_uri *uri = pjsip_tel_uri_create(pool);
633
634 uri->number = pj_str("863-1234");
635 uri->context = pj_str("+1-914-555");
636 return (pjsip_uri*)uri;
637}
638
639/* "tel:1" */
640static pjsip_uri *create_uri28(pj_pool_t *pool)
641{
642 pjsip_tel_uri *uri = pjsip_tel_uri_create(pool);
643
644 uri->number = pj_str("1");
645 return (pjsip_uri*)uri;
646}
647
648/* "tel:(44).1234-*#+Deaf" */
649static pjsip_uri *create_uri29(pj_pool_t *pool)
650{
651 pjsip_tel_uri *uri = pjsip_tel_uri_create(pool);
652
653 uri->number = pj_str("(44).1234-*#+Deaf");
654 return (pjsip_uri*)uri;
655}
656
657/* "tel:+1;isub=/:@&$,-_.!~*'()[]/:&$aA1%21+=" */
658static pjsip_uri *create_uri30(pj_pool_t *pool)
659{
660 pjsip_tel_uri *uri = pjsip_tel_uri_create(pool);
661
662 uri->number = pj_str("+1");
663 uri->isub_param = pj_str("/:@&$,-_.!~*'()[]/:&$aA1!+=");
664 return (pjsip_uri*)uri;
665}
666
667/* "tel:+1;ext=+123" */
668static pjsip_uri *create_uri31(pj_pool_t *pool)
669{
670 pjsip_tel_uri *uri = pjsip_tel_uri_create(pool);
671
672 uri->number = pj_str("+1");
673 uri->ext_param = pj_str("+123");
674 return (pjsip_uri*)uri;
675}
676
677/* "tel:911;phone-context=+1-911" */
678static pjsip_uri *create_uri32(pj_pool_t *pool)
679{
680 pjsip_tel_uri *uri = pjsip_tel_uri_create(pool);
681
682 uri->number = pj_str("911");
683 uri->context = pj_str("+1-911");
684 return (pjsip_uri*)uri;
685}
686
687/* "tel:911;phone-context=emergency.example.com" */
688static pjsip_uri *create_uri33(pj_pool_t *pool)
689{
690 pjsip_tel_uri *uri = pjsip_tel_uri_create(pool);
691
692 uri->number = pj_str("911");
693 uri->context = pj_str("EMERGENCY.EXAMPLE.COM");
694 return (pjsip_uri*)uri;
695}
696
697/* "tel:911;p1=p1;p2=p2" */
698static pjsip_uri *create_uri34(pj_pool_t *pool)
699{
700 pjsip_tel_uri *uri = pjsip_tel_uri_create(pool);
701 pjsip_param *p;
702
703 uri->number = pj_str("911");
704
705 p = PJ_POOL_ALLOC_T(pool, pjsip_param);
706 p->name = p->value = pj_str("p1");
707 pj_list_insert_before(&uri->other_param, p);
708
709 return (pjsip_uri*)uri;
710}
711
712/* "sip:user@[::1];maddr=[::01]" */
713static pjsip_uri *create_uri35( pj_pool_t *pool )
714{
715 pjsip_sip_uri *url;
716 url = pjsip_sip_uri_create(pool, 0);
717 url->user = pj_str("user");
718 url->host = pj_str("::1");
719 url->maddr_param = pj_str("::01");
720 return (pjsip_uri*)url;
721}
722
723/* "sip:[::1];maddr=[::01]" */
724static pjsip_uri *create_uri36( pj_pool_t *pool )
725{
726 pjsip_sip_uri *url;
727 url = pjsip_sip_uri_create(pool, 0);
728 url->host = pj_str("::1");
729 url->maddr_param = pj_str("::01");
730 return (pjsip_uri*)url;
731
732}
733
734/* "\"\xC0\x81\" <sip:localhost>" */
735static pjsip_uri *create_uri37( pj_pool_t *pool )
736{
737 pjsip_name_addr *name;
738 pjsip_sip_uri *url;
739
740 name = pjsip_name_addr_create(pool);
741 name->display = pj_str("\xC0\x81");
742
743 url = pjsip_sip_uri_create(pool, 0);
744 url->host = pj_str("localhost");
745
746 name->uri = (pjsip_uri*)url;
747
748 return (pjsip_uri*)name;
749
750}
751
752/* "\xC0\x81 <sip:localhost>" */
753static pjsip_uri *create_uri38( pj_pool_t *pool )
754{
755 pjsip_name_addr *name;
756 pjsip_sip_uri *url;
757
758 name = pjsip_name_addr_create(pool);
759 name->display = pj_str("\xC0\x81");
760
761 url = pjsip_sip_uri_create(pool, 0);
762 url->host = pj_str("localhost");
763
764 name->uri = (pjsip_uri*)url;
765
766 return (pjsip_uri*)name;
767
768}
769
770/* "\"User\\\\\" <sip:localhost>" */
771static pjsip_uri *create_uri39(pj_pool_t *pool)
772{
773 pjsip_name_addr *name_addr = pjsip_name_addr_create(pool);
774 pjsip_sip_uri *url;
775
776 url = pjsip_sip_uri_create(pool, 0);
777 name_addr->uri = (pjsip_uri*) url;
778
779 pj_strdup2(pool, &name_addr->display, "User\\\\");
780 pj_strdup2(pool, &url->host, "localhost");
781 return (pjsip_uri*)name_addr;
782}
783
784static pjsip_uri *create_dummy(pj_pool_t *pool)
785{
786 PJ_UNUSED_ARG(pool);
787 return NULL;
788}
789
790/*****************************************************************************/
791
792/*
793 * Test one test entry.
794 */
795static pj_status_t do_uri_test(pj_pool_t *pool, struct uri_test *entry)
796{
797 pj_status_t status;
798 int len;
799 char *input;
800 pjsip_uri *parsed_uri, *ref_uri;
801 pj_str_t s1 = {NULL, 0}, s2 = {NULL, 0};
802 pj_timestamp t1, t2;
803
804 if (entry->len == 0)
805 entry->len = pj_ansi_strlen(entry->str);
806
807#if defined(PJSIP_UNESCAPE_IN_PLACE) && PJSIP_UNESCAPE_IN_PLACE!=0
808 input = pj_pool_alloc(pool, entry->len + 1);
809 pj_memcpy(input, entry->str, entry->len);
810 input[entry->len] = '\0';
811#else
812 input = entry->str;
813#endif
814
815 /* Parse URI text. */
816 pj_get_timestamp(&t1);
817 var.parse_len = var.parse_len + entry->len;
818 parsed_uri = pjsip_parse_uri(pool, input, entry->len, 0);
819 if (!parsed_uri) {
820 /* Parsing failed. If the entry says that this is expected, then
821 * return OK.
822 */
823 status = entry->status==ERR_SYNTAX_ERR ? PJ_SUCCESS : -10;
824 if (status != 0) {
825 PJ_LOG(3,(THIS_FILE, " uri parse error!\n"
826 " uri='%s'\n",
827 input));
828 }
829 goto on_return;
830 }
831 pj_get_timestamp(&t2);
832 pj_sub_timestamp(&t2, &t1);
833 pj_add_timestamp(&var.parse_time, &t2);
834
835 /* Create the reference URI. */
836 ref_uri = entry->creator(pool);
837
838 /* Print both URI. */
839 s1.ptr = (char*) pj_pool_alloc(pool, PJSIP_MAX_URL_SIZE);
840 s2.ptr = (char*) pj_pool_alloc(pool, PJSIP_MAX_URL_SIZE);
841
842 pj_get_timestamp(&t1);
843 len = pjsip_uri_print( PJSIP_URI_IN_OTHER, parsed_uri, s1.ptr, PJSIP_MAX_URL_SIZE);
844 if (len < 1) {
845 status = -20;
846 goto on_return;
847 }
848 s1.ptr[len] = '\0';
849 s1.slen = len;
850
851 var.print_len = var.print_len + len;
852 pj_get_timestamp(&t2);
853 pj_sub_timestamp(&t2, &t1);
854 pj_add_timestamp(&var.print_time, &t2);
855
856 len = pjsip_uri_print( PJSIP_URI_IN_OTHER, ref_uri, s2.ptr, PJSIP_MAX_URL_SIZE);
857 if (len < 1) {
858 status = -30;
859 goto on_return;
860 }
861 s2.ptr[len] = '\0';
862 s2.slen = len;
863
864 /* Full comparison of parsed URI with reference URI. */
865 pj_get_timestamp(&t1);
866 status = pjsip_uri_cmp(PJSIP_URI_IN_OTHER, parsed_uri, ref_uri);
867 if (status != 0) {
868 /* Not equal. See if this is the expected status. */
869 status = entry->status==ERR_NOT_EQUAL ? PJ_SUCCESS : -40;
870 if (status != 0) {
871 PJ_LOG(3,(THIS_FILE, " uri comparison mismatch, status=%d:\n"
872 " uri1='%s'\n"
873 " uri2='%s'",
874 status, s1.ptr, s2.ptr));
875 }
876 goto on_return;
877
878 } else {
879 /* Equal. See if this is the expected status. */
880 status = entry->status==PJ_SUCCESS ? PJ_SUCCESS : -50;
881 if (status != PJ_SUCCESS) {
882 goto on_return;
883 }
884 }
885
886 var.cmp_len = var.cmp_len + len;
887 pj_get_timestamp(&t2);
888 pj_sub_timestamp(&t2, &t1);
889 pj_add_timestamp(&var.cmp_time, &t2);
890
891 /* Compare text. */
892 if (entry->printed) {
893 if (pj_strcmp2(&s1, entry->printed) != 0) {
894 /* Not equal. */
895 PJ_LOG(3,(THIS_FILE, " uri print mismatch:\n"
896 " printed='%s'\n"
897 " expectd='%s'",
898 s1.ptr, entry->printed));
899 status = -60;
900 }
901 } else {
902 if (pj_strcmp(&s1, &s2) != 0) {
903 /* Not equal. */
904 PJ_LOG(3,(THIS_FILE, " uri print mismatch:\n"
905 " uri1='%s'\n"
906 " uri2='%s'",
907 s1.ptr, s2.ptr));
908 status = -70;
909 }
910 }
911
912on_return:
913 return status;
914}
915
916
917static int simple_uri_test(void)
918{
919 unsigned i;
920 pj_pool_t *pool;
921 pj_status_t status;
922
923 PJ_LOG(3,(THIS_FILE, " simple test"));
924 for (i=0; i<PJ_ARRAY_SIZE(uri_test_array); ++i) {
925 pool = pjsip_endpt_create_pool(endpt, "", POOL_SIZE, POOL_SIZE);
926 status = do_uri_test(pool, &uri_test_array[i]);
927 pjsip_endpt_release_pool(endpt, pool);
928 if (status != PJ_SUCCESS) {
929 PJ_LOG(3,(THIS_FILE, " error %d when testing entry %d",
930 status, i));
931 return status;
932 }
933 }
934
935 return 0;
936}
937
938#if INCLUDE_BENCHMARKS
939static int uri_benchmark(unsigned *p_parse, unsigned *p_print, unsigned *p_cmp)
940{
941 unsigned i, loop;
942 pj_status_t status = PJ_SUCCESS;
943 pj_timestamp zero;
944 pj_time_val elapsed;
945 pj_highprec_t avg_parse, avg_print, avg_cmp, kbytes;
946
947 pj_bzero(&var, sizeof(var));
948
949 zero.u32.hi = zero.u32.lo = 0;
950
951 var.parse_len = var.print_len = var.cmp_len = 0;
952 var.parse_time.u32.hi = var.parse_time.u32.lo = 0;
953 var.print_time.u32.hi = var.print_time.u32.lo = 0;
954 var.cmp_time.u32.hi = var.cmp_time.u32.lo = 0;
955 for (loop=0; loop<LOOP_COUNT; ++loop) {
956 for (i=0; i<PJ_ARRAY_SIZE(uri_test_array); ++i) {
957 pj_pool_t *pool;
958 pool = pjsip_endpt_create_pool(endpt, "", POOL_SIZE, POOL_SIZE);
959 status = do_uri_test(pool, &uri_test_array[i]);
960 pjsip_endpt_release_pool(endpt, pool);
961 if (status != PJ_SUCCESS) {
962 PJ_LOG(3,(THIS_FILE, " error %d when testing entry %d",
963 status, i));
964 pjsip_endpt_release_pool(endpt, pool);
965 goto on_return;
966 }
967 }
968 }
969
970 kbytes = var.parse_len;
971 pj_highprec_mod(kbytes, 1000000);
972 pj_highprec_div(kbytes, 100000);
973 elapsed = pj_elapsed_time(&zero, &var.parse_time);
974 avg_parse = pj_elapsed_usec(&zero, &var.parse_time);
975 pj_highprec_mul(avg_parse, AVERAGE_URL_LEN);
976 pj_highprec_div(avg_parse, var.parse_len);
977 if (avg_parse == 0)
978 avg_parse = 1;
979 avg_parse = 1000000 / avg_parse;
980
981 PJ_LOG(3,(THIS_FILE,
982 " %u.%u MB of urls parsed in %d.%03ds (avg=%d urls/sec)",
983 (unsigned)(var.parse_len/1000000), (unsigned)kbytes,
984 elapsed.sec, elapsed.msec,
985 (unsigned)avg_parse));
986
987 *p_parse = (unsigned)avg_parse;
988
989 kbytes = var.print_len;
990 pj_highprec_mod(kbytes, 1000000);
991 pj_highprec_div(kbytes, 100000);
992 elapsed = pj_elapsed_time(&zero, &var.print_time);
993 avg_print = pj_elapsed_usec(&zero, &var.print_time);
994 pj_highprec_mul(avg_print, AVERAGE_URL_LEN);
995 pj_highprec_div(avg_print, var.parse_len);
996 if (avg_print == 0)
997 avg_print = 1;
998 avg_print = 1000000 / avg_print;
999
1000 PJ_LOG(3,(THIS_FILE,
1001 " %u.%u MB of urls printed in %d.%03ds (avg=%d urls/sec)",
1002 (unsigned)(var.print_len/1000000), (unsigned)kbytes,
1003 elapsed.sec, elapsed.msec,
1004 (unsigned)avg_print));
1005
1006 *p_print = (unsigned)avg_print;
1007
1008 kbytes = var.cmp_len;
1009 pj_highprec_mod(kbytes, 1000000);
1010 pj_highprec_div(kbytes, 100000);
1011 elapsed = pj_elapsed_time(&zero, &var.cmp_time);
1012 avg_cmp = pj_elapsed_usec(&zero, &var.cmp_time);
1013 pj_highprec_mul(avg_cmp, AVERAGE_URL_LEN);
1014 pj_highprec_div(avg_cmp, var.cmp_len);
1015 if (avg_cmp == 0)
1016 avg_cmp = 1;
1017 avg_cmp = 1000000 / avg_cmp;
1018
1019 PJ_LOG(3,(THIS_FILE,
1020 " %u.%u MB of urls compared in %d.%03ds (avg=%d urls/sec)",
1021 (unsigned)(var.cmp_len/1000000), (unsigned)kbytes,
1022 elapsed.sec, elapsed.msec,
1023 (unsigned)avg_cmp));
1024
1025 *p_cmp = (unsigned)avg_cmp;
1026
1027on_return:
1028 return status;
1029}
1030#endif /* INCLUDE_BENCHMARKS */
1031
1032/*****************************************************************************/
1033
1034int uri_test(void)
1035{
1036 enum { COUNT = 1, DETECT=0, PARSE=1, PRINT=2 };
1037 struct {
1038 unsigned parse;
1039 unsigned print;
1040 unsigned cmp;
1041 } run[COUNT];
1042 unsigned i, max;
1043 pj_ssize_t avg_len;
1044 char desc[200];
1045 pj_status_t status;
1046
1047 status = simple_uri_test();
1048 if (status != PJ_SUCCESS)
1049 return status;
1050
1051#if INCLUDE_BENCHMARKS
1052 for (i=0; i<COUNT; ++i) {
1053 PJ_LOG(3,(THIS_FILE, " benchmarking (%d of %d)...", i+1, COUNT));
1054 status = uri_benchmark(&run[i].parse, &run[i].print, &run[i].cmp);
1055 if (status != PJ_SUCCESS)
1056 return status;
1057 }
1058
1059 /* Calculate average URI length */
1060 for (i=0, avg_len=0; i<PJ_ARRAY_SIZE(uri_test_array); ++i) {
1061 avg_len += uri_test_array[i].len;
1062 }
1063 avg_len /= PJ_ARRAY_SIZE(uri_test_array);
1064
1065
1066 /*
1067 * Print maximum parse/sec
1068 */
1069 for (i=0, max=0; i<COUNT; ++i)
1070 if (run[i].parse > max) max = run[i].parse;
1071
1072 PJ_LOG(3,("", " Maximum URI parse/sec=%u", max));
1073
1074 pj_ansi_sprintf(desc, "Number of SIP/TEL URIs that can be <B>parsed</B> with "
1075 "<tt>pjsip_parse_uri()</tt> per second "
1076 "(tested with %d URI set, with average length of "
1077 "%d chars)",
1078 (int)PJ_ARRAY_SIZE(uri_test_array), (int)avg_len);
1079
1080 report_ival("uri-parse-per-sec", max, "URI/sec", desc);
1081
1082 /* URI parsing bandwidth */
1083 report_ival("uri-parse-bandwidth-mb", (int)avg_len*max/1000000, "MB/sec",
1084 "URI parsing bandwidth in megabytes (number of megabytes "
1085 "worth of URI that can be parsed per second)");
1086
1087
1088 /* Print maximum print/sec */
1089 for (i=0, max=0; i<COUNT; ++i)
1090 if (run[i].print > max) max = run[i].print;
1091
1092 PJ_LOG(3,("", " Maximum URI print/sec=%u", max));
1093
1094 pj_ansi_sprintf(desc, "Number of SIP/TEL URIs that can be <B>printed</B> with "
1095 "<tt>pjsip_uri_print()</tt> per second "
1096 "(tested with %d URI set, with average length of "
1097 "%d chars)",
1098 (int)PJ_ARRAY_SIZE(uri_test_array), (int)avg_len);
1099
1100 report_ival("uri-print-per-sec", max, "URI/sec", desc);
1101
1102 /* Print maximum detect/sec */
1103 for (i=0, max=0; i<COUNT; ++i)
1104 if (run[i].cmp > max) max = run[i].cmp;
1105
1106 PJ_LOG(3,("", " Maximum URI comparison/sec=%u", max));
1107
1108 pj_ansi_sprintf(desc, "Number of SIP/TEL URIs that can be <B>compared</B> with "
1109 "<tt>pjsip_uri_cmp()</tt> per second "
1110 "(tested with %d URI set, with average length of "
1111 "%d chars)",
1112 (int)PJ_ARRAY_SIZE(uri_test_array), (int)avg_len);
1113
1114 report_ival("uri-cmp-per-sec", max, "URI/sec", desc);
1115
1116#endif /* INCLUDE_BENCHMARKS */
1117
1118 return PJ_SUCCESS;
1119}
1120