Asterisk - The Open Source Telephony Project  18.5.0
res_pjsip_session.c
Go to the documentation of this file.
1 /*
2 * Asterisk -- An open source telephony toolkit.
3 *
4 * Copyright (C) 2013, Digium, Inc.
5 *
6 * Mark Michelson <[email protected]>
7 *
8 * See http://www.asterisk.org for more information about
9 * the Asterisk project. Please do not directly contact
10 * any of the maintainers of this project for assistance;
11 * the project provides a web site, mailing lists and IRC
12 * channels for your use.
13 *
14 * This program is free software, distributed under the terms of
15 * the GNU General Public License Version 2. See the LICENSE file
16 * at the top of the source tree.
17 */
18 
19 /*** MODULEINFO
20  <depend>pjproject</depend>
21  <depend>res_pjsip</depend>
22  <support_level>core</support_level>
23  ***/
24 
25 #include "asterisk.h"
26 
27 #include <pjsip.h>
28 #include <pjsip_ua.h>
29 #include <pjlib.h>
30 #include <pjmedia.h>
31 
32 #include "asterisk/res_pjsip.h"
35 #include "asterisk/callerid.h"
36 #include "asterisk/datastore.h"
37 #include "asterisk/module.h"
38 #include "asterisk/logger.h"
39 #include "asterisk/res_pjsip.h"
40 #include "asterisk/astobj2.h"
41 #include "asterisk/lock.h"
42 #include "asterisk/uuid.h"
43 #include "asterisk/pbx.h"
44 #include "asterisk/taskprocessor.h"
45 #include "asterisk/causes.h"
46 #include "asterisk/sdp_srtp.h"
47 #include "asterisk/dsp.h"
48 #include "asterisk/acl.h"
50 #include "asterisk/pickup.h"
51 #include "asterisk/test.h"
52 #include "asterisk/stream.h"
53 #include "asterisk/vector.h"
54 
55 #define SDP_HANDLER_BUCKETS 11
56 
57 #define MOD_DATA_ON_RESPONSE "on_response"
58 #define MOD_DATA_NAT_HOOK "nat_hook"
59 
60 /* Most common case is one audio and one video stream */
61 #define DEFAULT_NUM_SESSION_MEDIA 2
62 
63 /* Some forward declarations */
64 static void handle_session_begin(struct ast_sip_session *session);
65 static void handle_session_end(struct ast_sip_session *session);
67 static void handle_incoming_request(struct ast_sip_session *session, pjsip_rx_data *rdata);
68 static void handle_incoming_response(struct ast_sip_session *session, pjsip_rx_data *rdata,
70 static int handle_incoming(struct ast_sip_session *session, pjsip_rx_data *rdata,
72 static void handle_outgoing_request(struct ast_sip_session *session, pjsip_tx_data *tdata);
73 static void handle_outgoing_response(struct ast_sip_session *session, pjsip_tx_data *tdata);
75  ast_sip_session_request_creation_cb on_request_creation,
76  ast_sip_session_sdp_creation_cb on_sdp_creation,
77  ast_sip_session_response_cb on_response,
78  enum ast_sip_session_refresh_method method, int generate_new_sdp,
79  struct ast_sip_session_media_state *pending_media_state,
80  struct ast_sip_session_media_state *active_media_state,
81  int queued);
82 
83 /*! \brief NAT hook for modifying outgoing messages with SDP */
84 static struct ast_sip_nat_hook *nat_hook;
85 
86 /*!
87  * \brief Registered SDP stream handlers
88  *
89  * This container is keyed on stream types. Each
90  * object in the container is a linked list of
91  * handlers for the stream type.
92  */
93 static struct ao2_container *sdp_handlers;
94 
95 /*!
96  * These are the objects in the sdp_handlers container
97  */
99  /* The list of handlers to visit */
101  /* The handlers in this list handle streams of this type */
102  char stream_type[1];
103 };
104 
105 static struct pjmedia_sdp_session *create_local_sdp(pjsip_inv_session *inv, struct ast_sip_session *session, const pjmedia_sdp_session *offer);
106 
107 static int sdp_handler_list_hash(const void *obj, int flags)
108 {
109  const struct sdp_handler_list *handler_list = obj;
110  const char *stream_type = flags & OBJ_KEY ? obj : handler_list->stream_type;
111 
112  return ast_str_hash(stream_type);
113 }
114 
116 {
117  if (!session) {
118  return "(null session)";
119  }
120  if (session->channel) {
121  return ast_channel_name(session->channel);
122  } else if (session->endpoint) {
123  return ast_sorcery_object_get_id(session->endpoint);
124  } else {
125  return "unknown";
126  }
127 }
128 
129 static int sdp_handler_list_cmp(void *obj, void *arg, int flags)
130 {
131  struct sdp_handler_list *handler_list1 = obj;
132  struct sdp_handler_list *handler_list2 = arg;
133  const char *stream_type2 = flags & OBJ_KEY ? arg : handler_list2->stream_type;
134 
135  return strcmp(handler_list1->stream_type, stream_type2) ? 0 : CMP_MATCH | CMP_STOP;
136 }
137 
139 {
140  RAII_VAR(struct sdp_handler_list *, handler_list,
141  ao2_find(sdp_handlers, stream_type, OBJ_KEY), ao2_cleanup);
142  SCOPED_AO2LOCK(lock, sdp_handlers);
143 
144  if (handler_list) {
145  struct ast_sip_session_sdp_handler *iter;
146  /* Check if this handler is already registered for this stream type */
147  AST_LIST_TRAVERSE(&handler_list->list, iter, next) {
148  if (!strcmp(iter->id, handler->id)) {
149  ast_log(LOG_WARNING, "Handler '%s' already registered for stream type '%s'.\n", handler->id, stream_type);
150  return -1;
151  }
152  }
153  AST_LIST_INSERT_TAIL(&handler_list->list, handler, next);
154  ast_debug(1, "Registered SDP stream handler '%s' for stream type '%s'\n", handler->id, stream_type);
155 
156  return 0;
157  }
158 
159  /* No stream of this type has been registered yet, so we need to create a new list */
160  handler_list = ao2_alloc(sizeof(*handler_list) + strlen(stream_type), NULL);
161  if (!handler_list) {
162  return -1;
163  }
164  /* Safe use of strcpy */
165  strcpy(handler_list->stream_type, stream_type);
166  AST_LIST_HEAD_INIT_NOLOCK(&handler_list->list);
167  AST_LIST_INSERT_TAIL(&handler_list->list, handler, next);
168  if (!ao2_link(sdp_handlers, handler_list)) {
169  return -1;
170  }
171  ast_debug(1, "Registered SDP stream handler '%s' for stream type '%s'\n", handler->id, stream_type);
172 
173  return 0;
174 }
175 
176 static int remove_handler(void *obj, void *arg, void *data, int flags)
177 {
178  struct sdp_handler_list *handler_list = obj;
179  struct ast_sip_session_sdp_handler *handler = data;
180  struct ast_sip_session_sdp_handler *iter;
181  const char *stream_type = arg;
182 
183  AST_LIST_TRAVERSE_SAFE_BEGIN(&handler_list->list, iter, next) {
184  if (!strcmp(iter->id, handler->id)) {
186  ast_debug(1, "Unregistered SDP stream handler '%s' for stream type '%s'\n", handler->id, stream_type);
187  }
188  }
190 
191  if (AST_LIST_EMPTY(&handler_list->list)) {
192  ast_debug(3, "No more handlers exist for stream type '%s'\n", stream_type);
193  return CMP_MATCH;
194  } else {
195  return CMP_STOP;
196  }
197 }
198 
200 {
201  ao2_callback_data(sdp_handlers, OBJ_KEY | OBJ_UNLINK | OBJ_NODATA, remove_handler, (void *)stream_type, handler);
202 }
203 
205  const struct ast_rtp_instance_stats *vec_elem, const struct ast_rtp_instance_stats *srch)
206 {
207  if (vec_elem->local_ssrc == srch->local_ssrc) {
208  return 1;
209  }
210 
211  return 0;
212 }
213 
215  size_t sessions, size_t read_callbacks)
216 {
217  struct ast_sip_session_media_state *media_state;
218 
219  media_state = ast_calloc(1, sizeof(*media_state));
220  if (!media_state) {
221  return NULL;
222  }
223 
224  if (AST_VECTOR_INIT(&media_state->sessions, sessions) < 0) {
225  ast_free(media_state);
226  return NULL;
227  }
228 
229  if (AST_VECTOR_INIT(&media_state->read_callbacks, read_callbacks) < 0) {
230  AST_VECTOR_FREE(&media_state->sessions);
231  ast_free(media_state);
232  return NULL;
233  }
234 
235  return media_state;
236 }
237 
239 {
242 }
243 
245 {
246  int i;
247  int ret;
248 
249  if (!media_state || !sip_session) {
250  return;
251  }
252 
253  for (i = 0; i < AST_VECTOR_SIZE(&media_state->sessions); i++) {
254  struct ast_rtp_instance_stats *stats_tmp = NULL;
255  struct ast_sip_session_media *media = AST_VECTOR_GET(&media_state->sessions, i);
256  if (!media || !media->rtp) {
257  continue;
258  }
259 
260  stats_tmp = ast_calloc(1, sizeof(struct ast_rtp_instance_stats));
261  if (!stats_tmp) {
262  return;
263  }
264 
265  ret = ast_rtp_instance_get_stats(media->rtp, stats_tmp, AST_RTP_INSTANCE_STAT_ALL);
266  if (ret) {
267  ast_free(stats_tmp);
268  continue;
269  }
270 
271  /* remove all the duplicated stats if exist */
272  AST_VECTOR_REMOVE_CMP_UNORDERED(&sip_session->media_stats, stats_tmp, media_stats_local_ssrc_cmp, ast_free);
273 
274  AST_VECTOR_APPEND(&sip_session->media_stats, stats_tmp);
275  }
276 }
277 
279 {
280  int index;
281 
282  if (!media_state) {
283  return;
284  }
285 
286  AST_VECTOR_RESET(&media_state->sessions, ao2_cleanup);
287  AST_VECTOR_RESET(&media_state->read_callbacks, AST_VECTOR_ELEM_CLEANUP_NOOP);
288 
289  for (index = 0; index < AST_MEDIA_TYPE_END; ++index) {
290  media_state->default_session[index] = NULL;
291  }
292 
293  ast_stream_topology_free(media_state->topology);
294  media_state->topology = NULL;
295 }
296 
298 {
299  struct ast_sip_session_media_state *cloned;
300  int index;
301 
302  if (!media_state) {
303  return NULL;
304  }
305 
307  AST_VECTOR_SIZE(&media_state->sessions),
308  AST_VECTOR_SIZE(&media_state->read_callbacks));
309  if (!cloned) {
310  return NULL;
311  }
312 
313  if (media_state->topology) {
314  cloned->topology = ast_stream_topology_clone(media_state->topology);
315  if (!cloned->topology) {
317  return NULL;
318  }
319  }
320 
321  for (index = 0; index < AST_VECTOR_SIZE(&media_state->sessions); ++index) {
322  struct ast_sip_session_media *session_media = AST_VECTOR_GET(&media_state->sessions, index);
324 
325  ao2_bump(session_media);
326  if (AST_VECTOR_REPLACE(&cloned->sessions, index, session_media)) {
327  ao2_cleanup(session_media);
328  }
330  !cloned->default_session[type]) {
331  cloned->default_session[type] = session_media;
332  }
333  }
334 
335  for (index = 0; index < AST_VECTOR_SIZE(&media_state->read_callbacks); ++index) {
336  struct ast_sip_session_media_read_callback_state *read_callback = AST_VECTOR_GET_ADDR(&media_state->read_callbacks, index);
337 
338  AST_VECTOR_REPLACE(&cloned->read_callbacks, index, *read_callback);
339  }
340 
341  return cloned;
342 }
343 
345 {
346  if (!media_state) {
347  return;
348  }
349 
350  /* This will reset the internal state so we only have to free persistent things */
352 
353  AST_VECTOR_FREE(&media_state->sessions);
354  AST_VECTOR_FREE(&media_state->read_callbacks);
355 
356  ast_free(media_state);
357 }
358 
360 {
361  int index;
362 
363  if (!session->pending_media_state->topology) {
364  ast_log(LOG_WARNING, "Pending topology was NULL for channel '%s'\n",
365  session->channel ? ast_channel_name(session->channel) : "unknown");
366  return 0;
367  }
368 
370  return 0;
371  }
372 
373  for (index = 0; index < ast_stream_topology_get_count(session->pending_media_state->topology); ++index) {
375  ast_stream_get_type(stream)) {
376  continue;
377  }
378 
379  return ast_stream_topology_get_stream(session->pending_media_state->topology, index) == stream ? 1 : 0;
380  }
381 
382  return 0;
383 }
384 
386  int fd, ast_sip_session_media_read_cb callback)
387 {
388  struct ast_sip_session_media_read_callback_state callback_state = {
389  .fd = fd,
390  .read_callback = callback,
391  .session = session_media,
392  };
393 
394  /* The contents of the vector are whole structs and not pointers */
395  return AST_VECTOR_APPEND(&session->pending_media_state->read_callbacks, callback_state);
396 }
397 
400 {
401  if (session_media->write_callback) {
402  if (session_media->write_callback == callback) {
403  return 0;
404  }
405 
406  return -1;
407  }
408 
409  session_media->write_callback = callback;
410 
411  return 0;
412 }
413 
415 {
416  int index;
417 
418  if (!session->endpoint->media.bundle || ast_strlen_zero(session_media->mid)) {
419  return session_media;
420  }
421 
422  for (index = 0; index < AST_VECTOR_SIZE(&session->pending_media_state->sessions); ++index) {
423  struct ast_sip_session_media *bundle_group_session_media;
424 
425  bundle_group_session_media = AST_VECTOR_GET(&session->pending_media_state->sessions, index);
426 
427  /* The first session which is in the bundle group is considered the authoritative session for transport */
428  if (bundle_group_session_media->bundle_group == session_media->bundle_group) {
429  return bundle_group_session_media;
430  }
431  }
432 
433  return session_media;
434 }
435 
436 /*!
437  * \brief Set an SDP stream handler for a corresponding session media.
438  *
439  * \note Always use this function to set the SDP handler for a session media.
440  *
441  * This function will properly free resources on the SDP handler currently being
442  * used by the session media, then set the session media to use the new SDP
443  * handler.
444  */
445 static void session_media_set_handler(struct ast_sip_session_media *session_media,
447 {
448  ast_assert(session_media->handler != handler);
449 
450  if (session_media->handler) {
451  session_media->handler->stream_destroy(session_media);
452  }
453  session_media->handler = handler;
454 }
455 
456 static int stream_destroy(void *obj, void *arg, int flags)
457 {
458  struct sdp_handler_list *handler_list = obj;
459  struct ast_sip_session_media *session_media = arg;
461 
462  AST_LIST_TRAVERSE(&handler_list->list, handler, next) {
463  handler->stream_destroy(session_media);
464  }
465 
466  return 0;
467 }
468 
469 static void session_media_dtor(void *obj)
470 {
471  struct ast_sip_session_media *session_media = obj;
472 
473  /* It is possible for multiple handlers to have allocated memory on the
474  * session media (usually through a stream changing types). Therefore, we
475  * traverse all the SDP handlers and let them all call stream_destroy on
476  * the session_media
477  */
478  ao2_callback(sdp_handlers, 0, stream_destroy, session_media);
479 
480  if (session_media->srtp) {
481  ast_sdp_srtp_destroy(session_media->srtp);
482  }
483 
484  ast_free(session_media->mid);
485  ast_free(session_media->remote_mslabel);
486  ast_free(session_media->remote_label);
487  ast_free(session_media->stream_name);
488 }
489 
491  struct ast_sip_session_media_state *media_state, enum ast_media_type type, int position)
492 {
493  struct ast_sip_session_media *session_media = NULL;
494  struct ast_sip_session_media *current_session_media = NULL;
495  SCOPE_ENTER(1, "%s Adding position %d\n", ast_sip_session_get_name(session), position);
496 
497  /* It is possible for this media state to already contain a session for the stream. If this
498  * is the case we simply return it.
499  */
500  if (position < AST_VECTOR_SIZE(&media_state->sessions)) {
501  current_session_media = AST_VECTOR_GET(&media_state->sessions, position);
502  if (current_session_media && current_session_media->type == type) {
503  SCOPE_EXIT_RTN_VALUE(current_session_media, "Using existing media_session\n");
504  }
505  }
506 
507  /* Determine if we can reuse the session media from the active media state if present */
508  if (position < AST_VECTOR_SIZE(&session->active_media_state->sessions)) {
509  session_media = AST_VECTOR_GET(&session->active_media_state->sessions, position);
510  /* A stream can never exist without an accompanying media session */
511  if (session_media->type == type) {
512  ao2_ref(session_media, +1);
513  ast_trace(1, "Reusing existing media session\n");
514  /*
515  * If this session_media was previously removed, its bundle group was probably reset
516  * to -1 so if bundling is enabled on the endpoint, we need to reset it to 0, set
517  * the bundled flag and reset its mid.
518  */
519  if (session->endpoint->media.bundle && session_media->bundle_group == -1) {
520  session_media->bundled = session->endpoint->media.webrtc;
521  session_media->bundle_group = 0;
522  ast_free(session_media->mid);
523  if (ast_asprintf(&session_media->mid, "%s-%d", ast_codec_media_type2str(type), position) < 0) {
524  ao2_ref(session_media, -1);
525  SCOPE_EXIT_RTN_VALUE(NULL, "Couldn't alloc mid\n");
526  }
527  }
528  } else {
529  ast_trace(1, "Can't reuse existing media session because the types are different. %s <> %s\n",
531  session_media = NULL;
532  }
533  }
534 
535  if (!session_media) {
536  /* No existing media session we can use so create a new one */
537  session_media = ao2_alloc_options(sizeof(*session_media), session_media_dtor, AO2_ALLOC_OPT_LOCK_NOLOCK);
538  if (!session_media) {
539  return NULL;
540  }
541  ast_trace(1, "Creating new media session\n");
542 
543  session_media->encryption = session->endpoint->media.rtp.encryption;
544  session_media->remote_ice = session->endpoint->media.rtp.ice_support;
545  session_media->remote_rtcp_mux = session->endpoint->media.rtcp_mux;
546  session_media->keepalive_sched_id = -1;
547  session_media->timeout_sched_id = -1;
548  session_media->type = type;
549  session_media->stream_num = position;
550 
551  if (session->endpoint->media.bundle) {
552  /* This is a new stream so create a new mid based on media type and position, which makes it unique.
553  * If this is the result of an offer the mid will just end up getting replaced.
554  */
555  if (ast_asprintf(&session_media->mid, "%s-%d", ast_codec_media_type2str(type), position) < 0) {
556  ao2_ref(session_media, -1);
557  SCOPE_EXIT_RTN_VALUE(NULL, "Couldn't alloc mid\n");
558  }
559  session_media->bundle_group = 0;
560 
561  /* Some WebRTC clients can't handle an offer to bundle media streams. Instead they expect them to
562  * already be bundled. Every client handles this scenario though so if WebRTC is enabled just go
563  * ahead and treat the streams as having already been bundled.
564  */
565  session_media->bundled = session->endpoint->media.webrtc;
566  } else {
567  session_media->bundle_group = -1;
568  }
569  }
570 
571  ast_free(session_media->stream_name);
572  session_media->stream_name = ast_strdup(ast_stream_get_name(ast_stream_topology_get_stream(media_state->topology, position)));
573 
574  if (AST_VECTOR_REPLACE(&media_state->sessions, position, session_media)) {
575  ao2_ref(session_media, -1);
576 
577  SCOPE_EXIT_RTN_VALUE(NULL, "Couldn't replace media_session\n");
578  }
579 
580  ao2_cleanup(current_session_media);
581 
582  /* If this stream will be active in some way and it is the first of this type then consider this the default media session to match */
583  if (!media_state->default_session[type] && ast_stream_get_state(ast_stream_topology_get_stream(media_state->topology, position)) != AST_STREAM_STATE_REMOVED) {
584  ast_trace(1, "Setting media session as default for %s\n", ast_codec_media_type2str(session_media->type));
585 
586  media_state->default_session[type] = session_media;
587  }
588 
589  SCOPE_EXIT_RTN_VALUE(session_media, "Done\n");
590 }
591 
592 static int is_stream_limitation_reached(enum ast_media_type type, const struct ast_sip_endpoint *endpoint, int *type_streams)
593 {
594  switch (type) {
596  return !(type_streams[type] < endpoint->media.max_audio_streams);
598  return !(type_streams[type] < endpoint->media.max_video_streams);
600  /* We don't have an option for image (T.38) streams so cap it to one. */
601  return (type_streams[type] > 0);
603  case AST_MEDIA_TYPE_TEXT:
604  default:
605  /* We don't want any unknown or "other" streams on our endpoint,
606  * so always just say we've reached the limit
607  */
608  return 1;
609  }
610 }
611 
612 static int get_mid_bundle_group(const pjmedia_sdp_session *sdp, const char *mid)
613 {
614  int bundle_group = 0;
615  int index;
616 
617  for (index = 0; index < sdp->attr_count; ++index) {
618  pjmedia_sdp_attr *attr = sdp->attr[index];
619  char value[pj_strlen(&attr->value) + 1], *mids = value, *attr_mid;
620 
621  if (pj_strcmp2(&attr->name, "group") || pj_strncmp2(&attr->value, "BUNDLE", 6)) {
622  continue;
623  }
624 
625  ast_copy_pj_str(value, &attr->value, sizeof(value));
626 
627  /* Skip the BUNDLE at the front */
628  mids += 7;
629 
630  while ((attr_mid = strsep(&mids, " "))) {
631  if (!strcmp(attr_mid, mid)) {
632  /* The ordering of attributes determines our internal identification of the bundle group based on number,
633  * with -1 being not in a bundle group. Since this is only exposed internally for response purposes it's
634  * actually even fine if things move around.
635  */
636  return bundle_group;
637  }
638  }
639 
640  bundle_group++;
641  }
642 
643  return -1;
644 }
645 
647  struct ast_sip_session_media *session_media,
648  const pjmedia_sdp_session *sdp,
649  const struct pjmedia_sdp_media *stream)
650 {
651  pjmedia_sdp_attr *attr;
652 
653  if (!session->endpoint->media.bundle) {
654  return 0;
655  }
656 
657  /* By default on an incoming negotiation we assume no mid and bundle group is present */
658  ast_free(session_media->mid);
659  session_media->mid = NULL;
660  session_media->bundle_group = -1;
661  session_media->bundled = 0;
662 
663  /* Grab the media identifier for the stream */
664  attr = pjmedia_sdp_media_find_attr2(stream, "mid", NULL);
665  if (!attr) {
666  return 0;
667  }
668 
669  session_media->mid = ast_calloc(1, attr->value.slen + 1);
670  if (!session_media->mid) {
671  return 0;
672  }
673  ast_copy_pj_str(session_media->mid, &attr->value, attr->value.slen + 1);
674 
675  /* Determine what bundle group this is part of */
676  session_media->bundle_group = get_mid_bundle_group(sdp, session_media->mid);
677 
678  /* If this is actually part of a bundle group then the other side requested or accepted the bundle request */
679  session_media->bundled = session_media->bundle_group != -1;
680 
681  return 0;
682 }
683 
685  struct ast_sip_session_media *session_media,
686  const pjmedia_sdp_session *sdp,
687  const struct pjmedia_sdp_media *stream,
688  struct ast_stream *asterisk_stream)
689 {
690  int index;
691 
692  ast_free(session_media->remote_mslabel);
693  session_media->remote_mslabel = NULL;
694  ast_free(session_media->remote_label);
695  session_media->remote_label = NULL;
696 
697  for (index = 0; index < stream->attr_count; ++index) {
698  pjmedia_sdp_attr *attr = stream->attr[index];
699  char attr_value[pj_strlen(&attr->value) + 1];
700  char *ssrc_attribute_name, *ssrc_attribute_value = NULL;
701  char *msid, *tmp = attr_value;
702  static const pj_str_t STR_msid = { "msid", 4 };
703  static const pj_str_t STR_ssrc = { "ssrc", 4 };
704  static const pj_str_t STR_label = { "label", 5 };
705 
706  if (!pj_strcmp(&attr->name, &STR_label)) {
707  ast_copy_pj_str(attr_value, &attr->value, sizeof(attr_value));
708  session_media->remote_label = ast_strdup(attr_value);
709  } else if (!pj_strcmp(&attr->name, &STR_msid)) {
710  ast_copy_pj_str(attr_value, &attr->value, sizeof(attr_value));
711  msid = strsep(&tmp, " ");
712  session_media->remote_mslabel = ast_strdup(msid);
713  break;
714  } else if (!pj_strcmp(&attr->name, &STR_ssrc)) {
715  ast_copy_pj_str(attr_value, &attr->value, sizeof(attr_value));
716 
717  if ((ssrc_attribute_name = strchr(attr_value, ' '))) {
718  /* This has an actual attribute */
719  *ssrc_attribute_name++ = '\0';
720  ssrc_attribute_value = strchr(ssrc_attribute_name, ':');
721  if (ssrc_attribute_value) {
722  /* Values are actually optional according to the spec */
723  *ssrc_attribute_value++ = '\0';
724  }
725 
726  if (!strcasecmp(ssrc_attribute_name, "mslabel") && !ast_strlen_zero(ssrc_attribute_value)) {
727  session_media->remote_mslabel = ast_strdup(ssrc_attribute_value);
728  break;
729  }
730  }
731  }
732  }
733 
734  if (ast_strlen_zero(session_media->remote_mslabel)) {
735  return;
736  }
737 
738  /* Iterate through the existing streams looking for a match and if so then group this with it */
739  for (index = 0; index < AST_VECTOR_SIZE(&session->pending_media_state->sessions); ++index) {
740  struct ast_sip_session_media *group_session_media;
741 
742  group_session_media = AST_VECTOR_GET(&session->pending_media_state->sessions, index);
743 
744  if (ast_strlen_zero(group_session_media->remote_mslabel) ||
745  strcmp(group_session_media->remote_mslabel, session_media->remote_mslabel)) {
746  continue;
747  }
748 
749  ast_stream_set_group(asterisk_stream, index);
750  break;
751  }
752 }
753 
754 static void remove_stream_from_bundle(struct ast_sip_session_media *session_media,
755  struct ast_stream *stream)
756 {
758  ast_free(session_media->mid);
759  session_media->mid = NULL;
760  session_media->bundle_group = -1;
761  session_media->bundled = 0;
762 }
763 
764 static int handle_incoming_sdp(struct ast_sip_session *session, const pjmedia_sdp_session *sdp)
765 {
766  int i;
767  int handled = 0;
768  int type_streams[AST_MEDIA_TYPE_END] = {0};
769  SCOPE_ENTER(3, "%s: Media count: %d\n", ast_sip_session_get_name(session), sdp->media_count);
770 
771  if (session->inv_session && session->inv_session->state == PJSIP_INV_STATE_DISCONNECTED) {
772  SCOPE_EXIT_LOG_RTN_VALUE(-1, LOG_ERROR, "%s: Failed to handle incoming SDP. Session has been already disconnected\n",
773  ast_sip_session_get_name(session));
774  }
775 
776  /* It is possible for SDP deferral to have already created a pending topology */
777  if (!session->pending_media_state->topology) {
779  if (!session->pending_media_state->topology) {
780  SCOPE_EXIT_LOG_RTN_VALUE(-1, LOG_ERROR, "%s: Couldn't alloc pending topology\n",
781  ast_sip_session_get_name(session));
782  }
783  }
784 
785  for (i = 0; i < sdp->media_count; ++i) {
786  /* See if there are registered handlers for this media stream type */
787  char media[20];
789  RAII_VAR(struct sdp_handler_list *, handler_list, NULL, ao2_cleanup);
790  struct ast_sip_session_media *session_media = NULL;
791  int res;
792  enum ast_media_type type;
793  struct ast_stream *stream = NULL;
794  pjmedia_sdp_media *remote_stream = sdp->media[i];
795  SCOPE_ENTER(4, "%s: Processing stream %d\n", ast_sip_session_get_name(session), i);
796 
797  /* We need a null-terminated version of the media string */
798  ast_copy_pj_str(media, &sdp->media[i]->desc.media, sizeof(media));
799  type = ast_media_type_from_str(media);
800 
801  /* See if we have an already existing stream, which can occur from SDP deferral checking */
804  ast_trace(-1, "%s: Using existing pending stream %s\n", ast_sip_session_get_name(session),
805  ast_str_tmp(128, ast_stream_to_str(stream, &STR_TMP)));
806  }
807  if (!stream) {
808  struct ast_stream *existing_stream = NULL;
809  char *stream_name = NULL, *stream_name_allocated = NULL;
810  const char *stream_label = NULL;
811 
812  if (session->active_media_state->topology &&
814  existing_stream = ast_stream_topology_get_stream(session->active_media_state->topology, i);
815  ast_trace(-1, "%s: Found existing active stream %s\n", ast_sip_session_get_name(session),
816  ast_str_tmp(128, ast_stream_to_str(existing_stream, &STR_TMP)));
817 
818  if (ast_stream_get_state(existing_stream) != AST_STREAM_STATE_REMOVED) {
819  stream_name = (char *)ast_stream_get_name(existing_stream);
820  stream_label = ast_stream_get_metadata(existing_stream, "SDP:LABEL");
821  }
822  }
823 
824  if (ast_strlen_zero(stream_name)) {
825  if (ast_asprintf(&stream_name_allocated, "%s-%d", ast_codec_media_type2str(type), i) < 0) {
826  handled = 0;
827  SCOPE_EXIT_LOG_EXPR(goto end, LOG_ERROR, "%s: Couldn't alloc stream name\n",
828  ast_sip_session_get_name(session));
829 
830  }
831  stream_name = stream_name_allocated;
832  ast_trace(-1, "%s: Using %s for new stream name\n", ast_sip_session_get_name(session),
833  stream_name);
834  }
835 
836  stream = ast_stream_alloc(stream_name, type);
837  ast_free(stream_name_allocated);
838  if (!stream) {
839  handled = 0;
840  SCOPE_EXIT_LOG_EXPR(goto end, LOG_ERROR, "%s: Couldn't alloc stream\n",
841  ast_sip_session_get_name(session));
842  }
843 
844  if (!ast_strlen_zero(stream_label)) {
845  ast_stream_set_metadata(stream, "SDP:LABEL", stream_label);
846  ast_trace(-1, "%s: Using %s for new stream label\n", ast_sip_session_get_name(session),
847  stream_label);
848 
849  }
850 
851  if (ast_stream_topology_set_stream(session->pending_media_state->topology, i, stream)) {
852  ast_stream_free(stream);
853  handled = 0;
854  SCOPE_EXIT_LOG_EXPR(goto end, LOG_ERROR, "%s: Couldn't set stream in topology\n",
855  ast_sip_session_get_name(session));
856  }
857 
858  /* For backwards compatibility with the core the default audio stream is always sendrecv */
859  if (!ast_sip_session_is_pending_stream_default(session, stream) || strcmp(media, "audio")) {
860  if (pjmedia_sdp_media_find_attr2(remote_stream, "sendonly", NULL)) {
861  /* Stream state reflects our state of a stream, so in the case of
862  * sendonly and recvonly we store the opposite since that is what ours
863  * is.
864  */
866  } else if (pjmedia_sdp_media_find_attr2(remote_stream, "recvonly", NULL)) {
868  } else if (pjmedia_sdp_media_find_attr2(remote_stream, "inactive", NULL)) {
870  } else {
872  }
873  } else {
875  }
876  ast_trace(-1, "%s: Using new stream %s\n", ast_sip_session_get_name(session),
877  ast_str_tmp(128, ast_stream_to_str(stream, &STR_TMP)));
878  }
879 
880  session_media = ast_sip_session_media_state_add(session, session->pending_media_state, ast_media_type_from_str(media), i);
881  if (!session_media) {
882  SCOPE_EXIT_LOG_EXPR(goto end, LOG_ERROR, "%s: Couldn't alloc session media\n",
883  ast_sip_session_get_name(session));
884  }
885 
886  /* If this stream is already declined mark it as such, or mark it as such if we've reached the limit */
887  if (!remote_stream->desc.port || is_stream_limitation_reached(type, session->endpoint, type_streams)) {
888  remove_stream_from_bundle(session_media, stream);
889  SCOPE_EXIT_EXPR(continue, "%s: Declining incoming SDP media stream %s'\n",
890  ast_sip_session_get_name(session), ast_str_tmp(128, ast_stream_to_str(stream, &STR_TMP)));
891  }
892 
893  set_mid_and_bundle_group(session, session_media, sdp, remote_stream);
894  set_remote_mslabel_and_stream_group(session, session_media, sdp, remote_stream, stream);
895 
896  if (session_media->handler) {
897  handler = session_media->handler;
898  ast_trace(-1, "%s: Negotiating incoming SDP media stream %s using %s SDP handler\n",
899  ast_sip_session_get_name(session), ast_str_tmp(128, ast_stream_to_str(stream, &STR_TMP)),
900  session_media->handler->id);
901  res = handler->negotiate_incoming_sdp_stream(session, session_media, sdp, i, stream);
902  if (res < 0) {
903  /* Catastrophic failure. Abort! */
904  SCOPE_EXIT_LOG_EXPR(goto end, LOG_ERROR, "%s: Couldn't negotiate stream %s\n",
905  ast_sip_session_get_name(session), ast_str_tmp(128, ast_stream_to_str(stream, &STR_TMP)));
906  } else if (res == 0) {
907  remove_stream_from_bundle(session_media, stream);
908  SCOPE_EXIT_EXPR(continue, "%s: Declining incoming SDP media stream %s\n",
909  ast_sip_session_get_name(session), ast_str_tmp(128, ast_stream_to_str(stream, &STR_TMP)));
910  } else if (res > 0) {
911  handled = 1;
912  ++type_streams[type];
913  /* Handled by this handler. Move to the next stream */
914  SCOPE_EXIT_EXPR(continue, "%s: Media stream %s handled by %s\n",
915  ast_sip_session_get_name(session), ast_str_tmp(128, ast_stream_to_str(stream, &STR_TMP)),
916  session_media->handler->id);
917  }
918  }
919 
920  handler_list = ao2_find(sdp_handlers, media, OBJ_KEY);
921  if (!handler_list) {
922  SCOPE_EXIT_EXPR(continue, "%s: Media stream %s has no registered handlers\n",
923  ast_sip_session_get_name(session), ast_str_tmp(128, ast_stream_to_str(stream, &STR_TMP)));
924  }
925  AST_LIST_TRAVERSE(&handler_list->list, handler, next) {
926  if (handler == session_media->handler) {
927  continue;
928  }
929  ast_trace(-1, "%s: Negotiating incoming SDP media stream %s using %s SDP handler\n",
930  ast_sip_session_get_name(session), ast_str_tmp(128, ast_stream_to_str(stream, &STR_TMP)),
931  handler->id);
932 
933  res = handler->negotiate_incoming_sdp_stream(session, session_media, sdp, i, stream);
934  if (res < 0) {
935  /* Catastrophic failure. Abort! */
936  handled = 0;
937  SCOPE_EXIT_LOG_EXPR(goto end, LOG_ERROR, "%s: Couldn't negotiate stream %s\n",
938  ast_sip_session_get_name(session), ast_str_tmp(128, ast_stream_to_str(stream, &STR_TMP)));
939  } else if (res == 0) {
940  remove_stream_from_bundle(session_media, stream);
941  ast_trace(-1, "%s: Declining incoming SDP media stream %s\n",
942  ast_sip_session_get_name(session), ast_str_tmp(128, ast_stream_to_str(stream, &STR_TMP)));
943  continue;
944  } else if (res > 0) {
945  session_media_set_handler(session_media, handler);
946  handled = 1;
947  ++type_streams[type];
948  ast_trace(-1, "%s: Media stream %s handled by %s\n",
949  ast_sip_session_get_name(session), ast_str_tmp(128, ast_stream_to_str(stream, &STR_TMP)),
950  session_media->handler->id);
951  break;
952  }
953  }
954 
955  SCOPE_EXIT("%s: Done with stream %s\n", ast_sip_session_get_name(session),
956  ast_str_tmp(128, ast_stream_to_str(stream, &STR_TMP)));
957  }
958 
959 end:
960  SCOPE_EXIT_RTN_VALUE(handled ? 0 : -1, "%s: Handled? %s\n", ast_sip_session_get_name(session),
961  handled ? "yes" : "no");
962 }
963 
965  struct ast_sip_session *session, const pjmedia_sdp_session *local,
966  const pjmedia_sdp_session *remote, int index, struct ast_stream *asterisk_stream)
967 {
968  /* See if there are registered handlers for this media stream type */
969  struct pjmedia_sdp_media *local_stream = local->media[index];
970  char media[20];
972  RAII_VAR(struct sdp_handler_list *, handler_list, NULL, ao2_cleanup);
973  int res;
974  SCOPE_ENTER(1, "%s\n", session ? ast_sip_session_get_name(session) : "unknown");
975 
976  /* We need a null-terminated version of the media string */
977  ast_copy_pj_str(media, &local->media[index]->desc.media, sizeof(media));
978 
979  /* For backwards compatibility we only reflect the stream state correctly on
980  * the non-default streams and any non-audio streams. This is because the stream
981  * state of the default audio stream is also used for signaling that someone has
982  * placed us on hold. This situation is not handled currently and can result in
983  * the remote side being sorted of placed on hold too.
984  */
985  if (!ast_sip_session_is_pending_stream_default(session, asterisk_stream) || strcmp(media, "audio")) {
986  /* Determine the state of the stream based on our local SDP */
987  if (pjmedia_sdp_media_find_attr2(local_stream, "sendonly", NULL)) {
989  } else if (pjmedia_sdp_media_find_attr2(local_stream, "recvonly", NULL)) {
991  } else if (pjmedia_sdp_media_find_attr2(local_stream, "inactive", NULL)) {
993  } else {
995  }
996  } else {
998  }
999 
1000  set_mid_and_bundle_group(session, session_media, remote, remote->media[index]);
1001  set_remote_mslabel_and_stream_group(session, session_media, remote, remote->media[index], asterisk_stream);
1002 
1003  handler = session_media->handler;
1004  if (handler) {
1005  ast_debug(4, "%s: Applying negotiated SDP media stream '%s' using %s SDP handler\n",
1006  ast_sip_session_get_name(session), ast_codec_media_type2str(session_media->type),
1007  handler->id);
1008  res = handler->apply_negotiated_sdp_stream(session, session_media, local, remote, index, asterisk_stream);
1009  if (res >= 0) {
1010  ast_debug(4, "%s: Applied negotiated SDP media stream '%s' using %s SDP handler\n",
1011  ast_sip_session_get_name(session), ast_codec_media_type2str(session_media->type),
1012  handler->id);
1013  SCOPE_EXIT_RTN_VALUE(0, "%s: Applied negotiated SDP media stream '%s' using %s SDP handler\n",
1014  ast_sip_session_get_name(session), ast_codec_media_type2str(session_media->type),
1015  handler->id);
1016  }
1017  SCOPE_EXIT_RTN_VALUE(-1, "%s: Failed to apply negotiated SDP media stream '%s' using %s SDP handler\n",
1018  ast_sip_session_get_name(session), ast_codec_media_type2str(session_media->type),
1019  handler->id);
1020  }
1021 
1022  handler_list = ao2_find(sdp_handlers, media, OBJ_KEY);
1023  if (!handler_list) {
1024  ast_debug(4, "%s: No registered SDP handlers for media type '%s'\n", ast_sip_session_get_name(session), media);
1025  return -1;
1026  }
1027  AST_LIST_TRAVERSE(&handler_list->list, handler, next) {
1028  if (handler == session_media->handler) {
1029  continue;
1030  }
1031  ast_debug(4, "%s: Applying negotiated SDP media stream '%s' using %s SDP handler\n",
1032  ast_sip_session_get_name(session), ast_codec_media_type2str(session_media->type),
1033  handler->id);
1034  res = handler->apply_negotiated_sdp_stream(session, session_media, local, remote, index, asterisk_stream);
1035  if (res < 0) {
1036  /* Catastrophic failure. Abort! */
1037  SCOPE_EXIT_RTN_VALUE(-1, "%s: Handler '%s' returned %d\n",
1038  ast_sip_session_get_name(session), handler->id, res);
1039  }
1040  if (res > 0) {
1041  ast_debug(4, "%s: Applied negotiated SDP media stream '%s' using %s SDP handler\n",
1042  ast_sip_session_get_name(session), ast_codec_media_type2str(session_media->type),
1043  handler->id);
1044  /* Handled by this handler. Move to the next stream */
1045  session_media_set_handler(session_media, handler);
1046  SCOPE_EXIT_RTN_VALUE(0, "%s: Handler '%s' handled this sdp stream\n",
1047  ast_sip_session_get_name(session), handler->id);
1048  }
1049  }
1050 
1051  res = 0;
1052  if (session_media->handler && session_media->handler->stream_stop) {
1053  ast_debug(4, "%s: Stopping SDP media stream '%s' as it is not currently negotiated\n",
1054  ast_sip_session_get_name(session), ast_codec_media_type2str(session_media->type));
1055  session_media->handler->stream_stop(session_media);
1056  }
1057 
1058  SCOPE_EXIT_RTN_VALUE(0, "%s: Media type '%s' %s\n",
1059  ast_sip_session_get_name(session), ast_codec_media_type2str(session_media->type),
1060  res ? "not negotiated. Stopped" : "handled");
1061 }
1062 
1063 static int handle_negotiated_sdp(struct ast_sip_session *session, const pjmedia_sdp_session *local, const pjmedia_sdp_session *remote)
1064 {
1065  int i;
1066  struct ast_stream_topology *topology;
1067  unsigned int changed = 0; /* 0 = unchanged, 1 = new source, 2 = new topology */
1068  SCOPE_ENTER(1, "%s\n", ast_sip_session_get_name(session));
1069 
1070  if (!session->pending_media_state->topology) {
1071  if (session->active_media_state->topology) {
1072  /*
1073  * This happens when we have negotiated media after receiving a 183,
1074  * and we're now receiving a 200 with a new SDP. In this case, there
1075  * is active_media_state, but the pending_media_state has been reset.
1076  */
1077  struct ast_sip_session_media_state *active_media_state_clone;
1078 
1079  active_media_state_clone =
1081  if (!active_media_state_clone) {
1082  ast_log(LOG_WARNING, "%s: Unable to clone active media state\n",
1083  ast_sip_session_get_name(session));
1084  return -1;
1085  }
1086 
1088  session->pending_media_state = active_media_state_clone;
1089  } else {
1090  ast_log(LOG_WARNING, "%s: No pending or active media state\n",
1091  ast_sip_session_get_name(session));
1092  return -1;
1093  }
1094  }
1095 
1096  /* If we're handling negotiated streams, then we should already have set
1097  * up session media instances (and Asterisk streams) that correspond to
1098  * the local SDP, and there should be the same number of session medias
1099  * and streams as there are local SDP streams
1100  */
1101  if (ast_stream_topology_get_count(session->pending_media_state->topology) != local->media_count
1102  || AST_VECTOR_SIZE(&session->pending_media_state->sessions) != local->media_count) {
1103  ast_log(LOG_WARNING, "%s: Local SDP contains %d media streams while we expected it to contain %u\n",
1104  ast_sip_session_get_name(session),
1105  ast_stream_topology_get_count(session->pending_media_state->topology), local->media_count);
1106  SCOPE_EXIT_RTN_VALUE(-1, "Media stream count mismatch\n");
1107  }
1108 
1109  for (i = 0; i < local->media_count; ++i) {
1110  struct ast_sip_session_media *session_media;
1111  struct ast_stream *stream;
1112 
1113  if (!remote->media[i]) {
1114  continue;
1115  }
1116 
1117  session_media = AST_VECTOR_GET(&session->pending_media_state->sessions, i);
1119 
1120  /* Make sure that this stream is in the correct state. If we need to change
1121  * the state to REMOVED, then our work here is done, so go ahead and move on
1122  * to the next stream.
1123  */
1124  if (!remote->media[i]->desc.port) {
1126  continue;
1127  }
1128 
1129  /* If the stream state is REMOVED, nothing needs to be done, so move on to the
1130  * next stream. This can occur if an internal thing has requested it to be
1131  * removed, or if we remove it as a result of the stream limit being reached.
1132  */
1134  /*
1135  * Defer removing the handler until we are ready to activate
1136  * the new topology. The channel's thread may still be using
1137  * the stream and we could crash before we are ready.
1138  */
1139  continue;
1140  }
1141 
1142  if (handle_negotiated_sdp_session_media(session_media, session, local, remote, i, stream)) {
1143  SCOPE_EXIT_RTN_VALUE(-1, "Unable to handle negotiated session media\n");
1144  }
1145 
1146  changed |= session_media->changed;
1147  session_media->changed = 0;
1148  }
1149 
1150  /* Apply the pending media state to the channel and make it active */
1151  ast_channel_lock(session->channel);
1152 
1153  /* Now update the stream handler for any declined/removed streams */
1154  for (i = 0; i < local->media_count; ++i) {
1155  struct ast_sip_session_media *session_media;
1156  struct ast_stream *stream;
1157 
1158  if (!remote->media[i]) {
1159  continue;
1160  }
1161 
1162  session_media = AST_VECTOR_GET(&session->pending_media_state->sessions, i);
1164 
1166  && session_media->handler) {
1167  /*
1168  * This stream is no longer being used and the channel's thread
1169  * is held off because we have the channel lock so release any
1170  * resources the handler may have on it.
1171  */
1172  session_media_set_handler(session_media, NULL);
1173  }
1174  }
1175 
1176  /* Update the topology on the channel to match the accepted one */
1178  if (topology) {
1179  ast_channel_set_stream_topology(session->channel, topology);
1180  /* If this is a remotely done renegotiation that has changed the stream topology notify what is
1181  * currently handling this channel. Note that fax uses its own process, so if we are transitioning
1182  * between audio and fax or vice versa we don't notify.
1183  */
1184  if (pjmedia_sdp_neg_was_answer_remote(session->inv_session->neg) == PJ_FALSE &&
1185  session->active_media_state && session->active_media_state->topology &&
1186  !ast_stream_topology_equal(session->active_media_state->topology, topology) &&
1189  changed = 2;
1190  }
1191  }
1192 
1193  /* Remove all current file descriptors from the channel */
1194  for (i = 0; i < AST_VECTOR_SIZE(&session->active_media_state->read_callbacks); ++i) {
1196  }
1197 
1198  /* Add all the file descriptors from the pending media state */
1199  for (i = 0; i < AST_VECTOR_SIZE(&session->pending_media_state->read_callbacks); ++i) {
1200  struct ast_sip_session_media_read_callback_state *callback_state;
1201 
1202  callback_state = AST_VECTOR_GET_ADDR(&session->pending_media_state->read_callbacks, i);
1203  ast_channel_internal_fd_set(session->channel, i + AST_EXTENDED_FDS, callback_state->fd);
1204  }
1205 
1206  /* Active and pending flip flop as needed */
1208  SWAP(session->active_media_state, session->pending_media_state);
1210 
1211  ast_channel_unlock(session->channel);
1212 
1213  if (changed == 1) {
1214  struct ast_frame f = { AST_FRAME_CONTROL, .subclass.integer = AST_CONTROL_STREAM_TOPOLOGY_SOURCE_CHANGED };
1215 
1216  ast_queue_frame(session->channel, &f);
1217  } else if (changed == 2) {
1219  } else {
1221  }
1222 
1224 }
1225 
1226 #define DATASTORE_BUCKETS 53
1227 #define MEDIA_BUCKETS 7
1228 
1229 static void session_datastore_destroy(void *obj)
1230 {
1231  struct ast_datastore *datastore = obj;
1232 
1233  /* Using the destroy function (if present) destroy the data */
1234  if (datastore->info->destroy != NULL && datastore->data != NULL) {
1235  datastore->info->destroy(datastore->data);
1236  datastore->data = NULL;
1237  }
1238 
1239  ast_free((void *) datastore->uid);
1240  datastore->uid = NULL;
1241 }
1242 
1244 {
1245  RAII_VAR(struct ast_datastore *, datastore, NULL, ao2_cleanup);
1246  char uuid_buf[AST_UUID_STR_LEN];
1247  const char *uid_ptr = uid;
1248 
1249  if (!info) {
1250  return NULL;
1251  }
1252 
1253  datastore = ao2_alloc(sizeof(*datastore), session_datastore_destroy);
1254  if (!datastore) {
1255  return NULL;
1256  }
1257 
1258  datastore->info = info;
1259  if (ast_strlen_zero(uid)) {
1260  /* They didn't provide an ID so we'll provide one ourself */
1261  uid_ptr = ast_uuid_generate_str(uuid_buf, sizeof(uuid_buf));
1262  }
1263 
1264  datastore->uid = ast_strdup(uid_ptr);
1265  if (!datastore->uid) {
1266  return NULL;
1267  }
1268 
1269  ao2_ref(datastore, +1);
1270  return datastore;
1271 }
1272 
1274 {
1275  ast_assert(datastore != NULL);
1276  ast_assert(datastore->info != NULL);
1277  ast_assert(ast_strlen_zero(datastore->uid) == 0);
1278 
1279  if (!ao2_link(session->datastores, datastore)) {
1280  return -1;
1281  }
1282  return 0;
1283 }
1284 
1286 {
1287  return ao2_find(session->datastores, name, OBJ_KEY);
1288 }
1289 
1291 {
1292  ao2_callback(session->datastores, OBJ_KEY | OBJ_UNLINK | OBJ_NODATA, NULL, (void *) name);
1293 }
1294 
1299 };
1300 
1301 /*!
1302  * \internal
1303  * \brief Convert delayed method enum value to a string.
1304  * \since 13.3.0
1305  *
1306  * \param method Delayed method enum value to convert to a string.
1307  *
1308  * \return String value of delayed method.
1309  */
1310 static const char *delayed_method2str(enum delayed_method method)
1311 {
1312  const char *str = "<unknown>";
1313 
1314  switch (method) {
1315  case DELAYED_METHOD_INVITE:
1316  str = "INVITE";
1317  break;
1318  case DELAYED_METHOD_UPDATE:
1319  str = "UPDATE";
1320  break;
1321  case DELAYED_METHOD_BYE:
1322  str = "BYE";
1323  break;
1324  }
1325 
1326  return str;
1327 }
1328 
1329 /*!
1330  * \brief Structure used for sending delayed requests
1331  *
1332  * Requests are typically delayed because the current transaction
1333  * state of an INVITE. Once the pending INVITE transaction terminates,
1334  * the delayed request will be sent
1335  */
1337  /*! Method of the request */
1339  /*! Callback to call when the delayed request is created. */
1341  /*! Callback to call when the delayed request SDP is created */
1343  /*! Callback to call when the delayed request receives a response */
1345  /*! Whether to generate new SDP */
1347  /*! Requested media state for the SDP */
1349  /*! Active media state at the time of the original request */
1351 
1353 };
1354 
1356  enum delayed_method method,
1360  int generate_new_sdp,
1363 {
1364  struct ast_sip_session_delayed_request *delay = ast_calloc(1, sizeof(*delay));
1365 
1366  if (!delay) {
1367  return NULL;
1368  }
1369  delay->method = method;
1372  delay->on_response = on_response;
1376  return delay;
1377 }
1378 
1380 {
1383  ast_free(delay);
1384 }
1385 
1386 /*!
1387  * \internal
1388  * \brief Send a delayed request
1389  *
1390  * \retval -1 failure
1391  * \retval 0 success
1392  * \retval 1 refresh request not sent as no change would occur
1393  */
1395 {
1396  int res;
1397  SCOPE_ENTER(3, "%s: sending delayed %s request\n",
1398  ast_sip_session_get_name(session),
1399  delayed_method2str(delay->method));
1400 
1401  switch (delay->method) {
1402  case DELAYED_METHOD_INVITE:
1403  res = sip_session_refresh(session, delay->on_request_creation,
1404  delay->on_sdp_creation, delay->on_response,
1406  delay->active_media_state, 1);
1407  /* Ownership of media state transitions to ast_sip_session_refresh */
1408  delay->pending_media_state = NULL;
1409  delay->active_media_state = NULL;
1410  SCOPE_EXIT_RTN_VALUE(res, "%s\n", ast_sip_session_get_name(session));
1411  case DELAYED_METHOD_UPDATE:
1412  res = sip_session_refresh(session, delay->on_request_creation,
1413  delay->on_sdp_creation, delay->on_response,
1415  delay->active_media_state, 1);
1416  /* Ownership of media state transitions to ast_sip_session_refresh */
1417  delay->pending_media_state = NULL;
1418  delay->active_media_state = NULL;
1419  SCOPE_EXIT_RTN_VALUE(res, "%s\n", ast_sip_session_get_name(session));
1420  case DELAYED_METHOD_BYE:
1421  ast_sip_session_terminate(session, 0);
1422  SCOPE_EXIT_RTN_VALUE(0, "%s: Terminating session on delayed BYE\n", ast_sip_session_get_name(session));
1423  }
1424 
1425  SCOPE_EXIT_LOG_RTN_VALUE(-1, LOG_WARNING, "%s: Don't know how to send delayed %s(%d) request.\n",
1426  ast_sip_session_get_name(session),
1427  delayed_method2str(delay->method), delay->method);
1428 }
1429 
1430 /*!
1431  * \internal
1432  * \brief The current INVITE transaction is in the PROCEEDING state.
1433  * \since 13.3.0
1434  *
1435  * \param vsession Session object.
1436  *
1437  * \retval 0 on success.
1438  * \retval -1 on error.
1439  */
1440 static int invite_proceeding(void *vsession)
1441 {
1442  struct ast_sip_session *session = vsession;
1443  struct ast_sip_session_delayed_request *delay;
1444  int found = 0;
1445  int res = 0;
1446  SCOPE_ENTER(3, "%s\n", ast_sip_session_get_name(session));
1447 
1449  switch (delay->method) {
1450  case DELAYED_METHOD_INVITE:
1451  break;
1452  case DELAYED_METHOD_UPDATE:
1454  ast_trace(-1, "%s: Sending delayed %s request\n", ast_sip_session_get_name(session),
1455  delayed_method2str(delay->method));
1456  res = send_delayed_request(session, delay);
1457  delayed_request_free(delay);
1458  if (!res) {
1459  found = 1;
1460  }
1461  break;
1462  case DELAYED_METHOD_BYE:
1463  /* A BYE is pending so don't bother anymore. */
1464  found = 1;
1465  break;
1466  }
1467  if (found) {
1468  break;
1469  }
1470  }
1472 
1473  ao2_ref(session, -1);
1474  SCOPE_EXIT_RTN_VALUE(res, "%s\n", ast_sip_session_get_name(session));
1475 }
1476 
1477 /*!
1478  * \internal
1479  * \brief The current INVITE transaction is in the TERMINATED state.
1480  * \since 13.3.0
1481  *
1482  * \param vsession Session object.
1483  *
1484  * \retval 0 on success.
1485  * \retval -1 on error.
1486  */
1487 static int invite_terminated(void *vsession)
1488 {
1489  struct ast_sip_session *session = vsession;
1490  struct ast_sip_session_delayed_request *delay;
1491  int found = 0;
1492  int res = 0;
1493  int timer_running;
1494  SCOPE_ENTER(3, "%s\n", ast_sip_session_get_name(session));
1495 
1496  /* re-INVITE collision timer running? */
1497  timer_running = pj_timer_entry_running(&session->rescheduled_reinvite);
1498 
1500  switch (delay->method) {
1501  case DELAYED_METHOD_INVITE:
1502  if (!timer_running) {
1503  found = 1;
1504  }
1505  break;
1506  case DELAYED_METHOD_UPDATE:
1507  case DELAYED_METHOD_BYE:
1508  found = 1;
1509  break;
1510  }
1511  if (found) {
1513  ast_trace(-1, "%s: Sending delayed %s request\n", ast_sip_session_get_name(session),
1514  delayed_method2str(delay->method));
1515  res = send_delayed_request(session, delay);
1516  delayed_request_free(delay);
1517  if (!res) {
1518  break;
1519  }
1520  }
1521  }
1523 
1524  ao2_ref(session, -1);
1525  SCOPE_EXIT_RTN_VALUE(res, "%s\n", ast_sip_session_get_name(session));
1526 }
1527 
1528 /*!
1529  * \internal
1530  * \brief INVITE collision timeout.
1531  * \since 13.3.0
1532  *
1533  * \param vsession Session object.
1534  *
1535  * \retval 0 on success.
1536  * \retval -1 on error.
1537  */
1538 static int invite_collision_timeout(void *vsession)
1539 {
1540  struct ast_sip_session *session = vsession;
1541  int res;
1542  SCOPE_ENTER(3, "%s\n", ast_sip_session_get_name(session));
1543 
1544  if (session->inv_session->invite_tsx) {
1545  /*
1546  * INVITE transaction still active. Let it send
1547  * the collision re-INVITE when it terminates.
1548  */
1549  ao2_ref(session, -1);
1550  res = 0;
1551  } else {
1552  res = invite_terminated(session);
1553  }
1554 
1555  SCOPE_EXIT_RTN_VALUE(res, "%s\n", ast_sip_session_get_name(session));
1556 }
1557 
1558 /*!
1559  * \internal
1560  * \brief The current UPDATE transaction is in the COMPLETED state.
1561  * \since 13.3.0
1562  *
1563  * \param vsession Session object.
1564  *
1565  * \retval 0 on success.
1566  * \retval -1 on error.
1567  */
1568 static int update_completed(void *vsession)
1569 {
1570  struct ast_sip_session *session = vsession;
1571  int res;
1572 
1573  if (session->inv_session->invite_tsx) {
1574  res = invite_proceeding(session);
1575  } else {
1576  res = invite_terminated(session);
1577  }
1578 
1579  return res;
1580 }
1581 
1583  int (*cb)(void *vsession))
1584 {
1585  ao2_ref(session, +1);
1586  if (ast_sip_push_task(session->serializer, cb, session)) {
1587  ao2_ref(session, -1);
1588  }
1589 }
1590 
1591 static int delay_request(struct ast_sip_session *session,
1593  ast_sip_session_sdp_creation_cb on_sdp_creation,
1594  ast_sip_session_response_cb on_response,
1595  int generate_new_sdp,
1596  enum delayed_method method,
1599  int queue_head)
1600 {
1602  on_request, on_sdp_creation, on_response, generate_new_sdp, pending_media_state,
1603  active_media_state);
1604  SCOPE_ENTER(3, "%s\n", ast_sip_session_get_name(session));
1605 
1606  if (!delay) {
1607  ast_sip_session_media_state_free(pending_media_state);
1608  ast_sip_session_media_state_free(active_media_state);
1609  SCOPE_EXIT_LOG_RTN_VALUE(-1, LOG_ERROR, "Unable to allocate delay request\n");
1610  }
1611 
1612  if (method == DELAYED_METHOD_BYE || queue_head) {
1613  /* Send BYE as early as possible */
1614  AST_LIST_INSERT_HEAD(&session->delayed_requests, delay, next);
1615  } else {
1616  AST_LIST_INSERT_TAIL(&session->delayed_requests, delay, next);
1617  }
1619 }
1620 
1621 static pjmedia_sdp_session *generate_session_refresh_sdp(struct ast_sip_session *session)
1622 {
1623  pjsip_inv_session *inv_session = session->inv_session;
1624  const pjmedia_sdp_session *previous_sdp = NULL;
1625  SCOPE_ENTER(3, "%s\n", ast_sip_session_get_name(session));
1626 
1627  if (inv_session->neg) {
1628  if (pjmedia_sdp_neg_was_answer_remote(inv_session->neg)) {
1629  pjmedia_sdp_neg_get_active_remote(inv_session->neg, &previous_sdp);
1630  } else {
1631  pjmedia_sdp_neg_get_active_local(inv_session->neg, &previous_sdp);
1632  }
1633  }
1634  SCOPE_EXIT_RTN_VALUE(create_local_sdp(inv_session, session, previous_sdp));
1635 }
1636 
1637 static void set_from_header(struct ast_sip_session *session)
1638 {
1639  struct ast_party_id effective_id;
1640  struct ast_party_id connected_id;
1641  pj_pool_t *dlg_pool;
1642  pjsip_fromto_hdr *dlg_info;
1643  pjsip_contact_hdr *dlg_contact;
1644  pjsip_name_addr *dlg_info_name_addr;
1645  pjsip_sip_uri *dlg_info_uri;
1646  pjsip_sip_uri *dlg_contact_uri;
1647  int restricted;
1648  const char *pjsip_from_domain;
1649 
1650  if (!session->channel || session->saved_from_hdr) {
1651  return;
1652  }
1653 
1654  /* We need to save off connected_id for RPID/PAI generation */
1655  ast_party_id_init(&connected_id);
1656  ast_channel_lock(session->channel);
1657  effective_id = ast_channel_connected_effective_id(session->channel);
1658  ast_party_id_copy(&connected_id, &effective_id);
1659  ast_channel_unlock(session->channel);
1660 
1661  restricted =
1663 
1664  /* Now set up dlg->local.info so pjsip can correctly generate From */
1665 
1666  dlg_pool = session->inv_session->dlg->pool;
1667  dlg_info = session->inv_session->dlg->local.info;
1668  dlg_contact = session->inv_session->dlg->local.contact;
1669  dlg_info_name_addr = (pjsip_name_addr *) dlg_info->uri;
1670  dlg_info_uri = pjsip_uri_get_uri(dlg_info_name_addr);
1671  dlg_contact_uri = (pjsip_sip_uri*)pjsip_uri_get_uri(dlg_contact->uri);
1672 
1673  if (session->endpoint->id.trust_outbound || !restricted) {
1674  ast_sip_modify_id_header(dlg_pool, dlg_info, &connected_id);
1676  pj_strdup2(dlg_pool, &dlg_contact_uri->user, S_COR(connected_id.number.valid, connected_id.number.str, ""));
1677  }
1678  }
1679 
1680  ast_party_id_free(&connected_id);
1681 
1682  if (!ast_strlen_zero(session->endpoint->fromuser)) {
1683  dlg_info_name_addr->display.ptr = NULL;
1684  dlg_info_name_addr->display.slen = 0;
1685  pj_strdup2(dlg_pool, &dlg_info_uri->user, session->endpoint->fromuser);
1686  }
1687 
1688  if (!ast_strlen_zero(session->endpoint->fromdomain)) {
1689  pj_strdup2(dlg_pool, &dlg_info_uri->host, session->endpoint->fromdomain);
1690  }
1691 
1692  /*
1693  * Channel variable for compatibility with chan_sip SIPFROMDOMAIN
1694  */
1695  ast_channel_lock(session->channel);
1696  pjsip_from_domain = pbx_builtin_getvar_helper(session->channel, "SIPFROMDOMAIN");
1697  if (!ast_strlen_zero(pjsip_from_domain)) {
1698  ast_debug(3, "%s: From header domain reset by channel variable SIPFROMDOMAIN (%s)\n",
1699  ast_sip_session_get_name(session), pjsip_from_domain);
1700  pj_strdup2(dlg_pool, &dlg_info_uri->host, pjsip_from_domain);
1701  }
1702  ast_channel_unlock(session->channel);
1703 
1704  /* We need to save off the non-anonymized From for RPID/PAI generation (for domain) */
1705  session->saved_from_hdr = pjsip_hdr_clone(dlg_pool, dlg_info);
1706  ast_sip_add_usereqphone(session->endpoint, dlg_pool, session->saved_from_hdr->uri);
1707 
1708  /* In chan_sip, fromuser and fromdomain trump restricted so we only
1709  * anonymize if they're not set.
1710  */
1711  if (restricted) {
1712  /* fromuser doesn't provide a display name so we always set it */
1713  pj_strdup2(dlg_pool, &dlg_info_name_addr->display, "Anonymous");
1714 
1715  if (ast_strlen_zero(session->endpoint->fromuser)) {
1716  pj_strdup2(dlg_pool, &dlg_info_uri->user, "anonymous");
1717  }
1718 
1720  pj_strdup2(dlg_pool, &dlg_contact_uri->user, "anonymous");
1721  }
1722 
1723  if (ast_strlen_zero(session->endpoint->fromdomain)) {
1724  pj_strdup2(dlg_pool, &dlg_info_uri->host, "anonymous.invalid");
1725  }
1726  } else {
1727  ast_sip_add_usereqphone(session->endpoint, dlg_pool, dlg_info->uri);
1728  }
1729 }
1730 
1731 /*
1732  * Helper macros for merging and validating media states
1733  */
1734 #define STREAM_REMOVED(_stream) (ast_stream_get_state(_stream) == AST_STREAM_STATE_REMOVED)
1735 #define STATE_REMOVED(_stream_state) (_stream_state == AST_STREAM_STATE_REMOVED)
1736 #define STATE_NONE(_stream_state) (_stream_state == AST_STREAM_STATE_END)
1737 #define GET_STREAM_SAFE(_topology, _i) (_i < ast_stream_topology_get_count(_topology) ? ast_stream_topology_get_stream(_topology, _i) : NULL)
1738 #define GET_STREAM_STATE_SAFE(_stream) (_stream ? ast_stream_get_state(_stream) : AST_STREAM_STATE_END)
1739 #define GET_STREAM_NAME_SAFE(_stream) (_stream ? ast_stream_get_name(_stream) : "")
1740 
1741 /*!
1742  * \internal
1743  * \brief Validate a media state
1744  *
1745  * \param state Media state
1746  *
1747  * \retval 1 The media state is valid
1748  * \retval 0 The media state is NOT valid
1749  *
1750  */
1751 static int is_media_state_valid(const char *session_name, struct ast_sip_session_media_state *state)
1752 {
1753  int stream_count = ast_stream_topology_get_count(state->topology);
1754  int session_count = AST_VECTOR_SIZE(&state->sessions);
1755  int i;
1756  int res = 0;
1757  SCOPE_ENTER(3, "%s: Topology: %s\n", session_name,
1758  ast_str_tmp(256, ast_stream_topology_to_str(state->topology, &STR_TMP)));
1759 
1760  if (session_count != stream_count) {
1761  SCOPE_EXIT_RTN_VALUE(0, "%s: %d media sessions but %d streams\n", session_name,
1762  session_count, stream_count);
1763  }
1764 
1765  for (i = 0; i < stream_count; i++) {
1766  struct ast_sip_session_media *media = NULL;
1767  struct ast_stream *stream = ast_stream_topology_get_stream(state->topology, i);
1768  const char *stream_name = NULL;
1769  int j;
1770  SCOPE_ENTER(4, "%s: Checking stream %s\n", session_name, ast_str_tmp(128, ast_stream_to_str(stream, &STR_TMP)));
1771 
1772  if (!stream) {
1773  SCOPE_EXIT_EXPR(goto end, "%s: stream %d is null\n", session_name, i);
1774  }
1775  stream_name = ast_stream_get_name(stream);
1776 
1777  for (j = 0; j < stream_count; j++) {
1778  struct ast_stream *possible_dup = ast_stream_topology_get_stream(state->topology, j);
1779  if (j == i || !possible_dup) {
1780  continue;
1781  }
1782  if (!STREAM_REMOVED(stream) && ast_strings_equal(stream_name, GET_STREAM_NAME_SAFE(possible_dup))) {
1783  SCOPE_EXIT_EXPR(goto end, "%s: stream %i %s is duplicated to %d\n", session_name,
1784  i, stream_name, j);
1785  }
1786  }
1787 
1788  media = AST_VECTOR_GET(&state->sessions, i);
1789  if (!media) {
1790  SCOPE_EXIT_EXPR(continue, "%s: media %d is null\n", session_name, i);
1791  }
1792 
1793  for (j = 0; j < session_count; j++) {
1794  struct ast_sip_session_media *possible_dup = AST_VECTOR_GET(&state->sessions, j);
1795  if (j == i || !possible_dup) {
1796  continue;
1797  }
1798  if (!ast_strlen_zero(media->label) && !ast_strlen_zero(possible_dup->label)
1799  && ast_strings_equal(media->label, possible_dup->label)) {
1800  SCOPE_EXIT_EXPR(goto end, "%s: media %d %s is duplicated to %d\n", session_name,
1801  i, media->label, j);
1802  }
1803  }
1804 
1805  if (media->stream_num != i) {
1806  SCOPE_EXIT_EXPR(goto end, "%s: media %d has stream_num %d\n", session_name,
1807  i, media->stream_num);
1808  }
1809 
1810  if (media->type != ast_stream_get_type(stream)) {
1811  SCOPE_EXIT_EXPR(goto end, "%s: media %d has type %s but stream has type %s\n", stream_name,
1813  }
1814  SCOPE_EXIT("%s: Done with stream %s\n", session_name, ast_str_tmp(128, ast_stream_to_str(stream, &STR_TMP)));
1815  }
1816 
1817  res = 1;
1818 end:
1819  SCOPE_EXIT_RTN_VALUE(res, "%s: %s\n", session_name, res ? "Valid" : "NOT Valid");
1820 }
1821 
1822 /*!
1823  * \internal
1824  * \brief Merge media states for a delayed session refresh
1825  *
1826  * \param session_name For log messages
1827  * \param delayed_pending_state The pending media state at the time the resuest was queued
1828  * \param delayed_active_state The active media state at the time the resuest was queued
1829  * \param current_active_state The current active media state
1830  * \param run_validation Whether to run validation on the resulting media state or not
1831  *
1832  * \returns New merged topology or NULL if there's an error
1833  *
1834  */
1836  const char *session_name,
1837  struct ast_sip_session_media_state *delayed_pending_state,
1838  struct ast_sip_session_media_state *delayed_active_state,
1839  struct ast_sip_session_media_state *current_active_state,
1840  int run_post_validation)
1841 {
1843  struct ast_sip_session_media_state *returned_media_state = NULL;
1844  struct ast_stream_topology *delayed_pending = delayed_pending_state->topology;
1845  struct ast_stream_topology *delayed_active = delayed_active_state->topology;
1846  struct ast_stream_topology *current_active = current_active_state->topology;
1847  struct ast_stream_topology *new_pending = NULL;
1848  int i;
1849  int max_stream_count;
1850  int res;
1851  SCOPE_ENTER(2, "%s: DP: %s DA: %s CA: %s\n", session_name,
1852  ast_str_tmp(256, ast_stream_topology_to_str(delayed_pending, &STR_TMP)),
1853  ast_str_tmp(256, ast_stream_topology_to_str(delayed_active, &STR_TMP)),
1854  ast_str_tmp(256, ast_stream_topology_to_str(current_active, &STR_TMP))
1855  );
1856 
1857  max_stream_count = MAX(ast_stream_topology_get_count(delayed_pending),
1858  ast_stream_topology_get_count(delayed_active));
1859  max_stream_count = MAX(max_stream_count, ast_stream_topology_get_count(current_active));
1860 
1861  /*
1862  * The new_pending_state is always based on the currently negotiated state because
1863  * the stream ordering in its topology must be preserved.
1864  */
1865  new_pending_state = ast_sip_session_media_state_clone(current_active_state);
1866  if (!new_pending_state) {
1867  SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR, "%s: Couldn't clone current_active_state to new_pending_state\n", session_name);
1868  }
1869  new_pending = new_pending_state->topology;
1870 
1871  for (i = 0; i < max_stream_count; i++) {
1872  struct ast_stream *dp_stream = GET_STREAM_SAFE(delayed_pending, i);
1873  struct ast_stream *da_stream = GET_STREAM_SAFE(delayed_active, i);
1874  struct ast_stream *ca_stream = GET_STREAM_SAFE(current_active, i);
1875  struct ast_stream *np_stream = GET_STREAM_SAFE(new_pending, i);
1876  struct ast_stream *found_da_stream = NULL;
1877  struct ast_stream *found_np_stream = NULL;
1878  enum ast_stream_state dp_state = GET_STREAM_STATE_SAFE(dp_stream);
1879  enum ast_stream_state da_state = GET_STREAM_STATE_SAFE(da_stream);
1880  enum ast_stream_state ca_state = GET_STREAM_STATE_SAFE(ca_stream);
1881  enum ast_stream_state np_state = GET_STREAM_STATE_SAFE(np_stream);
1882  enum ast_stream_state found_da_state = AST_STREAM_STATE_END;
1883  enum ast_stream_state found_np_state = AST_STREAM_STATE_END;
1884  const char *da_name = GET_STREAM_NAME_SAFE(da_stream);
1885  const char *dp_name = GET_STREAM_NAME_SAFE(dp_stream);
1886  const char *ca_name = GET_STREAM_NAME_SAFE(ca_stream);
1887  const char *np_name = GET_STREAM_NAME_SAFE(np_stream);
1888  const char *found_da_name __attribute__((unused)) = "";
1889  const char *found_np_name __attribute__((unused)) = "";
1890  int found_da_slot __attribute__((unused)) = -1;
1891  int found_np_slot = -1;
1892  int removed_np_slot = -1;
1893  int j;
1894  SCOPE_ENTER(3, "%s: slot: %d DP: %s DA: %s CA: %s\n", session_name, i,
1895  ast_str_tmp(128, ast_stream_to_str(dp_stream, &STR_TMP)),
1896  ast_str_tmp(128, ast_stream_to_str(da_stream, &STR_TMP)),
1897  ast_str_tmp(128, ast_stream_to_str(ca_stream, &STR_TMP)));
1898 
1899  if (STATE_NONE(da_state) && STATE_NONE(dp_state) && STATE_NONE(ca_state)) {
1900  SCOPE_EXIT_EXPR(break, "%s: All gone\n", session_name);
1901  }
1902 
1903  /*
1904  * Simple cases are handled first to avoid having to search the NP and DA
1905  * topologies for streams with the same name but not in the same position.
1906  */
1907 
1908  if (STATE_NONE(dp_state) && !STATE_NONE(da_state)) {
1909  /*
1910  * The slot in the delayed pending topology can't be empty if the delayed
1911  * active topology has a stream there. Streams can't just go away. They
1912  * can be reused or marked "removed" but they can't go away.
1913  */
1914  SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_WARNING, "%s: DP slot is empty but DA is not\n", session_name);
1915  }
1916 
1917  if (STATE_NONE(dp_state)) {
1918  /*
1919  * The current active topology can certainly have streams that weren't
1920  * in existence when the delayed request was queued. In this case,
1921  * no action is needed since we already copied the current active topology
1922  * to the new pending one.
1923  */
1924  SCOPE_EXIT_EXPR(continue, "%s: No DP stream so use CA stream as is\n", session_name);
1925  }
1926 
1927  if (ast_strings_equal(dp_name, da_name) && ast_strings_equal(da_name, ca_name)) {
1928  /*
1929  * The delayed pending stream in this slot matches by name, the streams
1930  * in the same slot in the other two topologies. Easy case.
1931  */
1932  ast_trace(-1, "%s: Same stream in all 3 states\n", session_name);
1933  if (dp_state == da_state && da_state == ca_state) {
1934  /* All the same state, no need to update. */
1935  SCOPE_EXIT_EXPR(continue, "%s: All in the same state so nothing to do\n", session_name);
1936  }
1937  if (da_state != ca_state) {
1938  /*
1939  * Something set the CA state between the time this request was queued
1940  * and now. The CA state wins so we don't do anything.
1941  */
1942  SCOPE_EXIT_EXPR(continue, "%s: Ignoring request to change state from %s to %s\n",
1943  session_name, ast_stream_state2str(ca_state), ast_stream_state2str(dp_state));
1944  }
1945  if (dp_state != da_state) {
1946  /* DP needs to update the state */
1947  ast_stream_set_state(np_stream, dp_state);
1948  SCOPE_EXIT_EXPR(continue, "%s: Changed NP stream state from %s to %s\n",
1949  session_name, ast_stream_state2str(ca_state), ast_stream_state2str(dp_state));
1950  }
1951  }
1952 
1953  /*
1954  * We're done with the simple cases. For the rest, we need to identify if the
1955  * DP stream we're trying to take action on is already in the other topologies
1956  * possibly in a different slot. To do that, if the stream in the DA or CA slots
1957  * doesn't match the current DP stream, we need to iterate over the topology
1958  * looking for a stream with the same name.
1959  */
1960 
1961  /*
1962  * Since we already copied all of the CA streams to the NP topology, we'll use it
1963  * instead of CA because we'll be updating the NP as we go.
1964  */
1965  if (!ast_strings_equal(dp_name, np_name)) {
1966  /*
1967  * The NP stream in this slot doesn't have the same name as the DP stream
1968  * so we need to see if it's in another NP slot. We're not going to stop
1969  * when we find a matching stream because we also want to find the first
1970  * removed removed slot, if any, so we can re-use this slot. We'll break
1971  * early if we find both before we reach the end.
1972  */
1973  ast_trace(-1, "%s: Checking if DP is already in NP somewhere\n", session_name);
1974  for (j = 0; j < ast_stream_topology_get_count(new_pending); j++) {
1975  struct ast_stream *possible_existing = ast_stream_topology_get_stream(new_pending, j);
1976  const char *possible_existing_name = GET_STREAM_NAME_SAFE(possible_existing);
1977 
1978  ast_trace(-1, "%s: Checking %s against %s\n", session_name, dp_name, possible_existing_name);
1979  if (found_np_slot == -1 && ast_strings_equal(dp_name, possible_existing_name)) {
1980  ast_trace(-1, "%s: Pending stream %s slot %d is in NP slot %d\n", session_name,
1981  dp_name, i, j);
1982  found_np_slot = j;
1983  found_np_stream = possible_existing;
1984  found_np_state = ast_stream_get_state(possible_existing);
1985  found_np_name = ast_stream_get_name(possible_existing);
1986  }
1987  if (STREAM_REMOVED(possible_existing) && removed_np_slot == -1) {
1988  removed_np_slot = j;
1989  }
1990  if (removed_np_slot >= 0 && found_np_slot >= 0) {
1991  break;
1992  }
1993  }
1994  } else {
1995  /* Makes the subsequent code easier */
1996  found_np_slot = i;
1997  found_np_stream = np_stream;
1998  found_np_state = np_state;
1999  found_np_name = np_name;
2000  }
2001 
2002  if (!ast_strings_equal(dp_name, da_name)) {
2003  /*
2004  * The DA stream in this slot doesn't have the same name as the DP stream
2005  * so we need to see if it's in another DA slot. In real life, the DA stream
2006  * in this slot could have a different name but there shouldn't be a case
2007  * where the DP stream is another slot in the DA topology. Just in case though.
2008  * We don't care about removed slots in the DA topology.
2009  */
2010  ast_trace(-1, "%s: Checking if DP is already in DA somewhere\n", session_name);
2011  for (j = 0; j < ast_stream_topology_get_count(delayed_active); j++) {
2012  struct ast_stream *possible_existing = ast_stream_topology_get_stream(delayed_active, j);
2013  const char *possible_existing_name = GET_STREAM_NAME_SAFE(possible_existing);
2014 
2015  ast_trace(-1, "%s: Checking %s against %s\n", session_name, dp_name, possible_existing_name);
2016  if (ast_strings_equal(dp_name, possible_existing_name)) {
2017  ast_trace(-1, "%s: Pending stream %s slot %d is already in delayed active slot %d\n",
2018  session_name, dp_name, i, j);
2019  found_da_slot = j;
2020  found_da_stream = possible_existing;
2021  found_da_state = ast_stream_get_state(possible_existing);
2022  found_da_name = ast_stream_get_name(possible_existing);
2023  break;
2024  }
2025  }
2026  } else {
2027  /* Makes the subsequent code easier */
2028  found_da_slot = i;
2029  found_da_stream = da_stream;
2030  found_da_state = da_state;
2031  found_da_name = da_name;
2032  }
2033 
2034  ast_trace(-1, "%s: Found NP slot: %d Found removed NP slot: %d Found DA slot: %d\n",
2035  session_name, found_np_slot, removed_np_slot, found_da_slot);
2036 
2037  /*
2038  * Now we know whether the DP stream is new or changing state and we know if the DP
2039  * stream exists in the other topologies and if so, where in those topologies it exists.
2040  */
2041 
2042  if (!found_da_stream) {
2043  /*
2044  * The DP stream isn't in the DA topology which would imply that the intention of the
2045  * request was to add the stream, not change its state. It's possible though that
2046  * the stream was added by another request between the time this request was queued
2047  * and now so we need to check the CA topology as well.
2048  */
2049  ast_trace(-1, "%s: There was no corresponding DA stream so the request was to add a stream\n", session_name);
2050 
2051  if (found_np_stream) {
2052  /*
2053  * We found it in the CA topology. Since the intention was to add it
2054  * and it's already there, there's nothing to do.
2055  */
2056  SCOPE_EXIT_EXPR(continue, "%s: New stream requested but it's already in CA\n", session_name);
2057  } else {
2058  /* OK, it's not in either which would again imply that the intention of the
2059  * request was to add the stream.
2060  */
2061  ast_trace(-1, "%s: There was no corresponding NP stream\n", session_name);
2062  if (STATE_REMOVED(dp_state)) {
2063  /*
2064  * How can DP request to remove a stream that doesn't seem to exist anythere?
2065  * It's not. It's possible that the stream was already removed and the slot
2066  * reused in the CA topology, but it would still have to exist in the DA
2067  * topology. Bail.
2068  */
2070  "%s: Attempting to remove stream %d:%s but it doesn't exist anywhere.\n", session_name, i, dp_name);
2071  } else {
2072  /*
2073  * We're now sure we want to add the the stream. Since we can re-use
2074  * slots in the CA topology that have streams marked as "removed", we
2075  * use the slot we saved in removed_np_slot if it exists.
2076  */
2077  ast_trace(-1, "%s: Checking for open slot\n", session_name);
2078  if (removed_np_slot >= 0) {
2079  struct ast_sip_session_media *old_media = AST_VECTOR_GET(&new_pending_state->sessions, removed_np_slot);
2080  res = ast_stream_topology_set_stream(new_pending, removed_np_slot, ast_stream_clone(dp_stream, NULL));
2081  if (res != 0) {
2082  SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_WARNING, "%s: Couldn't set stream in new topology\n", session_name);
2083  }
2084  /*
2085  * Since we're reusing the removed_np_slot slot for something else, we need
2086  * to free and remove any session media already in it.
2087  * ast_stream_topology_set_stream() took care of freeing the old stream.
2088  */
2089  res = AST_VECTOR_REPLACE(&new_pending_state->sessions, removed_np_slot, NULL);
2090  if (res != 0) {
2091  SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_WARNING, "%s: Couldn't replace media session\n", session_name);
2092  }
2093 
2094  ao2_cleanup(old_media);
2095  SCOPE_EXIT_EXPR(continue, "%s: Replaced removed stream in slot %d\n",
2096  session_name, removed_np_slot);
2097  } else {
2098  int new_slot = ast_stream_topology_append_stream(new_pending, ast_stream_clone(dp_stream, NULL));
2099  if (new_slot < 0) {
2100  SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_WARNING, "%s: Couldn't append stream in new topology\n", session_name);
2101  }
2102 
2103  res = AST_VECTOR_REPLACE(&new_pending_state->sessions, new_slot, NULL);
2104  if (res != 0) {
2105  SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_WARNING, "%s: Couldn't replace media session\n", session_name);
2106  }
2107  SCOPE_EXIT_EXPR(continue, "%s: Appended new stream to slot %d\n",
2108  session_name, new_slot);
2109  }
2110  }
2111  }
2112  } else {
2113  /*
2114  * The DP stream exists in the DA topology so it's a change of some sort.
2115  */
2116  ast_trace(-1, "%s: There was a corresponding DA stream so the request was to change/remove a stream\n", session_name);
2117  if (dp_state == found_da_state) {
2118  /* No change? Let's see if it's in CA */
2119  if (!found_np_stream) {
2120  /*
2121  * The DP and DA state are the same which would imply that the stream
2122  * already exists but it's not in the CA topology. It's possible that
2123  * between the time this request was queued and now the stream was removed
2124  * from the CA topology and the slot used for something else. Nothing
2125  * we can do here.
2126  */
2127  SCOPE_EXIT_EXPR(continue, "%s: Stream doesn't exist in CA so nothing to do\n", session_name);
2128  } else if (dp_state == found_np_state) {
2129  SCOPE_EXIT_EXPR(continue, "%s: States are the same all around so nothing to do\n", session_name);
2130  } else {
2131  SCOPE_EXIT_EXPR(continue, "%s: Something changed the CA state so we're going to leave it as is\n", session_name);
2132  }
2133  } else {
2134  /* We have a state change. */
2135  ast_trace(-1, "%s: Requesting state change to %s\n", session_name, ast_stream_state2str(dp_state));
2136  if (!found_np_stream) {
2137  SCOPE_EXIT_EXPR(continue, "%s: Stream doesn't exist in CA so nothing to do\n", session_name);
2138  } else if (da_state == found_np_state) {
2139  ast_stream_set_state(found_np_stream, dp_state);
2140  SCOPE_EXIT_EXPR(continue, "%s: Changed NP stream state from %s to %s\n",
2141  session_name, ast_stream_state2str(found_np_state), ast_stream_state2str(dp_state));
2142  } else {
2143  SCOPE_EXIT_EXPR(continue, "%s: Something changed the CA state so we're going to leave it as is\n",
2144  session_name);
2145  }
2146  }
2147  }
2148 
2149  SCOPE_EXIT("%s: Done with slot %d\n", session_name, i);
2150  }
2151 
2152  ast_trace(-1, "%s: Resetting default media states\n", session_name);
2153  for (i = 0; i < AST_MEDIA_TYPE_END; i++) {
2154  int j;
2155  new_pending_state->default_session[i] = NULL;
2156  for (j = 0; j < AST_VECTOR_SIZE(&new_pending_state->sessions); j++) {
2157  struct ast_sip_session_media *media = AST_VECTOR_GET(&new_pending_state->sessions, j);
2158  struct ast_stream *stream = ast_stream_topology_get_stream(new_pending_state->topology, j);
2159 
2160  if (media && media->type == i && !STREAM_REMOVED(stream)) {
2161  new_pending_state->default_session[i] = media;
2162  break;
2163  }
2164  }
2165  }
2166 
2167  if (run_post_validation) {
2168  ast_trace(-1, "%s: Running post-validation\n", session_name);
2169  if (!is_media_state_valid(session_name, new_pending_state)) {
2170  SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR, "State not consistent\n");
2171  }
2172  }
2173 
2174  /*
2175  * We need to move the new pending state to another variable and set new_pending_state to NULL
2176  * so RAII_VAR doesn't free it.
2177  */
2178  returned_media_state = new_pending_state;
2179  new_pending_state = NULL;
2180  SCOPE_EXIT_RTN_VALUE(returned_media_state, "%s: NP: %s\n", session_name,
2181  ast_str_tmp(256, ast_stream_topology_to_str(new_pending, &STR_TMP)));
2182 }
2183 
2184 static int sip_session_refresh(struct ast_sip_session *session,
2185  ast_sip_session_request_creation_cb on_request_creation,
2186  ast_sip_session_sdp_creation_cb on_sdp_creation,
2187  ast_sip_session_response_cb on_response,
2188  enum ast_sip_session_refresh_method method, int generate_new_sdp,
2189  struct ast_sip_session_media_state *pending_media_state,
2190  struct ast_sip_session_media_state *active_media_state,
2191  int queued)
2192 {
2193  pjsip_inv_session *inv_session = session->inv_session;
2194  pjmedia_sdp_session *new_sdp = NULL;
2195  pjsip_tx_data *tdata;
2196  int res = -1;
2197  SCOPE_ENTER(3, "%s: New SDP? %s Queued? %s DP: %s DA: %s\n", ast_sip_session_get_name(session),
2198  generate_new_sdp ? "yes" : "no", queued ? "yes" : "no",
2199  pending_media_state ? ast_str_tmp(256, ast_stream_topology_to_str(pending_media_state->topology, &STR_TMP)) : "none",
2200  active_media_state ? ast_str_tmp(256, ast_stream_topology_to_str(active_media_state->topology, &STR_TMP)) : "none");
2201 
2202  if (pending_media_state && (!pending_media_state->topology || !generate_new_sdp)) {
2203 
2204  ast_sip_session_media_state_free(pending_media_state);
2205  ast_sip_session_media_state_free(active_media_state);
2206  SCOPE_EXIT_RTN_VALUE(-1, "%s: Not sending reinvite because %s%s\n", ast_sip_session_get_name(session),
2207  pending_media_state->topology == NULL ? "pending topology is null " : "",
2208  !generate_new_sdp ? "generate_new_sdp is false" : "");
2209  }
2210 
2211  if (inv_session->state == PJSIP_INV_STATE_DISCONNECTED) {
2212  /* Don't try to do anything with a hung-up call */
2213  ast_sip_session_media_state_free(pending_media_state);
2214  ast_sip_session_media_state_free(active_media_state);
2215  SCOPE_EXIT_RTN_VALUE(0, "%s: Not sending reinvite because of disconnected state\n",
2216  ast_sip_session_get_name(session));
2217  }
2218 
2219  /* If the dialog has not yet been established we have to defer until it has */
2220  if (inv_session->dlg->state != PJSIP_DIALOG_STATE_ESTABLISHED) {
2221  res = delay_request(session, on_request_creation, on_sdp_creation, on_response,
2222  generate_new_sdp,
2225  pending_media_state, active_media_state ? active_media_state : ast_sip_session_media_state_clone(session->active_media_state), queued);
2226  SCOPE_EXIT_RTN_VALUE(res, "%s: Delay sending reinvite because dialog has not been established\n",
2227  ast_sip_session_get_name(session));
2228  }
2229 
2230  if (method == AST_SIP_SESSION_REFRESH_METHOD_INVITE) {
2231  if (inv_session->invite_tsx) {
2232  /* We can't send a reinvite yet, so delay it */
2233  res = delay_request(session, on_request_creation, on_sdp_creation,
2234  on_response, generate_new_sdp, DELAYED_METHOD_INVITE, pending_media_state,
2235  active_media_state ? active_media_state : ast_sip_session_media_state_clone(session->active_media_state), queued);
2236  SCOPE_EXIT_RTN_VALUE(res, "%s: Delay sending reinvite because of outstanding transaction\n",
2237  ast_sip_session_get_name(session));
2238  } else if (inv_session->state != PJSIP_INV_STATE_CONFIRMED) {
2239  /* Initial INVITE transaction failed to progress us to a confirmed state
2240  * which means re-invites are not possible
2241  */
2242  ast_sip_session_media_state_free(pending_media_state);
2243  ast_sip_session_media_state_free(active_media_state);
2244  SCOPE_EXIT_RTN_VALUE(0, "%s: Not sending reinvite because not in confirmed state\n",
2245  ast_sip_session_get_name(session));
2246  }
2247  }
2248 
2249  if (generate_new_sdp) {
2250  /* SDP can only be generated if current negotiation has already completed */
2251  if (inv_session->neg
2252  && pjmedia_sdp_neg_get_state(inv_session->neg)
2253  != PJMEDIA_SDP_NEG_STATE_DONE) {
2254  res = delay_request(session, on_request_creation, on_sdp_creation,
2255  on_response, generate_new_sdp,
2257  ? DELAYED_METHOD_INVITE : DELAYED_METHOD_UPDATE, pending_media_state,
2258  active_media_state ? active_media_state : ast_sip_session_media_state_clone(session->active_media_state), queued);
2259  SCOPE_EXIT_RTN_VALUE(res, "%s: Delay session refresh with new SDP because SDP negotiation is not yet done\n",
2260  ast_sip_session_get_name(session));
2261  }
2262 
2263  /* If an explicitly requested media state has been provided use it instead of any pending one */
2264  if (pending_media_state) {
2265  int index;
2266  int type_streams[AST_MEDIA_TYPE_END] = {0};
2267 
2268  ast_trace(-1, "%s: Pending media state exists\n", ast_sip_session_get_name(session));
2269 
2270  /* Media state conveys a desired media state, so if there are outstanding
2271  * delayed requests we need to ensure we go into the queue and not jump
2272  * ahead. If we sent this media state now then updates could go out of
2273  * order.
2274  */
2275  if (!queued && !AST_LIST_EMPTY(&session->delayed_requests)) {
2276  res = delay_request(session, on_request_creation, on_sdp_creation,
2277  on_response, generate_new_sdp,
2279  ? DELAYED_METHOD_INVITE : DELAYED_METHOD_UPDATE, pending_media_state,
2280  active_media_state ? active_media_state : ast_sip_session_media_state_clone(session->active_media_state), queued);
2281  SCOPE_EXIT_RTN_VALUE(res, "%s: Delay sending reinvite because of outstanding requests\n",
2282  ast_sip_session_get_name(session));
2283  }
2284 
2285  /*
2286  * Attempt to resolve only if objects are available, and it's not
2287  * switching to or from an image type.
2288  */
2289  if (active_media_state && active_media_state->topology &&
2290  (!active_media_state->default_session[AST_MEDIA_TYPE_IMAGE] ==
2291  !pending_media_state->default_session[AST_MEDIA_TYPE_IMAGE])) {
2292 
2293  struct ast_sip_session_media_state *new_pending_state;
2294 
2295  ast_trace(-1, "%s: Active media state exists and is%s equal to pending\n", ast_sip_session_get_name(session),
2296  !ast_stream_topology_equal(active_media_state->topology,pending_media_state->topology) ? " not" : "");
2297  ast_trace(-1, "%s: DP: %s\n", ast_sip_session_get_name(session), ast_str_tmp(256, ast_stream_topology_to_str(pending_media_state->topology, &STR_TMP)));
2298  ast_trace(-1, "%s: DA: %s\n", ast_sip_session_get_name(session), ast_str_tmp(256, ast_stream_topology_to_str(active_media_state->topology, &STR_TMP)));
2299  ast_trace(-1, "%s: CP: %s\n", ast_sip_session_get_name(session), ast_str_tmp(256, ast_stream_topology_to_str(session->pending_media_state->topology, &STR_TMP)));
2300  ast_trace(-1, "%s: CA: %s\n", ast_sip_session_get_name(session), ast_str_tmp(256, ast_stream_topology_to_str(session->active_media_state->topology, &STR_TMP)));
2301 
2302  new_pending_state = resolve_refresh_media_states(ast_sip_session_get_name(session),
2303  pending_media_state, active_media_state, session->active_media_state, 1);
2304  if (new_pending_state) {
2305  ast_trace(-1, "%s: NP: %s\n", ast_sip_session_get_name(session), ast_str_tmp(256, ast_stream_topology_to_str(new_pending_state->topology, &STR_TMP)));
2306  ast_sip_session_media_state_free(pending_media_state);
2307  pending_media_state = new_pending_state;
2308  } else {
2309  ast_sip_session_media_state_reset(pending_media_state);
2310  ast_sip_session_media_state_free(active_media_state);
2311  SCOPE_EXIT_LOG_RTN_VALUE(-1, LOG_WARNING, "%s: Unable to merge media states\n", ast_sip_session_get_name(session));
2312  }
2313  }
2314 
2315  /* Prune the media state so the number of streams fit within the configured limits - we do it here
2316  * so that the index of the resulting streams in the SDP match. If we simply left the streams out
2317  * of the SDP when producing it we'd be in trouble. We also enforce formats here for media types that
2318  * are configurable on the endpoint.
2319  */
2320  ast_trace(-1, "%s: Pruning and checking formats of streams\n", ast_sip_session_get_name(session));
2321 
2322  for (index = 0; index < ast_stream_topology_get_count(pending_media_state->topology); ++index) {
2323  struct ast_stream *existing_stream = NULL;
2324  struct ast_stream *stream = ast_stream_topology_get_stream(pending_media_state->topology, index);
2325  SCOPE_ENTER(4, "%s: Checking stream %s\n", ast_sip_session_get_name(session),
2326  ast_stream_get_name(stream));
2327 
2328  if (session->active_media_state->topology &&
2329  index < ast_stream_topology_get_count(session->active_media_state->topology)) {
2330  existing_stream = ast_stream_topology_get_stream(session->active_media_state->topology, index);
2331  ast_trace(-1, "%s: Found existing stream %s\n", ast_sip_session_get_name(session),
2332  ast_stream_get_name(existing_stream));
2333  }
2334 
2335  if (is_stream_limitation_reached(ast_stream_get_type(stream), session->endpoint, type_streams)) {
2336  if (index < AST_VECTOR_SIZE(&pending_media_state->sessions)) {
2337  struct ast_sip_session_media *session_media = AST_VECTOR_GET(&pending_media_state->sessions, index);
2338 
2339  ao2_cleanup(session_media);
2340  AST_VECTOR_REMOVE(&pending_media_state->sessions, index, 1);
2341  }
2342 
2343  ast_stream_topology_del_stream(pending_media_state->topology, index);
2344  ast_trace(-1, "%s: Dropped overlimit stream %s\n", ast_sip_session_get_name(session),
2345  ast_stream_get_name(stream));
2346 
2347  /* A stream has potentially moved into our spot so we need to jump back so we process it */
2348  index -= 1;
2349  SCOPE_EXIT_EXPR(continue);
2350  }
2351 
2352  /* No need to do anything with stream if it's media state is removed */
2354  /* If there is no existing stream we can just not have this stream in the topology at all. */
2355  if (!existing_stream) {
2356  ast_trace(-1, "%s: Dropped removed stream %s\n", ast_sip_session_get_name(session),
2357  ast_stream_get_name(stream));
2358  ast_stream_topology_del_stream(pending_media_state->topology, index);
2359  /* TODO: Do we need to remove the corresponding media state? */
2360  index -= 1;
2361  }
2362  SCOPE_EXIT_EXPR(continue);
2363  }
2364 
2365  /* Enforce the configured allowed codecs on audio and video streams */
2367  !ast_stream_get_metadata(stream, "pjsip_session_refresh")) {
2368  struct ast_format_cap *joint_cap;
2369 
2371  if (!joint_cap) {
2372  ast_sip_session_media_state_free(pending_media_state);
2373  ast_sip_session_media_state_free(active_media_state);
2374  res = -1;
2375  SCOPE_EXIT_LOG_EXPR(goto end, LOG_ERROR, "%s: Unable to alloc format caps\n", ast_sip_session_get_name(session));
2376  }
2378  if (!ast_format_cap_count(joint_cap)) {
2379  ao2_ref(joint_cap, -1);
2380 
2381  if (!existing_stream) {
2382  /* If there is no existing stream we can just not have this stream in the topology
2383  * at all.
2384  */
2385  ast_stream_topology_del_stream(pending_media_state->topology, index);
2386  index -= 1;
2387  SCOPE_EXIT_EXPR(continue, "%s: Dropped incompatible stream %s\n",
2388  ast_sip_session_get_name(session), ast_stream_get_name(stream));
2389  } else if (ast_stream_get_state(stream) != ast_stream_get_state(existing_stream) ||
2390  strcmp(ast_stream_get_name(stream), ast_stream_get_name(existing_stream))) {
2391  /* If the underlying stream is a different type or different name then we have to
2392  * mark it as removed, as it is replacing an existing stream. We do this so order
2393  * is preserved.
2394  */
2396  SCOPE_EXIT_EXPR(continue, "%s: Dropped incompatible stream %s\n",
2397  ast_sip_session_get_name(session), ast_stream_get_name(stream));
2398  } else {
2399  /* However if the stream is otherwise remaining the same we can keep the formats
2400  * that exist on it already which allows media to continue to flow. We don't modify
2401  * the format capabilities but do need to cast it so that ao2_bump can raise the
2402  * reference count.
2403  */
2404  joint_cap = ao2_bump((struct ast_format_cap *)ast_stream_get_formats(existing_stream));
2405  }
2406  }
2407  ast_stream_set_formats(stream, joint_cap);
2408  ao2_cleanup(joint_cap);
2409  }
2410 
2411  ++type_streams[ast_stream_get_type(stream)];
2412 
2413  SCOPE_EXIT();
2414  }
2415 
2416  if (session->active_media_state->topology) {
2417  /* SDP is a fun thing. Take for example the fact that streams are never removed. They just become
2418  * declined. To better handle this in the case where something requests a topology change for fewer
2419  * streams than are currently present we fill in the topology to match the current number of streams
2420  * that are active.
2421  */
2422 
2423  for (index = ast_stream_topology_get_count(pending_media_state->topology);
2424  index < ast_stream_topology_get_count(session->active_media_state->topology); ++index) {
2425  struct ast_stream *stream = ast_stream_topology_get_stream(session->active_media_state->topology, index);
2426  struct ast_stream *cloned;
2427  int position;
2428  SCOPE_ENTER(4, "%s: Stream %s not in pending\n", ast_sip_session_get_name(session),
2429  ast_stream_get_name(stream));
2430 
2431  cloned = ast_stream_clone(stream, NULL);
2432  if (!cloned) {
2433  ast_sip_session_media_state_free(pending_media_state);
2434  ast_sip_session_media_state_free(active_media_state);
2435  res = -1;
2436  SCOPE_EXIT_LOG_EXPR(goto end, LOG_ERROR, "%s: Unable to clone stream %s\n",
2437  ast_sip_session_get_name(session), ast_stream_get_name(stream));
2438  }
2439 
2441  position = ast_stream_topology_append_stream(pending_media_state->topology, cloned);
2442  if (position < 0) {
2443  ast_stream_free(cloned);
2444  ast_sip_session_media_state_free(pending_media_state);
2445  ast_sip_session_media_state_free(active_media_state);
2446  res = -1;
2447  SCOPE_EXIT_LOG_EXPR(goto end, LOG_ERROR, "%s: Unable to append cloned stream\n",
2448  ast_sip_session_get_name(session));
2449  }
2450  SCOPE_EXIT("%s: Appended empty stream in position %d to make counts match\n",
2451  ast_sip_session_get_name(session), position);
2452  }
2453 
2454  /*
2455  * We can suppress this re-invite if the pending topology is equal to the currently
2456  * active topology.
2457  */
2458  if (ast_stream_topology_equal(session->active_media_state->topology, pending_media_state->topology)) {
2459  ast_trace(-1, "%s: CA: %s\n", ast_sip_session_get_name(session), ast_str_tmp(256, ast_stream_topology_to_str(session->active_media_state->topology, &STR_TMP)));
2460  ast_trace(-1, "%s: NP: %s\n", ast_sip_session_get_name(session), ast_str_tmp(256, ast_stream_topology_to_str(pending_media_state->topology, &STR_TMP)));
2461  ast_sip_session_media_state_free(pending_media_state);
2462  ast_sip_session_media_state_free(active_media_state);
2463  /* For external consumers we return 0 to say success, but internally for
2464  * send_delayed_request we return a separate value to indicate that this
2465  * session refresh would be redundant so we didn't send it
2466  */
2467  SCOPE_EXIT_RTN_VALUE(queued ? 1 : 0, "%s: Topologies are equal. Not sending re-invite\n",
2468  ast_sip_session_get_name(session));
2469  }
2470  }
2471 
2473  session->pending_media_state = pending_media_state;
2474  }
2475 
2476  new_sdp = generate_session_refresh_sdp(session);
2477  if (!new_sdp) {
2479  ast_sip_session_media_state_free(active_media_state);
2480  SCOPE_EXIT_LOG_RTN_VALUE(-1, LOG_WARNING, "%s: Failed to generate session refresh SDP. Not sending session refresh\n",
2481  ast_sip_session_get_name(session));
2482  }
2483  if (on_sdp_creation) {
2484  if (on_sdp_creation(session, new_sdp)) {
2486  ast_sip_session_media_state_free(active_media_state);
2487  SCOPE_EXIT_LOG_RTN_VALUE(-1, LOG_WARNING, "%s: on_sdp_creation failed\n", ast_sip_session_get_name(session));
2488  }
2489  }
2490  }
2491 
2492  if (method == AST_SIP_SESSION_REFRESH_METHOD_INVITE) {
2493  if (pjsip_inv_reinvite(inv_session, NULL, new_sdp, &tdata)) {
2494  if (generate_new_sdp) {
2496  }
2497  ast_sip_session_media_state_free(active_media_state);
2498  SCOPE_EXIT_LOG_RTN_VALUE(-1, LOG_WARNING, "%s: Failed to create reinvite properly\n", ast_sip_session_get_name(session));
2499  }
2500  } else if (pjsip_inv_update(inv_session, NULL, new_sdp, &tdata)) {
2501  if (generate_new_sdp) {
2503  }
2504  ast_sip_session_media_state_free(active_media_state);
2505  SCOPE_EXIT_LOG_RTN_VALUE(-1, LOG_WARNING, "%s: Failed to create UPDATE properly\n", ast_sip_session_get_name(session));
2506  }
2507  if (on_request_creation) {
2508  if (on_request_creation(session, tdata)) {
2509  if (generate_new_sdp) {
2511  }
2512  ast_sip_session_media_state_free(active_media_state);
2513  SCOPE_EXIT_LOG_RTN_VALUE(-1, LOG_WARNING, "%s: on_request_creation failed.\n", ast_sip_session_get_name(session));
2514  }
2515  }
2516  ast_sip_session_send_request_with_cb(session, tdata, on_response);
2517  ast_sip_session_media_state_free(active_media_state);
2518 
2519 end:
2520  SCOPE_EXIT_RTN_VALUE(res, "%s: Sending session refresh SDP via %s\n", ast_sip_session_get_name(session),
2521  method == AST_SIP_SESSION_REFRESH_METHOD_INVITE ? "re-INVITE" : "UPDATE");
2522 }
2523 
2525  ast_sip_session_request_creation_cb on_request_creation,
2526  ast_sip_session_sdp_creation_cb on_sdp_creation,
2527  ast_sip_session_response_cb on_response,
2528  enum ast_sip_session_refresh_method method, int generate_new_sdp,
2529  struct ast_sip_session_media_state *media_state)
2530 {
2531  return sip_session_refresh(session, on_request_creation, on_sdp_creation,
2532  on_response, method, generate_new_sdp, media_state, NULL, 0);
2533 }
2534 
2536  ast_sip_session_sdp_creation_cb on_sdp_creation)
2537 {
2538  pjsip_inv_session *inv_session = session->inv_session;
2539  pjmedia_sdp_session *new_answer = NULL;
2540  const pjmedia_sdp_session *previous_offer = NULL;
2541  SCOPE_ENTER(1, "%s\n", ast_sip_session_get_name(session));
2542 
2543  /* The SDP answer can only be regenerated if it is still pending to be sent */
2544  if (!inv_session->neg || (pjmedia_sdp_neg_get_state(inv_session->neg) != PJMEDIA_SDP_NEG_STATE_REMOTE_OFFER &&
2545  pjmedia_sdp_neg_get_state(inv_session->neg) != PJMEDIA_SDP_NEG_STATE_WAIT_NEGO)) {
2546  ast_log(LOG_WARNING, "Requested to regenerate local SDP answer for channel '%s' but negotiation in state '%s'\n",
2547  ast_channel_name(session->channel), pjmedia_sdp_neg_state_str(pjmedia_sdp_neg_get_state(inv_session->neg)));
2548  SCOPE_EXIT_RTN_VALUE(-1, "Bad negotiation state\n");
2549  }
2550 
2551  pjmedia_sdp_neg_get_neg_remote(inv_session->neg, &previous_offer);
2552  if (pjmedia_sdp_neg_get_state(inv_session->neg) == PJMEDIA_SDP_NEG_STATE_WAIT_NEGO) {
2553  /* Transition the SDP negotiator back to when it received the remote offer */
2554  pjmedia_sdp_neg_negotiate(inv_session->pool, inv_session->neg, 0);
2555  pjmedia_sdp_neg_set_remote_offer(inv_session->pool, inv_session->neg, previous_offer);
2556  }
2557 
2558  new_answer = create_local_sdp(inv_session, session, previous_offer);
2559  if (!new_answer) {
2560  ast_log(LOG_WARNING, "Could not create a new local SDP answer for channel '%s'\n",
2561  ast_channel_name(session->channel));
2562  SCOPE_EXIT_RTN_VALUE(-1, "Couldn't create new SDP\n");
2563  }
2564 
2565  if (on_sdp_creation) {
2566  if (on_sdp_creation(session, new_answer)) {
2567  SCOPE_EXIT_RTN_VALUE(-1, "Callback failed\n");
2568  }
2569  }
2570 
2571  pjsip_inv_set_sdp_answer(inv_session, new_answer);
2572 
2574 }
2575 
2576 void ast_sip_session_send_response(struct ast_sip_session *session, pjsip_tx_data *tdata)
2577 {
2578  handle_outgoing_response(session, tdata);
2579  pjsip_inv_send_msg(session->inv_session, tdata);
2580  return;
2581 }
2582 
2583 static pj_bool_t session_on_rx_request(pjsip_rx_data *rdata);
2584 static pj_bool_t session_on_rx_response(pjsip_rx_data *rdata);
2585 static void session_on_tsx_state(pjsip_transaction *tsx, pjsip_event *e);
2586 
2587 static pjsip_module session_module = {
2588  .name = {"Session Module", 14},
2589  .priority = PJSIP_MOD_PRIORITY_APPLICATION,
2590  .on_rx_request = session_on_rx_request,
2591  .on_rx_response = session_on_rx_response,
2592  .on_tsx_state = session_on_tsx_state,
2593 };
2594 
2595 /*! \brief Determine whether the SDP provided requires deferral of negotiating or not
2596  *
2597  * \retval 1 re-invite should be deferred and resumed later
2598  * \retval 0 re-invite should not be deferred
2599  */
2600 static int sdp_requires_deferral(struct ast_sip_session *session, const pjmedia_sdp_session *sdp)
2601 {
2602  int i;
2603 
2604  if (!session->pending_media_state->topology) {
2606  if (!session->pending_media_state->topology) {
2607  return -1;
2608  }
2609  }
2610 
2611  for (i = 0; i < sdp->media_count; ++i) {
2612  /* See if there are registered handlers for this media stream type */
2613  char media[20];
2615  RAII_VAR(struct sdp_handler_list *, handler_list, NULL, ao2_cleanup);
2616  struct ast_stream *existing_stream = NULL;
2617  struct ast_stream *stream;
2618  enum ast_media_type type;
2619  struct ast_sip_session_media *session_media = NULL;
2621  pjmedia_sdp_media *remote_stream = sdp->media[i];
2622 
2623  /* We need a null-terminated version of the media string */
2624  ast_copy_pj_str(media, &sdp->media[i]->desc.media, sizeof(media));
2625 
2626  if (session->active_media_state->topology &&
2628  existing_stream = ast_stream_topology_get_stream(session->active_media_state->topology, i);
2629  }
2630 
2631  type = ast_media_type_from_str(media);
2632  stream = ast_stream_alloc(existing_stream ? ast_stream_get_name(existing_stream) : ast_codec_media_type2str(type), type);
2633  if (!stream) {
2634  return -1;
2635  }
2636 
2637  /* As this is only called on an incoming SDP offer before processing it is not possible
2638  * for streams and their media sessions to exist.
2639  */
2640  if (ast_stream_topology_set_stream(session->pending_media_state->topology, i, stream)) {
2641  ast_stream_free(stream);
2642  return -1;
2643  }
2644 
2645  if (existing_stream) {
2646  const char *stream_label = ast_stream_get_metadata(existing_stream, "SDP:LABEL");
2647 
2648  if (!ast_strlen_zero(stream_label)) {
2649  ast_stream_set_metadata(stream, "SDP:LABEL", stream_label);
2650  }
2651  }
2652 
2653  session_media = ast_sip_session_media_state_add(session, session->pending_media_state, ast_media_type_from_str(media), i);
2654  if (!session_media) {
2655  return -1;
2656  }
2657 
2658  /* For backwards compatibility with the core the default audio stream is always sendrecv */
2659  if (!ast_sip_session_is_pending_stream_default(session, stream) || strcmp(media, "audio")) {
2660  if (pjmedia_sdp_media_find_attr2(remote_stream, "sendonly", NULL)) {
2661  /* Stream state reflects our state of a stream, so in the case of
2662  * sendonly and recvonly we store the opposite since that is what ours
2663  * is.
2664  */
2666  } else if (pjmedia_sdp_media_find_attr2(remote_stream, "recvonly", NULL)) {
2668  } else if (pjmedia_sdp_media_find_attr2(remote_stream, "inactive", NULL)) {
2670  } else {
2672  }
2673  } else {
2675  }
2676 
2677  if (session_media->handler) {
2678  handler = session_media->handler;
2679  if (handler->defer_incoming_sdp_stream) {
2680  res = handler->defer_incoming_sdp_stream(session, session_media, sdp,
2681  sdp->media[i]);
2682  switch (res) {
2684  break;
2686  return 0;
2688  break;
2690  return 1;
2691  }
2692  }
2693  /* Handled by this handler. Move to the next stream */
2694  continue;
2695  }
2696 
2697  handler_list = ao2_find(sdp_handlers, media, OBJ_KEY);
2698  if (!handler_list) {
2699  ast_debug(3, "%s: No registered SDP handlers for media type '%s'\n", ast_sip_session_get_name(session), media);
2700  continue;
2701  }
2702  AST_LIST_TRAVERSE(&handler_list->list, handler, next) {
2703  if (handler == session_media->handler) {
2704  continue;
2705  }
2706  if (!handler->defer_incoming_sdp_stream) {
2707  continue;
2708  }
2709  res = handler->defer_incoming_sdp_stream(session, session_media, sdp,
2710  sdp->media[i]);
2711  switch (res) {
2713  continue;
2715  session_media_set_handler(session_media, handler);
2716  return 0;
2718  /* Handled by this handler. */
2719  session_media_set_handler(session_media, handler);
2720  break;
2722  /* Handled by this handler. */
2723  session_media_set_handler(session_media, handler);
2724  return 1;
2725  }
2726  /* Move to the next stream */
2727  break;
2728  }
2729  }
2730  return 0;
2731 }
2732 
2733 static pj_bool_t session_reinvite_on_rx_request(pjsip_rx_data *rdata)
2734 {
2735  pjsip_dialog *dlg;
2736  RAII_VAR(struct ast_sip_session *, session, NULL, ao2_cleanup);
2737  pjsip_rdata_sdp_info *sdp_info;
2738  int deferred;
2739 
2740  if (rdata->msg_info.msg->line.req.method.id != PJSIP_INVITE_METHOD ||
2741  !(dlg = pjsip_ua_find_dialog(&rdata->msg_info.cid->id, &rdata->msg_info.to->tag, &rdata->msg_info.from->tag, PJ_FALSE)) ||
2742  !(session = ast_sip_dialog_get_session(dlg)) ||
2743  !session->channel) {
2744  return PJ_FALSE;
2745  }
2746 
2747  if (session->inv_session->invite_tsx) {
2748  /* There's a transaction in progress so bail now and let pjproject send 491 */
2749  return PJ_FALSE;
2750  }
2751 
2752  if (session->deferred_reinvite) {
2753  pj_str_t key, deferred_key;
2754  pjsip_tx_data *tdata;
2755 
2756  /* We use memory from the new request on purpose so the deferred reinvite pool does not grow uncontrollably */
2757  pjsip_tsx_create_key(rdata->tp_info.pool, &key, PJSIP_ROLE_UAS, &rdata->msg_info.cseq->method, rdata);
2758  pjsip_tsx_create_key(rdata->tp_info.pool, &deferred_key, PJSIP_ROLE_UAS, &session->deferred_reinvite->msg_info.cseq->method,
2759  session->deferred_reinvite);
2760 
2761  /* If this is a retransmission ignore it */
2762  if (!pj_strcmp(&key, &deferred_key)) {
2763  return PJ_TRUE;
2764  }
2765 
2766  /* Otherwise this is a new re-invite, so reject it */
2767  if (pjsip_dlg_create_response(dlg, rdata, 491, NULL, &tdata) == PJ_SUCCESS) {
2768  if (pjsip_endpt_send_response2(ast_sip_get_pjsip_endpoint(), rdata, tdata, NULL, NULL) != PJ_SUCCESS) {
2769  pjsip_tx_data_dec_ref(tdata);
2770  }
2771  }
2772 
2773  return PJ_TRUE;
2774  }
2775 
2776  if (!(sdp_info = pjsip_rdata_get_sdp_info(rdata)) ||
2777  (sdp_info->sdp_err != PJ_SUCCESS)) {
2778  return PJ_FALSE;
2779  }
2780 
2781  if (!sdp_info->sdp) {
2782  return PJ_FALSE;
2783  }
2784 
2785  deferred = sdp_requires_deferral(session, sdp_info->sdp);
2786  if (deferred == -1) {
2788  return PJ_FALSE;
2789  } else if (!deferred) {
2790  return PJ_FALSE;
2791  }
2792 
2793  pjsip_rx_data_clone(rdata, 0, &session->deferred_reinvite);
2794 
2795  return PJ_TRUE;
2796 }
2797 
2799 {
2800  if (!session->deferred_reinvite) {
2801  return;
2802  }
2803 
2804  if (session->channel) {
2805  pjsip_endpt_process_rx_data(ast_sip_get_pjsip_endpoint(),
2806  session->deferred_reinvite, NULL, NULL);
2807  }
2808  pjsip_rx_data_free_cloned(session->deferred_reinvite);
2809  session->deferred_reinvite = NULL;
2810 }
2811 
2812 static pjsip_module session_reinvite_module = {
2813  .name = { "Session Re-Invite Module", 24 },
2814  .priority = PJSIP_MOD_PRIORITY_UA_PROXY_LAYER - 1,
2815  .on_rx_request = session_reinvite_on_rx_request,
2816 };
2817 
2818 void ast_sip_session_send_request_with_cb(struct ast_sip_session *session, pjsip_tx_data *tdata,
2819  ast_sip_session_response_cb on_response)
2820 {
2821  pjsip_inv_session *inv_session = session->inv_session;
2822 
2823  /* For every request except BYE we disallow sending of the message when
2824  * the session has been disconnected. A BYE request is special though
2825  * because it can be sent again after the session is disconnected except
2826  * with credentials.
2827  */
2828  if (inv_session->state == PJSIP_INV_STATE_DISCONNECTED &&
2829  tdata->msg->line.req.method.id != PJSIP_BYE_METHOD) {
2830  return;
2831  }
2832 
2833  ast_sip_mod_data_set(tdata->pool, tdata->mod_data, session_module.id,
2834  MOD_DATA_ON_RESPONSE, on_response);
2835 
2836  handle_outgoing_request(session, tdata);
2837  pjsip_inv_send_msg(session->inv_session, tdata);
2838 
2839  return;
2840 }
2841 
2842 void ast_sip_session_send_request(struct ast_sip_session *session, pjsip_tx_data *tdata)
2843 {
2844  ast_sip_session_send_request_with_cb(session, tdata, NULL);
2845 }
2846 
2847 int ast_sip_session_create_invite(struct ast_sip_session *session, pjsip_tx_data **tdata)
2848 {
2849  pjmedia_sdp_session *offer;
2850  SCOPE_ENTER(1, "%s\n", ast_sip_session_get_name(session));
2851 
2852  if (!(offer = create_local_sdp(session->inv_session, session, NULL))) {
2853  pjsip_inv_terminate(session->inv_session, 500, PJ_FALSE);
2854  SCOPE_EXIT_RTN_VALUE(-1, "Couldn't create offer\n");
2855  }
2856 
2857  pjsip_inv_set_local_sdp(session->inv_session, offer);
2858  pjmedia_sdp_neg_set_prefer_remote_codec_order(session->inv_session->neg, PJ_FALSE);
2859 #ifdef PJMEDIA_SDP_NEG_ANSWER_MULTIPLE_CODECS
2860  if (!session->endpoint->preferred_codec_only) {
2861  pjmedia_sdp_neg_set_answer_multiple_codecs(session->inv_session->neg, PJ_TRUE);
2862  }
2863 #endif
2864 
2865  /*
2866  * We MUST call set_from_header() before pjsip_inv_invite. If we don't, the
2867  * From in the initial INVITE will be wrong but the rest of the messages will be OK.
2868  */
2869  set_from_header(session);
2870 
2871  if (pjsip_inv_invite(session->inv_session, tdata) != PJ_SUCCESS) {
2872  SCOPE_EXIT_RTN_VALUE(-1, "pjsip_inv_invite failed\n");
2873  }
2874 
2876 }
2877 
2878 static int datastore_hash(const void *obj, int flags)
2879 {
2880  const struct ast_datastore *datastore = obj;
2881  const char *uid = flags & OBJ_KEY ? obj : datastore->uid;
2882 
2883  ast_assert(uid != NULL);
2884 
2885  return ast_str_hash(uid);
2886 }
2887 
2888 static int datastore_cmp(void *obj, void *arg, int flags)
2889 {
2890  const struct ast_datastore *datastore1 = obj;
2891  const struct ast_datastore *datastore2 = arg;
2892  const char *uid2 = flags & OBJ_KEY ? arg : datastore2->uid;
2893 
2894  ast_assert(datastore1->uid != NULL);
2895  ast_assert(uid2 != NULL);
2896 
2897  return strcmp(datastore1->uid, uid2) ? 0 : CMP_MATCH | CMP_STOP;
2898 }
2899 
2900 static void session_destructor(void *obj)
2901 {
2902  struct ast_sip_session *session = obj;
2903  struct ast_sip_session_delayed_request *delay;
2904 
2905 #ifdef TEST_FRAMEWORK
2906  /* We dup the endpoint ID in case the endpoint gets freed out from under us */
2907  const char *endpoint_name = session->endpoint ?
2908  ast_strdupa(ast_sorcery_object_get_id(session->endpoint)) : "<none>";
2909 #endif
2910 
2911  ast_debug(3, "%s: Destroying SIP session\n", ast_sip_session_get_name(session));
2912 
2913  ast_test_suite_event_notify("SESSION_DESTROYING",
2914  "Endpoint: %s\r\n"
2915  "AOR: %s\r\n"
2916  "Contact: %s"
2917  , endpoint_name
2918  , session->aor ? ast_sorcery_object_get_id(session->aor) : "<none>"
2919  , session->contact ? ast_sorcery_object_get_id(session->contact) : "<none>"
2920  );
2921 
2922  /* fire session destroy handler */
2923  handle_session_destroy(session);
2924 
2925  /* remove all registered supplements */
2928 
2929  /* remove all saved media stats */
2930  AST_VECTOR_RESET(&session->media_stats, ast_free);
2931  AST_VECTOR_FREE(&session->media_stats);
2932 
2934  ao2_cleanup(session->datastores);
2937 
2938  while ((delay = AST_LIST_REMOVE_HEAD(&session->delayed_requests, next))) {
2939  delayed_request_free(delay);
2940  }
2941  ast_party_id_free(&session->id);
2942  ao2_cleanup(session->endpoint);
2943  ao2_cleanup(session->aor);
2944  ao2_cleanup(session->contact);
2945  ao2_cleanup(session->direct_media_cap);
2946 
2947  ast_dsp_free(session->dsp);
2948 
2949  if (session->inv_session) {
2950  struct pjsip_dialog *dlg = session->inv_session->dlg;
2951 
2952  /* The INVITE session uses the dialog pool for memory, so we need to
2953  * decrement its reference first before that of the dialog.
2954  */
2955 
2956 #ifdef HAVE_PJSIP_INV_SESSION_REF
2957  pjsip_inv_dec_ref(session->inv_session);
2958 #endif
2959  pjsip_dlg_dec_session(dlg, &session_module);
2960  }
2961 
2962  ast_test_suite_event_notify("SESSION_DESTROYED", "Endpoint: %s", endpoint_name);
2963 }
2964 
2965 /*! \brief Destructor for SIP channel */
2966 static void sip_channel_destroy(void *obj)
2967 {
2968  struct ast_sip_channel_pvt *channel = obj;
2969 
2970  ao2_cleanup(channel->pvt);
2971  ao2_cleanup(channel->session);
2972 }
2973 
2975 {
2976  struct ast_sip_channel_pvt *channel = ao2_alloc(sizeof(*channel), sip_channel_destroy);
2977 
2978  if (!channel) {
2979  return NULL;
2980  }
2981 
2982  ao2_ref(pvt, +1);
2983  channel->pvt = pvt;
2984  ao2_ref(session, +1);
2985  channel->session = session;
2986 
2987  return channel;
2988 }
2989 
2991  struct ast_sip_contact *contact, pjsip_inv_session *inv_session, pjsip_rx_data *rdata)
2992 {
2993  RAII_VAR(struct ast_sip_session *, session, NULL, ao2_cleanup);
2994  struct ast_sip_session *ret_session;
2995  int dsp_features = 0;
2996 
2997  session = ao2_alloc(sizeof(*session), session_destructor);
2998  if (!session) {
2999  return NULL;
3000  }
3001 
3002  AST_LIST_HEAD_INIT(&session->supplements);
3004  ast_party_id_init(&session->id);
3005 
3007  if (!session->direct_media_cap) {
3008  return NULL;
3009  }
3012  if (!session->datastores) {
3013  return NULL;
3014  }
3016  if (!session->active_media_state) {
3017  return NULL;
3018  }
3020  if (!session->pending_media_state) {
3021  return NULL;
3022  }
3023  if (AST_VECTOR_INIT(&session->media_stats, 1) < 0) {
3024  return NULL;
3025  }
3026 
3027  if (endpoint->dtmf == AST_SIP_DTMF_INBAND || endpoint->dtmf == AST_SIP_DTMF_AUTO) {
3028  dsp_features |= DSP_FEATURE_DIGIT_DETECT;
3029  }
3030  if (endpoint->faxdetect) {
3031  dsp_features |= DSP_FEATURE_FAX_DETECT;
3032  }
3033  if (dsp_features) {
3034  session->dsp = ast_dsp_new();
3035  if (!session->dsp) {
3036  return NULL;
3037  }
3038 
3039  ast_dsp_set_features(session->dsp, dsp_features);
3040  }
3041 
3042  session->endpoint = ao2_bump(endpoint);
3043 
3044  if (rdata) {
3045  /*
3046  * We must continue using the serializer that the original
3047  * INVITE came in on for the dialog. There may be
3048  * retransmissions already enqueued in the original
3049  * serializer that can result in reentrancy and message
3050  * sequencing problems.
3051  */
3053  } else {
3054  char tps_name[AST_TASKPROCESSOR_MAX_NAME + 1];
3055 
3056  /* Create name with seq number appended. */
3057  ast_taskprocessor_build_name(tps_name, sizeof(tps_name), "pjsip/outsess/%s",
3058  ast_sorcery_object_get_id(endpoint));
3059 
3060  session->serializer = ast_sip_create_serializer(tps_name);
3061  }
3062  if (!session->serializer) {
3063  return NULL;
3064  }
3065  ast_sip_dialog_set_serializer(inv_session->dlg, session->serializer);
3066  ast_sip_dialog_set_endpoint(inv_session->dlg, endpoint);
3067 
3068  /* When a PJSIP INVITE session is created it is created with a reference
3069  * count of 1, with that reference being managed by the underlying state
3070  * of the INVITE session itself. When the INVITE session transitions to
3071  * a DISCONNECTED state that reference is released. This means we can not
3072  * rely on that reference to ensure the INVITE session remains for the
3073  * lifetime of our session. To ensure it does we add our own reference
3074  * and release it when our own session goes away, ensuring that the INVITE
3075  * session remains for the lifetime of session.
3076  */
3077 
3078 #ifdef HAVE_PJSIP_INV_SESSION_REF
3079  if (pjsip_inv_add_ref(inv_session) != PJ_SUCCESS) {
3080  ast_log(LOG_ERROR, "Can't increase the session reference counter\n");
3081  return NULL;
3082  }
3083 #endif
3084 
3085  pjsip_dlg_inc_session(inv_session->dlg, &session_module);
3086  inv_session->mod_data[session_module.id] = ao2_bump(session);
3087  session->contact = ao2_bump(contact);
3088  session->inv_session = inv_session;
3089 
3090  session->dtmf = endpoint->dtmf;
3091  session->moh_passthrough = endpoint->moh_passthrough;
3092 
3093  if (ast_sip_session_add_supplements(session)) {
3094  /* Release the ref held by session->inv_session */
3095  ao2_ref(session, -1);
3096  return NULL;
3097  }
3098 
3099  session->authentication_challenge_count = 0;
3100 
3101  /* Fire seesion begin handlers */
3102  handle_session_begin(session);
3103 
3104  /* Avoid unnecessary ref manipulation to return a session */
3105  ret_session = session;
3106  session = NULL;
3107  return ret_session;
3108 }
3109 
3110 /*! \brief struct controlling the suspension of the session's serializer. */
3116 };
3117 
3118 static void sip_session_suspender_dtor(void *vdoomed)
3119 {
3120  struct ast_sip_session_suspender *doomed = vdoomed;
3121 
3122  ast_cond_destroy(&doomed->cond_suspended);
3123  ast_cond_destroy(&doomed->cond_complete);
3124 }
3125 
3126 /*!
3127  * \internal
3128  * \brief Block the session serializer thread task.
3129  *
3130  * \param data Pushed serializer task data for suspension.
3131  *
3132  * \retval 0
3133  */
3134 static int sip_session_suspend_task(void *data)
3135 {
3136  struct ast_sip_session_suspender *suspender = data;
3137 
3138  ao2_lock(suspender);
3139 
3140  /* Signal that the serializer task is now suspended. */
3141  suspender->suspended = 1;
3142  ast_cond_signal(&suspender->cond_suspended);
3143 
3144  /* Wait for the serializer suspension to be completed. */
3145  while (!suspender->complete) {
3146  ast_cond_wait(&suspender->cond_complete, ao2_object_get_lockaddr(suspender));
3147  }
3148 
3149  ao2_unlock(suspender);
3150  ao2_ref(suspender, -1);
3151 
3152  return 0;
3153 }
3154 
3156 {
3157  struct ast_sip_session_suspender *suspender;
3158  int res;
3159 
3160  ast_assert(session->suspended == NULL);
3161 
3162  if (ast_taskprocessor_is_task(session->serializer)) {
3163  /* I am the session's serializer thread so I cannot suspend. */
3164  return;
3165  }
3166 
3168  /* The serializer already suspended. */
3169  return;
3170  }
3171 
3172  suspender = ao2_alloc(sizeof(*suspender), sip_session_suspender_dtor);
3173  if (!suspender) {
3174  /* We will just have to hope that the system does not deadlock */
3175  return;
3176  }
3177  ast_cond_init(&suspender->cond_suspended, NULL);
3178  ast_cond_init(&suspender->cond_complete, NULL);
3179 
3180  ao2_ref(suspender, +1);
3181  res = ast_sip_push_task(session->serializer, sip_session_suspend_task, suspender);
3182  if (res) {
3183  /* We will just have to hope that the system does not deadlock */
3184  ao2_ref(suspender, -2);
3185  return;
3186  }
3187 
3188  session->suspended = suspender;
3189 
3190  /* Wait for the serializer to get suspended. */
3191  ao2_lock(suspender);
3192  while (!suspender->suspended) {
3193  ast_cond_wait(&suspender->cond_suspended, ao2_object_get_lockaddr(suspender));
3194  }
3195  ao2_unlock(suspender);
3196 
3198 }
3199 
3201 {
3202  struct ast_sip_session_suspender *suspender = session->suspended;
3203 
3204  if (!suspender) {
3205  /* Nothing to do */
3206  return;
3207  }
3208  session->suspended = NULL;
3209 
3210  /* Signal that the serializer task suspension is now complete. */
3211  ao2_lock(suspender);
3212  suspender->complete = 1;
3213  ast_cond_signal(&suspender->cond_complete);
3214  ao2_unlock(suspender);
3215 
3216  ao2_ref(suspender, -1);
3217 
3219 }
3220 
3221 /*!
3222  * \internal
3223  * \brief Handle initial INVITE challenge response message.
3224  * \since 13.5.0
3225  *
3226  * \param rdata PJSIP receive response message data.
3227  *
3228  * \retval PJ_FALSE Did not handle message.
3229  * \retval PJ_TRUE Handled message.
3230  */
3231 static pj_bool_t outbound_invite_auth(pjsip_rx_data *rdata)
3232 {
3233  pjsip_transaction *tsx;
3234  pjsip_dialog *dlg;
3235  pjsip_inv_session *inv;
3236  pjsip_tx_data *tdata;
3237  struct ast_sip_session *session;
3238 
3239  if (rdata->msg_info.msg->line.status.code != 401
3240  && rdata->msg_info.msg->line.status.code != 407) {
3241  /* Doesn't pertain to us. Move on */
3242  return PJ_FALSE;
3243  }
3244 
3245  tsx = pjsip_rdata_get_tsx(rdata);
3246  dlg = pjsip_rdata_get_dlg(rdata);
3247  if (!dlg || !tsx) {
3248  return PJ_FALSE;
3249  }
3250 
3251  if (tsx->method.id != PJSIP_INVITE_METHOD) {
3252  /* Not an INVITE that needs authentication */
3253  return PJ_FALSE;
3254  }
3255 
3256  inv = pjsip_dlg_get_inv_session(dlg);
3257  session = inv->mod_data[session_module.id];
3258 
3259  if (PJSIP_INV_STATE_CONFIRMED <= inv->state) {
3260  /*
3261  * We cannot handle reINVITE authentication at this
3262  * time because the reINVITE transaction is still in
3263  * progress.
3264  */
3265  ast_debug(3, "%s: A reINVITE is being challenged\n", ast_sip_session_get_name(session));
3266  return PJ_FALSE;
3267  }
3268  ast_debug(3, "%s: Initial INVITE is being challenged.\n", ast_sip_session_get_name(session));
3269 
3271  ast_debug(3, "%s: Initial INVITE reached maximum number of auth attempts.\n", ast_sip_session_get_name(session));
3272  return PJ_FALSE;
3273  }
3274 
3276  tsx->last_tx, &tdata)) {
3277  return PJ_FALSE;
3278  }
3279 
3280  /*
3281  * Restart the outgoing initial INVITE transaction to deal
3282  * with authentication.
3283  */
3284  pjsip_inv_uac_restart(inv, PJ_FALSE);
3285 
3286  ast_sip_session_send_request(session, tdata);
3287  return PJ_TRUE;
3288 }
3289 
3290 static pjsip_module outbound_invite_auth_module = {
3291  .name = {"Outbound INVITE Auth", 20},
3292  .priority = PJSIP_MOD_PRIORITY_DIALOG_USAGE,
3293  .on_rx_response = outbound_invite_auth,
3294 };
3295 
3296 /*!
3297  * \internal
3298  * \brief Setup outbound initial INVITE authentication.
3299  * \since 13.5.0
3300  *
3301  * \param dlg PJSIP dialog to attach outbound authentication.
3302  *
3303  * \retval 0 on success.
3304  * \retval -1 on error.
3305  */
3306 static int setup_outbound_invite_auth(pjsip_dialog *dlg)
3307 {
3308  pj_status_t status;
3309 
3310  ++dlg->sess_count;
3311  status = pjsip_dlg_add_usage(dlg, &outbound_invite_auth_module, NULL);
3312  --dlg->sess_count;
3313 
3314  return status != PJ_SUCCESS ? -1 : 0;
3315 }
3316 
3318  struct ast_sip_contact *contact, const char *location, const char *request_user,
3319  struct ast_stream_topology *req_topology)
3320 {
3321  const char *uri = NULL;
3322  RAII_VAR(struct ast_sip_aor *, found_aor, NULL, ao2_cleanup);
3323  RAII_VAR(struct ast_sip_contact *, found_contact, NULL, ao2_cleanup);
3324  pjsip_timer_setting timer;
3325  pjsip_dialog *dlg;
3326  struct pjsip_inv_session *inv_session;
3327  RAII_VAR(struct ast_sip_session *, session, NULL, ao2_cleanup);
3328  struct ast_sip_session *ret_session;
3329  SCOPE_ENTER(1, "%s %s Topology: %s\n", ast_sorcery_object_get_id(endpoint), request_user,
3330  ast_str_tmp(256, ast_stream_topology_to_str(req_topology, &STR_TMP)));
3331 
3332  /* If no location has been provided use the AOR list from the endpoint itself */
3333  if (location || !contact) {
3334  location = S_OR(location, endpoint->aors);
3335 
3337  &found_aor, &found_contact);
3338  if (!found_contact || ast_strlen_zero(found_contact->uri)) {
3339  uri = location;
3340  } else {
3341  uri = found_contact->uri;
3342  }
3343  } else {
3344  uri = contact->uri;
3345  }
3346 
3347  /* If we still have no URI to dial fail to create the session */
3348  if (ast_strlen_zero(uri)) {
3349  ast_log(LOG_ERROR, "Endpoint '%s': No URI available. Is endpoint registered?\n",
3350  ast_sorcery_object_get_id(endpoint));
3351  SCOPE_EXIT_RTN_VALUE(NULL, "No URI\n");
3352  }
3353 
3354  if (!(dlg = ast_sip_create_dialog_uac(endpoint, uri, request_user))) {
3355  SCOPE_EXIT_RTN_VALUE(NULL, "Couldn't create dialog\n");
3356  }
3357 
3358  if (setup_outbound_invite_auth(dlg)) {
3359  pjsip_dlg_terminate(dlg);
3360  SCOPE_EXIT_RTN_VALUE(NULL, "Couldn't setup auth\n");
3361  }
3362 
3363  if (pjsip_inv_create_uac(dlg, NULL, endpoint->extensions.flags, &inv_session) != PJ_SUCCESS) {
3364  pjsip_dlg_terminate(dlg);
3365  SCOPE_EXIT_RTN_VALUE(NULL, "Couldn't create uac\n");
3366  }
3367 #if defined(HAVE_PJSIP_REPLACE_MEDIA_STREAM) || defined(PJMEDIA_SDP_NEG_ALLOW_MEDIA_CHANGE)
3368  inv_session->sdp_neg_flags = PJMEDIA_SDP_NEG_ALLOW_MEDIA_CHANGE;
3369 #endif
3370 
3371  pjsip_timer_setting_default(&timer);
3372  timer.min_se = endpoint->extensions.timer.min_se;
3373  timer.sess_expires = endpoint->extensions.timer.sess_expires;
3374  pjsip_timer_init_session(inv_session, &timer);
3375 
3376  session = ast_sip_session_alloc(endpoint, found_contact ? found_contact : contact,
3377  inv_session, NULL);
3378  if (!session) {
3379  pjsip_inv_terminate(inv_session, 500, PJ_FALSE);
3380  return NULL;
3381  }
3382  session->aor = ao2_bump(found_aor);
3384 
3385  ast_party_id_copy(&session->id, &endpoint->id.self);
3386 
3387  if (ast_stream_topology_get_count(req_topology) > 0) {
3388  /* get joint caps between req_topology and endpoint topology */
3389  int i;
3390 
3391  for (i = 0; i < ast_stream_topology_get_count(req_topology); ++i) {
3392  struct ast_stream *req_stream;
3393  struct ast_stream *clone_stream;
3394 
3395  req_stream = ast_stream_topology_get_stream(req_topology, i);
3396 
3397  if (ast_stream_get_state(req_stream) == AST_STREAM_STATE_REMOVED) {
3398  continue;
3399  }
3400 
3401  clone_stream = ast_sip_session_create_joint_call_stream(session, req_stream);
3402  if (!clone_stream || ast_stream_get_format_count(clone_stream) == 0) {
3403  ast_stream_free(clone_stream);
3404  continue;
3405  }
3406 
3407  if (!session->pending_media_state->topology) {
3409  if (!session->pending_media_state->topology) {
3410  pjsip_inv_terminate(inv_session, 500, PJ_FALSE);
3411  ao2_ref(session, -1);
3412  SCOPE_EXIT_RTN_VALUE(NULL, "Couldn't create topology\n");
3413  }
3414  }
3415 
3416  if (ast_stream_topology_append_stream(session->pending_media_state->topology, clone_stream) < 0) {
3417  ast_stream_free(clone_stream);
3418  continue;
3419  }
3420  }
3421  }
3422 
3423  if (!session->pending_media_state->topology) {
3424  /* Use the configured topology on the endpoint as the pending one */
3426  if (!session->pending_media_state->topology) {
3427  pjsip_inv_terminate(inv_session, 500, PJ_FALSE);
3428  ao2_ref(session, -1);
3429  SCOPE_EXIT_RTN_VALUE(NULL, "Couldn't clone topology\n");
3430  }
3431  }
3432 
3433  if (pjsip_dlg_add_usage(dlg, &session_module, NULL) != PJ_SUCCESS) {
3434  pjsip_inv_terminate(inv_session, 500, PJ_FALSE);
3435  /* Since we are not notifying ourselves that the INVITE session is being terminated
3436  * we need to manually drop its reference to session
3437  */
3438  ao2_ref(session, -1);
3439  SCOPE_EXIT_RTN_VALUE(NULL, "Couldn't add usage\n");
3440  }
3441 
3442  /* Avoid unnecessary ref manipulation to return a session */
3443  ret_session = session;
3444  session = NULL;
3445  SCOPE_EXIT_RTN_VALUE(ret_session);
3446 }
3447 
3448 static int session_end(void *vsession);
3449 static int session_end_completion(void *vsession);
3450 
3451 void ast_sip_session_terminate(struct ast_sip_session *session, int response)
3452 {
3453  pj_status_t status;
3454  pjsip_tx_data *packet = NULL;
3455  SCOPE_ENTER(1, "%s Response %d\n", ast_sip_session_get_name(session), response);
3456 
3457  if (session->defer_terminate) {
3458  session->terminate_while_deferred = 1;
3459  SCOPE_EXIT_RTN("Deferred\n");
3460  }
3461 
3462  if (!response) {
3463  response = 603;
3464  }
3465 
3466  /* The media sessions need to exist for the lifetime of the underlying channel
3467  * to ensure that anything (such as bridge_native_rtp) has access to them as
3468  * appropriate. Since ast_sip_session_terminate is called by chan_pjsip and other
3469  * places when the session is to be terminated we terminate any existing
3470  * media sessions here.
3471  */
3473  SWAP(session->active_media_state, session->pending_media_state);
3475 
3476  switch (session->inv_session->state) {
3477  case PJSIP_INV_STATE_NULL:
3478  if (!session->inv_session->invite_tsx) {
3479  /*
3480  * Normally, it's pjproject's transaction cleanup that ultimately causes the
3481  * final session reference to be released but if both STATE and invite_tsx are NULL,
3482  * we never created a transaction in the first place. In this case, we need to
3483  * do the cleanup ourselves.
3484  */
3485  /* Transfer the inv_session session reference to the session_end_task */
3486  session->inv_session->mod_data[session_module.id] = NULL;
3487  pjsip_inv_terminate(session->inv_session, response, PJ_TRUE);
3488  session_end(session);
3489  /*
3490  * session_end_completion will cleanup the final session reference unless
3491  * ast_sip_session_terminate's caller is holding one.
3492  */
3493  session_end_completion(session);
3494  } else {
3495  pjsip_inv_terminate(session->inv_session, response, PJ_TRUE);
3496  }
3497  break;
3498  case PJSIP_INV_STATE_CONFIRMED:
3499  if (session->inv_session->invite_tsx) {
3500  ast_debug(3, "%s: Delay sending BYE because of outstanding transaction...\n",
3501  ast_sip_session_get_name(session));
3502  /* If this is delayed the only thing that will happen is a BYE request so we don't
3503  * actually need to store the response code for when it happens.
3504  */
3505  delay_request(session, NULL, NULL, NULL, 0, DELAYED_METHOD_BYE, NULL, NULL, 1);
3506  break;
3507  }
3508  /* Fall through */
3509  default:
3510  status = pjsip_inv_end_session(session->inv_session, response, NULL, &packet);
3511  if (status == PJ_SUCCESS && packet) {
3512  struct ast_sip_session_delayed_request *delay;
3513 
3514  /* Flush any delayed requests so they cannot overlap this transaction. */
3515  while ((delay = AST_LIST_REMOVE_HEAD(&session->delayed_requests, next))) {
3516  delayed_request_free(delay);
3517  }
3518 
3519  if (packet->msg->type == PJSIP_RESPONSE_MSG) {
3520  ast_sip_session_send_response(session, packet);
3521  } else {
3522  ast_sip_session_send_request(session, packet);
3523  }
3524  }
3525  break;
3526  }
3527  SCOPE_EXIT_RTN();
3528 }
3529 
3530 static int session_termination_task(void *data)
3531 {
3532  struct ast_sip_session *session = data;
3533 
3534  if (session->defer_terminate) {
3535  session->defer_terminate = 0;
3536  if (session->inv_session) {
3537  ast_sip_session_terminate(session, 0);
3538  }
3539  }
3540 
3541  ao2_ref(session, -1);
3542  return 0;
3543 }
3544 
3545 static void session_termination_cb(pj_timer_heap_t *timer_heap, struct pj_timer_entry *entry)
3546 {
3547  struct ast_sip_session *session = entry->user_data;
3548 
3549  if (ast_sip_push_task(session->serializer, session_termination_task, session)) {
3550  ao2_cleanup(session);
3551  }
3552 }
3553 
3555 {
3556  pj_time_val delay = { .sec = 60, };
3557  int res;
3558 
3559  /* The session should not have an active deferred termination request. */
3560  ast_assert(!session->defer_terminate);
3561 
3562  session->defer_terminate = 1;
3563 
3564  session->defer_end = 1;
3565  session->ended_while_deferred = 0;
3566 
3567  ao2_ref(session, +1);
3568  pj_timer_entry_init(&session->scheduled_termination, 0, session, session_termination_cb);
3569 
3570  res = (pjsip_endpt_schedule_timer(ast_sip_get_pjsip_endpoint(),
3571  &session->scheduled_termination, &delay) != PJ_SUCCESS) ? -1 : 0;
3572  if (res) {
3573  session->defer_terminate = 0;
3574  ao2_ref(session, -1);
3575  }
3576  return res;
3577 }
3578 
3579 /*!
3580  * \internal
3581  * \brief Stop the defer termination timer if it is still running.
3582  * \since 13.5.0
3583  *
3584  * \param session Which session to stop the timer.
3585  *
3586  * \return Nothing
3587  */
3589 {
3590  if (pj_timer_heap_cancel_if_active(pjsip_endpt_get_timer_heap(ast_sip_get_pjsip_endpoint()),
3591  &session->scheduled_termination, session->scheduled_termination.id)) {
3592  ao2_ref(session, -1);
3593  }
3594 }
3595 
3597 {
3598  if (!session->defer_terminate) {
3599  /* Already canceled or timer fired. */
3600  return;
3601  }
3602 
3603  session->defer_terminate = 0;
3604 
3605  if (session->terminate_while_deferred) {
3606  /* Complete the termination started by the upper layer. */
3607  ast_sip_session_terminate(session, 0);
3608  }
3609 
3610  /* Stop the termination timer if it is still running. */
3612 }
3613 
3615 {
3616  if (!session->defer_end) {
3617  return;
3618  }
3619 
3620  session->defer_end = 0;
3621 
3622  if (session->ended_while_deferred) {
3623  /* Complete the session end started by the remote hangup. */
3624  ast_debug(3, "%s: Ending session after being deferred\n", ast_sip_session_get_name(session));
3625  session->ended_while_deferred = 0;
3626  session_end(session);
3627  }
3628 }
3629 
3631 {
3632  pjsip_inv_session *inv_session = pjsip_dlg_get_inv_session(dlg);
3633  struct ast_sip_session *session;
3634 
3635  if (!inv_session ||
3636  !(session = inv_session->mod_data[session_module.id])) {
3637  return NULL;
3638  }
3639 
3640  ao2_ref(session, +1);
3641 
3642  return session;
3643 }
3644 
3646  /*! The extension was successfully found */
3648  /*! The extension specified in the RURI was not found */
3650  /*! The extension specified in the RURI was a partial match */
3652  /*! The RURI is of an unsupported scheme */
3654 };
3655 
3656 /*!
3657  * \brief Determine where in the dialplan a call should go
3658  *
3659  * This uses the username in the request URI to try to match
3660  * an extension in the endpoint's configured context in order
3661  * to route the call.
3662  *
3663  * \param session The inbound SIP session
3664  * \param rdata The SIP INVITE
3665  */
3666 static enum sip_get_destination_result get_destination(struct ast_sip_session *session, pjsip_rx_data *rdata)
3667 {
3668  pjsip_uri *ruri = rdata->msg_info.msg->line.req.uri;
3669  pjsip_sip_uri *sip_ruri;
3670  struct ast_features_pickup_config *pickup_cfg;
3671  const char *pickupexten;
3672 
3673  if (!PJSIP_URI_SCHEME_IS_SIP(ruri) && !PJSIP_URI_SCHEME_IS_SIPS(ruri)) {
3675  }
3676 
3677  sip_ruri = pjsip_uri_get_uri(ruri);
3678  ast_copy_pj_str(session->exten, &sip_ruri->user, sizeof(session->exten));
3679 
3680  /*
3681  * We may want to match in the dialplan without any user
3682  * options getting in the way.
3683  */
3685 
3686  pickup_cfg = ast_get_chan_features_pickup_config(NULL); /* session->channel doesn't exist yet, using NULL */
3687  if (!pickup_cfg) {
3688  ast_log(LOG_ERROR, "%s: Unable to retrieve pickup configuration options. Unable to detect call pickup extension\n",
3689  ast_sip_session_get_name(session));
3690  pickupexten = "";
3691  } else {
3692  pickupexten = ast_strdupa(pickup_cfg->pickupexten);
3693  ao2_ref(pickup_cfg, -1);
3694  }
3695 
3696  if (!strcmp(session->exten, pickupexten) ||
3697  ast_exists_extension(NULL, session->endpoint->context, session->exten, 1, NULL)) {
3698  /*
3699  * Save off the INVITE Request-URI in case it is
3700  * needed: CHANNEL(pjsip,request_uri)
3701  */
3702  session->request_uri = pjsip_uri_clone(session->inv_session->pool, ruri);
3703 
3704  return SIP_GET_DEST_EXTEN_FOUND;
3705  }
3706 
3707  /*
3708  * Check for partial match via overlap dialling (if enabled)
3709  */
3710  if (session->endpoint->allow_overlap && (
3711  !strncmp(session->exten, pickupexten, strlen(session->exten)) ||
3712  ast_canmatch_extension(NULL, session->endpoint->context, session->exten, 1, NULL))) {
3713  /* Overlap partial match */
3715  }
3716 
3718 }
3719 
3720 /*
3721  * /internal
3722  * /brief Process initial answer for an incoming invite
3723  *
3724  * This function should only be called during the setup, and handling of a
3725  * new incoming invite. Most, if not all of the time, this will be called
3726  * when an error occurs and we need to respond as such.
3727  *
3728  * When a SIP session termination code is given for the answer it's assumed
3729  * this call then will be the final bit of processing before ending session
3730  * setup. As such, we've been holding a lock, and a reference on the invite
3731  * session's dialog. So before returning this function removes that reference,
3732  * and unlocks the dialog.
3733  *
3734  * \param inv_session The session on which to answer
3735  * \param rdata The original request
3736  * \param answer_code The answer's numeric code
3737  * \param terminate_code The termination code if the answer fails
3738  * \param notify Whether or not to call on_state_changed
3739  *
3740  * \retval 0 if invite successfully answered, -1 if an error occurred
3741  */
3742 static int new_invite_initial_answer(pjsip_inv_session *inv_session, pjsip_rx_data *rdata,
3743  int answer_code, int terminate_code, pj_bool_t notify)
3744 {
3745  pjsip_tx_data *tdata = NULL;
3746  int res = 0;
3747 
3748  if (inv_session->state != PJSIP_INV_STATE_DISCONNECTED) {
3749  if (pjsip_inv_initial_answer(
3750  inv_session, rdata, answer_code, NULL, NULL, &tdata) != PJ_SUCCESS) {
3751 
3752  pjsip_inv_terminate(inv_session, terminate_code ? terminate_code : answer_code, notify);
3753  res = -1;
3754  } else {
3755  pjsip_inv_send_msg(inv_session, tdata);
3756  }
3757  }
3758 
3759  if (answer_code >= 300) {
3760  /*
3761  * A session is ending. The dialog has a reference that needs to be
3762  * removed and holds a lock that needs to be unlocked before returning.
3763  */
3764  pjsip_dlg_dec_lock(inv_session->dlg);
3765  }
3766 
3767  return res;
3768 }
3769 
3770 /*
3771  * /internal
3772  * /brief Create and initialize a pjsip invite session
3773 
3774  * pjsip_inv_session adds, and maintains a reference to the dialog upon a successful
3775  * invite session creation until the session is destroyed. However, we'll wait to
3776  * remove the reference that was added for the dialog when it gets created since we're
3777  * not ready to unlock the dialog in this function.
3778  *
3779  * So, if this function successfully returns that means it returns with its newly
3780  * created, and associated dialog locked and with two references (i.e. dialog's
3781  * reference count should be 2).
3782  *
3783  * \param endpoint A pointer to the endpoint
3784  * \param rdata The request that is starting the dialog
3785  *
3786  * \retval A pjsip invite session object
3787  * \retval NULL on error
3788  */
3789 static pjsip_inv_session *pre_session_setup(pjsip_rx_data *rdata, const struct ast_sip_endpoint *endpoint)
3790 {
3791  pjsip_tx_data *tdata;
3792  pjsip_dialog *dlg;
3793  pjsip_inv_session *inv_session;
3794  unsigned int options = endpoint->extensions.flags;
3795  pj_status_t dlg_status = PJ_EUNKNOWN;
3796 
3797  if (pjsip_inv_verify_request(rdata, &options, NULL, NULL, ast_sip_get_pjsip_endpoint(), &tdata) != PJ_SUCCESS) {
3798  if (tdata) {
3799  if (pjsip_endpt_send_response2(ast_sip_get_pjsip_endpoint(), rdata, tdata, NULL, NULL) != PJ_SUCCESS) {
3800  pjsip_tx_data_dec_ref(tdata);
3801  }
3802  } else {
3803  pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 500, NULL, NULL, NULL);
3804  }
3805  return NULL;
3806  }
3807 
3808  dlg = ast_sip_create_dialog_uas_locked(endpoint, rdata, &dlg_status);
3809  if (!dlg) {
3810  if (dlg_status != PJ_EEXISTS) {
3811  pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 500, NULL, NULL, NULL);
3812  }
3813  return NULL;
3814  }
3815 
3816  /*
3817  * The returned dialog holds a lock and has a reference added. Any paths where the
3818  * dialog invite session is not returned must unlock the dialog and remove its reference.
3819  */
3820 
3821  if (pjsip_inv_create_uas(dlg, rdata, NULL, options, &inv_session) != PJ_SUCCESS) {
3822  pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 500, NULL, NULL, NULL);
3823  /*
3824  * The acquired dialog holds a lock, and a reference. Since the dialog is not
3825  * going to be returned here it must first be unlocked and de-referenced. This
3826  * must be done prior to calling dialog termination.
3827  */
3828  pjsip_dlg_dec_lock(dlg);
3829  pjsip_dlg_terminate(dlg);
3830  return NULL;
3831  }
3832 
3833 #if defined(HAVE_PJSIP_REPLACE_MEDIA_STREAM) || defined(PJMEDIA_SDP_NEG_ALLOW_MEDIA_CHANGE)
3834  inv_session->sdp_neg_flags = PJMEDIA_SDP_NEG_ALLOW_MEDIA_CHANGE;
3835 #endif
3836  if (pjsip_dlg_add_usage(dlg, &session_module, NULL) != PJ_SUCCESS) {
3837  /* Dialog's lock and a reference are removed in new_invite_initial_answer */
3838  new_invite_initial_answer(inv_session, rdata, 500, 500, PJ_FALSE);
3839  /* Remove 2nd reference added at inv_session creation */
3840  pjsip_dlg_dec_session(inv_session->dlg, &session_module);
3841  return NULL;
3842  }
3843 
3844  return inv_session;
3845 }
3846 
3847 struct new_invite {
3848  /*! \brief Session created for the new INVITE */
3850 
3851  /*! \brief INVITE request itself */
3852  pjsip_rx_data *rdata;
3853 };
3854 
3855 static int check_sdp_content_type_supported(pjsip_media_type *content_type)
3856 {
3857  pjsip_media_type app_sdp;
3858  pjsip_media_type_init2(&app_sdp, "application", "sdp");
3859 
3860  if (!pjsip_media_type_cmp(content_type, &app_sdp, 0)) {
3861  return 1;
3862  }
3863 
3864  return 0;
3865 }
3866 
3867 static int check_content_disposition_in_multipart(pjsip_multipart_part *part)
3868 {
3869  pjsip_hdr *hdr = part->hdr.next;
3870  static const pj_str_t str_handling_required = {"handling=required", 16};
3871 
3872  while (hdr != &part->hdr) {
3873  if (hdr->type == PJSIP_H_OTHER) {
3874  pjsip_generic_string_hdr *generic_hdr = (pjsip_generic_string_hdr*)hdr;
3875 
3876  if (!pj_stricmp2(&hdr->name, "Content-Disposition") &&
3877  pj_stristr(&generic_hdr->hvalue, &str_handling_required) &&
3878  !check_sdp_content_type_supported(&part->body->content_type)) {
3879  return 1;
3880  }
3881  }
3882  hdr = hdr->next;
3883  }
3884 
3885  return 0;
3886 }
3887 
3888 /**
3889  * if there is required media we don't understand, return 1
3890  */
3891 static int check_content_disposition(pjsip_rx_data *rdata)
3892 {
3893  pjsip_msg_body *body = rdata->msg_info.msg->body;
3894  pjsip_ctype_hdr *ctype_hdr = rdata->msg_info.ctype;
3895 
3896  if (body && ctype_hdr &&
3897  !pj_stricmp2(&ctype_hdr->media.type, "multipart") &&
3898  (!pj_stricmp2(&ctype_hdr->media.subtype, "mixed") ||
3899  !pj_stricmp2(&ctype_hdr->media.subtype, "alternative"))) {
3900  pjsip_multipart_part *part = pjsip_multipart_get_first_part(body);
3901  while (part != NULL) {
3903  return 1;
3904  }
3905  part = pjsip_multipart_get_next_part(body, part);
3906  }
3907  }
3908  return 0;
3909 }
3910 
3911 static int new_invite(struct new_invite *invite)
3912 {
3913  pjsip_tx_data *tdata = NULL;
3914  pjsip_timer_setting timer;
3915  pjsip_rdata_sdp_info *sdp_info;
3916  pjmedia_sdp_session *local = NULL;
3917  char buffer[AST_SOCKADDR_BUFLEN];
3918  SCOPE_ENTER(3, "%s\n", ast_sip_session_get_name(invite->session));
3919 
3920 
3921  /* From this point on, any calls to pjsip_inv_terminate have the last argument as PJ_TRUE
3922  * so that we will be notified so we can destroy the session properly
3923  */
3924 
3925  if (invite->session->inv_session->state == PJSIP_INV_STATE_DISCONNECTED) {
3926  ast_trace_log(-1, LOG_ERROR, "%s: Session already DISCONNECTED [reason=%d (%s)]\n",
3928  invite->session->inv_session->cause,
3929  pjsip_get_status_text(invite->session->inv_session->cause)->ptr);
3931  }
3932 
3933  switch (get_destination(invite->session, invite->rdata)) {
3935  /* Things worked. Keep going */
3936  break;
3938  ast_trace(-1, "%s: Call (%s:%s) to extension '%s' - unsupported uri\n",
3940  invite->rdata->tp_info.transport->type_name,
3941  pj_sockaddr_print(&invite->rdata->pkt_info.src_addr, buffer, sizeof(buffer), 3),
3942  invite->session->exten);
3943  if (pjsip_inv_initial_answer(invite->session->inv_session, invite->rdata, 416, NULL, NULL, &tdata) == PJ_SUCCESS) {
3944  ast_sip_session_send_response(invite->session, tdata);
3945  } else {
3946  pjsip_inv_terminate(invite->session->inv_session, 416, PJ_TRUE);
3947  }
3948  goto end;
3950  ast_trace(-1, "%s: Call (%s:%s) to extension '%s' - partial match\n",
3952  invite->rdata->tp_info.transport->type_name,
3953  pj_sockaddr_print(&invite->rdata->pkt_info.src_addr, buffer, sizeof(buffer), 3),
3954  invite->session->exten);
3955 
3956  if (pjsip_inv_initial_answer(invite->session->inv_session, invite->rdata, 484, NULL, NULL, &tdata) == PJ_SUCCESS) {
3957  ast_sip_session_send_response(invite->session, tdata);
3958  } else {
3959  pjsip_inv_terminate(invite->session->inv_session, 484, PJ_TRUE);
3960  }
3961  goto end;
3963  default:
3964  ast_trace_log(-1, LOG_NOTICE, "%s: Call (%s:%s) to extension '%s' rejected because extension not found in context '%s'.\n",
3966  invite->rdata->tp_info.transport->type_name,
3967  pj_sockaddr_print(&invite->rdata->pkt_info.src_addr, buffer, sizeof(buffer), 3),
3968  invite->session->exten,
3969  invite->session->endpoint->context);
3970 
3971  if (pjsip_inv_initial_answer(invite->session->inv_session, invite->rdata, 404, NULL, NULL, &tdata) == PJ_SUCCESS) {
3972  ast_sip_session_send_response(invite->session, tdata);
3973  } else {
3974  pjsip_inv_terminate(invite->session->inv_session, 404, PJ_TRUE);
3975  }
3976  goto end;
3977  };
3978 
3979  if (check_content_disposition(invite->rdata)) {
3980  if (pjsip_inv_initial_answer(invite->session->inv_session, invite->rdata, 415, NULL, NULL, &tdata) == PJ_SUCCESS) {
3981  ast_sip_session_send_response(invite->session, tdata);
3982  } else {
3983  pjsip_inv_terminate(invite->session->inv_session, 415, PJ_TRUE);
3984  }
3985  goto end;
3986  }
3987 
3988  pjsip_timer_setting_default(&timer);
3989  timer.min_se = invite->session->endpoint->extensions.timer.min_se;
3990  timer.sess_expires = invite->session->endpoint->extensions.timer.sess_expires;
3991  pjsip_timer_init_session(invite->session->inv_session, &timer);
3992 
3993  /*
3994  * At this point, we've verified what we can that won't take awhile,
3995  * so let's go ahead and send a 100 Trying out to stop any
3996  * retransmissions.
3997  */
3998  ast_trace(-1, "%s: Call (%s:%s) to extension '%s' sending 100 Trying\n",
4000  invite->rdata->tp_info.transport->type_name,
4001  pj_sockaddr_print(&invite->rdata->pkt_info.src_addr, buffer, sizeof(buffer), 3),
4002  invite->session->exten);
4003  if (pjsip_inv_initial_answer(invite->session->inv_session, invite->rdata, 100, NULL, NULL, &tdata) != PJ_SUCCESS) {
4004  pjsip_inv_terminate(invite->session->inv_session, 500, PJ_TRUE);
4005  goto end;
4006  }
4007  ast_sip_session_send_response(invite->session, tdata);
4008 
4009  sdp_info = pjsip_rdata_get_sdp_info(invite->rdata);
4010  if (sdp_info && (sdp_info->sdp_err == PJ_SUCCESS) && sdp_info->sdp) {
4011  if (handle_incoming_sdp(invite->session, sdp_info->sdp)) {
4012  tdata = NULL;
4013  if (pjsip_inv_end_session(invite->session->inv_session, 488, NULL, &tdata) == PJ_SUCCESS
4014  && tdata) {
4015  ast_sip_session_send_response(invite->session, tdata);
4016  }
4017  goto end;
4018  }
4019  /* We are creating a local SDP which is an answer to their offer */
4020  local = create_local_sdp(invite->session->inv_session, invite->session, sdp_info->sdp);
4021  } else {
4022  /* We are creating a local SDP which is an offer */
4023  local = create_local_sdp(invite->session->inv_session, invite->session, NULL);
4024  }
4025 
4026  /* If we were unable to create a local SDP terminate the session early, it won't go anywhere */
4027  if (!local) {
4028  tdata = NULL;
4029  if (pjsip_inv_end_session(invite->session->inv_session, 500, NULL, &tdata) == PJ_SUCCESS
4030  && tdata) {
4031  ast_sip_session_send_response(invite->session, tdata);
4032  }
4033  goto end;
4034  }
4035 
4036  pjsip_inv_set_local_sdp(invite->session->inv_session, local);
4037  pjmedia_sdp_neg_set_prefer_remote_codec_order(invite->session->inv_session->neg, PJ_FALSE);
4038 #ifdef PJMEDIA_SDP_NEG_ANSWER_MULTIPLE_CODECS
4039  if (!invite->session->endpoint->preferred_codec_only) {
4040  pjmedia_sdp_neg_set_answer_multiple_codecs(invite->session->inv_session->neg, PJ_TRUE);
4041  }
4042 #endif
4043 
4044  handle_incoming_request(invite->session, invite->rdata);
4045 
4046 end:
4048 }
4049 
4050 static void handle_new_invite_request(pjsip_rx_data *rdata)
4051 {
4054  pjsip_inv_session *inv_session = NULL;
4055  struct ast_sip_session *session;
4056  struct new_invite invite;
4057  char *req_uri = TRACE_ATLEAST(1) ? ast_alloca(256) : "";
4058  int res = TRACE_ATLEAST(1) ? pjsip_uri_print(PJSIP_URI_IN_REQ_URI, rdata->msg_info.msg->line.req.uri, req_uri, 256) : 0;
4059  SCOPE_ENTER(1, "Request: %s\n", res ? req_uri : "");
4060 
4061  ast_assert(endpoint != NULL);
4062 
4063  inv_session = pre_session_setup(rdata, endpoint);
4064  if (!inv_session) {
4065  /* pre_session_setup() returns a response on failure */
4066  SCOPE_EXIT_RTN("Failure in pre session setup\n");
4067  }
4068 
4069  /*
4070  * Upon a successful pre_session_setup the associated dialog is returned locked
4071  * and with an added reference. Well actually two references. One added when the
4072  * dialog itself was created, and another added when the pjsip invite session was
4073  * created and the dialog was added to it.
4074  *
4075  * In order to ensure the dialog's, and any of its internal attributes, lifetimes
4076  * we'll hold the lock and maintain the reference throughout the entire new invite
4077  * handling process. See ast_sip_create_dialog_uas_locked for more details but,
4078  * basically we do this to make sure a transport failure does not destroy the dialog
4079  * and/or transaction out from underneath us between pjsip calls. Alternatively, we
4080  * could probably release the lock if we needed to, but then we'd have to re-lock and
4081  * check the dialog and transaction prior to every pjsip call.
4082  *
4083  * That means any off nominal/failure paths in this function must remove the associated
4084  * dialog reference added at dialog creation, and remove the lock. As well the
4085  * referenced pjsip invite session must be "cleaned up", which should also then
4086  * remove its reference to the dialog at that time.
4087  *
4088  * Nominally we'll unlock the dialog, and release the reference when all new invite
4089  * process handling has successfully completed.
4090  */
4091 
4092  session = ast_sip_session_alloc(endpoint, NULL, inv_session, rdata);
4093  if (!session) {
4094  /* Dialog's lock and reference are removed in new_invite_initial_answer */
4095  if (!new_invite_initial_answer(inv_session, rdata, 500, 500, PJ_FALSE)) {
4096  /* Terminate the session if it wasn't done in the answer */
4097  pjsip_inv_terminate(inv_session, 500, PJ_FALSE);
4098  }
4099  SCOPE_EXIT_RTN("Couldn't create session\n");
4100  }
4102 
4103  /*
4104  * The current thread is supposed be the session serializer to prevent
4105  * any initial INVITE retransmissions from trying to setup the same
4106  * call again.
4107  */
4109 
4110  invite.session = session;
4111  invite.rdata = rdata;
4112  new_invite(&invite);
4113 
4114  /*
4115  * The dialog lock and reference added at dialog creation time must be
4116  * maintained throughout the new invite process. Since we're pretty much
4117  * done at this point with things it's safe to go ahead and remove the lock
4118  * and the reference here. See ast_sip_create_dialog_uas_locked for more info.
4119  *
4120  * Note, any future functionality added that does work using the dialog must
4121  * be done before this.
4122  */
4123  pjsip_dlg_dec_lock(inv_session->dlg);
4124 
4125  SCOPE_EXIT("Request: %s Session: %s\n", req_uri, ast_sip_session_get_name(session));
4126  ao2_ref(session, -1);
4127 }
4128 
4129 static pj_bool_t does_method_match(const pj_str_t *message_method, const char *supplement_method)
4130 {
4131  pj_str_t method;
4132 
4133  if (ast_strlen_zero(supplement_method)) {
4134  return PJ_TRUE;
4135  }
4136 
4137  pj_cstr(&method, supplement_method);
4138 
4139  return pj_stristr(&method, message_method) ? PJ_TRUE : PJ_FALSE;
4140 }
4141 
4142 static pj_bool_t has_supplement(const struct ast_sip_session *session, const pjsip_rx_data *rdata)
4143 {
4144  struct ast_sip_session_supplement *supplement;
4145  struct pjsip_method *method = &rdata->msg_info.msg->line.req.method;
4146 
4147  if (!session) {
4148  return PJ_FALSE;
4149  }
4150 
4151  AST_LIST_TRAVERSE(&session->supplements, supplement, next) {
4152  if (does_method_match(&method->name, supplement->method)) {
4153  return PJ_TRUE;
4154  }
4155  }
4156  return PJ_FALSE;
4157 }
4158 
4159 /*!
4160  * \internal
4161  * Added for debugging purposes
4162  */
4163 static void session_on_tsx_state(pjsip_transaction *tsx, pjsip_event *e)
4164 {
4165 
4166  pjsip_dialog *dlg = pjsip_tsx_get_dlg(tsx);
4167  pjsip_inv_session *inv_session = (dlg ? pjsip_dlg_get_inv_session(dlg) : NULL);
4168  struct ast_sip_session *session = (inv_session ? inv_session->mod_data[session_module.id] : NULL);
4169  SCOPE_ENTER(1, "%s TSX State: %s Inv State: %s\n", ast_sip_session_get_name(session),
4170  pjsip_tsx_state_str(tsx->state), inv_session ? pjsip_inv_state_name(inv_session->state) : "unknown");
4171 
4172  if (session) {
4173  ast_trace(2, "Topology: Pending: %s Active: %s\n",
4176  }
4177 
4178  SCOPE_EXIT_RTN();
4179 }
4180 
4181 /*!
4182  * \internal
4183  * Added for debugging purposes
4184  */
4185 static pj_bool_t session_on_rx_response(pjsip_rx_data *rdata)
4186 {
4187 
4188  struct pjsip_status_line status = rdata->msg_info.msg->line.status;
4189  pjsip_dialog *dlg = pjsip_rdata_get_dlg(rdata);
4190  pjsip_inv_session *inv_session = dlg ? pjsip_dlg_get_inv_session(dlg) : NULL;
4191  struct ast_sip_session *session = (inv_session ? inv_session->mod_data[session_module.id] : NULL);
4192  SCOPE_ENTER(1, "%s Method: %.*s Status: %d\n", ast_sip_session_get_name(session),
4193  (int)rdata->msg_info.cseq->method.name.slen, rdata->msg_info.cseq->method.name.ptr, status.code);
4194 
4195  SCOPE_EXIT_RTN_VALUE(PJ_FALSE);
4196 }
4197 
4198 /*!
4199  * \brief Called when a new SIP request comes into PJSIP
4200  *
4201  * This function is called under two circumstances
4202  * 1) An out-of-dialog request is received by PJSIP
4203  * 2) An in-dialog request that the inv_session layer does not
4204  * handle is received (such as an in-dialog INFO)
4205  *
4206  * Except for INVITEs, there is very little we actually do in this function
4207  * 1) For requests we don't handle, we return PJ_FALSE
4208  * 2) For new INVITEs, handle them now to prevent retransmissions from
4209  * trying to setup the same call again.
4210  * 3) For in-dialog requests we handle, we process them in the
4211  * .on_state_changed = session_inv_on_state_changed or
4212  * .on_tsx_state_changed = session_inv_on_tsx_state_changed
4213  * callbacks instead.
4214  */
4215 static pj_bool_t session_on_rx_request(pjsip_rx_data *rdata)
4216 {
4217  pj_status_t handled = PJ_FALSE;
4218  struct pjsip_request_line req = rdata->msg_info.msg->line.req;
4219  pjsip_dialog *dlg = pjsip_rdata_get_dlg(rdata);
4220  pjsip_inv_session *inv_session = (dlg ? pjsip_dlg_get_inv_session(dlg) : NULL);
4221  struct ast_sip_session *session = (inv_session ? inv_session->mod_data[session_module.id] : NULL);
4222  char *req_uri = TRACE_ATLEAST(1) ? ast_alloca(256) : "";
4223  int res = TRACE_ATLEAST(1) ? pjsip_uri_print(PJSIP_URI_IN_REQ_URI, rdata->msg_info.msg->line.req.uri, req_uri, 256) : 0;
4224  SCOPE_ENTER(1, "%s Request: %.*s %s\n", ast_sip_session_get_name(session),
4225  (int) pj_strlen(&req.method.name), pj_strbuf(&req.method.name), res ? req_uri : "");
4226 
4227  switch (req.method.id) {
4228  case PJSIP_INVITE_METHOD:
4229  if (dlg) {
4230  ast_log(LOG_WARNING, "on_rx_request called for INVITE in mid-dialog?\n");
4231  break;
4232  }
4233  handled = PJ_TRUE;
4235  break;
4236  default:
4237  /* Handle other in-dialog methods if their supplements have been registered */
4238  handled = dlg && (inv_session = pjsip_dlg_get_inv_session(dlg)) &&
4239  has_supplement(inv_session->mod_data[session_module.id], rdata);
4240  break;
4241  }
4242 
4243  SCOPE_EXIT_RTN_VALUE(handled, "%s Handled request %.*s %s ? %s\n", ast_sip_session_get_name(session),
4244  (int) pj_strlen(&req.method.name), pj_strbuf(&req.method.name), req_uri,
4245  handled == PJ_TRUE ? "yes" : "no");
4246 }
4247 
4248 static void resend_reinvite(pj_timer_heap_t *timer, pj_timer_entry *entry)
4249 {
4250  struct ast_sip_session *session = entry->user_data;
4251 
4252  ast_debug(3, "%s: re-INVITE collision timer expired.\n",
4253  ast_sip_session_get_name(session));
4254 
4255  if (AST_LIST_EMPTY(&session->delayed_requests)) {
4256  /* No delayed request pending, so just return */
4257  ao2_ref(session, -1);
4258  return;
4259  }
4260  if (ast_sip_push_task(session->serializer, invite_collision_timeout, session)) {
4261  /*
4262  * Uh oh. We now have nothing in the foreseeable future
4263  * to trigger sending the delayed requests.
4264  */
4265  ao2_ref(session, -1);
4266  }
4267 }
4268 
4269 static void reschedule_reinvite(struct ast_sip_session *session, ast_sip_session_response_cb on_response)
4270 {
4271  pjsip_inv_session *inv = session->inv_session;
4272  pj_time_val tv;
4273  struct ast_sip_session_media_state *pending_media_state = NULL;
4274  struct ast_sip_session_media_state *active_media_state = NULL;
4275  const char *session_name = ast_sip_session_get_name(session);
4276  int use_pending = 0;
4277  int use_active = 0;
4278 
4279  SCOPE_ENTER(3, "%s\n", session_name);
4280 
4281  /*
4282  * If the two media state topologies are the same this means that the session refresh request
4283  * did not specify a desired topology, so it does not care. If that is the case we don't even
4284  * pass one in here resulting in the current topology being used. It's possible though that
4285  * either one of the topologies could be NULL so we have to test for that before we check for
4286  * equality.
4287  */
4288 
4289  /* We only want to clone a media state if its topology is not null */
4290  use_pending = session->pending_media_state->topology != NULL;
4291  use_active = session->active_media_state->topology != NULL;
4292 
4293  /*
4294  * If both media states have topologies, we can test for equality. If they're equal we're not going to
4295  * clone either states.
4296  */
4297  if (use_pending && use_active && ast_stream_topology_equal(session->active_media_state->topology, session->pending_media_state->topology)) {
4298  use_pending = 0;
4299  use_active = 0;
4300  }
4301 
4302  if (use_pending) {
4303  pending_media_state = ast_sip_session_media_state_clone(session->pending_media_state);
4304  if (!pending_media_state) {
4305  SCOPE_EXIT_LOG_RTN(LOG_ERROR, "%s: Failed to clone pending media state\n", session_name);
4306  }
4307  }
4308 
4309  if (use_active) {
4310  active_media_state = ast_sip_session_media_state_clone(session->active_media_state);
4311  if (!active_media_state) {
4312  ast_sip_session_media_state_free(pending_media_state);
4313  SCOPE_EXIT_LOG_RTN(LOG_ERROR, "%s: Failed to clone active media state\n", session_name);
4314  }
4315  }
4316 
4317  if (delay_request(session, NULL, NULL, on_response, 1, DELAYED_METHOD_INVITE, pending_media_state,
4318  active_media_state, 1)) {
4319  ast_sip_session_media_state_free(pending_media_state);
4320  ast_sip_session_media_state_free(active_media_state);
4321  SCOPE_EXIT_LOG_RTN(LOG_ERROR, "%s: Failed to add delayed request\n", session_name);
4322  }
4323 
4324  if (pj_timer_entry_running(&session->rescheduled_reinvite)) {
4325  /* Timer already running. Something weird is going on. */
4326  SCOPE_EXIT_LOG_RTN(LOG_ERROR, "%s: re-INVITE collision while timer running!!!\n", session_name);
4327  }
4328 
4329  tv.sec = 0;
4330  if (inv->role == PJSIP_ROLE_UAC) {
4331  tv.msec = 2100 + ast_random() % 2000;
4332  } else {
4333  tv.msec = ast_random() % 2000;
4334  }
4335  pj_timer_entry_init(&session->rescheduled_reinvite, 0, session, resend_reinvite);
4336 
4337  ao2_ref(session, +1);
4338  if (pjsip_endpt_schedule_timer(ast_sip_get_pjsip_endpoint(),
4339  &session->rescheduled_reinvite, &tv) != PJ_SUCCESS) {
4340  ao2_ref(session, -1);
4341  SCOPE_EXIT_LOG_RTN(LOG_ERROR, "%s: Couldn't schedule timer\n", session_name);
4342  }
4343 
4344  SCOPE_EXIT_RTN();
4345 }
4346 
4347 static void __print_debug_details(const char *function, pjsip_inv_session *inv, pjsip_transaction *tsx, pjsip_event *e)
4348 {
4349  int id = session_module.id;
4350  struct ast_sip_session *session = NULL;
4351 
4352  if (!DEBUG_ATLEAST(5)) {
4353  /* Debug not spamy enough */
4354  return;
4355  }
4356 
4357  ast_log(LOG_DEBUG, "Function %s called on event %s\n",
4358  function, pjsip_event_str(e->type));
4359  if (!inv) {
4360  ast_log(LOG_DEBUG, "Transaction %p does not belong to an inv_session?\n", tsx);
4361  ast_log(LOG_DEBUG, "The transaction state is %s\n",
4362  pjsip_tsx_state_str(tsx->state));
4363  return;
4364  }
4365  if (id > -1) {
4366  session = inv->mod_data[session_module.id];
4367  }
4368  if (!session) {
4369  ast_log(LOG_DEBUG, "inv_session %p has no ast session\n", inv);
4370  } else {
4371  ast_log(LOG_DEBUG, "The state change pertains to the endpoint '%s(%s)'\n",
4373  session->channel ? ast_channel_name(session->channel) : "");
4374  }
4375  if (inv->invite_tsx) {
4376  ast_log(LOG_DEBUG, "The inv session still has an invite_tsx (%p)\n",
4377  inv->invite_tsx);
4378  } else {
4379  ast_log(LOG_DEBUG, "The inv session does NOT have an invite_tsx\n");
4380  }
4381  if (tsx) {
4382  ast_log(LOG_DEBUG, "The %s %.*s transaction involved in this state change is %p\n",
4383  pjsip_role_name(tsx->role),
4384  (int) pj_strlen(&tsx->method.name), pj_strbuf(&tsx->method.name),
4385  tsx);
4386  ast_log(LOG_DEBUG, "The current transaction state is %s\n",
4387  pjsip_tsx_state_str(tsx->state));
4388  ast_log(LOG_DEBUG, "The transaction state change event is %s\n",
4389  pjsip_event_str(e->body.tsx_state.type));
4390  } else {
4391  ast_log(LOG_DEBUG, "There is no transaction involved in this state change\n");
4392  }
4393  ast_log(LOG_DEBUG, "The current inv state is %s\n", pjsip_inv_state_name(inv->state));
4394 }
4395 
4396 #define print_debug_details(inv, tsx, e) __print_debug_details(__PRETTY_FUNCTION__, (inv), (tsx), (e))
4397 
4398 static void handle_incoming_request(struct ast_sip_session *session, pjsip_rx_data *rdata)
4399 {
4400  struct ast_sip_session_supplement *supplement;
4401  struct pjsip_request_line req = rdata->msg_info.msg->line.req;
4402  SCOPE_ENTER(3, "%s: Method is %.*s\n", ast_sip_session_get_name(session), (int) pj_strlen(&req.method.name), pj_strbuf(&req.method.name));
4403 
4404  AST_LIST_TRAVERSE(&session->supplements, supplement, next) {
4405  if (supplement->incoming_request && does_method_match(&req.method.name, supplement->method)) {
4406  if (supplement->incoming_request(session, rdata)) {
4407  break;
4408  }
4409  }
4410  }
4411 
4412  SCOPE_EXIT("%s\n", ast_sip_session_get_name(session));
4413 }
4414 
4415 static void handle_session_begin(struct ast_sip_session *session)
4416 {
4417  struct ast_sip_session_supplement *iter;
4418 
4419  AST_LIST_TRAVERSE(&session->supplements, iter, next) {
4420  if (iter->session_begin) {
4421  iter->session_begin(session);
4422  }
4423  }
4424 }
4425 
4426 static void handle_session_destroy(struct ast_sip_session *session)
4427 {
4428  struct ast_sip_session_supplement *iter;
4429 
4430  AST_LIST_TRAVERSE(&session->supplements, iter, next) {
4431  if (iter->session_destroy) {
4432  iter->session_destroy(session);
4433  }
4434  }
4435 }
4436 
4437 static void handle_session_end(struct ast_sip_session *session)
4438 {
4439  struct ast_sip_session_supplement *iter;
4440 
4441  /* Session is dead. Notify the supplements. */
4442  AST_LIST_TRAVERSE(&session->supplements, iter, next) {
4443  if (iter->session_end) {
4444  iter->session_end(session);
4445  }
4446  }
4447 }
4448 
4449 static void handle_incoming_response(struct ast_sip_session *session, pjsip_rx_data *rdata,
4451 {
4452  struct ast_sip_session_supplement *supplement;
4453  struct pjsip_status_line status = rdata->msg_info.msg->line.status;
4454  SCOPE_ENTER(3, "%s: Response is %d %.*s\n", ast_sip_session_get_name(session),
4455  status.code, (int) pj_strlen(&status.reason), pj_strbuf(&status.reason));
4456 
4457  AST_LIST_TRAVERSE(&session->supplements, supplement, next) {
4458  if (!(supplement->response_priority & response_priority)) {
4459  continue;
4460  }
4461  if (supplement->incoming_response && does_method_match(&rdata->msg_info.cseq->method.name, supplement->method)) {
4462  supplement->incoming_response(session, rdata);
4463  }
4464  }
4465 
4466  SCOPE_EXIT("%s\n", ast_sip_session_get_name(session));
4467 }
4468 
4469 static int handle_incoming(struct ast_sip_session *session, pjsip_rx_data *rdata,
4470  enum ast_sip_session_response_priority response_priority)
4471 {
4472  if (rdata->msg_info.msg->type == PJSIP_REQUEST_MSG) {
4473  handle_incoming_request(session, rdata);
4474  } else {
4475  handle_incoming_response(session, rdata, response_priority);
4476  }
4477 
4478  return 0;
4479 }
4480 
4481 static void handle_outgoing_request(struct ast_sip_session *session, pjsip_tx_data *tdata)
4482 {
4483  struct ast_sip_session_supplement *supplement;
4484  struct pjsip_request_line req = tdata->msg->line.req;
4485  SCOPE_ENTER(3, "%s: Method is %.*s\n", ast_sip_session_get_name(session),
4486  (int) pj_strlen(&req.method.name), pj_strbuf(&req.method.name));
4487 
4489 
4490  AST_LIST_TRAVERSE(&session->supplements, supplement, next) {
4491  if (supplement->outgoing_request && does_method_match(&req.method.name, supplement->method)) {
4492  supplement->outgoing_request(session, tdata);
4493  }
4494  }
4495  SCOPE_EXIT("%s\n", ast_sip_session_get_name(session));
4496 }
4497 
4498 static void handle_outgoing_response(struct ast_sip_session *session, pjsip_tx_data *tdata)
4499 {
4500  struct ast_sip_session_supplement *supplement;
4501  struct pjsip_status_line status = tdata->msg->line.status;
4502  pjsip_cseq_hdr *cseq = pjsip_msg_find_hdr(tdata->msg, PJSIP_H_CSEQ, NULL);
4503  SCOPE_ENTER(3, "%s: Method is %.*s, Response is %d %.*s\n", ast_sip_session_get_name(session),
4504  (int) pj_strlen(&cseq->method.name),
4505  pj_strbuf(&cseq->method.name), status.code, (int) pj_strlen(&status.reason),
4506  pj_strbuf(&status.reason));
4507 
4508 
4509  if (!cseq) {
4510  SCOPE_EXIT_LOG_RTN(LOG_ERROR, "%s: Cannot send response due to missing sequence header",
4511  ast_sip_session_get_name(session));
4512  }
4513 
4515 
4516  AST_LIST_TRAVERSE(&session->supplements, supplement, next) {
4517  if (supplement->outgoing_response && does_method_match(&cseq->method.name, supplement->method)) {
4518  supplement->outgoing_response(session, tdata);
4519  }
4520  }
4521 
4522  SCOPE_EXIT("%s\n", ast_sip_session_get_name(session));
4523 }
4524 
4525 static int session_end(void *vsession)
4526 {
4527  struct ast_sip_session *session = vsession;
4528 
4529  /* Stop the scheduled termination */
4531 
4532  /* Session is dead. Notify the supplements. */
4533  handle_session_end(session);
4534 
4535  return 0;
4536 }
4537 
4538 /*!
4539  * \internal
4540  * \brief Complete ending session activities.
4541  * \since 13.5.0
4542  *
4543  * \param vsession Which session to complete stopping.
4544  *
4545  * \retval 0 on success.
4546  * \retval -1 on error.
4547  */
4548 static int session_end_completion(void *vsession)
4549 {
4550  struct ast_sip_session *session = vsession;
4551 
4554 
4555  /* Now we can release the ref that was held by session->inv_session */
4556  ao2_cleanup(session);
4557  return 0;
4558 }
4559 
4560 static int check_request_status(pjsip_inv_session *inv, pjsip_event *e)
4561 {
4562  struct ast_sip_session *session = inv->mod_data[session_module.id];
4563  pjsip_transaction *tsx = e->body.tsx_state.tsx;
4564 
4565  if (tsx->status_code != 503 && tsx->status_code != 408) {
4566  return 0;
4567  }
4568 
4569  if (!ast_sip_failover_request(tsx->last_tx)) {
4570  return 0;
4571  }
4572 
4573  pjsip_inv_uac_restart(inv, PJ_FALSE);
4574  /*
4575  * Bump the ref since it will be on a new transaction and
4576  * we don't want it to go away along with the old transaction.
4577  */
4578  pjsip_tx_data_add_ref(tsx->last_tx);
4579  ast_sip_session_send_request(session, tsx->last_tx);
4580  return 1;
4581 }
4582 
4583 static void handle_incoming_before_media(pjsip_inv_session *inv,
4584  struct ast_sip_session *session, pjsip_rx_data *rdata)
4585 {
4586  pjsip_msg *msg;
4587  ast_debug(3, "%s: Received %s\n", ast_sip_session_get_name(session), rdata->msg_info.msg->type == PJSIP_REQUEST_MSG ?
4588  "request" : "response");
4589 
4590 
4592  msg = rdata->msg_info.msg;
4593  if (msg->type == PJSIP_REQUEST_MSG
4594  && msg->line.req.method.id == PJSIP_ACK_METHOD
4595  && pjmedia_sdp_neg_get_state(inv->neg) != PJMEDIA_SDP_NEG_STATE_DONE) {
4596  pjsip_tx_data *tdata;
4597 
4598  /*
4599  * SDP negotiation failed on an incoming call that delayed
4600  * negotiation and then gave us an invalid SDP answer. We
4601  * need to send a BYE to end the call because of the invalid
4602  * SDP answer.
4603  */
4604  ast_debug(1,
4605  "%s: Ending session due to incomplete SDP negotiation. %s\n",
4606  ast_sip_session_get_name(session),
4607  pjsip_rx_data_get_info(rdata));
4608  if (pjsip_inv_end_session(inv, 400, NULL, &tdata) == PJ_SUCCESS
4609  && tdata) {
4610  ast_sip_session_send_request(session, tdata);
4611  }
4612  }
4613 }
4614 
4615 static void session_inv_on_state_changed(pjsip_inv_session *inv, pjsip_event *e)
4616 {
4617  pjsip_event_id_e type;
4618  struct ast_sip_session *session = inv->mod_data[session_module.id];
4619  SCOPE_ENTER(1, "%s Event: %s Inv State: %s\n", ast_sip_session_get_name(session),
4620  pjsip_event_str(e->type), pjsip_inv_state_name(inv->state));
4621 
4622  if (ast_shutdown_final()) {
4623  SCOPE_EXIT_RTN("Shutting down\n");
4624  }
4625 
4626  if (e) {
4627  print_debug_details(inv, NULL, e);
4628  type = e->type;
4629  } else {
4630  type = PJSIP_EVENT_UNKNOWN;
4631  }
4632 
4633  session = inv->mod_data[session_module.id];
4634  if (!session) {
4635  SCOPE_EXIT_RTN("No session\n");
4636  }
4637 
4638  switch(type) {
4639  case PJSIP_EVENT_TX_MSG:
4640  break;
4641  case PJSIP_EVENT_RX_MSG:
4642  handle_incoming_before_media(inv, session, e->body.rx_msg.rdata);
4643  break;
4644  case PJSIP_EVENT_TSX_STATE:
4645  ast_debug(3, "%s: Source of transaction state change is %s\n", ast_sip_session_get_name(session),
4646  pjsip_event_str(e->body.tsx_state.type));
4647  /* Transaction state changes are prompted by some other underlying event. */
4648  switch(e->body.tsx_state.type) {
4649  case PJSIP_EVENT_TX_MSG:
4650  break;
4651  case PJSIP_EVENT_RX_MSG:
4652  if (!check_request_status(inv, e)) {
4653  handle_incoming_before_media(inv, session, e->body.tsx_state.src.rdata);
4654  }
4655  break;
4656  case PJSIP_EVENT_TRANSPORT_ERROR:
4657  case PJSIP_EVENT_TIMER:
4658  /*
4659  * Check the request status on transport error or timeout. A transport
4660  * error can occur when a TCP socket closes and that can be the result
4661  * of a 503. Also we may need to failover on a timeout (408).
4662  */
4663  check_request_status(inv, e);
4664  break;
4665  case PJSIP_EVENT_USER:
4666  case PJSIP_EVENT_UNKNOWN:
4667  case PJSIP_EVENT_TSX_STATE:
4668  /* Inception? */
4669  break;
4670  }
4671  break;
4672  case PJSIP_EVENT_TRANSPORT_ERROR:
4673  case PJSIP_EVENT_TIMER:
4674  case PJSIP_EVENT_UNKNOWN:
4675  case PJSIP_EVENT_USER:
4676  default:
4677  break;
4678  }
4679 
4680  if (inv->state == PJSIP_INV_STATE_DISCONNECTED) {
4681  if (session->defer_end) {
4682  ast_debug(3, "%s: Deferring session end\n", ast_sip_session_get_name(session));
4683  session->ended_while_deferred = 1;
4684  SCOPE_EXIT_RTN("Deferring\n");
4685  }
4686 
4687  if (ast_sip_push_task(session->serializer, session_end, session)) {
4688  /* Do it anyway even though this is not the right thread. */
4689  session_end(session);
4690  }
4691  }
4692 
4693  SCOPE_EXIT_RTN();
4694 }
4695 
4696 static void session_inv_on_new_session(pjsip_inv_session *inv, pjsip_event *e)
4697 {
4698  /* XXX STUB */
4699 }
4700 
4701 static int session_end_if_disconnected(int id, pjsip_inv_session *inv)
4702 {
4703  struct ast_sip_session *session;
4704 
4705  if (inv->state != PJSIP_INV_STATE_DISCONNECTED) {
4706  return 0;
4707  }
4708 
4709  /*
4710  * We are locking because ast_sip_dialog_get_session() needs
4711  * the dialog locked to get the session by other threads.
4712  */
4713  pjsip_dlg_inc_lock(inv->dlg);
4714  session = inv->mod_data[id];
4715  inv->mod_data[id] = NULL;
4716  pjsip_dlg_dec_lock(inv->dlg);
4717 
4718  /*
4719  * Pass the session ref held by session->inv_session to
4720  * session_end_completion().
4721  */
4722  if (session
4723  && ast_sip_push_task(session->serializer, session_end_completion, session)) {
4724  /* Do it anyway even though this is not the right thread. */
4725  session_end_completion(session);
4726  }
4727 
4728  return 1;
4729 }
4730 
4731 static void session_inv_on_tsx_state_changed(pjsip_inv_session *inv, pjsip_transaction *tsx, pjsip_event *e)
4732 {
4734  int id = session_module.id;
4735  pjsip_tx_data *tdata;
4736  struct ast_sip_session *session = inv->mod_data[session_module.id];
4737  SCOPE_ENTER(1, "%s TSX State: %s Inv State: %s\n", ast_sip_session_get_name(session),
4738  pjsip_tsx_state_str(tsx->state), pjsip_inv_state_name(inv->state));
4739 
4740  if (ast_shutdown_final()) {
4741  SCOPE_EXIT_RTN("Shutting down\n");
4742  }
4743 
4744  session = inv->mod_data[id];
4745 
4746  print_debug_details(inv, tsx, e);
4747  if (!session) {
4748  /* The session has ended. Ignore the transaction change. */
4749  SCOPE_EXIT_RTN("Session ended\n");
4750  }
4751 
4752  /*
4753  * If the session is disconnected really nothing else to do unless currently transacting
4754  * a BYE. If a BYE then hold off destruction until the transaction timeout occurs. This
4755  * has to be done for BYEs because sometimes the dialog can be in a disconnected
4756  * state but the BYE request transaction has not yet completed.
4757  */
4758  if (tsx->method.id != PJSIP_BYE_METHOD && session_end_if_disconnected(id, inv)) {
4759  SCOPE_EXIT_RTN("Disconnected\n");
4760  }
4761 
4762  switch (e->body.tsx_state.type) {
4763  case PJSIP_EVENT_TX_MSG:
4764  /* When we create an outgoing request, we do not have access to the transaction that
4765  * is created. Instead, We have to place transaction-specific data in the tdata. Here,
4766  * we transfer the data into the transaction. This way, when we receive a response, we
4767  * can dig this data out again
4768  */
4769  tsx->mod_data[id] = e->body.tsx_state.src.tdata->mod_data[id];
4770  break;
4771  case PJSIP_EVENT_RX_MSG:
4772  cb = ast_sip_mod_data_get(tsx->mod_data, id, MOD_DATA_ON_RESPONSE);
4773  /* As the PJSIP invite session implementation responds with a 200 OK before we have a
4774  * chance to be invoked session supplements for BYE requests actually end up executing
4775  * in the invite session state callback as well. To prevent session supplements from
4776  * running on the BYE request again we explicitly squash invocation of them here.
4777  */
4778  if ((e->body.tsx_state.src.rdata->msg_info.msg->type != PJSIP_REQUEST_MSG) ||
4779  (tsx->method.id != PJSIP_BYE_METHOD)) {
4780  handle_incoming(session, e->body.tsx_state.src.rdata,
4782  }
4783  if (tsx->method.id == PJSIP_INVITE_METHOD) {
4784  if (tsx->role == PJSIP_ROLE_UAC) {
4785  if (tsx->state == PJSIP_TSX_STATE_COMPLETED) {
4786  /* This means we got a non 2XX final response to our outgoing INVITE */
4787  if (tsx->status_code == PJSIP_SC_REQUEST_PENDING) {
4788  reschedule_reinvite(session, cb);
4789  SCOPE_EXIT_RTN("Non 2XX final response\n");
4790  }
4791  if (inv->state == PJSIP_INV_STATE_CONFIRMED) {
4792  ast_debug(1, "%s: reINVITE received final response code %d\n",
4793  ast_sip_session_get_name(session),
4794  tsx->status_code);
4795  if ((tsx->status_code == 401 || tsx->status_code == 407)
4798  &session->endpoint->outbound_auths,
4799  e->body.tsx_state.src.rdata, tsx->last_tx, &tdata)) {
4800  /* Send authed reINVITE */
4801  ast_sip_session_send_request_with_cb(session, tdata, cb);
4802  SCOPE_EXIT_RTN("Sending authed reinvite\n");
4803  }
4804  /* Per RFC3261 14.1 a response to a re-INVITE should only terminate
4805  * the dialog if a 481 or 408 occurs. All other responses should leave
4806  * the dialog untouched.
4807  */
4808  if (tsx->status_code == 481 || tsx->status_code == 408) {
4809  if (pjsip_inv_end_session(inv, 500, NULL, &tdata) == PJ_SUCCESS
4810  && tdata) {
4811  ast_sip_session_send_request(session, tdata);
4812  }
4813  }
4814  }
4815  } else if (tsx->state == PJSIP_TSX_STATE_TERMINATED) {
4816  if (!inv->cancelling
4817  && inv->role == PJSIP_ROLE_UAC
4818  && inv->state == PJSIP_INV_STATE_CONFIRMED
4819  && pjmedia_sdp_neg_was_answer_remote(inv->neg)
4820  && pjmedia_sdp_neg_get_state(inv->neg) == PJMEDIA_SDP_NEG_STATE_DONE
4822  ) {
4823  /*
4824  * We didn't send a CANCEL but the UAS sent us the 200 OK with an invalid or unacceptable codec SDP.
4825  * In this case the SDP negotiation is incomplete and PJPROJECT has already sent the ACK.
4826  * So, we send the BYE with 503 status code here. And the actual hangup cause code is already set
4827  * to AST_CAUSE_BEARERCAPABILITY_NOTAVAIL by the session_inv_on_media_update(), setting the 503
4828  * status code doesn't affect to hangup cause code.
4829  */
4830  ast_debug(1, "Endpoint '%s(%s)': Ending session due to 200 OK with incomplete SDP negotiation. %s\n",
4832  session->channel ? ast_channel_name(session->channel) : "",
4833  pjsip_rx_data_get_info(e->body.tsx_state.src.rdata));
4834  pjsip_inv_end_session(session->inv_session, 503, NULL, &tdata);
4835  SCOPE_EXIT_RTN("Incomplete SDP negotiation\n");
4836  }
4837 
4838  if (inv->cancelling && tsx->status_code == PJSIP_SC_OK) {
4839  int sdp_negotiation_done =
4840  pjmedia_sdp_neg_get_state(inv->neg) == PJMEDIA_SDP_NEG_STATE_DONE;
4841 
4842  /*
4843  * We can get here for the following reasons.
4844  *
4845  * 1) The race condition detailed in RFC5407 section 3.1.2.
4846  * We sent a CANCEL at the same time that the UAS sent us a
4847  * 200 OK with a valid SDP for the original INVITE. As a
4848  * result, we have now received a 200 OK for a cancelled
4849  * call and the SDP negotiation is complete. We need to
4850  * immediately send a BYE to end the dialog.
4851  *
4852  * 2) We sent a CANCEL and hit the race condition but the
4853  * UAS sent us an invalid SDP with the 200 OK. In this case
4854  * the SDP negotiation is incomplete and PJPROJECT has
4855  * already sent the BYE for us because of the invalid SDP.
4856  */
4857  ast_test_suite_event_notify("PJSIP_SESSION_CANCELED",
4858  "Endpoint: %s\r\n"
4859  "Channel: %s\r\n"
4860  "Message: %s\r\n"
4861  "SDP: %s",
4863  session->channel ? ast_channel_name(session->channel) : "",
4864  pjsip_rx_data_get_info(e->body.tsx_state.src.rdata),
4865  sdp_negotiation_done ? "complete" : "incomplete");
4866  if (!sdp_negotiation_done) {
4867  ast_debug(1, "%s: Incomplete SDP negotiation cancelled session. %s\n",
4868  ast_sip_session_get_name(session),
4869  pjsip_rx_data_get_info(e->body.tsx_state.src.rdata));
4870  } else if (pjsip_inv_end_session(inv, 500, NULL, &tdata) == PJ_SUCCESS
4871  && tdata) {
4872  ast_debug(1, "%s: Ending session due to RFC5407 race condition. %s\n",
4873  ast_sip_session_get_name(session),
4874  pjsip_rx_data_get_info(e->body.tsx_state.src.rdata));
4875  ast_sip_session_send_request(session, tdata);
4876  }
4877  }
4878  }
4879  }
4880  } else {
4881  /* All other methods */
4882  if (tsx->role == PJSIP_ROLE_UAC) {
4883  if (tsx->state == PJSIP_TSX_STATE_COMPLETED) {
4884  /* This means we got a final response to our outgoing method */
4885  ast_debug(1, "%s: %.*s received final response code %d\n",
4886  ast_sip_session_get_name(session),
4887  (int) pj_strlen(&tsx->method.name), pj_strbuf(&tsx->method.name),
4888  tsx->status_code);
4889  if ((tsx->status_code == 401 || tsx->status_code == 407)
4892  &session->endpoint->outbound_auths,
4893  e->body.tsx_state.src.rdata, tsx->last_tx, &tdata)) {
4894  /* Send authed version of the method */
4895  ast_sip_session_send_request_with_cb(session, tdata, cb);
4896  SCOPE_EXIT_RTN("Sending authed %.*s\n",
4897  (int) pj_strlen(&tsx->method.name), pj_strbuf(&tsx->method.name));
4898  }
4899  }
4900  }
4901  }
4902  if (cb) {
4903  cb(session, e->body.tsx_state.src.rdata);
4904  }
4905  break;
4906  case PJSIP_EVENT_TRANSPORT_ERROR:
4907  case PJSIP_EVENT_TIMER:
4908  /*
4909  * The timer event is run by the pjsip monitor thread and not
4910  * by the session serializer.
4911  */
4912  if (session_end_if_disconnected(id, inv)) {
4913  SCOPE_EXIT_RTN("Disconnected\n");
4914  }
4915  break;
4916  case PJSIP_EVENT_USER:
4917  case PJSIP_EVENT_UNKNOWN:
4918  case PJSIP_EVENT_TSX_STATE:
4919  /* Inception? */
4920  break;
4921  }
4922 
4923  if (AST_LIST_EMPTY(&session->delayed_requests)) {
4924  /* No delayed request pending, so just return */
4925  SCOPE_EXIT_RTN("Nothing delayed\n");
4926  }
4927 
4928  if (tsx->method.id == PJSIP_INVITE_METHOD) {
4929  if (tsx->state == PJSIP_TSX_STATE_PROCEEDING) {
4930  ast_debug(3, "%s: INVITE delay check. tsx-state:%s\n",
4931  ast_sip_session_get_name(session),
4932  pjsip_tsx_state_str(tsx->state));
4934  } else if (tsx->state == PJSIP_TSX_STATE_TERMINATED) {
4935  /*
4936  * Terminated INVITE transactions always should result in
4937  * queuing delayed requests, no matter what event caused
4938  * the transaction to terminate.
4939  */
4940  ast_debug(3, "%s: INVITE delay check. tsx-state:%s\n",
4941  ast_sip_session_get_name(session),
4942  pjsip_tsx_state_str(tsx->state));
4944  }
4945  } else if (tsx->role == PJSIP_ROLE_UAC
4946  && tsx->state == PJSIP_TSX_STATE_COMPLETED
4947  && !pj_strcmp2(&tsx->method.name, "UPDATE")) {
4948  ast_debug(3, "%s: UPDATE delay check. tsx-state:%s\n",
4949  ast_sip_session_get_name(session),
4950  pjsip_tsx_state_str(tsx->state));
4952  }
4953 
4954  SCOPE_EXIT_RTN();
4955 }
4956 
4957 static int add_sdp_streams(struct ast_sip_session_media *session_media,
4958  struct ast_sip_session *session, pjmedia_sdp_session *answer,
4959  const struct pjmedia_sdp_session *remote,
4960  struct ast_stream *stream)
4961 {
4962  struct ast_sip_session_sdp_handler *handler = session_media->handler;
4963  RAII_VAR(struct sdp_handler_list *, handler_list, NULL, ao2_cleanup);
4964  int res = 0;
4965  SCOPE_ENTER(1, "%s Stream: %s\n", ast_sip_session_get_name(session),
4966  ast_str_tmp(128, ast_stream_to_str(stream, &STR_TMP)));
4967 
4968  if (handler) {
4969  /* if an already assigned handler reports a catastrophic error, fail */
4970  res = handler->create_outgoing_sdp_stream(session, session_media, answer, remote, stream);
4971  if (res < 0) {
4972  SCOPE_EXIT_RTN_VALUE(-1, "Coudn't create sdp stream\n");
4973  }
4974  SCOPE_EXIT_RTN_VALUE(0, "Had handler\n");
4975  }
4976 
4977  handler_list = ao2_find(sdp_handlers, ast_codec_media_type2str(session_media->type), OBJ_KEY);
4978  if (!handler_list) {
4979  SCOPE_EXIT_RTN_VALUE(0, "No handlers\n");
4980  }
4981 
4982  /* no handler for this stream type and we have a list to search */
4983  AST_LIST_TRAVERSE(&handler_list->list, handler, next) {
4984  if (handler == session_media->handler) {
4985  continue;
4986  }
4987  res = handler->create_outgoing_sdp_stream(session, session_media, answer, remote, stream);
4988  if (res < 0) {
4989  /* catastrophic error */
4990  SCOPE_EXIT_RTN_VALUE(-1, "Coudn't create sdp stream\n");
4991  }
4992  if (res > 0) {
4993  /* Handled by this handler. Move to the next stream */
4994  session_media_set_handler(session_media, handler);
4995  SCOPE_EXIT_RTN_VALUE(0, "Handled\n");
4996  }
4997  }
4998 
4999  /* streams that weren't handled won't be included in generated outbound SDP */
5000  SCOPE_EXIT_RTN_VALUE(0, "Not handled\n");
5001 }
5002 
5003 /*! \brief Bundle group building structure */
5005  /*! \brief The media identifiers in this bundle group */
5006  char *mids[PJMEDIA_MAX_SDP_MEDIA];
5007  /*! \brief SDP attribute string */
5009 };
5010 
5011 static int add_bundle_groups(struct ast_sip_session *session, pj_pool_t *pool, pjmedia_sdp_session *answer)
5012 {
5013  pj_str_t stmp;
5014  pjmedia_sdp_attr *attr;
5015  struct sip_session_media_bundle_group bundle_groups[PJMEDIA_MAX_SDP_MEDIA];
5016  int index, mid_id;
5017  struct sip_session_media_bundle_group *bundle_group;
5018 
5019  if (session->endpoint->media.webrtc) {
5020  attr = pjmedia_sdp_attr_create(pool, "msid-semantic", pj_cstr(&stmp, "WMS *"));
5021  pjmedia_sdp_attr_add(&answer->attr_count, answer->attr, attr);
5022  }
5023 
5024  if (!session->endpoint->media.bundle) {
5025  return 0;
5026  }
5027 
5028  memset(bundle_groups, 0, sizeof(bundle_groups));
5029 
5030  /* Build the bundle group layout so we can then add it to the SDP */
5031  for (index = 0; index < AST_VECTOR_SIZE(&session->pending_media_state->sessions); ++index) {
5032  struct ast_sip_session_media *session_media = AST_VECTOR_GET(&session->pending_media_state->sessions, index);
5033 
5034  /* If this stream is not part of a bundle group we can't add it */
5035  if (session_media->bundle_group == -1) {
5036  continue;
5037  }
5038 
5039  bundle_group = &bundle_groups[session_media->bundle_group];
5040 
5041  /* If this is the first mid then we need to allocate the attribute string and place BUNDLE in front */
5042  if (!bundle_group->mids[0]) {
5043  bundle_group->mids[0] = session_media->mid;
5044  bundle_group->attr_string = ast_str_create(64);
5045  if (!bundle_group->attr_string) {
5046  continue;
5047  }
5048 
5049  ast_str_set(&bundle_group->attr_string, 0, "BUNDLE %s", session_media->mid);
5050  continue;
5051  }
5052 
5053  for (mid_id = 1; mid_id < PJMEDIA_MAX_SDP_MEDIA; ++mid_id) {
5054  if (!bundle_group->mids[mid_id]) {
5055  bundle_group->mids[mid_id] = session_media->mid;
5056  ast_str_append(&bundle_group->attr_string, 0, " %s", session_media->mid);
5057  break;
5058  } else if (!strcmp(bundle_group->mids[mid_id], session_media->mid)) {
5059  break;
5060  }
5061  }
5062  }
5063 
5064  /* Add all bundle groups that have mids to the SDP */
5065  for (index = 0; index < PJMEDIA_MAX_SDP_MEDIA; ++index) {
5066  bundle_group = &bundle_groups[index];
5067 
5068  if (!bundle_group->attr_string) {
5069  continue;
5070  }
5071 
5072  attr = pjmedia_sdp_attr_create(pool, "group", pj_cstr(&stmp, ast_str_buffer(bundle_group->attr_string)));
5073  pjmedia_sdp_attr_add(&answer->attr_count, answer->attr, attr);
5074 
5075  ast_free(bundle_group->attr_string);
5076  }
5077 
5078  return 0;
5079 }
5080 
5081 static struct pjmedia_sdp_session *create_local_sdp(pjsip_inv_session *inv, struct ast_sip_session *session, const pjmedia_sdp_session *offer)
5082 {
5083  static const pj_str_t STR_IN = { "IN", 2 };
5084  static const pj_str_t STR_IP4 = { "IP4", 3 };
5085  static const pj_str_t STR_IP6 = { "IP6", 3 };
5086  pjmedia_sdp_session *local;
5087  int i;
5088  int stream;
5089  SCOPE_ENTER(3, "%s\n", ast_sip_session_get_name(session));
5090 
5091  if (inv->state == PJSIP_INV_STATE_DISCONNECTED) {
5092  SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR, "%s: Failed to create session SDP. Session has been already disconnected\n",
5093  ast_sip_session_get_name(session));
5094  }
5095 
5096  if (!inv->pool_prov || !(local = PJ_POOL_ZALLOC_T(inv->pool_prov, pjmedia_sdp_session))) {
5097  SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR, "%s: Pool allocation failure\n", ast_sip_session_get_name(session));
5098  }
5099 
5100  if (!offer) {
5101  local->origin.version = local->origin.id = (pj_uint32_t)(ast_random());
5102  } else {
5103  local->origin.version = offer->origin.version + 1;
5104  local->origin.id = offer->origin.id;
5105  }
5106 
5107  pj_strdup2(inv->pool_prov, &local->origin.user, session->endpoint->media.sdpowner);
5108  pj_strdup2(inv->pool_prov, &local->name, session->endpoint->media.sdpsession);
5109 
5111  /* We've encountered a situation where we have been told to create a local SDP but noone has given us any indication
5112  * of what kind of stream topology they would like. We try to not alter the current state of the SDP negotiation
5113  * by using what is currently negotiated. If this is unavailable we fall back to what is configured on the endpoint.
5114  */
5116  if (session->active_media_state->topology) {
5118  } else {
5120  }
5121  if (!session->pending_media_state->topology) {
5122  SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR, "%s: No pending media state topology\n", ast_sip_session_get_name(session));
5123  }
5124  }
5125 
5126  ast_trace(-1, "%s: Processing streams\n", ast_sip_session_get_name(session));
5127 
5128  for (i = 0; i < ast_stream_topology_get_count(session->pending_media_state->topology); ++i) {
5129  struct ast_sip_session_media *session_media;
5131  unsigned int streams = local->media_count;
5132  SCOPE_ENTER(4, "%s: Processing stream %s\n", ast_sip_session_get_name(session),
5133  ast_str_tmp(128, ast_stream_to_str(stream, &STR_TMP)));
5134 
5135  /* This code does not enforce any maximum stream count limitations as that is done on either
5136  * the handling of an incoming SDP offer or on the handling of a session refresh.
5137  */
5138 
5139  session_media = ast_sip_session_media_state_add(session, session->pending_media_state, ast_stream_get_type(stream), i);
5140  if (!session_media) {
5141  local = NULL;
5142  SCOPE_EXIT_LOG_EXPR(goto end, LOG_ERROR, "%s: Couldn't alloc/add session media for stream %s\n",
5143  ast_sip_session_get_name(session), ast_str_tmp(128, ast_stream_to_str(stream, &STR_TMP)));
5144  }
5145 
5146  if (add_sdp_streams(session_media, session, local, offer, stream)) {
5147  local = NULL;
5148  SCOPE_EXIT_LOG_EXPR(goto end, LOG_ERROR, "%s: Couldn't add sdp streams for stream %s\n",
5149  ast_sip_session_get_name(session), ast_str_tmp(128, ast_stream_to_str(stream, &STR_TMP)));
5150  }
5151 
5152  /* If a stream was actually added then add any additional details */
5153  if (streams != local->media_count) {
5154  pjmedia_sdp_media *media = local->media[streams];
5155  pj_str_t stmp;
5156  pjmedia_sdp_attr *attr;
5157 
5158  /* Add the media identifier if present */
5159  if (!ast_strlen_zero(session_media->mid)) {
5160  attr = pjmedia_sdp_attr_create(inv->pool_prov, "mid", pj_cstr(&stmp, session_media->mid));
5161  pjmedia_sdp_attr_add(&media->attr_count, media->attr, attr);
5162  }
5163 
5164  ast_trace(-1, "%s: Stream %s added%s%s\n", ast_sip_session_get_name(session),
5165  ast_str_tmp(128, ast_stream_to_str(stream, &STR_TMP)),
5166  S_COR(!ast_strlen_zero(session_media->mid), " with mid ", ""), S_OR(session_media->mid, ""));
5167 
5168  }
5169 
5170  /* Ensure that we never exceed the maximum number of streams PJMEDIA will allow. */
5171  if (local->media_count == PJMEDIA_MAX_SDP_MEDIA) {
5172  SCOPE_EXIT_EXPR(break, "%s: Stream %s exceeded max pjmedia count of %d\n",
5173  ast_sip_session_get_name(session), ast_str_tmp(128, ast_stream_to_str(stream, &STR_TMP)),
5174  PJMEDIA_MAX_SDP_MEDIA);
5175  }
5176 
5177  SCOPE_EXIT("%s: Done with %s\n", ast_sip_session_get_name(session),
5178  ast_str_tmp(128, ast_stream_to_str(stream, &STR_TMP)));
5179 
5180  }
5181 
5182  /* Add any bundle groups that are present on the media state */
5183  ast_trace(-1, "%s: Adding bundle groups (if available)\n", ast_sip_session_get_name(session));
5184  if (add_bundle_groups(session, inv->pool_prov, local)) {
5185  SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR, "%s: Couldn't add bundle groups\n", ast_sip_session_get_name(session));
5186  }
5187 
5188  /* Use the connection details of an available media if possible for SDP level */
5189  ast_trace(-1, "%s: Copying connection details\n", ast_sip_session_get_name(session));
5190 
5191  for (stream = 0; stream < local->media_count; stream++) {
5192  SCOPE_ENTER(4, "%s: Processing media %d\n", ast_sip_session_get_name(session), stream);
5193  if (!local->media[stream]->conn) {
5194  SCOPE_EXIT_EXPR(continue, "%s: Media %d has no connection info\n", ast_sip_session_get_name(session), stream);
5195  }
5196 
5197  if (local->conn) {
5198  if (!pj_strcmp(&local->conn->net_type, &local->media[stream]->conn->net_type) &&
5199  !pj_strcmp(&local->conn->addr_type, &local->media[stream]->conn->addr_type) &&
5200  !pj_strcmp(&local->conn->addr, &local->media[stream]->conn->addr)) {
5201  local->media[stream]->conn = NULL;
5202  }
5203  SCOPE_EXIT_EXPR(continue, "%s: Media %d has good existing connection info\n", ast_sip_session_get_name(session), stream);
5204  }
5205 
5206  /* This stream's connection info will serve as the connection details for SDP level */
5207  local->conn = local->media[stream]->conn;
5208  local->media[stream]->conn = NULL;
5209 
5210  SCOPE_EXIT_EXPR(continue, "%s: Media %d reset\n", ast_sip_session_get_name(session), stream);
5211  }
5212 
5213  /* If no SDP level connection details are present then create some */
5214  if (!local->conn) {
5215  ast_trace(-1, "%s: Creating connection details\n", ast_sip_session_get_name(session));
5216 
5217  local->conn = pj_pool_zalloc(inv->pool_prov, sizeof(struct pjmedia_sdp_conn));
5218  local->conn->net_type = STR_IN;
5219  local->conn->addr_type = session->endpoint->media.rtp.ipv6 ? STR_IP6 : STR_IP4;
5220 
5221  if (!ast_strlen_zero(session->endpoint->media.address)) {
5222  pj_strdup2(inv->pool_prov, &local->conn->addr, session->endpoint->media.address);
5223  } else {
5224  pj_strdup2(inv->pool_prov, &local->conn->addr, ast_sip_get_host_ip_string(session->endpoint->media.rtp.ipv6 ? pj_AF_INET6() : pj_AF_INET()));
5225  }
5226  }
5227 
5228  pj_strassign(&local->origin.net_type, &local->conn->net_type);
5229  pj_strassign(&local->origin.addr_type, &local->conn->addr_type);
5230  pj_strassign(&local->origin.addr, &local->conn->addr);
5231 
5232 end:
5233  SCOPE_EXIT_RTN_VALUE(local, "%s\n", ast_sip_session_get_name(session));
5234 }
5235 
5236 static void session_inv_on_rx_offer(pjsip_inv_session *inv, const pjmedia_sdp_session *offer)
5237 {
5238  struct ast_sip_session *session = inv->mod_data[session_module.id];
5239  pjmedia_sdp_session *answer;
5240  SCOPE_ENTER(3, "%s\n", ast_sip_session_get_name(session));
5241 
5242  if (ast_shutdown_final()) {
5243  SCOPE_EXIT_RTN("%s: Shutdown in progress\n", ast_sip_session_get_name(session));
5244  }
5245 
5246  session = inv->mod_data[session_module.id];
5247  if (handle_incoming_sdp(session, offer)) {
5249  SCOPE_EXIT_RTN("%s: handle_incoming_sdp failed\n", ast_sip_session_get_name(session));
5250  }
5251 
5252  if ((answer = create_local_sdp(inv, session, offer))) {
5253  pjsip_inv_set_sdp_answer(inv, answer);
5254  SCOPE_EXIT_RTN("%s: Set SDP answer\n", ast_sip_session_get_name(session));
5255  }
5256  SCOPE_EXIT_RTN("%s: create_local_sdp failed\n", ast_sip_session_get_name(session));
5257 }
5258 
5259 static void session_inv_on_create_offer(pjsip_inv_session *inv, pjmedia_sdp_session **p_offer)
5260 {
5261  struct ast_sip_session *session = inv->mod_data[session_module.id];
5262  const pjmedia_sdp_session *previous_sdp = NULL;
5263  pjmedia_sdp_session *offer;
5264  int i;
5265 
5266  if (inv->neg) {
5267  if (pjmedia_sdp_neg_was_answer_remote(inv->neg)) {
5268  pjmedia_sdp_neg_get_active_remote(inv->neg, &previous_sdp);
5269  } else {
5270  pjmedia_sdp_neg_get_active_local(inv->neg, &previous_sdp);
5271  }
5272  }
5273 
5274  offer = create_local_sdp(inv, session, previous_sdp);
5275  if (!offer) {
5276  return;
5277  }
5278 
5279  ast_queue_unhold(session->channel);
5280 
5281  /*
5282  * Some devices indicate hold with deferred SDP reinvites (i.e. no SDP in the reinvite).
5283  * When hold is initially indicated, we
5284  * - Receive an INVITE with no SDP
5285  * - Send a 200 OK with SDP, indicating sendrecv in the media streams
5286  * - Receive an ACK with SDP, indicating sendonly in the media streams
5287  *
5288  * At this point, the pjmedia negotiator saves the state of the media direction so that
5289  * if we are to send any offers, we'll offer recvonly in the media streams. This is
5290  * problematic if the device is attempting to unhold, though. If the device unholds
5291  * by sending a reinvite with no SDP, then we will respond with a 200 OK with recvonly.
5292  * According to RFC 3264, if an offerer offers recvonly, then the answerer MUST respond
5293  * with sendonly or inactive. The result of this is that the stream is not off hold.
5294  *
5295  * Therefore, in this case, when we receive a reinvite while the stream is on hold, we
5296  * need to be sure to offer sendrecv. This way, the answerer can respond with sendrecv
5297  * in order to get the stream off hold. If this is actually a different purpose reinvite
5298  * (like a session timer refresh), then the answerer can respond to our sendrecv with
5299  * sendonly, keeping the stream on hold.
5300  */
5301  for (i = 0; i < offer->media_count; ++i) {
5302  pjmedia_sdp_media *m = offer->media[i];
5303  pjmedia_sdp_attr *recvonly;
5304  pjmedia_sdp_attr *inactive;
5305  pjmedia_sdp_attr *sendonly;
5306 
5307  recvonly = pjmedia_sdp_attr_find2(m->attr_count, m->attr, "recvonly", NULL);
5308  inactive = pjmedia_sdp_attr_find2(m->attr_count, m->attr, "inactive", NULL);
5309  sendonly = pjmedia_sdp_attr_find2(m->attr_count, m->attr, "sendonly", NULL);
5310  if (recvonly || inactive || sendonly) {
5311  pjmedia_sdp_attr *to_remove = recvonly ?: inactive ?: sendonly;
5312  pjmedia_sdp_attr *sendrecv;
5313 
5314  pjmedia_sdp_attr_remove(&m->attr_count, m->attr, to_remove);
5315 
5316  sendrecv = pjmedia_sdp_attr_create(session->inv_session->pool, "sendrecv", NULL);
5317  pjmedia_sdp_media_add_attr(m, sendrecv);
5318  }
5319  }
5320 
5321  *p_offer = offer;
5322 }
5323 
5324 static void session_inv_on_media_update(pjsip_inv_session *inv, pj_status_t status)
5325 {
5326  struct ast_sip_session *session = inv->mod_data[session_module.id];
5327  const pjmedia_sdp_session *local, *remote;
5328  SCOPE_ENTER(3, "%s\n", ast_sip_session_get_name(session));
5329 
5330  if (ast_shutdown_final()) {
5331  SCOPE_EXIT_RTN("%s: Shutdown in progress\n", ast_sip_session_get_name(session));
5332  }
5333 
5334  session = inv->mod_data[session_module.id];
5335  if (!session || !session->channel) {
5336  /*
5337  * If we don't have a session or channel then we really
5338  * don't care about media updates.
5339  * Just ignore
5340  */
5341  SCOPE_EXIT_RTN("%s: No channel or session\n", ast_sip_session_get_name(session));
5342  }
5343 
5344  if (session->endpoint) {
5345  int bail = 0;
5346 
5347  /*
5348  * If following_fork is set, then this is probably the result of a
5349  * forked INVITE and SDP asnwers coming from the different fork UAS
5350  * destinations. In this case updated_sdp_answer will also be set.
5351  *
5352  * If only updated_sdp_answer is set, then this is the non-forking
5353  * scenario where the same UAS just needs to change something like
5354  * the media port.
5355  */
5356 
5357  if (inv->following_fork) {
5358  if (session->endpoint->media.rtp.follow_early_media_fork) {
5359  ast_trace(-1, "%s: Following early media fork with different To tags\n", ast_sip_session_get_name(session));
5360  } else {
5361  ast_trace(-1, "%s: Not following early media fork with different To tags\n", ast_sip_session_get_name(session));
5362  bail = 1;
5363  }
5364  }
5365 #ifdef HAVE_PJSIP_INV_ACCEPT_MULTIPLE_SDP_ANSWERS
5366  else if (inv->updated_sdp_answer) {
5368  ast_trace(-1, "%s: Accepting updated SDP with same To tag\n", ast_sip_session_get_name(session));
5369  } else {
5370  ast_trace(-1, "%s: Ignoring updated SDP answer with same To tag\n", ast_sip_session_get_name(session));
5371  bail = 1;
5372  }
5373  }
5374 #endif
5375  if (bail) {
5376  SCOPE_EXIT_RTN("%s: Bailing\n", ast_sip_session_get_name(session));
5377  }
5378  }
5379 
5380  if ((status != PJ_SUCCESS) || (pjmedia_sdp_neg_get_active_local(inv->neg, &local) != PJ_SUCCESS) ||
5381  (pjmedia_sdp_neg_get_active_remote(inv->neg, &remote) != PJ_SUCCESS)) {
5383  ast_set_hangupsource(session->channel, ast_channel_name(session->channel), 0);
5384  ast_queue_hangup(session->channel);
5385  SCOPE_EXIT_RTN("%s: Couldn't get active or local or remote negotiator. Hanging up\n", ast_sip_session_get_name(session));
5386  }
5387 
5388  if (handle_negotiated_sdp(session, local, remote)) {
5390  SCOPE_EXIT_RTN("%s: handle_negotiated_sdp failed. Resetting pending media state\n", ast_sip_session_get_name(session));
5391  }
5392  SCOPE_EXIT_RTN("%s\n", ast_sip_session_get_name(session));
5393 }
5394 
5395 static pjsip_redirect_op session_inv_on_redirected(pjsip_inv_session *inv, const pjsip_uri *target, const pjsip_event *e)
5396 {
5397  struct ast_sip_session *session;
5398  const pjsip_sip_uri *uri;
5399 
5400  if (ast_shutdown_final()) {
5401  return PJSIP_REDIRECT_STOP;
5402  }
5403 
5404  session = inv->mod_data[session_module.id];
5405  if (!session || !session->channel) {
5406  return PJSIP_REDIRECT_STOP;
5407  }
5408 
5410  return PJSIP_REDIRECT_ACCEPT;
5411  }
5412 
5413  if (!PJSIP_URI_SCHEME_IS_SIP(target) && !PJSIP_URI_SCHEME_IS_SIPS(target)) {
5414  return PJSIP_REDIRECT_STOP;
5415  }
5416 
5417  handle_incoming(session, e->body.rx_msg.rdata, AST_SIP_SESSION_BEFORE_REDIRECTING);
5418 
5419  uri = pjsip_uri_get_uri(target);
5420 
5421  if (session->endpoint->redirect_method == AST_SIP_REDIRECT_USER) {
5422  char exten[AST_MAX_EXTENSION];
5423 
5424  ast_copy_pj_str(exten, &uri->user, sizeof(exten));
5425 
5426  /*
5427  * We may want to match in the dialplan without any user
5428  * options getting in the way.
5429  */
5431 
5432  ast_channel_call_forward_set(session->channel, exten);
5433  } else if (session->endpoint->redirect_method == AST_SIP_REDIRECT_URI_CORE) {
5434  char target_uri[PJSIP_MAX_URL_SIZE];
5435  /* PJSIP/ + endpoint length + / + max URL size */
5436  char forward[8 + strlen(ast_sorcery_object_get_id(session->endpoint)) + PJSIP_MAX_URL_SIZE];
5437 
5438  pjsip_uri_print(PJSIP_URI_IN_REQ_URI, uri, target_uri, sizeof(target_uri));
5439  sprintf(forward, "PJSIP/%s/%s", ast_sorcery_object_get_id(session->endpoint), target_uri);
5440  ast_channel_call_forward_set(session->channel, forward);
5441  }
5442 
5443  return PJSIP_REDIRECT_STOP;
5444 }
5445 
5446 static pjsip_inv_callback inv_callback = {
5447  .on_state_changed = session_inv_on_state_changed,
5448  .on_new_session = session_inv_on_new_session,
5449  .on_tsx_state_changed = session_inv_on_tsx_state_changed,
5450  .on_rx_offer = session_inv_on_rx_offer,
5451  .on_create_offer = session_inv_on_create_offer,
5452  .on_media_update = session_inv_on_media_update,
5453  .on_redirected = session_inv_on_redirected,
5454 };
5455 
5456 /*! \brief Hook for modifying outgoing messages with SDP to contain the proper address information */
5457 static void session_outgoing_nat_hook(pjsip_tx_data *tdata, struct ast_sip_transport *transport)
5458 {
5460  struct ast_sip_nat_hook *hook = ast_sip_mod_data_get(
5461  tdata->mod_data, session_module.id, MOD_DATA_NAT_HOOK);
5462  struct pjmedia_sdp_session *sdp;
5463  pjsip_dialog *dlg = pjsip_tdata_get_dlg(tdata);
5464  RAII_VAR(struct ast_sip_session *, session, dlg ? ast_sip_dialog_get_session(dlg) : NULL, ao2_cleanup);
5465  int stream;
5466 
5467  /* SDP produced by us directly will never be multipart */
5468  if (!transport_state || hook || !tdata->msg->body ||
5469  !ast_sip_is_content_type(&tdata->msg->body->content_type, "application", "sdp") ||
5471  return;
5472  }
5473 
5474  sdp = tdata->msg->body->data;
5475 
5476  if (sdp->conn) {
5477  char host[NI_MAXHOST];
5478  struct ast_sockaddr our_sdp_addr = { { 0, } };
5479 
5480  ast_copy_pj_str(host, &sdp->conn->addr, sizeof(host));
5481  ast_sockaddr_parse(&our_sdp_addr, host, PARSE_PORT_FORBID);
5482 
5483  /* Reversed check here. We don't check the remote
5484  * endpoint being in our local net, but whether our
5485  * outgoing session IP is local. If it is, we'll do
5486  * rewriting. No localnet configured? Always rewrite. */
5487  if (ast_sip_transport_is_local(transport_state, &our_sdp_addr) || !transport_state->localnet) {
5488  ast_debug(5, "%s: Setting external media address to %s\n", ast_sip_session_get_name(session),
5489  ast_sockaddr_stringify_host(&transport_state->external_media_address));
5490  pj_strdup2(tdata->pool, &sdp->conn->addr, ast_sockaddr_stringify_host(&transport_state->external_media_address));
5491  pj_strassign(&sdp->origin.addr, &sdp->conn->addr);
5492  }
5493  }
5494 
5495  for (stream = 0; stream < sdp->media_count; ++stream) {
5496  /* See if there are registered handlers for this media stream type */
5497  char media[20];
5499  RAII_VAR(struct sdp_handler_list *, handler_list, NULL, ao2_cleanup);
5500 
5501  /* We need a null-terminated version of the media string */
5502  ast_copy_pj_str(media, &sdp->media[stream]->desc.media, sizeof(media));
5503 
5504  handler_list = ao2_find(sdp_handlers, media, OBJ_KEY);
5505  if (!handler_list) {
5506  ast_debug(4, "%s: No registered SDP handlers for media type '%s'\n", ast_sip_session_get_name(session),
5507  media);
5508  continue;
5509  }
5510  AST_LIST_TRAVERSE(&handler_list->list, handler, next) {
5512  handler->change_outgoing_sdp_stream_media_address(tdata, sdp->media[stream], transport);
5513  }
5514  }
5515  }
5516 
5517  /* We purposely do this so that the hook will not be invoked multiple times, ie: if a retransmit occurs */
5518  ast_sip_mod_data_set(tdata->pool, tdata->mod_data, session_module.id, MOD_DATA_NAT_HOOK, nat_hook);
5519 }
5520 
5521 #ifdef TEST_FRAMEWORK
5522 
5524 {
5525  struct ast_stream *stream;
5526 
5527  stream = ast_stream_alloc(name, type);
5528  if (!stream) {
5529  return NULL;
5530  }
5531  ast_stream_set_state(stream, state);
5532 
5533  return stream;
5534 }
5535 
5537  struct ast_sip_session_media_state *media_state, const char *name, enum ast_media_type type,
5538  enum ast_stream_state state, int position)
5539 {
5540  struct ast_sip_session_media *session_media = NULL;
5541  struct ast_stream *stream = NULL;
5542 
5543  stream = test_stream_alloc(name, type, state);
5544  if (!stream) {
5545  return NULL;
5546  }
5547 
5548  if (position >= 0 && position < ast_stream_topology_get_count(media_state->topology)) {
5549  ast_stream_topology_set_stream(media_state->topology, position, stream);
5550  } else {
5551  position = ast_stream_topology_append_stream(media_state->topology, stream);
5552  }
5553 
5554  session_media = ao2_alloc_options(sizeof(*session_media), session_media_dtor, AO2_ALLOC_OPT_LOCK_NOLOCK);
5555  if (!session_media) {
5556  return NULL;
5557  }
5558 
5559  session_media->keepalive_sched_id = -1;
5560  session_media->timeout_sched_id = -1;
5561  session_media->type = type;
5562  session_media->stream_num = position;
5563  session_media->bundle_group = -1;
5564  strcpy(session_media->label, name);
5565 
5566  if (AST_VECTOR_REPLACE(&media_state->sessions, position, session_media)) {
5567  ao2_ref(session_media, -1);
5568 
5569  return NULL;
5570  }
5571 
5572  /* If this stream will be active in some way and it is the first of this type then consider this the default media session to match */
5573  if (!media_state->default_session[type] && ast_stream_get_state(ast_stream_topology_get_stream(media_state->topology, position)) != AST_STREAM_STATE_REMOVED) {
5574  media_state->default_session[type] = session_media;
5575  }
5576 
5577  return session_media;
5578 }
5579 
5581 {
5582  if (left == right) {
5583  return 1;
5584  }
5585 
5586  if (!left) {
5587  return 1;
5588  }
5589 
5590  if (!right) {
5591  return 0;
5592  }
5593  return memcmp(left, right, sizeof(*left)) == 0;
5594 }
5595 
5597  int assert_on_failure)
5598 {
5599  int i;
5600  SCOPE_ENTER(2);
5601 
5602  if (left == right) {
5603  SCOPE_EXIT_RTN_VALUE(1, "equal\n");
5604  }
5605 
5606  if (!(left && right)) {
5607  ast_assert(!assert_on_failure);
5608  SCOPE_EXIT_RTN_VALUE(0, "one is null: left: %p right: %p\n", left, right);
5609  }
5610 
5611  if (!ast_stream_topology_equal(left->topology, right->topology)) {
5612  ast_assert(!assert_on_failure);
5613  SCOPE_EXIT_RTN_VALUE(0, "topologies differ\n");
5614  }
5615  if (AST_VECTOR_SIZE(&left->sessions) != AST_VECTOR_SIZE(&right->sessions)) {
5616  ast_assert(!assert_on_failure);
5617  SCOPE_EXIT_RTN_VALUE(0, "session vector sizes different: left %zu != right %zu\n",
5618  AST_VECTOR_SIZE(&left->sessions),
5619  AST_VECTOR_SIZE(&right->sessions));
5620  }
5621  if (AST_VECTOR_SIZE(&left->read_callbacks) != AST_VECTOR_SIZE(&right->read_callbacks)) {
5622  ast_assert(!assert_on_failure);
5623  SCOPE_EXIT_RTN_VALUE(0, "read_callback vector sizes different: left %zu != right %zu\n",
5624  AST_VECTOR_SIZE(&left->read_callbacks),
5625  AST_VECTOR_SIZE(&right->read_callbacks));
5626  }
5627 
5628  for (i = 0; i < AST_VECTOR_SIZE(&left->sessions) ; i++) {
5629  if (!test_is_media_session_equal(AST_VECTOR_GET(&left->sessions, i), AST_VECTOR_GET(&right->sessions, i))) {
5630  ast_assert(!assert_on_failure);
5631  SCOPE_EXIT_RTN_VALUE(0, "Media session %d different\n", i);
5632  }
5633  }
5634 
5635  for (i = 0; i < AST_VECTOR_SIZE(&left->read_callbacks) ; i++) {
5636  if (memcmp(AST_VECTOR_GET_ADDR(&left->read_callbacks, i),
5637  AST_VECTOR_GET_ADDR(&right->read_callbacks, i),
5638  sizeof(struct ast_sip_session_media_read_callback_state)) != 0) {
5639  ast_assert(!assert_on_failure);
5640  SCOPE_EXIT_RTN_VALUE(0, "read_callback %d different\n", i);
5641  }
5642  }
5643 
5644  for (i = 0; i < AST_MEDIA_TYPE_END; i++) {
5645  if (!(left->default_session[i] && right->default_session[i])) {
5646  continue;
5647  }
5648  if (!left->default_session[i] || !right->default_session[i]
5649  || left->default_session[i]->stream_num != right->default_session[i]->stream_num) {
5650  ast_assert(!assert_on_failure);
5651  SCOPE_EXIT_RTN_VALUE(0, "Default media session %d different. Left: %s Right: %s\n", i,
5652  left->default_session[i] ? left->default_session[i]->label : "null",
5653  right->default_session[i] ? right->default_session[i]->label : "null");
5654  }
5655  }
5656 
5657  SCOPE_EXIT_RTN_VALUE(1, "equal\n");
5658 }
5659 
5660 AST_TEST_DEFINE(test_resolve_refresh_media_states)
5661 {
5662 #define FREE_STATE() \
5663 ({ \
5664  ast_sip_session_media_state_free(new_pending_state); \
5665  new_pending_state = NULL; \
5666  ast_sip_session_media_state_free(delayed_pending_state); \
5667  delayed_pending_state = NULL; \
5668  ast_sip_session_media_state_free(delayed_active_state); \
5669  delayed_active_state = NULL; \
5670  ast_sip_session_media_state_free(current_active_state); \
5671  current_active_state = NULL; \
5672  ast_sip_session_media_state_free(expected_pending_state); \
5673  expected_pending_state = NULL; \
5674 })
5675 
5676 #define RESET_STATE(__num) \
5677 ({ \
5678  testnum=__num; \
5679  ast_trace(-1, "Test %d\n", testnum); \
5680  test_failed = 0; \
5681  delayed_pending_state = ast_sip_session_media_state_alloc(); \
5682  delayed_pending_state->topology = ast_stream_topology_alloc(); \
5683  delayed_active_state = ast_sip_session_media_state_alloc(); \
5684  delayed_active_state->topology = ast_stream_topology_alloc(); \
5685  current_active_state = ast_sip_session_media_state_alloc(); \
5686  current_active_state->topology = ast_stream_topology_alloc(); \
5687  expected_pending_state = ast_sip_session_media_state_alloc(); \
5688  expected_pending_state->topology = ast_stream_topology_alloc(); \
5689 })
5690 
5691 #define CHECKER() \
5692 ({ \
5693  new_pending_state = resolve_refresh_media_states("unittest", delayed_pending_state, delayed_active_state, current_active_state, 1); \
5694  if (!test_is_media_state_equal(new_pending_state, expected_pending_state, 0)) { \
5695  res = AST_TEST_FAIL; \
5696  test_failed = 1; \
5697  ast_test_status_update(test, "da: %s\n", ast_str_tmp(256, ast_stream_topology_to_str(delayed_active_state->topology, &STR_TMP))); \
5698  ast_test_status_update(test, "dp: %s\n", ast_str_tmp(256, ast_stream_topology_to_str(delayed_pending_state->topology, &STR_TMP))); \
5699  ast_test_status_update(test, "ca: %s\n", ast_str_tmp(256, ast_stream_topology_to_str(current_active_state->topology, &STR_TMP))); \
5700  ast_test_status_update(test, "ep: %s\n", ast_str_tmp(256, ast_stream_topology_to_str(expected_pending_state->topology, &STR_TMP))); \
5701  ast_test_status_update(test, "np: %s\n", ast_str_tmp(256, ast_stream_topology_to_str(new_pending_state->topology, &STR_TMP))); \
5702  } \
5703  ast_test_status_update(test, "Test %d %s\n", testnum, test_failed ? "FAILED" : "passed"); \
5704  ast_trace(-1, "Test %d %s\n", testnum, test_failed ? "FAILED" : "passed"); \
5705  test_failed = 0; \
5706  FREE_STATE(); \
5707 })
5708 
5709 
5710  struct ast_sip_session_media_state * delayed_pending_state = NULL;
5711  struct ast_sip_session_media_state * delayed_active_state = NULL;
5712  struct ast_sip_session_media_state * current_active_state = NULL;
5713  struct ast_sip_session_media_state * new_pending_state = NULL;
5714  struct ast_sip_session_media_state * expected_pending_state = NULL;
5716  int test_failed = 0;
5717  int testnum = 0;
5718  SCOPE_ENTER(1);
5719 
5720  switch (cmd) {
5721  case TEST_INIT:
5722  info->name = "merge_refresh_topologies";
5723  info->category = "/res/res_pjsip_session/";
5724  info->summary = "Test merging of delayed request topologies";
5725  info->description = "Test merging of delayed request topologies";
5727  case TEST_EXECUTE:
5728  break;
5729  }
5730 
5731  RESET_STATE(1);
5732  test_media_add(delayed_active_state, "audio", AST_MEDIA_TYPE_AUDIO, AST_STREAM_STATE_SENDRECV, -1);
5733  test_media_add(delayed_active_state, "myvideo1", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5734  test_media_add(delayed_active_state, "myvideo2", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5735 
5736  test_media_add(delayed_pending_state, "audio", AST_MEDIA_TYPE_AUDIO, AST_STREAM_STATE_SENDRECV, -1);
5737  test_media_add(delayed_pending_state, "myvideo1", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5738  test_media_add(delayed_pending_state, "myvideo2", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5739  test_media_add(delayed_pending_state, "myvideo3", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5740 
5741  test_media_add(current_active_state, "audio", AST_MEDIA_TYPE_AUDIO, AST_STREAM_STATE_SENDRECV, -1);
5742  test_media_add(current_active_state, "myvideo1", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5743  test_media_add(current_active_state, "myvideo2", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5744 
5745  test_media_add(expected_pending_state, "audio", AST_MEDIA_TYPE_AUDIO, AST_STREAM_STATE_SENDRECV, -1);
5746  test_media_add(expected_pending_state, "myvideo1", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5747  test_media_add(expected_pending_state, "myvideo2", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5748  test_media_add(expected_pending_state, "myvideo3", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5749  CHECKER();
5750 
5751  RESET_STATE(2);
5752  test_media_add(delayed_active_state, "audio", AST_MEDIA_TYPE_AUDIO, AST_STREAM_STATE_SENDRECV, -1);
5753  test_media_add(delayed_active_state, "myvideo1", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5754  test_media_add(delayed_active_state, "myvideo2", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5755 
5756  test_media_add(delayed_pending_state, "audio", AST_MEDIA_TYPE_AUDIO, AST_STREAM_STATE_SENDRECV, -1);
5757  test_media_add(delayed_pending_state, "myvideo1", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5758  test_media_add(delayed_pending_state, "myvideo2", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5759  test_media_add(delayed_pending_state, "myvideo3", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5760 
5761  test_media_add(current_active_state, "audio", AST_MEDIA_TYPE_AUDIO, AST_STREAM_STATE_SENDRECV, -1);
5762  test_media_add(current_active_state, "myvideo1", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5763  test_media_add(current_active_state, "myvideo2", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5764 
5765  test_media_add(expected_pending_state, "audio", AST_MEDIA_TYPE_AUDIO, AST_STREAM_STATE_SENDRECV, -1);
5766  test_media_add(expected_pending_state, "myvideo1", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5767  test_media_add(expected_pending_state, "myvideo2", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5768  test_media_add(expected_pending_state, "myvideo3", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5769  CHECKER();
5770 
5771  RESET_STATE(3);
5772  test_media_add(delayed_active_state, "audio", AST_MEDIA_TYPE_AUDIO, AST_STREAM_STATE_SENDRECV, -1);
5773  test_media_add(delayed_active_state, "myvideo1", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5774  test_media_add(delayed_active_state, "myvideo2", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5775 
5776  test_media_add(delayed_pending_state, "audio", AST_MEDIA_TYPE_AUDIO, AST_STREAM_STATE_SENDRECV, -1);
5777  test_media_add(delayed_pending_state, "myvideo1", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5778  test_media_add(delayed_pending_state, "myvideo2", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5779  test_media_add(delayed_pending_state, "myvideo3", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5780 
5781  test_media_add(current_active_state, "audio", AST_MEDIA_TYPE_AUDIO, AST_STREAM_STATE_SENDRECV, -1);
5782  test_media_add(current_active_state, "myvideo1", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5783  test_media_add(current_active_state, "myvideo2", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5784  test_media_add(current_active_state, "myvideo4", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5785  test_media_add(current_active_state, "myvideo5", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5786 
5787  test_media_add(expected_pending_state, "audio", AST_MEDIA_TYPE_AUDIO, AST_STREAM_STATE_SENDRECV, -1);
5788  test_media_add(expected_pending_state, "myvideo1", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5789  test_media_add(expected_pending_state, "myvideo2", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5790  test_media_add(expected_pending_state, "myvideo4", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5791  test_media_add(expected_pending_state, "myvideo5", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5792  test_media_add(expected_pending_state, "myvideo3", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5793  CHECKER();
5794 
5795  RESET_STATE(4);
5796  test_media_add(delayed_active_state, "audio", AST_MEDIA_TYPE_AUDIO, AST_STREAM_STATE_SENDRECV, -1);
5797  test_media_add(delayed_active_state, "myvideo1", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5798  test_media_add(delayed_active_state, "myvideo2", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5799 
5800  test_media_add(delayed_pending_state, "audio", AST_MEDIA_TYPE_AUDIO, AST_STREAM_STATE_SENDRECV, -1);
5801  test_media_add(delayed_pending_state, "myvideo1", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5802  test_media_add(delayed_pending_state, "myvideo2", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5803  test_media_add(delayed_pending_state, "myvideo3", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5804 
5805  test_media_add(current_active_state, "audio", AST_MEDIA_TYPE_AUDIO, AST_STREAM_STATE_SENDRECV, -1);
5806  test_media_add(current_active_state, "myvideo1", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5807  test_media_add(current_active_state, "myvideo2", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_REMOVED, -1);
5808 
5809  test_media_add(expected_pending_state, "audio", AST_MEDIA_TYPE_AUDIO, AST_STREAM_STATE_SENDRECV, -1);
5810  test_media_add(expected_pending_state, "myvideo1", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5811  test_media_add(expected_pending_state, "myvideo3", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5812  CHECKER();
5813 
5814  RESET_STATE(5);
5815  test_media_add(delayed_active_state, "audio", AST_MEDIA_TYPE_AUDIO, AST_STREAM_STATE_SENDRECV, -1);
5816  test_media_add(delayed_active_state, "myvideo1", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5817  test_media_add(delayed_active_state, "myvideo2", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5818 
5819  test_media_add(delayed_pending_state, "audio", AST_MEDIA_TYPE_AUDIO, AST_STREAM_STATE_SENDRECV, -1);
5820  test_media_add(delayed_pending_state, "myvideo1", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5821  test_media_add(delayed_pending_state, "myvideo2", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_REMOVED, -1);
5822 
5823  test_media_add(current_active_state, "audio", AST_MEDIA_TYPE_AUDIO, AST_STREAM_STATE_SENDRECV, -1);
5824  test_media_add(current_active_state, "myvideo1", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5825  test_media_add(current_active_state, "myvideo2", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_REMOVED, -1);
5826 
5827  test_media_add(expected_pending_state, "audio", AST_MEDIA_TYPE_AUDIO, AST_STREAM_STATE_SENDRECV, -1);
5828  test_media_add(expected_pending_state, "myvideo1", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5829  test_media_add(expected_pending_state, "myvideo2", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_REMOVED, -1);
5830  CHECKER();
5831 
5832  RESET_STATE(6);
5833  test_media_add(delayed_active_state, "audio", AST_MEDIA_TYPE_AUDIO, AST_STREAM_STATE_SENDRECV, -1);
5834  test_media_add(delayed_active_state, "myvideo1", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5835  test_media_add(delayed_active_state, "myvideo2", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5836 
5837  test_media_add(delayed_pending_state, "audio", AST_MEDIA_TYPE_AUDIO, AST_STREAM_STATE_SENDRECV, -1);
5838  test_media_add(delayed_pending_state, "myvideo1", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5839  test_media_add(delayed_pending_state, "myvideo2", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5840  test_media_add(delayed_pending_state, "myvideo3", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5841 
5842  test_media_add(current_active_state, "audio", AST_MEDIA_TYPE_AUDIO, AST_STREAM_STATE_SENDRECV, -1);
5843  test_media_add(current_active_state, "myvideo1", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5844  test_media_add(current_active_state, "myvideo2", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_REMOVED, -1);
5845  test_media_add(current_active_state, "myvideo4", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5846 
5847  test_media_add(expected_pending_state, "audio", AST_MEDIA_TYPE_AUDIO, AST_STREAM_STATE_SENDRECV, -1);
5848  test_media_add(expected_pending_state, "myvideo1", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5849  test_media_add(expected_pending_state, "myvideo3", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5850  test_media_add(expected_pending_state, "myvideo4", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5851  CHECKER();
5852 
5853  RESET_STATE(7);
5854  test_media_add(delayed_active_state, "audio", AST_MEDIA_TYPE_AUDIO, AST_STREAM_STATE_SENDRECV, -1);
5855  test_media_add(delayed_active_state, "myvideo1", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5856  test_media_add(delayed_active_state, "myvideo2", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5857 
5858  test_media_add(delayed_pending_state, "audio", AST_MEDIA_TYPE_AUDIO, AST_STREAM_STATE_SENDRECV, -1);
5859  test_media_add(delayed_pending_state, "myvideo1", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5860  test_media_add(delayed_pending_state, "myvideo2", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5861  test_media_add(delayed_pending_state, "myvideo3", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5862  test_media_add(delayed_pending_state, "myvideo4", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5863 
5864  test_media_add(current_active_state, "audio", AST_MEDIA_TYPE_AUDIO, AST_STREAM_STATE_SENDRECV, -1);
5865  test_media_add(current_active_state, "myvideo1", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5866  test_media_add(current_active_state, "myvideo2", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5867  test_media_add(current_active_state, "myvideo5", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5868  test_media_add(current_active_state, "myvideo6", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5869 
5870  test_media_add(expected_pending_state, "audio", AST_MEDIA_TYPE_AUDIO, AST_STREAM_STATE_SENDRECV, -1);
5871  test_media_add(expected_pending_state, "myvideo1", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5872  test_media_add(expected_pending_state, "myvideo2", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5873  test_media_add(expected_pending_state, "myvideo5", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5874  test_media_add(expected_pending_state, "myvideo6", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5875  test_media_add(expected_pending_state, "myvideo3", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5876  test_media_add(expected_pending_state, "myvideo4", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5877  CHECKER();
5878 
5879  RESET_STATE(8);
5880  test_media_add(delayed_active_state, "audio", AST_MEDIA_TYPE_AUDIO, AST_STREAM_STATE_SENDRECV, -1);
5881  test_media_add(delayed_active_state, "myvideo1", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5882  test_media_add(delayed_active_state, "myvideo2", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5883 
5884  test_media_add(delayed_pending_state, "audio", AST_MEDIA_TYPE_AUDIO, AST_STREAM_STATE_SENDRECV, -1);
5885  test_media_add(delayed_pending_state, "myvideo1", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5886  test_media_add(delayed_pending_state, "myvideo2", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5887  test_media_add(delayed_pending_state, "myvideo3", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5888  test_media_add(delayed_pending_state, "myvideo4", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5889 
5890  test_media_add(current_active_state, "audio", AST_MEDIA_TYPE_AUDIO, AST_STREAM_STATE_SENDRECV, -1);
5891  test_media_add(current_active_state, "myvideo1", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5892  test_media_add(current_active_state, "myvideo2", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_REMOVED, -1);
5893 
5894  test_media_add(expected_pending_state, "audio", AST_MEDIA_TYPE_AUDIO, AST_STREAM_STATE_SENDRECV, -1);
5895  test_media_add(expected_pending_state, "myvideo1", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5896  test_media_add(expected_pending_state, "myvideo3", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5897  test_media_add(expected_pending_state, "myvideo4", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5898  CHECKER();
5899 
5900  RESET_STATE(9);
5901  test_media_add(delayed_active_state, "audio", AST_MEDIA_TYPE_AUDIO, AST_STREAM_STATE_SENDRECV, -1);
5902  test_media_add(delayed_active_state, "myvideo1", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5903  test_media_add(delayed_active_state, "myvideo2", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5904 
5905  test_media_add(delayed_pending_state, "audio", AST_MEDIA_TYPE_AUDIO, AST_STREAM_STATE_SENDRECV, -1);
5906  test_media_add(delayed_pending_state, "myvideo1", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5907  test_media_add(delayed_pending_state, "myvideo2", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5908  test_media_add(delayed_pending_state, "myvideo3", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5909  test_media_add(delayed_pending_state, "myvideo4", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5910 
5911  test_media_add(current_active_state, "audio", AST_MEDIA_TYPE_AUDIO, AST_STREAM_STATE_SENDRECV, -1);
5912  test_media_add(current_active_state, "myvideo1", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_REMOVED, -1);
5913  test_media_add(current_active_state, "myvideo2", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_REMOVED, -1);
5914 
5915  test_media_add(expected_pending_state, "audio", AST_MEDIA_TYPE_AUDIO, AST_STREAM_STATE_SENDRECV, -1);
5916  test_media_add(expected_pending_state, "myvideo3", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5917  test_media_add(expected_pending_state, "myvideo4", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5918  CHECKER();
5919 
5920  RESET_STATE(10);
5921  test_media_add(delayed_active_state, "audio", AST_MEDIA_TYPE_AUDIO, AST_STREAM_STATE_SENDRECV, -1);
5922  test_media_add(delayed_active_state, "myvideo1", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5923  test_media_add(delayed_active_state, "myvideo2", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5924 
5925  test_media_add(delayed_pending_state, "audio", AST_MEDIA_TYPE_AUDIO, AST_STREAM_STATE_SENDRECV, -1);
5926  test_media_add(delayed_pending_state, "myvideo1", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_REMOVED, -1);
5927  test_media_add(delayed_pending_state, "myvideo2", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_REMOVED, -1);
5928 
5929  test_media_add(current_active_state, "audio", AST_MEDIA_TYPE_AUDIO, AST_STREAM_STATE_SENDRECV, -1);
5930  test_media_add(current_active_state, "myvideo1", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5931  test_media_add(current_active_state, "myvideo2", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5932  test_media_add(current_active_state, "myvideo3", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5933 
5934  test_media_add(expected_pending_state, "audio", AST_MEDIA_TYPE_AUDIO, AST_STREAM_STATE_SENDRECV, -1);
5935  test_media_add(expected_pending_state, "myvideo1", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_REMOVED, -1);
5936  test_media_add(expected_pending_state, "myvideo2", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_REMOVED, -1);
5937  test_media_add(expected_pending_state, "myvideo3", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5938  CHECKER();
5939 
5940  RESET_STATE(11);
5941  test_media_add(delayed_active_state, "audio", AST_MEDIA_TYPE_AUDIO, AST_STREAM_STATE_SENDRECV, -1);
5942  test_media_add(delayed_active_state, "myvideo1", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5943  test_media_add(delayed_active_state, "myvideo2", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5944  test_media_add(delayed_active_state, "myvideo4", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5945 
5946  test_media_add(delayed_pending_state, "audio", AST_MEDIA_TYPE_AUDIO, AST_STREAM_STATE_SENDRECV, -1);
5947  test_media_add(delayed_pending_state, "myvideo1", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5948  test_media_add(delayed_pending_state, "myvideo2", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5949  test_media_add(delayed_pending_state, "myvideo3", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5950 
5951  test_media_add(current_active_state, "audio", AST_MEDIA_TYPE_AUDIO, AST_STREAM_STATE_SENDRECV, -1);
5952  test_media_add(current_active_state, "myvideo1", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5953  test_media_add(current_active_state, "myvideo2", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5954  test_media_add(current_active_state, "myvideo4", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5955 
5956  test_media_add(expected_pending_state, "audio", AST_MEDIA_TYPE_AUDIO, AST_STREAM_STATE_SENDRECV, -1);
5957  test_media_add(expected_pending_state, "myvideo1", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5958  test_media_add(expected_pending_state, "myvideo2", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5959  test_media_add(expected_pending_state, "myvideo4", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5960  test_media_add(expected_pending_state, "myvideo3", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5961  CHECKER();
5962 
5963  RESET_STATE(12);
5964  test_media_add(delayed_active_state, "audio", AST_MEDIA_TYPE_AUDIO, AST_STREAM_STATE_SENDRECV, -1);
5965  test_media_add(delayed_active_state, "292-1", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5966  test_media_add(delayed_active_state, "296-2", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5967 
5968  test_media_add(delayed_pending_state, "audio", AST_MEDIA_TYPE_AUDIO, AST_STREAM_STATE_SENDRECV, -1);
5969  test_media_add(delayed_pending_state, "292-1", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5970  test_media_add(delayed_pending_state, "296-2", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5971  test_media_add(delayed_pending_state, "297-4", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5972  test_media_add(delayed_pending_state, "294-5", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5973 
5974  test_media_add(current_active_state, "audio", AST_MEDIA_TYPE_AUDIO, AST_STREAM_STATE_SENDRECV, -1);
5975  test_media_add(current_active_state, "292-1", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5976  test_media_add(current_active_state, "296-2", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5977  test_media_add(current_active_state, "290-3", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5978  test_media_add(current_active_state, "297-4", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5979 
5980  test_media_add(expected_pending_state, "audio", AST_MEDIA_TYPE_AUDIO, AST_STREAM_STATE_SENDRECV, -1);
5981  test_media_add(expected_pending_state, "292-1", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5982  test_media_add(expected_pending_state, "296-2", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5983  test_media_add(expected_pending_state, "290-3", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5984  test_media_add(expected_pending_state, "297-4", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5985  test_media_add(expected_pending_state, "294-5", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5986  CHECKER();
5987 
5988  RESET_STATE(13);
5989  test_media_add(delayed_active_state, "audio", AST_MEDIA_TYPE_AUDIO, AST_STREAM_STATE_SENDRECV, -1);
5990  test_media_add(delayed_active_state, "293-1", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5991  test_media_add(delayed_active_state, "292-2", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5992  test_media_add(delayed_active_state, "294-3", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5993  test_media_add(delayed_active_state, "295-4", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5994  test_media_add(delayed_active_state, "296-5", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5995 
5996  test_media_add(delayed_pending_state, "audio", AST_MEDIA_TYPE_AUDIO, AST_STREAM_STATE_SENDRECV, -1);
5997  test_media_add(delayed_pending_state, "293-1", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5998  test_media_add(delayed_pending_state, "292-2", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
5999  test_media_add(delayed_pending_state, "294-3", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
6000  test_media_add(delayed_pending_state, "295-4", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
6001  test_media_add(delayed_pending_state, "296-5", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
6002  test_media_add(delayed_pending_state, "298-7", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
6003 
6004  test_media_add(current_active_state, "audio", AST_MEDIA_TYPE_AUDIO, AST_STREAM_STATE_SENDRECV, -1);
6005  test_media_add(current_active_state, "293-1", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
6006  test_media_add(current_active_state, "292-2", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
6007  test_media_add(current_active_state, "294-3", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
6008  test_media_add(current_active_state, "295-4", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
6009  test_media_add(current_active_state, "296-5", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
6010  test_media_add(current_active_state, "290-6", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
6011 
6012  test_media_add(expected_pending_state, "audio", AST_MEDIA_TYPE_AUDIO, AST_STREAM_STATE_SENDRECV, -1);
6013  test_media_add(expected_pending_state, "293-1", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
6014  test_media_add(expected_pending_state, "292-2", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
6015  test_media_add(expected_pending_state, "294-3", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
6016  test_media_add(expected_pending_state, "295-4", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
6017  test_media_add(expected_pending_state, "296-5", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
6018  test_media_add(expected_pending_state, "290-6", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
6019  test_media_add(expected_pending_state, "298-7", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
6020  CHECKER();
6021 
6022  RESET_STATE(14);
6023  test_media_add(delayed_active_state, "audio", AST_MEDIA_TYPE_AUDIO, AST_STREAM_STATE_SENDRECV, -1);
6024  test_media_add(delayed_active_state, "298-1", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
6025  test_media_add(delayed_active_state, "297-2", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
6026 
6027  test_media_add(delayed_pending_state, "audio", AST_MEDIA_TYPE_AUDIO, AST_STREAM_STATE_SENDRECV, -1);
6028  test_media_add(delayed_pending_state, "298-1", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
6029  test_media_add(delayed_pending_state, "294-4", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
6030  test_media_add(delayed_pending_state, "295-5", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
6031 
6032  test_media_add(current_active_state, "audio", AST_MEDIA_TYPE_AUDIO, AST_STREAM_STATE_SENDRECV, -1);
6033  test_media_add(current_active_state, "298-1", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
6034  test_media_add(current_active_state, "297-2", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
6035  test_media_add(current_active_state, "291-3", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
6036  test_media_add(current_active_state, "294-4", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
6037 
6038  test_media_add(expected_pending_state, "audio", AST_MEDIA_TYPE_AUDIO, AST_STREAM_STATE_SENDRECV, -1);
6039  test_media_add(expected_pending_state, "298-1", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
6040  test_media_add(expected_pending_state, "297-2", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
6041  test_media_add(expected_pending_state, "291-3", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
6042  test_media_add(expected_pending_state, "294-4", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
6043  test_media_add(expected_pending_state, "295-5", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
6044  CHECKER();
6045 
6046  RESET_STATE(15);
6047  test_media_add(delayed_active_state, "audio", AST_MEDIA_TYPE_AUDIO, AST_STREAM_STATE_SENDRECV, -1);
6048  test_media_add(delayed_active_state, "298-1", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
6049  test_media_add(delayed_active_state, "297-2", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
6050 
6051  test_media_add(delayed_pending_state, "audio", AST_MEDIA_TYPE_AUDIO, AST_STREAM_STATE_SENDRECV, -1);
6052  test_media_add(delayed_pending_state, "298-1", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDONLY, -1);
6053  test_media_add(delayed_pending_state, "294-4", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
6054  test_media_add(delayed_pending_state, "295-5", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
6055 
6056  test_media_add(current_active_state, "audio", AST_MEDIA_TYPE_AUDIO, AST_STREAM_STATE_SENDRECV, -1);
6057  test_media_add(current_active_state, "297-2", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
6058  test_media_add(current_active_state, "291-3", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
6059  test_media_add(current_active_state, "294-4", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
6060  test_media_add(current_active_state, "298-1", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
6061 
6062  test_media_add(expected_pending_state, "audio", AST_MEDIA_TYPE_AUDIO, AST_STREAM_STATE_SENDRECV, -1);
6063  test_media_add(expected_pending_state, "297-2", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
6064  test_media_add(expected_pending_state, "291-3", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
6065  test_media_add(expected_pending_state, "294-4", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
6066  test_media_add(expected_pending_state, "298-1", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDONLY, -1);
6067  test_media_add(expected_pending_state, "295-5", AST_MEDIA_TYPE_VIDEO, AST_STREAM_STATE_SENDRECV, -1);
6068  CHECKER();
6069 
6070  SCOPE_EXIT_RTN_VALUE(res);
6071 }
6072 #endif /* TEST_FRAMEWORK */
6073 
6074 static int load_module(void)
6075 {
6076  pjsip_endpoint *endpt;
6077 
6079  return AST_MODULE_LOAD_DECLINE;
6080  }
6081  if (!(nat_hook = ast_sorcery_alloc(ast_sip_get_sorcery(), "nat_hook", NULL))) {
6082  return AST_MODULE_LOAD_DECLINE;
6083  }
6088  if (!sdp_handlers) {
6089  return AST_MODULE_LOAD_DECLINE;
6090  }
6091  endpt = ast_sip_get_pjsip_endpoint();
6092  pjsip_inv_usage_init(endpt, &inv_callback);
6093  pjsip_100rel_init_module(endpt);
6094  pjsip_timer_init_module(endpt);
6095  if (ast_sip_register_service(&session_module)) {
6096  return AST_MODULE_LOAD_DECLINE;
6097  }
6098  ast_sip_register_service(&session_reinvite_module);
6099  ast_sip_register_service(&outbound_invite_auth_module);
6100 
6102 #ifdef TEST_FRAMEWORK
6103  AST_TEST_REGISTER(test_resolve_refresh_media_states);
6104 #endif
6105  return AST_MODULE_LOAD_SUCCESS;
6106 }
6107 
6108 static int unload_module(void)
6109 {
6110 #ifdef TEST_FRAMEWORK
6111  AST_TEST_UNREGISTER(test_resolve_refresh_media_states);
6112 #endif
6113  ast_sip_unregister_service(&outbound_invite_auth_module);
6114  ast_sip_unregister_service(&session_reinvite_module);
6115  ast_sip_unregister_service(&session_module);
6117  ao2_cleanup(nat_hook);
6118  ao2_cleanup(sdp_handlers);
6119  return 0;
6120 }
6121 
6123  .support_level = AST_MODULE_SUPPORT_CORE,
6124  .load = load_module,
6125  .unload = unload_module,
6126  .load_pri = AST_MODPRI_APP_DEPEND,
6127  .requires = "res_pjsip",
6128 );
ast_sip_session_response_priority
Describes when a supplement should be called into on incoming responses.
#define AST_VECTOR_FREE(vec)
Deallocates this vector.
Definition: vector.h:174
void ast_sip_session_suspend(struct ast_sip_session *session)
Request and wait for the session serializer to be suspended.
unsigned int defer_end
int ast_queue_hangup(struct ast_channel *chan)
Queue a hangup frame.
Definition: channel.c:1150
#define SCOPE_EXIT_LOG_RTN_VALUE(__value, __log_level,...)
Definition: logger.h:940
static const char type[]
Definition: chan_ooh323.c:109
Information needed to identify an endpoint in a call.
Definition: channel.h:339
#define AST_SOCKADDR_BUFLEN
Definition: netsock2.h:46
static int set_mid_and_bundle_group(struct ast_sip_session *session, struct ast_sip_session_media *session_media, const pjmedia_sdp_session *sdp, const struct pjmedia_sdp_media *stream)
#define ast_channel_lock(chan)
Definition: channel.h:2945
static char exten[AST_MAX_EXTENSION]
Definition: chan_alsa.c:118
struct ast_sip_endpoint * endpoint
struct ast_sip_session * ast_sip_session_alloc(struct ast_sip_endpoint *endpoint, struct ast_sip_contact *contact, pjsip_inv_session *inv_session, pjsip_rx_data *rdata)
Allocate a new SIP session.
static pjsip_module session_reinvite_module
#define AST_SIP_USER_OPTIONS_TRUNCATE_CHECK(str)
Truncate the URI user field options string if enabled.
Definition: res_pjsip.h:3036
const char * ast_stream_to_str(const struct ast_stream *stream, struct ast_str **buf)
Get a string representing the stream for debugging/display purposes.
Definition: stream.c:337
enum ast_sip_dtmf_mode dtmf
Definition: res_pjsip.h:857
ast_sip_session_sdp_creation_cb on_sdp_creation
char * str
Subscriber phone number (Malloced)
Definition: channel.h:292
static int load_module(void)
void ast_taskprocessor_build_name(char *buf, unsigned int size, const char *format,...)
Build a taskprocessor name with a sequence number on the end.
#define SDP_HANDLER_BUCKETS
static int unload_module(void)
void ast_sip_add_usereqphone(const struct ast_sip_endpoint *endpoint, pj_pool_t *pool, pjsip_uri *uri)
Add &#39;user=phone&#39; parameter to URI if enabled and user is a phone number.
Definition: res_pjsip.c:3994
struct ast_frame *(* ast_sip_session_media_read_cb)(struct ast_sip_session *session, struct ast_sip_session_media *session_media)
Asterisk locking-related definitions:
unsigned int sess_expires
Definition: res_pjsip.h:567
Asterisk main include file. File version handling, generic pbx functions.
Structure which contains media state information (streams, sessions)
static pj_bool_t session_on_rx_response(pjsip_rx_data *rdata)
void ast_channel_internal_fd_clear(struct ast_channel *chan, int which)
static void reschedule_reinvite(struct ast_sip_session *session, ast_sip_session_response_cb on_response)
const ast_string_field fromuser
Definition: res_pjsip.h:829
A SIP address of record.
Definition: res_pjsip.h:361
int(* ast_sip_session_response_cb)(struct ast_sip_session *session, pjsip_rx_data *rdata)
void(* stream_destroy)(struct ast_sip_session_media *session_media)
Destroy a session_media created by this handler.
void ast_sip_session_defer_termination_cancel(struct ast_sip_session *session)
Cancel a pending deferred termination.
static int is_media_state_valid(const char *session_name, struct ast_sip_session_media_state *state)
struct ast_features_pickup_config * ast_get_chan_features_pickup_config(struct ast_channel *chan)
Get the pickup configuration options for a channel.
struct ast_sip_session * ast_sip_dialog_get_session(pjsip_dialog *dlg)
Retrieves a session from a dialog.
int ast_sip_session_defer_termination(struct ast_sip_session *session)
Defer local termination of a session until remote side terminates, or an amount of time passes...
int(* ast_sip_session_request_creation_cb)(struct ast_sip_session *session, pjsip_tx_data *tdata)
#define print_debug_details(inv, tsx, e)
Bundle group building structure.
static void session_outgoing_nat_hook(pjsip_tx_data *tdata, struct ast_sip_transport *transport)
Hook for modifying outgoing messages with SDP to contain the proper address information.
struct ast_sip_session_media_state * pending_media_state
int(* ast_sip_session_media_write_cb)(struct ast_sip_session *session, struct ast_sip_session_media *session_media, struct ast_frame *frame)
struct ast_sip_session_media_state * pending_media_state
static int session_end_completion(void *vsession)
#define AST_UUID_STR_LEN
Definition: uuid.h:27
CallerID (and other GR30) management and generation Includes code and algorithms from the Zapata libr...
#define STREAM_REMOVED(_stream)
int ast_rtp_instance_get_stats(struct ast_rtp_instance *instance, struct ast_rtp_instance_stats *stats, enum ast_rtp_instance_stat stat)
Retrieve statistics about an RTP instance.
Definition: rtp_engine.c:2446
int ast_sockaddr_parse(struct ast_sockaddr *addr, const char *str, int flags)
Parse an IPv4 or IPv6 address string.
Definition: netsock2.c:230
static pjsip_inv_callback inv_callback
void ast_sip_session_send_response(struct ast_sip_session *session, pjsip_tx_data *tdata)
Send a SIP response.
#define AST_VECTOR_REMOVE_CMP_UNORDERED(vec, value, cmp, cleanup)
Remove an element from a vector that matches the given comparison.
Definition: vector.h:488
static int send_delayed_request(struct ast_sip_session *session, struct ast_sip_session_delayed_request *delay)
pjsip_uri * request_uri
static int handle_incoming_sdp(struct ast_sip_session *session, const pjmedia_sdp_session *sdp)
#define STATE_NONE(_stream_state)
static const pjsip_method message_method
Definition: res_pjsip.c:4332
const ast_string_field transport
Definition: res_pjsip.h:817
#define OBJ_KEY
Definition: astobj2.h:1155
void ast_dsp_free(struct ast_dsp *dsp)
Definition: dsp.c:1770
#define DSP_FEATURE_DIGIT_DETECT
Definition: dsp.h:28
static pjsip_inv_session * pre_session_setup(pjsip_rx_data *rdata, const struct ast_sip_endpoint *endpoint)
static int is_stream_limitation_reached(enum ast_media_type type, const struct ast_sip_endpoint *endpoint, int *type_streams)
void ast_channel_hangupcause_set(struct ast_channel *chan, int value)
static void set_from_header(struct ast_sip_session *session)
void ast_sip_dialog_set_serializer(pjsip_dialog *dlg, struct ast_taskprocessor *serializer)
Set a serializer on a SIP dialog so requests and responses are automatically serialized.
unsigned int defer_terminate
#define RESET_STATE(__num)
void(* session_destroy)(struct ast_sip_session *session)
Notification that the session is being destroyed.
int ast_queue_unhold(struct ast_channel *chan)
Queue an unhold frame.
Definition: channel.c:1216
unsigned int terminate_while_deferred
struct ao2_container * datastores
Convenient Signal Processing routines.
static int handle_negotiated_sdp(struct ast_sip_session *session, const pjmedia_sdp_session *local, const pjmedia_sdp_session *remote)
enum ast_media_type ast_stream_get_type(const struct ast_stream *stream)
Get the media type of a stream.
Definition: stream.c:316
static int check_content_disposition(pjsip_rx_data *rdata)
Call Pickup API.
static int test_is_media_state_equal(struct ast_sip_session_media_state *left, struct ast_sip_session_media_state *right, int assert_on_failure)
#define LOG_WARNING
Definition: logger.h:274
int(* incoming_request)(struct ast_sip_session *session, struct pjsip_rx_data *rdata)
Called on incoming SIP request This method can indicate a failure in processing in its return...
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:714
static int setup_outbound_invite_auth(pjsip_dialog *dlg)
char * contact_user
Definition: res_pjsip.h:887
int ast_party_id_presentation(const struct ast_party_id *id)
Determine the overall presentation value for the given party.
Definition: channel.c:1821
void ast_sip_session_media_state_free(struct ast_sip_session_media_state *media_state)
Free a session media state structure.
#define ao2_callback(c, flags, cb_fn, arg)
Definition: astobj2.h:1716
static int delay_request(struct ast_sip_session *session, ast_sip_session_request_creation_cb on_request, ast_sip_session_sdp_creation_cb on_sdp_creation, ast_sip_session_response_cb on_response, int generate_new_sdp, enum delayed_method method, struct ast_sip_session_media_state *pending_media_state, struct ast_sip_session_media_state *active_media_state, int queue_head)
const ast_string_field external_media_address
Definition: res_pjsip.h:191
static int check_sdp_content_type_supported(pjsip_media_type *content_type)
struct ast_dsp * ast_dsp_new(void)
Allocates a new dsp, assumes 8khz for internal sample rate.
Definition: dsp.c:1745
unsigned int ended_while_deferred
char * mid
Media identifier for this stream (may be shared across multiple streams)
void(* outgoing_response)(struct ast_sip_session *session, struct pjsip_tx_data *tdata)
Called on an outgoing SIP response This method is always called from a SIP servant thread...
AST_TEST_DEFINE(test_resolve_refresh_media_states)
struct ast_sip_session * session
Session created for the new INVITE.
static int tmp()
Definition: bt_open.c:389
A handler for SDPs in SIP sessions.
const char * ast_codec_media_type2str(enum ast_media_type type)
Conversion function to take a media type and turn it into a string.
Definition: codec.c:347
const ast_string_field sdpsession
Definition: res_pjsip.h:762
void ast_party_id_copy(struct ast_party_id *dest, const struct ast_party_id *src)
Copy the source party id information to the destination party id.
Definition: channel.c:1765
static pj_pool_t * pool
Global memory pool for configuration and timers.
struct ast_str * attr_string
SDP attribute string.
#define AST_VECTOR_APPEND(vec, elem)
Append an element to a vector, growing the vector if needed.
Definition: vector.h:256
void ast_sip_dialog_set_endpoint(pjsip_dialog *dlg, struct ast_sip_endpoint *endpoint)
Set an endpoint on a SIP dialog so in-dialog requests do not undergo endpoint lookup.
struct ast_sip_auth_vector outbound_auths
Definition: res_pjsip.h:855
struct ast_datastore * ast_sip_session_alloc_datastore(const struct ast_datastore_info *info, const char *uid)
Alternative for ast_datastore_alloc()
void * pvt
Pointer to channel specific implementation information, must be ao2 object.
Universally unique identifier support.
enum ast_media_type ast_media_type_from_str(const char *media_type_str)
Conversion function to take a media string and convert it to a media type.
Definition: codec.c:363
struct ast_format_cap * codecs
Definition: res_pjsip.h:770
Set when the stream has been removed/declined.
Definition: stream.h:78
Test Framework API.
ast_sip_session_request_creation_cb on_request_creation
const ast_string_field context
Definition: res_pjsip.h:815
struct ast_sip_session_media * default_session[AST_MEDIA_TYPE_END]
Default media sessions for each type.
static void delayed_request_free(struct ast_sip_session_delayed_request *delay)
#define AST_TEST_REGISTER(cb)
Definition: test.h:127
static int sdp_handler_list_cmp(void *obj, void *arg, int flags)
Structure for a data store type.
Definition: datastore.h:31
#define ast_trace(level,...)
Print a basic trace message.
Definition: logger.h:692
void(* change_outgoing_sdp_stream_media_address)(struct pjsip_tx_data *tdata, struct pjmedia_sdp_media *stream, struct ast_sip_transport *transport)
Update media stream with external address if applicable.
static int check_content_disposition_in_multipart(pjsip_multipart_part *part)
ast_sip_session_media_write_cb write_callback
The write callback when writing frames.
A structure which contains a channel implementation and session.
const ast_string_field address
Definition: res_pjsip.h:758
struct ast_sip_session * session
Pointer to session.
static int get_mid_bundle_group(const pjmedia_sdp_session *sdp, const char *mid)
struct ast_sip_session_media * ast_sip_session_media_get_transport(struct ast_sip_session *session, struct ast_sip_session_media *session_media)
Retrieve the underlying media session that is acting as transport for a media session.
static const char * delayed_method2str(enum delayed_method method)
#define ast_cond_wait(cond, mutex)
Definition: lock.h:203
static void session_termination_cb(pj_timer_heap_t *timer_heap, struct pj_timer_entry *entry)
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1091
#define ast_cond_init(cond, attr)
Definition: lock.h:199
static struct ast_sip_nat_hook * nat_hook
NAT hook for modifying outgoing messages with SDP.
size_t ast_format_cap_count(const struct ast_format_cap *cap)
Get the number of formats present within the capabilities structure.
Definition: format_cap.c:395
int ast_stream_get_format_count(const struct ast_stream *stream)
Get the count of the current negotiated formats of a stream.
Definition: stream.c:358
#define MOD_DATA_ON_RESPONSE
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
Definition: linkedlists.h:449
#define ao2_alloc_options(data_size, destructor_fn, options)
Definition: astobj2.h:406
#define ast_assert(a)
Definition: utils.h:695
static struct ast_sip_session_media * test_media_add(struct ast_sip_session_media_state *media_state, const char *name, enum ast_media_type type, enum ast_stream_state state, int position)
Set when the stream is not sending OR receiving media.
Definition: stream.h:94
#define ao2_unlock(a)
Definition: astobj2.h:730
Definition: muted.c:95
static enum sip_get_destination_result get_destination(struct ast_sip_session *session, pjsip_rx_data *rdata)
Determine where in the dialplan a call should go.
static int test_is_media_session_equal(struct ast_sip_session_media *left, struct ast_sip_session_media *right)
void ast_party_id_free(struct ast_party_id *doomed)
Destroy the party id contents.
Definition: channel.c:1811
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:243
Structure for a data store object.
Definition: datastore.h:68
void ast_copy_pj_str(char *dest, const pj_str_t *src, size_t size)
Copy a pj_str_t into a standard character buffer.
Definition: res_pjsip.c:5240
#define SWAP(a, b)
Definition: utils.h:230
const char * str
Definition: app_jack.c:147
ast_stream_state
States that a stream may be in.
Definition: stream.h:74
static int new_invite(struct new_invite *invite)
char exten[AST_MAX_EXTENSION]
struct ast_sip_session_delayed_request * next
struct ast_stream * ast_stream_topology_get_stream(const struct ast_stream_topology *topology, unsigned int position)
Get a specific stream from the topology.
Definition: stream.c:788
#define NULL
Definition: resample.c:96
int ast_stream_topology_append_stream(struct ast_stream_topology *topology, struct ast_stream *stream)
Append a stream to the topology.
Definition: stream.c:748
#define SCOPE_EXIT_LOG_EXPR(__expr, __log_level,...)
Definition: logger.h:946
char * end
Definition: eagi_proxy.c:73
int value
Definition: syslog.c:37
static int handle_negotiated_sdp_session_media(struct ast_sip_session_media *session_media, struct ast_sip_session *session, const pjmedia_sdp_session *local, const pjmedia_sdp_session *remote, int index, struct ast_stream *asterisk_stream)
#define AST_TASKPROCESSOR_MAX_NAME
Suggested maximum taskprocessor name length (less null terminator).
Definition: taskprocessor.h:60
struct pjsip_inv_session * inv_session
struct ast_sip_session * ast_sip_session_create_outgoing(struct ast_sip_endpoint *endpoint, struct ast_sip_contact *contact, const char *location, const char *request_user, struct ast_stream_topology *req_topology)
Create a new outgoing SIP session.
#define LOG_DEBUG
Definition: logger.h:241
void ast_stream_set_formats(struct ast_stream *stream, struct ast_format_cap *caps)
Set the current negotiated formats of a stream.
Definition: stream.c:365
unsigned int accept_multiple_sdp_answers
Definition: res_pjsip.h:723
#define AST_LIST_TRAVERSE_SAFE_END
Closes a safe loop traversal block.
Definition: linkedlists.h:614
static void handle_session_end(struct ast_sip_session *session)
Socket address structure.
Definition: netsock2.h:97
#define ast_cond_signal(cond)
Definition: lock.h:201
static int invite_terminated(void *vsession)
int ast_stream_topology_set_stream(struct ast_stream_topology *topology, unsigned int position, struct ast_stream *stream)
Set a specific position in a topology.
Definition: stream.c:796
int ast_sip_session_refresh(struct ast_sip_session *session, ast_sip_session_request_creation_cb on_request_creation, ast_sip_session_sdp_creation_cb on_sdp_creation, ast_sip_session_response_cb on_response, enum ast_sip_session_refresh_method method, int generate_new_sdp, struct ast_sip_session_media_state *media_state)
Send a reinvite or UPDATE on a session.
A structure describing a SIP session.
static int stream_destroy(void *obj, void *arg, int flags)
void(* outgoing_request)(struct ast_sip_session *session, struct pjsip_tx_data *tdata)
Called on an outgoing SIP request This method is always called from a SIP servant thread...
int ast_canmatch_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Looks for a valid matching extension.
Definition: pbx.c:4194
static void check_delayed_requests(struct ast_sip_session *session, int(*cb)(void *vsession))
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
struct ast_format_cap * direct_media_cap
enum ast_sip_session_media_encryption encryption
What type of encryption is in use on this stream.
Media Stream API.
const char * uid
Definition: datastore.h:69
unsigned int bundled
Whether this stream is currently bundled or not.
#define DATASTORE_BUCKETS
#define ast_asprintf(ret, fmt,...)
A wrapper for asprintf()
Definition: astmm.h:269
enum ast_sip_session_response_priority response_priority
static void session_datastore_destroy(void *obj)
pthread_cond_t ast_cond_t
Definition: lock.h:176
#define ast_strlen_zero(foo)
Definition: strings.h:52
int(* negotiate_incoming_sdp_stream)(struct ast_sip_session *session, struct ast_sip_session_media *session_media, const struct pjmedia_sdp_session *sdp, int index, struct ast_stream *asterisk_stream)
Set session details based on a stream in an incoming SDP offer or answer.
struct ast_sip_session_media_state * active_media_state
const char * ast_sip_get_host_ip_string(int af)
Retrieve the local host address in string form.
Definition: res_pjsip.c:5473
#define AST_LIST_HEAD_DESTROY(head)
Destroys a list head structure.
Definition: linkedlists.h:652
int ast_sip_failover_request(pjsip_tx_data *tdata)
Set a request to use the next value in the list of resolved addresses.
Definition: res_pjsip.c:4871
static void resend_reinvite(pj_timer_heap_t *timer, pj_timer_entry *entry)
char * stream_name
Stream name.
struct ast_sip_endpoint * ast_pjsip_rdata_get_endpoint(pjsip_rx_data *rdata)
Get the looked-up endpoint on an out-of dialog request or response.
struct ast_sip_endpoint_media_configuration media
Definition: res_pjsip.h:841
Asterisk datastore objects.
#define ao2_bump(obj)
Definition: astobj2.h:491
struct ast_dsp * dsp
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:1065
void * ao2_object_get_lockaddr(void *obj)
Return the mutex lock address of an object.
Definition: astobj2.c:476
static int session_end(void *vsession)
const ast_string_field sdpowner
Definition: res_pjsip.h:760
unsigned int min_se
Definition: res_pjsip.h:565
#define ast_trace_log(__level, __log_level,...)
Definition: logger.h:952
#define ast_str_tmp(init_len, __expr)
Definition: strings.h:1136
#define DEFAULT_NUM_SESSION_MEDIA
sip_get_destination_result
int ast_taskprocessor_suspend(struct ast_taskprocessor *tps)
Indicate the taskprocessor is suspended.
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:452
#define ast_log
Definition: astobj2.c:42
int ast_sorcery_create(const struct ast_sorcery *sorcery, void *object)
Create and potentially persist an object using an available wizard.
Definition: sorcery.c:2057
pjsip_rx_data * deferred_reinvite
#define MAX(a, b)
Definition: utils.h:228
unsigned int follow_early_media_fork
Definition: res_pjsip.h:721
Structure for SIP nat hook information.
Definition: res_pjsip.h:271
static void session_destructor(void *obj)
const char * ast_stream_topology_to_str(const struct ast_stream_topology *topology, struct ast_str **buf)
Get a string representing the topology for debugging/display purposes.
Definition: stream.c:936
#define AST_VECTOR_INIT(vec, size)
Initialize a vector.
Definition: vector.h:113
static char host[256]
Definition: muted.c:77
struct ast_module * self
Definition: module.h:342
Structure for SIP transport information.
Definition: res_pjsip.h:87
struct ast_sip_session_sdp_handler * next
struct ast_sip_session_media_state * active_media_state
static void session_inv_on_media_update(pjsip_inv_session *inv, pj_status_t status)
#define AST_VECTOR_GET_ADDR(vec, idx)
Get an address of element in a vector.
Definition: vector.h:670
void(* outgoing_external_message)(struct pjsip_tx_data *tdata, struct ast_sip_transport *transport)
Definition: res_pjsip.h:275
static int sip_session_refresh(struct ast_sip_session *session, ast_sip_session_request_creation_cb on_request_creation, ast_sip_session_sdp_creation_cb on_sdp_creation, ast_sip_session_response_cb on_response, enum ast_sip_session_refresh_method method, int generate_new_sdp, struct ast_sip_session_media_state *pending_media_state, struct ast_sip_session_media_state *active_media_state, int queued)
#define ast_sip_mod_data_set(pool, mod_data, id, key, val)
Utilizing a mod_data array for a given id, set the value associated with the given key...
Definition: res_pjsip.h:2670
void ast_set_hangupsource(struct ast_channel *chan, const char *source, int force)
Set the source of the hangup in this channel and it&#39;s bridge.
Definition: channel.c:2504
static int handle_incoming(struct ast_sip_session *session, pjsip_rx_data *rdata, enum ast_sip_session_response_priority response_priority)
#define AST_VECTOR_ELEM_CLEANUP_NOOP(elem)
Vector element cleanup that does nothing.
Definition: vector.h:573
static pj_bool_t outbound_invite_auth(pjsip_rx_data *rdata)
SRTP and SDP Security descriptions.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:911
pjsip_rx_data * rdata
INVITE request itself.
static struct ast_mansession session
Access Control of various sorts.
ast_mutex_t lock
Definition: app_meetme.c:1091
static void session_inv_on_rx_offer(pjsip_inv_session *inv, const pjmedia_sdp_session *offer)
#define AST_MAX_EXTENSION
Definition: channel.h:135
#define AST_LIST_REMOVE_CURRENT(field)
Removes the current entry from a list during a traversal.
Definition: linkedlists.h:556
struct ast_sip_media_rtp_configuration rtp
Definition: res_pjsip.h:764
static struct ast_sip_session_media_state * internal_sip_session_media_state_alloc(size_t sessions, size_t read_callbacks)
#define ao2_ref(o, delta)
Definition: astobj2.h:464
#define S_COR(a, b, c)
returns the equivalent of logic or for strings, with an additional boolean check: second one if not e...
Definition: strings.h:85
#define DSP_FEATURE_FAX_DETECT
Definition: dsp.h:29
pj_timer_entry rescheduled_reinvite
int ast_sip_session_register_sdp_handler(struct ast_sip_session_sdp_handler *handler, const char *stream_type)
Register an SDP handler.
long int ast_random(void)
Definition: main/utils.c:2064
const struct ast_datastore_info * info
Definition: datastore.h:71
void(* destroy)(void *data)
Definition: datastore.h:34
#define ao2_lock(a)
Definition: astobj2.h:718
ast_sip_session_media_read_cb read_callback
The callback to invoke.
int ast_sip_session_is_pending_stream_default(const struct ast_sip_session *session, const struct ast_stream *stream)
Determines if a provided pending stream will be the default stream or not.
struct ast_datastore * ast_sip_session_get_datastore(struct ast_sip_session *session, const char *name)
Retrieve a session datastore.
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:300
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
Definition: sorcery.c:2312
static int check_request_status(pjsip_inv_session *inv, pjsip_event *e)
struct ast_channel * channel
static void handle_outgoing_request(struct ast_sip_session *session, pjsip_tx_data *tdata)
const char * method
Definition: res_pjsip.c:4335
void(* incoming_response)(struct ast_sip_session *session, struct pjsip_rx_data *rdata)
Called on an incoming SIP response This method is always called from a SIP servant thread...
int ast_sip_create_request_with_auth(const struct ast_sip_auth_vector *auths, pjsip_rx_data *challenge, pjsip_tx_data *tdata, pjsip_tx_data **new_request)
Create a response to an authentication challenge.
Definition: res_pjsip.c:3412
struct ast_sdp_srtp * srtp
Holds SRTP information.
struct ast_sip_channel_pvt * ast_sip_channel_pvt_alloc(void *pvt, struct ast_sip_session *session)
Allocate a new SIP channel pvt structure.
static void session_media_set_handler(struct ast_sip_session_media *session_media, struct ast_sip_session_sdp_handler *handler)
Set an SDP stream handler for a corresponding session media.
#define SCOPE_EXIT(...)
Scope Exit.
Definition: logger.h:805
static void handle_incoming_before_media(pjsip_inv_session *inv, struct ast_sip_session *session, pjsip_rx_data *rdata)
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:832
static pjsip_module session_module
const struct ast_format_cap * ast_stream_get_formats(const struct ast_stream *stream)
Get the current negotiated formats of a stream.
Definition: stream.c:330
AST_LIST_HEAD_NOLOCK(contactliststruct, contact)
int ast_taskprocessor_unsuspend(struct ast_taskprocessor *tps)
Indicate the taskprocessor is unsuspended.
Structure which contains read callback information.
An entity with which Asterisk communicates.
Definition: res_pjsip.h:812
static pj_bool_t has_supplement(const struct ast_sip_session *session, const pjsip_rx_data *rdata)
int ast_exists_extension(struct ast_channel *c, const char *context, const char *exten, int priority, const char *callerid)
Determine whether an extension exists.
Definition: pbx.c:4179
static int answer(void *data)
Definition: chan_pjsip.c:682
#define ast_format_cap_alloc(flags)
Definition: format_cap.h:52
static void session_inv_on_create_offer(pjsip_inv_session *inv, pjmedia_sdp_session **p_offer)
unsigned int ast_sip_get_use_callerid_contact(void)
Retrieve the global setting &#39;use_callerid_contact&#39;.
static void handle_session_destroy(struct ast_sip_session *session)
int ast_sip_register_service(pjsip_module *module)
Register a SIP service in Asterisk.
Definition: res_pjsip.c:3315
#define SCOPE_EXIT_EXPR(__expr,...)
Definition: logger.h:834
Core PBX routines and definitions.
int ast_queue_frame(struct ast_channel *chan, struct ast_frame *f)
Queue one or more frames to a channel&#39;s frame queue.
Definition: channel.c:1139
static void remove_stream_from_bundle(struct ast_sip_session_media *session_media, struct ast_stream *stream)
struct ast_taskprocessor * serializer
#define ast_sip_mod_data_get(mod_data, id, key)
Using the dictionary stored in mod_data array at a given id, retrieve the value associated with the g...
Definition: res_pjsip.h:2638
void ast_stream_set_group(struct ast_stream *stream, int group)
Set the stream group for a stream.
Definition: stream.c:1084
void ast_sip_location_retrieve_contact_and_aor_from_list_filtered(const char *aor_list, unsigned int flags, struct ast_sip_aor **aor, struct ast_sip_contact **contact)
Retrieve the first bound contact AND the AOR chosen from a list of AORs and filter based on flags...
Definition: location.c:272
int ast_sip_is_content_type(pjsip_media_type *content_type, char *type, char *subtype)
Checks if the given content type matches type/subtype.
Definition: res_pjsip.c:5259
#define ast_test_suite_event_notify(s, f,...)
Definition: test.h:196
static int add_sdp_streams(struct ast_sip_session_media *session_media, struct ast_sip_session *session, pjmedia_sdp_session *answer, const struct pjmedia_sdp_session *remote, struct ast_stream *stream)
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: astmm.h:290
static int datastore_hash(const void *obj, int flags)
struct ast_sip_endpoint_id_configuration id
Definition: res_pjsip.h:847
void ast_sip_session_resume_reinvite(struct ast_sip_session *session)
Resumes processing of a deferred incoming re-invite.
enum ast_sip_session_media_encryption encryption
Definition: res_pjsip.h:711
static int invite_proceeding(void *vsession)
Sentinel.
Definition: stream.h:98
void ast_sip_session_remove_supplements(struct ast_sip_session *session)
Remove supplements from a SIP session.
static pjmedia_sdp_session * generate_session_refresh_sdp(struct ast_sip_session *session)
int stream_num
The stream number to place into any resulting frames.
int fd
The file descriptor itself.
int ast_shutdown_final(void)
Definition: asterisk.c:1829
static void sip_session_defer_termination_stop_timer(struct ast_sip_session *session)
#define SCOPE_EXIT_LOG_RTN(__log_level,...)
Definition: logger.h:934
static void session_inv_on_new_session(pjsip_inv_session *inv, pjsip_event *e)
int ast_sorcery_delete(const struct ast_sorcery *sorcery, void *object)
Delete an object.
Definition: sorcery.c:2233
Set when the stream is sending and receiving media.
Definition: stream.h:82
#define AST_EXTENDED_FDS
Definition: channel.h:196
#define LOG_ERROR
Definition: logger.h:285
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:730
#define ao2_container_alloc_hash(ao2_options, container_options, n_buckets, hash_fn, sort_fn, cmp_fn)
Definition: astobj2.h:1310
struct ast_stream_topology * ast_channel_set_stream_topology(struct ast_channel *chan, struct ast_stream_topology *topology)
Set the topology of streams on a channel.
static void session_media_dtor(void *obj)
The descriptor of a dynamic string XXX storage will be optimized later if needed We use the ts field ...
Definition: strings.h:584
Format capabilities structure, holds formats + preference order + etc.
Definition: format_cap.c:54
int ast_stream_topology_equal(const struct ast_stream_topology *left, const struct ast_stream_topology *right)
Compare two stream topologies to see if they are equal.
Definition: stream.c:696
struct ast_party_id ast_channel_connected_effective_id(struct ast_channel *chan)
struct ast_stream_topology * ast_stream_topology_alloc(void)
Create a stream topology.
Definition: stream.c:650
unsigned int local_ssrc
Definition: rtp_engine.h:422
static struct ast_stream * test_stream_alloc(const char *name, enum ast_media_type type, enum ast_stream_state state)
int ast_sip_push_task(struct ast_taskprocessor *serializer, int(*sip_task)(void *), void *task_data)
Pushes a task to SIP servants.
Definition: res_pjsip.c:5138
void ast_sip_session_remove_datastore(struct ast_sip_session *session, const char *name)
Remove a session datastore from the session.
#define AST_TEST_UNREGISTER(cb)
Definition: test.h:128
static int datastore_cmp(void *obj, void *arg, int flags)
Transport to bind to.
Definition: res_pjsip.h:171
delayed_method
def info(msg)
#define ast_module_shutdown_ref(mod)
Prevent unload of the module before shutdown.
Definition: module.h:464
enum ast_sip_dtmf_mode dtmf
struct ast_sip_session_media * ast_sip_session_media_state_add(struct ast_sip_session *session, struct ast_sip_session_media_state *media_state, enum ast_media_type type, int position)
Allocate an ast_session_media and add it to the media state&#39;s vector.
#define ao2_callback_data(container, flags, cb_fn, arg, data)
Definition: astobj2.h:1743
#define ast_sip_transport_is_local(transport_state, addr)
Definition: res_pjsip.h:165
Contact associated with an address of record.
Definition: res_pjsip.h:281
int ast_strings_equal(const char *str1, const char *str2)
Compare strings for equality checking for NULL.
Definition: strings.c:239
struct ast_taskprocessor * ast_sip_create_serializer(const char *name)
Create a new serializer for SIP tasks.
Definition: res_pjsip.c:5133
static int add_bundle_groups(struct ast_sip_session *session, pj_pool_t *pool, pjmedia_sdp_session *answer)
ast_sip_session_refresh_method
Definition: res_pjsip.h:484
#define ast_cond_destroy(cond)
Definition: lock.h:200
unsigned int faxdetect
Definition: res_pjsip.h:869
#define ao2_alloc(data_size, destructor_fn)
Definition: astobj2.h:411
struct sdp_handler_list::@487 list
struct ast_taskprocessor * ast_sip_get_distributor_serializer(pjsip_rx_data *rdata)
Determine the distributor serializer for the SIP message.
#define LOG_NOTICE
Definition: logger.h:263
pj_timer_entry scheduled_termination
void * ast_sorcery_alloc(const struct ast_sorcery *sorcery, const char *type, const char *id)
Allocate an object.
Definition: sorcery.c:1744
#define MAX_RX_CHALLENGES
Definition: res_pjsip.h:80
#define SCOPE_EXIT_RTN(...)
Scope Exit with return.
Definition: logger.h:854
static void session_inv_on_state_changed(pjsip_inv_session *inv, pjsip_event *e)
#define AST_LIST_TRAVERSE(head, var, field)
Loops over (traverses) the entries in a list.
Definition: linkedlists.h:490
#define AST_LIST_ENTRY(type)
Declare a forward link structure inside a list entry.
Definition: linkedlists.h:409
int ast_sip_session_regenerate_answer(struct ast_sip_session *session, ast_sip_session_sdp_creation_cb on_sdp_creation)
Regenerate SDP Answer.
ast_sip_session_sdp_stream_defer
#define AST_LIST_INSERT_HEAD(head, elm, field)
Inserts a list entry at the head of a list.
Definition: linkedlists.h:710
unsigned int preferred_codec_only
Definition: res_pjsip.h:889
#define ast_channel_unlock(chan)
Definition: channel.h:2946
int timeout_sched_id
Scheduler ID for RTP timeout.
int ast_taskprocessor_is_task(struct ast_taskprocessor *tps)
Am I the given taskprocessor&#39;s current task.
Set when the stream is sending media only.
Definition: stream.h:86
struct ast_sip_transport_state * ast_sip_get_transport_state(const char *transport_id)
Retrieve transport state.
char * mids[PJMEDIA_MAX_SDP_MEDIA]
The media identifiers in this bundle group.
void ast_dsp_set_features(struct ast_dsp *dsp, int features)
Select feature set.
Definition: dsp.c:1755
struct ast_sip_timer_options timer
Definition: res_pjsip.h:580
#define SCOPED_AO2LOCK(varname, obj)
scoped lock specialization for ao2 mutexes.
Definition: lock.h:602
#define CHECKER()
static const char name[]
Definition: cdr_mysql.c:74
#define AST_LIST_HEAD_INIT(head)
Initializes a list head structure.
Definition: linkedlists.h:625
#define ast_free(a)
Definition: astmm.h:182
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:204
void ast_sip_session_media_stats_save(struct ast_sip_session *sip_session, struct ast_sip_session_media_state *media_state)
Save a media stats.
#define AST_VECTOR_RESET(vec, cleanup)
Reset vector.
Definition: vector.h:627
pjsip_dialog * ast_sip_create_dialog_uas_locked(const struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata, pj_status_t *status)
General purpose method for creating a UAS dialog with an endpoint.
Definition: res_pjsip.c:4249
static void session_on_tsx_state(pjsip_transaction *tsx, pjsip_event *e)
void(* session_end)(struct ast_sip_session *session)
Notification that the session has ended.
static struct ast_sip_session_delayed_request * delayed_request_alloc(enum delayed_method method, ast_sip_session_request_creation_cb on_request_creation, ast_sip_session_sdp_creation_cb on_sdp_creation, ast_sip_session_response_cb on_response, int generate_new_sdp, struct ast_sip_session_media_state *pending_media_state, struct ast_sip_session_media_state *active_media_state)
#define GET_STREAM_SAFE(_topology, _i)
void ast_sip_message_apply_transport(const char *transport_name, pjsip_tx_data *tdata)
Apply the configuration for a transport to an outgoing message.
#define STATE_REMOVED(_stream_state)
unsigned int moh_passthrough
Definition: res_pjsip.h:879
void ast_stream_set_state(struct ast_stream *stream, enum ast_stream_state state)
Set the state of a stream.
Definition: stream.c:380
struct ast_sip_session::@308 supplements
Structure used for sending delayed requests.
char * ast_uuid_generate_str(char *buf, size_t size)
Generate a UUID string.
Definition: uuid.c:143
#define SCOPE_ENTER(level,...)
Non RAII_VAR Scope Trace macros The advantage of these macros is that the EXITs will have the actual ...
Definition: logger.h:780
static void handle_session_begin(struct ast_sip_session *session)
struct controlling the suspension of the session&#39;s serializer.
static void set_remote_mslabel_and_stream_group(struct ast_sip_session *session, struct ast_sip_session_media *session_media, const pjmedia_sdp_session *sdp, const struct pjmedia_sdp_media *stream, struct ast_stream *asterisk_stream)
struct ast_sip_session_media_state * ast_sip_session_media_state_clone(const struct ast_sip_session_media_state *media_state)
Clone a media state.
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
char * remote_mslabel
Remote media stream label.
Vector container support.
static pj_bool_t session_on_rx_request(pjsip_rx_data *rdata)
Called when a new SIP request comes into PJSIP.
#define ao2_find(container, arg, flags)
Definition: astobj2.h:1756
int bundle_group
The bundle group the stream belongs to.
An API for managing task processing threads that can be shared across modules.
#define TRACE_ATLEAST(level)
Definition: logger.h:637
const char * ast_sip_session_get_name(const struct ast_sip_session *session)
Get the channel or endpoint name associated with the session.
#define GET_STREAM_STATE_SAFE(_stream)
ast_sip_session_response_cb on_response
void ast_party_id_init(struct ast_party_id *init)
Initialize the given party id structure.
Definition: channel.c:1757
int ast_taskprocessor_is_suspended(struct ast_taskprocessor *tps)
Get the task processor suspend status.
int ast_stream_topology_get_count(const struct ast_stream_topology *topology)
Get the number of streams in a topology.
Definition: stream.c:765
void ast_sdp_srtp_destroy(struct ast_sdp_srtp *srtp)
free a ast_sdp_srtp structure
Definition: sdp_srtp.c:51
int keepalive_sched_id
Scheduler ID for RTP keepalive.
A structure containing SIP session media information.
static int session_count
Definition: http.c:109
struct ast_sip_session_suspender * suspended
#define MOD_DATA_NAT_HOOK
static int session_end_if_disconnected(int id, pjsip_inv_session *inv)
struct ast_sip_session_supplement * next
static void handle_incoming_response(struct ast_sip_session *session, pjsip_rx_data *rdata, enum ast_sip_session_response_priority response_priority)
static pj_bool_t session_reinvite_on_rx_request(pjsip_rx_data *rdata)
Support for logging to various files, console and syslog Configuration in file logger.conf.
AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS|AST_MODFLAG_LOAD_ORDER, "HTTP Phone Provisioning",.support_level=AST_MODULE_SUPPORT_EXTENDED,.load=load_module,.unload=unload_module,.reload=reload,.load_pri=AST_MODPRI_CHANNEL_DEPEND,.requires="http",)
void(* session_begin)(struct ast_sip_session *session)
Notification that the session has begun This method will always be called from a SIP servant thread...
struct ast_sip_session::@309 delayed_requests
static int session_termination_task(void *data)
void ast_sip_modify_id_header(pj_pool_t *pool, pjsip_fromto_hdr *id_hdr, const struct ast_party_id *id)
Set name and number information on an identity header.
Definition: res_pjsip.c:5587
A supplement to SIP message processing.
struct ast_stream_topology * ast_stream_topology_clone(const struct ast_stream_topology *topology)
Create a deep clone of an existing stream topology.
Definition: stream.c:667
void ast_sip_session_unregister_sdp_handler(struct ast_sip_session_sdp_handler *handler, const char *stream_type)
Unregister an SDP handler.
pjsip_endpoint * ast_sip_get_pjsip_endpoint(void)
Get a pointer to the PJSIP endpoint.
Definition: res_pjsip.c:3718
#define AST_PRES_RESTRICTION
Definition: callerid.h:323
struct ast_frame ast_null_frame
Definition: main/frame.c:79
static int remove_handler(void *obj, void *arg, void *data, int flags)
#define SCOPE_EXIT_RTN_VALUE(__return_value,...)
Scope Exit with return value.
Definition: logger.h:875
static int sdp_requires_deferral(struct ast_sip_session *session, const pjmedia_sdp_session *sdp)
Determine whether the SDP provided requires deferral of negotiating or not.
void ast_stream_free(struct ast_stream *stream)
Destroy a media stream representation.
Definition: stream.c:292
static struct pjmedia_sdp_session * create_local_sdp(pjsip_inv_session *inv, struct ast_sip_session *session, const pjmedia_sdp_session *offer)
unsigned int allow_overlap
Definition: res_pjsip.h:893
static pjsip_redirect_op session_inv_on_redirected(pjsip_inv_session *inv, const pjsip_uri *target, const pjsip_event *e)
void * data
Definition: datastore.h:70
#define AST_VECTOR_GET(vec, idx)
Get an element from a vector.
Definition: vector.h:682
#define AST_LIST_HEAD_INIT_NOLOCK(head)
Initializes a list head structure.
Definition: linkedlists.h:680
char * strsep(char **str, const char *delims)
enum ast_media_type type
Media type of this session media.
struct ast_stream * ast_stream_alloc(const char *name, enum ast_media_type type)
Create a new media stream representation.
Definition: stream.c:233
static int invite_collision_timeout(void *vsession)
static void __print_debug_details(const char *function, pjsip_inv_session *inv, pjsip_transaction *tsx, pjsip_event *e)
struct ast_stream_topology * topology
Definition: res_pjsip.h:772
struct ast_sorcery * ast_sip_get_sorcery(void)
Get a pointer to the SIP sorcery structure.
#define ao2_cleanup(obj)
Definition: astobj2.h:1958
unsigned int changed
The underlying session has been changed in some fashion.
struct ast_party_id self
Definition: res_pjsip.h:629
int ast_channel_hangupcause(const struct ast_channel *chan)
struct ast_stream * ast_stream_clone(const struct ast_stream *stream, const char *name)
Create a deep clone of an existing stream.
Definition: stream.c:257
struct ast_stream_topology * topology
The media stream topology.
#define GET_STREAM_NAME_SAFE(_stream)
struct ast_sip_session_sdp_handler * handler
SDP handler that setup the RTP.
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
Definition: strings.h:79
void * ast_taskprocessor_unreference(struct ast_taskprocessor *tps)
Unreference the specified taskprocessor and its reference count will decrement.
struct ast_rtp_instance * rtp
RTP instance itself.
const char * ast_channel_name(const struct ast_channel *chan)
enum ast_sip_session_call_direction call_direction
static void session_inv_on_tsx_state_changed(pjsip_inv_session *inv, pjsip_transaction *tsx, pjsip_event *e)
void ast_sip_unregister_service(pjsip_module *module)
Definition: res_pjsip.c:3331
const char * ast_stream_state2str(enum ast_stream_state state)
Convert the state of a stream into a string.
Definition: stream.c:388
static void handler(const char *name, int response_code, struct ast_variable *get_params, struct ast_variable *path_vars, struct ast_variable *headers, struct ast_json *body, struct ast_ari_response *response)
Definition: test_ari.c:59
int ast_stream_set_metadata(struct ast_stream *stream, const char *m_key, const char *value)
Set a stream metadata value.
Definition: stream.c:460
const char * ast_stream_get_metadata(const struct ast_stream *stream, const char *m_key)
Get a stream metadata value.
Definition: stream.c:423
static void handle_incoming_request(struct ast_sip_session *session, pjsip_rx_data *rdata)
static void sip_session_suspender_dtor(void *vdoomed)
#define AST_PRES_ALLOWED
Definition: callerid.h:324
#define AST_VECTOR_REPLACE(vec, idx, elem)
Replace an element at a specific position in a vector, growing the vector if needed.
Definition: vector.h:284
static int media_stats_local_ssrc_cmp(const struct ast_rtp_instance_stats *vec_elem, const struct ast_rtp_instance_stats *srch)
Data structure associated with a single frame of data.
Internal Asterisk hangup causes.
void ast_sip_session_send_request_with_cb(struct ast_sip_session *session, pjsip_tx_data *tdata, ast_sip_session_response_cb on_response)
Send a SIP request and get called back when a response is received.
unsigned int authentication_challenge_count
enum ast_sip_session_sdp_stream_defer(* defer_incoming_sdp_stream)(struct ast_sip_session *session, struct ast_sip_session_media *session_media, const struct pjmedia_sdp_session *sdp, const struct pjmedia_sdp_media *stream)
Determine whether a stream requires that the re-invite be deferred. If a stream can not be immediatel...
static int sip_session_suspend_task(void *data)
struct ast_sip_endpoint_extensions extensions
Definition: res_pjsip.h:839
int ast_sip_session_add_supplements(struct ast_sip_session *session)
Add supplements to a SIP session.
Definition: pjsip_session.c:90
void ast_sip_session_media_state_reset(struct ast_sip_session_media_state *media_state)
Reset a media state to a clean state.
Definition: search.h:40
pjsip_dialog * ast_sip_create_dialog_uac(const struct ast_sip_endpoint *endpoint, const char *aor_name, const char *request_user)
General purpose method for creating a UAC dialog with an endpoint.
Definition: res_pjsip.c:4028
enum queue_result id
Definition: app_queue.c:1507
ast_media_type
Types of media.
Definition: codec.h:30
static void handle_outgoing_response(struct ast_sip_session *session, pjsip_tx_data *tdata)
#define AST_LIST_TRAVERSE_SAFE_BEGIN(head, var, field)
Loops safely over (traverses) the entries in a list.
Definition: linkedlists.h:528
Return only reachable or unknown contacts.
Definition: res_pjsip.h:1009
char label[AST_UUID_STR_LEN]
Track label.
unsigned int remote_rtcp_mux
Does remote support rtcp_mux.
void ast_sip_session_unsuspend(struct ast_sip_session *session)
Request the session serializer be unsuspended.
Generic container type.
static struct test_options options
int ast_sip_session_media_set_write_callback(struct ast_sip_session *session, struct ast_sip_session_media *session_media, ast_sip_session_media_write_cb callback)
Set a write callback for a media session.
void ast_sip_session_send_request(struct ast_sip_session *session, pjsip_tx_data *tdata)
Send a SIP request.
static pj_timer_heap_t * timer_heap
Global timer heap.
void ast_channel_internal_fd_set(struct ast_channel *chan, int which, int value)
int ast_sip_session_create_invite(struct ast_sip_session *session, pjsip_tx_data **tdata)
Creates an INVITE request.
void ast_stream_topology_free(struct ast_stream_topology *topology)
Unreference and destroy a stream topology.
Definition: stream.c:743
struct ast_sip_session_media_state * ast_sip_session_media_state_alloc(void)
Allocate a session media state structure.
const ast_string_field aors
Definition: res_pjsip.h:821
pjsip_fromto_hdr * saved_from_hdr
const char * ast_stream_get_name(const struct ast_stream *stream)
Get the name of a stream.
Definition: stream.c:309
int ast_sip_session_media_add_read_callback(struct ast_sip_session *session, struct ast_sip_session_media *session_media, int fd, ast_sip_session_media_read_cb callback)
Set a read callback for a media session with a specific file descriptor.
#define ASTERISK_GPL_KEY
The text the key() function should return.
Definition: module.h:46
#define DEBUG_ATLEAST(level)
Definition: logger.h:441
const ast_string_field uri
Definition: res_pjsip.h:303
static int sdp_handler_list_hash(const void *obj, int flags)
static struct ast_timer * timer
Definition: chan_iax2.c:360
#define AST_VECTOR_REMOVE(vec, idx, preserve_ordered)
Remove an element from a vector by index.
Definition: vector.h:412
struct ast_sip_contact * contact
char * remote_label
Remote stream label.
#define AST_CAUSE_BEARERCAPABILITY_NOTAVAIL
Definition: causes.h:129
Asterisk module definitions.
static pj_bool_t does_method_match(const pj_str_t *message_method, const char *supplement_method)
struct ast_sip_aor * aor
int ast_channel_stream_topology_changed_externally(struct ast_channel *chan)
Provide notice from a channel that the topology has changed on it as a result of the remote party ren...
Definition: channel.c:11209
int ast_format_cap_get_compatible(const struct ast_format_cap *cap1, const struct ast_format_cap *cap2, struct ast_format_cap *result)
Find the compatible formats between two capabilities structures.
Definition: format_cap.c:630
int ast_sip_session_add_datastore(struct ast_sip_session *session, struct ast_datastore *datastore)
Add a datastore to a SIP session.
enum ast_sip_session_redirect redirect_method
Definition: res_pjsip.h:873
void ast_sip_session_end_if_deferred(struct ast_sip_session *session)
End the session if it had been previously deferred.
struct ast_party_id id
unsigned char valid
TRUE if the number information is valid/present.
Definition: channel.h:298
static void sip_channel_destroy(void *obj)
Destructor for SIP channel.
static struct ao2_container * sdp_handlers
Registered SDP stream handlers.
int(* create_outgoing_sdp_stream)(struct ast_sip_session *session, struct ast_sip_session_media *session_media, struct pjmedia_sdp_session *sdp, const struct pjmedia_sdp_session *remote, struct ast_stream *stream)
Create an SDP media stream and add it to the outgoing SDP offer or answer.
int(* ast_sip_session_sdp_creation_cb)(struct ast_sip_session *session, pjmedia_sdp_session *sdp)
Set when the stream is receiving media only.
Definition: stream.h:90
int(* apply_negotiated_sdp_stream)(struct ast_sip_session *session, struct ast_sip_session_media *session_media, const struct pjmedia_sdp_session *local, const struct pjmedia_sdp_session *remote, int index, struct ast_stream *asterisk_stream)
Apply a negotiated SDP media stream.
int ast_stream_topology_del_stream(struct ast_stream_topology *topology, unsigned int position)
Delete a specified stream from the given topology.
Definition: stream.c:825
enum ast_stream_state ast_stream_get_state(const struct ast_stream *stream)
Get the current state of a stream.
Definition: stream.c:373
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:611
unsigned int position
The position of the stream in the topology.
Definition: stream.c:90
static void handle_new_invite_request(pjsip_rx_data *rdata)
static pjsip_module outbound_invite_auth_module
void(* stream_stop)(struct ast_sip_session_media *session_media)
Stop a session_media created by this handler but do not destroy resources.
struct ast_stream * ast_sip_session_create_joint_call_stream(const struct ast_sip_session *session, struct ast_stream *remote)
Create a new stream of joint capabilities.
ast_test_result_state
Definition: test.h:200
static struct ast_sip_session_media_state * resolve_refresh_media_states(const char *session_name, struct ast_sip_session_media_state *delayed_pending_state, struct ast_sip_session_media_state *delayed_active_state, struct ast_sip_session_media_state *current_active_state, int run_post_validation)
jack_status_t status
Definition: app_jack.c:146
static int new_invite_initial_answer(pjsip_inv_session *inv_session, pjsip_rx_data *rdata, int answer_code, int terminate_code, pj_bool_t notify)
static char * ast_sockaddr_stringify_host(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() to return an address only, suitable for a URL (with brack...
Definition: netsock2.h:331
static int update_completed(void *vsession)
#define ast_str_create(init_len)
Create a malloc&#39;ed dynamic length string.
Definition: strings.h:620
unsigned int moh_passthrough
const ast_string_field fromdomain
Definition: res_pjsip.h:831
Configuration relating to call pickup.
static force_inline int attribute_pure ast_str_hash(const char *str)
Compute a hash value on a string.
Definition: strings.h:1206
unsigned int remote_ice
Does remote support ice.
struct ast_party_number number
Subscriber phone number.
Definition: channel.h:343
void ast_sip_session_terminate(struct ast_sip_session *session, int response)
Terminate a session and, if possible, send the provided response code.
#define ao2_link(container, obj)
Definition: astobj2.h:1549