Merge "SDP: Rework SDP offer/answer model and update capabilities merges."

This commit is contained in:
Joshua Colp
2017-07-26 08:20:35 -05:00
committed by Gerrit Code Review
11 changed files with 3400 additions and 612 deletions

View File

@@ -253,16 +253,6 @@ void ast_sdp_s_free(struct ast_sdp_s_line *s_line);
*/
void ast_sdp_t_free(struct ast_sdp_t_line *t_line);
/*!
* \brief Free an SDP
* Frees the sdp and all resources it contains
*
* \param sdp The sdp to free
*
* \since 15
*/
void ast_sdp_free(struct ast_sdp *sdp);
/*!
* \brief Allocate an SDP Attribute
*
@@ -544,7 +534,7 @@ int ast_sdp_m_add_format(struct ast_sdp_m_line *m_line, const struct ast_sdp_opt
int rtp_code, int asterisk_format, const struct ast_format *format, int code);
/*!
* \brief Create an SDP
* \brief Create an SDP ao2 object
*
* \param o_line Origin
* \param c_line Connection

View File

@@ -20,6 +20,7 @@
#define _ASTERISK_SDP_OPTIONS_H
#include "asterisk/udptl.h"
#include "asterisk/format_cap.h"
struct ast_sdp_options;
@@ -79,6 +80,149 @@ enum ast_sdp_options_encryption {
AST_SDP_ENCRYPTION_DTLS,
};
/*!
* \brief Callback when processing an offer SDP for our answer SDP.
* \since 15.0.0
*
* \details
* This callback is called after merging our last negotiated topology
* with the remote's offer topology and before we have sent our answer
* SDP. At this point you can alter new_topology streams. You can
* decline, remove formats, or rename streams. Changing anything else
* on the streams is likely to not end well.
*
* * To decline a stream simply set the stream state to
* AST_STREAM_STATE_REMOVED. You could implement a maximum number
* of active streams of a given type policy.
*
* * To remove formats use the format API to remove any formats from a
* stream. The streams have the current joint negotiated formats.
* Most likely you would want to remove all but the first format.
*
* * To rename a stream you need to clone the stream and give it a
* new name and then set it in new_topology using
* ast_stream_topology_set_stream().
*
* \note Removing all formats is an error. You should decline the
* stream instead.
*
* \param context User supplied context data pointer for the SDP
* state.
* \param old_topology Active negotiated topology. NULL if this is
* the first SDP negotiation. The old topology is available so you
* can tell if any streams are new or changing type.
* \param new_topology New negotiated topology that we intend to
* generate the answer SDP.
*
* \return Nothing
*/
typedef void (*ast_sdp_answerer_modify_cb)(void *context,
const struct ast_stream_topology *old_topology,
struct ast_stream_topology *new_topology);
/*!
* \internal
* \brief Callback when generating a topology for our SDP offer.
* \since 15.0.0
*
* \details
* This callback is called after merging any topology updates from the
* system by ast_sdp_state_update_local_topology() and before we have
* sent our offer SDP. At this point you can alter new_topology
* streams. You can decline, add/remove/update formats, or rename
* streams. Changing anything else on the streams is likely to not
* end well.
*
* * To decline a stream simply set the stream state to
* AST_STREAM_STATE_REMOVED. You could implement a maximum number
* of active streams of a given type policy.
*
* * To update formats use the format API to change formats of the
* streams. The streams have the current proposed formats. You
* could do whatever you want for formats but you should stay within
* the configured formats for the stream type's endpoint. However,
* you should use ast_sdp_state_update_local_topology() instead of
* this backdoor method.
*
* * To rename a stream you need to clone the stream and give it a
* new name and then set it in new_topology using
* ast_stream_topology_set_stream().
*
* \note Removing all formats is an error. You should decline the
* stream instead.
*
* \note Declined new streams that are in slots higher than present in
* old_topology are removed so the SDP can be smaller. The remote has
* never seen those slots so we shouldn't bother keeping them.
*
* \param context User supplied context data pointer for the SDP
* state.
* \param old_topology Active negotiated topology. NULL if this is
* the first SDP negotiation. The old topology is available so you
* can tell if any streams are new or changing type.
* \param new_topology Merged topology that we intend to generate the
* offer SDP.
*
* \return Nothing
*/
typedef void (*ast_sdp_offerer_modify_cb)(void *context,
const struct ast_stream_topology *old_topology,
struct ast_stream_topology *new_topology);
/*!
* \brief Callback when generating an offer SDP to configure extra stream data.
* \since 15.0.0
*
* \details
* This callback is called after any ast_sdp_offerer_modify_cb
* callback and before we have sent our offer SDP. The callback can
* call several SDP API calls to configure the proposed capabilities
* of streams before we create the SDP offer. For example, the
* callback could configure a stream specific connection address, T.38
* parameters, RTP instance, or UDPTL instance parameters.
*
* \param context User supplied context data pointer for the SDP
* state.
* \param topology Topology ready to configure extra stream options.
*
* \return Nothing
*/
typedef void (*ast_sdp_offerer_config_cb)(void *context, const struct ast_stream_topology *topology);
/*!
* \brief Callback before applying a topology.
* \since 15.0.0
*
* \details
* This callback is called before the topology is applied so the
* using module can do what is necessary before the topology becomes
* active.
*
* \param context User supplied context data pointer for the SDP
* state.
* \param topology Topology ready to be applied.
*
* \return Nothing
*/
typedef void (*ast_sdp_preapply_cb)(void *context, const struct ast_stream_topology *topology);
/*!
* \brief Callback after applying a topology.
* \since 15.0.0
*
* \details
* This callback is called after the topology is applied so the
* using module can do what is necessary after the topology becomes
* active.
*
* \param context User supplied context data pointer for the SDP
* state.
* \param topology Topology already applied.
*
* \return Nothing
*/
typedef void (*ast_sdp_postapply_cb)(void *context, const struct ast_stream_topology *topology);
/*!
* \since 15.0.0
* \brief Allocate a new SDP options structure.
@@ -204,6 +348,24 @@ void ast_sdp_options_set_rtp_engine(struct ast_sdp_options *options,
*/
const char *ast_sdp_options_get_rtp_engine(const struct ast_sdp_options *options);
void ast_sdp_options_set_state_context(struct ast_sdp_options *options, void *state_context);
void *ast_sdp_options_get_state_context(const struct ast_sdp_options *options);
void ast_sdp_options_set_answerer_modify_cb(struct ast_sdp_options *options, ast_sdp_answerer_modify_cb answerer_modify_cb);
ast_sdp_answerer_modify_cb ast_sdp_options_get_answerer_modify_cb(const struct ast_sdp_options *options);
void ast_sdp_options_set_offerer_modify_cb(struct ast_sdp_options *options, ast_sdp_offerer_modify_cb offerer_modify_cb);
ast_sdp_offerer_modify_cb ast_sdp_options_get_offerer_modify_cb(const struct ast_sdp_options *options);
void ast_sdp_options_set_offerer_config_cb(struct ast_sdp_options *options, ast_sdp_offerer_config_cb offerer_config_cb);
ast_sdp_offerer_config_cb ast_sdp_options_get_offerer_config_cb(const struct ast_sdp_options *options);
void ast_sdp_options_set_preapply_cb(struct ast_sdp_options *options, ast_sdp_preapply_cb preapply_cb);
ast_sdp_preapply_cb ast_sdp_options_get_preapply_cb(const struct ast_sdp_options *options);
void ast_sdp_options_set_postapply_cb(struct ast_sdp_options *options, ast_sdp_postapply_cb postapply_cb);
ast_sdp_postapply_cb ast_sdp_options_get_postapply_cb(const struct ast_sdp_options *options);
/*!
* \since 15.0.0
* \brief Set SDP Options rtp_symmetric
@@ -503,6 +665,26 @@ void ast_sdp_options_set_udptl_far_max_datagram(struct ast_sdp_options *options,
*/
unsigned int ast_sdp_options_get_udptl_far_max_datagram(const struct ast_sdp_options *options);
/*!
* \since 15.0.0
* \brief Set SDP Options max_streams
*
* \param options SDP Options
* \param max_streams
*/
void ast_sdp_options_set_max_streams(struct ast_sdp_options *options,
unsigned int max_streams);
/*!
* \since 15.0.0
* \brief Get SDP Options max_streams
*
* \param options SDP Options
*
* \returns max_streams
*/
unsigned int ast_sdp_options_get_max_streams(const struct ast_sdp_options *options);
/*!
* \since 15.0.0
* \brief Enable setting SSRC level attributes on SDPs
@@ -547,4 +729,46 @@ void ast_sdp_options_set_sched_type(struct ast_sdp_options *options,
struct ast_sched_context *ast_sdp_options_get_sched_type(const struct ast_sdp_options *options,
enum ast_media_type type);
/*!
* \brief Set all allowed stream types to create new streams.
* \since 15.0.0
*
* \param options SDP Options
* \param cap Format capabilities to set all allowed stream types at once.
* Could be NULL to disable creating any new streams.
*
* \return Nothing
*/
void ast_sdp_options_set_format_caps(struct ast_sdp_options *options,
struct ast_format_cap *cap);
/*!
* \brief Set the SDP options format cap used to create new streams of the type.
* \since 15.0.0
*
* \param options SDP Options
* \param type Media type the format cap represents.
* \param cap Format capabilities to use for the specified media type.
* Could be NULL to disable creating new streams of type.
*
* \return Nothing
*/
void ast_sdp_options_set_format_cap_type(struct ast_sdp_options *options,
enum ast_media_type type, struct ast_format_cap *cap);
/*!
* \brief Get the SDP options format cap used to create new streams of the type.
* \since 15.0.0
*
* \param options SDP Options
* \param type Media type the format cap represents.
*
* \retval NULL if stream not allowed to be created.
* \retval cap to use in negotiating the new stream.
*
* \note The returned cap does not have its own ao2 ref.
*/
struct ast_format_cap *ast_sdp_options_get_format_cap_type(const struct ast_sdp_options *options,
enum ast_media_type type);
#endif /* _ASTERISK_SDP_OPTIONS_H */

