@@ -167,6 +167,7 @@ enum rtpe_operation {
167167 OP_SUBSCRIBE_REQUEST ,
168168 OP_SUBSCRIBE_ANSWER ,
169169 OP_UNSUBSCRIBE ,
170+ OP_ROLLBACK ,
170171};
171172
172173enum rtpe_stat {
@@ -258,6 +259,7 @@ static const char *command_strings[] = {
258259 [OP_SUBSCRIBE_REQUEST ]= "subscribe request" ,
259260 [OP_SUBSCRIBE_ANSWER ] = "subscribe answer" ,
260261 [OP_UNSUBSCRIBE ] = "unsubscribe" ,
262+ [OP_ROLLBACK ] = "rollback" ,
261263};
262264
263265static const str stat_maps [] = {
@@ -301,6 +303,8 @@ static int rtpengine_answer_f(struct sip_msg *msg, str *flags, pv_spec_t *spvar,
301303static int rtpengine_manage_f (struct sip_msg * msg , str * flags , pv_spec_t * spvar ,
302304 pv_spec_t * bpvar , str * body );
303305static int rtpengine_delete_f (struct sip_msg * msg , str * flags , pv_spec_t * spvar );
306+ static int rtpengine_rollback_f (struct sip_msg * msg , str * flags ,
307+ pv_spec_t * spvar , pv_spec_t * rolled_back );
304308static void free_rtpe_nodes (struct rtpe_set * list );
305309static int rtpengine_playmedia_f (struct sip_msg * msg , str * flags ,
306310 pv_spec_t * duration , pv_spec_t * spvar );
@@ -508,6 +512,12 @@ static const cmd_export_t cmds[] = {
508512 {CMD_PARAM_STR | CMD_PARAM_OPT , 0 , 0 },
509513 {CMD_PARAM_VAR | CMD_PARAM_OPT , 0 , 0 }, {0 ,0 ,0 }},
510514 ALL_ROUTES },
515+ {"rtpengine_rollback" , (cmd_function )rtpengine_rollback_f , {
516+ {CMD_PARAM_STR | CMD_PARAM_OPT , 0 , 0 },
517+ {CMD_PARAM_VAR | CMD_PARAM_OPT , 0 , 0 },
518+ {CMD_PARAM_VAR | CMD_PARAM_OPT , 0 , 0 },
519+ {0 ,0 ,0 }},
520+ ALL_ROUTES },
511521 {"rtpengine_play_media" , (cmd_function )rtpengine_playmedia_f , {
512522 {CMD_PARAM_STR , 0 , 0 },
513523 {CMD_PARAM_VAR | CMD_PARAM_OPT , 0 , 0 },
@@ -2832,7 +2842,7 @@ static int rtpe_function_call_prepare(bencode_buffer_t *bencbuf, struct sip_msg
28322842 bencode_dictionary_add_str (ng_flags -> dict , "from-tag" , & ng_flags -> from_tag );
28332843 } else if (ng_flags -> directional
28342844 || (msg && ((msg -> first_line .type == SIP_REQUEST && op != OP_ANSWER )
2835- || (msg -> first_line .type == SIP_REPLY && op == OP_DELETE )
2845+ || (msg -> first_line .type == SIP_REPLY && ( op == OP_DELETE || op == OP_ROLLBACK ) )
28362846 || (msg -> first_line .type == SIP_REPLY && op == OP_ANSWER ))))
28372847 {
28382848 if (!from_tag_exist && !ng_flags -> no_from_tag )
@@ -3467,6 +3477,35 @@ rtpengine_delete_f(struct sip_msg* msg, str *flags, pv_spec_t *spvar)
34673477 return rtpengine_delete (msg , flags , NULL , NULL , spvar );
34683478}
34693479
3480+ static int
3481+ rtpengine_rollback_f (struct sip_msg * msg , str * flags , pv_spec_t * spvar ,
3482+ pv_spec_t * rolled_back )
3483+ {
3484+ bencode_buffer_t bencbuf ;
3485+ bencode_item_t * dict ;
3486+ pv_value_t val ;
3487+
3488+ if (set_rtpengine_set_from_avp (msg ) == -1 )
3489+ return -1 ;
3490+
3491+ dict = rtpe_function_call_ok (& bencbuf , msg , OP_ROLLBACK , flags ,
3492+ NULL , spvar , NULL , NULL , NULL );
3493+ if (!dict ) {
3494+ LM_ERR ("could not roll back media!\n" );
3495+ return -1 ;
3496+ }
3497+
3498+ if (rolled_back ) {
3499+ memset (& val , 0 , sizeof (pv_value_t ));
3500+ val .flags = PV_TYPE_INT |PV_VAL_INT ;
3501+ val .ri = bencode_dictionary_get_integer (dict , "rolled-back" , -1 );
3502+ if (pv_set_value (msg , rolled_back , 0 , & val ) != 0 )
3503+ LM_ERR ("failed to set rolled-back after rolling back media!\n" );
3504+ }
3505+ bencode_buffer_free (& bencbuf );
3506+ return 1 ;
3507+ }
3508+
34703509static bencode_item_t * rtpe_function_call_process (bencode_buffer_t * bencbuf , char * cp , int ret )
34713510{
34723511 bencode_item_t * resp ;
0 commit comments