소스 검색

- per new dialog callback, called each time a new UAS (DLG_CB_UAS) or UAC
(DLG_CB_UAC) is created (see dlg.h for details)
- per in-dialog sent message callback, called each time a new message is sent
in a dialog (one should use the new dialog callback to register per message
callbacks for the dialogs he is interested in)
Both of this callbacks are experimental and are disabled by default (one need
to compile with -DDIALOG_CALLBACKS or uncomment the correponding define in
dlg.h).

Andrei Pelinescu-Onciul 18 년 전
부모
커밋
0277f618eb
5개의 변경된 파일165개의 추가작업 그리고 11개의 파일을 삭제
  1. 104 0
      modules/tm/dlg.c
  2. 40 0
      modules/tm/dlg.h
  3. 7 6
      modules/tm/t_hooks.c
  4. 10 5
      modules/tm/t_hooks.h
  5. 4 0
      modules/tm/uac.c

+ 104 - 0
modules/tm/dlg.c

@@ -28,6 +28,7 @@
  * -------
  * 2003-03-29 Created by janakj
  * 2003-07-08 added wrapper to calculate_hooks, needed by b2bua (dcm)
+ * 2007-04-13 added dialog callbacks (andrei)
  */
 
 
@@ -59,6 +60,103 @@
 #define ROUTE_SEPARATOR_LEN (sizeof(ROUTE_SEPARATOR) - 1)
 
 
+#ifdef DIALOG_CALLBACKS
+
+struct new_dlg_cb{
+	int types;
+	struct new_dlg_cb* next;
+	dialog_cb* callback;
+	void* param;
+};
+
+static struct new_dlg_cb* new_dlg_cb_list=0;
+/* callbacks for new dialogs (called each time a new dialog (uas or uac) is
+ * created)
+ * params: type - DLG_CB_UAC or DLG_CB_UAS
+ *            f - callback function
+ *        param - parameter passed to the callback; if allocated it must
+ *                  be allocated in shared mem.
+ * returns < 0 on error
+ * WARNING: this callbacks can be registered only before forking (in mod_init)
+ */
+int register_new_dlg_cb(int type, dialog_cb f, void* param)
+{
+	struct new_dlg_cb* dlg_cb;
+	
+	dlg_cb=shm_malloc(sizeof(struct new_dlg_cb));
+	if (dlg_cb==0)
+		return E_OUT_OF_MEM;
+	dlg_cb->types=type;
+	dlg_cb->callback=f;
+	dlg_cb->param=param;
+	dlg_cb->next=new_dlg_cb_list;
+	new_dlg_cb_list=dlg_cb;
+	return 0;
+}
+
+
+void destroy_new_dlg_cbs()
+{
+	struct new_dlg_cb* c;
+	struct new_dlg_cb* n;
+
+	c=new_dlg_cb_list;
+	while(c){
+		n=c->next;
+		shm_free(c);
+		c=n;
+	}
+	new_dlg_cb_list=0;
+}
+
+
+static void run_new_dlg_callbacks(int type, dlg_t* dlg, struct sip_msg* msg)
+{
+	struct new_dlg_cb* c;
+	for (c=new_dlg_cb_list; c; c=c->next){
+		if (c->types & type)
+			c->callback(type, dlg, msg);
+	}
+}
+
+
+int register_dlg_tmcb(int types, dlg_t* dlg, transaction_cb f, void* param)
+{
+	if (types!=TMCB_DLG){
+		LOG(L_CRIT, "BUG: tm: register_dlg_tmcb: bad types %d\n", types);
+		return E_BUG;
+	}
+	if (f==0){
+		LOG(L_CRIT, "BUG: tm: register_dlg_tmcb: null callback function");
+		return E_BUG;
+	}
+	return insert_tmcb(&dlg->dlg_callbacks, types, f, param);
+}
+
+
+/* per dialog callbacks receive only the transaction, send buffer, destination
+ * and the retr. buff */
+void run_trans_dlg_callbacks(dlg_t* dlg, struct cell* trans,
+								struct retr_buf* rbuf)
+{
+	struct tmcb_params params;
+	
+	if (dlg->dlg_callbacks.first==0)
+		return;
+	memset(&params, 0, sizeof(params));
+#ifdef TMCB_ONSEND
+	params.t_rbuf=rbuf;
+	params.dst=&rbuf->dst;
+	params.send_buf.s=rbuf->buffer;
+	params.send_buf.len=rbuf->buffer_len;
+#endif
+	
+	run_trans_callbacks_internal(&dlg->dlg_callbacks, TMCB_DLG, trans, 
+									&params);
+}
+
+#endif /* DIALOG_CALLBACKS */
+
 /*** Temporary hack ! */
 /*
  * This function skips name part
@@ -224,6 +322,9 @@ int new_dlg_uac(str* _cid, str* _ltag, unsigned int _lseq, str* _luri, str* _rur
 		shm_free(res);
 		return -2;
 	}
+#ifdef DIALOG_CALLBACKS
+	run_new_dlg_callbacks(DLG_CB_UAC, res, 0);
+#endif
 	
 	return 0;
 }
@@ -866,6 +967,9 @@ int new_dlg_uas(struct sip_msg* _req, int _code, /*str* _tag,*/ dlg_t** _d)
 		free_dlg(res);
 		return -6;
 	}
