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