Browse code

- 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 authored on 24/04/2007 06:01:51
Showing 5 changed files
... ...
@@ -28,6 +28,7 @@
28 28
  * -------
29 29
  * 2003-03-29 Created by janakj
30 30
  * 2003-07-08 added wrapper to calculate_hooks, needed by b2bua (dcm)
31
+ * 2007-04-13 added dialog callbacks (andrei)
31 32
  */
32 33
 
33 34
 
... ...
@@ -59,6 +60,103 @@
59 60
 #define ROUTE_SEPARATOR_LEN (sizeof(ROUTE_SEPARATOR) - 1)
60 61
 
61 62
 
63
+#ifdef DIALOG_CALLBACKS
64
+
65
+struct new_dlg_cb{
66
+	int types;
67
+	struct new_dlg_cb* next;
68
+	dialog_cb* callback;
69
+	void* param;
70
+};
71
+
72
+static struct new_dlg_cb* new_dlg_cb_list=0;
73
+/* callbacks for new dialogs (called each time a new dialog (uas or uac) is
74
+ * created)
75
+ * params: type - DLG_CB_UAC or DLG_CB_UAS
76
+ *            f - callback function
77
+ *        param - parameter passed to the callback; if allocated it must
78
+ *                  be allocated in shared mem.
79
+ * returns < 0 on error
80
+ * WARNING: this callbacks can be registered only before forking (in mod_init)
81
+ */
82
+int register_new_dlg_cb(int type, dialog_cb f, void* param)
83
+{
84
+	struct new_dlg_cb* dlg_cb;
85
+	
86
+	dlg_cb=shm_malloc(sizeof(struct new_dlg_cb));
87
+	if (dlg_cb==0)
88
+		return E_OUT_OF_MEM;
89
+	dlg_cb->types=type;
90
+	dlg_cb->callback=f;
91
+	dlg_cb->param=param;
92
+	dlg_cb->next=new_dlg_cb_list;
93
+	new_dlg_cb_list=dlg_cb;
94
+	return 0;
95
+}
96
+
97
+
98
+void destroy_new_dlg_cbs()
99
+{
100
+	struct new_dlg_cb* c;
101
+	struct new_dlg_cb* n;
102
+
103
+	c=new_dlg_cb_list;
104
+	while(c){
105
+		n=c->next;
106
+		shm_free(c);
107
+		c=n;
108
+	}
109
+	new_dlg_cb_list=0;
110
+}
111
+
112
+
113
+static void run_new_dlg_callbacks(int type, dlg_t* dlg, struct sip_msg* msg)
114
+{
115
+	struct new_dlg_cb* c;
116
+	for (c=new_dlg_cb_list; c; c=c->next){
117
+		if (c->types & type)
118
+			c->callback(type, dlg, msg);
119
+	}
120
+}
121
+
122
+
123
+int register_dlg_tmcb(int types, dlg_t* dlg, transaction_cb f, void* param)
124
+{
125
+	if (types!=TMCB_DLG){
126
+		LOG(L_CRIT, "BUG: tm: register_dlg_tmcb: bad types %d\n", types);
127
+		return E_BUG;
128
+	}
129
+	if (f==0){
130
+		LOG(L_CRIT, "BUG: tm: register_dlg_tmcb: null callback function");
131
+		return E_BUG;
132
+	}
133
+	return insert_tmcb(&dlg->dlg_callbacks, types, f, param);
134
+}
135
+
136
+
137
+/* per dialog callbacks receive only the transaction, send buffer, destination
138
+ * and the retr. buff */
139
+void run_trans_dlg_callbacks(dlg_t* dlg, struct cell* trans,
140
+								struct retr_buf* rbuf)
141
+{
142
+	struct tmcb_params params;
143
+	
144
+	if (dlg->dlg_callbacks.first==0)
145
+		return;
146
+	memset(&params, 0, sizeof(params));
147
+#ifdef TMCB_ONSEND
148
+	params.t_rbuf=rbuf;
149
+	params.dst=&rbuf->dst;
150
+	params.send_buf.s=rbuf->buffer;
151
+	params.send_buf.len=rbuf->buffer_len;
152
+#endif
153
+	
154
+	run_trans_callbacks_internal(&dlg->dlg_callbacks, TMCB_DLG, trans, 
155
+									&params);
156
+}
157
+
158
+#endif /* DIALOG_CALLBACKS */
159
+
62 160
 /*** Temporary hack ! */
63 161
 /*
64 162
  * This function skips name part
... ...
@@ -224,6 +322,9 @@ int new_dlg_uac(str* _cid, str* _ltag, unsigned int _lseq, str* _luri, str* _rur
224 322
 		shm_free(res);
225 323
 		return -2;
226 324
 	}
325
+#ifdef DIALOG_CALLBACKS
326
+	run_new_dlg_callbacks(DLG_CB_UAC, res, 0);
327
+#endif
227 328
 	
228 329
 	return 0;
229 330
 }
... ...
@@ -866,6 +967,9 @@ int new_dlg_uas(struct sip_msg* _req, int _code, /*str* _tag,*/ dlg_t** _d)
866 967
 		free_dlg(res);
