Browse Source

dialog: added dlg_update_state() function

Daniel-Constantin Mierla 9 months ago
parent
commit
0acd9c9106
3 changed files with 98 additions and 4 deletions
  1. 19 0
      src/modules/dialog/dialog.c
  2. 74 4
      src/modules/dialog/dlg_handlers.c
  3. 5 0
      src/modules/dialog/dlg_handlers.h

+ 19 - 0
src/modules/dialog/dialog.c

@@ -221,6 +221,7 @@ static int w_dlg_req_with_content(
 static int w_dlg_req_with_headers(struct sip_msg *, char *, char *, char *);
 static int w_dlg_req_within(struct sip_msg *, char *, char *);
 static int w_dlg_set_state(sip_msg_t *, char *, char *);
+static int w_dlg_update_state(sip_msg_t *, char *, char *);
 
 static int fixup_dlg_dlg_req_within(void **, int);
 static int fixup_dlg_req_with_headers(void **, int);
@@ -233,6 +234,8 @@ static cmd_export_t cmds[]={
 			0, REQUEST_ROUTE },
 	{"dlg_set_state", (cmd_function)w_dlg_set_state,      1,fixup_spve_null,
 			fixup_free_spve_null, ANY_ROUTE },
+	{"dlg_update_state", (cmd_function)w_dlg_update_state, 0,0,
+			0, REQUEST_ROUTE| FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE },
 	{"set_dlg_profile", (cmd_function)w_set_dlg_profile,  1,fixup_profile,
 			0, ANY_ROUTE },
 	{"set_dlg_profile", (cmd_function)w_set_dlg_profile,  2,fixup_profile,
@@ -1202,6 +1205,22 @@ static int w_dlg_set_state(sip_msg_t *msg, char *pstate, char *p2)
 	return ki_dlg_set_state(msg, &state);
 }
 
+/**
+ *
+ */
+static int ki_dlg_update_state(sip_msg_t *msg, str *state)
+{
+	return dlg_update_state(msg);
+}
+
+/**
+ *
+ */
+static int w_dlg_update_state(sip_msg_t *msg, char *pstate, char *p2)
+{
+	return dlg_update_state(msg);
+}
+
 static int fixup_dlg_dlg_req_within(void **param, int param_no)
 {
 	char *val;

+ 74 - 4
src/modules/dialog/dlg_handlers.c

@@ -1927,12 +1927,82 @@ int dlg_set_state(sip_msg_t *msg, int istate)
 		dlg->end_ts = (unsigned int)(time(0));
 	}
 	dlg->dflags |= DLG_FLAG_CHANGED;
+	dlg_release(dlg);
+
+	return 0;
+}
+
+/*!
+ *
+ */
+int dlg_update_state(sip_msg_t *msg)
+{
+	str sc = STR_NULL;
+	str sf = STR_NULL;
+	str st = STR_NULL;
+	dlg_cell_t *dlg = NULL;
+	unsigned int dir = 0;
+	int old_state = 0;
+	int new_state = 0;
+	int event = 0;
+	int unref = 0;
+
+	if(msg->callid == NULL
+			&& ((parse_headers(msg, HDR_CALLID_F, 0) == -1)
+					|| (msg->callid == NULL))) {
+		LM_ERR("cannot parse Call-Id header\n");
+		return -1;
+	}
+	if(parse_from_header(msg) < 0) {
+		LM_ERR("cannot parse From header\n");
+		return -1;
+	}
+	if(parse_to_header(msg) < 0) {
+		LM_ERR("cannot parse To header\n");
+		return -1;
+	}
+	if(msg->first_line.type != SIP_REQUEST
+			&& msg->first_line.type != SIP_REPLY) {
+		LM_ERR("unknown message type\n");
+		return -1;
+	}
+	sc = msg->callid->body;
+	sf = get_from(msg)->tag_value;
+	st = get_to(msg)->tag_value;
+
 	if(msg->first_line.type == SIP_REQUEST) {
-		LM_DBG("handling request - oldstate: %d newstate: %d\n", ostate,
-				istate);
+		switch(msg->first_line.u.request.method_value) {
+			case METHOD_PRACK:
+				event = DLG_EVENT_REQPRACK;
+				break;
+			case METHOD_ACK:
+				event = DLG_EVENT_REQACK;
+				break;
+			case METHOD_BYE:
+				event = DLG_EVENT_REQBYE;
+				break;
+			default:
+				event = DLG_EVENT_REQ;
+		}
 	} else {
-		LM_DBG("handling response - oldstate: %d newstate: %d\n", ostate,
-				istate);
+		if(msg->first_line.u.reply.statuscode < 200) {
+			event = DLG_EVENT_RPL1xx;
+		} else if(msg->first_line.u.reply.statuscode < 300) {
+			event = DLG_EVENT_RPL2xx;
+		} else {
+			event = DLG_EVENT_RPL3xx;
+		}
+	}
+
+	dlg = get_dlg(&sc, &sf, &st, &dir);
+	if(dlg == NULL) {
+		LM_DBG("dialog not found\n");
+		return -1;
+	}
+	next_state_dlg(dlg, event, &old_state, &new_state, &unref);
+	dlg->dflags |= DLG_FLAG_CHANGED;
+	if(unref > 0) {
+		dlg_unref(dlg, unref);
 	}
 	dlg_release(dlg);
 

+ 5 - 0
src/modules/dialog/dlg_handlers.h

@@ -186,4 +186,9 @@ int dlg_manage(sip_msg_t *msg);
  */
 int dlg_set_state(sip_msg_t *msg, int istate);
 
+/*!
+ *
+ */
+int dlg_update_state(sip_msg_t *msg);
+
 #endif