Skip to content

Commit b2f4209

Browse files
jarrodbrazvancrainea
authored andcommitted
rtpengine: add rtpengine_rollback()
1 parent 3b2d988 commit b2f4209

2 files changed

Lines changed: 78 additions & 1 deletion

File tree

‎modules/rtpengine/README.md‎

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -638,6 +638,9 @@ be used in the SDP body. Address family is detected automatically.
638638
- *record-call=yes/no* - indicates whether rtpengine should
639639
record the call or not. When using this parameter, you may pass further
640640
information in the "metadata".
641+
- *track-state* - instructs rtpengine to record the media state of the
642+
last completed offer/answer exchange before applying an offer, so that
643+
*rtpengine_rollback()* can restore it.
641644
- *transcode-CODEC* - used only for offer, indicates that
642645
rtpengine should transcode the CODEC towards the B-side. Example:
643646
*transcode-PCMA* will present to the B-side the PCMA codec.
@@ -829,6 +832,41 @@ rtpengine_delete();
829832
```
830833

831834

835+
#### rtpengine_rollback([flags[, sock_var[, rolled_back]]])
836+
837+
838+
This function will restore the media state of the last completed
839+
offer/answer exchange, recorded for offers made with the *track-state*
840+
flag, without deleting the call. Use it when the remote endpoint refuses
841+
an offer RTPEngine already applied, for example a re-INVITE answered with
842+
a negative final response.
843+
844+
845+
Meaning of the parameters is as follows:
846+
847+
848+
- *flags(string)* - a list of flags similar to
849+
the other functions.
850+
- *rolled_back(var, optional)* - a pseudo variable that
851+
will contain 1 when a recorded state was restored, or 0 when none was
852+
outstanding.
853+
854+
855+
This function can be used from any route.
856+
857+
858+
```opensips title="rtpengine_rollback usage"
859+
...
860+
rtpengine_offer("track-state");
861+
...
862+
onreply_route[reinvite_reply] {
863+
if (t_check_status("[3-6][0-9][0-9]"))
864+
rtpengine_rollback();
865+
}
866+
...
867+
```
868+
869+
832870
#### rtpengine_manage([flags[, sock_var[, sdp_var[, body]]]])
833871

834872

‎modules/rtpengine/rtpengine.c‎

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@ enum rtpe_operation {
167167
OP_SUBSCRIBE_REQUEST,
168168
OP_SUBSCRIBE_ANSWER,
169169
OP_UNSUBSCRIBE,
170+
OP_ROLLBACK,
170171
};
171172

172173
enum 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

263265
static const str stat_maps[] = {
@@ -301,6 +303,8 @@ static int rtpengine_answer_f(struct sip_msg *msg, str *flags, pv_spec_t *spvar,
301303
static int rtpengine_manage_f(struct sip_msg *msg, str *flags, pv_spec_t *spvar,
302304
pv_spec_t *bpvar, str *body);
303305
static 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);
304308
static void free_rtpe_nodes(struct rtpe_set *list);
305309
static 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+
34703509
static bencode_item_t *rtpe_function_call_process(bencode_buffer_t *bencbuf, char* cp, int ret)
34713510
{
34723511
bencode_item_t *resp;

0 commit comments

Comments
 (0)