867 968
 		return -6;
868 969
 	}
970
+#ifdef DIALOG_CALLBACKS
971
+	run_new_dlg_callbacks(DLG_CB_UAS, res, _req);
972
+#endif
869 973
 
870 974
 	return 0;
871 975
 }
... ...
@@ -26,6 +26,7 @@
26 26
  * History:
27 27
  * -------
28 28
  * 2003-03-29 Created by janakj
29
+ * 2007-04-13 added dialog callbacks (andrei)
29 30
  */
30 31
 
31 32
 #ifndef DLG_H
... ...
@@ -37,6 +38,19 @@
37 38
 #include "../../parser/parse_rr.h"
38 39
 #include "../../parser/msg_parser.h"
39 40
 
41
+/*
42
+#define DIALOG_CALLBACKS
43
+*/
44
+
45
+#ifdef DIALOG_CALLBACKS
46
+#include "t_hooks.h"
47
+#include "h_table.h"
48
+
49
+#define DLG_CB_UAC 30
50
+#define DLG_CB_UAS 31
51
+
52
+#endif /* DIALOG_CALLBACKS */
53
+
40 54
 
41 55
 /*
42 56
  * Dialog sequence
... ...
@@ -104,6 +118,9 @@ typedef struct dlg {
104 118
 				 * can be reused when building a message (to
105 119
 				 * prevent repeated analyzing of the dialog data
106 120
 				 */
121
+#ifdef DIALOG_CALLBACKS
122
+	struct tmcb_head_list dlg_callbacks;
123
+#endif
107 124
 } dlg_t;
108 125
 
