This is about the simplest SIP application with PJSIP, all it does is respond all incoming requests with 501 (Not Implemented) response statelessly.
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00030
00031 #include <pjsip.h>
00032 #include <pjlib-util.h>
00033 #include <pjlib.h>
00034
00035
00036
00037 #define HAS_UDP_TRANSPORT
00038
00039
00040 #define HAS_TCP_TRANSPORT (1 && PJ_HAS_TCP)
00041
00042
00043 #define THIS_FILE "sipstateless.c"
00044
00045
00046
00047 static pjsip_endpoint *sip_endpt;
00048
00049
00050 static int code = PJSIP_SC_NOT_IMPLEMENTED;
00051
00052
00053 struct pjsip_hdr hdr_list;
00054
00055
00056 static void usage(void)
00057 {
00058 puts("Usage:");
00059 puts(" sipstateless [code] [-H HDR] ..");
00060 puts("");
00061 puts("Options:");
00062 puts(" code SIP status code to send (default: 501/Not Implemented");
00063 puts(" -H HDR Specify additional headers to send with response");
00064 puts(" This option may be specified more than once.");
00065 puts(" Example:");
00066 puts(" -H 'Expires: 300' -H 'Contact: <sip:localhost>'");
00067 }
00068
00069
00070
00071 static pj_bool_t on_rx_request( pjsip_rx_data *rdata )
00072 {
00073
00074
00075
00076 if (rdata->msg_info.msg->line.req.method.id != PJSIP_ACK_METHOD) {
00077 pjsip_endpt_respond_stateless( sip_endpt, rdata,
00078 code, NULL,
00079 &hdr_list, NULL);
00080 }
00081 return PJ_TRUE;
00082 }
00083
00084
00085
00086
00087
00088
00089
00090 int main(int argc, char *argv[])
00091 {
00092 pj_caching_pool cp;
00093 pj_pool_t *pool = NULL;
00094 pjsip_module mod_app =
00095 {
00096 NULL, NULL,
00097 { "mod-app", 7 },
00098 -1,
00099 PJSIP_MOD_PRIORITY_APPLICATION,
00100 NULL,
00101 NULL,
00102 NULL,
00103 NULL,
00104 &on_rx_request,
00105 NULL,
00106 NULL,
00107 NULL,
00108 NULL,
00109 };
00110 int c;
00111 pj_status_t status;
00112
00113
00114 status = pj_init();
00115 PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
00116
00117
00118
00119 status = pjlib_util_init();
00120 PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
00121
00122
00123 pj_caching_pool_init(&cp, &pj_pool_factory_default_policy, 0);
00124
00125
00126 {
00127
00128
00129
00130
00131
00132
00133 status = pjsip_endpt_create(&cp.factory, "sipstateless",
00134 &sip_endpt);
00135 PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
00136 }
00137
00138
00139 pj_optind = 0;
00140 pj_list_init(&hdr_list);
00141 while ((c=pj_getopt(argc, argv , "H:")) != -1) {
00142 switch (c) {
00143 case 'H':
00144 if (pool == NULL) {
00145 pool = pj_pool_create(&cp.factory, "sipstateless", 1000,
00146 1000, NULL);
00147 }
00148
00149 if (pool) {
00150 char *name;
00151 name = strtok(pj_optarg, ":");
00152 if (name == NULL) {
00153 puts("Error: invalid header format");
00154 return 1;
00155 } else {
00156 char *val = strtok(NULL, "\r\n");
00157 pjsip_generic_string_hdr *h;
00158 pj_str_t hname, hvalue;
00159
00160 hname = pj_str(name);
00161 hvalue = pj_str(val);
00162
00163 h = pjsip_generic_string_hdr_create(pool, &hname, &hvalue);
00164
00165 pj_list_push_back(&hdr_list, h);
00166
00167 PJ_LOG(4,(THIS_FILE, "Header %s: %s added", name, val));
00168 }
00169 }
00170 break;
00171 default:
00172 puts("Error: invalid argument");
00173 usage();
00174 return 1;
00175 }
00176 }
00177
00178 if (pj_optind != argc) {
00179 code = atoi(argv[pj_optind]);
00180 if (code < 200 || code > 699) {
00181 puts("Error: invalid status code");
00182 usage();
00183 return 1;
00184 }
00185 }
00186
00187 PJ_LOG(4,(THIS_FILE, "Returning %d to incoming requests", code));
00188
00189
00190
00191
00192
00193 #ifdef HAS_UDP_TRANSPORT
00194 {
00195 pj_sockaddr_in addr;
00196
00197 addr.sin_family = pj_AF_INET();
00198 addr.sin_addr.s_addr = 0;
00199 addr.sin_port = pj_htons(5060);
00200
00201 status = pjsip_udp_transport_start( sip_endpt, &addr, NULL, 1, NULL);
00202 if (status != PJ_SUCCESS) {
00203 PJ_LOG(3,(THIS_FILE,
00204 "Error starting UDP transport (port in use?)"));
00205 return 1;
00206 }
00207 }
00208 #endif
00209
00210 #if HAS_TCP_TRANSPORT
00211
00212
00213
00214 {
00215 pj_sockaddr_in addr;
00216
00217 addr.sin_family = pj_AF_INET();
00218 addr.sin_addr.s_addr = 0;
00219 addr.sin_port = pj_htons(5060);
00220
00221 status = pjsip_tcp_transport_start(sip_endpt, &addr, 1, NULL);
00222 if (status != PJ_SUCCESS) {
00223 PJ_LOG(3,(THIS_FILE,
00224 "Error starting TCP transport (port in use?)"));
00225 return 1;
00226 }
00227 }
00228 #endif
00229
00230
00231
00232
00233 status = pjsip_endpt_register_module( sip_endpt, &mod_app);
00234 PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
00235
00236
00237
00238 PJ_LOG(3,(THIS_FILE, "Press Ctrl-C to quit.."));
00239
00240 for (;;) {
00241 pjsip_endpt_handle_events(sip_endpt, NULL);
00242 }
00243 }