Browse code

- added new function: uac_send_req() - send sip request messages from config file - introduced a new pseudo-variable class to control the build of the message to be sent - $uac_req(key) - see README for more

git-svn-id: https://openser.svn.sourceforge.net/svnroot/openser/trunk@5477 689a6050-402a-0410-94f2-e92a70836424

Daniel-Constantin Mierla authored on 16/01/2009 10:50:08
Showing 6 changed files
... ...
@@ -4,6 +4,10 @@ Ramona-Elena Modroiu
4 4
 
5 5
    <ramona@rosdev.ro>
6 6
 
7
+Daniel-Constantin Mierla
8
+
9
+   <miconda@gmail.com>
10
+
7 11
 Edited by
8 12
 
9 13
 Ramona-Elena Modroiu
... ...
@@ -11,9 +15,8 @@ Ramona-Elena Modroiu
11 15
    <ramona@rosdev.ro>
12 16
 
13 17
    Copyright � 2005 Voice Sistem
14
-   Revision History
15
-   Revision $Revision$ $Date: 2008-08-06 12:08:33 +0200
16
-                              (Mi, 06 Aug 2008) $
18
+
19
+   Copyright � 2009 Asipto.com
17 20
      __________________________________________________________
18 21
 
19 22
    Table of Contents
... ...
@@ -42,6 +45,9 @@ Ramona-Elena Modroiu
42 45
               1.4.2. uac_replace_from(uri)
43 46
               1.4.3. uac_restore_from()
44 47
               1.4.4. uac_auth()
48
+              1.4.5. uac_send_req()
49
+
50
+        1.5. Exported pseudo-variables
45 51
 
46 52
    List of Examples
47 53
 
... ...
@@ -56,6 +62,7 @@ Ramona-Elena Modroiu
56 62
    1.9. uac_replace_from usage
57 63
    1.10. uac_restore_from usage
58 64
    1.11. uac_auth usage
65
+   1.12. uac_send_request usage
59 66
 
60 67
 Chapter 1. Admin Guide
61 68
 
... ...
@@ -63,7 +70,8 @@ Chapter 1. Admin Guide
63 70
 
64 71
    UAC (User Agent Client) module provides some basic UAC
65 72
    functionalities like FROM header manipulation (anonymization)
66
-   or client authentication.
73
+   or client authentication. From version 1.5.0 it has function to
74
+   send SIP message from configuration file.
67 75
 
68 76
    Known limitations in this version:
69 77
      * authentication does not support qop auth-int, just qop
... ...
@@ -248,3 +256,27 @@ uac_restore_from();
248 256
 ...
249 257
 uac_auth();
250 258
 ...
259
+
260
+1.4.5.  uac_send_req()
261
+
262
+   This function sends a SIP message from the configuration file.
263
+   The message is built out of $uac_req(...) pseudo-variable.
264
+
265
+   This function can be used from REQUEST_ROUTE, FAILURE_ROUTE,
266
+   BRANCH_ROUTE, ONREPLY_ROUTE, LOCAL_ROUTE.
267
+
268
+   Example 1.12. uac_send_request usage
269
+...
270
+$uac_req(method)="OPTIONS";
271
+$uac_req(ruri)="sip:kamailio.org";
272
+$uac_req(furi)="sip:kamailio.org";
273
+$uac_req(turi)="sip:kamailio.org";
274
+uac_send_req();
275
+...
276
+
277
+1.5. Exported pseudo-variables
278
+
279
+     * $uac_req(key)
280
+
281
+   Exported pseudo-variables are documented at
282
+   http://www.kamailio.org/dokuwiki/.
... ...
@@ -22,6 +22,11 @@
22 22
 			<surname>Modroiu</surname>
23 23
 				<email>ramona@rosdev.ro</email>
24 24
 		</author>
25
+		<author>
26
+			<firstname>Daniel-Constantin</firstname>
27
+			<surname>Mierla</surname>
28
+				<email>miconda@gmail.com</email>
29
+		</author>
25 30
 		<editor>
26 31
 			<firstname>Ramona-Elena</firstname>
27 32
 			<surname>Modroiu</surname>
... ...
@@ -32,12 +37,10 @@
32 37
 		<year>2005</year>
33 38
 		<holder>Voice Sistem</holder>
34 39
 	</copyright>