109 126
 typedef enum {
... ...
@@ -183,4 +200,27 @@ typedef int (*calculate_hooks_f)(dlg_t* _d);
183 200
 int set_dlg_target(dlg_t* _d, str* _ruri, str* _duri);
184 201
 typedef int (*set_dlg_target_f)(dlg_t* _d, str* _ruri, str* _duri);
185 202
 
203
+#ifdef DIALOG_CALLBACKS
204
+
205
+/* dialog callback
206
+ * params:  type - DLG_UAC or DLG_UAS
207
+ *          dlg  - dialog structure
208
+ *          msg  - message used for creating the new dialog for the new_dlg_uas
209
+ *                 case, 0 otherwise (new_dlg_uac)
210
+ */
211
+typedef void (dialog_cb) (int type, dlg_t* dlg, struct sip_msg* msg);
212
+
213
+/* callbacks for new dialogs (called each time a new dialog (uas or uac) is
214
+ * created). Can be used for installing in-dialog callbacks
215
+ * returns < 0 on error*/
216
+int register_new_dlg_cb(int types, dialog_cb f, void* param);
217
+/* callbacks for messages sent dialogs */
218
+int register_dlg_tmcb(int type, dlg_t* dlg, transaction_cb f, void* param);
219
+void run_trans_dlg_callbacks(dlg_t* dlg, struct cell* trans,
220
+								struct retr_buf* rbuf);
221
+/* cleanup on exit */
222
+void destroy_new_dlg_cbs();
223
+#endif /* DIALOG_CALLBACKS */
224
+
225
+
186 226
 #endif /* DLG_H */
... ...
@@ -216,8 +216,9 @@ int register_tmcb( struct sip_msg* p_msg, struct cell *t, int types,
216 216
 }
217 217
 
218 218
 
219
-static void run_trans_callbacks_internal(int type, struct cell *trans, 
220
-											struct tmcb_params *params)
219
+void run_trans_callbacks_internal(struct tmcb_head_list* cb_lst, int type,
220
+									struct cell *trans, 
221
+									struct tmcb_params *params)
221 222
 {
222 223
 	struct tm_callback    *cbp;
223 224
 	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,
234 235
 			&trans->domain_avps_from);
235 236
 	backup_dom_to = set_avp_list(AVP_CLASS_DOMAIN | AVP_TRACK_TO, 
236 237
 			&trans->domain_avps_to);
237
-	for (cbp=trans->tmcb_hl.first; cbp; cbp=cbp->next)  {
238
+	for (cbp=cb_lst->first; cbp; cbp=cbp->next)  {
238 239
 		if ( (cbp->types)&type ) {
239 240
 			DBG("DBG: trans=%p, callback type %d, id %d entered\n",
240 241
 				trans, type, cbp->id );
... ...
@@ -262,7 +263,7 @@ void run_trans_callbacks( int type , struct cell *trans,
262 263
 	params.req = req;
263 264
 	params.rpl = rpl;
264 265
 	params.code = code;
265
-	run_trans_callbacks_internal(type, trans, &params);
266
+	run_trans_callbacks_internal(&trans->tmcb_hl, type, trans, &params);
266 267
 }
267 268
 
268 269
 
... ...
@@ -286,7 +287,7 @@ void run_onsend_callbacks(int type, struct retr_buf* rbuf, int retr)
286 287
 	params.t_rbuf=rbuf;
287 288
 	params.code=rbuf->activ_type;
288 289
 	/* req, rpl */
289
-	run_trans_callbacks_internal(type, trans, &params);
290
+	run_trans_callbacks_internal(&trans->tmcb_hl, type, trans, &params);
290 291
 }
291 292
 
292 293
 
... ...
@@ -309,7 +310,7 @@ void run_onsend_callbacks2(int type , struct retr_buf* rbuf, char* buf,
309 310
 	params.t_rbuf=rbuf;
310 311
 	params.code=code;
311 312
 	/* req, rpl */
312
-	run_trans_callbacks_internal(type, trans, &params);
313
+	run_trans_callbacks_internal(&trans->tmcb_hl, type, trans, &params);
313 314
 }
314 315
 
315 316
 #endif
... ...
@@ -69,12 +69,13 @@ struct cell;
69 69
 #define TMCB_REQ_RETR_IN_N      11
70 70
 #define TMCB_LOCAL_RESPONSE_IN_N 12
71 71
 #define TMCB_LOCAL_REQUEST_IN_N  13
72
+#define TMCB_DLG_N              14
72 73
 #ifdef TMCB_ONSEND
73
-#define TMCB_REQUEST_SENT_N     14
74
-#define TMCB_RESPONSE_SENT_N    15
75
-#define TMCB_MAX_N              15
74
+#define TMCB_REQUEST_SENT_N     15
75
+#define TMCB_RESPONSE_SENT_N    16
76
+#define TMCB_MAX_N              16
76 77
 #else
77
-#define TMCB_MAX_N              13
78
+#define TMCB_MAX_N              14
78 79
 #endif
79 80
 
80 81
 #define TMCB_REQUEST_IN       (1<<TMCB_REQUEST_IN_N)
... ...
@@ -91,6 +92,7 @@ struct cell;
91 92
 #define TMCB_REQ_RETR_IN      (1<<TMCB_REQ_RETR_IN_N)
92 93
 #define TMCB_LOCAL_RESPONSE_IN (1<<TMCB_LOCAL_RESPONSE_IN_N)
93 94
 #define TMCB_LOCAL_REQUEST_IN (1<<TMCB_LOCAL_REQUEST_IN_N)
95
+#define TMCB_DLG              (1<<TMCB_DLG_N)
94 96
 #ifdef TMCB_ONSEND
95 97
 #define TMCB_REQUEST_SENT      (1<<TMCB_REQUEST_SENT_N)
96 98
 #define TMCB_RESPONSE_SENT     (1<<TMCB_RESPONSE_SENT_N)
... ...
@@ -371,7 +373,10 @@ int insert_tmcb(struct tmcb_head_list *cb_list, int types,
371 373
 /* run all transaction callbacks for an event type */
372 374
 void run_trans_callbacks( int type , struct cell *trans,
373 375
 						struct sip_msg *req, struct sip_msg *rpl, int code );
374
-
376
+/* helper function */
377
+void run_trans_callbacks_internal(struct tmcb_head_list* cb_lst, int type,
378
+									struct cell *trans, 
379
+									struct tmcb_params *params);
375 380
 /* run all REQUEST_IN callbacks */
376 381
 void run_reqin_callbacks( struct cell *trans, struct sip_msg *req, int code );
377 382
 void run_local_reqin_callbacks( struct cell *trans, struct sip_msg *req, 
... ...
@@ -55,6 +55,7 @@
55 55
  *  2006-08-11  t_uac uses dns failover until it finds a send socket (andrei)
56 56
  *  2007-03-15  TMCB_ONSEND callbacks support added (andrei)
57 57
  *  2007-03-23  TMCB_LOCAL_REQUEST_IN callbacks support (andrei)
58
+ *  2007-04-23  per dialog callbacks support (andrei)
58 59
  */
59 60
 
60 61
 #include <string.h>
... ...
@@ -297,6 +298,9 @@ static inline int t_uac_prepare(str* method, str* headers, str* body,
297 298
 	
298 299
 	if (has_local_reqin_tmcbs())
299 300
 			run_local_reqin_callbacks(new_cell, 0, 0);
301
+#ifdef DIALOG_CALLBACKS
302
+	run_trans_dlg_callbacks(dialog, new_cell, request);
303
+#endif /* DIALOG_CALLBACKS */
300 304
 	if (dst_req) *dst_req = request;
301 305
 	if (dst_cell) *dst_cell = new_cell;
302 306