summaryrefslogtreecommitdiff
path: root/pjsip/src/test-pjsip/txdata_test.c
diff options
context:
space:
mode:
Diffstat (limited to 'pjsip/src/test-pjsip/txdata_test.c')
-rw-r--r--pjsip/src/test-pjsip/txdata_test.c320
1 files changed, 320 insertions, 0 deletions
diff --git a/pjsip/src/test-pjsip/txdata_test.c b/pjsip/src/test-pjsip/txdata_test.c
new file mode 100644
index 00000000..08cad024
--- /dev/null
+++ b/pjsip/src/test-pjsip/txdata_test.c
@@ -0,0 +1,320 @@
+/* $Id$ */
+/*
+ * Copyright (C) 2003-2006 Benny Prijono <benny@prijono.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "test.h"
+#include <pjsip_core.h>
+#include <pjlib.h>
+
+#define HFIND(msg,h,H) ((pjsip_##h##_hdr*) pjsip_msg_find_hdr(msg, PJSIP_H_##H, NULL))
+
+/*
+ * This tests various core message creation functions.
+ */
+int txdata_test(void)
+{
+ pj_status_t status;
+ pj_str_t target, from, to, contact, body;
+ pjsip_rx_data dummy_rdata;
+ pjsip_tx_data *invite, *invite2, *cancel, *response, *ack;
+
+ /* Create INVITE request. */
+ target = pj_str("tel:+1");
+ from = pj_str("tel:+0");
+ to = pj_str("tel:+1");
+ contact = pj_str("Bob <sip:+0@example.com;user=phone>");
+ body = pj_str("Hello world!");
+
+ status = pjsip_endpt_create_request( endpt, &pjsip_invite_method, &target,
+ &from, &to, &contact, NULL, 10, &body,
+ &invite);
+ if (status != PJ_SUCCESS) {
+ app_perror(" error: unable to create request", status);
+ return -10;
+ }
+
+ /* Buffer must be invalid. */
+ if (pjsip_tx_data_is_valid(invite) != 0) {
+ PJ_LOG(3,("", " error: buffer must be invalid"));
+ return -14;
+ }
+ /* Reference counter must be set to 1. */
+ if (pj_atomic_get(invite->ref_cnt) != 1) {
+ PJ_LOG(3,("", " error: invalid reference counter"));
+ return -15;
+ }
+ /* Check message type. */
+ if (invite->msg->type != PJSIP_REQUEST_MSG)
+ return -16;
+ /* Check method. */
+ if (invite->msg->line.req.method.id != PJSIP_INVITE_METHOD)
+ return -17;
+
+ /* Check that mandatory headers are present. */
+ if (HFIND(invite->msg, from, FROM) == 0)
+ return -20;
+ if (HFIND(invite->msg, to, TO) == 0)
+ return -21;
+ if (HFIND(invite->msg, contact, CONTACT) == 0)
+ return -22;
+ if (HFIND(invite->msg, cid, CALL_ID) == 0)
+ return -23;
+ if (HFIND(invite->msg, cseq, CSEQ) == 0)
+ return -24;
+ do {
+ pjsip_via_hdr *via = HFIND(invite->msg, via, VIA);
+ if (via == NULL)
+ return -25;
+ /* Branch param must be empty. */
+ if (via->branch_param.slen != 0)
+ return -26;
+ } while (0);
+ if (invite->msg->body == NULL)
+ return -28;
+
+ /* Create another INVITE request from first request. */
+ status = pjsip_endpt_create_request_from_hdr( endpt, &pjsip_invite_method,
+ invite->msg->line.req.uri,
+ HFIND(invite->msg,from,FROM),
+ HFIND(invite->msg,to,TO),
+ HFIND(invite->msg,contact,CONTACT),
+ HFIND(invite->msg,cid,CALL_ID),
+ 10, &body, &invite2);
+ if (status != PJ_SUCCESS) {
+ app_perror(" error: create second request failed", status);
+ return -30;
+ }
+
+ /* Buffer must be invalid. */
+ if (pjsip_tx_data_is_valid(invite2) != 0) {
+ PJ_LOG(3,("", " error: buffer must be invalid"));
+ return -34;
+ }
+ /* Reference counter must be set to 1. */
+ if (pj_atomic_get(invite2->ref_cnt) != 1) {
+ PJ_LOG(3,("", " error: invalid reference counter"));
+ return -35;
+ }
+ /* Check message type. */
+ if (invite2->msg->type != PJSIP_REQUEST_MSG)
+ return -36;
+ /* Check method. */
+ if (invite2->msg->line.req.method.id != PJSIP_INVITE_METHOD)
+ return -37;
+
+ /* Check that mandatory headers are again present. */
+ if (HFIND(invite2->msg, from, FROM) == 0)
+ return -40;
+ if (HFIND(invite2->msg, to, TO) == 0)
+ return -41;
+ if (HFIND(invite2->msg, contact, CONTACT) == 0)
+ return -42;
+ if (HFIND(invite2->msg, cid, CALL_ID) == 0)
+ return -43;
+ if (HFIND(invite2->msg, cseq, CSEQ) == 0)
+ return -44;
+ if (HFIND(invite2->msg, via, VIA) == 0)
+ return -45;
+ /*
+ if (HFIND(invite2->msg, ctype, CONTENT_TYPE) == 0)
+ return -46;
+ if (HFIND(invite2->msg, clen, CONTENT_LENGTH) == 0)
+ return -47;
+ */
+ if (invite2->msg->body == NULL)
+ return -48;
+
+ /* Done checking invite2. We can delete this. */
+ if (pjsip_tx_data_dec_ref(invite2) != PJSIP_EBUFDESTROYED) {
+ PJ_LOG(3,("", " error: request buffer not destroyed!"));
+ return -49;
+ }
+
+ /* Initialize dummy rdata (to simulate receiving a request)
+ * We should never do this in real application, as there are many
+ * many more fields need to be initialized!!
+ */
+ dummy_rdata.msg_info.call_id = (HFIND(invite->msg, cid, CALL_ID))->id;
+ dummy_rdata.msg_info.clen = NULL;
+ dummy_rdata.msg_info.cseq = HFIND(invite->msg, cseq, CSEQ);
+ dummy_rdata.msg_info.ctype = NULL;
+ dummy_rdata.msg_info.from = HFIND(invite->msg, from, FROM);
+ dummy_rdata.msg_info.max_fwd = NULL;
+ dummy_rdata.msg_info.msg = invite->msg;
+ dummy_rdata.msg_info.record_route = NULL;
+ dummy_rdata.msg_info.require = NULL;
+ dummy_rdata.msg_info.route = NULL;
+ dummy_rdata.msg_info.to = HFIND(invite->msg, to, TO);
+ dummy_rdata.msg_info.via = HFIND(invite->msg, via, VIA);
+
+ /* Create a response message for the request. */
+ status = pjsip_endpt_create_response( endpt, &dummy_rdata, 301, NULL,
+ &response);
+ if (status != PJ_SUCCESS) {
+ app_perror(" error: unable to create response", status);
+ return -50;
+ }
+
+ /* Buffer must be invalid. */
+ if (pjsip_tx_data_is_valid(response) != 0) {
+ PJ_LOG(3,("", " error: buffer must be invalid"));
+ return -54;
+ }
+ /* Check reference counter. */
+ if (pj_atomic_get(response->ref_cnt) != 1) {
+ PJ_LOG(3,("", " error: invalid ref count in response"));
+ return -55;
+ }
+ /* Check message type. */
+ if (response->msg->type != PJSIP_RESPONSE_MSG)
+ return -56;
+ /* Check correct status is set. */
+ if (response->msg->line.status.code != 301)
+ return -57;
+
+ /* Check that mandatory headers are again present. */
+ if (HFIND(response->msg, from, FROM) == 0)
+ return -60;
+ if (HFIND(response->msg, to, TO) == 0)
+ return -61;
+ /*
+ if (HFIND(response->msg, contact, CONTACT) == 0)
+ return -62;
+ */
+ if (HFIND(response->msg, cid, CALL_ID) == 0)
+ return -63;
+ if (HFIND(response->msg, cseq, CSEQ) == 0)
+ return -64;
+ if (HFIND(response->msg, via, VIA) == 0)
+ return -65;
+
+ /* This response message will be used later when creating ACK */
+
+ /* Create CANCEL request for the original request. */
+ status = pjsip_endpt_create_cancel( endpt, invite, &cancel);
+ if (status != PJ_SUCCESS) {
+ app_perror(" error: unable to create CANCEL request", status);
+ return -80;
+ }
+
+ /* Buffer must be invalid. */
+ if (pjsip_tx_data_is_valid(cancel) != 0) {
+ PJ_LOG(3,("", " error: buffer must be invalid"));
+ return -84;
+ }
+ /* Check reference counter. */
+ if (pj_atomic_get(cancel->ref_cnt) != 1) {
+ PJ_LOG(3,("", " error: invalid ref count in CANCEL request"));
+ return -85;
+ }
+ /* Check message type. */
+ if (cancel->msg->type != PJSIP_REQUEST_MSG)
+ return -86;
+ /* Check method. */
+ if (cancel->msg->line.req.method.id != PJSIP_CANCEL_METHOD)
+ return -87;
+
+ /* Check that mandatory headers are again present. */
+ if (HFIND(cancel->msg, from, FROM) == 0)
+ return -90;
+ if (HFIND(cancel->msg, to, TO) == 0)
+ return -91;
+ /*
+ if (HFIND(cancel->msg, contact, CONTACT) == 0)
+ return -92;
+ */
+ if (HFIND(cancel->msg, cid, CALL_ID) == 0)
+ return -93;
+ if (HFIND(cancel->msg, cseq, CSEQ) == 0)
+ return -94;
+ if (HFIND(cancel->msg, via, VIA) == 0)
+ return -95;
+
+ /* Done checking CANCEL request. */
+ if (pjsip_tx_data_dec_ref(cancel) != PJSIP_EBUFDESTROYED) {
+ PJ_LOG(3,("", " error: response buffer not destroyed!"));
+ return -99;
+ }
+
+ /* Modify dummy_rdata to simulate receiving response. */
+ pj_memset(&dummy_rdata, 0, sizeof(dummy_rdata));
+ dummy_rdata.msg_info.msg = response->msg;
+ dummy_rdata.msg_info.to = HFIND(response->msg, to, TO);
+
+ /* Create ACK request */
+ status = pjsip_endpt_create_ack( endpt, invite, &dummy_rdata, &ack );
+ if (status != PJ_SUCCESS) {
+ PJ_LOG(3,("", " error: unable to create ACK"));
+ return -100;
+ }
+ /* Buffer must be invalid. */
+ if (pjsip_tx_data_is_valid(ack) != 0) {
+ PJ_LOG(3,("", " error: buffer must be invalid"));
+ return -104;
+ }
+ /* Check reference counter. */
+ if (pj_atomic_get(ack->ref_cnt) != 1) {
+ PJ_LOG(3,("", " error: invalid ref count in ACK request"));
+ return -105;
+ }
+ /* Check message type. */
+ if (ack->msg->type != PJSIP_REQUEST_MSG)
+ return -106;
+ /* Check method. */
+ if (ack->msg->line.req.method.id != PJSIP_ACK_METHOD)
+ return -107;
+ /* Check Request-URI is present. */
+ if (ack->msg->line.req.uri == NULL)
+ return -108;
+
+ /* Check that mandatory headers are again present. */
+ if (HFIND(ack->msg, from, FROM) == 0)
+ return -110;
+ if (HFIND(ack->msg, to, TO) == 0)
+ return -111;
+ if (HFIND(ack->msg, cid, CALL_ID) == 0)
+ return -112;
+ if (HFIND(ack->msg, cseq, CSEQ) == 0)
+ return -113;
+ if (HFIND(ack->msg, via, VIA) == 0)
+ return -114;
+ if (ack->msg->body != NULL)
+ return -115;
+
+ /* Done checking invite message. */
+ if (pjsip_tx_data_dec_ref(invite) != PJSIP_EBUFDESTROYED) {
+ PJ_LOG(3,("", " error: response buffer not destroyed!"));
+ return -120;
+ }
+
+ /* Done checking response message. */
+ if (pjsip_tx_data_dec_ref(response) != PJSIP_EBUFDESTROYED) {
+ PJ_LOG(3,("", " error: response buffer not destroyed!"));
+ return -130;
+ }
+
+ /* Done checking ack message. */
+ if (pjsip_tx_data_dec_ref(ack) != PJSIP_EBUFDESTROYED) {
+ PJ_LOG(3,("", " error: response buffer not destroyed!"));
+ return -140;
+ }
+
+ /* Done. */
+ return 0;
+}
+