Browse code

lost: end of line normalization to linux line ending format

Henning Westerholt authored on 09/09/2019 19:28:45
Showing 7 changed files
... ...
@@ -1,611 +1,611 @@
1
-/*
2
- * lost module functions
3
- *
4
- * Copyright (C) 2019 Wolfgang Kampichler
5
- * DEC112, FREQUENTIS AG
6
- *
7
- * This file is part of Kamailio, a free SIP server.
8
- *
9
- * Kamailio is free software; you can redistribute it and/or modify
10
- * it under the terms of the GNU General Public License as published by
11
- * the Free Software Foundation; either version 2 of the License, or
12
- * (at your option) any later version
13
- *
14
- * Kamailio is distributed in the hope that it will be useful,
15
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
- * GNU General Public License for more details.
18
- *
19
- * You should have received a copy of the GNU General Public License
20
- * along with this program; if not, write to the Free Software
21
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
22
- *
23
- */
24
-
25
-/*!
26
- * \file
27
- * \brief Kamailio lost :: functions
28
- * \ingroup lost
29
- * Module: \ref lost
30
- */
31
-/*****************/
32
-
33
-#include "../../modules/http_client/curl_api.h"
34
-
35
-#include "../../core/mod_fix.h"
36
-#include "../../core/pvar.h"
37
-#include "../../core/route_struct.h"
38
-#include "../../core/ut.h"
39
-#include "../../core/trim.h"
40
-#include "../../core/mem/mem.h"
41
-#include "../../core/parser/msg_parser.h"
42
-#include "../../core/parser/parse_body.h"
43
-#include "../../core/lvalue.h"
44
-
45
-#include "pidf.h"
46
-#include "utilities.h"
47
-
48
-#define LOST_SUCCESS 200
49
-#define LOST_CLIENT_ERROR 400
50
-#define LOST_SERVER_ERROR 500
51
-
52
-extern httpc_api_t httpapi;
53
-
54
-char mtheld[] = "application/held+xml;charset=utf-8";
55
-char mtlost[] = "application/lost+xml;charset=utf-8";
56
-
57
-char uri_element[] = "uri";
58
-char name_element[] = "displayName";
59
-char errors_element[] = "errors";
60
-
61
-/*
62
- * lost_function_held(msg, con, pidf, url, err, id)
63
- * assembles and runs HELD locationRequest, parses results
64
- */
65
-int lost_function_held(struct sip_msg *_m, char *_con, char *_pidf, char *_url,
66
-		char *_err, char *_id)
67
-{
68
-	pv_spec_t *pspidf;
69
-	pv_spec_t *psurl;
70
-	pv_spec_t *pserr;
71
-
72
-	pv_value_t pvpidf;
73
-	pv_value_t pvurl;
74
-	pv_value_t pverr;
75
-
76
-	xmlDocPtr doc = NULL;
77
-	xmlNodePtr root = NULL;
78
-
79
-	str did = {NULL, 0};
80
-	str que = {NULL, 0};
81
-	str con = {NULL, 0};
82
-	str geo = {NULL, 0};
83
-	str err = {NULL, 0};
84
-	str res = {NULL, 0};
85
-	str idhdr = {NULL, 0};
86
-
87
-	int curlres = 0;
88
-
89
-	if(_con == NULL || _pidf == NULL || _url == NULL || _err == NULL) {
90
-		LM_ERR("invalid parameter\n");
91
-		goto err;
92
-	}
93
-	/* connection from parameter */
94
-	if(fixup_get_svalue(_m, (gparam_p)_con, &con) != 0) {
95
-		LM_ERR("cannot get connection string\n");
96
-		goto err;
97
-	}
98
-	/* id from parameter */
99
-	if(_id) {
100
-		if(fixup_get_svalue(_m, (gparam_p)_id, &did) != 0) {
101
-			LM_ERR("cannot get device id\n");
102
-			goto err;
103
-		}
104
-		if(!did.s) {
105
-			LM_ERR("no device found\n");
106
-			goto err;
107
-		}
108
-	} else {
109
-
110
-		LM_DBG("parsing P-A-I header\n");
111
-
112
-		/* id from P-A-I header */
113
-		idhdr.s = lost_get_pai_header(_m, &idhdr.len);
114
-		if(idhdr.len == 0) {
115
-			LM_WARN("P-A-I header not found, trying From header ...\n");
116
-
117
-			LM_DBG("parsing From header\n");
118
-			
119
-			/* id from From header */
120
-			idhdr.s = lost_get_from_header(_m, &idhdr.len);
121
-			if(idhdr.len == 0) {
122
-				LM_ERR("no device id found\n");
123
-				goto err;
124
-			}
125
-		}
126
-		did.s = idhdr.s;
127
-		did.len = idhdr.len;
128
-	}
129
-	LM_INFO("### HELD id [%.*s]\n", did.len, did.s);
130
-
131
-	/* check if connection exists */
132
-	if(httpapi.http_connection_exists(&con) == 0) {
133
-		LM_ERR("connection: [%s] does not exist\n", con.s);
134
-		goto err;
135
-	}
136
-
137
-	/* assemble locationRequest */
138
-	que.s = lost_held_location_request(did.s, &que.len);
139
-	/* free memory */
140
-	lost_free_string(&idhdr);
141
-	did.s = NULL;
142
-	did.len = 0;
143
-	if(!que.s) {
144
-		LM_ERR("held request document error\n");
145
-		goto err;
146
-	}
147
-
148
-	LM_DBG("held location request: [%s]\n", que.s);
149
-
150
-	/* send locationRequest to location server - HTTP POST */
151
-	curlres = httpapi.http_connect(_m, &con, NULL, &res, mtheld, &que);
152
-	/* only HTTP 2xx responses are accepted */ 
153
-	if(curlres >= 300 || curlres < 100) {
154
-		LM_ERR("[%.*s] failed with error: %d\n", con.len, con.s, curlres);
155
-		res.s = NULL;
156
-		res.len = 0;
157
-		goto err;
158
-	}
159
-
160
-	LM_DBG("[%.*s] returned: %d\n", con.len, con.s, curlres);
161
-
162
-	/* free memory */
163
-	lost_free_string(&que);
164
-	/* read and parse the returned xml */
165
-	doc = xmlReadMemory(res.s, res.len, 0, NULL,
166
-			XML_PARSE_NOBLANKS | XML_PARSE_NONET | XML_PARSE_NOCDATA);
167
-	if(!doc) {
168
-		LM_WARN("invalid xml document: [%.*s]\n", res.len, res.s);
169
-		doc = xmlRecoverMemory(res.s, res.len);
170
-		if(!doc) {
171
-			LM_ERR("xml document recovery failed on: [%.*s]\n", res.len,
172
-					res.s);
173
-			goto err;
174
-		}
175
-
176
-		LM_DBG("xml document recovered\n");
177
-	}
178
-	root = xmlDocGetRootElement(doc);
179
-	if(!root) {
180
-		LM_ERR("empty xml document\n");
181
-		goto err;
182
-	}
183
-	/* check the root element, shall be locationResponse, or errors */
184
-	if(!xmlStrcmp(root->name, (const xmlChar *)"locationResponse")) {
185
-
186
-		LM_DBG("HELD location response [%.*s]\n", res.len, res.s);
187
-
188
-		/* get the locationUri element */
189
-		geo.s = lost_get_content(root, (char *)"locationURI", &geo.len);
190
-		if(!geo.s) {
191
-			LM_ERR("no locationURI element found\n");
192
-			goto err;
193
-		}
194
-	} else if(!xmlStrcmp(root->name, (const xmlChar *)"error")) {
195
-
196
-		LM_DBG("HELD error response [%.*s]\n", res.len, res.s);
197
-
198
-		/* get the error patterm */
199
-		err.s = lost_get_property(root, (char *)"code", &err.len);
200
-		if(!err.s) {
201
-			LM_ERR("error - code property not found: [%.*s]\n", res.len,
202
-					res.s);
203
-			goto err;
204
-		}
205
-		LM_WARN("locationRequest error response: [%.*s]\n", err.len, err.s);
206
-	} else {
207
-		LM_ERR("root element is not valid: [%.*s]\n", res.len, res.s);
208
-		goto err;
209
-	}
210
-	xmlFreeDoc(doc);
211
-
212
-	/* set writeable pvars */
213
-	pvpidf.rs = res;
214
-	pvpidf.rs.s = res.s;
215
-	pvpidf.rs.len = res.len;
216
-
217
-	pvpidf.flags = PV_VAL_STR;
218
-	pspidf = (pv_spec_t *)_pidf;
219
-	pspidf->setf(_m, &pspidf->pvp, (int)EQ_T, &pvpidf);
220
-
221
-	pvurl.rs = geo;
222
-	pvurl.rs.s = geo.s;
223
-	pvurl.rs.len = geo.len;
224
-
225
-	pvurl.flags = PV_VAL_STR;
226
-	psurl = (pv_spec_t *)_url;
227
-	psurl->setf(_m, &psurl->pvp, (int)EQ_T, &pvurl);
228
-
229
-	pverr.rs = err;
230
-	pverr.rs.s = err.s;
231
-	pverr.rs.len = err.len;
232
-
233
-	pverr.flags = PV_VAL_STR;
234
-	pserr = (pv_spec_t *)_err;
235
-	pserr->setf(_m, &pserr->pvp, (int)EQ_T, &pverr);
236
-
237
-	return (err.len > 0) ? LOST_SERVER_ERROR : LOST_SUCCESS;
238
-
239
-err:
240
-	if(doc)
241
-		xmlFreeDoc(doc);
242
-	
243
-	lost_free_string(&idhdr);
244
-	lost_free_string(&que);
245
-
246
-	return LOST_CLIENT_ERROR;
247
-}
248
-
249
-/*
250
- * lost_function(msg, con, pidf, uri, name, err, pidf, urn)
251
- * assembles and runs LOST findService request, parses results
252
- */
253
-int lost_function(struct sip_msg *_m, char *_con, char *_uri, char *_name,
254
-		char *_err, char *_pidf, char *_urn)
255
-{
256
-	pv_spec_t *psname;
257
-	pv_spec_t *psuri;
258
-	pv_spec_t *pserr;
259
-
260
-	pv_value_t pvname;
261
-	pv_value_t pvuri;
262
-	pv_value_t pverr;
263
-
264
-	p_loc_t loc = NULL;
265
-
266
-	xmlDocPtr doc = NULL;
267
-	xmlNodePtr root = NULL;
268
-
269
-	str uri = {NULL, 0};
270
-	str urn = {NULL, 0};
271
-	str err = {NULL, 0};
272
-	str res = {NULL, 0};
273
-	str con = {NULL, 0};
274
-	str ret = {NULL, 0};
275
-	str geo = {NULL, 0};
276
-	str geohdr = {NULL, 0};
277
-	str name = {NULL, 0};
278
-	str pidf = {NULL, 0};
279
-	str pidfhdr = {NULL, 0};
280
-
281
-	struct msg_start *fl;
282
-	char *search = NULL;
283
-	int curlres = 0;
284
-	
285
-	if(_con == NULL || _uri == NULL || _name == NULL || _err == NULL) {
286
-		LM_ERR("invalid parameter\n");
287
-		goto err;
288
-	}
289
-	if(fixup_get_svalue(_m, (gparam_p)_con, &con) != 0) {
290
-		LM_ERR("cannot get connection string\n");
291
-		goto err;
292
-	}
293
-	/* urn from parameter */
294
-	if(_urn) {
295
-		if(fixup_get_svalue(_m, (gparam_p)_urn, &urn) != 0) {
296
-			LM_ERR("cannot get service urn\n");
297
-			goto err;
298
-		}
299
-	}
300
-	/* urn from request line */
301
-	if(urn.len == 0) {
302
-		LM_WARN("no sevice urn parameter, trying request line ...\n");
303
-		fl = &(_m->first_line);
304
-		urn.len = fl->u.request.uri.len;
305
-		urn.s = fl->u.request.uri.s;
306
-	}
307
-	/* check urn scheme */
308
-	if(urn.len > 3) {
309
-		search = urn.s;
310
-		if(((*(search + 0) == 'u') || (*(search + 0) == 'U'))
311
-				&& ((*(search + 1) == 'r') || (*(search + 1) == 'R'))
312
-				&& ((*(search + 2) == 'n') || (*(search + 2) == 'N'))
313
-				&& (*(search + 3) == ':')) {
314
-			LM_INFO("### LOST urn [%.*s]\n", urn.len, urn.s);
315
-		} else {
316
-			LM_ERR("service urn not found\n");
317
-			goto err;
318
-		}
319
-	} else {
320
-		LM_ERR("service urn not found\n");
321
-		goto err;
322
-	}
323
-	/* pidf from parameter */
324
-	if(_pidf) {
325
-		if(fixup_get_svalue(_m, (gparam_p)_pidf, &pidf) != 0) {
326
-			LM_ERR("cannot get pidf-lo\n");
327
-			goto err;
328
-		}
329
-	}
330
-	/* pidf from geolocation header */
331
-	if(pidf.len == 0) {
332
-		LM_WARN("no pidf parameter, trying geolocation header ...\n");
333
-		geohdr.s = lost_get_geolocation_header(_m, &geohdr.len);
334
-		if(!geohdr.s) {
335
-			LM_ERR("geolocation header not found\n");
336
-			goto err;
337
-		} else {
338
-
339
-			LM_DBG("geolocation header found\n");
340
-
341
-			/* pidf from multipart body, check cid scheme */
342
-			if(geohdr.len > 6) {
343
-				search = geohdr.s;
344
-				if((*(search + 0) == '<')
345
-						&& ((*(search + 1) == 'c') || (*(search + 1) == 'C'))
346
-						&& ((*(search + 2) == 'i') || (*(search + 2) == 'I'))
347
-						&& ((*(search + 3) == 'd') || (*(search + 3) == 'D'))
348
-						&& (*(search + 4) == ':')) {
349
-					search += 4;
350
-					*search = '<';
351
-					geo.s = search;
352
-					geo.len = geo.len - 4;
353
-
354
-					LM_DBG("cid: [%.*s]\n", geo.len, geo.s);
355
-
356
-					/* get body part - filter=>content id */
357
-					pidf.s = get_body_part_by_filter(
358
-							_m, 0, 0, geo.s, NULL, &pidf.len);
359
-					if(!pidf.s) {
360
-						LM_ERR("no multipart body found\n");
361
-						goto err;
362
-					}
363
-				}
364
-				/* no pidf-lo so far ... check http(s) scheme */
365
-				if(((*(search + 0) == 'h') || (*(search + 0) == 'H'))
366
-						&& ((*(search + 1) == 't') || (*(search + 1) == 'T'))
367
-						&& ((*(search + 2) == 't') || (*(search + 2) == 'T'))
368
-						&& ((*(search + 3) == 'p') || (*(search + 3) == 'P'))) {
369
-					geo.s = geohdr.s;
370
-					geo.len = geohdr.len;
371
-
372
-					if(*(search + 4) == ':') {
373
-					
374
-						LM_DBG("http url: [%.*s]\n", geo.len, geo.s);
375
-					
376
-					} else if(((*(search + 4) == 's') || (*(search + 4) == 'S'))
377
-							&& (*(search + 5) == ':')) {
378
-					
379
-						LM_DBG("https url: [%.*s]\n", geo.len, geo.s);
380
-					
381
-					} else {
382
-						LM_ERR("invalid url: [%.*s]\n", geo.len, geo.s);
383
-						goto err;
384
-					}
385
-
386
-					/* ! dereference pidf.lo at location server - HTTP GET */
387
-					/* ! requires hack in http_client module */
388
-					/* ! functions.c => http_client_query => query_params.oneline = 0; */
389
-					curlres = httpapi.http_client_query(_m, geo.s, &pidfhdr, NULL, NULL);
390
-					/* free memory */
391
-					lost_free_string(&geohdr);
392
-					geo.s = NULL;
393
-					geo.len = 0;
394
-					/* only HTTP 2xx responses are accepted */ 
395
-					if(curlres >= 300 || curlres < 100) {
396
-						LM_ERR("http GET failed with error: %d\n", curlres);
397
-						pidfhdr.s = NULL;
398
-						pidfhdr.len = 0;
399
-						goto err;
400
-					}
401
-
402
-					LM_DBG("http GET returned: %d\n", curlres);
403
-
404
-					if(!pidfhdr.s) {
405
-						LM_ERR("dereferencing location failed\n");
406
-						goto err;
407
-					}
408
-					pidf.s = pidfhdr.s;
409
-					pidf.len = pidfhdr.len;
410
-				}
411
-			} else {
412
-				LM_ERR("invalid geolocation header\n");
413
-				goto err;
414
-			}
415
-		}
416
-	}
417
-
418
-	/* no pidf-lo return error */
419
-	if(!pidf.s) {
420
-		LM_ERR("pidf-lo not found\n");
421
-		goto err;
422
-	}
423
-
424
-	LM_DBG("pidf-lo: [%.*s]\n", pidf.len, pidf.s);
425
-
426
-	/* read and parse pidf-lo */
427
-	doc = xmlReadMemory(pidf.s, pidf.len, 0, NULL,
428
-			XML_PARSE_NOBLANKS | XML_PARSE_NONET | XML_PARSE_NOCDATA);
429
-
430
-	if(!doc) {
431
-		LM_WARN("invalid xml (pidf-lo): [%.*s]\n", pidf.len, pidf.s);
432
-		doc = xmlRecoverMemory(pidf.s, pidf.len);
433
-		if(!doc) {
434
-			LM_ERR("xml (pidf-lo) recovery failed on: [%.*s]\n", pidf.len,
435
-					pidf.s);
436
-			goto err;
437
-		}
438
-
439
-		LM_DBG("xml (pidf-lo) recovered\n");
440
-	}
441
-
442
-	root = xmlDocGetRootElement(doc);
443
-	if(!root) {
444
-		LM_ERR("empty pidf-lo document\n");
445
-		goto err;
446
-	}
447
-	if((!xmlStrcmp(root->name, (const xmlChar *)"presence"))
448
-			|| (!xmlStrcmp(root->name, (const xmlChar *)"locationResponse"))) {
449
-		/* get the geolocation: point or circle, urn, ... */
450
-		loc = lost_new_loc(urn);
451
-		if(!loc) {
452
-			LM_ERR("location object allocation failed\n");
453
-			goto err;			
454
-		}
455
-		if(lost_parse_location_info(root, loc) < 0) {
456
-			LM_ERR("location element not found\n");
457
-			goto err;
458
-		}
459
-	} else {
460
-		LM_ERR("findServiceResponse or presence element not found in "
461
-			   "[%.*s]\n",
462
-				pidf.len, pidf.s);
463
-		goto err;
464
-	}
465
-
466
-	/* free memory */
467
-	lost_free_string(&pidfhdr);
468
-	pidf.s = NULL;
469
-	pidf.len = 0;
470
-
471
-	/* check if connection exits */
472
-	if(httpapi.http_connection_exists(&con) == 0) {
473
-		LM_ERR("connection: [%.*s] does not exist\n", con.len, con.s);
474
-		goto err;
475
-	}
476
-	/* assemble findService request */
477
-	res.s = lost_find_service_request(loc, &res.len);
478
-	/* free memory */
479
-	if(loc) {
480
-		lost_free_loc(loc);
481
-		loc = NULL;
482
-	}
483
-	xmlFreeDoc(doc);
484
-	doc = NULL;
485
-
486
-	if(!res.s) {
487
-		LM_ERR("lost request failed\n");
488
-		goto err;
489
-	}
490
-
491
-	LM_DBG("findService request: [%.*s]\n", res.len, res.s);
492
-
493
-	/* send findService request to mapping server - HTTP POST */
494
-	curlres = httpapi.http_connect(_m, &con, NULL, &ret, mtlost, &res);
495
-	/* only HTTP 2xx responses are accepted */ 
496
-	if(curlres >= 300 || curlres < 100) {
497
-		LM_ERR("[%.*s] failed with error: %d\n", con.len, con.s, curlres);
498
-		ret.s = NULL;
499
-		ret.len = 0;
500
-		goto err;
501
-	}
502
-
503
-	LM_DBG("[%.*s] returned: %d\n", con.len, con.s, curlres);
504
-
505
-	/* free memory */
506
-	lost_free_string(&res);
507
-
508
-	if(!ret.s) {
509
-		LM_ERR("findService request failed\n");
510
-		goto err;
511
-	}
512
-
513
-	LM_DBG("findService response: [%.*s]\n", ret.len, ret.s);
514
-
515
-	/* read and parse the returned xml */
516
-	doc = xmlReadMemory(ret.s, ret.len, 0, 0,
517
-			XML_PARSE_NOBLANKS | XML_PARSE_NONET | XML_PARSE_NOCDATA);
518
-
519
-	if(!doc) {
520
-		LM_ERR("invalid xml document: [%.*s]\n", ret.len, ret.s);
521
-		doc = xmlRecoverMemory(ret.s, ret.len);
522
-		if(!doc) {
523
-			LM_ERR("xml document recovery failed on: [%.*s]\n", ret.len,
524
-					ret.s);
525
-			goto err;
526
-		}
527
-
528
-		LM_DBG("xml document recovered\n");
529
-	}
530
-	root = xmlDocGetRootElement(doc);
531
-	if(!root) {
532
-		LM_ERR("empty xml document: [%.*s]\n", ret.len, ret.s);
533
-		goto err;
534
-	}
535
-	/* check the root element, shall be findServiceResponse, or errors */
536
-	if((!xmlStrcmp(root->name, (const xmlChar *)"findServiceResponse"))) {
537
-		/* get the uri element */
538
-		uri.s = lost_get_content(root, uri_element, &uri.len);
539
-		if(!uri.s) {
540
-			LM_ERR("uri element not found: [%.*s]\n", ret.len, ret.s);
541
-			goto err;
542
-		}
543
-		LM_INFO("### LOST uri [%.*s]\n", uri.len, uri.s);
544
-		/* get the displayName element */
545
-		name.s = lost_get_content(root, name_element, &name.len);
546
-		if(!name.s) {
547
-			LM_ERR("displayName element not found: [%.*s]\n", ret.len, ret.s);
548
-			goto err;
549
-		}
550
-		LM_INFO("### LOST name [%.*s]\n", name.len, name.s);
551
-	} else if((!xmlStrcmp(root->name, (const xmlChar *)"errors"))) {
552
-
553
-		LM_DBG("findService error response received\n");
554
-
555
-		/* get the error patterm */
556
-		err.s = lost_get_childname(root, errors_element, &err.len);
557
-		if(!err.s) {
558
-			LM_ERR("error pattern element not found: [%.*s]\n", ret.len,
559
-					ret.s);
560
-			goto err;
561
-		}
562
-		LM_WARN("findService error response: [%.*s]\n", err.len, err.s);
563
-	} else {
564
-		LM_ERR("root element is not valid: [%.*s]\n", ret.len, ret.s);
565
-		goto err;
566
-	}
567
-
568
-	/* free memory */
569
-	xmlFreeDoc(doc);
570
-	doc = NULL;
571
-	lost_free_string(&ret);
572
-
573
-	/* set writable pvars */
574
-	pvname.rs = name;
575
-	pvname.rs.s = name.s;
576
-	pvname.rs.len = name.len;
577
-
578
-	pvname.flags = PV_VAL_STR;
579
-	psname = (pv_spec_t *)_name;
580
-	psname->setf(_m, &psname->pvp, (int)EQ_T, &pvname);
581
-
582
-	pvuri.rs = uri;
583
-	pvuri.rs.s = uri.s;
584
-	pvuri.rs.len = uri.len;
585
-
586
-	pvuri.flags = PV_VAL_STR;
587
-	psuri = (pv_spec_t *)_uri;
588
-	psuri->setf(_m, &psuri->pvp, (int)EQ_T, &pvuri);
589
-
590
-	pverr.rs = err;
591
-	pverr.rs.s = err.s;
592
-	pverr.rs.len = err.len;
593
-
594
-	pverr.flags = PV_VAL_STR;
595
-	pserr = (pv_spec_t *)_err;
596
-	pserr->setf(_m, &pserr->pvp, (int)EQ_T, &pverr);
597
-
598
-	return (err.len > 0) ? LOST_SERVER_ERROR : LOST_SUCCESS;
599
-
600
-err:
601
-	if(loc)
602
-		lost_free_loc(loc);
603
-	if(doc)
604
-		xmlFreeDoc(doc);
605
-
606
-	lost_free_string(&pidfhdr);
607
-	lost_free_string(&geohdr);
608
-	lost_free_string(&ret);
609
-
610
-	return LOST_CLIENT_ERROR;
611
-}
1
+/*
2
+ * lost module functions
3
+ *
4
+ * Copyright (C) 2019 Wolfgang Kampichler
5
+ * DEC112, FREQUENTIS AG
6
+ *
7
+ * This file is part of Kamailio, a free SIP server.
8
+ *
9
+ * Kamailio is free software; you can redistribute it and/or modify
10
+ * it under the terms of the GNU General Public License as published by
11
+ * the Free Software Foundation; either version 2 of the License, or
12
+ * (at your option) any later version
13
+ *
14
+ * Kamailio is distributed in the hope that it will be useful,
15
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
+ * GNU General Public License for more details.
18
+ *
19
+ * You should have received a copy of the GNU General Public License
20
+ * along with this program; if not, write to the Free Software
21
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
22
+ *
23
+ */
24
+
25
+/*!
26
+ * \file
27
+ * \brief Kamailio lost :: functions
28
+ * \ingroup lost
29
+ * Module: \ref lost
30
+ */
31
+/*****************/
32
+
33
+#include "../../modules/http_client/curl_api.h"
34
+
35
+#include "../../core/mod_fix.h"
36
+#include "../../core/pvar.h"
37
+#include "../../core/route_struct.h"
38
+#include "../../core/ut.h"
39
+#include "../../core/trim.h"
40
+#include "../../core/mem/mem.h"
41
+#include "../../core/parser/msg_parser.h"
42
+#include "../../core/parser/parse_body.h"
43
+#include "../../core/lvalue.h"
44
+
45
+#include "pidf.h"
46
+#include "utilities.h"
47
+
48
+#define LOST_SUCCESS 200
49
+#define LOST_CLIENT_ERROR 400
50
+#define LOST_SERVER_ERROR 500
51
+
52
+extern httpc_api_t httpapi;
53
+
54
+char mtheld[] = "application/held+xml;charset=utf-8";
55
+char mtlost[] = "application/lost+xml;charset=utf-8";
56
+
57
+char uri_element[] = "uri";
58
+char name_element[] = "displayName";
59
+char errors_element[] = "errors";
60
+
61
+/*
62
+ * lost_function_held(msg, con, pidf, url, err, id)
63
+ * assembles and runs HELD locationRequest, parses results
64
+ */
65
+int lost_function_held(struct sip_msg *_m, char *_con, char *_pidf, char *_url,
66
+		char *_err, char *_id)
67
+{
68
+	pv_spec_t *pspidf;
69
+	pv_spec_t *psurl;
70
+	pv_spec_t *pserr;
71
+
72
+	pv_value_t pvpidf;
73
+	pv_value_t pvurl;
74
+	pv_value_t pverr;
75
+
76
+	xmlDocPtr doc = NULL;
77
+	xmlNodePtr root = NULL;
78
+
79
+	str did = {NULL, 0};
80
+	str que = {NULL, 0};
81
+	str con = {NULL, 0};
82
+	str geo = {NULL, 0};
83
+	str err = {NULL, 0};
84
+	str res = {NULL, 0};
85
+	str idhdr = {NULL, 0};
86
+
87
+	int curlres = 0;
88
+
89
+	if(_con == NULL || _pidf == NULL || _url == NULL || _err == NULL) {
90
+		LM_ERR("invalid parameter\n");
91
+		goto err;
92
+	}
93
+	/* connection from parameter */
94
+	if(fixup_get_svalue(_m, (gparam_p)_con, &con) != 0) {
95
+		LM_ERR("cannot get connection string\n");
96
+		goto err;
97
+	}
98
+	/* id from parameter */
99
+	if(_id) {
100
+		if(fixup_get_svalue(_m, (gparam_p)_id, &did) != 0) {
101
+			LM_ERR("cannot get device id\n");
102
+			goto err;
103
+		}
104
+		if(!did.s) {
105
+			LM_ERR("no device found\n");
106
+			goto err;
107
+		}
108
+	} else {
109
+
110
+		LM_DBG("parsing P-A-I header\n");
111
+
112
+		/* id from P-A-I header */
113
+		idhdr.s = lost_get_pai_header(_m, &idhdr.len);
114
+		if(idhdr.len == 0) {
115
+			LM_WARN("P-A-I header not found, trying From header ...\n");
116
+
117
+			LM_DBG("parsing From header\n");
118
+			
119
+			/* id from From header */
120
+			idhdr.s = lost_get_from_header(_m, &idhdr.len);
121
+			if(idhdr.len == 0) {
122
+				LM_ERR("no device id found\n");
123
+				goto err;
124
+			}
125
+		}
126
+		did.s = idhdr.s;
127
+		did.len = idhdr.len;
128
+	}
129
+	LM_INFO("### HELD id [%.*s]\n", did.len, did.s);
130
+
131
+	/* check if connection exists */
132
+	if(httpapi.http_connection_exists(&con) == 0) {
133
+		LM_ERR("connection: [%s] does not exist\n", con.s);
134
+		goto err;
135
+	}
136
+
137
+	/* assemble locationRequest */
138
+	que.s = lost_held_location_request(did.s, &que.len);
139
+	/* free memory */
140
+	lost_free_string(&idhdr);
141
+	did.s = NULL;
142
+	did.len = 0;
143
+	if(!que.s) {
144
+		LM_ERR("held request document error\n");
145
+		goto err;
146
+	}
147
+
148
+	LM_DBG("held location request: [%s]\n", que.s);
149
+
150
+	/* send locationRequest to location server - HTTP POST */
151
+	curlres = httpapi.http_connect(_m, &con, NULL, &res, mtheld, &que);
152
+	/* only HTTP 2xx responses are accepted */ 
153
+	if(curlres >= 300 || curlres < 100) {
154
+		LM_ERR("[%.*s] failed with error: %d\n", con.len, con.s, curlres);
155
+		res.s = NULL;
156
+		res.len = 0;
157
+		goto err;
158
+	}
159
+
160
+	LM_DBG("[%.*s] returned: %d\n", con.len, con.s, curlres);
161
+
162
+	/* free memory */
163
+	lost_free_string(&que);
164
+	/* read and parse the returned xml */
165
+	doc = xmlReadMemory(res.s, res.len, 0, NULL,
166
+			XML_PARSE_NOBLANKS | XML_PARSE_NONET | XML_PARSE_NOCDATA);
167
+	if(!doc) {
168
+		LM_WARN("invalid xml document: [%.*s]\n", res.len, res.s);
169
+		doc = xmlRecoverMemory(res.s, res.len);
170
+		if(!doc) {
171
+			LM_ERR("xml document recovery failed on: [%.*s]\n", res.len,
172
+					res.s);
173
+			goto err;
174
+		}
175
+
176
+		LM_DBG("xml document recovered\n");
177
+	}
178
+	root = xmlDocGetRootElement(doc);
179
+	if(!root) {
180
+		LM_ERR("empty xml document\n");
181
+		goto err;
182
+	}
183
+	/* check the root element, shall be locationResponse, or errors */
184
+	if(!xmlStrcmp(root->name, (const xmlChar *)"locationResponse")) {
185
+
186
+		LM_DBG("HELD location response [%.*s]\n", res.len, res.s);
187
+
188
+		/* get the locationUri element */
189
+		geo.s = lost_get_content(root, (char *)"locationURI", &geo.len);
190
+		if(!geo.s) {
191
+			LM_ERR("no locationURI element found\n");
192
+			goto err;
193
+		}
194
+	} else if(!xmlStrcmp(root->name, (const xmlChar *)"error")) {
195
+
196
+		LM_DBG("HELD error response [%.*s]\n", res.len, res.s);
197
+
198
+		/* get the error patterm */
199
+		err.s = lost_get_property(root, (char *)"code", &err.len);
200
+		if(!err.s) {
201
+			LM_ERR("error - code property not found: [%.*s]\n", res.len,
202
+					res.s);
203
+			goto err;
204
+		}
205
+		LM_WARN("locationRequest error response: [%.*s]\n", err.len, err.s);
206
+	} else {
207
+		LM_ERR("root element is not valid: [%.*s]\n", res.len, res.s);
208
+		goto err;
209
+	}
210
+	xmlFreeDoc(doc);
211
+
212
+	/* set writeable pvars */
213
+	pvpidf.rs = res;
214
+	pvpidf.rs.s = res.s;
215
+	pvpidf.rs.len = res.len;
216
+
217
+	pvpidf.flags = PV_VAL_STR;
218
+	pspidf = (pv_spec_t *)_pidf;
219
+	pspidf->setf(_m, &pspidf->pvp, (int)EQ_T, &pvpidf);
220
+
221
+	pvurl.rs = geo;
222
+	pvurl.rs.s = geo.s;
223
+	pvurl.rs.len = geo.len;
224
+
225
+	pvurl.flags = PV_VAL_STR;
226
+	psurl = (pv_spec_t *)_url;
227
+	psurl->setf(_m, &psurl->pvp, (int)EQ_T, &pvurl);
228
+
229
+	pverr.rs = err;
230
+	pverr.rs.s = err.s;
231
+	pverr.rs.len = err.len;
232
+
233
+	pverr.flags = PV_VAL_STR;
234
+	pserr = (pv_spec_t *)_err;
235
+	pserr->setf(_m, &pserr->pvp, (int)EQ_T, &pverr);
236
+
237
+	return (err.len > 0) ? LOST_SERVER_ERROR : LOST_SUCCESS;
238
+
239
+err:
240
+	if(doc)
241
+		xmlFreeDoc(doc);
242
+	
243
+	lost_free_string(&idhdr);
244
+	lost_free_string(&que);
245
+
246
+	return LOST_CLIENT_ERROR;
247
+}
248
+
249
+/*
250
+ * lost_function(msg, con, pidf, uri, name, err, pidf, urn)
251
+ * assembles and runs LOST findService request, parses results
252
+ */
253
+int lost_function(struct sip_msg *_m, char *_con, char *_uri, char *_name,
254
+		char *_err, char *_pidf, char *_urn)
255
+{
256
+	pv_spec_t *psname;
257
+	pv_spec_t *psuri;
258
+	pv_spec_t *pserr;
259
+
260
+	pv_value_t pvname;
261
+	pv_value_t pvuri;
262
+	pv_value_t pverr;
263
+
264
+	p_loc_t loc = NULL;
265
+
266
+	xmlDocPtr doc = NULL;
267
+	xmlNodePtr root = NULL;
268
+
269
+	str uri = {NULL, 0};
270
+	str urn = {NULL, 0};
271
+	str err = {NULL, 0};
272
+	str res = {NULL, 0};
273
+	str con = {NULL, 0};
274
+	str ret = {NULL, 0};
275
+	str geo = {NULL, 0};
276
+	str geohdr = {NULL, 0};
277
+	str name = {NULL, 0};
278
+	str pidf = {NULL, 0};
279
+	str pidfhdr = {NULL, 0};
280
+
281
+	struct msg_start *fl;
282
+	char *search = NULL;
283
+	int curlres = 0;
284
+	
285
+	if(_con == NULL || _uri == NULL || _name == NULL || _err == NULL) {
286
+		LM_ERR("invalid parameter\n");
287
+		goto err;
288
+	}
289
+	if(fixup_get_svalue(_m, (gparam_p)_con, &con) != 0) {
290
+		LM_ERR("cannot get connection string\n");
291
+		goto err;
292
+	}
293
+	/* urn from parameter */
294
+	if(_urn) {
295
+		if(fixup_get_svalue(_m, (gparam_p)_urn, &urn) != 0) {
296
+			LM_ERR("cannot get service urn\n");
297
+			goto err;
298
+		}
299
+	}
300
+	/* urn from request line */
301
+	if(urn.len == 0) {
302
+		LM_WARN("no sevice urn parameter, trying request line ...\n");
303
+		fl = &(_m->first_line);
304
+		urn.len = fl->u.request.uri.len;
305
+		urn.s = fl->u.request.uri.s;
306
+	}
307
+	/* check urn scheme */
308
+	if(urn.len > 3) {
309
+		search = urn.s;
310
+		if(((*(search + 0) == 'u') || (*(search + 0) == 'U'))
311
+				&& ((*(search + 1) == 'r') || (*(search + 1) == 'R'))
312
+				&& ((*(search + 2) == 'n') || (*(search + 2) == 'N'))
313
+				&& (*(search + 3) == ':')) {
314
+			LM_INFO("### LOST urn [%.*s]\n", urn.len, urn.s);
315
+		} else {
316
+			LM_ERR("service urn not found\n");
317
+			goto err;
318
+		}
319
+	} else {
320
+		LM_ERR("service urn not found\n");
321
+		goto err;
322
+	}
323
+	/* pidf from parameter */
324
+	if(_pidf) {
325
+		if(fixup_get_svalue(_m, (gparam_p)_pidf, &pidf) != 0) {
326
+			LM_ERR("cannot get pidf-lo\n");
327
+			goto err;
328
+		}
329
+	}
330
+	/* pidf from geolocation header */
331
+	if(pidf.len == 0) {
332
+		LM_WARN("no pidf parameter, trying geolocation header ...\n");
333
+		geohdr.s = lost_get_geolocation_header(_m, &geohdr.len);
334
+		if(!geohdr.s) {
335
+			LM_ERR("geolocation header not found\n");
336
+			goto err;
337
+		} else {
338
+
339
+			LM_DBG("geolocation header found\n");
340
+
341
+			/* pidf from multipart body, check cid scheme */
342
+			if(geohdr.len > 6) {
343
+				search = geohdr.s;
344
+				if((*(search + 0) == '<')
345
+						&& ((*(search + 1) == 'c') || (*(search + 1) == 'C'))
346
+						&& ((*(search + 2) == 'i') || (*(search + 2) == 'I'))
347
+						&& ((*(search + 3) == 'd') || (*(search + 3) == 'D'))
348
+						&& (*(search + 4) == ':')) {
349
+					search += 4;
350
+					*search = '<';
351
+					geo.s = search;
352
+					geo.len = geo.len - 4;
353
+
354
+					LM_DBG("cid: [%.*s]\n", geo.len, geo.s);
355
+
356
+					/* get body part - filter=>content id */
357
+					pidf.s = get_body_part_by_filter(
358
+							_m, 0, 0, geo.s, NULL, &pidf.len);
359
+					if(!pidf.s) {
360
+						LM_ERR("no multipart body found\n");
361
+						goto err;
362
+					}
363
+				}
364
+				/* no pidf-lo so far ... check http(s) scheme */
365
+				if(((*(search + 0) == 'h') || (*(search + 0) == 'H'))
366
+						&& ((*(search + 1) == 't') || (*(search + 1) == 'T'))
367
+						&& ((*(search + 2) == 't') || (*(search + 2) == 'T'))
368
+						&& ((*(search + 3) == 'p') || (*(search + 3) == 'P'))) {
369
+					geo.s = geohdr.s;
370
+					geo.len = geohdr.len;
371
+
372
+					if(*(search + 4) == ':') {
373
+					
374
+						LM_DBG("http url: [%.*s]\n", geo.len, geo.s);
375
+					
376
+					} else if(((*(search + 4) == 's') || (*(search + 4) == 'S'))
377
+							&& (*(search + 5) == ':')) {
378
+					
379
+						LM_DBG("https url: [%.*s]\n", geo.len, geo.s);
380
+					
381
+					} else {
382
+						LM_ERR("invalid url: [%.*s]\n", geo.len, geo.s);
383
+						goto err;
384
+					}
385
+
386
+					/* ! dereference pidf.lo at location server - HTTP GET */
387
+					/* ! requires hack in http_client module */
388
+					/* ! functions.c => http_client_query => query_params.oneline = 0; */
389
+					curlres = httpapi.http_client_query(_m, geo.s, &pidfhdr, NULL, NULL);
390
+					/* free memory */
391
+					lost_free_string(&geohdr);
392
+					geo.s = NULL;
393
+					geo.len = 0;
394
+					/* only HTTP 2xx responses are accepted */ 
395
+					if(curlres >= 300 || curlres < 100) {
396
+						LM_ERR("http GET failed with error: %d\n", curlres);
397
+						pidfhdr.s = NULL;
398
+						pidfhdr.len = 0;
399
+						goto err;
400
+					}
401
+
402
+					LM_DBG("http GET returned: %d\n", curlres);
403
+
404
+					if(!pidfhdr.s) {
405
+						LM_ERR("dereferencing location failed\n");
406
+						goto err;
407
+					}
408
+					pidf.s = pidfhdr.s;
409
+					pidf.len = pidfhdr.len;
410
+				}
411
+			} else {
412
+				LM_ERR("invalid geolocation header\n");
413
+				goto err;
414
+			}
415
+		}
416
+	}
417
+
418
+	/* no pidf-lo return error */
419
+	if(!pidf.s) {
420
+		LM_ERR("pidf-lo not found\n");
421
+		goto err;
422
+	}
423
+
424
+	LM_DBG("pidf-lo: [%.*s]\n", pidf.len, pidf.s);
425
+
426
+	/* read and parse pidf-lo */
427
+	doc = xmlReadMemory(pidf.s, pidf.len, 0, NULL,
428
+			XML_PARSE_NOBLANKS | XML_PARSE_NONET | XML_PARSE_NOCDATA);
429
+
430
+	if(!doc) {
431
+		LM_WARN("invalid xml (pidf-lo): [%.*s]\n", pidf.len, pidf.s);
432
+		doc = xmlRecoverMemory(pidf.s, pidf.len);
433
+		if(!doc) {
434
+			LM_ERR("xml (pidf-lo) recovery failed on: [%.*s]\n", pidf.len,
435
+					pidf.s);
436
+			goto err;
437
+		}
438
+
439
+		LM_DBG("xml (pidf-lo) recovered\n");
440
+	}
441
+
442
+	root = xmlDocGetRootElement(doc);
443
+	if(!root) {
444
+		LM_ERR("empty pidf-lo document\n");
445
+		goto err;
446
+	}
447
+	if((!xmlStrcmp(root->name, (const xmlChar *)"presence"))
448
+			|| (!xmlStrcmp(root->name, (const xmlChar *)"locationResponse"))) {
449
+		/* get the geolocation: point or circle, urn, ... */
450
+		loc = lost_new_loc(urn);
451
+		if(!loc) {
452
+			LM_ERR("location object allocation failed\n");
453
+			goto err;			
454
+		}
455
+		if(lost_parse_location_info(root, loc) < 0) {
456
+			LM_ERR("location element not found\n");
457
+			goto err;
458
+		}
459
+	} else {
460
+		LM_ERR("findServiceResponse or presence element not found in "
461
+			   "[%.*s]\n",
462
+				pidf.len, pidf.s);
463
+		goto err;
464
+	}
465
+
466
+	/* free memory */
467
+	lost_free_string(&pidfhdr);
468
+	pidf.s = NULL;
469
+	pidf.len = 0;
470
+
471
+	/* check if connection exits */
472
+	if(httpapi.http_connection_exists(&con) == 0) {
473
+		LM_ERR("connection: [%.*s] does not exist\n", con.len, con.s);
474
+		goto err;
475
+	}
476
+	/* assemble findService request */
477
+	res.s = lost_find_service_request(loc, &res.len);
478
+	/* free memory */
479
+	if(loc) {
480
+		lost_free_loc(loc);
481
+		loc = NULL;
482
+	}
483
+	xmlFreeDoc(doc);
484
+	doc = NULL;
485
+
486
+	if(!res.s) {
487
+		LM_ERR("lost request failed\n");
488
+		goto err;
489
+	}
490
+
491
+	LM_DBG("findService request: [%.*s]\n", res.len, res.s);
492
+
493
+	/* send findService request to mapping server - HTTP POST */
494
+	curlres = httpapi.http_connect(_m, &con, NULL, &ret, mtlost, &res);
495
+	/* only HTTP 2xx responses are accepted */ 
496
+	if(curlres >= 300 || curlres < 100) {
497
+		LM_ERR("[%.*s] failed with error: %d\n", con.len, con.s, curlres);
498
+		ret.s = NULL;
499
+		ret.len = 0;
500
+		goto err;
501
+	}
502
+
503
+	LM_DBG("[%.*s] returned: %d\n", con.len, con.s, curlres);
504
+
505
+	/* free memory */
506
+	lost_free_string(&res);
507
+
508
+	if(!ret.s) {
509
+		LM_ERR("findService request failed\n");
510
+		goto err;
511
+	}
512
+
513
+	LM_DBG("findService response: [%.*s]\n", ret.len, ret.s);
514
+
515
+	/* read and parse the returned xml */
516
+	doc = xmlReadMemory(ret.s, ret.len, 0, 0,
517
+			XML_PARSE_NOBLANKS | XML_PARSE_NONET | XML_PARSE_NOCDATA);
518
+
519
+	if(!doc) {
520
+		LM_ERR("invalid xml document: [%.*s]\n", ret.len, ret.s);
521
+		doc = xmlRecoverMemory(ret.s, ret.len);
522
+		if(!doc) {
523
+			LM_ERR("xml document recovery failed on: [%.*s]\n", ret.len,
524
+					ret.s);
525
+			goto err;
526
+		}
527
+
528
+		LM_DBG("xml document recovered\n");
529
+	}
530
+	root = xmlDocGetRootElement(doc);
531
+	if(!root) {
532
+		LM_ERR("empty xml document: [%.*s]\n", ret.len, ret.s);
533
+		goto err;
534
+	}
535
+	/* check the root element, shall be findServiceResponse, or errors */
536
+	if((!xmlStrcmp(root->name, (const xmlChar *)"findServiceResponse"))) {
537
+		/* get the uri element */
538
+		uri.s = lost_get_content(root, uri_element, &uri.len);
539
+		if(!uri.s) {
540
+			LM_ERR("uri element not found: [%.*s]\n", ret.len, ret.s);
541
+			goto err;
542
+		}
543
+		LM_INFO("### LOST uri [%.*s]\n", uri.len, uri.s);
544
+		/* get the displayName element */
545
+		name.s = lost_get_content(root, name_element, &name.len);
546
+		if(!name.s) {
547
+			LM_ERR("displayName element not found: [%.*s]\n", ret.len, ret.s);
548
+			goto err;
549
+		}
550
+		LM_INFO("### LOST name [%.*s]\n", name.len, name.s);
551
+	} else if((!xmlStrcmp(root->name, (const xmlChar *)"errors"))) {
552
+
553
+		LM_DBG("findService error response received\n");
554
+
555
+		/* get the error patterm */
556
+		err.s = lost_get_childname(root, errors_element, &err.len);
557
+		if(!err.s) {
558
+			LM_ERR("error pattern element not found: [%.*s]\n", ret.len,
559
+					ret.s);
560
+			goto err;
561
+		}
562
+		LM_WARN("findService error response: [%.*s]\n", err.len, err.s);
563
+	} else {
564
+		LM_ERR("root element is not valid: [%.*s]\n", ret.len, ret.s);
565
+		goto err;
566
+	}
567
+
568
+	/* free memory */
569
+	xmlFreeDoc(doc);
570
+	doc = NULL;
571
+	lost_free_string(&ret);
572
+
573
+	/* set writable pvars */
574
+	pvname.rs = name;
575
+	pvname.rs.s = name.s;
576
+	pvname.rs.len = name.len;
577
+
578
+	pvname.flags = PV_VAL_STR;
579
+	psname = (pv_spec_t *)_name;
580
+	psname->setf(_m, &psname->pvp, (int)EQ_T, &pvname);
581
+
582
+	pvuri.rs = uri;
583
+	pvuri.rs.s = uri.s;
584
+	pvuri.rs.len = uri.len;
585
+
586
+	pvuri.flags = PV_VAL_STR;
587
+	psuri = (pv_spec_t *)_uri;
588
+	psuri->setf(_m, &psuri->pvp, (int)EQ_T, &pvuri);
589
+
590
+	pverr.rs = err;
591
+	pverr.rs.s = err.s;
592
+	pverr.rs.len = err.len;
593
+
594
+	pverr.flags = PV_VAL_STR;
595
+	pserr = (pv_spec_t *)_err;
596
+	pserr->setf(_m, &pserr->pvp, (int)EQ_T, &pverr);
597
+
598
+	return (err.len > 0) ? LOST_SERVER_ERROR : LOST_SUCCESS;
599
+
600
+err:
601
+	if(loc)
602
+		lost_free_loc(loc);
603
+	if(doc)
604
+		xmlFreeDoc(doc);
605
+
606
+	lost_free_string(&pidfhdr);
607
+	lost_free_string(&geohdr);
608
+	lost_free_string(&ret);
609
+
610
+	return LOST_CLIENT_ERROR;
611
+}
... ...
@@ -1,40 +1,40 @@
1
-/*
2
- * lost module functions
3
- *
4
- * Copyright (C) 2019 Wolfgang Kampichler
5
- * DEC112, FREQUENTIS AG
6
- *
7
- * This file is part of Kamailio, a free SIP server.
8
- *
9
- * Kamailio is free software; you can redistribute it and/or modify
10
- * it under the terms of the GNU General Public License as published by
11
- * the Free Software Foundation; either version 2 of the License, or
12
- * (at your option) any later version
13
- *
14
- * Kamailio is distributed in the hope that it will be useful,
15
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
- * GNU General Public License for more details.
18
- *
19
- * You should have received a copy of the GNU General Public License
20
- * along with this program; if not, write to the Free Software
21
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
22
- *
23
- */
24
-
25
-/*!
26
- * \file
27
- * \brief Kamailio lost :: functions
28
- * \ingroup lost
29
- * Module: \ref lost
30
- */
31
-
32
-#ifndef LOST_FUNCTIONS_H
33
-#define LOST_FUNCTIONS_H
34
-
35
-int lost_function_held(
36
-		struct sip_msg *, char *, char *, char *, char *, char *);
37
-int lost_function(
38
-		struct sip_msg *, char *, char *, char *, char *, char *, char *);
39
-
40
-#endif
1
+/*
2
+ * lost module functions
3
+ *
4
+ * Copyright (C) 2019 Wolfgang Kampichler
5
+ * DEC112, FREQUENTIS AG
6
+ *
7
+ * This file is part of Kamailio, a free SIP server.
8
+ *
9
+ * Kamailio is free software; you can redistribute it and/or modify
10
+ * it under the terms of the GNU General Public License as published by
11
+ * the Free Software Foundation; either version 2 of the License, or
12
+ * (at your option) any later version
13
+ *
14
+ * Kamailio is distributed in the hope that it will be useful,
15
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
+ * GNU General Public License for more details.
18
+ *
19
+ * You should have received a copy of the GNU General Public License
20
+ * along with this program; if not, write to the Free Software
21
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
22
+ *
23
+ */
24
+
25
+/*!
26
+ * \file
27
+ * \brief Kamailio lost :: functions
28
+ * \ingroup lost
29
+ * Module: \ref lost
30
+ */
31
+
32
+#ifndef LOST_FUNCTIONS_H
33
+#define LOST_FUNCTIONS_H
34
+
35
+int lost_function_held(
36
+		struct sip_msg *, char *, char *, char *, char *, char *);
37
+int lost_function(
38
+		struct sip_msg *, char *, char *, char *, char *, char *, char *);
39
+
40
+#endif
... ...
@@ -1,339 +1,339 @@
1
-/*
2
- * lost module
3
- *
4
- * Copyright (C) 2019 Wolfgang Kampichler
5
- * DEC112, FREQUENTIS AG
6
- *
7
- * This file is part of Kamailio, a free SIP server.
8
- *
9
- * Kamailio is free software; you can redistribute it and/or modify
10
- * it under the terms of the GNU General Public License as published by
11
- * the Free Software Foundation; either version 2 of the License, or
12
- * (at your option) any later version
13
- *
14
- * Kamailio is distributed in the hope that it will be useful,
15
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
16
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
- * GNU General Public License for more details.
18
- *
19
- * You should have received a copy of the GNU General Public License
20
- * along with this program; if not, write to the Free Software
21
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
22
- *
23
- */
24
-
25
-/*!
26
- * \file
27
- * \brief Kamailio lost ::
28
- * \ingroup lost
29
- * Module: \ref lost
30
- */
31
-
32
-#include "../../modules/http_client/curl_api.h"
33
-
34
-#include "../../core/mod_fix.h"
35
-#include "../../core/sr_module.h"
36
-#include "../../core/ut.h"
37
-#include "../../core/locking.h"
38
-
39
-#include "../../core/pvar.h"
40
-#include "../../core/mem/mem.h"
41
-#include "../../core/dprint.h"
42
-
43
-#include "../../core/script_cb.h"
44
-
45
-#include "functions.h"
46
-
47
-MODULE_VERSION
48
-
49
-/* Module parameter variables */
50
-httpc_api_t httpapi;
51
-
52
-/* Module management function prototypes */
53
-static int mod_init(void);
54
-static int child_init(int);
55
-static void destroy(void);
56
-
57
-/* Fixup functions to be defined later */
58
-static int fixup_lost_held_query(void **param, int param_no);
59
-static int fixup_free_lost_held_query(void **param, int param_no);
60
-static int fixup_lost_held_query_id(void **param, int param_no);
61
-static int fixup_free_lost_held_query_id(void **param, int param_no);
62
-
63
-static int fixup_lost_query(void **param, int param_no);
64
-static int fixup_free_lost_query(void **param, int param_no);
65
-static int fixup_lost_query_all(void **param, int param_no);
66
-static int fixup_free_lost_query_all(void **param, int param_no);
67
-
68
-/* Wrappers for http_query to be defined later */
69
-static int w_lost_held_query(
70
-		struct sip_msg *_m, char *_con, char *_pidf, char *_url, char *_err);
71
-static int w_lost_held_query_id(struct sip_msg *_m, char *_con, char *_id,
72
-		char *_pidf, char *_url, char *_err);
73
-static int w_lost_query(
74
-		struct sip_msg *_m, char *_con, char *_uri, char *_name, char *_err);
75
-static int w_lost_query_all(struct sip_msg *_m, char *_con, char *_pidf,
76
-		char *_urn, char *_uri, char *_name, char *_err);
77
-
78
-/* Exported functions */
79
-static cmd_export_t cmds[] = {
80
-		{"lost_held_query", (cmd_function)w_lost_held_query, 4,
81
-				fixup_lost_held_query, fixup_free_lost_held_query,
82
-				REQUEST_ROUTE | FAILURE_ROUTE | BRANCH_ROUTE},
83
-		{"lost_held_query", (cmd_function)w_lost_held_query_id, 5,
84
-				fixup_lost_held_query_id, fixup_free_lost_held_query_id,
85
-				REQUEST_ROUTE | FAILURE_ROUTE | BRANCH_ROUTE},
86
-		{"lost_query", (cmd_function)w_lost_query, 4, fixup_lost_query,
87
-				fixup_free_lost_query,
88
-				REQUEST_ROUTE | FAILURE_ROUTE | BRANCH_ROUTE},
89
-		{"lost_query", (cmd_function)w_lost_query_all, 6, fixup_lost_query_all,
90
-				fixup_free_lost_query_all,
91
-				REQUEST_ROUTE | FAILURE_ROUTE | BRANCH_ROUTE},
92
-		{0, 0, 0, 0, 0, 0}};
93
-
94
-
95
-/* Module interface */
96
-struct module_exports exports = {
97
-		"lost",			 /* module name*/
98
-		DEFAULT_DLFLAGS, /* dlopen flags */
99
-		cmds,			 /* exported functions */
100
-		0,				 /* exported parameters */
101
-		0,				 /* RPC method exports */
102
-		0,				 /* exported pseudo-variables */
103
-		0,				 /* response handling function */
104
-		mod_init,		 /* module initialization function */
105
-		child_init,		 /* per-child init function */
106
-		destroy			 /* module destroy function */
107
-};
108
-
109
-/* Module initialization function */
110