Browse code

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)

Julien Chavanton authored on 25/10/2020 18:54:33 • Daniel-Constantin Mierla committed on 26/10/2020 09:59:47
Showing 3 changed files
... ...
@@ -68,6 +68,27 @@ void rms_dialog_list_free()
68 68
 	shm_free(rms_dialog_list);
69 69
 }
70 70
 
71
+char *rms_dialog_state_toa(rms_dialog_state_t state) {
72
+	if (state == 0) return "RMS_ST_DEFAULT";
73
+	else if (state == 1) return "RMS_ST_CONNECTING";
74
+	else if (state == 2) return "RMS_ST_CONNECTED";
75
+	else if (state == 3) return "RMS_ST_CONNECTED_ACK";
76
+	else if (state == 4) return "RMS_ST_DISCONNECTING";
77
+	else if (state == 5) return "RMS_ST_DISCONNECTED";
78
+	return "RMS_ST_UNKNOWN";
79
+}
80
+
81
+int rms_dialog_info_set_state(rms_dialog_info_t *di, rms_dialog_state_t state)
82
+{
83
+	if (state <= di->state) {
84
+		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);
85
+	} else {
86
+		LM_NOTICE("[%s] >> [%s] call-id[%s]\n", rms_dialog_state_toa(di->state), rms_dialog_state_toa(state), di->callid.s);
87
+		di->state = state;
88
+	}
89
+	return 1;
90
+}
91
+
71 92
 rms_dialog_info_t *rms_dialog_search(struct sip_msg *msg) // str *from_tag)
72 93
 {
73 94
 	rms_dialog_info_t *si;
... ...
@@ -70,6 +70,7 @@ rms_dialog_info_t *rms_dialog_new_bleg(struct sip_msg *msg);
70 70
 int rms_dialogs_dump_f(struct sip_msg *msg, char *param1, char *param2);
71 71
 rms_dialog_info_t *rms_get_dialog_list(void);
72 72
 
73
+
73 74
 typedef struct ms_res
74 75
 {
75 76
 	AudioStream *audio_stream;
... ...
@@ -80,10 +81,13 @@ typedef enum rms_dialog_state {
80 81
 	RMS_ST_DEFAULT,
81 82
 	RMS_ST_CONNECTING,
82 83
 	RMS_ST_CONNECTED,
84
+	RMS_ST_CONNECTED_ACK,
83 85
 	RMS_ST_DISCONNECTING,
84 86
 	RMS_ST_DISCONNECTED,
85 87
 } rms_dialog_state_t;
86 88
 
89
+int rms_dialog_info_set_state(rms_dialog_info_t *di, rms_dialog_state_t state);
90
+
87 91
 typedef struct rms_dialog_info
88 92
 {
89 93
 	struct rms_dialog_info *next;
... ...
@@ -225,7 +225,9 @@ static rms_dialog_info_t *rms_stop(rms_dialog_info_t *di)
225 225
 	}
226 226
 
227 227
 	rms_dialog_info_t *tmp = di->prev;
228
-	di->state = RMS_ST_DISCONNECTED;
228
+	// not yet, we need the confirmation.
229
+	// rms_dialog_info_set_state(di, RMS_ST_DISCONNECTED);
230
+
229 231
 	// keep it for a little while to deal with retransmissions ...
230 232
 	//clist_rm(di, next, prev);
231 233
 	//rms_dialog_free(di);
... ...
@@ -269,7 +271,7 @@ static rms_dialog_info_t *rms_dialog_action_check(rms_dialog_info_t *di)
269 271
 			//	rms_stop(di->bridged_di);
270 272
 			di = rms_stop(di);
271 273
 			a->type = RMS_NONE;
272
-			// di->state = RMS_SSTATE_DISCONNECTED;
274
+			// rms_dialog_info_set_state(di, RMS_ST_DISCONNECTED);
273 275
 			return di;
274 276
 		} else if(a->type == RMS_PLAY) {
275 277
 			LM_INFO("dialog action RMS_PLAY [%s]\n", di->callid.s);
... ...
@@ -428,7 +430,7 @@ static int rms_answer_call(
428 430
 			return 0;
429 431
 		}
430 432
 		LM_INFO("answered\n");
431
-		di->state = RMS_ST_CONNECTED;
433
+		rms_dialog_info_set_state(di, RMS_ST_CONNECTED);
432 434
 	} else {
433 435
 		LM_INFO("no request found\n");
434 436
 	}
... ...
@@ -473,7 +475,7 @@ static void bridge_cb(struct cell *ptrans, int ntype, struct tmcb_params *pcbp)
473 475
 	if(ntype == TMCB_ON_FAILURE) {
474 476
 		LM_NOTICE("FAILURE [%d]\n", pcbp->code);
475 477
 		rms_action_t *a = (rms_action_t *)*pcbp->param;
476
-		a->di->state = RMS_ST_DISCONNECTED;
478
+		rms_dialog_info_set_state(a->di, RMS_ST_DISCONNECTED);
477 479
 		if(a->cell->uas.request) {
478 480
 			str *reason = &pcbp->rpl->first_line.u.reply.reason;
479 481
 			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)
1064 1066
 	}
1065 1067
 
1066 1068
 	if(di && strncmp(method->s, "BYE", 3) == 0) {
1069
+		if(di->state == RMS_ST_DISCONNECTING)
1070
+			return -1;
1067 1071
 		if(di->state == RMS_ST_CONNECTED)
1068
-			di->state = RMS_ST_DISCONNECTING;
1072
+			rms_dialog_info_set_state(di, RMS_ST_DISCONNECTING);
1069 1073
 		rms_action_t *a = rms_action_new(RMS_STOP);
1070 1074
 		if(!a)
1071 1075
 			return -1;
1072 1076
 		rms_action_add_sync(di, a);
1073 1077
 		if(di->bridged_di) { // bridged
1074 1078
 			LM_NOTICE("BYE in brigde mode\n");
1079
+			rms_sip_forward(di, msg, method);
1075 1080
 		} else { // connected localy
1076 1081
 			LM_NOTICE("BYE in local mode\n");
1077 1082
 			rms_disconnect(msg);
... ...
@@ -1083,7 +1088,6 @@ static int rms_sip_request_f(struct sip_msg *msg)
1083 1088
 		LM_NOTICE("initial INVITE\n");
1084 1089
 		return 1;
1085 1090
 	} else {
1086
-		LM_NOTICE("in dialog message, state [%d]\n", di->state);
1087 1091
 		if (di->state == RMS_ST_DISCONNECTING) {
1088 1092
 			return -1; // ignore in dialog message in this state
1089 1093
 		} else if (di->state == RMS_ST_DISCONNECTED) {