35
-	<revhistory>
36
-		<revision>
37
-			<revnumber>$Revision$</revnumber>
38
-			<date>$Date$</date>
39
-		</revision>
40
-	</revhistory>
40
+	<copyright>
41
+		<year>2009</year>
42
+		<holder>Asipto.com</holder>
43
+	</copyright>
41 44
 	</bookinfo>
42 45
 	<toc></toc>
43 46
 
... ...
@@ -10,7 +10,8 @@
10 10
 		<para>
11 11
 		UAC (User Agent Client) module provides some basic UAC
12 12
 		functionalities like FROM header manipulation (anonymization)
13
-		or client authentication.
13
+		or client authentication. From version 1.5.0 it has function to
14
+		send SIP message from configuration file.
14 15
 		</para>
15 16
 		<para>
16 17
 		Known limitations in this version:
... ...
@@ -335,11 +336,46 @@ uac_restore_from();
335 336
 				<programlisting format="linespecific">
336 337
 ...
337 338
 uac_auth();
339
+...
340
+				</programlisting>
341
+			</example>
342
+		</section>
343
+		<section>
344
+			<title>
345
+				<function moreinfo="none">uac_send_req()</function>
346
+			</title>
347
+			<para>
348
+			This function sends a SIP message from the configuration file.
349
+			The message is built out of $uac_req(...) pseudo-variable.
350
+			</para>
351
+			<para>
352
+			This function can be used from REQUEST_ROUTE, FAILURE_ROUTE,
353
+			BRANCH_ROUTE, ONREPLY_ROUTE, LOCAL_ROUTE.
354
+			</para>
355
+			<example>
356
+				<title><function>uac_send_request</function> usage</title>
357
+				<programlisting format="linespecific">
358
+...
359
+$uac_req(method)="OPTIONS";
360
+$uac_req(ruri)="sip:kamailio.org";
361
+$uac_req(furi)="sip:kamailio.org";
362
+$uac_req(turi)="sip:kamailio.org";
363
+uac_send_req();
338 364
 ...
339 365
 				</programlisting>
340 366
 			</example>
341 367
 		</section>
342 368
 	</section>
343
-
369
+	<section>
370
+		<title>Exported pseudo-variables</title>
371
+		<itemizedlist>
372
+			<listitem><para>
373
+				<emphasis>$uac_req(key)</emphasis>
374
+			</para></listitem>
375
+		</itemizedlist>
376
+		<para>
377
+		Exported pseudo-variables are documented at &kamwikilink;.
378
+		</para>
379
+	</section>
344 380
 </chapter>
345 381
 
... ...
@@ -47,6 +47,7 @@
47 47
 
48 48
 #include "from.h"
49 49
 #include "auth.h"
50
+#include "uac_send.h"
50 51
 
51 52
 
52 53
 MODULE_VERSION
... ...
@@ -78,6 +79,13 @@ static int mod_init(void);
78 79
 static void mod_destroy(void);
79 80
 
80 81
 
82
+static pv_export_t mod_pvs[] = {
83
+	{ {"uac_req", sizeof("uac_req")-1}, PVT_OTHER, pv_get_uac_req, pv_set_uac_req,
84
+		pv_parse_uac_req_name, 0, 0, 0 },
85
+	{ {0, 0}, 0, 0, 0, 0, 0, 0, 0 }
86
+};
87
+
88
+
81 89
 /* Exported functions */
