BLOG | DOCUMENTATION | TRAC

Home --> Documentations --> PJSIP Reference

Samples: Simple UA

This is a very simple SIP User Agent application that only use PJSIP (without PJSIP-UA). It's able to make and receive call, and play media to the sound device.

1 /* $Id: simpleua.c 5943 2019-03-08 02:57:22Z ming $ */
2 /*
3  * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
4  * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
5  *
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.
10  *
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.
15  *
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
19  */
20 
21 
54 /* Include all headers. */
55 #include <pjsip.h>
56 #include <pjmedia.h>
57 #include <pjmedia-codec.h>
58 #include <pjsip_ua.h>
59 #include <pjsip_simple.h>
60 #include <pjlib-util.h>
61 #include <pjlib.h>
62 
63 /* For logging purpose. */
64 #define THIS_FILE "simpleua.c"
65 
66 #include "util.h"
67 
68 
69 /* Settings */
70 #define AF pj_AF_INET() /* Change to pj_AF_INET6() for IPv6.
71  * PJ_HAS_IPV6 must be enabled and
72  * your system must support IPv6. */
73 #if 0
74 #define SIP_PORT 5080 /* Listening SIP port */
75 #define RTP_PORT 5000 /* RTP port */
76 #else
77 #define SIP_PORT 5060 /* Listening SIP port */
78 #define RTP_PORT 4000 /* RTP port */
79 #endif
80 
81 #define MAX_MEDIA_CNT 2 /* Media count, set to 1 for audio
82  * only or 2 for audio and video */
83 
84 /*
85  * Static variables.
86  */
87 
88 static pj_bool_t g_complete; /* Quit flag. */
89 static pjsip_endpoint *g_endpt; /* SIP endpoint. */
90 static pj_caching_pool cp; /* Global pool factory. */
91 
92 static pjmedia_endpt *g_med_endpt; /* Media endpoint. */
93 
94 static pjmedia_transport_info g_med_tpinfo[MAX_MEDIA_CNT];
95  /* Socket info for media */
96 static pjmedia_transport *g_med_transport[MAX_MEDIA_CNT];
97  /* Media stream transport */
98 static pjmedia_sock_info g_sock_info[MAX_MEDIA_CNT];
99  /* Socket info array */
100 
101 /* Call variables: */
102 static pjsip_inv_session *g_inv; /* Current invite session. */
103 static pjmedia_stream *g_med_stream; /* Call's audio stream. */
104 static pjmedia_snd_port *g_snd_port; /* Sound device. */
105 
106 #if defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0)
107 static pjmedia_vid_stream *g_med_vstream; /* Call's video stream. */
108 static pjmedia_vid_port *g_vid_capturer;/* Call's video capturer. */
109 static pjmedia_vid_port *g_vid_renderer;/* Call's video renderer. */
110 #endif /* PJMEDIA_HAS_VIDEO */
111 
112 /*
113  * Prototypes:
114  */
115 
116 /* Callback to be called when SDP negotiation is done in the call: */
117 static void call_on_media_update( pjsip_inv_session *inv,
118  pj_status_t status);
119 
120 /* Callback to be called when invite session's state has changed: */
121 static void call_on_state_changed( pjsip_inv_session *inv,
122  pjsip_event *e);
123 
124 /* Callback to be called when dialog has forked: */
125 static void call_on_forked(pjsip_inv_session *inv, pjsip_event *e);
126 
127 /* Callback to be called to handle incoming requests outside dialogs: */
128 static pj_bool_t on_rx_request( pjsip_rx_data *rdata );
129 
130 
131 
132 
133 /* This is a PJSIP module to be registered by application to handle
134  * incoming requests outside any dialogs/transactions. The main purpose
135  * here is to handle incoming INVITE request message, where we will
136  * create a dialog and INVITE session for it.
137  */
138 static pjsip_module mod_simpleua =
139 {
140  NULL, NULL, /* prev, next. */
141  { "mod-simpleua", 12 }, /* Name. */
142  -1, /* Id */
143  PJSIP_MOD_PRIORITY_APPLICATION, /* Priority */
144  NULL, /* load() */
145  NULL, /* start() */
146  NULL, /* stop() */
147  NULL, /* unload() */
148  &on_rx_request, /* on_rx_request() */
149  NULL, /* on_rx_response() */
150  NULL, /* on_tx_request. */
151  NULL, /* on_tx_response() */
152  NULL, /* on_tsx_state() */
153 };
154 
155 
156 /* Notification on incoming messages */
157 static pj_bool_t logging_on_rx_msg(pjsip_rx_data *rdata)
158 {
159  PJ_LOG(4,(THIS_FILE, "RX %d bytes %s from %s %s:%d:\n"
160  "%.*s\n"
161  "--end msg--",
162  rdata->msg_info.len,
163  pjsip_rx_data_get_info(rdata),
164  rdata->tp_info.transport->type_name,
165  rdata->pkt_info.src_name,
166  rdata->pkt_info.src_port,
167  (int)rdata->msg_info.len,
168  rdata->msg_info.msg_buf));
169 
170  /* Always return false, otherwise messages will not get processed! */
171  return PJ_FALSE;
172 }
173 
174 /* Notification on outgoing messages */
175 static pj_status_t logging_on_tx_msg(pjsip_tx_data *tdata)
176 {
177 
178  /* Important note:
179  * tp_info field is only valid after outgoing messages has passed
180  * transport layer. So don't try to access tp_info when the module
181  * has lower priority than transport layer.
182  */
183 
184  PJ_LOG(4,(THIS_FILE, "TX %d bytes %s to %s %s:%d:\n"
185  "%.*s\n"
186  "--end msg--",
187  (tdata->buf.cur - tdata->buf.start),
188  pjsip_tx_data_get_info(tdata),
189  tdata->tp_info.transport->type_name,
190  tdata->tp_info.dst_name,
191  tdata->tp_info.dst_port,
192  (int)(tdata->buf.cur - tdata->buf.start),
193  tdata->buf.start));
194 
195  /* Always return success, otherwise message will not get sent! */
196  return PJ_SUCCESS;
197 }
198 
199 /* The module instance. */
200 static pjsip_module msg_logger =
201 {
202  NULL, NULL, /* prev, next. */
203  { "mod-msg-log", 13 }, /* Name. */
204  -1, /* Id */
205  PJSIP_MOD_PRIORITY_TRANSPORT_LAYER-1,/* Priority */
206  NULL, /* load() */
207  NULL, /* start() */
208  NULL, /* stop() */
209  NULL, /* unload() */
210  &logging_on_rx_msg, /* on_rx_request() */
211  &logging_on_rx_msg, /* on_rx_response() */
212  &logging_on_tx_msg, /* on_tx_request. */
213  &logging_on_tx_msg, /* on_tx_response() */
214  NULL, /* on_tsx_state() */
215 
216 };
217 
218 
219 /*
220  * main()
221  *
222  * If called with argument, treat argument as SIP URL to be called.
223  * Otherwise wait for incoming calls.
224  */
225 int main(int argc, char *argv[])
226 {
227  pj_pool_t *pool = NULL;
228  pj_status_t status;
229  unsigned i;
230 
231  /* Must init PJLIB first: */
232  status = pj_init();
233  PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
234 
235  pj_log_set_level(5);
236 
237  /* Then init PJLIB-UTIL: */
238  status = pjlib_util_init();
239  PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
240 
241 
242  /* Must create a pool factory before we can allocate any memory. */
244 
245 
246  /* Create global endpoint: */
247  {
248  const pj_str_t *hostname;
249  const char *endpt_name;
250 
251  /* Endpoint MUST be assigned a globally unique name.
252  * The name will be used as the hostname in Warning header.
253  */
254 
255  /* For this implementation, we'll use hostname for simplicity */
256  hostname = pj_gethostname();
257  endpt_name = hostname->ptr;
258 
259  /* Create the endpoint: */
260 
261  status = pjsip_endpt_create(&cp.factory, endpt_name,
262  &g_endpt);
263  PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
264  }
265 
266 
267  /*
268  * Add UDP transport, with hard-coded port
269  * Alternatively, application can use pjsip_udp_transport_attach() to
270  * start UDP transport, if it already has an UDP socket (e.g. after it
271  * resolves the address with STUN).
272  */
273  {
274  pj_sockaddr addr;
275 
276  pj_sockaddr_init(AF, &addr, NULL, (pj_uint16_t)SIP_PORT);
277 
278  if (AF == pj_AF_INET()) {
279  status = pjsip_udp_transport_start( g_endpt, &addr.ipv4, NULL,
280  1, NULL);
281  } else if (AF == pj_AF_INET6()) {
282  status = pjsip_udp_transport_start6(g_endpt, &addr.ipv6, NULL,
283  1, NULL);
284  } else {
285  status = PJ_EAFNOTSUP;
286  }
287 
288  if (status != PJ_SUCCESS) {
289  app_perror(THIS_FILE, "Unable to start UDP transport", status);
290  return 1;
291  }
292  }
293 
294 
295  /*
296  * Init transaction layer.
297  * This will create/initialize transaction hash tables etc.
298  */
299  status = pjsip_tsx_layer_init_module(g_endpt);
300  PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
301 
302 
303  /*
304  * Initialize UA layer module.
305  * This will create/initialize dialog hash tables etc.
306  */
307  status = pjsip_ua_init_module( g_endpt, NULL );
308  PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
309 
310 
311  /*
312  * Init invite session module.
313  * The invite session module initialization takes additional argument,
314  * i.e. a structure containing callbacks to be called on specific
315  * occurence of events.
316  *
317  * The on_state_changed and on_new_session callbacks are mandatory.
318  * Application must supply the callback function.
319  *
320  * We use on_media_update() callback in this application to start
321  * media transmission.
322  */
323  {
324  pjsip_inv_callback inv_cb;
325 
326  /* Init the callback for INVITE session: */
327  pj_bzero(&inv_cb, sizeof(inv_cb));
328  inv_cb.on_state_changed = &call_on_state_changed;
329  inv_cb.on_new_session = &call_on_forked;
330  inv_cb.on_media_update = &call_on_media_update;
331 
332  /* Initialize invite session module: */
333  status = pjsip_inv_usage_init(g_endpt, &inv_cb);
334  PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
335  }
336 
337  /* Initialize 100rel support */
338  status = pjsip_100rel_init_module(g_endpt);
339  PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
340 
341  /*
342  * Register our module to receive incoming requests.
343  */
344  status = pjsip_endpt_register_module( g_endpt, &mod_simpleua);
345  PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
346 
347  /*
348  * Register message logger module.
349  */
350  status = pjsip_endpt_register_module( g_endpt, &msg_logger);
351  PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
352 
353 
354  /*
355  * Initialize media endpoint.
356  * This will implicitly initialize PJMEDIA too.
357  */
358 #if PJ_HAS_THREADS
359  status = pjmedia_endpt_create(&cp.factory, NULL, 1, &g_med_endpt);
360 #else
361  status = pjmedia_endpt_create(&cp.factory,
362  pjsip_endpt_get_ioqueue(g_endpt),
363  0, &g_med_endpt);
364 #endif
365  PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
366 
367  /*
368  * Add PCMA/PCMU codec to the media endpoint.
369  */
370 #if defined(PJMEDIA_HAS_G711_CODEC) && PJMEDIA_HAS_G711_CODEC!=0
371  status = pjmedia_codec_g711_init(g_med_endpt);
372  PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
373 #endif
374 
375 
376 #if defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0)
377  /* Init video subsystem */
378  pool = pjmedia_endpt_create_pool(g_med_endpt, "Video subsystem", 512, 512);
379  status = pjmedia_video_format_mgr_create(pool, 64, 0, NULL);
380  PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
381  status = pjmedia_converter_mgr_create(pool, NULL);
382  PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
383  status = pjmedia_vid_codec_mgr_create(pool, NULL);
384  PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
385  status = pjmedia_vid_dev_subsys_init(&cp.factory);
386  PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
387 
388 #if PJMEDIA_HAS_VIDEO && PJMEDIA_HAS_VID_TOOLBOX_CODEC
389  status = pjmedia_codec_vid_toolbox_init(NULL, &cp.factory);
390  PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
391 #endif
392 
393 # if defined(PJMEDIA_HAS_OPENH264_CODEC) && PJMEDIA_HAS_OPENH264_CODEC != 0
394  status = pjmedia_codec_openh264_vid_init(NULL, &cp.factory);
395  PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
396 # endif
397 
398 # if defined(PJMEDIA_HAS_FFMPEG_VID_CODEC) && PJMEDIA_HAS_FFMPEG_VID_CODEC!=0
399  /* Init ffmpeg video codecs */
400  status = pjmedia_codec_ffmpeg_vid_init(NULL, &cp.factory);
401  PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
402 # endif /* PJMEDIA_HAS_FFMPEG_VID_CODEC */
403 
404 #endif /* PJMEDIA_HAS_VIDEO */
405 
406  /* Create event manager */
407  status = pjmedia_event_mgr_create(pool, 0, NULL);
408  PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
409 
410  /*
411  * Create media transport used to send/receive RTP/RTCP socket.
412  * One media transport is needed for each call. Application may
413  * opt to re-use the same media transport for subsequent calls.
414  */
415  for (i = 0; i < PJ_ARRAY_SIZE(g_med_transport); ++i) {
416  status = pjmedia_transport_udp_create3(g_med_endpt, AF, NULL, NULL,
417  RTP_PORT + i*2, 0,
418  &g_med_transport[i]);
419  if (status != PJ_SUCCESS) {
420  app_perror(THIS_FILE, "Unable to create media transport", status);
421  return 1;
422  }
423 
424  /*
425  * Get socket info (address, port) of the media transport. We will
426  * need this info to create SDP (i.e. the address and port info in
427  * the SDP).
428  */
429  pjmedia_transport_info_init(&g_med_tpinfo[i]);
430  pjmedia_transport_get_info(g_med_transport[i], &g_med_tpinfo[i]);
431 
432  pj_memcpy(&g_sock_info[i], &g_med_tpinfo[i].sock_info,
433  sizeof(pjmedia_sock_info));
434  }
435 
436  /*
437  * If URL is specified, then make call immediately.
438  */
439  if (argc > 1) {
440  pj_sockaddr hostaddr;
441  char hostip[PJ_INET6_ADDRSTRLEN+2];
442  char temp[80];
443  pj_str_t dst_uri = pj_str(argv[1]);
444  pj_str_t local_uri;
445  pjsip_dialog *dlg;
446  pjmedia_sdp_session *local_sdp;
447  pjsip_tx_data *tdata;
448 
449  if (pj_gethostip(AF, &hostaddr) != PJ_SUCCESS) {
450  app_perror(THIS_FILE, "Unable to retrieve local host IP", status);
451  return 1;
452  }
453  pj_sockaddr_print(&hostaddr, hostip, sizeof(hostip), 2);
454 
455  pj_ansi_sprintf(temp, "<sip:simpleuac@%s:%d>",
456  hostip, SIP_PORT);
457  local_uri = pj_str(temp);
458 
459  /* Create UAC dialog */
461  &local_uri, /* local URI */
462  &local_uri, /* local Contact */
463  &dst_uri, /* remote URI */
464  &dst_uri, /* remote target */
465  &dlg); /* dialog */
466  if (status != PJ_SUCCESS) {
467  app_perror(THIS_FILE, "Unable to create UAC dialog", status);
468  return 1;
469  }
470 
471  /* If we expect the outgoing INVITE to be challenged, then we should
472  * put the credentials in the dialog here, with something like this:
473  *
474  {
475  pjsip_cred_info cred[1];
476 
477  cred[0].realm = pj_str("sip.server.realm");
478  cred[0].scheme = pj_str("digest");
479  cred[0].username = pj_str("theuser");
480  cred[0].data_type = PJSIP_CRED_DATA_PLAIN_PASSWD;
481  cred[0].data = pj_str("thepassword");
482 
483  pjsip_auth_clt_set_credentials( &dlg->auth_sess, 1, cred);
484  }
485  *
486  */
487 
488 
489  /* Get the SDP body to be put in the outgoing INVITE, by asking
490  * media endpoint to create one for us.
491  */
492  status = pjmedia_endpt_create_sdp( g_med_endpt, /* the media endpt */
493  dlg->pool, /* pool. */
494  MAX_MEDIA_CNT, /* # of streams */
495  g_sock_info, /* RTP sock info */
496  &local_sdp); /* the SDP result */
497  PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
498 
499 
500 
501  /* Create the INVITE session, and pass the SDP returned earlier
502  * as the session's initial capability.
503  */
504  status = pjsip_inv_create_uac( dlg, local_sdp, 0, &g_inv);
505  PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
506 
507  /* If we want the initial INVITE to travel to specific SIP proxies,
508  * then we should put the initial dialog's route set here. The final
509  * route set will be updated once a dialog has been established.
510  * To set the dialog's initial route set, we do it with something
511  * like this:
512  *
513  {
514  pjsip_route_hdr route_set;
515  pjsip_route_hdr *route;
516  const pj_str_t hname = { "Route", 5 };
517  char *uri = "sip:proxy.server;lr";
518 
519  pj_list_init(&route_set);
520 
521  route = pjsip_parse_hdr( dlg->pool, &hname,
522  uri, strlen(uri),
523  NULL);
524  PJ_ASSERT_RETURN(route != NULL, 1);
525  pj_list_push_back(&route_set, route);
526 
527  pjsip_dlg_set_route_set(dlg, &route_set);
528  }
529  *
530  * Note that Route URI SHOULD have an ";lr" parameter!
531  */
532 
533  /* Create initial INVITE request.
534  * This INVITE request will contain a perfectly good request and
535  * an SDP body as well.
536  */
537  status = pjsip_inv_invite(g_inv, &tdata);
538  PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
539 
540 
541 
542  /* Send initial INVITE request.
543  * From now on, the invite session's state will be reported to us
544  * via the invite session callbacks.
545  */
546  status = pjsip_inv_send_msg(g_inv, tdata);
547  PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);
548 
549 
550  } else {
551 
552  /* No URL to make call to */
553 
554  PJ_LOG(3,(THIS_FILE, "Ready to accept incoming calls..."));
555  }
556 
557 
558  /* Loop until one call is completed */
559  for (;!g_complete;) {
560  pj_time_val timeout = {0, 10};
561  pjsip_endpt_handle_events(g_endpt, &timeout);
562  }
563 
564  /* On exit, dump current memory usage: */
565  dump_pool_usage(THIS_FILE, &cp);
566 
567  /* Destroy audio ports. Destroy the audio port first
568  * before the stream since the audio port has threads
569  * that get/put frames to the stream.
570  */
571  if (g_snd_port)
572  pjmedia_snd_port_destroy(g_snd_port);
573 
574 #if defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0)
575  /* Destroy video ports */
576  if (g_vid_capturer)
577  pjmedia_vid_port_destroy(g_vid_capturer);
578  if (g_vid_renderer)
579  pjmedia_vid_port_destroy(g_vid_renderer);
580 #endif
581 
582  /* Destroy streams */
583  if (g_med_stream)
584  pjmedia_stream_destroy(g_med_stream);
585 #if defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0)
586  if (g_med_vstream)
587  pjmedia_vid_stream_destroy(g_med_vstream);
588 
589  /* Deinit ffmpeg codec */
590 # if defined(PJMEDIA_HAS_FFMPEG_VID_CODEC) && PJMEDIA_HAS_FFMPEG_VID_CODEC!=0
592 # endif
593 # if defined(PJMEDIA_HAS_OPENH264_CODEC) && PJMEDIA_HAS_OPENH264_CODEC != 0
595 # endif
596 # if PJMEDIA_HAS_VIDEO && PJMEDIA_HAS_VID_TOOLBOX_CODEC
598 # endif
599 
600 #endif
601 
602  /* Destroy media transports */
603  for (i = 0; i < MAX_MEDIA_CNT; ++i) {
604  if (g_med_transport[i])
605  pjmedia_transport_close(g_med_transport[i]);
606  }
607 
608  /* Destroy event manager */
610 
611  /* Deinit pjmedia endpoint */
612  if (g_med_endpt)
613  pjmedia_endpt_destroy(g_med_endpt);
614 
615  /* Deinit pjsip endpoint */
616  if (g_endpt)
617  pjsip_endpt_destroy(g_endpt);
618 
619  /* Release pool */
620  if (pool)
621  pj_pool_release(pool);
622 
623  return 0;
624 }
625 
626 
627 
628 /*
629  * Callback when INVITE session state has changed.
630  * This callback is registered when the invite session module is initialized.
631  * We mostly want to know when the invite session has been disconnected,
632  * so that we can quit the application.
633  */
634 static void call_on_state_changed( pjsip_inv_session *inv,
635  pjsip_event *e)
636 {
637  PJ_UNUSED_ARG(e);
638 
639  if (inv->state == PJSIP_INV_STATE_DISCONNECTED) {
640 
641  PJ_LOG(3,(THIS_FILE, "Call DISCONNECTED [reason=%d (%s)]",
642  inv->cause,
644 
645  PJ_LOG(3,(THIS_FILE, "One call completed, application quitting..."));
646  g_complete = 1;
647 
648  } else {
649 
650  PJ_LOG(3,(THIS_FILE, "Call state changed to %s",
651  pjsip_inv_state_name(inv->state)));
652 
653  }
654 }
655 
656 
657 /* This callback is called when dialog has forked. */
658 static void call_on_forked(pjsip_inv_session *inv, pjsip_event *e)
659 {
660  /* To be done... */
661  PJ_UNUSED_ARG(inv);
662  PJ_UNUSED_ARG(e);
663 }
664 
665 
666 /*
667  * Callback when incoming requests outside any transactions and any
668  * dialogs are received. We're only interested to hande incoming INVITE
669  * request, and we'll reject any other requests with 500 response.
670  */
671 static pj_bool_t on_rx_request( pjsip_rx_data *rdata )
672 {
673  pj_sockaddr hostaddr;
674  char temp[80], hostip[PJ_INET6_ADDRSTRLEN];
675  pj_str_t local_uri;
676  pjsip_dialog *dlg;
677  pjmedia_sdp_session *local_sdp;
678  pjsip_tx_data *tdata;
679  unsigned options = 0;
680  pj_status_t status;
681 
682 
683  /*
684  * Respond (statelessly) any non-INVITE requests with 500
685  */
686  if (rdata->msg_info.msg->line.req.method.id != PJSIP_INVITE_METHOD) {
687 
688  if (rdata->msg_info.msg->line.req.method.id != PJSIP_ACK_METHOD) {
689  pj_str_t reason = pj_str("Simple UA unable to handle "
690  "this request");
691 
692  pjsip_endpt_respond_stateless( g_endpt, rdata,
693  500, &reason,
694  NULL, NULL);
695  }
696  return PJ_TRUE;
697  }
698 
699 
700  /*
701  * Reject INVITE if we already have an INVITE session in progress.
702  */
703  if (g_inv) {
704 
705  pj_str_t reason = pj_str("Another call is in progress");
706 
707  pjsip_endpt_respond_stateless( g_endpt, rdata,
708  500, &reason,
709  NULL, NULL);
710  return PJ_TRUE;
711 
712  }
713 
714  /* Verify that we can handle the request. */
715  status = pjsip_inv_verify_request(rdata, &options, NULL, NULL,
716  g_endpt, NULL);
717  if (status != PJ_SUCCESS) {
718 
719  pj_str_t reason = pj_str("Sorry Simple UA can not handle this INVITE");
720 
721  pjsip_endpt_respond_stateless( g_endpt, rdata,
722  500, &reason,
723  NULL, NULL);
724  return PJ_TRUE;
725  }
726 
727  /*
728  * Generate Contact URI
729  */
730  if (pj_gethostip(AF, &hostaddr) != PJ_SUCCESS) {
731  app_perror(THIS_FILE, "Unable to retrieve local host IP", status);
732  return PJ_TRUE;
733  }
734  pj_sockaddr_print(&hostaddr, hostip, sizeof(hostip), 2);
735 
736  pj_ansi_sprintf(temp, "<sip:simpleuas@%s:%d>",
737  hostip, SIP_PORT);
738  local_uri = pj_str(temp);
739 
740  /*
741  * Create UAS dialog.
742  */
744  rdata,
745  &local_uri, /* contact */
746  &dlg);
747  if (status != PJ_SUCCESS) {
748  pjsip_endpt_respond_stateless(g_endpt, rdata, 500, NULL,
749  NULL, NULL);
750  return PJ_TRUE;
751  }
752 
753  /*
754  * Get media capability from media endpoint:
755  */
756 
757  status = pjmedia_endpt_create_sdp( g_med_endpt, rdata->tp_info.pool,
758  MAX_MEDIA_CNT, g_sock_info, &local_sdp);
759  pj_assert(status == PJ_SUCCESS);
760  if (status != PJ_SUCCESS) {
761  pjsip_dlg_dec_lock(dlg);
762  return PJ_TRUE;
763  }
764 
765 
766  /*
767  * Create invite session, and pass both the UAS dialog and the SDP
768  * capability to the session.
769  */
770  status = pjsip_inv_create_uas( dlg, rdata, local_sdp, 0, &g_inv);
771  pj_assert(status == PJ_SUCCESS);
772  if (status != PJ_SUCCESS) {
773  pjsip_dlg_dec_lock(dlg);
774  return PJ_TRUE;
775  }
776 
777  /*
778  * Invite session has been created, decrement & release dialog lock.
779  */
780  pjsip_dlg_dec_lock(dlg);
781 
782 
783  /*
784  * Initially send 180 response.
785  *
786  * The very first response to an INVITE must be created with
787  * pjsip_inv_initial_answer(). Subsequent responses to the same
788  * transaction MUST use pjsip_inv_answer().
789  */
790  status = pjsip_inv_initial_answer(g_inv, rdata,
791  180,
792  NULL, NULL, &tdata);
793  PJ_ASSERT_RETURN(status == PJ_SUCCESS, PJ_TRUE);
794 
795 
796  /* Send the 180 response. */
797  status = pjsip_inv_send_msg(g_inv, tdata);
798  PJ_ASSERT_RETURN(status == PJ_SUCCESS, PJ_TRUE);
799 
800 
801  /*
802  * Now create 200 response.
803  */
804  status = pjsip_inv_answer( g_inv,
805  200, NULL, /* st_code and st_text */
806  NULL, /* SDP already specified */
807  &tdata);
808  PJ_ASSERT_RETURN(status == PJ_SUCCESS, PJ_TRUE);
809 
810  /*
811  * Send the 200 response.
812  */
813  status = pjsip_inv_send_msg(g_inv, tdata);
814  PJ_ASSERT_RETURN(status == PJ_SUCCESS, PJ_TRUE);
815 
816 
817  /* Done.
818  * When the call is disconnected, it will be reported via the callback.
819  */
820 
821  return PJ_TRUE;
822 }
823 
824 
825 
826 /*
827  * Callback when SDP negotiation has completed.
828  * We are interested with this callback because we want to start media
829  * as soon as SDP negotiation is completed.
830  */
831 static void call_on_media_update( pjsip_inv_session *inv,
832  pj_status_t status)
833 {
834  pjmedia_stream_info stream_info;
835  const pjmedia_sdp_session *local_sdp;
836  const pjmedia_sdp_session *remote_sdp;
837  pjmedia_port *media_port;
838 
839  if (status != PJ_SUCCESS) {
840 
841  app_perror(THIS_FILE, "SDP negotiation has failed", status);
842 
843  /* Here we should disconnect call if we're not in the middle
844  * of initializing an UAS dialog and if this is not a re-INVITE.
845  */
846  return;
847  }
848 
849  /* Get local and remote SDP.
850  * We need both SDPs to create a media session.
851  */
852  status = pjmedia_sdp_neg_get_active_local(inv->neg, &local_sdp);
853 
854  status = pjmedia_sdp_neg_get_active_remote(inv->neg, &remote_sdp);
855 
856 
857  /* Create stream info based on the media audio SDP. */
858  status = pjmedia_stream_info_from_sdp(&stream_info, inv->dlg->pool,
859  g_med_endpt,
860  local_sdp, remote_sdp, 0);
861  if (status != PJ_SUCCESS) {
862  app_perror(THIS_FILE,"Unable to create audio stream info",status);
863  return;
864  }
865 
866  /* If required, we can also change some settings in the stream info,
867  * (such as jitter buffer settings, codec settings, etc) before we
868  * create the stream.
869  */
870 
871  /* Create new audio media stream, passing the stream info, and also the
872  * media socket that we created earlier.
873  */
874  status = pjmedia_stream_create(g_med_endpt, inv->dlg->pool, &stream_info,
875  g_med_transport[0], NULL, &g_med_stream);
876  if (status != PJ_SUCCESS) {
877  app_perror( THIS_FILE, "Unable to create audio stream", status);
878  return;
879  }
880 
881  /* Start the audio stream */
882  status = pjmedia_stream_start(g_med_stream);
883  if (status != PJ_SUCCESS) {
884  app_perror( THIS_FILE, "Unable to start audio stream", status);
885  return;
886  }
887 
888  /* Start the UDP media transport */
889  pjmedia_transport_media_start(g_med_transport[0], 0, 0, 0, 0);
890 
891  /* Get the media port interface of the audio stream.
892  * Media port interface is basicly a struct containing get_frame() and
893  * put_frame() function. With this media port interface, we can attach
894  * the port interface to conference bridge, or directly to a sound
895  * player/recorder device.
896  */
897  pjmedia_stream_get_port(g_med_stream, &media_port);
898 
899  /* Create sound port */
903  PJMEDIA_PIA_SRATE(&media_port->info),/* clock rate */
904  PJMEDIA_PIA_CCNT(&media_port->info),/* channel count */
905  PJMEDIA_PIA_SPF(&media_port->info), /* samples per frame*/
906  PJMEDIA_PIA_BITS(&media_port->info),/* bits per sample */
907  0,
908  &g_snd_port);
909 
910  if (status != PJ_SUCCESS) {
911  app_perror( THIS_FILE, "Unable to create sound port", status);
912  PJ_LOG(3,(THIS_FILE, "%d %d %d %d",
913  PJMEDIA_PIA_SRATE(&media_port->info),/* clock rate */
914  PJMEDIA_PIA_CCNT(&media_port->info),/* channel count */
915  PJMEDIA_PIA_SPF(&media_port->info), /* samples per frame*/
916  PJMEDIA_PIA_BITS(&media_port->info) /* bits per sample */
917  ));
918  return;
919  }
920 
921  status = pjmedia_snd_port_connect(g_snd_port, media_port);
922 
923 
924  /* Get the media port interface of the second stream in the session,
925  * which is video stream. With this media port interface, we can attach
926  * the port directly to a renderer/capture video device.
927  */
928 #if defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0)
929  if (local_sdp->media_count > 1) {
930  pjmedia_vid_stream_info vstream_info;
931  pjmedia_vid_port_param vport_param;
932 
933  pjmedia_vid_port_param_default(&vport_param);
934 
935  /* Create stream info based on the media video SDP. */
936  status = pjmedia_vid_stream_info_from_sdp(&vstream_info,
937  inv->dlg->pool, g_med_endpt,
938  local_sdp, remote_sdp, 1);
939  if (status != PJ_SUCCESS) {
940  app_perror(THIS_FILE,"Unable to create video stream info",status);
941  return;
942  }
943 
944  /* If required, we can also change some settings in the stream info,
945  * (such as jitter buffer settings, codec settings, etc) before we
946  * create the video stream.
947  */
948 
949  /* Create new video media stream, passing the stream info, and also the
950  * media socket that we created earlier.
951  */
952  status = pjmedia_vid_stream_create(g_med_endpt, NULL, &vstream_info,
953  g_med_transport[1], NULL,
954  &g_med_vstream);
955  if (status != PJ_SUCCESS) {
956  app_perror( THIS_FILE, "Unable to create video stream", status);
957  return;
958  }
959 
960  /* Start the video stream */
961  status = pjmedia_vid_stream_start(g_med_vstream);
962  if (status != PJ_SUCCESS) {
963  app_perror( THIS_FILE, "Unable to start video stream", status);
964  return;
965  }
966 
967  /* Start the UDP media transport */
968  pjmedia_transport_media_start(g_med_transport[1], 0, 0, 0, 0);
969 
970  if (vstream_info.dir & PJMEDIA_DIR_DECODING) {
973  &vport_param.vidparam);
974  if (status != PJ_SUCCESS) {
975  app_perror(THIS_FILE, "Unable to get default param of video "
976  "renderer device", status);
977  return;
978  }
979 
980  /* Get video stream port for decoding direction */
982  &media_port);
983 
984  /* Set format */
985  pjmedia_format_copy(&vport_param.vidparam.fmt,
986  &media_port->info.fmt);
987  vport_param.vidparam.dir = PJMEDIA_DIR_RENDER;
988  vport_param.active = PJ_TRUE;
989 
990  /* Create renderer */
991  status = pjmedia_vid_port_create(inv->pool, &vport_param,
992  &g_vid_renderer);
993  if (status != PJ_SUCCESS) {
994  app_perror(THIS_FILE, "Unable to create video renderer device",
995  status);
996  return;
997  }
998 
999  /* Connect renderer to media_port */
1000  status = pjmedia_vid_port_connect(g_vid_renderer, media_port,
1001  PJ_FALSE);
1002  if (status != PJ_SUCCESS) {
1003  app_perror(THIS_FILE, "Unable to connect renderer to stream",
1004  status);
1005  return;
1006  }
1007  }
1008 
1009  /* Create capturer */
1010  if (vstream_info.dir & PJMEDIA_DIR_ENCODING) {
1013  &vport_param.vidparam);
1014  if (status != PJ_SUCCESS) {
1015  app_perror(THIS_FILE, "Unable to get default param of video "
1016  "capture device", status);
1017  return;
1018  }
1019 
1020  /* Get video stream port for decoding direction */
1022  &media_port);
1023 
1024  /* Get capturer format from stream info */
1025  pjmedia_format_copy(&vport_param.vidparam.fmt,
1026  &media_port->info.fmt);
1027  vport_param.vidparam.dir = PJMEDIA_DIR_CAPTURE;
1028  vport_param.active = PJ_TRUE;
1029 
1030  /* Create capturer */
1031  status = pjmedia_vid_port_create(inv->pool, &vport_param,
1032  &g_vid_capturer);
1033  if (status != PJ_SUCCESS) {
1034  app_perror(THIS_FILE, "Unable to create video capture device",
1035  status);
1036  return;
1037  }
1038 
1039  /* Connect capturer to media_port */
1040  status = pjmedia_vid_port_connect(g_vid_capturer, media_port,
1041  PJ_FALSE);
1042  if (status != PJ_SUCCESS) {
1043  app_perror(THIS_FILE, "Unable to connect capturer to stream",
1044  status);
1045  return;
1046  }
1047  }
1048 
1049  /* Start streaming */
1050  if (g_vid_renderer) {
1051  status = pjmedia_vid_port_start(g_vid_renderer);
1052  if (status != PJ_SUCCESS) {
1053  app_perror(THIS_FILE, "Unable to start video renderer",
1054  status);
1055  return;
1056  }
1057  }
1058  if (g_vid_capturer) {
1059  status = pjmedia_vid_port_start(g_vid_capturer);
1060  if (status != PJ_SUCCESS) {
1061  app_perror(THIS_FILE, "Unable to start video capturer",
1062  status);
1063  return;
1064  }
1065  }
1066  }
1067 #endif /* PJMEDIA_HAS_VIDEO */
1068 
1069  /* Done with media. */
1070 }
1071 
1072 
pj_status_t pjmedia_transport_close(pjmedia_transport *tp)
pj_status_t pjmedia_sdp_neg_get_active_local(pjmedia_sdp_neg *neg, const pjmedia_sdp_session **local)
pj_status_t pjmedia_sdp_neg_get_active_remote(pjmedia_sdp_neg *neg, const pjmedia_sdp_session **remote)
Definition: sip_module.h:191
pjsip_buffer buf
Definition: sip_transport.h:569
struct pjsip_request_line req
Definition: sip_msg.h:794
void(* on_media_update)(pjsip_inv_session *inv_ses, pj_status_t status)
Definition: sip_inv.h:243
pj_status_t pjsip_inv_usage_init(pjsip_endpoint *endpt, const pjsip_inv_callback *cb)
const pj_str_t * pjsip_get_status_text(int status_code)
#define PJ_ASSERT_RETURN(expr, retval)
pj_status_t pjsip_udp_transport_start6(pjsip_endpoint *endpt, const pj_sockaddr_in6 *local, const pjsip_host_port *a_name, unsigned async_cnt, pjsip_transport **p_transport)
Definition: sip_transport.h:522
PJMEDIA_VID_DEFAULT_CAPTURE_DEV
char * ptr
pjmedia_port_info info
void pj_pool_release(pj_pool_t *pool)
const char * pjsip_inv_state_name(pjsip_inv_state state)
pjmedia_format fmt
int pj_bool_t
pjmedia_format * pjmedia_format_copy(pjmedia_format *dst, const pjmedia_format *src)
pjsip_dialog * dlg
Definition: sip_inv.h:433
SIP SIMPLE Extension.
pjmedia_sdp_neg * neg
Definition: sip_inv.h:436
pj_status_t pjsip_inv_send_msg(pjsip_inv_session *inv, pjsip_tx_data *tdata)
void * pj_memcpy(void *dst, const void *src, pj_size_t size)
void pjsip_dlg_dec_lock(pjsip_dialog *dlg)
pjsip_method_e id
Definition: sip_msg.h:79
void pjmedia_vid_port_param_default(pjmedia_vid_port_param *prm)
pj_status_t pjmedia_vid_stream_info_from_sdp(pjmedia_vid_stream_info *si, pj_pool_t *pool, pjmedia_endpt *endpt, const pjmedia_sdp_session *local, const pjmedia_sdp_session *remote, unsigned stream_idx)
#define PJMEDIA_AUD_DEFAULT_CAPTURE_DEV
pj_ssize_t len
Definition: sip_transport.h:335
struct pjmedia_endpt pjmedia_endpt
PJMEDIA_DIR_RENDER
pj_status_t pjmedia_vid_stream_create(pjmedia_endpt *endpt, pj_pool_t *pool, pjmedia_vid_stream_info *info, pjmedia_transport *tp, void *user_data, pjmedia_vid_stream **p_stream)
#define pj_AF_INET()
pj_status_t pjmedia_codec_vid_toolbox_init(pjmedia_vid_codec_mgr *mgr, pj_pool_factory *pf)
pj_status_t pjmedia_stream_start(pjmedia_stream *stream)
pj_status_t pjmedia_snd_port_destroy(pjmedia_snd_port *snd_port)
struct pjmedia_vid_port pjmedia_vid_port
pj_pool_t * pool
Definition: sip_dialog.h:143
pj_status_t pjmedia_video_format_mgr_create(pj_pool_t *pool, unsigned max_fmt, unsigned options, pjmedia_video_format_mgr **p_mgr)
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)
char src_name[PJ_INET6_ADDRSTRLEN]
Definition: sip_transport.h:344
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)
pj_status_t pjsip_inv_create_uas(pjsip_dialog *dlg, pjsip_rx_data *rdata, const pjmedia_sdp_session *local_sdp, unsigned options, pjsip_inv_session **p_inv)
pj_status_t pjmedia_vid_stream_start(pjmedia_vid_stream *stream)
#define PJ_LOG(level, arg)
pj_status_t pjmedia_transport_get_info(pjmedia_transport *tp, pjmedia_transport_info *info)
char * start
Definition: sip_types.h:202
struct pjmedia_snd_port pjmedia_snd_port
int pj_status_t
char * type_name
Definition: sip_transport.h:822
pj_status_t pjsip_inv_initial_answer(pjsip_inv_session *inv, pjsip_rx_data *rdata, int st_code, const pj_str_t *st_text, const pjmedia_sdp_session *sdp, pjsip_tx_data **p_tdata)
pjmedia_vid_dev_param vidparam
char * msg_buf
Definition: sip_transport.h:359
pj_pool_factory_policy pj_pool_factory_default_policy
Definition: sip_msg.h:57
pj_status_t pjmedia_converter_mgr_create(pj_pool_t *pool, pjmedia_converter_mgr **mgr)
pj_status_t pjmedia_event_mgr_create(pj_pool_t *pool, unsigned options, pjmedia_event_mgr **mgr)
PJMEDIA_DIR_ENCODING
void pjsip_endpt_destroy(pjsip_endpoint *endpt)
#define PJMEDIA_AUD_DEFAULT_PLAYBACK_DEV
PJMEDIA_DIR_DECODING
pj_pool_t * pool
Definition: sip_transport.h:305
pj_status_t pjmedia_vid_codec_mgr_create(pj_pool_t *pool, pjmedia_vid_codec_mgr **mgr)
pj_status_t pjsip_endpt_create(pj_pool_factory *pf, const char *name, pjsip_endpoint **endpt)
pj_status_t pjsip_inv_create_uac(pjsip_dialog *dlg, const pjmedia_sdp_session *local_sdp, unsigned options, pjsip_inv_session **p_inv)
pj_status_t pjmedia_stream_create(pjmedia_endpt *endpt, pj_pool_t *pool, const pjmedia_stream_info *info, pjmedia_transport *tp, void *user_data, pjmedia_stream **p_stream)
Definition: sip_event.h:81
Definition: sip_msg.h:59
pj_status_t pjsip_endpt_handle_events(pjsip_endpoint *endpt, const pj_time_val *max_timeout)
pj_status_t pjmedia_vid_stream_destroy(pjmedia_vid_stream *stream)
pj_ioqueue_t * pjsip_endpt_get_ioqueue(pjsip_endpoint *endpt)
pj_pool_factory factory
pj_status_t pjmedia_stream_info_from_sdp(pjmedia_stream_info *si, pj_pool_t *pool, pjmedia_endpt *endpt, const pjmedia_sdp_session *local, const pjmedia_sdp_session *remote, unsigned stream_idx)
pj_status_t pjmedia_vid_port_connect(pjmedia_vid_port *vid_port, pjmedia_port *port, pj_bool_t destroy)
void pjmedia_event_mgr_destroy(pjmedia_event_mgr *mgr)
pj_status_t pjsip_dlg_create_uac(pjsip_user_agent *ua, const pj_str_t *local_uri, const pj_str_t *local_contact, const pj_str_t *remote_uri, const pj_str_t *target, pjsip_dialog **p_dlg)
Definition: sip_transport.h:295
char * cur
Definition: sip_types.h:207
pj_status_t pjsip_endpt_register_module(pjsip_endpoint *endpt, pjsip_module *module)
Definition: sip_inv.h:419
pjsip_user_agent * pjsip_ua_instance(void)
Definition: sip_inv.h:96
pj_status_t pjmedia_snd_port_create(pj_pool_t *pool, int rec_id, int play_id, unsigned clock_rate, unsigned channel_count, unsigned samples_per_frame, unsigned bits_per_sample, unsigned options, pjmedia_snd_port **p_port)
pj_pool_t * pool
Definition: sip_inv.h:422
PJ_TRUE
const pj_str_t * pj_gethostname(void)
struct pjsip_rx_data::@24 msg_info
int dst_port
Definition: sip_transport.h:616
struct pjsip_rx_data::@23 pkt_info
pj_status_t pjmedia_codec_vid_toolbox_deinit(void)
unsigned PJMEDIA_PIA_CCNT(const pjmedia_port_info *pia)
struct pjsip_rx_data::@22 tp_info
pj_status_t pjmedia_endpt_create(pj_pool_factory *pf, pj_ioqueue_t *ioqueue, unsigned worker_cnt, pjmedia_endpt **p_endpt)
pj_status_t pjmedia_codec_ffmpeg_vid_init(pjmedia_vid_codec_mgr *mgr, pj_pool_factory *pf)
pj_sockaddr_in6 ipv6
pj_status_t pjmedia_vid_port_start(pjmedia_vid_port *vid_port)
void pjmedia_transport_info_init(pjmedia_transport_info *info)
char * pjsip_tx_data_get_info(pjsip_tx_data *tdata)
pj_status_t pj_gethostip(int af, pj_sockaddr *addr)
pj_status_t pjmedia_vid_dev_default_param(pj_pool_t *pool, pjmedia_vid_dev_index id, pjmedia_vid_dev_param *param)
pj_str_t pj_str(char *str)
pj_status_t pjsip_tsx_layer_init_module(pjsip_endpoint *endpt)
pjsip_msg * msg
Definition: sip_transport.h:365
pj_status_t pjsip_100rel_init_module(pjsip_endpoint *endpt)
void pj_caching_pool_init(pj_caching_pool *ch_pool, const pj_pool_factory_policy *policy, pj_size_t max_capacity)
pj_status_t pj_sockaddr_init(int af, pj_sockaddr *addr, const pj_str_t *cp, pj_uint16_t port)
char dst_name[PJ_INET6_ADDRSTRLEN]
Definition: sip_transport.h:615
pj_status_t pjsip_inv_verify_request(pjsip_rx_data *rdata, unsigned *options, const pjmedia_sdp_session *sdp, pjsip_dialog *dlg, pjsip_endpoint *endpt, pjsip_tx_data **tdata)
PJ_BEGIN_DECL pj_status_t pjlib_util_init(void)
char * pj_sockaddr_print(const pj_sockaddr_t *addr, char *buf, int size, unsigned flags)
void pj_bzero(void *dst, pj_size_t size)
pj_status_t pjsip_dlg_create_uas_and_inc_lock(pjsip_user_agent *ua, pjsip_rx_data *rdata, const pj_str_t *contact, pjsip_dialog **p_dlg)
void(* on_state_changed)(pjsip_inv_session *inv, pjsip_event *e)
Definition: sip_inv.h:128
pj_status_t pjsip_ua_init_module(pjsip_endpoint *endpt, const pjsip_ua_init_param *prm)
pj_status_t pjmedia_codec_openh264_vid_deinit(void)
pj_status_t pjmedia_vid_dev_subsys_init(pj_pool_factory *pf)
#define PJ_EAFNOTSUP
struct pjsip_endpoint pjsip_endpoint
Definition: sip_types.h:106
#define pj_assert(expr)
Definition: sip_inv.h:115
void pjmedia_vid_port_destroy(pjmedia_vid_port *vid_port)
char * pjsip_rx_data_get_info(pjsip_rx_data *rdata)
pjsip_inv_state state
Definition: sip_inv.h:425
#define PJ_ARRAY_SIZE(a)
pj_status_t pjmedia_stream_destroy(pjmedia_stream *stream)
pjsip_transport * transport
Definition: sip_transport.h:308
int src_port
Definition: sip_transport.h:347
union pjsip_msg::@17 line
unsigned PJMEDIA_PIA_SPF(const pjmedia_port_info *pia)
struct pjsip_tx_data::@27 tp_info
pj_status_t pjmedia_snd_port_connect(pjmedia_snd_port *snd_port, pjmedia_port *port)
PJMEDIA_VID_DEFAULT_RENDER_DEV
unsigned PJMEDIA_PIA_SRATE(const pjmedia_port_info *pia)
pj_status_t pjmedia_transport_udp_create3(pjmedia_endpt *endpt, int af, const char *name, const pj_str_t *addr, int port, unsigned options, pjmedia_transport **p_tp)
pj_status_t pjmedia_transport_media_start(pjmedia_transport *tp, pj_pool_t *tmp_pool, const pjmedia_sdp_session *sdp_local, const pjmedia_sdp_session *sdp_remote, unsigned media_index)
PJMEDIA_DIR_CAPTURE
pj_sockaddr_in ipv4
pj_status_t pjsip_inv_invite(pjsip_inv_session *inv, pjsip_tx_data **p_tdata)
unsigned PJMEDIA_PIA_BITS(const pjmedia_port_info *pia)
Definition: sip_module.h:54
#define pj_AF_INET6()
pj_pool_t * pjmedia_endpt_create_pool(pjmedia_endpt *endpt, const char *name, pj_size_t initial, pj_size_t increment)
Definition: sip_dialog.h:136
pj_status_t pjmedia_stream_get_port(pjmedia_stream *stream, pjmedia_port **p_port)
pj_status_t pjmedia_codec_openh264_vid_init(pjmedia_vid_codec_mgr *mgr, pj_pool_factory *pf)
PJ_BEGIN_DECL pj_status_t pjmedia_codec_g711_init(pjmedia_endpt *endpt)
pj_status_t pjmedia_vid_stream_get_port(pjmedia_vid_stream *stream, pjmedia_dir dir, pjmedia_port **p_port)
void(* on_new_session)(pjsip_inv_session *inv, pjsip_event *e)
Definition: sip_inv.h:141
PJ_SUCCESS
pjmedia_format fmt
pj_status_t pjmedia_vid_port_create(pj_pool_t *pool, const pjmedia_vid_port_param *prm, pjmedia_vid_port **p_vp)
unsigned short pj_uint16_t
pjsip_transport * transport
Definition: sip_transport.h:612
pj_status_t pj_init(void)
pj_status_t pjsip_inv_answer(pjsip_inv_session *inv, int st_code, const pj_str_t *st_text, const pjmedia_sdp_session *local_sdp, pjsip_tx_data **p_tdata)
pj_status_t pjmedia_endpt_destroy(pjmedia_endpt *endpt)
pjsip_method method
Definition: sip_msg.h:382
pjsip_status_code cause
Definition: sip_inv.h:429
PJ_FALSE
void pj_log_set_level(int level)
#define PJ_UNUSED_ARG(arg)
pj_status_t pjmedia_endpt_create_sdp(pjmedia_endpt *endpt, pj_pool_t *pool, unsigned stream_cnt, const pjmedia_sock_info sock_info[], pjmedia_sdp_session **p_sdp)
pj_status_t pjmedia_codec_ffmpeg_vid_deinit(void)
#define PJ_INET6_ADDRSTRLEN
Definition: sip_module.h:211

 


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