Răsfoiți Sursa

uac: new fields in $uac_req() to allow execution of event route on reply

- attributes:
  - evroute - set to 1 to enable execution of event route
  - evparam - generic string value that will be available in event route
  - evcode - sip reply code, available in event route
  - evtype - type of the reply - received or local generated (e.g.,
    timout)
Daniel-Constantin Mierla 10 ani în urmă
părinte
comite
52d08e0bde
1 a modificat fișierele cu 94 adăugiri și 22 ștergeri
  1. 94 22
      modules/uac/uac_send.c

+ 94 - 22
modules/uac/uac_send.c

@@ -34,6 +34,7 @@
 
 #define MAX_UACH_SIZE 2048
 #define MAX_UACB_SIZE 4086
+#define MAX_UACD_SIZE 128
 
 /** TM bind */
 struct tm_binds tmb;
@@ -62,11 +63,32 @@ typedef struct _uac_send_info {
 	str   s_auser;
 	char  b_apasswd[64];
 	str   s_apasswd;
-	unsigned int onreply;
+	char  b_evparam[MAX_UACD_SIZE];
+	str   s_evparam;
+	unsigned int evroute;
+	unsigned int evcode;
+	unsigned int evtype;
 } uac_send_info_t;
 
 static struct _uac_send_info _uac_req;
 
+void uac_send_info_copy(uac_send_info_t *src, uac_send_info_t *dst)
+{
+	memcpy(dst, src, sizeof(uac_send_info_t));
+	dst->s_method.s  = dst->b_method;
+	dst->s_ruri.s    = dst->b_ruri;
+	dst->s_turi.s    = dst->b_turi;
+	dst->s_furi.s    = dst->b_furi;
+	dst->s_hdrs.s    = dst->b_hdrs;
+	dst->s_body.s    = dst->b_body;
+	dst->s_ouri.s    = dst->b_ouri;
+	dst->s_auser.s   = dst->b_auser;
+	dst->s_apasswd.s = dst->b_apasswd;
+	dst->s_callid.s  = dst->b_callid;
+	dst->s_sock.s    = dst->b_sock;
+	dst->s_evparam.s = dst->b_evparam;
+}
+
 uac_send_info_t *uac_send_info_clone(uac_send_info_t *ur)
 {
 	uac_send_info_t *tp = NULL;
@@ -76,18 +98,7 @@ uac_send_info_t *uac_send_info_clone(uac_send_info_t *ur)
 		LM_ERR("no more shm memory\n");
 		return NULL;
 	}
-	memcpy(tp, ur, sizeof(uac_send_info_t));
-	tp->s_method.s  = tp->b_method;
-	tp->s_ruri.s    = tp->b_ruri;
-	tp->s_turi.s    = tp->b_turi;
-	tp->s_furi.s    = tp->b_furi;
-	tp->s_hdrs.s    = tp->b_hdrs;
-	tp->s_body.s    = tp->b_body;
-	tp->s_ouri.s    = tp->b_ouri;
-	tp->s_auser.s   = tp->b_auser;
-	tp->s_apasswd.s = tp->b_apasswd;
-	tp->s_callid.s  = tp->b_callid;
-	tp->s_sock.s    = tp->b_sock;
+	uac_send_info_copy(ur, tp);
 
 	return tp;
 }