+#ifdef DIALOG_CALLBACKS
+	run_new_dlg_callbacks(DLG_CB_UAS, res, _req);
+#endif
 
 	return 0;
 }

+ 40 - 0
modules/tm/dlg.h

@@ -26,6 +26,7 @@
  * History:
  * -------
  * 2003-03-29 Created by janakj
+ * 2007-04-13 added dialog callbacks (andrei)
  */
 
 #ifndef DLG_H
@@ -37,6 +38,19 @@
 #include "../../parser/parse_rr.h"
 #include "../../parser/msg_parser.h"
 
+/*
+#define DIALOG_CALLBACKS
+*/
+
+#ifdef DIALOG_CALLBACKS
+#include "t_hooks.h"
+#include "h_table.h"
+
+#define DLG_CB_UAC 30
+#define DLG_CB_UAS 31
+
+#endif /* DIALOG_CALLBACKS */
+
 
 /*
  * Dialog sequence
@@ -104,6 +118,9 @@ typedef struct dlg {
 				 * can be reused when building a message (to
 				 * prevent repeated analyzing of the dialog data
 				 */
+#ifdef DIALOG_CALLBACKS
+	struct tmcb_head_list dlg_callbacks;
+#endif
 } dlg_t;
 
 typedef enum {
@@ -183,4 +200,27 @@ typedef int (*calculate_hooks_f)(dlg_t* _d);
 int set_dlg_target(dlg_t* _d, str* _ruri, str* _duri);
 typedef int (*set_dlg_target_f)(dlg_t* _d, str* _ruri, str* _duri);
 
+#ifdef DIALOG_CALLBACKS
+
+/* dialog callback
+ * params:  type - DLG_UAC or DLG_UAS
+ *          dlg  - dialog structure
+ *          msg  - message used for creating the new dialog for the new_dlg_uas
+ *                 case, 0 otherwise (new_dlg_uac)
+ */
+typedef void (dialog_cb) (int type, dlg_t* dlg, struct sip_msg* msg);
+
+/* callbacks for new dialogs (called each time a new dialog (uas or uac) is
+ * created). Can be used for installing in-dialog callbacks
+ * returns < 0 on error*/
+int register_new_dlg_cb(int types, dialog_cb f, void* param);
+/* callbacks for messages sent dialogs */
+int register_dlg_tmcb(int type, dlg_t* dlg, transaction_cb f, void* param);
+void run_trans_dlg_callbacks(dlg_t* dlg, struct cell* trans,
+								struct retr_buf* rbuf);
+/* cleanup on exit */
+void destroy_new_dlg_cbs();
+#endif /* DIALOG_CALLBACKS */
+
+
 #endif /* DLG_H */

+ 7 - 6
modules/tm/t_hooks.c

@@ -216,8 +216,9 @@ int register_tmcb( struct sip_msg* p_msg, struct cell *t, int types,
 }
 
 
-static void run_trans_callbacks_internal(int type, struct cell *trans, 
-											struct tmcb_params *params)
+void run_trans_callbacks_internal(struct tmcb_head_list* cb_lst, int type,
+									struct cell *trans, 
+									struct tmcb_params *params)
 {
 	struct tm_callback    *cbp;
 	avp_list_t* backup_from, *backup_to, *backup_dom_from, *backup_dom_to, *backup_uri_from, *backup_uri_to;
@@ -234,7 +235,7 @@ static void run_trans_callbacks_internal(int type, struct cell *trans,
 			&trans->domain_avps_from);
 	backup_dom_to = set_avp_list(AVP_CLASS_DOMAIN | AVP_TRACK_TO, 
 			&trans->domain_avps_to);
-	for (cbp=trans->tmcb_hl.first; cbp; cbp=cbp->next)  {
+	for (cbp=cb_lst->first; cbp; cbp=cbp->next)  {
 		if ( (cbp->types)&type ) {
 			DBG("DBG: trans=%p, callback type %d, id %d entered\n",
 				trans, type, cbp->id );
@@ -262,7 +263,7 @@ void run_trans_callbacks( int type , struct cell *trans,
 	params.req = req;
 	params.rpl = rpl;
 	params.code = code;
-	run_trans_callbacks_internal(type, trans, &params);
+	run_trans_callbacks_internal(&trans->tmcb_hl, type, trans, &params);
 }
 
 
@@ -286,7 +287,7 @@ void run_onsend_callbacks(int type, struct retr_buf* rbuf, int retr)
 	params.t_rbuf=rbuf;
 	params.code=rbuf->activ_type;
 	/* req, rpl */
-	run_trans_callbacks_internal(type, trans, &params);
+	run_trans_callbacks_internal(&trans->tmcb_hl, type, trans, &params);
 }
 
 
@@ -309,7 +310,7 @@ void run_onsend_callbacks2(int type , struct retr_buf* rbuf, char* buf,
 	params.t_rbuf=rbuf;
 	params.code=code;
 	/* req, rpl */
-	run_trans_callbacks_internal(type, trans, &params);
+	run_trans_callbacks_internal(&trans->tmcb_hl, type, trans, &params);
 }
 
 #endif

+ 10 - 5
modules/tm/t_hooks.h

@@ -69,12 +69,13 @@ struct cell;
 #define TMCB_REQ_RETR_IN_N      11
 #define TMCB_LOCAL_RESPONSE_IN_N 12
 #define TMCB_LOCAL_REQUEST_IN_N  13
+#define TMCB_DLG_N              14
 #ifdef TMCB_ONSEND
-#define TMCB_REQUEST_SENT_N     14
-#define TMCB_RESPONSE_SENT_N    15
-#define TMCB_MAX_N              15
+#define TMCB_REQUEST_SENT_N     15
+#define TMCB_RESPONSE_SENT_N    16
+#define TMCB_MAX_N              16
 #else
-#define TMCB_MAX_N              13
+#define TMCB_MAX_N              14
 #endif
 
 #define TMCB_REQUEST_IN       (1<<TMCB_REQUEST_IN_N)
@@ -91,6 +92,7 @@ struct cell;
 #define TMCB_REQ_RETR_IN      (1<<TMCB_REQ_RETR_IN_N)
 #define TMCB_LOCAL_RESPONSE_IN (1<<TMCB_LOCAL_RESPONSE_IN_N)
 #define TMCB_LOCAL_REQUEST_IN (1<<TMCB_LOCAL_REQUEST_IN_N)
+#define TMCB_DLG              (1<<TMCB_DLG_N)
 #ifdef TMCB_ONSEND
 #define TMCB_REQUEST_SENT      (1<<TMCB_REQUEST_SENT_N)
 #define TMCB_RESPONSE_SENT     (1<<TMCB_RESPONSE_SENT_N)
@@ -371,7 +373,10 @@ int insert_tmcb(struct tmcb_head_list *cb_list, int types,
 /* run all transaction callbacks for an event type */
 void run_trans_callbacks( int type , struct cell *trans,
 						struct sip_msg *req, struct sip_msg *rpl, int code );
-
+/* helper function */
+void run_trans_callbacks_internal(struct tmcb_head_list* cb_lst, int type,
+									struct cell *trans, 
+									struct tmcb_params *params);
 /* run all REQUEST_IN callbacks */
 void run_reqin_callbacks( struct cell *trans, struct sip_msg *req, int code );
 void run_local_reqin_callbacks( struct cell *trans, struct sip_msg *req, 

+ 4 - 0
modules/tm/uac.c

@@ -55,6 +55,7 @@
  *  2006-08-11  t_uac uses dns failover until it finds a send socket (andrei)
  *  2007-03-15  TMCB_ONSEND callbacks support added (andrei)
  *  2007-03-23  TMCB_LOCAL_REQUEST_IN callbacks support (andrei)
+ *  2007-04-23  per dialog callbacks support (andrei)
  */
 
 #include <string.h>
@@ -297,6 +298,9 @@ static inline int t_uac_prepare(str* method, str* headers, str* body,
 	
 	if (has_local_reqin_tmcbs())
 			run_local_reqin_callbacks(new_cell, 0, 0);
+#ifdef DIALOG_CALLBACKS
+	run_trans_dlg_callbacks(dialog, new_cell, request);
+#endif /* DIALOG_CALLBACKS */
 	if (dst_req) *dst_req = request;
 	if (dst_cell) *dst_cell = new_cell;