From dfa7bf13fb0e5513cd3b1558765ba32e9300a120 Mon Sep 17 00:00:00 2001 From: Julien Chavanton Date: Sun, 25 Oct 2020 18:54:33 +0000 Subject: [PATCH] rtp_media_server: state transition improvement - fix disconnection while in bridge, to keep thing simple for now the second leg is automaticaly disconnected. (cherry picked from commit e419bad759dc817ba673563ec4e79681f685dc28) --- .../rtp_media_server/rms_dialog_info.c | 21 +++++++++++++++++++ .../rtp_media_server/rms_dialog_info.h | 4 ++++ .../rtp_media_server/rtp_media_server.c | 16 ++++++++------ 3 files changed, 35 insertions(+), 6 deletions(-) diff --git a/src/modules/rtp_media_server/rms_dialog_info.c b/src/modules/rtp_media_server/rms_dialog_info.c index 5d05daf54f9..cbe57985188 100644 --- a/src/modules/rtp_media_server/rms_dialog_info.c +++ b/src/modules/rtp_media_server/rms_dialog_info.c @@ -68,6 +68,27 @@ void rms_dialog_list_free() shm_free(rms_dialog_list); } +char *rms_dialog_state_toa(rms_dialog_state_t state) { + if (state == 0) return "RMS_ST_DEFAULT"; + else if (state == 1) return "RMS_ST_CONNECTING"; + else if (state == 2) return "RMS_ST_CONNECTED"; + else if (state == 3) return "RMS_ST_CONNECTED_ACK"; + else if (state == 4) return "RMS_ST_DISCONNECTING"; + else if (state == 5) return "RMS_ST_DISCONNECTED"; + return "RMS_ST_UNKNOWN"; +} + +int rms_dialog_info_set_state(rms_dialog_info_t *di, rms_dialog_state_t state) +{ + if (state <= di->state) { + LM_ERR("[%s] >> [%s] (invalid state transition) call-id[%s]\n", rms_dialog_state_toa(di->state), rms_dialog_state_toa(state), di->callid.s); + } else { + LM_NOTICE("[%s] >> [%s] call-id[%s]\n", rms_dialog_state_toa(di->state), rms_dialog_state_toa(state), di->callid.s); + di->state = state; + } + return 1; +} + rms_dialog_info_t *rms_dialog_search(struct sip_msg *msg) // str *from_tag) { rms_dialog_info_t *si; diff --git a/src/modules/rtp_media_server/rms_dialog_info.h b/src/modules/rtp_media_server/rms_dialog_info.h index f32bad60e50..e8bb3cf3090 100644 --- a/src/modules/rtp_media_server/rms_dialog_info.h +++ b/src/modules/rtp_media_server/rms_dialog_info.h @@ -70,6 +70,7 @@ rms_dialog_info_t *rms_dialog_new_bleg(struct sip_msg *msg); int rms_dialogs_dump_f(struct sip_msg *msg, char *param1, char *param2); rms_dialog_info_t *rms_get_dialog_list(void); + typedef struct ms_res { AudioStream *audio_stream; @@ -80,10 +81,13 @@ typedef enum rms_dialog_state { RMS_ST_DEFAULT, RMS_ST_CONNECTING, RMS_ST_CONNECTED, + RMS_ST_CONNECTED_ACK, RMS_ST_DISCONNECTING, RMS_ST_DISCONNECTED, } rms_dialog_state_t; +int rms_dialog_info_set_state(rms_dialog_info_t *di, rms_dialog_state_t state); + typedef struct rms_dialog_info { struct rms_dialog_info *next; diff --git a/src/modules/rtp_media_server/rtp_media_server.c b/src/modules/rtp_media_server/rtp_media_server.c index 886a05b3248..6a1fbca636b 100644 --- a/src/modules/rtp_media_server/rtp_media_server.c +++ b/src/modules/rtp_media_server/rtp_media_server.c @@ -225,7 +225,9 @@ static rms_dialog_info_t *rms_stop(rms_dialog_info_t *di) } rms_dialog_info_t *tmp = di->prev; - di->state = RMS_ST_DISCONNECTED; + // not yet, we need the confirmation. + // rms_dialog_info_set_state(di, RMS_ST_DISCONNECTED); + // keep it for a little while to deal with retransmissions ... //clist_rm(di, next, prev); //rms_dialog_free(di); @@ -269,7 +271,7 @@ static rms_dialog_info_t *rms_dialog_action_check(rms_dialog_info_t *di) // rms_stop(di->bridged_di); di = rms_stop(di); a->type = RMS_NONE; - // di->state = RMS_SSTATE_DISCONNECTED; + // rms_dialog_info_set_state(di, RMS_ST_DISCONNECTED); return di; } else if(a->type == RMS_PLAY) { LM_INFO("dialog action RMS_PLAY [%s]\n", di->callid.s); @@ -428,7 +430,7 @@ static int rms_answer_call( return 0; } LM_INFO("answered\n"); - di->state = RMS_ST_CONNECTED; + rms_dialog_info_set_state(di, RMS_ST_CONNECTED); } else { LM_INFO("no request found\n"); } @@ -473,7 +475,7 @@ static void bridge_cb(struct cell *ptrans, int ntype, struct tmcb_params *pcbp) if(ntype == TMCB_ON_FAILURE) { LM_NOTICE("FAILURE [%d]\n", pcbp->code); rms_action_t *a = (rms_action_t *)*pcbp->param; - a->di->state = RMS_ST_DISCONNECTED; + rms_dialog_info_set_state(a->di, RMS_ST_DISCONNECTED); if(a->cell->uas.request) { str *reason = &pcbp->rpl->first_line.u.reply.reason; if(!tmb.t_reply_with_body(a->cell, pcbp->code, reason, NULL, NULL, @@ -1064,14 +1066,17 @@ static int rms_sip_request_f(struct sip_msg *msg) } if(di && strncmp(method->s, "BYE", 3) == 0) { + if(di->state == RMS_ST_DISCONNECTING) + return -1; if(di->state == RMS_ST_CONNECTED) - di->state = RMS_ST_DISCONNECTING; + rms_dialog_info_set_state(di, RMS_ST_DISCONNECTING); rms_action_t *a = rms_action_new(RMS_STOP); if(!a) return -1; rms_action_add_sync(di, a); if(di->bridged_di) { // bridged LM_NOTICE("BYE in brigde mode\n"); + rms_sip_forward(di, msg, method); } else { // connected localy LM_NOTICE("BYE in local mode\n"); rms_disconnect(msg); @@ -1083,7 +1088,6 @@ static int rms_sip_request_f(struct sip_msg *msg) LM_NOTICE("initial INVITE\n"); return 1; } else { - LM_NOTICE("in dialog message, state [%d]\n", di->state); if (di->state == RMS_ST_DISCONNECTING) { return -1; // ignore in dialog message in this state } else if (di->state == RMS_ST_DISCONNECTED) {