[Asterisk-code-review] chan pjsip: Multistream: Configure stream maxima (asterisk[master])
Mark Michelson
asteriskteam at digium.com
Wed Jun 14 16:19:38 CDT 2017
Mark Michelson has uploaded this change for review. ( https://gerrit.asterisk.org/5841
Change subject: chan_pjsip: Multistream: Configure stream maxima
......................................................................
chan_pjsip: Multistream: Configure stream maxima
This adds two new configuration options for PJSIP endpoints:
max_audio_streams: determines the maximum number of audio streams to
offer/accept from an endpoint. Defaults to 1.
max_video_streams: determines the maximum number of video streams to
offer/accept from an endpoint. Defaults to 1.
This change fixes the four tests that were failing due to the previous
change in this series.
Change-Id: Id4b192c06fb311428d907ece78a131fdebc29163
---
M channels/chan_pjsip.c
M include/asterisk/res_pjsip.h
M res/res_pjsip/pjsip_configuration.c
M res/res_pjsip_session.c
4 files changed, 70 insertions(+), 3 deletions(-)
git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/41/5841/1
diff --git a/channels/chan_pjsip.c b/channels/chan_pjsip.c
index bd76110..9e60755 100644
--- a/channels/chan_pjsip.c
+++ b/channels/chan_pjsip.c
@@ -479,8 +479,9 @@
struct ast_sip_session_media *session_media;
session_media = AST_VECTOR_GET(&session->media, i);
-
- ast_assert(session_media != NULL);
+ if (!session_media) {
+ continue;
+ }
if (session_media->type == type) {
return ao2_bump(session_media);
diff --git a/include/asterisk/res_pjsip.h b/include/asterisk/res_pjsip.h
index ad0dc28..ecad2bf 100644
--- a/include/asterisk/res_pjsip.h
+++ b/include/asterisk/res_pjsip.h
@@ -680,6 +680,10 @@
unsigned int bind_rtp_to_media_address;
/*! Use RTCP-MUX */
unsigned int rtcp_mux;
+ /*! Maximum number of audio streams to offer/accept */
+ unsigned int max_audio_streams;
+ /*! Maximum number of video streams to offer/accept */
+ unsigned int max_video_streams;
};
/*!
diff --git a/res/res_pjsip/pjsip_configuration.c b/res/res_pjsip/pjsip_configuration.c
index e6e0821..dc4226b 100644
--- a/res/res_pjsip/pjsip_configuration.c
+++ b/res/res_pjsip/pjsip_configuration.c
@@ -1989,6 +1989,8 @@
ast_sorcery_object_field_register(sip_sorcery, "endpoint", "rtcp_mux", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, media.rtcp_mux));
ast_sorcery_object_field_register(sip_sorcery, "endpoint", "allow_overlap", "yes", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, allow_overlap));
ast_sorcery_object_field_register(sip_sorcery, "endpoint", "refer_blind_progress", "yes", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, refer_blind_progress));
+ ast_sorcery_object_field_register(sip_sorcery, "endpoint", "max_audio_streams", "1", OPT_UINT_T, 0, FLDSET(struct ast_sip_endpoint, media.max_audio_streams));
+ ast_sorcery_object_field_register(sip_sorcery, "endpoint", "max_video_streams", "1", OPT_UINT_T, 0, FLDSET(struct ast_sip_endpoint, media.max_video_streams));
if (ast_sip_initialize_sorcery_transport()) {
ast_log(LOG_ERROR, "Failed to register SIP transport support with sorcery\n");
diff --git a/res/res_pjsip_session.c b/res/res_pjsip_session.c
index 56acbd3..e9f5d51 100644
--- a/res/res_pjsip_session.c
+++ b/res/res_pjsip_session.c
@@ -259,10 +259,45 @@
return session_media;
}
+static int limitation_reached(enum ast_media_type type, const struct ast_sip_endpoint *endpoint, int *type_streams)
+{
+ switch (type) {
+ case AST_MEDIA_TYPE_AUDIO:
+ if (type_streams[type] < endpoint->media.max_audio_streams) {
+ return 0;
+ } else {
+ return 1;
+ }
+ case AST_MEDIA_TYPE_VIDEO:
+ if (type_streams[type] < endpoint->media.max_video_streams) {
+ return 0;
+ } else {
+ return 1;
+ }
+ case AST_MEDIA_TYPE_IMAGE:
+ case AST_MEDIA_TYPE_TEXT:
+ /* We don't have an option for image (T.38) and text streams
+ * so we cap these at one
+ */
+ if (type_streams[type] > 0) {
+ return 1;
+ } else {
+ return 0;
+ }
+ case AST_MEDIA_TYPE_UNKNOWN:
+ default:
+ /* We don't want any unknown or "other" streams on our endpoint,
+ * so always just say we've reached the limit
+ */
+ return 1;
+ }
+}
+
static int handle_incoming_sdp(struct ast_sip_session *session, const pjmedia_sdp_session *sdp)
{
int i;
int handled = 0;
+ int type_streams[AST_MEDIA_TYPE_END] = {0};
if (session->inv_session && session->inv_session->state == PJSIP_INV_STATE_DISCONNECTED) {
ast_log(LOG_ERROR, "Failed to handle incoming SDP. Session has been already disconnected\n");
@@ -276,9 +311,15 @@
RAII_VAR(struct sdp_handler_list *, handler_list, NULL, ao2_cleanup);
struct ast_sip_session_media *session_media = NULL;
int res;
+ enum ast_media_type type;
/* We need a null-terminated version of the media string */
ast_copy_pj_str(media, &sdp->media[i]->desc.media, sizeof(media));
+ type = ast_media_type_from_str(media);
+
+ if (limitation_reached(type, session->endpoint, type_streams)) {
+ continue;
+ }
if (i < AST_VECTOR_SIZE(&session->media)) {
session_media = AST_VECTOR_GET(&session->media, i);
@@ -288,7 +329,7 @@
* on this session media. The session media destructor will ensure that
* all SDP handlers get a chance to free the memory they allocated
*/
- session_media->type = ast_media_type_from_str(media);
+ session_media->type = type;
session_media->handler = NULL;
}
}
@@ -314,6 +355,7 @@
session_media->handler->id);
/* Handled by this handler. Move to the next stream */
handled = 1;
+ ++type_streams[type];
continue;
}
}
@@ -342,6 +384,7 @@
/* Handled by this handler. Move to the next stream */
session_media_set_handler(session_media, handler);
handled = 1;
+ ++type_streams[type];
break;
}
}
@@ -419,10 +462,19 @@
static int handle_negotiated_sdp(struct ast_sip_session *session, const pjmedia_sdp_session *local, const pjmedia_sdp_session *remote)
{
int i;
+ int type_streams[AST_MEDIA_TYPE_END] = {0};
for (i = 0; i < local->media_count; ++i) {
struct ast_sip_session_media *session_media;
+ char media[20];
+ enum ast_media_type type;
+
if (!remote->media[i]) {
+ continue;
+ }
+ ast_copy_pj_str(media, &local->media[i]->desc.media, sizeof(media));
+ type = ast_media_type_from_str(media);
+ if (limitation_reached(type, session->endpoint, type_streams)) {
continue;
}
@@ -436,6 +488,7 @@
if (handle_negotiated_sdp_session_media(session_media, session, local, remote, i)) {
return -1;
}
+ ++type_streams[type];
}
return 0;
@@ -3038,6 +3091,7 @@
pjmedia_sdp_session *local;
struct ast_stream_topology *topology;
int i;
+ int type_streams[AST_MEDIA_TYPE_END] = {0};
if (inv->state == PJSIP_INV_STATE_DISCONNECTED) {
ast_log(LOG_ERROR, "Failed to create session SDP. Session has been already disconnected\n");
@@ -3075,6 +3129,11 @@
struct ast_stream *stream;
stream = ast_stream_topology_get_stream(topology, i);
+
+ if (limitation_reached(ast_stream_get_type(stream), session->endpoint, type_streams)) {
+ continue;
+ }
+
if (i < AST_VECTOR_SIZE(&session->media)) {
session_media = AST_VECTOR_GET(&session->media, i);
} else {
@@ -3087,6 +3146,7 @@
if (add_sdp_streams(session_media, session, local, stream)) {
return NULL;
}
+ ++type_streams[ast_stream_get_type(stream)];
}
/* Use the connection details of the first media stream if possible for SDP level */
--
To view, visit https://gerrit.asterisk.org/5841
To unsubscribe, visit https://gerrit.asterisk.org/settings
Gerrit-Project: asterisk
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: Id4b192c06fb311428d907ece78a131fdebc29163
Gerrit-Change-Number: 5841
Gerrit-PatchSet: 1
Gerrit-Owner: Mark Michelson <mmichelson at digium.com>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.digium.com/pipermail/asterisk-code-review/attachments/20170614/fb59936d/attachment.html>
More information about the asterisk-code-review
mailing list