View File

@@ -30,12 +30,22 @@ struct ast_control_t38_parameters;
/*!
* \brief Allocate a new SDP state
*
* \details
* SDP state keeps tabs on everything SDP-related for a media session.
* Most SDP operations will require the state to be provided.
* Ownership of the SDP options is taken on by the SDP state.
* A good strategy is to call this during session creation.
*
* \param topology Initial stream topology to offer.
* NULL if we are going to be the answerer. We can always
* update the local topology later if it turns out we need
* to be the offerer.
* \param options SDP options for the duration of the session.
*
* \retval SDP state struct
* \retval NULL on failure
*/
struct ast_sdp_state *ast_sdp_state_alloc(struct ast_stream_topology *streams,
struct ast_sdp_state *ast_sdp_state_alloc(struct ast_stream_topology *topology,
struct ast_sdp_options *options);
/*!
@@ -86,6 +96,8 @@ int ast_sdp_state_get_stream_connection_address(const struct ast_sdp_state *sdp_
*
* If this is called prior to receiving a remote SDP, then this will just mirror
* the local configured endpoint capabilities.
*
* \note Cannot return NULL. It is a BUG if it does.
*/
const struct ast_stream_topology *ast_sdp_state_get_joint_topology(
const struct ast_sdp_state *sdp_state);
@@ -93,6 +105,7 @@ const struct ast_stream_topology *ast_sdp_state_get_joint_topology(
/*!
* \brief Get the local topology
*
* \note Cannot return NULL. It is a BUG if it does.
*/
const struct ast_stream_topology *ast_sdp_state_get_local_topology(
const struct ast_sdp_state *sdp_state);
@@ -114,9 +127,10 @@ const struct ast_sdp_options *ast_sdp_state_get_options(
* \retval NULL Failure
*
* \note
* This function will allocate a new SDP with RTP instances if it has not already
* been allocated.
*
* This function will return the last local SDP created if one were
* previously requested for the current negotiation. Otherwise it
* creates our SDP offer/answer depending on what role we are playing
* in the current negotiation.
*/
const struct ast_sdp *ast_sdp_state_get_local_sdp(struct ast_sdp_state *sdp_state);
@@ -152,6 +166,7 @@ const void *ast_sdp_state_get_local_sdp_impl(struct ast_sdp_state *sdp_state);
*
* \retval 0 Success
* \retval non-0 Failure
* Use ast_sdp_state_is_offer_rejected() to see if the SDP offer was rejected.
*
* \since 15
*/
@@ -165,39 +180,72 @@ int ast_sdp_state_set_remote_sdp(struct ast_sdp_state *sdp_state, const struct a
*
* \retval 0 Success
* \retval non-0 Failure
* Use ast_sdp_state_is_offer_rejected() to see if the SDP offer was rejected.
*
* \since 15
*/
int ast_sdp_state_set_remote_sdp_from_impl(struct ast_sdp_state *sdp_state, const void *remote);
/*!
* \brief Reset the SDP state and stream capabilities as if the SDP state had just been allocated.
* \brief Was the set remote offer rejected.
* \since 15.0.0
*
* \param sdp_state
*
* \retval 0 if not rejected.
* \retval non-zero if rejected.
*/
int ast_sdp_state_is_offer_rejected(struct ast_sdp_state *sdp_state);
/*!
* \brief Are we the SDP offerer.
* \since 15.0.0
*
* \param sdp_state
*
* \retval 0 if we are not the offerer.
* \retval non-zero we are the offerer.
*/
int ast_sdp_state_is_offerer(struct ast_sdp_state *sdp_state);
/*!
* \brief Are we the SDP answerer.
* \since 15.0.0
*
* \param sdp_state
*
* \retval 0 if we are not the answerer.
* \retval non-zero we are the answerer.
*/
int ast_sdp_state_is_answerer(struct ast_sdp_state *sdp_state);
/*!
* \brief Restart the SDP offer/answer negotiations.
*
* \param sdp_state
* \param remote The implementation's representation of an SDP.
*
* \retval 0 Success
*
* \note
* This is most useful for when a channel driver is sending a session refresh message
* and needs to re-advertise its initial capabilities instead of the previously-negotiated
* joint capabilities.
*
* \since 15
* \retval non-0 Failure
*/
int ast_sdp_state_reset(struct ast_sdp_state *sdp_state);
int ast_sdp_state_restart_negotiations(struct ast_sdp_state *sdp_state);
/*!
* \brief Update the local stream topology on the SDP state.
*
* \details
* Basically we are saving off any topology updates until we create the
* next SDP offer. Repeated updates merge with the previous updated
* topology.
*
* \param sdp_state
* \param streams The new stream topology.
* \param topology The new stream topology.
*
* \retval 0 Success
* \retval non-0 Failure
*
* \since 15
*/
int ast_sdp_state_update_local_topology(struct ast_sdp_state *sdp_state, struct ast_stream_topology *streams);
int ast_sdp_state_update_local_topology(struct ast_sdp_state *sdp_state, struct ast_stream_topology *topology);
/*!
* \brief Set the local address (IP address) to use for connection addresses
@@ -231,7 +279,26 @@ int ast_sdp_state_set_connection_address(struct ast_sdp_state *sdp_state, int st
/*!
* \since 15.0.0
* \brief Set a stream to be held or unheld
* \brief Set the global locally held state.
*
* \param sdp_state
* \param locally_held
*/
void ast_sdp_state_set_global_locally_held(struct ast_sdp_state *sdp_state, unsigned int locally_held);
/*!
* \since 15.0.0
* \brief Get the global locally held state.
*
* \param sdp_state
*
* \returns locally_held
*/
unsigned int ast_sdp_state_get_global_locally_held(const struct ast_sdp_state *sdp_state);
/*!
* \since 15.0.0
* \brief Set a stream to be held or unheld locally
*
* \param sdp_state
* \param stream_index The stream to set the held value for
@@ -240,6 +307,30 @@ int ast_sdp_state_set_connection_address(struct ast_sdp_state *sdp_state, int st
void ast_sdp_state_set_locally_held(struct ast_sdp_state *sdp_state,
int stream_index, unsigned int locally_held);
/*!
* \since 15.0.0
* \brief Get whether a stream is locally held or not
*
* \param sdp_state
* \param stream_index The stream to get the held state for
*
* \returns locally_held
*/
unsigned int ast_sdp_state_get_locally_held(const struct ast_sdp_state *sdp_state,
int stream_index);
/*!
* \since 15.0.0
* \brief Get whether a stream is remotely held or not
*
* \param sdp_state
* \param stream_index The stream to get the held state for
*
* \returns remotely_held
*/
unsigned int ast_sdp_state_get_remotely_held(const struct ast_sdp_state *sdp_state,
int stream_index);
/*!
* \since 15.0.0
* \brief Set the UDPTL session parameters
@@ -251,16 +342,4 @@ void ast_sdp_state_set_locally_held(struct ast_sdp_state *sdp_state,
void ast_sdp_state_set_t38_parameters(struct ast_sdp_state *sdp_state,
int stream_index, struct ast_control_t38_parameters *params);
/*!
* \since 15.0.0
* \brief Get whether a stream is held or not
*
* \param sdp_state
* \param stream_index The stream to get the held state for
*
* \returns locally_held
*/
unsigned int ast_sdp_state_get_locally_held(const struct ast_sdp_state *sdp_state,
int stream_index);
#endif /* _ASTERISK_SDP_STATE_H */

View File

@@ -227,6 +227,17 @@ void ast_stream_set_state(struct ast_stream *stream, enum ast_stream_state state
*/
const char *ast_stream_state2str(enum ast_stream_state state);
/*!
* \brief Convert a string to a stream state
*
* \param str The string to convert
*
* \return The stream state
*
* \since 15.0.0
*/
enum ast_stream_state ast_stream_str2state(const char *str);
/*!
* \brief Get the opaque stream data
*