@@ -130,6 +141,8 @@ int pv_get_uac_req(struct sip_msg *msg, pv_param_t *param,
 			if(_uac_req.s_method.len<=0)
 				return pv_get_null(msg, param, res);
 			return pv_get_strval(msg, param, res, &_uac_req.s_method);
+		case 8:
+			return pv_get_uintval(msg, param, res, _uac_req.evroute);
 		case 9:
 			if(_uac_req.s_auser.len<=0)
 				return pv_get_null(msg, param, res);
@@ -146,6 +159,14 @@ int pv_get_uac_req(struct sip_msg *msg, pv_param_t *param,
 			if(_uac_req.s_sock.len<=0)
 				return pv_get_null(msg, param, res);
 			return pv_get_strval(msg, param, res, &_uac_req.s_sock);
+		case 14:
+			if(_uac_req.s_evparam.len<=0)
+				return pv_get_null(msg, param, res);
+			return pv_get_strval(msg, param, res, &_uac_req.s_evparam);
+		case 15:
+			return pv_get_uintval(msg, param, res, _uac_req.evcode);
+		case 16:
+			return pv_get_uintval(msg, param, res, _uac_req.evtype);
 		default:
 			return pv_get_uintval(msg, param, res, _uac_req.flags);
 	}
@@ -171,8 +192,11 @@ int pv_set_uac_req(struct sip_msg* msg, pv_param_t *param,
 				_uac_req.s_hdrs.len = 0;
 				_uac_req.s_body.len = 0;
 				_uac_req.s_method.len = 0;
-				_uac_req.onreply = 0;
 				_uac_req.s_callid.len = 0;
+				_uac_req.evroute = 0;
+				_uac_req.evtype = 0;
+				_uac_req.evcode = 0;
+				_uac_req.s_evparam.len = 0;
 			}
 			break;
 		case 1:
@@ -318,7 +342,7 @@ int pv_set_uac_req(struct sip_msg* msg, pv_param_t *param,
 		case 8:
 			if(val==NULL)
 			{
-				_uac_req.onreply = 0;
+				_uac_req.evroute = 0;
 				return 0;
 			}
 			if(!(val->flags&PV_VAL_INT))
@@ -326,12 +350,7 @@ int pv_set_uac_req(struct sip_msg* msg, pv_param_t *param,
 				LM_ERR("Invalid value type\n");
 				return -1;
 			}
-			if(val->ri>=ONREPLY_RT_NO)
-			{
-				LM_ERR("Value too big\n");
-				return -1;
-			}
-			_uac_req.onreply = val->ri;
+			_uac_req.evroute = val->ri;
 			break;
 		case 9:
 			if(val==NULL)
@@ -408,6 +427,52 @@ int pv_set_uac_req(struct sip_msg* msg, pv_param_t *param,
 			_uac_req.s_sock.s[val->rs.len] = '\0';
 			_uac_req.s_sock.len = val->rs.len;
 			break;
+		case 14:
+			if(val==NULL)
+			{
+				_uac_req.s_evparam.len = 0;
+				return 0;
+			}
+			if(!(val->flags&PV_VAL_STR))
+			{
+				LM_ERR("Invalid value type\n");
+				return -1;
+			}
+			if(val->rs.len>=MAX_UACD_SIZE)
+			{
+				LM_ERR("Value size too big\n");
+				return -1;
+			}
+			memcpy(_uac_req.s_evparam.s, val->rs.s, val->rs.len);
+			_uac_req.s_evparam.s[val->rs.len] = '\0';
+			_uac_req.s_evparam.len = val->rs.len;
+			break;
+		case 15:
+			if(val==NULL)
+			{
+				_uac_req.evcode = 0;
+				return 0;
+			}
+			if(!(val->flags&PV_VAL_INT))
+			{
+				LM_ERR("Invalid value type\n");
+				return -1;
+			}
+			_uac_req.evcode = val->ri;
+			break;
+		case 16:
+			if(val==NULL)
+			{
+				_uac_req.evtype = 0;
+				return 0;
+			}
+			if(!(val->flags&PV_VAL_INT))
+			{
+				LM_ERR("Invalid value type\n");
+				return -1;
+			}
+			_uac_req.evtype = val->ri;
+			break;
 	}
 	return 0;
 }
@@ -451,13 +516,19 @@ int pv_parse_uac_req_name(pv_spec_p sp, str *in)
 				sp->pvp.pvn.u.isname.name.n = 7;
 			else if(strncmp(in->s, "callid", 6)==0)
 				sp->pvp.pvn.u.isname.name.n = 11;
+			else if(strncmp(in->s, "evcode", 6)==0)
+				sp->pvp.pvn.u.isname.name.n = 15;
+			else if(strncmp(in->s, "evtype", 6)==0)
+				sp->pvp.pvn.u.isname.name.n = 16;
 			else goto error;
 		break;
 		case 7: 
-			if(strncmp(in->s, "onreply", 7)==0)
+			if(strncmp(in->s, "evroute", 7)==0)
 				sp->pvp.pvn.u.isname.name.n = 8;
 			else if(strncmp(in->s, "apasswd", 7)==0)
 				sp->pvp.pvn.u.isname.name.n = 10;
+			else if(strncmp(in->s, "evparam", 7)==0)
+				sp->pvp.pvn.u.isname.name.n = 14;
 			else goto error;
 		break;
 		default:
@@ -493,6 +564,7 @@ void uac_req_init(void)
 	_uac_req.s_apasswd.s  = _uac_req.b_apasswd;
 	_uac_req.s_callid.s   = _uac_req.b_callid;
 	_uac_req.s_sock.s     = _uac_req.b_sock;
+	_uac_req.s_evparam.s  = _uac_req.b_evparam;
 	return;
 }