Browse code

- global callbacks replaced by callbacks per transaction - per type callback list merged into a single one - TMCB_ON_FAILURE callback type addded - completion callback used by t_uac merged into transaction callbacks as TMCB_LOCAL_COMPLETED

Bogdan-Andrei Iancu authored on 05/12/2003 14:29:12
Showing 14 changed files
... ...
@@ -34,6 +34,8 @@
34 34
  * 2003-04-04  bug_fix: REQ_IN callback not called for local 
35 35
  *             UAC transactions (jiri)
36 36
  * 2003-09-12  timer_link->tg will be set only if EXTRA_DEBUG (andrei)
37
+ * 2003-12-04  global callbacks replaceed with callbacks per transaction;
38
+ *             completion callback merged into them as LOCAL_COMPETED (bogdan)
37 39
  */
38 40
 
39 41
 #include "defs.h"
... ...
@@ -106,6 +108,7 @@ void free_cell( struct cell* dead_cell )
106 108
 	int i;
107 109
 	struct sip_msg *rpl;
108 110
 	struct totag_elem *tt, *foo;
111
+	struct tm_callback *cbs, *cbs_tmp;
109 112
 
110 113
 	release_cell_lock( dead_cell );
111 114
 	shm_lock();
... ...
@@ -116,8 +119,12 @@ void free_cell( struct cell* dead_cell )
116 119
 	if ( dead_cell->uas.response.buffer )
117 120
 		shm_free_unsafe( dead_cell->uas.response.buffer );
118 121
 
119
-	/* completion callback */
120
-	if (dead_cell->cbp) shm_free_unsafe(dead_cell->cbp);
122
+	/* callbacks */
123
+	for( cbs=dead_cell->tmcb_hl.first ; cbs ; ) {
124
+		cbs_tmp = cbs;
125
+		cbs = cbs->next;
126
+		shm_free_unsafe( cbs_tmp );
127
+	}
121 128
 
122 129
 	/* UA Clients */
123 130
 	for ( i =0 ; i<dead_cell->nr_of_outgoings;  i++ )
... ...
@@ -183,15 +190,10 @@ struct cell*  build_cell( struct sip_msg* p_msg )
183 190
 	new_cell->uas.response.retr_timer.payload = &(new_cell->uas.response);
184 191
 	new_cell->uas.response.my_T=new_cell;
185 192
 
186
-	/* bogdan - debug */
187
-	/*fprintf(stderr,"before clone VIA |%.*s|\n",via_len(p_msg->via1),
188
-		via_s(p_msg->via1,p_msg));*/
189
-
190 193
 	/* enter callback, which may potentially want to parse some stuff,
191
-	   before the request is shmem-ized
192
-	*/ 
193
-    if (p_msg) callback_event(TMCB_REQUEST_IN, new_cell, p_msg,
194
-            p_msg->REQ_METHOD );
194
+	 * before the request is shmem-ized */
195
+	if ( p_msg && has_reqin_tmcbs() )
196
+		run_reqin_callbacks( new_cell, p_msg, p_msg->REQ_METHOD);
195 197
 
