1
/* $Id: sipstateless.c 3553 2011-05-05 06:14:19Z nanang $ */
3
* Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
4
* Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
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.
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.
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
24
* A simple program to respond any incoming requests (except ACK, of course!)
25
* with any status code (taken from command line argument, with the default
26
* is 501/Not Implemented).
30
/* Include all headers. */
32
#include <pjlib-util.h>
36
/* If this macro is set, UDP transport will be initialized at port 5060 */
37
#define HAS_UDP_TRANSPORT
39
/* If this macro is set, TCP transport will be initialized at port 5060 */
40
#define HAS_TCP_TRANSPORT (1 && PJ_HAS_TCP)
42
/* Log identification */
43
#define THIS_FILE "sipstateless.c"
46
/* Global SIP endpoint */
47
static pjsip_endpoint *sip_endpt;
49
/* What response code to be sent (default is 501/Not Implemented) */
50
static int code = PJSIP_SC_NOT_IMPLEMENTED;
52
/* Additional header list */
53
struct pjsip_hdr hdr_list;
56
static void usage(void)
59
puts(" sipstateless [code] [-H HDR] ..");
62
puts(" code SIP status code to send (default: 501/Not Implemented");
63
puts(" -H HDR Specify additional headers to send with response");
64
puts(" This option may be specified more than once.");
66
puts(" -H 'Expires: 300' -H 'Contact: <sip:localhost>'");
70
/* Callback to handle incoming requests. */
71
static pj_bool_t on_rx_request( pjsip_rx_data *rdata )
73
/* Respond (statelessly) all incoming requests (except ACK!)
74
* with 501 (Not Implemented)
76
if (rdata->msg_info.msg->line.req.method.id != PJSIP_ACK_METHOD) {
77
pjsip_endpt_respond_stateless( sip_endpt, rdata,
90
int main(int argc, char *argv[])
93
pj_pool_t *pool = NULL;
94
pjsip_module mod_app =
96
NULL, NULL, /* prev, next. */
97
{ "mod-app", 7 }, /* Name. */
99
PJSIP_MOD_PRIORITY_APPLICATION, /* Priority */
104
&on_rx_request, /* on_rx_request() */
105
NULL, /* on_rx_response() */
106
NULL, /* on_tx_request. */
107
NULL, /* on_tx_response() */
108
NULL, /* on_tsx_state() */
113
/* Must init PJLIB first: */
115
PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
118
/* Then init PJLIB-UTIL: */
119
status = pjlib_util_init();
120
PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
122
/* Must create a pool factory before we can allocate any memory. */
123
pj_caching_pool_init(&cp, &pj_pool_factory_default_policy, 0);
125
/* Create global endpoint: */
127
/* Endpoint MUST be assigned a globally unique name.
128
* Ideally we should put hostname or public IP address, but
129
* we'll just use an arbitrary name here.
132
/* Create the endpoint: */
133
status = pjsip_endpt_create(&cp.factory, "sipstateless",
135
PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
138
/* Parse arguments */
140
pj_list_init(&hdr_list);
141
while ((c=pj_getopt(argc, argv , "H:")) != -1) {
145
pool = pj_pool_create(&cp.factory, "sipstateless", 1000,
151
name = strtok(pj_optarg, ":");
153
puts("Error: invalid header format");
156
char *val = strtok(NULL, "\r\n");
157
pjsip_generic_string_hdr *h;
158
pj_str_t hname, hvalue;
160
hname = pj_str(name);
161
hvalue = pj_str(val);
163
h = pjsip_generic_string_hdr_create(pool, &hname, &hvalue);
165
pj_list_push_back(&hdr_list, h);
167
PJ_LOG(4,(THIS_FILE, "Header %s: %s added", name, val));
172
puts("Error: invalid argument");
178
if (pj_optind != argc) {
179
code = atoi(argv[pj_optind]);
180
if (code < 200 || code > 699) {
181
puts("Error: invalid status code");
187
PJ_LOG(4,(THIS_FILE, "Returning %d to incoming requests", code));
191
* Add UDP transport, with hard-coded port
193
#ifdef HAS_UDP_TRANSPORT
197
addr.sin_family = pj_AF_INET();
198
addr.sin_addr.s_addr = 0;
199
addr.sin_port = pj_htons(5060);
201
status = pjsip_udp_transport_start( sip_endpt, &addr, NULL, 1, NULL);
202
if (status != PJ_SUCCESS) {
204
"Error starting UDP transport (port in use?)"));
210
#if HAS_TCP_TRANSPORT
212
* Add UDP transport, with hard-coded port
217
addr.sin_family = pj_AF_INET();
218
addr.sin_addr.s_addr = 0;
219
addr.sin_port = pj_htons(5060);
221
status = pjsip_tcp_transport_start(sip_endpt, &addr, 1, NULL);
222
if (status != PJ_SUCCESS) {
224
"Error starting TCP transport (port in use?)"));
231
* Register our module to receive incoming requests.
233
status = pjsip_endpt_register_module( sip_endpt, &mod_app);
234
PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
237
/* Done. Loop forever to handle incoming events. */
238
PJ_LOG(3,(THIS_FILE, "Press Ctrl-C to quit.."));
241
pjsip_endpt_handle_events(sip_endpt, NULL);