blob: dc1327657240eae84e5498cdaf2a343dc14ced2c [file] [log] [blame]
Benny Prijono0ca04b62005-12-30 23:50:15 +00001/* $Id$ */
2/*
3 * Copyright (C) 2003-2006 Benny Prijono <benny@prijono.org>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20#include "test.h"
Benny Prijono40f2f642006-01-30 18:40:05 +000021#include <pjsip.h>
Benny Prijono0ca04b62005-12-30 23:50:15 +000022#include <pjlib.h>
23
Benny Prijono0ca04b62005-12-30 23:50:15 +000024
Benny Prijono85598d92006-01-07 18:44:25 +000025#define THIS_FILE "txdata_test.c"
26
27
Benny Prijonoe93e2872006-06-28 16:46:49 +000028#define HFIND(msg,h,H) ((pjsip_##h##_hdr*) pjsip_msg_find_hdr(msg, PJSIP_H_##H, NULL))
29
30#if defined(PJ_DEBUG) && PJ_DEBUG!=0
31# define LOOP 10000
32#else
33# define LOOP 100000
34#endif
35
36
Benny Prijono0ca04b62005-12-30 23:50:15 +000037/*
38 * This tests various core message creation functions.
39 */
Benny Prijono0c2bc612006-01-10 13:31:40 +000040static int core_txdata_test(void)
Benny Prijono0ca04b62005-12-30 23:50:15 +000041{
42 pj_status_t status;
43 pj_str_t target, from, to, contact, body;
44 pjsip_rx_data dummy_rdata;
45 pjsip_tx_data *invite, *invite2, *cancel, *response, *ack;
46
Benny Prijono0c2bc612006-01-10 13:31:40 +000047 PJ_LOG(3,(THIS_FILE, " core transmit data test"));
48
Benny Prijono0ca04b62005-12-30 23:50:15 +000049 /* Create INVITE request. */
50 target = pj_str("tel:+1");
51 from = pj_str("tel:+0");
52 to = pj_str("tel:+1");
53 contact = pj_str("Bob <sip:+0@example.com;user=phone>");
54 body = pj_str("Hello world!");
55
56 status = pjsip_endpt_create_request( endpt, &pjsip_invite_method, &target,
57 &from, &to, &contact, NULL, 10, &body,
58 &invite);
59 if (status != PJ_SUCCESS) {
60 app_perror(" error: unable to create request", status);
61 return -10;
62 }
63
64 /* Buffer must be invalid. */
65 if (pjsip_tx_data_is_valid(invite) != 0) {
Benny Prijono85598d92006-01-07 18:44:25 +000066 PJ_LOG(3,(THIS_FILE, " error: buffer must be invalid"));
Benny Prijono0ca04b62005-12-30 23:50:15 +000067 return -14;
68 }
69 /* Reference counter must be set to 1. */
70 if (pj_atomic_get(invite->ref_cnt) != 1) {
Benny Prijono85598d92006-01-07 18:44:25 +000071 PJ_LOG(3,(THIS_FILE, " error: invalid reference counter"));
Benny Prijono0ca04b62005-12-30 23:50:15 +000072 return -15;
73 }
74 /* Check message type. */
75 if (invite->msg->type != PJSIP_REQUEST_MSG)
76 return -16;
77 /* Check method. */
78 if (invite->msg->line.req.method.id != PJSIP_INVITE_METHOD)
79 return -17;
80
81 /* Check that mandatory headers are present. */
82 if (HFIND(invite->msg, from, FROM) == 0)
83 return -20;
84 if (HFIND(invite->msg, to, TO) == 0)
85 return -21;
86 if (HFIND(invite->msg, contact, CONTACT) == 0)
87 return -22;
88 if (HFIND(invite->msg, cid, CALL_ID) == 0)
89 return -23;
90 if (HFIND(invite->msg, cseq, CSEQ) == 0)
91 return -24;
92 do {
93 pjsip_via_hdr *via = HFIND(invite->msg, via, VIA);
94 if (via == NULL)
95 return -25;
96 /* Branch param must be empty. */
97 if (via->branch_param.slen != 0)
98 return -26;
99 } while (0);
100 if (invite->msg->body == NULL)
101 return -28;
102
103 /* Create another INVITE request from first request. */
104 status = pjsip_endpt_create_request_from_hdr( endpt, &pjsip_invite_method,
105 invite->msg->line.req.uri,
106 HFIND(invite->msg,from,FROM),
107 HFIND(invite->msg,to,TO),
108 HFIND(invite->msg,contact,CONTACT),
109 HFIND(invite->msg,cid,CALL_ID),
110 10, &body, &invite2);
111 if (status != PJ_SUCCESS) {
112 app_perror(" error: create second request failed", status);
113 return -30;
114 }
115
116 /* Buffer must be invalid. */
117 if (pjsip_tx_data_is_valid(invite2) != 0) {
Benny Prijono85598d92006-01-07 18:44:25 +0000118 PJ_LOG(3,(THIS_FILE, " error: buffer must be invalid"));
Benny Prijono0ca04b62005-12-30 23:50:15 +0000119 return -34;
120 }
121 /* Reference counter must be set to 1. */
122 if (pj_atomic_get(invite2->ref_cnt) != 1) {
Benny Prijono85598d92006-01-07 18:44:25 +0000123 PJ_LOG(3,(THIS_FILE, " error: invalid reference counter"));
Benny Prijono0ca04b62005-12-30 23:50:15 +0000124 return -35;
125 }
126 /* Check message type. */
127 if (invite2->msg->type != PJSIP_REQUEST_MSG)
128 return -36;
129 /* Check method. */
130 if (invite2->msg->line.req.method.id != PJSIP_INVITE_METHOD)
131 return -37;
132
133 /* Check that mandatory headers are again present. */
134 if (HFIND(invite2->msg, from, FROM) == 0)
135 return -40;
136 if (HFIND(invite2->msg, to, TO) == 0)
137 return -41;
138 if (HFIND(invite2->msg, contact, CONTACT) == 0)
139 return -42;
140 if (HFIND(invite2->msg, cid, CALL_ID) == 0)
141 return -43;
142 if (HFIND(invite2->msg, cseq, CSEQ) == 0)
143 return -44;
144 if (HFIND(invite2->msg, via, VIA) == 0)
145 return -45;
146 /*
147 if (HFIND(invite2->msg, ctype, CONTENT_TYPE) == 0)
148 return -46;
149 if (HFIND(invite2->msg, clen, CONTENT_LENGTH) == 0)
150 return -47;
151 */
152 if (invite2->msg->body == NULL)
153 return -48;
154
155 /* Done checking invite2. We can delete this. */
156 if (pjsip_tx_data_dec_ref(invite2) != PJSIP_EBUFDESTROYED) {
Benny Prijono85598d92006-01-07 18:44:25 +0000157 PJ_LOG(3,(THIS_FILE, " error: request buffer not destroyed!"));
Benny Prijono0ca04b62005-12-30 23:50:15 +0000158 return -49;
159 }
160
161 /* Initialize dummy rdata (to simulate receiving a request)
162 * We should never do this in real application, as there are many
163 * many more fields need to be initialized!!
164 */
Benny Prijono728a9052006-01-18 23:34:15 +0000165 dummy_rdata.msg_info.cid = HFIND(invite->msg, cid, CALL_ID);
Benny Prijono0ca04b62005-12-30 23:50:15 +0000166 dummy_rdata.msg_info.clen = NULL;
167 dummy_rdata.msg_info.cseq = HFIND(invite->msg, cseq, CSEQ);
168 dummy_rdata.msg_info.ctype = NULL;
169 dummy_rdata.msg_info.from = HFIND(invite->msg, from, FROM);
170 dummy_rdata.msg_info.max_fwd = NULL;
171 dummy_rdata.msg_info.msg = invite->msg;
172 dummy_rdata.msg_info.record_route = NULL;
173 dummy_rdata.msg_info.require = NULL;
174 dummy_rdata.msg_info.route = NULL;
175 dummy_rdata.msg_info.to = HFIND(invite->msg, to, TO);
176 dummy_rdata.msg_info.via = HFIND(invite->msg, via, VIA);
177
178 /* Create a response message for the request. */
179 status = pjsip_endpt_create_response( endpt, &dummy_rdata, 301, NULL,
180 &response);
181 if (status != PJ_SUCCESS) {
182 app_perror(" error: unable to create response", status);
183 return -50;
184 }
185
186 /* Buffer must be invalid. */
187 if (pjsip_tx_data_is_valid(response) != 0) {
Benny Prijono85598d92006-01-07 18:44:25 +0000188 PJ_LOG(3,(THIS_FILE, " error: buffer must be invalid"));
Benny Prijono0ca04b62005-12-30 23:50:15 +0000189 return -54;
190 }
191 /* Check reference counter. */
192 if (pj_atomic_get(response->ref_cnt) != 1) {
Benny Prijono85598d92006-01-07 18:44:25 +0000193 PJ_LOG(3,(THIS_FILE, " error: invalid ref count in response"));
Benny Prijono0ca04b62005-12-30 23:50:15 +0000194 return -55;
195 }
196 /* Check message type. */
197 if (response->msg->type != PJSIP_RESPONSE_MSG)
198 return -56;
199 /* Check correct status is set. */
200 if (response->msg->line.status.code != 301)
201 return -57;
202
203 /* Check that mandatory headers are again present. */
204 if (HFIND(response->msg, from, FROM) == 0)
205 return -60;
206 if (HFIND(response->msg, to, TO) == 0)
207 return -61;
208 /*
209 if (HFIND(response->msg, contact, CONTACT) == 0)
210 return -62;
211 */
212 if (HFIND(response->msg, cid, CALL_ID) == 0)
213 return -63;
214 if (HFIND(response->msg, cseq, CSEQ) == 0)
215 return -64;
216 if (HFIND(response->msg, via, VIA) == 0)
217 return -65;
218
219 /* This response message will be used later when creating ACK */
220
221 /* Create CANCEL request for the original request. */
222 status = pjsip_endpt_create_cancel( endpt, invite, &cancel);
223 if (status != PJ_SUCCESS) {
224 app_perror(" error: unable to create CANCEL request", status);
225 return -80;
226 }
227
228 /* Buffer must be invalid. */
229 if (pjsip_tx_data_is_valid(cancel) != 0) {
Benny Prijono85598d92006-01-07 18:44:25 +0000230 PJ_LOG(3,(THIS_FILE, " error: buffer must be invalid"));
Benny Prijono0ca04b62005-12-30 23:50:15 +0000231 return -84;
232 }
233 /* Check reference counter. */
234 if (pj_atomic_get(cancel->ref_cnt) != 1) {
Benny Prijono85598d92006-01-07 18:44:25 +0000235 PJ_LOG(3,(THIS_FILE, " error: invalid ref count in CANCEL request"));
Benny Prijono0ca04b62005-12-30 23:50:15 +0000236 return -85;
237 }
238 /* Check message type. */
239 if (cancel->msg->type != PJSIP_REQUEST_MSG)
240 return -86;
241 /* Check method. */
242 if (cancel->msg->line.req.method.id != PJSIP_CANCEL_METHOD)
243 return -87;
244
245 /* Check that mandatory headers are again present. */
246 if (HFIND(cancel->msg, from, FROM) == 0)
247 return -90;
248 if (HFIND(cancel->msg, to, TO) == 0)
249 return -91;
250 /*
251 if (HFIND(cancel->msg, contact, CONTACT) == 0)
252 return -92;
253 */
254 if (HFIND(cancel->msg, cid, CALL_ID) == 0)
255 return -93;
256 if (HFIND(cancel->msg, cseq, CSEQ) == 0)
257 return -94;
258 if (HFIND(cancel->msg, via, VIA) == 0)
259 return -95;
260
261 /* Done checking CANCEL request. */
262 if (pjsip_tx_data_dec_ref(cancel) != PJSIP_EBUFDESTROYED) {
Benny Prijono85598d92006-01-07 18:44:25 +0000263 PJ_LOG(3,(THIS_FILE, " error: response buffer not destroyed!"));
Benny Prijono0ca04b62005-12-30 23:50:15 +0000264 return -99;
265 }
266
267 /* Modify dummy_rdata to simulate receiving response. */
Benny Prijonoac623b32006-07-03 15:19:31 +0000268 pj_bzero(&dummy_rdata, sizeof(dummy_rdata));
Benny Prijono0ca04b62005-12-30 23:50:15 +0000269 dummy_rdata.msg_info.msg = response->msg;
270 dummy_rdata.msg_info.to = HFIND(response->msg, to, TO);
271
272 /* Create ACK request */
273 status = pjsip_endpt_create_ack( endpt, invite, &dummy_rdata, &ack );
274 if (status != PJ_SUCCESS) {
Benny Prijono85598d92006-01-07 18:44:25 +0000275 PJ_LOG(3,(THIS_FILE, " error: unable to create ACK"));
Benny Prijono0ca04b62005-12-30 23:50:15 +0000276 return -100;
277 }
278 /* Buffer must be invalid. */
279 if (pjsip_tx_data_is_valid(ack) != 0) {
Benny Prijono85598d92006-01-07 18:44:25 +0000280 PJ_LOG(3,(THIS_FILE, " error: buffer must be invalid"));
Benny Prijono0ca04b62005-12-30 23:50:15 +0000281 return -104;
282 }
283 /* Check reference counter. */
284 if (pj_atomic_get(ack->ref_cnt) != 1) {
Benny Prijono85598d92006-01-07 18:44:25 +0000285 PJ_LOG(3,(THIS_FILE, " error: invalid ref count in ACK request"));
Benny Prijono0ca04b62005-12-30 23:50:15 +0000286 return -105;
287 }
288 /* Check message type. */
289 if (ack->msg->type != PJSIP_REQUEST_MSG)
290 return -106;
291 /* Check method. */
292 if (ack->msg->line.req.method.id != PJSIP_ACK_METHOD)
293 return -107;
294 /* Check Request-URI is present. */
295 if (ack->msg->line.req.uri == NULL)
296 return -108;
297
298 /* Check that mandatory headers are again present. */
299 if (HFIND(ack->msg, from, FROM) == 0)
300 return -110;
301 if (HFIND(ack->msg, to, TO) == 0)
302 return -111;
303 if (HFIND(ack->msg, cid, CALL_ID) == 0)
304 return -112;
305 if (HFIND(ack->msg, cseq, CSEQ) == 0)
306 return -113;
307 if (HFIND(ack->msg, via, VIA) == 0)
308 return -114;
309 if (ack->msg->body != NULL)
310 return -115;
311
312 /* Done checking invite message. */
313 if (pjsip_tx_data_dec_ref(invite) != PJSIP_EBUFDESTROYED) {
Benny Prijono85598d92006-01-07 18:44:25 +0000314 PJ_LOG(3,(THIS_FILE, " error: response buffer not destroyed!"));
Benny Prijono0ca04b62005-12-30 23:50:15 +0000315 return -120;
316 }
317
318 /* Done checking response message. */
319 if (pjsip_tx_data_dec_ref(response) != PJSIP_EBUFDESTROYED) {
Benny Prijono85598d92006-01-07 18:44:25 +0000320 PJ_LOG(3,(THIS_FILE, " error: response buffer not destroyed!"));
Benny Prijono0ca04b62005-12-30 23:50:15 +0000321 return -130;
322 }
323
324 /* Done checking ack message. */
325 if (pjsip_tx_data_dec_ref(ack) != PJSIP_EBUFDESTROYED) {
Benny Prijono85598d92006-01-07 18:44:25 +0000326 PJ_LOG(3,(THIS_FILE, " error: response buffer not destroyed!"));
Benny Prijono0ca04b62005-12-30 23:50:15 +0000327 return -140;
328 }
329
330 /* Done. */
331 return 0;
332}
333
Benny Prijonoe93e2872006-06-28 16:46:49 +0000334
335
336/*
337 * This test demonstrate the bug as reported in:
338 * http://bugzilla.pjproject.net/show_bug.cgi?id=49
Benny Prijono0c2bc612006-01-10 13:31:40 +0000339 */
Benny Prijonobc331ca2006-09-19 13:32:05 +0000340#if INCLUDE_GCC_TEST
Benny Prijonoe93e2872006-06-28 16:46:49 +0000341static int gcc_test()
Benny Prijono0c2bc612006-01-10 13:31:40 +0000342{
343 char msgbuf[512];
344 pj_str_t target = pj_str("sip:alice@wonderland:5061;x-param=param%201"
345 "?X-Hdr-1=Header%201"
346 "&X-Empty-Hdr=");
Benny Prijono0c2bc612006-01-10 13:31:40 +0000347 pjsip_tx_data *tdata;
Benny Prijonoe93e2872006-06-28 16:46:49 +0000348 pjsip_parser_err_report err_list;
Benny Prijono0c2bc612006-01-10 13:31:40 +0000349 pjsip_msg *msg;
350 int len;
351 pj_status_t status;
352
353 PJ_LOG(3,(THIS_FILE, " header param in URI to create request"));
354
355 /* Create request with header param in target URI. */
356 status = pjsip_endpt_create_request(endpt, &pjsip_invite_method, &target,
357 &target, &target, &target, NULL, -1,
358 NULL, &tdata);
359 if (status != 0) {
360 app_perror(" error: Unable to create request", status);
361 return -200;
362 }
363
364 /* Print and parse the request.
365 * We'll check that header params are not present in
366 */
367 len = pjsip_msg_print(tdata->msg, msgbuf, sizeof(msgbuf));
368 if (len < 1) {
369 PJ_LOG(3,(THIS_FILE, " error: printing message"));
370 pjsip_tx_data_dec_ref(tdata);
371 return -250;
372 }
373 msgbuf[len] = '\0';
374
375 PJ_LOG(5,(THIS_FILE, "%d bytes request created:--begin-msg--\n"
376 "%s\n"
377 "--end-msg--", len, msgbuf));
378
379 /* Now parse the message. */
Benny Prijonoe93e2872006-06-28 16:46:49 +0000380 pj_list_init(&err_list);
381 msg = pjsip_parse_msg( tdata->pool, msgbuf, len, &err_list);
Benny Prijono0c2bc612006-01-10 13:31:40 +0000382 if (msg == NULL) {
Benny Prijonoe93e2872006-06-28 16:46:49 +0000383 pjsip_parser_err_report *e;
384
385 PJ_LOG(3,(THIS_FILE, " error: parsing message message"));
386
387 e = err_list.next;
388 while (e != &err_list) {
389 PJ_LOG(3,(THIS_FILE, " %s in line %d col %d hname=%.*s",
390 pj_exception_id_name(e->except_code),
391 e->line, e->col+1,
392 (int)e->hname.slen,
393 e->hname.ptr));
394 e = e->next;
395 }
396
397 pjsip_tx_data_dec_ref(tdata);
398 return -255;
399 }
400
401 pjsip_tx_data_dec_ref(tdata);
402 return 0;
403}
Benny Prijonobc331ca2006-09-19 13:32:05 +0000404#endif
Benny Prijonoe93e2872006-06-28 16:46:49 +0000405
406
407/* This tests the request creating functions against the following
408 * requirements:
409 * - header params in URI creates header in the request.
410 * - method and headers params are correctly shown or hidden in
411 * request URI, From, To, and Contact header.
412 */
413static int txdata_test_uri_params(void)
414{
415 char msgbuf[512];
416 pj_str_t target = pj_str("sip:alice@wonderland:5061;x-param=param%201"
417 "?X-Hdr-1=Header%201"
418 "&X-Empty-Hdr=");
419 pj_str_t pname = pj_str("x-param");
420 pj_str_t hname = pj_str("X-Hdr-1");
421 pj_str_t hemptyname = pj_str("X-Empty-Hdr");
422 pjsip_from_hdr *from_hdr;
423 pjsip_to_hdr *to_hdr;
424 pjsip_contact_hdr *contact_hdr;
425 pjsip_generic_string_hdr *hdr;
426 pjsip_tx_data *tdata;
427 pjsip_sip_uri *uri;
428 pjsip_param *param;
429 pjsip_via_hdr *via;
430 pjsip_parser_err_report err_list;
431 pjsip_msg *msg;
432 int len;
433 pj_status_t status;
434
435 PJ_LOG(3,(THIS_FILE, " header param in URI to create request"));
436
437 /* Create request with header param in target URI. */
438 status = pjsip_endpt_create_request(endpt, &pjsip_invite_method, &target,
439 &target, &target, &target, NULL, -1,
440 NULL, &tdata);
441 if (status != 0) {
442 app_perror(" error: Unable to create request", status);
443 return -200;
444 }
445
446 /* Fill up the Via header to prevent syntax error on parsing */
447 via = pjsip_msg_find_hdr(tdata->msg, PJSIP_H_VIA, NULL);
448 via->transport = pj_str("TCP");
449 via->sent_by.host = pj_str("127.0.0.1");
450
451 /* Print and parse the request.
452 * We'll check that header params are not present in
453 */
454 len = pjsip_msg_print(tdata->msg, msgbuf, sizeof(msgbuf));
455 if (len < 1) {
456 PJ_LOG(3,(THIS_FILE, " error: printing message"));
Benny Prijono0c2bc612006-01-10 13:31:40 +0000457 pjsip_tx_data_dec_ref(tdata);
458 return -250;
459 }
Benny Prijonoe93e2872006-06-28 16:46:49 +0000460 msgbuf[len] = '\0';
461
462 PJ_LOG(5,(THIS_FILE, "%d bytes request created:--begin-msg--\n"
463 "%s\n"
464 "--end-msg--", len, msgbuf));
465
466 /* Now parse the message. */
467 pj_list_init(&err_list);
468 msg = pjsip_parse_msg( tdata->pool, msgbuf, len, &err_list);
469 if (msg == NULL) {
470 pjsip_parser_err_report *e;
471
472 PJ_LOG(3,(THIS_FILE, " error: parsing message message"));
473
474 e = err_list.next;
475 while (e != &err_list) {
476 PJ_LOG(3,(THIS_FILE, " %s in line %d col %d hname=%.*s",
477 pj_exception_id_name(e->except_code),
478 e->line, e->col+1,
479 (int)e->hname.slen,
480 e->hname.ptr));
481 e = e->next;
482 }
483
484 pjsip_tx_data_dec_ref(tdata);
485 return -256;
486 }
Benny Prijono0c2bc612006-01-10 13:31:40 +0000487
488 /* Check the existence of port, other_param, and header param.
489 * Port is now allowed in To and From header.
490 */
491 /* Port in request URI. */
492 uri = (pjsip_sip_uri*) pjsip_uri_get_uri(msg->line.req.uri);
493 if (uri->port != 5061) {
494 PJ_LOG(3,(THIS_FILE, " error: port not present in request URI"));
495 pjsip_tx_data_dec_ref(tdata);
496 return -260;
497 }
498 /* other_param in request_uri */
499 param = pjsip_param_find(&uri->other_param, &pname);
500 if (param == NULL || pj_strcmp2(&param->value, "param 1") != 0) {
501 PJ_LOG(3,(THIS_FILE, " error: x-param not present in request URI"));
502 pjsip_tx_data_dec_ref(tdata);
503 return -261;
504 }
505 /* header param in request uri. */
506 if (!pj_list_empty(&uri->header_param)) {
507 PJ_LOG(3,(THIS_FILE, " error: hparam in request URI"));
508 pjsip_tx_data_dec_ref(tdata);
509 return -262;
510 }
511
512 /* Port in From header. */
513 from_hdr = (pjsip_from_hdr*) pjsip_msg_find_hdr(msg, PJSIP_H_FROM, NULL);
514 uri = (pjsip_sip_uri*) pjsip_uri_get_uri(from_hdr->uri);
515 if (uri->port != 0) {
516 PJ_LOG(3,(THIS_FILE, " error: port most not exist in From header"));
517 pjsip_tx_data_dec_ref(tdata);
518 return -270;
519 }
520 /* other_param in From header */
521 param = pjsip_param_find(&uri->other_param, &pname);
522 if (param == NULL || pj_strcmp2(&param->value, "param 1") != 0) {
523 PJ_LOG(3,(THIS_FILE, " error: x-param not present in From header"));
524 pjsip_tx_data_dec_ref(tdata);
525 return -271;
526 }
527 /* header param in From header. */
528 if (!pj_list_empty(&uri->header_param)) {
529 PJ_LOG(3,(THIS_FILE, " error: hparam in From header"));
530 pjsip_tx_data_dec_ref(tdata);
531 return -272;
532 }
533
534
535 /* Port in To header. */
536 to_hdr = (pjsip_to_hdr*) pjsip_msg_find_hdr(msg, PJSIP_H_TO, NULL);
537 uri = (pjsip_sip_uri*) pjsip_uri_get_uri(to_hdr->uri);
538 if (uri->port != 0) {
539 PJ_LOG(3,(THIS_FILE, " error: port most not exist in To header"));
540 pjsip_tx_data_dec_ref(tdata);
541 return -280;
542 }
543 /* other_param in To header */
544 param = pjsip_param_find(&uri->other_param, &pname);
545 if (param == NULL || pj_strcmp2(&param->value, "param 1") != 0) {
546 PJ_LOG(3,(THIS_FILE, " error: x-param not present in To header"));
547 pjsip_tx_data_dec_ref(tdata);
548 return -281;
549 }
550 /* header param in From header. */
551 if (!pj_list_empty(&uri->header_param)) {
552 PJ_LOG(3,(THIS_FILE, " error: hparam in To header"));
553 pjsip_tx_data_dec_ref(tdata);
554 return -282;
555 }
556
557
558
559 /* Port in Contact header. */
560 contact_hdr = (pjsip_contact_hdr*) pjsip_msg_find_hdr(msg, PJSIP_H_CONTACT, NULL);
561 uri = (pjsip_sip_uri*) pjsip_uri_get_uri(contact_hdr->uri);
562 if (uri->port != 5061) {
563 PJ_LOG(3,(THIS_FILE, " error: port not present in Contact header"));
564 pjsip_tx_data_dec_ref(tdata);
565 return -290;
566 }
567 /* other_param in Contact header */
568 param = pjsip_param_find(&uri->other_param, &pname);
569 if (param == NULL || pj_strcmp2(&param->value, "param 1") != 0) {
570 PJ_LOG(3,(THIS_FILE, " error: x-param not present in Contact header"));
571 pjsip_tx_data_dec_ref(tdata);
572 return -291;
573 }
574 /* header param in Contact header. */
575 if (pj_list_empty(&uri->header_param)) {
576 PJ_LOG(3,(THIS_FILE, " error: hparam is missing in Contact header"));
577 pjsip_tx_data_dec_ref(tdata);
578 return -292;
579 }
580 /* Check for X-Hdr-1 */
581 param = pjsip_param_find(&uri->header_param, &hname);
582 if (param == NULL || pj_strcmp2(&param->value, "Header 1")!=0) {
583 PJ_LOG(3,(THIS_FILE, " error: hparam is missing in Contact header"));
584 pjsip_tx_data_dec_ref(tdata);
585 return -293;
586 }
587 /* Check for X-Empty-Hdr */
588 param = pjsip_param_find(&uri->header_param, &hemptyname);
589 if (param == NULL || pj_strcmp2(&param->value, "")!=0) {
590 PJ_LOG(3,(THIS_FILE, " error: hparam is missing in Contact header"));
591 pjsip_tx_data_dec_ref(tdata);
592 return -294;
593 }
594
595
596 /* Check that headers are present in the request. */
597 hdr = (pjsip_generic_string_hdr*)
598 pjsip_msg_find_hdr_by_name(msg, &hname, NULL);
599 if (hdr == NULL || pj_strcmp2(&hdr->hvalue, "Header 1")!=0) {
600 PJ_LOG(3,(THIS_FILE, " error: header X-Hdr-1 not created"));
601 pjsip_tx_data_dec_ref(tdata);
602 return -300;
603 }
604
605 hdr = (pjsip_generic_string_hdr*)
606 pjsip_msg_find_hdr_by_name(msg, &hemptyname, NULL);
607 if (hdr == NULL || pj_strcmp2(&param->value, "")!=0) {
608 PJ_LOG(3,(THIS_FILE, " error: header X-Empty-Hdr not created"));
609 pjsip_tx_data_dec_ref(tdata);
610 return -330;
611 }
612
613 pjsip_tx_data_dec_ref(tdata);
614 return 0;
615}
616
Benny Prijonoe93e2872006-06-28 16:46:49 +0000617
618/*
619 * create request benchmark
620 */
621static int create_request_bench(pj_timestamp *p_elapsed)
622{
623 enum { COUNT = 100 };
624 unsigned i, j;
625 pjsip_tx_data *tdata[COUNT];
626 pj_timestamp t1, t2, elapsed;
627 pj_status_t status;
628
629 pj_str_t str_target = pj_str("sip:someuser@someprovider.com");
630 pj_str_t str_from = pj_str("\"Local User\" <sip:localuser@serviceprovider.com>");
631 pj_str_t str_to = pj_str("\"Remote User\" <sip:remoteuser@serviceprovider.com>");
632 pj_str_t str_contact = str_from;
633
634 elapsed.u64 = 0;
635
636 for (i=0; i<LOOP; i+=COUNT) {
Benny Prijonoac623b32006-07-03 15:19:31 +0000637 pj_bzero(tdata, sizeof(tdata));
Benny Prijonoe93e2872006-06-28 16:46:49 +0000638
639 pj_get_timestamp(&t1);
640
641 for (j=0; j<COUNT; ++j) {
642 status = pjsip_endpt_create_request(endpt, &pjsip_invite_method,
643 &str_target, &str_from, &str_to,
644 &str_contact, NULL, -1, NULL,
645 &tdata[j]);
646 if (status != PJ_SUCCESS) {
647 app_perror(" error: unable to create request", status);
648 goto on_error;
649 }
650 }
651
652 pj_get_timestamp(&t2);
653 pj_sub_timestamp(&t2, &t1);
654 pj_add_timestamp(&elapsed, &t2);
655
656 for (j=0; j<COUNT; ++j)
657 pjsip_tx_data_dec_ref(tdata[j]);
658 }
659
660 p_elapsed->u64 = elapsed.u64;
661 return PJ_SUCCESS;
662
663on_error:
664 for (i=0; i<COUNT; ++i) {
665 if (tdata[i])
666 pjsip_tx_data_dec_ref(tdata[i]);
667 }
668 return -400;
669}
670
671
672
673/*
674 * create response benchmark
675 */
676static int create_response_bench(pj_timestamp *p_elapsed)
677{
678 enum { COUNT = 100 };
679 unsigned i, j;
680 pjsip_via_hdr *via;
681 pjsip_rx_data rdata;
682 pjsip_tx_data *request;
683 pjsip_tx_data *tdata[COUNT];
684 pj_timestamp t1, t2, elapsed;
685 pj_status_t status;
686
687 /* Create the request first. */
688 pj_str_t str_target = pj_str("sip:someuser@someprovider.com");
689 pj_str_t str_from = pj_str("\"Local User\" <sip:localuser@serviceprovider.com>");
690 pj_str_t str_to = pj_str("\"Remote User\" <sip:remoteuser@serviceprovider.com>");
691 pj_str_t str_contact = str_from;
692
693 status = pjsip_endpt_create_request(endpt, &pjsip_invite_method,
694 &str_target, &str_from, &str_to,
695 &str_contact, NULL, -1, NULL,
696 &request);
697 if (status != PJ_SUCCESS) {
698 app_perror(" error: unable to create request", status);
699 return status;
700 }
701
702 /* Create several Via headers */
703 via = pjsip_via_hdr_create(request->pool);
704 via->sent_by.host = pj_str("192.168.0.7");
705 via->sent_by.port = 5061;
706 via->transport = pj_str("udp");
707 via->rport_param = 0;
708 via->branch_param = pj_str("012345678901234567890123456789");
709 via->recvd_param = pj_str("192.168.0.7");
710 pjsip_msg_insert_first_hdr(request->msg, pjsip_hdr_clone(request->pool, via));
711 pjsip_msg_insert_first_hdr(request->msg, pjsip_hdr_clone(request->pool, via));
712 pjsip_msg_insert_first_hdr(request->msg, (pjsip_hdr*)via);
713
714
715 /* Create "dummy" rdata from the tdata */
Benny Prijonoac623b32006-07-03 15:19:31 +0000716 pj_bzero(&rdata, sizeof(pjsip_rx_data));
Benny Prijonoe93e2872006-06-28 16:46:49 +0000717 rdata.tp_info.pool = request->pool;
718 rdata.msg_info.msg = request->msg;
719 rdata.msg_info.from = pjsip_msg_find_hdr(request->msg, PJSIP_H_FROM, NULL);
720 rdata.msg_info.to = pjsip_msg_find_hdr(request->msg, PJSIP_H_TO, NULL);
721 rdata.msg_info.cseq = pjsip_msg_find_hdr(request->msg, PJSIP_H_CSEQ, NULL);
722 rdata.msg_info.cid = pjsip_msg_find_hdr(request->msg, PJSIP_H_FROM, NULL);
723 rdata.msg_info.via = via;
724
725 /*
726 * Now benchmark create_response
727 */
728 elapsed.u64 = 0;
729
730 for (i=0; i<LOOP; i+=COUNT) {
Benny Prijonoac623b32006-07-03 15:19:31 +0000731 pj_bzero(tdata, sizeof(tdata));
Benny Prijonoe93e2872006-06-28 16:46:49 +0000732
733 pj_get_timestamp(&t1);
734
735 for (j=0; j<COUNT; ++j) {
736 status = pjsip_endpt_create_response(endpt, &rdata, 200, NULL, &tdata[j]);
737 if (status != PJ_SUCCESS) {
738 app_perror(" error: unable to create request", status);
739 goto on_error;
740 }
741 }
742
743 pj_get_timestamp(&t2);
744 pj_sub_timestamp(&t2, &t1);
745 pj_add_timestamp(&elapsed, &t2);
746
747 for (j=0; j<COUNT; ++j)
748 pjsip_tx_data_dec_ref(tdata[j]);
749 }
750
751 p_elapsed->u64 = elapsed.u64;
752 pjsip_tx_data_dec_ref(request);
753 return PJ_SUCCESS;
754
755on_error:
756 for (i=0; i<COUNT; ++i) {
757 if (tdata[i])
758 pjsip_tx_data_dec_ref(tdata[i]);
759 }
760 return -400;
761}
762
763
Benny Prijono0c2bc612006-01-10 13:31:40 +0000764int txdata_test(void)
765{
Benny Prijonoe93e2872006-06-28 16:46:49 +0000766 enum { REPEAT = 4 };
767 unsigned i, msgs;
768 pj_timestamp usec[REPEAT], min, freq;
Benny Prijono0c2bc612006-01-10 13:31:40 +0000769 int status;
770
Benny Prijonoe93e2872006-06-28 16:46:49 +0000771 status = pj_get_timestamp_freq(&freq);
772 if (status != PJ_SUCCESS)
773 return status;
774
Benny Prijono0c2bc612006-01-10 13:31:40 +0000775 status = core_txdata_test();
776 if (status != 0)
777 return status;
778
Benny Prijonoe93e2872006-06-28 16:46:49 +0000779#if INCLUDE_GCC_TEST
780 status = gcc_test();
781 if (status != 0)
782 return status;
783#endif
Benny Prijono0c2bc612006-01-10 13:31:40 +0000784
785 status = txdata_test_uri_params();
786 if (status != 0)
787 return status;
788
Benny Prijonoe93e2872006-06-28 16:46:49 +0000789
790 /*
791 * Benchmark create_request()
792 */
793 PJ_LOG(3,(THIS_FILE, " benchmarking request creation:"));
794 for (i=0; i<REPEAT; ++i) {
795 PJ_LOG(3,(THIS_FILE, " test %d of %d..",
796 i+1, REPEAT));
797 status = create_request_bench(&usec[i]);
798 if (status != PJ_SUCCESS)
799 return status;
800 }
801
802 min.u64 = PJ_UINT64(0xFFFFFFFFFFFFFFF);
803 for (i=0; i<REPEAT; ++i) {
804 if (usec[i].u64 < min.u64) min.u64 = usec[i].u64;
805 }
806
807 msgs = (unsigned)(freq.u64 * LOOP / min.u64);
808
809 PJ_LOG(3,(THIS_FILE, " Requests created at %d requests/sec", msgs));
810
811 report_ival("create-request-per-sec",
812 msgs, "msg/sec",
813 "Number of typical request messages that can be created "
814 "per second with <tt>pjsip_endpt_create_request()</tt>");
815
816
817 /*
818 * Benchmark create_response()
819 */
820 PJ_LOG(3,(THIS_FILE, " benchmarking response creation:"));
821 for (i=0; i<REPEAT; ++i) {
822 PJ_LOG(3,(THIS_FILE, " test %d of %d..",
823 i+1, REPEAT));
824 status = create_response_bench(&usec[i]);
825 if (status != PJ_SUCCESS)
826 return status;
827 }
828
829 min.u64 = PJ_UINT64(0xFFFFFFFFFFFFFFF);
830 for (i=0; i<REPEAT; ++i) {
831 if (usec[i].u64 < min.u64) min.u64 = usec[i].u64;
832 }
833
834 msgs = (unsigned)(freq.u64 * LOOP / min.u64);
835
836 PJ_LOG(3,(THIS_FILE, " Responses created at %d responses/sec", msgs));
837
838 report_ival("create-response-per-sec",
839 msgs, "msg/sec",
840 "Number of typical response messages that can be created "
841 "per second with <tt>pjsip_endpt_create_response()</tt>");
842
843
Benny Prijono0c2bc612006-01-10 13:31:40 +0000844 return 0;
845}
Benny Prijonoe93e2872006-06-28 16:46:49 +0000846