WARNING: The online documentation has moved to https://docs.pjsip.org.

Visit the new documentation at https://docs.pjsip.org:

BLOG | DOCUMENTATION | GITHUB

Home --> Documentations --> PJSIP Reference

Samples: Stateless SIP Endpoint

This is about the simplest SIP application with PJSIP, all it does is respond all incoming requests with 501 (Not Implemented) response statelessly.

1/*
2 * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
3 * Copyright (C) 2003-2008 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
29/* Include all headers. */
30#include <pjsip.h>
31#include <pjlib-util.h>
32#include <pjlib.h>
33
34
35/* If this macro is set, UDP transport will be initialized at port 5060 */
36#define HAS_UDP_TRANSPORT
37
38/* If this macro is set, TCP transport will be initialized at port 5060 */
39#define HAS_TCP_TRANSPORT (1 && PJ_HAS_TCP)
40
41/* Log identification */
42#define THIS_FILE "sipstateless.c"
43
44
45/* Global SIP endpoint */
46static pjsip_endpoint *sip_endpt;
47
48/* What response code to be sent (default is 501/Not Implemented) */
49static int code = PJSIP_SC_NOT_IMPLEMENTED;
50
51/* Additional header list */
52struct pjsip_hdr hdr_list;
53
54/* usage() */
55static void usage(void)
56{
57 puts("Usage:");
58 puts(" sipstateless [code] [-H HDR] ..");
59 puts("");
60 puts("Options:");
61 puts(" code SIP status code to send (default: 501/Not Implemented");
62 puts(" -H HDR Specify additional headers to send with response");
63 puts(" This option may be specified more than once.");
64 puts(" Example:");
65 puts(" -H 'Expires: 300' -H 'Contact: <sip:localhost>'");
66}
67
68
69/* Callback to handle incoming requests. */
70static pj_bool_t on_rx_request( pjsip_rx_data *rdata )
71{
72 /* Respond (statelessly) all incoming requests (except ACK!)
73 * with 501 (Not Implemented)
74 */
75 if (rdata->msg_info.msg->line.req.method.id != PJSIP_ACK_METHOD) {
76 pjsip_endpt_respond_stateless( sip_endpt, rdata,
77 code, NULL,
78 &hdr_list, NULL);
79 }
80 return PJ_TRUE;
81}
82
83
84
85/*
86 * main()
87 *
88 */
89int main(int argc, char *argv[])
90{
92 pj_pool_t *pool = NULL;
93 pjsip_module mod_app =
94 {
95 NULL, NULL, /* prev, next. */
96 { "mod-app", 7 }, /* Name. */
97 -1, /* Id */
98 PJSIP_MOD_PRIORITY_APPLICATION, /* Priority */
99 NULL, /* load() */
100 NULL, /* start() */
101 NULL, /* stop() */
102 NULL, /* unload() */
103 &on_rx_request, /* on_rx_request() */
104 NULL, /* on_rx_response() */
105 NULL, /* on_tx_request. */
106 NULL, /* on_tx_response() */
107 NULL, /* on_tsx_state() */
108 };
109 int c;
110 pj_status_t status;
111
112 /* Must init PJLIB first: */
113 status = pj_init();
114 PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
115
116
117 /* Then init PJLIB-UTIL: */
118 status = pjlib_util_init();
119 PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
120
121 /* Must create a pool factory before we can allocate any memory. */
123
124 /* Create global endpoint: */
125 {
126 /* Endpoint MUST be assigned a globally unique name.
127 * Ideally we should put hostname or public IP address, but
128 * we'll just use an arbitrary name here.
129 */
130
131 /* Create the endpoint: */
132 status = pjsip_endpt_create(&cp.factory, "sipstateless",
133 &sip_endpt);
134 PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
135 }
136
137 /* Parse arguments */
138 pj_optind = 0;
139 pj_list_init(&hdr_list);
140 while ((c=pj_getopt(argc, argv , "H:")) != -1) {
141 switch (c) {
142 case 'H':
143 if (pool == NULL) {
144 pool = pj_pool_create(&cp.factory, "sipstateless", 1000,
145 1000, NULL);
146 }
147
148 if (pool) {
149 char *name;
150 name = strtok(pj_optarg, ":");
151 if (name == NULL) {
152 puts("Error: invalid header format");
153 return 1;
154 } else {
155 char *val = strtok(NULL, "\r\n");
157 pj_str_t hname, hvalue;
158
159 hname = pj_str(name);
160 hvalue = pj_str(val);
161
162 h = pjsip_generic_string_hdr_create(pool, &hname, &hvalue);
163
164 pj_list_push_back(&hdr_list, h);
165
166 PJ_LOG(4,(THIS_FILE, "Header %s: %s added", name, val));
167 }
168 }
169 break;
170 default:
171 puts("Error: invalid argument");
172 usage();
173 return 1;
174 }
175 }
176
177 if (pj_optind != argc) {
178 code = atoi(argv[pj_optind]);
179 if (code < 200 || code > 699) {
180 puts("Error: invalid status code");
181 usage();
182 return 1;
183 }
184 }
185
186 PJ_LOG(4,(THIS_FILE, "Returning %d to incoming requests", code));
187
188
189 /*
190 * Add UDP transport, with hard-coded port
191 */
192#ifdef HAS_UDP_TRANSPORT
193 {
194 pj_sockaddr_in addr;
195
196 addr.sin_family = pj_AF_INET();
197 addr.sin_addr.s_addr = 0;
198 addr.sin_port = pj_htons(5060);
199
200 status = pjsip_udp_transport_start( sip_endpt, &addr, NULL, 1, NULL);
201 if (status != PJ_SUCCESS) {
202 PJ_LOG(3,(THIS_FILE,
203 "Error starting UDP transport (port in use?)"));
204 return 1;
205 }
206 }
207#endif
208
209#if HAS_TCP_TRANSPORT
210 /*
211 * Add UDP transport, with hard-coded port
212 */
213 {
214 pj_sockaddr_in addr;
215
216 addr.sin_family = pj_AF_INET();
217 addr.sin_addr.s_addr = 0;
218 addr.sin_port = pj_htons(5060);
219
220 status = pjsip_tcp_transport_start(sip_endpt, &addr, 1, NULL);
221 if (status != PJ_SUCCESS) {
222 PJ_LOG(3,(THIS_FILE,
223 "Error starting TCP transport (port in use?)"));
224 return 1;
225 }
226 }
227#endif
228
229 /*
230 * Register our module to receive incoming requests.
231 */
232 status = pjsip_endpt_register_module( sip_endpt, &mod_app);
233 PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
234
235
236 /* Done. Loop forever to handle incoming events. */
237 PJ_LOG(3,(THIS_FILE, "Press Ctrl-C to quit.."));
238
239 for (;;) {
240 pjsip_endpt_handle_events(sip_endpt, NULL);
241 }
242}
pj_status_t pjlib_util_init(void)
pj_status_t pjsip_endpt_respond_stateless(pjsip_endpoint *endpt, pjsip_rx_data *rdata, int st_code, const pj_str_t *st_text, const pjsip_hdr *hdr_list, const pjsip_msg_body *body)
pj_status_t pjsip_endpt_register_module(pjsip_endpoint *endpt, pjsip_module *module)
pj_status_t pjsip_endpt_handle_events(pjsip_endpoint *endpt, const pj_time_val *max_timeout)
pj_status_t pjsip_endpt_create(pj_pool_factory *pf, const char *name, pjsip_endpoint **endpt)
@ PJSIP_MOD_PRIORITY_APPLICATION
Definition: sip_module.h:210
pjsip_generic_string_hdr * pjsip_generic_string_hdr_create(pj_pool_t *pool, const pj_str_t *hname, const pj_str_t *hvalue)
@ PJSIP_ACK_METHOD
Definition: sip_msg.h:58
pj_status_t pjsip_tcp_transport_start(pjsip_endpoint *endpt, const pj_sockaddr_in *local, unsigned async_cnt, pjsip_tpfactory **p_factory)
pj_status_t pjsip_udp_transport_start(pjsip_endpoint *endpt, const pj_sockaddr_in *local, const pjsip_host_port *a_name, unsigned async_cnt, pjsip_transport **p_transport)
struct pjsip_endpoint pjsip_endpoint
Definition: sip_types.h:111
pj_status_t pj_init(void)
int pj_bool_t
int pj_status_t
PJ_SUCCESS
PJ_TRUE
void pj_caching_pool_init(pj_caching_pool *ch_pool, const pj_pool_factory_policy *policy, pj_size_t max_capacity)
void pj_list_init(pj_list_type *node)
void pj_list_push_back(pj_list_type *list, pj_list_type *node)
#define PJ_LOG(level, arg)
pj_pool_factory_policy pj_pool_factory_default_policy
pj_pool_t * pj_pool_create(pj_pool_factory *factory, const char *name, pj_size_t initial_size, pj_size_t increment_size, pj_pool_callback *callback)
pj_str_t pj_str(char *str)
pj_uint16_t pj_htons(pj_uint16_t hostshort)
#define pj_AF_INET()
#define PJ_ASSERT_RETURN(expr, retval)
pj_pool_factory factory
pj_uint16_t sin_port
pj_uint16_t sin_family
pj_in_addr sin_addr
Definition: sip_msg.h:1070
Definition: sip_msg.h:324
pj_str_t name
Definition: sip_msg.h:325
pjsip_method_e id
Definition: sip_msg.h:78
Definition: sip_module.h:54
struct pjsip_request_line req
Definition: sip_msg.h:868
union pjsip_msg::@19 line
pjsip_method method
Definition: sip_msg.h:434
Definition: sip_transport.h:295
struct pjsip_rx_data::@26 msg_info
pjsip_msg * msg
Definition: sip_transport.h:364

 


PJSIP Open Source, high performance, small footprint, and very very portable SIP stack
Copyright (C) 2006-2008 Teluu Inc.