196 198
 	if (p_msg) {
197 199
 		new_cell->uas.request = sip_msg_cloner(p_msg);
... ...
@@ -29,6 +29,8 @@
29 29
  * 2003-03-16  removed _TOTAG (jiri)
30 30
  * 2003-03-06  we keep a list of 200/INV to-tags now (jiri)
31 31
  * 2003-03-01  kr set through a function now (jiri)
32
+ * 2003-12-04  callbacks per transaction added; completion callback
33
+ *             merge into them as LOCAL_COMPETED (bogdan)
32 34
  */
33 35
 
34 36
 #include "defs.h"
... ...
@@ -174,21 +176,15 @@ typedef struct cell
174 176
 	   with proxied transactions to inbound request */
175 177
 	str from, callid, cseq_n, to;
176 178
 	/* a short-cut for remember whether this transaction needs
177
-	   INVITE-special handling (e.g., CANCEL, ACK, FR...)
178
-	*/
179
+	   INVITE-special handling (e.g., CANCEL, ACK, FR...)  */
179 180
 	short is_invite;
180 181
 	/* method shortcut -- for local transactions, pointer to
181 182
 	   outbound buffer, for proxies transactions pointer to
182
-	   original message; needed for reply matching
183
-	*/
183
+	   original message; needed for reply matching */
184 184
 	str method;
185 185
 
186
-	/* callback and parameter on completion of local transactions */
187
-	transaction_cb *completion_cb;
188
-	/* the parameter stores a pointer to shmem -- it will be released
189
-	   during freeing transaction too
190
-	*/
191
-	void *cbp;
186
+	/* head of callback list */
187
+	struct tmcb_head_list tmcb_hl;
192 188
 
193 189
 	/* how many processes are currently processing this transaction ;
194 190
 	   note that only processes working on a request/reply belonging
... ...
@@ -110,6 +110,8 @@ void tm_shutdown()
110 110
 	free_timer_table();
111 111
 	DBG("DEBUG: tm_shutdown : removing semaphores\n");
112 112
 	lock_cleanup();
113
+	DBG("DEBUG: tm_shutdown : destroing tmcb lists\n");
114
+	destroy_tmcb_lists();
113 115
 	free_tm_stats();
114 116
 	DBG("DEBUG: tm_shutdown : done\n");
115 117
 }
... ...
@@ -39,6 +39,8 @@
39 39
  *  2003-03-30  we now watch downstream delivery and if it fails, send an
40 40
  *              error message upstream (jiri)
41 41
  *  2003-04-14  use protocol from uri (jiri)
42
+ *  2003-12-04  global TM callbacks switched to per transaction callbacks
43
+ *              (bogdan)
42 44
  */
43 45
 
44 46
 #include "defs.h"
... ...
@@ -83,8 +85,8 @@ char *print_uac_request( struct cell *t, struct sip_msg *i_req,
83 85
 	/* ... update uri ... */
84 86
 	i_req->new_uri=*uri;
85 87
 
86
-	/* ... give apps a chance to change things ... */
87
-	callback_event( TMCB_REQUEST_FWDED, t, i_req, -i_req->REQ_METHOD);
88
+	/* run the specific callbacks for this transaction */
89
+	run_trans_callbacks( TMCB_REQUEST_FWDED , t, i_req, 0, -i_req->REQ_METHOD);
88 90
 
89 91
 	/* ... and build it now */
90 92
 	buf=build_req_buf_from_sip_req( i_req, len, send_sock, proto );
... ...
@@ -28,6 +28,9 @@
28 28
  * History:
29 29
  * --------
30 30
  *  2003-03-19  replaced all the mallocs/frees w/ pkg_malloc/pkg_free (andrei)
31
+ *  2003-12-04  global callbacks moved into transaction callbacks;
32
+ *              multiple events per callback added; single list per
33
+ *              transaction for all its callbacks (bogdan)
31 34
  */
32 35
 
33 36
 #include "defs.h"
... ...
@@ -38,46 +41,150 @@
38 41
 #include "../../error.h"
39 42
 #include "../../mem/mem.h"
40 43
 #include "t_hooks.h"
44
+#include "t_lookup.h"
45
+#include "t_funcs.h"
41 46
 
42
-/* strange things happen if callback_array is static on openbsd */
43
-struct tm_callback_s* callback_array[ TMCB_END ] = { 0, 0 } ;
44
-static int callback_id=0;
45 47
 
46
-/* register a callback function 'f' of type 'cbt'; will be called
47
-   back whenever the event 'cbt' occurs in transaction module
48
-*/
49
-int register_tmcb( tmcb_type cbt, transaction_cb f, void *param )
48
+struct tmcb_head_list* req_in_tmcb_hl = 0;
49
+
50
+
51
+
52
+int init_tmcb_lists()
53
+{
54
+	req_in_tmcb_hl = (struct tmcb_head_list*)shm_malloc
55
+		( sizeof(struct tmcb_head_list) );
56
+	if (req_in_tmcb_hl==0) {
57
+		LOG(L_CRIT,"ERROR:tm:init_tmcb_lists: nomore shared mem\n");
58
+		return -1;
59
+	}
60
+	req_in_tmcb_hl->first = 0;
61
+	req_in_tmcb_hl->reg_types = 0;
62
+	return 1;
63
+}
64
+
65
+
66
+void destroy_tmcb_lists()
50 67
 {
51
-	struct tm_callback_s *cbs;
68
+	struct tm_callback *cbp, *cbp_tmp;
52 69
 
53
-	if (cbt<0 || cbt>=TMCB_END ) {
54
-		LOG(L_ERR, "ERROR: register_tmcb: invalid callback type: %d\n",
55
-			cbt );
56
-		return E_BUG;
70
+	if (!req_in_tmcb_hl)
71
+		return;
72
+
73
+	for( cbp=req_in_tmcb_hl->first; cbp ; ) {
74
+		cbp_tmp = cbp;
75
+		cbp = cbp->next;
76
+		if (cbp->param) shm_free( cbp->param );
77
+		shm_free( cbp_tmp );
57 78
 	}
58 79
 
59
-	if (!(cbs=pkg_malloc( sizeof( struct tm_callback_s)))) {
60
-		LOG(L_ERR, "ERROR: register_tmcb: out of mem\n");
80
+	shm_free(req_in_tmcb_hl);
81
+}
82
+
83
+
84
+inline int insert_tmcb(struct tmcb_head_list *cb_list, int types,
85
+									transaction_cb f, void *param )
86
+{
87
+	struct tm_callback *cbp;
88
+
89
+	/* build a new callback structure */
90
+	if (!(cbp=shm_malloc( sizeof( struct tm_callback)))) {
91
+		LOG(L_ERR, "ERROR:tm:register_tmcb: out of shm. mem\n");
61 92
 		return E_OUT_OF_MEM;
62 93
 	}
63 94
 
64
-	callback_id++;
65
-	cbs->id=callback_id;
66
-	cbs->callback=f;
67
-	cbs->next=callback_array[ cbt ];
68
-	cbs->param=param;
69
-	callback_array[ cbt ]=cbs;
95
+	/* link it into the proper place... */
96
+	cbp->next = cb_list->first;
97
+	cb_list->first = cbp;
98
+	cb_list->reg_types |= types;
99
+	/* ... and fill it up */
100
+	cbp->callback = f;
101
+	cbp->param = param;
102
+	cbp->types = types;
103
+	if (cbp->next)
104
+		cbp->id = cbp->next->id+1;
105
+	else
106
+		cbp->id = 0;
107
+
108
+	return 1;
109
+}
110
+
111
+
112
+
113
+/* register a callback function 'f' for 'types' mask of events;
114
+ * will be called back whenever one of the events occurs in transaction module
115
+ * (global or per transacation, depinding of event type)
116
+*/
117
+int register_tmcb( struct sip_msg* p_msg, int types, transaction_cb f,
118
+																void *param )
119
+{
120
+	struct cell* t;
121
+	struct tmcb_head_list *cb_list;
122
+
123
+	/* are the callback types valid?... */
124
+	if ( types<0 || types>=TMCB_MAX ) {
125
+		LOG(L_CRIT, "BUG:tm:register_tmcb: invalid callback types: mask=%d\n",
126
+			types);
127
+		return E_BUG;
128
+	}
129
+	if (types&TMCB_REQUEST_IN) {
130
+		if (types!=TMCB_REQUEST_IN) {
131
+			LOG(L_CRIT, "BUG:tm:register_tmcb: callback type TMCB_REQUEST_IN "
132
+				"can't be register along with types\n");
133
+			return E_BUG;
134
+		}
135
+		cb_list = req_in_tmcb_hl;
136
+	} else {
137
+		/* look for the transaction */
138
+		if ( t_check(p_msg,0)!=1 ){
139
+			LOG(L_CRIT,"BUG:tm:register_tmcb: no transaction found\n");
140
+			return E_BUG;
141
+		}
142
+		if ( (t=get_t())==0 ) {
143
+			LOG(L_CRIT,"BUG:tm:register_tmcb: transaction found is NULL\n");
144
+			return E_BUG;
145
+		}
146
+		cb_list = &(t->tmcb_hl);
147
+	}
148
+
149
+	return insert_tmcb( cb_list, types, f, param );
150
+}
70 151
 
71
-	return callback_id;
152
+
153
+void run_trans_callbacks( int type , struct cell *trans,
154
+						struct sip_msg *req, struct sip_msg *rpl, int code )
155
+{
156
+	static struct tmcb_params params = {0,0,0,0};
157
+	struct tm_callback    *cbp;
158
+
159
+	params.req = req;
160
+	params.rpl = rpl;
161
+	params.code = code;
162
+
163
+	for (cbp=trans->tmcb_hl.first; cbp; cbp=cbp->next)  {
164
+		if ( (cbp->types)&type ) {
165
+			DBG("DBG: trans=%p, callback type %d, id %d entered\n",
166
+				trans, type, cbp->id );
167
+			params.param = cbp->param;
168
+			cbp->callback( trans, type, &params );
169
+		}
170
+	}
72 171
 }
73 172
 
74
-void callback_event( tmcb_type cbt , struct cell *trans,
75
-	struct sip_msg *msg, int code )
173
+
174
+
175
+void run_reqin_callbacks( struct cell *trans, struct sip_msg *req, int code )
76 176
 {
77
-	struct tm_callback_s *cbs;
177
+	static struct tmcb_params params = {0,0,0,0};
178
+	struct tm_callback    *cbp;
78 179
 
79
-	for (cbs=callback_array[ cbt ]; cbs; cbs=cbs->next)  {
80
-		DBG("DBG: callback type %d, id %d entered\n", cbt, cbs->id );
81
-		cbs->callback( trans, msg, code, cbs->param );
180
+	params.req = req;
181
+	params.code = code;
182
+
183
+	for (cbp=req_in_tmcb_hl->first; cbp; cbp=cbp->next)  {
184
+		DBG("DBG: trans=%p, callback type %d, id %d entered\n",
185
+			trans, cbp->types, cbp->id );
186
+		params.param = cbp->param;
187
+		cbp->callback( trans, cbp->types, &params );
82 188
 	}
83 189
 }
190
+
... ...
@@ -26,8 +26,11 @@
26 26
  *
27 27
  * History:
28 28
  * --------
29
- * 2003-03-16 backwards-compatibility callback names introduced (jiri)
30
- * 2003-03-06 old callbacks renamed, new one introduced (jiri)
29
+ * 2003-03-16 : backwards-compatibility callback names introduced (jiri)
30
+ * 2003-03-06 : old callbacks renamed, new one introduced (jiri)
31
+ * 2003-12-04 : global callbacks moved into transaction callbacks;
32
+ *              multiple events per callback added; single list per
33
+ *              transaction for all its callbacks (bogdan)
31 34
  */
32 35
 
33 36
 
... ...
@@ -36,25 +39,20 @@
36 39
 
37 40
 #include "defs.h"
38 41
 
39
-
40 42
 struct sip_msg;
41 43
 struct cell;
42 44
 
43
-/* backwards compatibility hooks */
44
-#define TMCB_REPLY TMCB_RESPONSE_OUT
45
-#define TMCB_E2EACK TMCB_E2EACK_IN
46
-#define TMCB_REPLY_IN TMCB_RESPONSE_IN
47
-#define TMCB_REQUEST_OUT TMCB_REQUEST_FWDED
48
-#define TMCB_ON_NEGATIVE TMCB_ON_FAILURE
49
-
50
-typedef enum { 
51
-		/* input events */
52
-		TMCB_RESPONSE_IN=1, TMCB_REQUEST_IN, TMCB_E2EACK_IN, 
53
-		/* routing decisions in progress */
54
-		TMCB_REQUEST_FWDED, TMCB_RESPONSE_FWDED, TMCB_ON_FAILURE,
55
-		/* completion events */
56
-		TMCB_RESPONSE_OUT, TMCB_LOCAL_COMPLETED, 
57
-		TMCB_END } tmcb_type;
45
+
46
+#define TMCB_REQUEST_IN       (1<<0)
47
+#define TMCB_RESPONSE_IN      (1<<1)
48
+#define TMCB_E2EACK_IN        (1<<2)
49
+#define TMCB_REQUEST_FWDED    (1<<3)
50
+#define TMCB_RESPONSE_FWDED   (1<<4)
51
+#define TMCB_ON_FAILURE_RO    (1<<5)
52
+#define TMCB_ON_FAILURE       (1<<6)
53
+#define TMCB_RESPONSE_OUT     (1<<7)
54
+#define TMCB_LOCAL_COMPLETED  (1<<8)
55
+#define TMCB_MAX              ((1<<9)-1)
58 56
 
59 57
 /* 
60 58
  *  Caution: most of the callbacks work with shmem-ized messages
... ...
@@ -65,6 +63,13 @@ typedef enum {
65 63
  *  is a non-dereferencable pointer indicating that no message
66 64
  *  was received and a timer hit instead.
67 65
  *
66
+ *  All callbacks excepting the TMCB_REQUEST_IN are associates to a
67
+ *  transaction. It means they will be run only when the event will hint
68
+ *  the transaction the callbacks were register for.
69
+ *  TMCB_REQUEST_IN is a global callback - it means it will be run for
70
+ *  all transactions.
71
+ *
72
+ *
68 73
  *  Callback description:
69 74
  *  ---------------------
70 75
  *
... ...
@@ -98,6 +103,11 @@ typedef enum {
98 103
  *    drops state silently, doesn't use callbacks and expects the
99 104
  *    transaction to complete statelessly.
100 105
  *
106
+ *  TMCB_ON_FAILURE_RO -- called on receipt of a reply or timer;
107
+ *  it means all branches completed with a failure; the callback 
108
+ *  function MUST not change anything in the transaction (READONLY)
109
+ *  that's a chance for doing ACC or stuff like this
110
+ *
101 111
  *  TMCB_ON_FAILURE -- called on receipt of a reply or timer;
102 112
  *  it means all branches completed with a failure; that's 
103 113
  *  a chance for example to add new transaction branches
... ...
@@ -139,36 +149,73 @@ typedef enum {
139 149
  *  TMCB_LOCAL COMPLETED -- final reply for localy initiated
140 150
  *  transaction arrived. Message may be FAKED_REPLY.
141 151
  *
142
- *  TMCB_END	- just a bumper
143
-
144
-	see the 'acc' module for an example of callback usage
145 152
 
146 153
 	note that callbacks MUST be installed before forking
147
-    (callback lists do not live in shmem and have no access
154
+	(callback lists do not live in shmem and have no access
148 155
 	protection), i.e., at best from mod_init functions.
149 156
 
150
-	also, note: the callback param is currently not used;
151
-	if whoever wishes to use a callback parameter, use
152
-	trans->cbp
157
+	the callback's param MUST be in shared memory and will
158
+	NOT be freed by TM; you must do it yourself from the
159
+	callback function id necessary.
153 160
 */
154 161
 
155
-typedef void (transaction_cb) ( struct cell* t, struct sip_msg* msg, 
156
-	int code, void *param );
157 162
 
158
-struct tm_callback_s {
159
-	int id;
160
-	transaction_cb* callback;
161
-	struct tm_callback_s* next;
163
+/* pack structure with all params passed toa callback function */
164
+struct tmcb_params {
165
+	struct sip_msg* req;
166
+	struct sip_msg* rpl;
167
+	int code;
162 168
 	void *param;
163 169
 };
164 170
 
171
+/* callback function prototype */
172
+typedef void (transaction_cb) (struct cell* t, int type, struct tmcb_params*);
173
+/* register callback function prototype */
174
+typedef int (*register_tmcb_f)(struct sip_msg* p_msg, int cb_types,
175
+		transaction_cb f, void *param);
176
+
177
+
178
+struct tm_callback {
179
+	int id;                      /* id of this callback - useless */
180
+	int types;                   /* types of events that trigger the callback*/
181
+	transaction_cb* callback;    /* callback function */
182
+	void *param;                 /* param to be passed to callback function */
183
+	struct tm_callback* next;
184
+};
185
+
186
+struct tmcb_head_list {
187
+	struct tm_callback *first;
188
+	int reg_types;
189
+};
190
+
191
+
192
+extern struct tmcb_head_list*  req_in_tmcb_hl;
193
+
194
+
195
+#define has_tran_tmcbs(_T_, _types_) \
196
+	( ((_T_)->tmcb_hl.reg_types)|(_types_) )
197
+#define has_reqin_tmcbs() \
198
+	( req_in_tmcb_hl->first!=0 )
199
+
200
+
201
+int init_tmcb_lists();
202
+
203
+void destroy_tmcb_lists();
204
+
205
+
206
+/* register a callback for several types of events */
207
+int register_tmcb( struct sip_msg* p_msg, int types, transaction_cb f,
208
+																void *param );
165 209
 
166
-extern struct tm_callback_s* callback_array[ TMCB_END ];
210
+/* inserts a callback into the a callback list */
211
+int insert_tmcb(struct tmcb_head_list *cb_list, int types,
212
+									transaction_cb f, void *param );
167 213
 
168
-typedef int (*register_tmcb_f)(tmcb_type cbt, transaction_cb f, void *param);
214
+/* run all transaction callbacks for an event type */
215
+void run_trans_callbacks( int type , struct cell *trans,
216
+						struct sip_msg *req, struct sip_msg *rpl, int code );
169 217
 
170
-int register_tmcb( tmcb_type cbt, transaction_cb f, void *param );
171
-void callback_event( tmcb_type cbt, struct cell *trans,
172
-	struct sip_msg *msg, int code );
218
+/* run all REQUEST_IN callbacks */
219
+void run_reqin_callbacks( struct cell *trans, struct sip_msg *req, int code );
173 220
 
174 221
 #endif
... ...
@@ -72,6 +72,8 @@
72 72
  * 2003-04-30  t_newtran clean up (jiri)
73 73
  * 2003-08-21  request lookups fixed to skip UAC transactions, 
74 74
  *             thanks Ed (jiri)
75
+ * 2003-12-04  global TM callbacks switched to per transaction callbacks
76
+ *             (bogdan)
75 77
  */
76 78
 
77 79
 
... ...
@@ -784,17 +786,19 @@ int t_reply_matching( struct sip_msg *p_msg , int *p_branch )
784 786
 		 * retransmissions of multiple 200/INV or ACK/200s
785 787
 		 */
786 788
 		if (p_cell->is_invite && p_msg->REPLY_STATUS>=200 
787
-				&& p_msg->REPLY_STATUS<300 
788
-				&& ( (!p_cell->local && 
789
-					(callback_array[TMCB_RESPONSE_OUT]||
790
-						callback_array[TMCB_E2EACK_IN]))
791
-					|| (p_cell->local && callback_array[TMCB_LOCAL_COMPLETED]) )) {
789
+		&& p_msg->REPLY_STATUS<300 
790
+		&& ( (!p_cell->local && 
791
+				has_tran_tmcbs(p_cell,TMCB_RESPONSE_OUT|TMCB_E2EACK_IN) )
792
+			|| (p_cell->local && has_tran_tmcbs(p_cell,TMCB_LOCAL_COMPLETED))
793
+		)) {
792 794
 			if (parse_headers(p_msg, HDR_TO, 0)==-1) {
793 795
 				LOG(L_ERR, "ERROR: t_reply_matching: to parsing failed\n");
794 796
 			}
795 797
 		}
796
-		if (!p_cell->local) 
797
-			callback_event(TMCB_RESPONSE_IN, T, p_msg, p_msg->REPLY_STATUS);
798
+		if (!p_cell->local) {
799
+			run_trans_callbacks( TMCB_RESPONSE_IN, T, T->uas.request, p_msg,
800
+				p_msg->REPLY_STATUS);
801
+		}
798 802
 		return 1;
799 803
 	} /* for cycle */
800 804
 
... ...
@@ -1051,21 +1055,20 @@ int t_newtran( struct sip_msg* p_msg )
1051 1055
 
1052 1056
 	if (lret==-2) { /* was it an e2e ACK ? if so, trigger a callback */
1053 1057
 		/* no callbacks? complete quickly */
1054
-		if (!callback_array[TMCB_E2EACK_IN]) {
1058
+		if ( !has_tran_tmcbs(t_ack,TMCB_E2EACK_IN) ) {
1055 1059
 			UNLOCK_HASH(p_msg->hash_index);
1056 1060
 			return 1;
1057 1061
 		} 
1058 1062
 		REF_UNSAFE(t_ack);
1059 1063
 		UNLOCK_HASH(p_msg->hash_index);
1060 1064
 		/* we don't call from within REPLY_LOCK -- that introduces
1061
-	   	   a race condition; however, it is so unlikely and the
1062
-	   	   impact is so small (callback called multiple times of
1063
-           multiple ACK/200s received in parallel), that we do not
1064
-	   	    better waste time in locks
1065
-		 */
1065
+		 * a race condition; however, it is so unlikely and the
1066
+		 * impact is so small (callback called multiple times of
1067
+		 * multiple ACK/200s received in parallel), that we do not
1068
+		 * better waste time in locks  */
1066 1069
 		if (unmatched_totag(t_ack, p_msg)) {
1067
-			callback_event( TMCB_E2EACK_IN, t_ack, p_msg, 
1068
-				p_msg->REQ_METHOD );
1070
+			run_trans_callbacks( TMCB_E2EACK_IN , t_ack, p_msg, 0,
1071
+				-p_msg->REQ_METHOD );
1069 1072
 		}
1070 1073
 		UNREF(t_ack);
1071 1074
 		return 1;
... ...
@@ -52,6 +52,8 @@
52 52
  *  2003-11-05  flag context updated from failure/reply handlers back
53 53
  *              to transaction context (jiri)
54 54
  *  2003-11-11: build_lump_rpl() removed, add_lump_rpl() has flags (bogdan)
55
+ *  2003-12-04  global TM callbacks switched to per transaction callbacks
56
+ *              (bogdan)
55 57
  */
56 58
 
57 59
 
... ...
@@ -102,6 +104,7 @@ static int goto_on_negative=0;
102 104
 static int goto_on_reply=0;
103 105
 
104 106
 
107
+
105 108
 /* we store the reply_route # in private memory which is
106 109
    then processed during t_relay; we cannot set this value
107 110
    before t_relay creates transaction context or after
... ...
@@ -309,11 +312,13 @@ static int _reply_light( struct cell *trans, char* buf, unsigned int len,
309 312
 	if (code>=200) {
310 313
 		if (trans->local) {
311 314
 			DBG("DEBUG: local transaction completed from _reply\n");
312
-			callback_event( TMCB_LOCAL_COMPLETED, trans, FAKED_REPLY, code );
313
-			if (trans->completion_cb) 
314
-				trans->completion_cb( trans, FAKED_REPLY, code, trans->cbp);
315
+			if ( has_tran_tmcbs(trans, TMCB_LOCAL_COMPLETED) )
316
+				run_trans_callbacks( TMCB_LOCAL_COMPLETED, trans,
317
+					0, FAKED_REPLY, code);
315 318
 		} else {
316
-			callback_event( TMCB_RESPONSE_OUT, trans, FAKED_REPLY, code );
319
+			if ( has_tran_tmcbs(trans, TMCB_RESPONSE_OUT) )
320
+				run_trans_callbacks( TMCB_RESPONSE_OUT, trans,
321
+					trans->uas.request, FAKED_REPLY, code);
317 322
 		}
318 323
 
319 324
 		cleanup_uac_timers( trans );
... ...
@@ -380,45 +385,15 @@ static int _reply( struct cell *trans, struct sip_msg* p_msg,
380 385
 }
381 386
 
382 387
 
383
-/* create a temporary faked message environment in which a conserved
384
- * t->uas.request in shmem is partially duplicated to pkgmem
385
- * to allow pkg-based actions to use it; 
386
- *
387
- * if restore parameter is set, the environment is restored to the
388
- * original setting and return value is unsignificant (always 0); 
389
- * otherwise  a faked environment if created; if that fails,
390
- * false is returned
391
- */
392
-static int faked_env(struct sip_msg *fake, 
393
-				struct cell *_t,
394
-				struct sip_msg *shmem_msg,
395
-				int _restore )
388
+/*if msg is set -> it will fake the env. vars conforming with the msg; if NULL
389
+ * the env. will be restore to original */
390
+static inline void faked_env( struct cell *t,struct sip_msg *msg)
396 391
 {
397 392
 	static enum route_mode backup_mode;
398 393
 	static struct cell *backup_t;
399 394
 	static unsigned int backup_msgid;
400 395
 
401
-	if (_restore) goto restore;
402
-
403
-	/* 
404
-     on_negative_reply faked msg now copied from shmem msg (as opposed
405
-     to zero-ing) -- more "read-only" actions (exec in particular) will 
406
-     work from reply_route as they will see msg->from, etc.; caution, 
407
-     rw actions may append some pkg stuff to msg, which will possibly be 
408
-     never released (shmem is released in a single block)
409
-    */
410
-	memcpy( fake, shmem_msg, sizeof(struct sip_msg));
411
-
412
-	/* if we set msg_id to something different from current's message
413
-       id, the first t_fork will properly clean new branch URIs
414
-	*/
415
-	fake->id=shmem_msg->id-1;
416
-	/* set items, which will be duped to pkg_mem, to zero, so that
417
-	 * "restore" called on error does not free the original items */
418
-	fake->add_rm=0;
419
-	fake->body_lumps=0;
420
-	fake->new_uri.s=0; fake->new_uri.len=0; 
421
-
396
+	if (msg) {
422 397
 	/* remember we are back in request processing, but process
423 398
 	 * a shmem-ed replica of the request; advertise it in rmode;
424 399
 	 * for example t_reply needs to know that
... ...
@@ -435,90 +410,109 @@ static int faked_env(struct sip_msg *fake,
435 410
 	backup_t=get_t();
436 411
 	backup_msgid=global_msg_id;
437 412
 	/* fake transaction and message id */
438
-	global_msg_id=fake->id;
439
-	set_t(_t);
413
+		global_msg_id=msg->id;
414
+		set_t(t);
415
+	} else {
416
+		/* restore original environment */
417
+		set_t(backup_t);
418
+		global_msg_id=backup_msgid;
419
+		rmode=backup_mode;
420
+	}
421
+}
422
+
423
+
424
+
425
+/* return 1 if a failure_route processes */
426
+static inline int run_failure_handlers(struct cell *t, struct sip_msg *rpl,
427
+																	int code)
428
+{
429
+	static struct sip_msg fake_req;
430
+	struct sip_msg *shmem_msg = t->uas.request;
431
+
432
+	/* failure_route for a local UAC? */
433
+	if (!shmem_msg) {
434
+		LOG(L_WARN, "Warning: run_failure_handlers: no UAC support\n");
435
+		return 0;
436
+	}
437
+
438
+	/* don't start faking anything if we don't have to */
439
+	if ( !has_tran_tmcbs( t, TMCB_ON_FAILURE) && !t->on_negative ) {
440
+		return 1;
441
+	}
440 442
 
441
-	/* environment is set up now, try to fake the message */
443
+	/* on_negative_reply faked msg now copied from shmem msg (as opposed
444
+	 * to zero-ing) -- more "read-only" actions (exec in particular) will
445
+	 * work from reply_route as they will see msg->from, etc.; caution,
446
+	 * rw actions may append some pkg stuff to msg, which will possibly be
447
+	 * never released (shmem is released in a single block) */
448
+	memcpy( &fake_req, shmem_msg, sizeof(struct sip_msg));
449
+
450
+	/* if we set msg_id to something different from current's message
451
+	 * id, the first t_fork will properly clean new branch URIs */
452
+	fake_req.id=shmem_msg->id-1;
442 453
 
443 454
 	/* new_uri can change -- make a private copy */
444 455
 	if (shmem_msg->new_uri.s!=0 && shmem_msg->new_uri.len!=0) {
445
-		fake->new_uri.s=pkg_malloc(shmem_msg->new_uri.len+1);
446
-		if (!fake->new_uri.s) {
447
-			LOG(L_ERR, "ERROR: faked_env: no uri/pkg mem\n");
448
-			goto restore;
456
+		fake_req.new_uri.s=pkg_malloc(shmem_msg->new_uri.len+1);
457
+		if (!fake_req.new_uri.s) {
458
+			LOG(L_ERR, "ERROR: run_failure_handlers: no uri/pkg mem\n");
459
+			return 0;
449 460
 		}
450
-		fake->new_uri.len=shmem_msg->new_uri.len;
451
-		memcpy( fake->new_uri.s, shmem_msg->new_uri.s, 
452
-			fake->new_uri.len);
453
-		fake->new_uri.s[fake->new_uri.len]=0;
454
-	} 
461
+		fake_req.new_uri.len=shmem_msg->new_uri.len;
462
+		memcpy( fake_req.new_uri.s, shmem_msg->new_uri.s, 
463
+			fake_req.new_uri.len);
464
+		fake_req.new_uri.s[fake_req.new_uri.len]=0;
465
+	}
455 466
 
456 467
 	/* create a duplicated lump list to which actions can add
457
-	 * new pkg items 
458
-	 */
468
+	 * new pkg items  */
459 469
 	if (shmem_msg->add_rm) {
460
-		fake->add_rm=dup_lump_list(shmem_msg->add_rm);
461
-		if (!fake->add_rm) { /* non_emty->empty ... failure */
462
-			LOG(L_ERR, "ERROR: on_negative_reply: lump dup failed\n");
463
-			goto restore;
470
+		fake_req.add_rm=dup_lump_list(shmem_msg->add_rm);
471
+		if (!fake_req.add_rm) { /* non_emty->empty ... failure */
472
+			LOG(L_ERR, "ERROR: run_failure_handlers: lump dup failed\n");
473
+			if (fake_req.new_uri.s) pkg_free(fake_req.new_uri.s);
474
+			return 0;
464 475
 		}
465 476
 	}
466 477
 
478
+	/* same for the body lumps */
467 479
 	if (shmem_msg->body_lumps) {
468
-		fake->body_lumps=dup_lump_list(shmem_msg->body_lumps);
469
-		if (!fake->body_lumps) { /* non_empty->empty ... failure */
470
-			LOG(L_ERR, "ERROR: on_negative_reply: lump dup failed\n");
471
-			goto restore;
480
+		fake_req.body_lumps=dup_lump_list(shmem_msg->body_lumps);
481
+		if (!fake_req.body_lumps) { /* non_empty->empty ... failure */
482
+			LOG(L_ERR, "ERROR: on_negative_handlers: lump dup failed\n");
483
+			free_duped_lump_list(fake_req.add_rm);
484
+			if (fake_req.new_uri.s) pkg_free(fake_req.new_uri.s);
485
+			return 0;
472 486
 		}
473 487
 	}
474
-	
475
-	/* success */
476
-	return 1;
477
-
478
-restore:
479
-	/* restore original environment and destroy faked message */
480
-	free_duped_lump_list(fake->add_rm);
481
-	free_duped_lump_list(fake->body_lumps);
482
-	if (fake->new_uri.s) pkg_free(fake->new_uri.s);
483
-	set_t(backup_t);
484
-	global_msg_id=backup_msgid;
485
-	rmode=backup_mode;
486
-	/* if failure handler changed flag, update transaction context */
487
-	shmem_msg->flags=fake->flags;
488
-	return 0;
489
-}
490 488
 
491
-/* return 1 if a failure_route processes */
492
-int failure_route(struct cell *t)
493
-{
494
-	struct sip_msg faked_msg;
495
-	struct sip_msg *orig_request;
496
-
497
-	/* don't do anything if we don't have to */
498
-	if (!t->on_negative) return 0;
499
-	orig_request=t->uas.request;
500
-	/* failure_route for a local UAC? */
501
-	if (!orig_request) {
502
-		LOG(L_WARN, "Warning: failure_route: no UAC support\n");
503
-		return 0;
504
-	}
489
+	/* fake also the env. conforming to the fake msg */
490
+	faked_env( t, &fake_req);
491
+	/* DONE with faking ;-) -> run the failure handlers */
505 492
 
506
-	/* if fake message creation failes, return error too */
507
-	if (!faked_env(&faked_msg, t, orig_request, 0 /* create fake */ )) {
508
-		LOG(L_ERR, "ERROR: on_negative_reply: faked_env failed\n");
509
-		return 0;
493
+	if ( has_tran_tmcbs( t, TMCB_ON_FAILURE) ) {
494
+		run_trans_callbacks( TMCB_ON_FAILURE, t, &fake_req, rpl, code);
510 495
 	}
511
-
496
+	if (t->on_negative) {
512 497
 	/* avoid recursion -- if failure_route forwards, and does not 
513 498
 	 * set next failure route, failure_route will not be rentered
514 499
 	 * on failure */
515 500
 	t_on_negative(0);
516 501
 	/* run a reply_route action if some was marked */
517
-	if (run_actions(failure_rlist[t->on_negative], &faked_msg)<0)
518
-		LOG(L_ERR, "ERROR: on_negative_reply: "
519
-			"Error in do_action\n");
520
-	/* restore original environment */
521
-	faked_env(&faked_msg, 0, orig_request, 1 );
502
+		if (run_actions(failure_rlist[t->on_negative], &fake_req)<0)
503
+			LOG(L_ERR, "ERROR: run_failure_handlers: Error in do_action\n");
504
+	}
505
+
506
+	/* restore original environment and free the fake msg */
507
+	faked_env( t, 0);
508
+	free_duped_lump_list(fake_req.add_rm);
509
+	free_duped_lump_list(fake_req.body_lumps);
510
+	fake_req.add_rm = fake_req.body_lumps = 0;
511
+	if (fake_req.new_uri.s) {
512
+		pkg_free(fake_req.new_uri.s);
513
+		fake_req.new_uri.s = 0;
514
+	}
515
+
522 516
 	return 1;
523 517
 }
524 518
 
... ...
@@ -572,7 +566,6 @@ static enum rps t_should_relay_response( struct cell *Trans , int new_code,
572 566
 	int branch , int *should_store, int *should_relay,
573 567
 	branch_bm_t *cancel_bitmap, struct sip_msg *reply )
574 568
 {
575
-	
576 569
 	int branch_cnt;
577 570
 	int picked_branch;
578 571
 	int picked_code;
... ...
@@ -630,15 +623,16 @@ static enum rps t_should_relay_response( struct cell *Trans , int new_code,
630 623
 
631 624
 		/* no more pending branches -- try if that changes after
632 625
 		   a callback; save banch count to be able to determine
633
-		   later if new branches were initiated
634
-		*/
626
+		   later if new branches were initiated */
635 627
 		branch_cnt=Trans->nr_of_outgoings;
636
-		callback_event( TMCB_ON_FAILURE, Trans, 
637
-			picked_branch==branch?reply:Trans->uac[picked_branch].reply, 
638
-			picked_code);
639
-		/* here, we create a faked environment, from which we
640
-		 * return to request processing, if marked to do so */
641
-		failure_route(Trans);
628
+
629
+		/* run ON_FAILURE handlers ( route and callbacks) */
630
+		if ( has_tran_tmcbs( Trans, TMCB_ON_FAILURE_RO|TMCB_ON_FAILURE)
631
+		|| Trans->on_negative ) {
632
+			run_failure_handlers( Trans,
633
+				picked_branch==branch?reply:Trans->uac[picked_branch].reply, 
634
+				picked_code);
635
+		}
642 636
 
643 637
 		/* look if the callback perhaps replied transaction; it also
644 638
 		   covers the case in which a transaction is replied localy
... ...
@@ -849,7 +843,7 @@ enum rps relay_reply( struct cell *t, struct sip_msg *p_msg, int branch,
849 843
 
850 844
 
851 845
 	/* remember, what was sent upstream to know whether we are
852
-	   forwarding a first final reply or not */
846
+	 * forwarding a first final reply or not */
853 847
 
854 848
 	/* *** store and relay message as needed *** */
855 849
 	reply_status = t_should_relay_response(t, msg_status, branch, 
... ...
@@ -866,19 +860,19 @@ enum rps relay_reply( struct cell *t, struct sip_msg *p_msg, int branch,
866 860
 
867 861
 	uas_rb = & t->uas.response;
868 862
 	if (relay >= 0 ) {
869
-
870 863
 		/* initialize sockets for outbound reply */
871 864
 		uas_rb->activ_type=msg_status;
872 865
 		/* only messages known to be relayed immediately will be
873
-		   be called on; we do not evoke this callback on messages
874
-		   stored in shmem -- they are fixed and one cannot change them
875
-		   anyway 
876
-        */
877
-		if (msg_status<300 && branch==relay) {
878
-			callback_event( TMCB_RESPONSE_FWDED, t, p_msg, msg_status );
866
+		 * be called on; we do not evoke this callback on messages
867
+		 * stored in shmem -- they are fixed and one cannot change them
868
+		 * anyway */
869
+		if (msg_status<300 && branch==relay
870
+		&& has_tran_tmcbs(t,TMCB_RESPONSE_FWDED) ) {
871
+			run_trans_callbacks( TMCB_RESPONSE_FWDED, t, t->uas.request,
872
+				p_msg, msg_status );
879 873
 		}
880 874
 		/* try bulding the outbound reply from either the current
881
-	       or a stored message */
875
+		 * or a stored message */
882 876
 		relayed_msg = branch==relay ? p_msg :  t->uac[relay].reply;
883 877
 		if (relayed_msg==FAKED_REPLY) {
884 878
 			tm_stats->replied_localy++;
... ...
@@ -942,9 +936,8 @@ enum rps relay_reply( struct cell *t, struct sip_msg *p_msg, int branch,
942 936
 		t->relaied_reply_branch = relay;
943 937
 
944 938
 		if (t->is_invite && relayed_msg!=FAKED_REPLY
945
-				&& relayed_code>=200 && relayed_code < 300
946
-				&& (callback_array[TMCB_RESPONSE_OUT] ||
947
-						callback_array[TMCB_E2EACK_IN]))  {
939
+		&& relayed_code>=200 && relayed_code < 300
940
+		&& has_tran_tmcbs( t, TMCB_RESPONSE_OUT|TMCB_E2EACK_IN) ) {
948 941
 			totag_retr=update_totag_set(t, relayed_msg);
949 942
 		}
950 943
 	}; /* if relay ... */
... ...
@@ -956,8 +949,10 @@ enum rps relay_reply( struct cell *t, struct sip_msg *p_msg, int branch,
956 949
 		SEND_PR_BUFFER( uas_rb, buf, res_len );
957 950
 		DBG("DEBUG: reply relayed. buf=%p: %.9s..., shmem=%p: %.9s\n", 
958 951
 			buf, buf, uas_rb->buffer, uas_rb->buffer );
959
-		if (!totag_retr) 
960
-				callback_event( TMCB_RESPONSE_OUT, t, relayed_msg, relayed_code );
952
+		if (!totag_retr && has_tran_tmcbs(t, TMCB_RESPONSE_OUT) ) {
953
+			run_trans_callbacks( TMCB_RESPONSE_OUT, t, t->uas.request,
954
+				relayed_msg, relayed_code);
955
+		}
961 956
 		pkg_free( buf );
962 957
 	}
963 958
 
... ...
@@ -1026,22 +1021,19 @@ enum rps local_reply( struct cell *t, struct sip_msg *p_msg, int branch,
1026 1021
 		}
1027 1022
 		t->uas.status = winning_code;
1028 1023
 		update_reply_stats( winning_code );
1029
-		if (t->is_invite && winning_msg!=FAKED_REPLY 
1030
-				&& winning_code>=200 && winning_code <300
1031
-				&& (callback_array[TMCB_RESPONSE_OUT] ||
1032
-						callback_array[TMCB_E2EACK_IN]))  {
1024
+		if (t->is_invite && winning_msg!=FAKED_REPLY
1025
+		&& winning_code>=200 && winning_code <300
1026
+		&& has_tran_tmcbs(t,TMCB_RESPONSE_OUT|TMCB_E2EACK_IN) )  {
1033 1027
 			totag_retr=update_totag_set(t, winning_msg);
1034 1028
 		}
1035
-		
1036 1029
 	}
1037 1030
 	UNLOCK_REPLIES(t);
1038 1031
 	if (local_winner>=0 && winning_code>=200 ) {
1039 1032
 		DBG("DEBUG: local transaction completed\n");
1040 1033
 		if (!totag_retr) {
1041
-			callback_event( TMCB_LOCAL_COMPLETED, t, winning_msg, 
1042
-				winning_code );
1043
-			if (t->completion_cb) t->completion_cb( t, winning_msg, 
1044
-						winning_code, t->cbp);
1034
+			if ( has_tran_tmcbs(t,TMCB_LOCAL_COMPLETED) )
1035
+				run_trans_callbacks( TMCB_LOCAL_COMPLETED, t, 0,
1036
+					winning_msg, winning_code );
1045 1037
 		}
1046 1038
 	}
1047 1039
 	return reply_status;
... ...
@@ -141,6 +141,5 @@ void tm_init_tags();
141 141
 /* selects the branch for fwd-ing the reply */
142 142
 int t_pick_branch(int inc_branch, int inc_code, struct cell *t, int *res_code);
143 143
 
144
-
145 144
 #endif
146 145
 
... ...
@@ -452,12 +452,12 @@ static int mod_init(void)
452 452
 		return -1;
453 453
 	}
454 454
 
455
+	/* building the hash table*/
455 456
 	if (!init_hash_table()) {
456 457
 		LOG(L_ERR, "ERROR: mod_init: initializing hash_table failed\n");
457 458
 		return -1;
458 459
 	}
459 460
 
460
-
461 461
 	/* init static hidden values */
462 462
 	init_t();
463 463
 
... ...
@@ -480,20 +480,24 @@ static int mod_init(void)
480 480
 		return -1;
481 481
 	}
482 482
 
483
-	/* building the hash table*/
484
-
485 483
 	if (uac_init()==-1) {
486 484
 		LOG(L_ERR, "ERROR: mod_init: uac_init failed\n");
487 485
 		return -1;
488 486
 	}
487
+
488
+	if (init_tmcb_lists()!=1) {
489
+		LOG(L_CRIT, "ERROR:tm:mod_init: failed to init tmcb lists\n");
490
+		return -1;
491
+	}
492
+
493
+	tm_init_tags();
494
+
489 495
 	/* register post-script clean-up function */
490 496
 	register_script_cb( w_t_unref, POST_SCRIPT_CB, 
491 497
 			0 /* empty param */ );
492 498
 	register_script_cb( script_init, PRE_SCRIPT_CB , 
493 499
 			0 /* empty param */ );
494 500
 
495
-	tm_init_tags();
496
-
497 501
 	return 0;
498 502
 }
499 503
 
... ...
@@ -45,7 +45,6 @@ int load_tm( struct tm_binds *tmb)
45 45
 		LOG(L_ERR, LOAD_ERROR "'register_tmcb' not found\n");
46 46
 		return -1;
47 47
 	}
48
-
49 48
 	if (!( tmb->t_relay_to_tcp=find_export(T_RELAY_TO_TCP, 2, 0)) ) {
50 49
 		LOG(L_ERR, LOAD_ERROR "'t_relay_to_tcp' not found\n");
51 50
 		return -1;
... ...
@@ -56,6 +56,7 @@
56 56
 #define T_RELAY              "t_relay"
57 57
 #define T_REPLY              "t_reply"
58 58
 #define T_REPLY_WB           "t_reply_with_body"
59
+#define T_REPLY_UNSAFE       "t_reply_unsafe"
59 60
 #define T_ADDBLIND           "t_add_blind"
60 61
 #define T_REPLY_UNSAFE       "t_reply_unsafe"
61 62
 #define T_FORWARD_NONACK     "t_forward_nonack"
... ...
@@ -68,35 +69,33 @@
68 69
 #define T_IS_LOCAL           "t_is_local"
69 70
 #define T_REQUEST_WITHIN     "request_within"
70 71
 #define T_REQUEST_OUTSIDE    "request_outside"
71
-#define T_GETT				 "t_gett"
72
+#define T_GETT               "t_gett"
72 73
 
73 74
 
74 75
 
75 76
 struct tm_binds {
76
-	register_tmcb_f register_tmcb;
77
-	cmd_function    t_relay_to_udp;
78
-	cmd_function    t_relay_to_tcp;
79
-	cmd_function    t_relay;
80
-	treply_f        t_reply;
81
-	treply_wb_f     t_reply_with_body;
82
-	tislocal_f      t_is_local;
83
-	tget_ti_f       t_get_trans_ident;
84
-	tlookup_ident_f t_lookup_ident;
85
-	taddblind_f     t_addblind;
86
-	treply_f        t_reply_unsafe;
87
-	tfwd_f          t_forward_nonack;
88
-	reqwith_t       t_request_within;
89
-	reqout_t        t_request_outside;
90
-	req_t           t_request;
91
-	
77
+	register_tmcb_f  register_tmcb;
78
+	cmd_function     t_relay_to_udp;
79
+	cmd_function     t_relay_to_tcp;
80
+	cmd_function     t_relay;
81
+	treply_f         t_reply;
82
+	treply_wb_f      t_reply_with_body;
83
+	tislocal_f       t_is_local;
84
+	tget_ti_f        t_get_trans_ident;
85
+	tlookup_ident_f  t_lookup_ident;
86
+	taddblind_f      t_addblind;
87
+	treply_f         t_reply_unsafe;
88
+	tfwd_f           t_forward_nonack;
89
+	reqwith_t        t_request_within;
90
+	reqout_t         t_request_outside;
91
+	req_t            t_request;
92 92
 	new_dlg_uac_f      new_dlg_uac;
93 93
 	dlg_response_uac_f dlg_response_uac;
94 94
 	new_dlg_uas_f      new_dlg_uas;
95 95
 	dlg_request_uas_f  dlg_request_uas;
96 96
 	free_dlg_f         free_dlg;
97 97
 	print_dlg_f        print_dlg;
98
-
99
-	tgett_f			t_gett;
98
+	tgett_f            t_gett;
100 99
 };
101 100
 
102 101
 
... ...
@@ -45,6 +45,8 @@
45 45
  *  2003-07-08  appropriate log messages in check_params(...), 
46 46
  *               call calculate_hooks if next_hop==NULL in t_uac (dcm) 
47 47
  *  2003-10-24  updated to the new socket_info lists (andrei)
48
+ *  2003-12-03  completion filed removed from transaction and uac callbacks
49
+ *              merged in transaction callbacks as LOCAL_COMPLETED (bogdan)
48 50
  */
49 51
 
50 52
 #include <string.h>
... ...
@@ -148,7 +150,8 @@ static inline int check_params(str* method, str* to, str* from, dlg_t** dialog)
148 150
 /*
149 151
  * Send a request using data from the dialog structure
150 152
  */
151
-int t_uac(str* method, str* headers, str* body, dlg_t* dialog, transaction_cb cb, void* cbp)
153
+int t_uac(str* method, str* headers, str* body, dlg_t* dialog,
154
+												transaction_cb cb, void* cbp)
152 155
 {
153 156
 	struct socket_info* send_sock;
154 157
 	union sockaddr_union to_su;
... ...
@@ -180,13 +183,15 @@ int t_uac(str* method, str* headers, str* body, dlg_t* dialog, transaction_cb cb
180 183
 		goto error2;
181 184
 	}
182 185
 
183
-	new_cell->completion_cb = cb;
184
-	new_cell->cbp = cbp;
185
-	
186
-	     /* cbp is installed -- tell error handling bellow not to free it */
187
-	cbp = 0;
186
+	/* add the callback the the transaction for LOCAL_COMPLETED event */
187
+	if (insert_tmcb( &(new_cell->tmcb_hl), TMCB_LOCAL_COMPLETED, cb, cbp)!=1) {
188
+		ret=E_OUT_OF_MEM;
189
+		LOG(L_ERR, "t_uac: short of tmcb shmem\n");
190
+		goto error2;
191
+	}
188 192
 
189
-	new_cell->is_invite = method->len == INVITE_LEN && memcmp(method->s, INVITE, INVITE_LEN) == 0;
193
+	new_cell->is_invite =
194
+		method->len==INVITE_LEN && memcmp(method->s, INVITE, INVITE_LEN)==0;
190 195
 	new_cell->local= 1;
191 196
 	set_kr(REQ_FWDED);
192 197
 	
... ...
@@ -196,12 +201,13 @@ int t_uac(str* method, str* headers, str* body, dlg_t* dialog, transaction_cb cb
196 201
 	request->dst.proto = send_sock->proto;
197 202
 	request->dst.proto_reserved1 = 0;
198 203
 
199
-	     /* need to put in table to calculate label which is needed for printing */
204
+	/* need to put in table to calculate label which is needed for printing */
200 205
 	LOCK_HASH(new_cell->hash_index);
201 206
 	insert_into_hash_table_unsafe(new_cell);
202 207
 	UNLOCK_HASH(new_cell->hash_index);
203 208
 
204
-	buf = build_uac_req(method, headers, body, dialog, 0, new_cell, &buf_len, send_sock);
209
+	buf = build_uac_req(method, headers, body, dialog, 0, new_cell,
210
+		&buf_len, send_sock);
205 211
 	if (!buf) {
206 212
 		LOG(L_ERR, "t_uac: Error while building message\n");
207 213
 		ret=E_OUT_OF_MEM;
... ...
@@ -217,23 +223,19 @@ int t_uac(str* method, str* headers, str* body, dlg_t* dialog, transaction_cb cb
217 223
 	
218 224
 	if (SEND_BUFFER(request) == -1) {
219 225
 		LOG(L_ERR, "t_uac: Attempt to send to '%.*s' failed\n", 
220
-		    dialog->hooks.next_hop->len,
221
-		    dialog->hooks.next_hop->s
222
-		    );
226
+			dialog->hooks.next_hop->len,
227
+			dialog->hooks.next_hop->s);
223 228
 	}
224 229
 	
225 230
 	start_retr(request);
226 231
 	return 1;
227 232
 
228
- error1:
233
+error1:
229 234
 	LOCK_HASH(new_cell->hash_index);
230 235
 	remove_from_hash_table_unsafe(new_cell);
231 236
 	UNLOCK_HASH(new_cell->hash_index);
232 237
 	free_cell(new_cell);
233
-
234
- error2:
235
-	     /* if we did not install cbp, release it now */
236
-	if (cbp) shm_free(cbp);
238
+error2:
237 239
 	return ret;
238 240
 }
239 241
 
... ...
@@ -1,5 +1,32 @@
1 1
 /*
2 2
  * $Id$
3
+ *
4
+ * Copyright (C) 2001-2003 Fhg Fokus
5
+ *
6
+ * This file is part of ser, a free SIP server.
7
+ *
8
+ * ser is free software; you can redistribute it and/or modify
9
+ * it under the terms of the GNU General Public License as published by
10
+ * the Free Software Foundation; either version 2 of the License, or
11
+ * (at your option) any later version
12
+ *
13
+ * For a license to use the ser software under conditions
14
+ * other than those described here, or to purchase support for this
15
+ * software, please contact iptel.org by e-mail at the following addresses:
16
+ *    info@iptel.org
17
+ *
18
+ * ser is distributed in the hope that it will be useful,
19
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
20
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21
+ * GNU General Public License for more details.
22
+ *
23
+ * You should have received a copy of the GNU General Public License 
24
+ * along with this program; if not, write to the Free Software 
25
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26
+ *
27
+ * History:
28
+ * --------
29
+ *  2003-12-03 : fifo_callback() updated for changes in tm callbacks (bogdan)
3 30
  */
4 31
 
5 32
 #include <string.h>
... ...
@@ -31,8 +58,8 @@ struct cb_data {
31 58
 
32 59
 
33 60
 struct str_list {
34
-        str s;
35
-        struct str_list *next;
61
+	str s;
62
+	struct str_list *next;
36 63
 };
37 64
 
38 65
 
... ...
@@ -502,8 +529,7 @@ static inline int print_uris(FILE* out, struct sip_msg* reply)
502 529
 }
503 530
 
504 531
 
505
-static void fifo_callback(struct cell *t, struct sip_msg *reply,
506
-			  int code, void *param)
532
+static void fifo_callback( struct cell *t, int type, struct tmcb_params *ps )
507 533
 {
508 534
 	
509 535
 	char *filename;
... ...
@@ -512,35 +538,39 @@ static void fifo_callback(struct cell *t, struct sip_msg *reply,
512 538
 
513 539
 	DBG("!!!!! ref_counter: %d\n", t->ref_count);
514 540
 
515
-	DBG("DEBUG: fifo UAC completed with status %d\n", code);
516
-	if (!t->cbp) {
517
-		LOG(L_INFO, "INFO: fifo UAC completed with status %d\n", code);
541
+	DBG("DEBUG: fifo UAC completed with status %d\n", ps->code);
542
+	if (!ps->param) {
543
+		LOG(L_INFO, "INFO: fifo UAC completed with status %d\n", ps->code);
518 544
 		return;
519 545
 	}
520 546
 
521
-	filename=(char *)(t->cbp);
522
-	if (reply==FAKED_REPLY) {
523
-		get_reply_status(&text,reply,code);
547
+	filename=(char *)(ps->param);
548
+	if (ps->rpl==FAKED_REPLY) {
549
+		get_reply_status( &text, ps->rpl, ps->code);
524 550
 		if (text.s==0) {
525 551
 			LOG(L_ERR, "ERROR: fifo_callback: get_reply_status failed\n");
526
-			fifo_reply(filename, "500 fifo_callback: get_reply_status failed\n");
527
-			return;
552
+			fifo_reply( filename,
553
+				"500 fifo_callback: get_reply_status failed\n");
554
+			goto done;
528 555
 		}
529 556
 		fifo_reply(filename, "%.*s\n", text.len, text.s );
530 557
 		pkg_free(text.s);
531 558
 	} else {
532
-		text.s=reply->first_line.u.reply.reason.s;
533
-		text.len=reply->first_line.u.reply.reason.len;
559
+		text.s = ps->rpl->first_line.u.reply.reason.s;
560
+		text.len = ps->rpl->first_line.u.reply.reason.len;
534 561
 
535 562
 		f = fopen(filename, "wt");
536
-		if (!f) return;
537
-		fprintf(f, "%d %.*s\n", reply->first_line.u.reply.statuscode, text.len, text.s);
538
-		print_uris(f, reply);
539
-		fprintf(f, "%s\n", reply->headers->name.s);
563
+		if (!f) goto done;
564
+		fprintf(f, "%d %.*s\n", ps->rpl->first_line.u.reply.statuscode,
565
+			text.len, text.s);
566
+		print_uris(f, ps->rpl);
567
+		fprintf(f, "%s\n", ps->rpl->headers->name.s);
540 568
 		fclose(f);
541 569
 	}
542 570
 	DBG("DEBUG: fifo_callback sucesssfuly completed\n");
543
-}	
571
+done:
572
+	shm_free(ps->param);
573
+}
544 574
 
545 575
 
546 576
 int fifo_uac(FILE *stream, char *response_file)
... ...
@@ -624,7 +654,7 @@ int fifo_uac(FILE *stream, char *response_file)
624 654
 
625 655
 	if (ret <= 0) {
626 656
 		err_ret = err2reason_phrase(ret, &sip_error, err_buf,
627
-					    sizeof(err_buf), "FIFO/UAC") ;
657
+			sizeof(err_buf), "FIFO/UAC") ;
628 658
 		if (err_ret > 0 )
629 659
 		{
630 660
 			fifo_uac_error(response_file, sip_error, err_buf);