@ -59,8 +59,55 @@
< / parameter >
< / syntax >
< description >
< para > Returns the codecs offered based upon the media choice < / para >
< para > When read , returns the codecs offered based upon the media choice . < / para >
< para > When written , sets the codecs to offer when an outbound dial attempt is made ,
or when a session refresh is sent using < replaceable > PJSIP_SEND_SESSION_REFRESH < / replaceable > .
< / para >
< / description >
< see - also >
< ref type = " function " > PJSIP_SEND_SESSION_REFRESH < / ref >
< / see - also >
< / function >
< function name = " PJSIP_SEND_SESSION_REFRESH " language = " en_US " >
< synopsis >
W / O : Initiate a session refresh via an UPDATE or re - INVITE on an established media session
< / synopsis >
< syntax >
< parameter name = " update_type " required = " false " >
< para > The type of update to send . Default is < literal > invite < / literal > . < / para >
< enumlist >
< enum name = " invite " >
< para > Send the session refresh as a re - INVITE . < / para >
< / enum >
< enum name = " update " >
< para > Send the session refresh as an UPDATE . < / para >
< / enum >
< / enumlist >
< / parameter >
< / syntax >
< description >
< para > This function will cause the PJSIP stack to immediately refresh
the media session for the channel . This will be done using either a
re - INVITE ( default ) or an UPDATE request .
< / para >
< para > This is most useful when combined with the < replaceable > PJSIP_MEDIA_OFFER < / replaceable >
dialplan function , as it allows the formats in use on a channel to be
re - negotiated after call setup . < / para >
< warning >
< para > The formats the endpoint supports are < emphasis > not < / emphasis >
checked or enforced by this function . Using this function to offer
formats not supported by the endpoint < emphasis > may < / emphasis > result
in a loss of media . < / para >
< / warning >
< example title = " Re-negotiate format to g722 " >
; Within some existing extension on an answered channel
same = > n , Set ( PJSIP_MEDIA_OFFER ( audio ) = ! all , g722 )
same = > n , Set ( PJSIP_SEND_SESSION_REFRESH ( ) = invite )
< / example >
< / description >
< see - also >
< ref type = " function " > PJSIP_MEDIA_OFFER < / ref >
< / see - also >
< / function >
< info name = " PJSIPCHANNEL " language = " en_US " tech = " PJSIP " >
< enumlist >
@ -961,3 +1008,70 @@ int pjsip_acf_media_offer_write(struct ast_channel *chan, const char *cmd, char
return ast_sip_push_task_synchronous ( channel - > session - > serializer , media_offer_write_av , & mdata ) ;
}
struct refresh_data {
struct ast_sip_session * session ;
enum ast_sip_session_refresh_method method ;
} ;
static int sip_session_response_cb ( struct ast_sip_session * session , pjsip_rx_data * rdata )
{
struct ast_format * fmt ;
if ( ! session - > channel ) {
/* Egads! */
return 0 ;
}
fmt = ast_format_cap_get_best_by_type ( ast_channel_nativeformats ( session - > channel ) , AST_MEDIA_TYPE_AUDIO ) ;
if ( ! fmt ) {
/* No format? That's weird. */
return 0 ;
}
ast_channel_set_writeformat ( session - > channel , fmt ) ;
ast_channel_set_rawwriteformat ( session - > channel , fmt ) ;
ast_channel_set_readformat ( session - > channel , fmt ) ;
ast_channel_set_rawreadformat ( session - > channel , fmt ) ;
ao2_ref ( fmt , - 1 ) ;
return 0 ;
}
static int refresh_write_cb ( void * obj )
{
struct refresh_data * data = obj ;
ast_sip_session_refresh ( data - > session , NULL , NULL ,
sip_session_response_cb , data - > method , 1 ) ;
return 0 ;
}
int pjsip_acf_session_refresh_write ( struct ast_channel * chan , const char * cmd , char * data , const char * value )
{
struct ast_sip_channel_pvt * channel ;
struct refresh_data rdata = {
. method = AST_SIP_SESSION_REFRESH_METHOD_INVITE ,
} ;
if ( ! chan ) {
ast_log ( LOG_WARNING , " No channel was provided to %s function. \n " , cmd ) ;
return - 1 ;
}
if ( strcmp ( ast_channel_tech ( chan ) - > type , " PJSIP " ) ) {
ast_log ( LOG_WARNING , " Cannot call %s on a non-PJSIP channel \n " , cmd ) ;
return - 1 ;
}
channel = ast_channel_tech_pvt ( chan ) ;
rdata . session = channel - > session ;
if ( ! strcmp ( value , " invite " ) ) {
rdata . method = AST_SIP_SESSION_REFRESH_METHOD_INVITE ;
} else if ( ! strcmp ( value , " update " ) ) {
rdata . method = AST_SIP_SESSION_REFRESH_METHOD_UPDATE ;
}
return ast_sip_push_task_synchronous ( channel - > session - > serializer , refresh_write_cb , & rdata ) ;
}