82 90
 static cmd_export_t cmds[]={
83 91
 	{"uac_replace_from",  (cmd_function)w_replace_from2,  2, fixup_replace_from2, 0,
... ...
@@ -88,6 +96,10 @@ static cmd_export_t cmds[]={
88 96
 			REQUEST_ROUTE },
89 97
 	{"uac_auth",          (cmd_function)w_uac_auth,       0,                  0, 0,
90 98
 			FAILURE_ROUTE },
99
+	{"uac_req_send",  (cmd_function)uac_req_send,         0,                  0, 0, 
100
+		REQUEST_ROUTE | FAILURE_ROUTE |
101
+		ONREPLY_ROUTE | BRANCH_ROUTE | ERROR_ROUTE | LOCAL_ROUTE},
102
+
91 103
 	{0,0,0,0,0,0}
92 104
 };
93 105
 
... ...
@@ -114,7 +126,7 @@ struct module_exports exports= {
114 126
 	params,     /* param exports */
115 127
 	0,          /* exported statistics */
116 128
 	0,          /* exported MI functions */
117
-	0,          /* exported pseudo-variables */
129
+	mod_pvs,    /* exported pseudo-variables */
118 130
 	0,          /* extra processes */
119 131
 	mod_init,   /* module initialization function */
120 132
 	0,
... ...
@@ -208,6 +220,8 @@ static int mod_init(void)
208 220
 
209 221
 	init_from_replacer();
210 222
 
223
+	uac_req_init();
224
+
211 225
 	return 0;
212 226
 error:
213 227
 	return -1;
214 228
new file mode 100644
... ...
@@ -0,0 +1,393 @@
1
+/**
2
+ * $Id$
3
+ *
4
+ * Copyright (C) 2009 Daniel-Constantin Mierla (asipto.com)
5
+ *
6
+ * This file is part of kamailio, a free SIP server.
7
+ *
8
+ * openser 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
+ * openser is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program; if not, write to the Free Software
20
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21
+ */
22
+
23
+#include "../../dprint.h"
24
+
25
+#include "../tm/tm_load.h"
26
+
27
+#include "uac_send.h"
28
+
29
+#define MAX_UACH_SIZE 2048
30
+#define MAX_UACB_SIZE 4086
31
+
32
+/** TM bind */
33
+struct tm_binds tmb;
34
+
35
+struct _uac_send_info {
36
+	unsigned int flags;
37
+	char  b_method[32];
38
+	str   s_method;
39
+	char  b_ruri[MAX_URI_SIZE];
40
+	str   s_ruri;
41
+	char  b_turi[MAX_URI_SIZE];
42
+	str   s_turi;
43
+	char  b_furi[MAX_URI_SIZE];
44
+	str   s_furi;
45
+	char  b_hdrs[MAX_UACH_SIZE];
46
+	str   s_hdrs;
47
+	char  b_body[MAX_UACB_SIZE];
48
+	str   s_body;
49
+	char  b_ouri[MAX_URI_SIZE];
50
+	str   s_ouri;
51
+	unsigned int onreply;
52
+};
53
+
54
+static struct _uac_send_info _uac_req;
55
+
56
+int pv_get_uac_req(struct sip_msg *msg, pv_param_t *param,
57
+		pv_value_t *res)
58
+{
59
+	if(param==NULL || tmb.t_request==NULL)
60
+		return -1;
61
+
62
+	switch(param->pvn.u.isname.name.n)
63
+	{
64
+		case 0:
65
+			return pv_get_uintval(msg, param, res, _uac_req.flags);
66
+		case 1:
67
+			if(_uac_req.s_ruri.len<=0)
68
+				return pv_get_null(msg, param, res);
69
+			return pv_get_strval(msg, param, res, &_uac_req.s_ruri);
70
+		case 2:
71
+			if(_uac_req.s_turi.len<=0)
72
+				return pv_get_null(msg, param, res);
73
+			return pv_get_strval(msg, param, res, &_uac_req.s_turi);
74
+		case 3:
75
+			if(_uac_req.s_furi.len<=0)
76
+				return pv_get_null(msg, param, res);
77
+			return pv_get_strval(msg, param, res, &_uac_req.s_furi);
78
+		case 4:
79
+			if(_uac_req.s_hdrs.len<=0)
80
+				return pv_get_null(msg, param, res);
81
+			return pv_get_strval(msg, param, res, &_uac_req.s_hdrs);
82
+		case 5:
83
+			if(_uac_req.s_body.len<=0)
84
+				return pv_get_null(msg, param, res);
85
+			return pv_get_strval(msg, param, res, &_uac_req.s_body);
86
+		case 6:
87
+			if(_uac_req.s_ouri.len<=0)
88
+				return pv_get_null(msg, param, res);
89
+			return pv_get_strval(msg, param, res, &_uac_req.s_ouri);
90
+		case 7:
91
+			if(_uac_req.s_method.len<=0)
92
+				return pv_get_null(msg, param, res);
93
+			return pv_get_strval(msg, param, res, &_uac_req.s_method);
94
+		default:
95
+			return pv_get_uintval(msg, param, res, _uac_req.flags);
96
+	}
97
+	return 0;
98
+}
99
+
100
+int pv_set_uac_req(struct sip_msg* msg, pv_param_t *param,
101
+		int op, pv_value_t *val)
102
+{
103
+	if(param==NULL || tmb.t_request==NULL)
104
+		return -1;
105
+
106
+	switch(param->pvn.u.isname.name.n)
107
+	{
108
+		case 0:
109
+			if(val==NULL)
110
+			{
111
+				_uac_req.flags = 0;
112
+				_uac_req.s_ruri.len = 0;
113
+				_uac_req.s_furi.len = 0;
114
+				_uac_req.s_turi.len = 0;
115
+				_uac_req.s_ouri.len = 0;
116
+				_uac_req.s_hdrs.len = 0;
117
+				_uac_req.s_body.len = 0;
118
+				_uac_req.s_method.len = 0;
119
+				_uac_req.onreply = 0;
120
+			}
121
+			break;
122
+		case 1:
123
+			if(val==NULL)
124
+			{
125
+				_uac_req.s_ruri.len = 0;
126
+				return 0;
127
+			}
128
+			if(!(val->flags&PV_VAL_STR))
129
+			{
130
+				LM_ERR("Invalid value type\n");
131
+				return -1;
132
+			}
133
+			if(val->rs.len>=MAX_URI_SIZE)
134
+			{
135
+				LM_ERR("Value size too big\n");
136
+				return -1;
137
+			}
138
+			memcpy(_uac_req.s_ruri.s, val->rs.s, val->rs.len);
139
+			_uac_req.s_ruri.s[val->rs.len] = '\0';
140
+			_uac_req.s_ruri.len = val->rs.len;
141
+			break;
142
+		case 2:
143
+			if(val==NULL)
144
+			{
145
+				_uac_req.s_turi.len = 0;
146
+				return 0;
147
+			}
148
+			if(!(val->flags&PV_VAL_STR))
149
+			{
150
+				LM_ERR("Invalid value type\n");
151
+				return -1;
152
+			}
153
+			if(val->rs.len>=MAX_URI_SIZE)
154
+			{
155
+				LM_ERR("Value size too big\n");
156
+				return -1;
157
+			}
158
+			memcpy(_uac_req.s_turi.s, val->rs.s, val->rs.len);
159
+			_uac_req.s_turi.s[val->rs.len] = '\0';
160
+			_uac_req.s_turi.len = val->rs.len;
161
+			break;
162
+		case 3:
163
+			if(val==NULL)
164
+			{
165
+				_uac_req.s_furi.len = 0;
166
+				return 0;
167
+			}
168
+			if(!(val->flags&PV_VAL_STR))
169
+			{
170
+				LM_ERR("Invalid value type\n");
171
+				return -1;
172
+			}
173
+			if(val->rs.len>=MAX_URI_SIZE)
174
+			{
175
+				LM_ERR("Value size too big\n");
176
+				return -1;
177
+			}
178
+			memcpy(_uac_req.s_furi.s, val->rs.s, val->rs.len);
179
+			_uac_req.s_furi.s[val->rs.len] = '\0';
180
+			_uac_req.s_furi.len = val->rs.len;
181
+			break;
182
+		case 4:
183
+			if(val==NULL)
184
+			{
185
+				_uac_req.s_hdrs.len = 0;
186
+				return 0;
187
+			}
188
+						if(!(val->flags&PV_VAL_STR))
189
+			{
190
+				LM_ERR("Invalid value type\n");
191
+				return -1;
192
+			}
193
+			if(val->rs.len>=MAX_UACH_SIZE)
194
+			{
195
+				LM_ERR("Value size too big\n");
196
+				return -1;
197
+			}
198
+			memcpy(_uac_req.s_hdrs.s, val->rs.s, val->rs.len);
199
+			_uac_req.s_hdrs.s[val->rs.len] = '\0';
200
+			_uac_req.s_hdrs.len = val->rs.len;
201
+			break;
202
+		case 5:
203
+			if(val==NULL)
204
+			{
205
+				_uac_req.s_body.len = 0;
206
+				return 0;
207
+			}
208
+			if(!(val->flags&PV_VAL_STR))
209
+			{
210
+				LM_ERR("Invalid value type\n");
211
+				return -1;
212
+			}
213
+			if(val->rs.len>=MAX_UACB_SIZE)
214
+			{
215
+				LM_ERR("Value size too big\n");
216
+				return -1;
217
+			}
218
+			memcpy(_uac_req.s_body.s, val->rs.s, val->rs.len);
219
+			_uac_req.s_body.s[val->rs.len] = '\0';
220
+			_uac_req.s_body.len = val->rs.len;
221
+			break;
222
+		case 6:
223
+			if(val==NULL)
224
+			{
225
+				_uac_req.s_ouri.len = 0;
226
+				return 0;
227
+			}
228
+			if(!(val->flags&PV_VAL_STR))
229
+			{
230
+				LM_ERR("Invalid value type\n");
231
+				return -1;
232
+			}
233
+			if(val->rs.len>=MAX_URI_SIZE)
234
+			{
235
+				LM_ERR("Value size too big\n");
236
+				return -1;
237
+			}
238
+			memcpy(_uac_req.s_ouri.s, val->rs.s, val->rs.len);
239
+			_uac_req.s_ouri.s[val->rs.len] = '\0';
240
+			_uac_req.s_ouri.len = val->rs.len;
241
+			break;
242
+		case 7:
243
+			if(val==NULL)
244
+			{
245
+				_uac_req.s_method.len = 0;
246
+				return 0;
247
+			}
248
+			if(!(val->flags&PV_VAL_STR))
249
+			{
250
+				LM_ERR("Invalid value type\n");
251
+				return -1;
252
+			}
253
+			if(val->rs.len>=32)
254
+			{
255
+				LM_ERR("Value size too big\n");
256
+				return -1;
257
+			}
258
+			memcpy(_uac_req.s_method.s, val->rs.s, val->rs.len);
259
+			_uac_req.s_method.s[val->rs.len] = '\0';
260
+			_uac_req.s_method.len = val->rs.len;
261
+			break;
262
+		case 8:
263
+			if(val==NULL)
264
+			{
265
+				_uac_req.onreply = 0;
266
+				return 0;
267
+			}
268
+			if(!(val->flags&PV_VAL_INT))
269
+			{
270
+				LM_ERR("Invalid value type\n");
271
+				return -1;
272
+			}
273
+			if(val->ri>=ONREPLY_RT_NO)
274
+			{
275
+				LM_ERR("Value too big\n");
276
+				return -1;
277
+			}
278
+			_uac_req.onreply = val->ri;
279
+			break;
280
+	}
281
+	return 0;
282
+}
283
+
284
+int pv_parse_uac_req_name(pv_spec_p sp, str *in)
285
+{
286
+	if(sp==NULL || in==NULL || in->len<=0)
287
+		return -1;
288
+
289
+	switch(in->len)
290
+	{
291
+		case 3: 
292
+			if(strncmp(in->s, "all", 3)==0)
293
+				sp->pvp.pvn.u.isname.name.n = 0;
294
+			else goto error;
295
+		break;
296
+		case 4: 
297
+			if(strncmp(in->s, "ruri", 4)==0)
298
+				sp->pvp.pvn.u.isname.name.n = 1;
299
+			else if(strncmp(in->s, "turi", 4)==0)
300
+				sp->pvp.pvn.u.isname.name.n = 2;
301
+			else if(strncmp(in->s, "furi", 4)==0)
302
+				sp->pvp.pvn.u.isname.name.n = 3;
303
+			else if(strncmp(in->s, "body", 4)==0)
304
+				sp->pvp.pvn.u.isname.name.n = 4;
305
+			else if(strncmp(in->s, "hdrs", 4)==0)
306
+				sp->pvp.pvn.u.isname.name.n = 5;
307
+			else if(strncmp(in->s, "ouri", 4)==0)
308
+				sp->pvp.pvn.u.isname.name.n = 6;
309
+			else goto error;
310
+		break;
311
+		case 6: 
312
+			if(strncmp(in->s, "method", 6)==0)
313
+				sp->pvp.pvn.u.isname.name.n = 7;
314
+			if(strncmp(in->s, "onreply", 6)==0)
315
+				sp->pvp.pvn.u.isname.name.n = 8;
316
+			else goto error;
317
+		break;
318
+		default:
319
+			goto error;
320
+	}
321
+	sp->pvp.pvn.type = PV_NAME_INTSTR;
322
+	sp->pvp.pvn.u.isname.type = 0;
323
+
324
+	return 0;
325
+
326
+error:
327
+	LM_ERR("unknown uac_req name %.*s\n", in->len, in->s);
328
+	return -1;
329
+}
330
+
331
+void uac_req_init(void)
332
+{
333
+	/* load the TM API */
334
+	if (load_tm_api(&tmb)!=0) {
335
+		LM_DBG("can't load TM API - disable it\n");
336
+		memset(&tmb, 0, sizeof(struct tm_binds));
337
+		return;
338
+	}
339
+	memset(&_uac_req, 0, sizeof(struct _uac_send_info));
340
+	_uac_req.s_ruri.s = _uac_req.b_ruri;
341
+	_uac_req.s_furi.s = _uac_req.b_furi;
342
+	_uac_req.s_turi.s = _uac_req.b_turi;
343
+	_uac_req.s_ouri.s = _uac_req.b_ouri;
344
+	_uac_req.s_hdrs.s = _uac_req.b_hdrs;
345
+	_uac_req.s_body.s = _uac_req.b_body;
346
+	_uac_req.s_method.s = _uac_req.b_method;
347
+	return;
348
+}
349
+
350
+/** 
351
+ * TM callback function
352
+ */
353
+void uac_send_tm_callback( struct cell *t, int type, struct tmcb_params *ps)
354
+{
355
+	unsigned int onreply;
356
+	if(ps->param==NULL || *ps->param==0)
357
+	{
358
+		LM_DBG("message id not received\n");
359
+		goto done;
360
+	}
361
+	onreply = *((unsigned int*)ps->param);
362
+	LM_DBG("completed with status %d [onreply: %u]\n",
363
+		ps->code, onreply);
364
+
365
+done:
366
+	return;
367
+}
368
+
369
+
370
+int uac_req_send(struct sip_msg *msg, char *s1, char *s2)
371
+{
372
+	int ret;
373
+	if(_uac_req.s_ruri.len<=0 || _uac_req.s_method.len == 0
374
+			|| tmb.t_request==NULL)
375
+		return -1;
376
+	ret = tmb.t_request(&_uac_req.s_method,  /* Type of the message */
377
+		&_uac_req.s_ruri,     /* Request-URI (To) */
378
+		(_uac_req.s_turi.len<=0)?&_uac_req.s_ruri:&_uac_req.s_turi,  /* To */
379
+		(_uac_req.s_furi.len<=0)?&_uac_req.s_ruri:&_uac_req.s_furi,  /* From */
380
+		(_uac_req.s_hdrs.len<=0)?NULL:&_uac_req.s_hdrs, /* Optional headers
381
+														   including CRLF */
382
+		(_uac_req.s_body.len<=0)?NULL:&_uac_req.s_body, /* Message body */
383
+		(_uac_req.s_ouri.len<=0)?NULL:&_uac_req.s_ouri, /* outbound uri */
384
+		(_uac_req.onreply>0)?uac_send_tm_callback:NULL, /* Callback function */
385
+		(_uac_req.onreply>0)?(void*)(long)_uac_req.onreply:0
386
+														/* Callback parameter */
387
+		);
388
+
389
+	if(ret!=0)
390
+		return -1;
391
+	return 1;
392
+}
393
+
0 394
new file mode 100644
... ...
@@ -0,0 +1,36 @@
1
+/**
2
+ * $Id$
3
+ *
4
+ * Copyright (C) 2009 Daniel-Constantin Mierla (asipto.com)
5
+ *
6
+ * This file is part of kamailio, a free SIP server.
7
+ *
8
+ * openser 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
+ * openser is distributed in the hope that it will be useful,
14
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
+ * GNU General Public License for more details.
17
+ *
18
+ * You should have received a copy of the GNU General Public License
19
+ * along with this program; if not, write to the Free Software
20
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21
+ */
22
+		       
23
+#ifndef _UAC_SEND_H_
24
+#define _UAC_SEND_H_
25
+
26
+#include "../../pvar.h"
27
+
28
+int pv_get_uac_req(struct sip_msg *msg, pv_param_t *param,
29
+		pv_value_t *res);
30
+int pv_set_uac_req(struct sip_msg* msg, pv_param_t *param,
31
+		int op, pv_value_t *val);
32
+int pv_parse_uac_req_name(pv_spec_p sp, str *in);
33
+void uac_req_init(void);
34
+int uac_req_send(struct sip_msg *msg, char *s1, char *s2);
35
+
36
+#endif