diff options
Diffstat (limited to 'pjsip-apps/src/samples/sipstateless.c')
-rw-r--r-- | pjsip-apps/src/samples/sipstateless.c | 243 |
1 files changed, 243 insertions, 0 deletions
diff --git a/pjsip-apps/src/samples/sipstateless.c b/pjsip-apps/src/samples/sipstateless.c new file mode 100644 index 0000000..0de89a6 --- /dev/null +++ b/pjsip-apps/src/samples/sipstateless.c @@ -0,0 +1,243 @@ +/* $Id: sipstateless.c 3553 2011-05-05 06:14:19Z nanang $ */ +/* + * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com) + * Copyright (C) 2003-2008 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 + */ + +/** + * sipcore.c + * + * A simple program to respond any incoming requests (except ACK, of course!) + * with any status code (taken from command line argument, with the default + * is 501/Not Implemented). + */ + + +/* Include all headers. */ +#include <pjsip.h> +#include <pjlib-util.h> +#include <pjlib.h> + + +/* If this macro is set, UDP transport will be initialized at port 5060 */ +#define HAS_UDP_TRANSPORT + +/* If this macro is set, TCP transport will be initialized at port 5060 */ +#define HAS_TCP_TRANSPORT (1 && PJ_HAS_TCP) + +/* Log identification */ +#define THIS_FILE "sipstateless.c" + + +/* Global SIP endpoint */ +static pjsip_endpoint *sip_endpt; + +/* What response code to be sent (default is 501/Not Implemented) */ +static int code = PJSIP_SC_NOT_IMPLEMENTED; + +/* Additional header list */ +struct pjsip_hdr hdr_list; + +/* usage() */ +static void usage(void) +{ + puts("Usage:"); + puts(" sipstateless [code] [-H HDR] .."); + puts(""); + puts("Options:"); + puts(" code SIP status code to send (default: 501/Not Implemented"); + puts(" -H HDR Specify additional headers to send with response"); + puts(" This option may be specified more than once."); + puts(" Example:"); + puts(" -H 'Expires: 300' -H 'Contact: <sip:localhost>'"); +} + + +/* Callback to handle incoming requests. */ +static pj_bool_t on_rx_request( pjsip_rx_data *rdata ) +{ + /* Respond (statelessly) all incoming requests (except ACK!) + * with 501 (Not Implemented) + */ + if (rdata->msg_info.msg->line.req.method.id != PJSIP_ACK_METHOD) { + pjsip_endpt_respond_stateless( sip_endpt, rdata, + code, NULL, + &hdr_list, NULL); + } + return PJ_TRUE; +} + + + +/* + * main() + * + */ +int main(int argc, char *argv[]) +{ + pj_caching_pool cp; + pj_pool_t *pool = NULL; + pjsip_module mod_app = + { + NULL, NULL, /* prev, next. */ + { "mod-app", 7 }, /* Name. */ + -1, /* Id */ + PJSIP_MOD_PRIORITY_APPLICATION, /* Priority */ + NULL, /* load() */ + NULL, /* start() */ + NULL, /* stop() */ + NULL, /* unload() */ + &on_rx_request, /* on_rx_request() */ + NULL, /* on_rx_response() */ + NULL, /* on_tx_request. */ + NULL, /* on_tx_response() */ + NULL, /* on_tsx_state() */ + }; + int c; + pj_status_t status; + + /* Must init PJLIB first: */ + status = pj_init(); + PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1); + + + /* Then init PJLIB-UTIL: */ + status = pjlib_util_init(); + PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1); + + /* Must create a pool factory before we can allocate any memory. */ + pj_caching_pool_init(&cp, &pj_pool_factory_default_policy, 0); + + /* Create global endpoint: */ + { + /* Endpoint MUST be assigned a globally unique name. + * Ideally we should put hostname or public IP address, but + * we'll just use an arbitrary name here. + */ + + /* Create the endpoint: */ + status = pjsip_endpt_create(&cp.factory, "sipstateless", + &sip_endpt); + PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1); + } + + /* Parse arguments */ + pj_optind = 0; + pj_list_init(&hdr_list); + while ((c=pj_getopt(argc, argv , "H:")) != -1) { + switch (c) { + case 'H': + if (pool == NULL) { + pool = pj_pool_create(&cp.factory, "sipstateless", 1000, + 1000, NULL); + } + + if (pool) { + char *name; + name = strtok(pj_optarg, ":"); + if (name == NULL) { + puts("Error: invalid header format"); + return 1; + } else { + char *val = strtok(NULL, "\r\n"); + pjsip_generic_string_hdr *h; + pj_str_t hname, hvalue; + + hname = pj_str(name); + hvalue = pj_str(val); + + h = pjsip_generic_string_hdr_create(pool, &hname, &hvalue); + + pj_list_push_back(&hdr_list, h); + + PJ_LOG(4,(THIS_FILE, "Header %s: %s added", name, val)); + } + } + break; + default: + puts("Error: invalid argument"); + usage(); + return 1; + } + } + + if (pj_optind != argc) { + code = atoi(argv[pj_optind]); + if (code < 200 || code > 699) { + puts("Error: invalid status code"); + usage(); + return 1; + } + } + + PJ_LOG(4,(THIS_FILE, "Returning %d to incoming requests", code)); + + + /* + * Add UDP transport, with hard-coded port + */ +#ifdef HAS_UDP_TRANSPORT + { + pj_sockaddr_in addr; + + addr.sin_family = pj_AF_INET(); + addr.sin_addr.s_addr = 0; + addr.sin_port = pj_htons(5060); + + status = pjsip_udp_transport_start( sip_endpt, &addr, NULL, 1, NULL); + if (status != PJ_SUCCESS) { + PJ_LOG(3,(THIS_FILE, + "Error starting UDP transport (port in use?)")); + return 1; + } + } +#endif + +#if HAS_TCP_TRANSPORT + /* + * Add UDP transport, with hard-coded port + */ + { + pj_sockaddr_in addr; + + addr.sin_family = pj_AF_INET(); + addr.sin_addr.s_addr = 0; + addr.sin_port = pj_htons(5060); + + status = pjsip_tcp_transport_start(sip_endpt, &addr, 1, NULL); + if (status != PJ_SUCCESS) { + PJ_LOG(3,(THIS_FILE, + "Error starting TCP transport (port in use?)")); + return 1; + } + } +#endif + + /* + * Register our module to receive incoming requests. + */ + status = pjsip_endpt_register_module( sip_endpt, &mod_app); + PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1); + + + /* Done. Loop forever to handle incoming events. */ + PJ_LOG(3,(THIS_FILE, "Press Ctrl-C to quit..")); + + for (;;) { + pjsip_endpt_handle_events(sip_endpt, NULL); + } +} |