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