Browse code

1. Re-formated all source code. Added comments for all functions. 2. Fix [1524046] bug reported for Scalable SIP server project in SourceForge. Please check OpenSER tracker for details.

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

Di-Shi Sun authored on 17/07/2006 19:02:53
Showing 20 changed files
... ...
@@ -1,14 +1,14 @@
1 1
 /*
2
- * openser osp module. 
2
+ * openser osp module.
3 3
  *
4
- * This module enables openser to communicate with an Open Settlement 
5
- * Protocol (OSP) server.  The Open Settlement Protocol is an ETSI 
4
+ * This module enables openser to communicate with an Open Settlement
5
+ * Protocol (OSP) server.  The Open Settlement Protocol is an ETSI
6 6
  * defined standard for Inter-Domain VoIP pricing, authorization
7
- * and usage exchange.  The technical specifications for OSP 
7
+ * and usage exchange.  The technical specifications for OSP
8 8
  * (ETSI TS 101 321 V4.1.1) are available at www.etsi.org.
9 9
  *
10 10
  * Uli Abend was the original contributor to this module.
11
- * 
11
+ *
12 12
  * Copyright (C) 2001-2005 Fhg Fokus
13 13
  *
14 14
  * This file is part of openser, a free SIP server.
... ...
@@ -28,327 +28,468 @@
28 28
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
29 29
  */
30 30
 
31
-
32
-
33
-
34
-
35
-#include "../../sr_module.h"
36
-#include "../../mem/mem.h"
31
+#include <string.h>
32
+#include "../../str.h"
33
+#include "../../dprint.h"
37 34
 #include "../../usr_avp.h"
38 35
 #include "destination.h"
39 36
 #include "usage.h"
40
-#include <time.h>
41
-
42
-
43
-/* A list of destination URIs */
44
-str ORIG_OSPDESTS_LABEL = {"_orig_osp_dests_",16};
45
-str TERM_OSPDESTS_LABEL = {"_term_osp_dests_",16};
46
-
47
-
48
-static int saveDestination(osp_dest* dest, str* label);
49
-static osp_dest* getLastOrigDestination();
50
-static void recordCode(int code, osp_dest* dest);
51
-static int isTimeToReportUsage(int code);
52
-
53 37
 
38
+/* Name of AVP item of OSP */
39
+str OSP_ORIGDEST_LABEL = {"_orig_osp_dests_", 16};
40
+str OSP_TERMDEST_LABEL = {"_term_osp_dests_", 16};
54 41
 
42
+static int ospSaveDestination(osp_dest* dest, str* label);
43
+static osp_dest* ospGetLastOrigDestination(void);
44
+static void ospRecordCode(int code, osp_dest* dest);
45
+static int ospIsToReportUsage(int code);
46
+    
47
+/*
48
+ * Initialize destination structure
49
+ * param dest Destination data structure
50
+ * return initialized destination sturcture
51
+ */
52
+osp_dest* ospInitDestination(
53
+    osp_dest* dest)
54
+{
55
+    LOG(L_DBG, "osp: ospInitDestion\n");
55 56
 
56
-osp_dest* initDestination(osp_dest* dest) {
57
+    memset(dest, 0, sizeof(osp_dest));
57 58
 
58
-	memset(dest,0,sizeof(osp_dest));
59
+    dest->callidsize = sizeof(dest->callid);
60
+    dest->tokensize = sizeof(dest->token);
59 61
 
60
-	dest->sizeofcallid   =  sizeof(dest->callid);
61
-	dest->sizeoftoken    =  sizeof(dest->osptoken);
62
+    LOG(L_DBG, "osp: callidsize '%d' tokensize '%d'\n", dest->callidsize, dest->tokensize);
62 63
 
63
-	return dest;
64
+    return dest;
64 65
 }
65 66
 
67
+/* 
68
+ * Save destination as an AVP
69
+ *     name - OSP_ORIGDEST_LABEL / OSP_TERMDEST_LABEL
70
+ *     value - osp_dest wrapped in a string
71
+ * param dest Destination structure
72
+ * param label Name
73
+ * return 0 success, -1 failure
74
+ */
75
+static int ospSaveDestination(
76
+    osp_dest* dest, 
77
+    str* label)
78
+{
79
+    str wrapper;
80
+    int result = -1;
81
+
82
+    LOG(L_DBG, "osp: ospSaveDestination\n");
83
+
84
+    wrapper.s = (char*)dest;
85
+    wrapper.len = sizeof(osp_dest);
86
+
87
+    /* 
88
+     * add_avp will make a private copy of both the name and value in shared memory 
89
+     * which will be released by TM at the end of the transaction
90
+     */
91
+    if (add_avp(AVP_NAME_STR | AVP_VAL_STR, (int_str)*label, (int_str)wrapper) == 0) {
92
+        result = 0;
93
+        LOG(L_DBG, "osp: saved\n");
94
+    } else {
95
+        LOG(L_ERR, "osp: ERROR: failed to save destination\n");
96
+    }
97
+
98
+    return result;
99
+}
66 100
 
67
-int saveOrigDestination(osp_dest* dest) {
68
-	DBG("osp: Saving originating destination\n");
101
+/*
102
+ * Save originate destination
103
+ * param dest Originate destination structure
104
+ * return 0 success, -1 failure
105
+ */
106
+int ospSaveOrigDestination(
107
+    osp_dest* dest
108
+    )
109
+{
110
+    LOG(L_DBG, "osp: ospSaveOrigDestination\n");
69 111
 
70
-	return saveDestination(dest,&ORIG_OSPDESTS_LABEL);
112
+    return ospSaveDestination(dest, &OSP_ORIGDEST_LABEL);
71 113
 }
72 114
 
73
-int saveTermDestination(osp_dest* dest) {
74
-	DBG("osp: Saving terminating destination\n");
115
+/*
116
+ * Save terminate destination
117
+ * param dest Terminate destination structure
118
+ * return 0 success, -1 failure
119
+ */
120
+int ospSaveTermDestination(
121
+    osp_dest* dest)
122
+{
123
+    LOG(L_DBG, "osp: ospSaveTermDestination\n");
75 124
 
76
-	return saveDestination(dest,&TERM_OSPDESTS_LABEL);
125
+    return ospSaveDestination(dest, &OSP_TERMDEST_LABEL);
77 126
 }
78 127
 
79
-/** Save destination as an AVP
80
- *  name - label
81
- *  value - osp_dest wrapped in a string
82
- *
83
- *  Returns: 0 - success, -1 failure
128
+/* 
129
+ * Check if there is an unused and supported originate destination from an AVP
130
+ *     name - OSP_ORIGDEST_LABEL
131
+ *     value - osp_dest wrapped in a string
132
+ *     search unused (used==0) & supported (support==1)
133
+ * return 0 success, -1 failure
84 134
  */
85
-static int saveDestination(osp_dest* dest, str* label) {
86
-	str wrapper;
87
-	int status = -1;
88
-
89
-	DBG("osp: Saving destination to avp\n");
90
-
91
-	wrapper.s   = (char *)dest;
92
-	wrapper.len = sizeof(osp_dest);
93
-
94
-	/* add_avp will make a private copy of both the name and value in shared memory.
95
-	 * memory will be released by TM at the end of the transaction
96
-	 */
97
-	if (add_avp(AVP_NAME_STR|AVP_VAL_STR,(int_str)*label,(int_str)wrapper) == 0) {
98
-		status = 0;
99
-		DBG("osp: Saved\n");
100
-	} else {
101
-		LOG(L_ERR, "ERROR: osp: Failed to add_avp destination\n");
102
-	}
103
-
104
-	return status;
135
+int ospCheckOrigDestination(void)
136
+{
137
+    struct usr_avp* destavp = NULL;
138
+    int_str destval;
139
+    osp_dest* dest = NULL;
140
+    int result = -1;
141
+
142
+    LOG(L_DBG, "osp: ospCheckOrigDestination\n");
143
+
144
+    for (destavp = search_first_avp(AVP_NAME_STR | AVP_VAL_STR, (int_str)OSP_ORIGDEST_LABEL, NULL, 0);
145
+        destavp != NULL;
146
+        destavp = search_next_avp(destavp, NULL))
147
+    {
148
+        get_avp_val(destavp, &destval);
149
+
150
+        /* OSP destintaion is wrapped in a string */
151
+        dest = (osp_dest*)destval.s.s;
152
+
153
+        if (dest->used == 0) {
154
+            if (dest->supported == 1) {
155
+                LOG(L_DBG, "osp: found\n");
156
+                result = 0;
157
+                break;
158
+            } else {
159
+                LOG(L_DBG, "osp: this destination does not been supported\n");
160
+            }
161
+        } else {
162
+            LOG(L_DBG, "osp: this destination has already been used\n");
163
+        }
164
+    }
165
+
166
+    if (result == -1) {
167
+        LOG(L_DBG, "osp: there is no unused destination\n");
168
+    }
169
+
170
+    return result;
105 171
 }
106 172
 
107
-
108
-/** Retrieved an unused orig destination from an AVP
109
- *  name - ORIG_OSPDESTS_LABEL
110
- *  value - osp_dest wrapped in a string
111
- *  There can be 0, 1 or more orig destinations.  Find the 1st unused destination (used==0),
112
- *  return it, and mark it as used (used==1).
113
- *
114
- *  Returns: NULL on failure
173
+/* 
174
+ * Retrieved an unused originate destination from an AVP
175
+ *     name - OSP_ORIGDEST_LABEL
176
+ *     value - osp_dest wrapped in a string
177
+ *     There can be 0, 1 or more originate destinations. 
178
+ *     Find the 1st unused destination (used==0), return it, 
179
+ *     and mark it as used (used==1).
180
+ * return NULL on failure
115 181
  */
116
-osp_dest* getNextOrigDestination() {
117
-	osp_dest*       retVal   = NULL;
118
-	osp_dest*       dest     = NULL;
119
-	struct usr_avp* dest_avp = NULL;
120
-	int_str         dest_val;
121
-
122
-	DBG("osp: Looking for the first unused orig destination\n");
123
-
124
-	for (	dest_avp=search_first_avp(AVP_NAME_STR|AVP_VAL_STR,(int_str)ORIG_OSPDESTS_LABEL,NULL,0);
125
-		dest_avp != NULL;
126
-		dest_avp=search_next_avp(dest_avp,NULL)) {
127
-
128
-		get_avp_val(dest_avp, &dest_val);
129
-
130
-		/* osp dest is wrapped in a string */
131
-		dest = (osp_dest *)dest_val.s.s;
132
-
133
-		if (dest->used == 0) {
134
-			DBG("osp: Found\n");
135
-			break;
136
-		} else {
137
-			DBG("osp: This destination has already been used\n");
138
-		}
139
-	}
140
-
141
-	if (dest != NULL && dest->used==0) {
142
-		dest->used = 1;
143
-		retVal = dest;
144
-	} else {
145
-		DBG("osp: There is no unused destinations\n");
146
-	}
147
-
148
-	return retVal;
182
+osp_dest* ospGetNextOrigDestination(void)
183
+{
184
+    struct usr_avp* destavp = NULL;
185
+    int_str destval;
186
+    osp_dest* dest = NULL;
187
+    osp_dest* result = NULL;
188
+
189
+    LOG(L_DBG, "osp: ospGetNextOrigDestination\n");
190
+
191
+    for (destavp = search_first_avp(AVP_NAME_STR | AVP_VAL_STR, (int_str)OSP_ORIGDEST_LABEL, NULL, 0);
192
+        destavp != NULL;
193
+        destavp = search_next_avp(destavp, NULL))
194
+    {
195
+        get_avp_val(destavp, &destval);
196
+
197
+        /* OSP destintaion is wrapped in a string */
198
+        dest = (osp_dest*)destval.s.s;
199
+
200
+        if (dest->used == 0) {
201
+            if (dest->supported == 1) {
202
+                LOG(L_DBG, "osp: found\n");
203
+                dest->used = 1;
204
+                result = dest;
205
+                break;
206
+            } else {
207
+                /* Make it looks like used */
208
+                dest->used = 1;
209
+                /* 111 means wrong protocol */
210
+                dest->lastcode = 111;
211
+                LOG(L_DBG, "osp: this destination does not been supported\n");
212
+            }
213
+        } else {
214
+            LOG(L_DBG, "osp: this destination has already been used\n");
215
+        }
216
+    }
217
+
218
+    if (result == NULL) {
219
+        LOG(L_DBG, "osp: there is no unused destination\n");
220
+    }
221
+
222
+    return result;
149 223
 }
150 224
 
151
-
152
-/** Retrieved the last used orig destination from an AVP
153
- *  name - ORIG_OSPDESTS_LABEL
154
- *  value - osp_dest wrapped in a string
155
- *  There can be 0, 1 or more destinations.  Find the last used destination (used==1),
156
- *  and return it.
157
- *
158
- *  Returns: NULL on failure
225
+/* 
226
+ * Retrieved the terminate destination from an AVP
227
+ *     name - OSP_TERMDEST_LABEL
228
+ *     value - osp_dest wrapped in a string
229
+ *     There can be 0 or 1 term destinations. Find and return it.
230
+ *  return NULL on failure (no terminate destination)
159 231
  */
160
-osp_dest* getLastOrigDestination() {
232
+osp_dest* ospGetTermDestination(void)
233
+{
234
+    struct usr_avp* destavp = NULL;
235
+    int_str destval;
236
+    osp_dest* dest = NULL;
161 237
 
162
-	osp_dest* dest = NULL;
163
-	osp_dest* last_dest = NULL;
164
-	struct usr_avp* dest_avp = NULL;
165
-	int_str   dest_val;
238
+    LOG(L_DBG, "osp: ospGetTermDestination\n");
166 239
 
167
-	for (	dest_avp=search_first_avp(AVP_NAME_STR|AVP_VAL_STR,(int_str)ORIG_OSPDESTS_LABEL,NULL,0);
168
-		dest_avp != NULL;
169
-		dest_avp=search_next_avp(dest_avp,NULL)) {
240
+    destavp = search_first_avp(AVP_NAME_STR | AVP_VAL_STR, (int_str)OSP_TERMDEST_LABEL, NULL, 0);
170 241
 
171
-		get_avp_val(dest_avp, &dest_val);
242
+    if (destavp) {
243
+        get_avp_val(destavp, &destval);
172 244
 
173
-		/* osp dest is wrapped in a string */
174
-		dest = (osp_dest *)dest_val.s.s;
245
+        /* OSP destination is wrapped in a string */
246
+        dest = (osp_dest*)destval.s.s;
175 247
 
176
-		if (dest->used == 1) {
177
-			last_dest = dest;
178
-			DBG("osp: getLastOrigDestination: updating curent destination to '%s'\n",last_dest->destination);
179
-		} else {
180
-			break;
181
-		}
182
-	}
248
+        LOG(L_DBG, "osp: found\n");
249
+    }
183 250
 
184
-	return last_dest;
251
+    return dest;
185 252
 }
186 253
 
187
-
188
-/** Retrieved the term destination from an AVP
189
- *  name - TERM_OSPDESTS_LABEL
190
- *  value - osp_dest wrapped in a string
191
- *  There can be 0 or 1 term destinations.  Find and return it.
192
- *
193
- *  Returns: NULL on failure (no term destination)
254
+/*
255
+ * Retrieved the last used originate destination from an AVP
256
+ *    name - OSP_ORIGDEST_LABEL
257
+ *    value - osp_dest wrapped in a string
258
+ *    There can be 0, 1 or more destinations. 
259
+ *    Find the last used destination (used==1),
260
+ *    and return it.
261
+ *  return NULL on failure
194 262
  */
195
-osp_dest* getTermDestination() {
196
-	osp_dest* term_dest = NULL;
197
-	struct usr_avp* dest_avp = NULL;
198
-	int_str   dest_val;
199
-
200
-	dest_avp=search_first_avp(AVP_NAME_STR|AVP_VAL_STR,(int_str)TERM_OSPDESTS_LABEL,NULL,0);
201
-
202
-	if (dest_avp) {
203
-		get_avp_val(dest_avp, &dest_val);
204
-
205
-		/* osp dest is wrapped in a string */
206
-		term_dest = (osp_dest *)dest_val.s.s;
207
-	}
208
-
209
-	return term_dest;
263
+static osp_dest* ospGetLastOrigDestination(void)
264
+{
265
+    struct usr_avp* destavp = NULL;
266
+    int_str destval;
267
+    osp_dest* dest = NULL;
268
+    osp_dest* lastdest = NULL;
269
+
270
+    LOG(L_DBG, "osp: ospGetLastOrigDesintaion\n");
271
+
272
+    for (destavp = search_first_avp(AVP_NAME_STR | AVP_VAL_STR, (int_str)OSP_ORIGDEST_LABEL, NULL, 0);
273
+        destavp != NULL;
274
+        destavp = search_next_avp(destavp, NULL))
275
+    {
276
+        get_avp_val(destavp, &destval);
277
+
278
+        /* OSP destination is wrapped in a string */
279
+        dest = (osp_dest*)destval.s.s;
280
+
281
+        if (dest->used == 1) {
282
+            lastdest = dest;
283
+            LOG(L_DBG, "osp: curent destination '%s'\n", lastdest->host);
284
+        } else {
285
+            break;
286
+        }
287
+    }
288
+
289
+    return lastdest;
210 290
 }
211 291
 
212
-
213
-
214
-
215
-void recordEvent(int client_code, int server_code) {
216
-	DBG("osp: recordEvent: client code %d / server code %d\n",client_code, server_code);
217
-
218
-	osp_dest* dest;
219
-
220
-	if (client_code!=0 && (dest=getLastOrigDestination())) {
221
-		recordCode(client_code,dest);
222
-
223
-		if (isTimeToReportUsage(server_code)==0) {
224
-			reportOrigCallSetUpUsage();
225
-		}
226
-	} 
227
-
228
-	if (server_code!=0 && (dest=getTermDestination())) {
229
-		recordCode(server_code,dest);
230
-
231
-		if (isTimeToReportUsage(server_code)==0) {
232
-			reportTermCallSetUpUsage();
233
-		}
234
-	}
292
+/*
293
+ * Retrieved the forked destination from an AVP
294
+ *    name - OSP_ORIGDEST_LABEL
295
+ *    value - osp_dest wrapped in a string
296
+ *    There can be 0, 1 or more destinations. 
297
+ *    Find the used (used==1), has the same dest item as the parameter fork,
298
+ *    and return it.
299
+ *    Note, there maybe multiple result destinations. osp_fork can be exten to
300
+ *    deal with it in the future. 
301
+ * param fork Forked destination index
302
+ * return NULL on failure
303
+ */
304
+osp_dest* ospGetForkedDestination(
305
+    osp_fork* fork)
306
+{
307
+    struct usr_avp* destavp = NULL;
308
+    int_str destval;
309
+    osp_dest* dest = NULL;
310
+    osp_dest* forked = NULL;
311
+    char* host;
312
+
313
+    LOG(L_DBG, "osp: ospGetForkedDesintaion\n");
314
+
315
+    for (destavp = search_first_avp(AVP_NAME_STR | AVP_VAL_STR, (int_str)OSP_ORIGDEST_LABEL, NULL, 0);
316
+        destavp != NULL;
317
+        destavp = search_next_avp(destavp, NULL))
318
+    {
319
+        get_avp_val(destavp, &destval);
320
+
321
+        /* OSP destination is wrapped in a string */
322
+        dest = (osp_dest*)destval.s.s;
323
+
324
+        if (dest->used == 1) {
325
+            if (*dest->host == '[') {
326
+                host = dest->host + 1;
327
+            } else {
328
+                host = dest->host ;
329
+            }
330
+            if (memcmp(host, fork->host, strlen(fork->host)) == 0) {
331
+                LOG(L_DBG, "osp: found\n");
332
+                forked = dest;
333
+                break;
334
+            }
335
+        }
336
+    }
337
+
338
+    return forked;
235 339
 }
236 340
 
237
-
238
-
239
-static int isTimeToReportUsage(int code)
341
+/*
342
+ * Record destination status
343
+ * param code Destination status
344
+ * param dest Destination
345
+ */
346
+static void ospRecordCode(
347
+    int code, 
348
+    osp_dest* dest)
240 349
 {
241
-	int isTime = -1;
242
-
243
-	if (code >= 200) {
244
-		isTime = 0;
245
-	}
246
-
247
-	return isTime;
350
+    LOG(L_DBG, "osp: ospRecordCode\n");
351
+    LOG(L_DBG, "osp: code '%d'\n", code);
352
+
353
+    dest->lastcode = code;
354
+
355
+    switch (code) {
356
+        case 100:
357
+            if (!dest->time100) {
358
+                dest->time100 = time(NULL);
359
+            } else {
360
+                LOG(L_DBG, "osp: 100 has already been recorded\n");
361
+            }
362
+            break;
363
+        case 180:
364
+        case 181:
365
+        case 182:
366
+        case 183:
367
+            if (!dest->time180) {
368
+                dest->time180 = time(NULL);
369
+            } else {
370
+                LOG(L_DBG, "osp: 180, 181, 182 or 183 has allready been recorded\n");
371
+            }
372
+            break;
373
+        case 200:
374
+        case 202:
375
+            if (!dest->time200) {
376
+                dest->time200 = time(NULL);
377
+            } else {
378
+                LOG(L_DBG, "osp: 200 or 202 has allready been recorded\n");
379
+            }
380
+            break;
381
+        default:
382
+            LOG(L_DBG, "osp: will not record time for '%d'\n", code);
383
+    }
248 384
 }
249 385
 
386
+/*
387
+ * Check destination status for reporting usage
388
+ * param code Destination status
389
+ * return 
390
+ */
391
+static int ospIsToReportUsage(
392
+    int code)
393
+{
394
+    int istime = -1;
250 395
 
396
+    LOG(L_DBG, "osp: ospIsToReportUsage\n");
397
+    LOG(L_DBG, "osp: code '%d'\n", code);
251 398
 
399
+    if (code >= 200) {
400
+        istime = 0;
401
+    }
252 402
 
253
-void recordCode(int code, osp_dest* dest) {
254
-
255
-	DBG("osp: recordCode: recording code %d\n",code);
256
-
257
-	dest->last_code = code;
258
-
259
-	switch (code) {
260
-		case 100:
261
-			if (!dest->time_100) {
262
-				dest->time_100 = time(NULL);
263
-			} else {
264
-				DBG("osp: recordCode: 100 has already been recorded\n");
265
-			}
266
-			break;
267
-		case 180:
268
-		case 181:
269
-		case 182:
270
-		case 183:
271
-			if (!dest->time_180) {
272
-				dest->time_180 = time(NULL);
273
-			} else {
274
-				DBG("osp: recordCode: 180, 181, 182 or 183 has allready been recorded\n");
275
-			}
276
-			break;
277
-		case 200:
278
-		case 202:
279
-			if (!dest->time_200) {
280
-				dest->time_200 = time(NULL);
281
-			} else {
282
-				DBG("osp: recordCode: 200 or 202 has allready been recorded\n");
283
-			}
284
-			break;
285
-		default:
286
-			DBG("osp: recordCode: will not record time for this code\n");
287
-	}
288
-
403
+    return istime;
289 404
 }
290 405
 
406
+/*
407
+ * Report call setup usage for both client and server side
408
+ * param clientcode Client status
409
+ * param servercode Server status
410
+ */
411
+void ospRecordEvent(
412
+    int clientcode, 
413
+    int servercode)
414
+{
415
+    osp_dest* dest;
291 416
 
417
+    LOG(L_DBG, "osp: ospRecordEvent\n");
418
+    LOG(L_DBG, "osp: client status '%d' server status '%d'\n", clientcode, servercode);
292 419
 
420
+    if ((clientcode != 0) && (dest = ospGetLastOrigDestination())) {
421
+        ospRecordCode(clientcode, dest);
293 422
 
423
+        if (ospIsToReportUsage(servercode) == 0) {
424
+            ospReportOrigSetupUsage();
425
+        }
426
+    }
294 427
 
428
+    if ((servercode != 0) && (dest = ospGetTermDestination())) {
429
+        ospRecordCode(servercode, dest);
295 430
 
296
-void dumpDebugInfo() {
297
-
298
-	osp_dest*       dest     = NULL;
299
-	struct usr_avp* dest_avp = NULL;
300
-	int_str         dest_val;
301
-	int             i = 0;
302
-
303
-	DBG("osp: dumpDebugInfo: IN\n");
304
-
305
-	for (	dest_avp=search_first_avp(AVP_NAME_STR|AVP_VAL_STR,(int_str)ORIG_OSPDESTS_LABEL,NULL,0);
306
-		dest_avp != NULL;
307
-		dest_avp=search_next_avp(dest_avp,NULL)) {
308
-
309
-		get_avp_val(dest_avp, &dest_val);
310
-
311
-		/* osp dest is wrapped in a string */
312
-		dest = (osp_dest *)dest_val.s.s;
313
-
314
-		DBG("osp: dumpDebugInfo: .....orig index...'%d'\n", i);
315
-
316
-		dumbDestDebugInfo(dest);
431
+        if (ospIsToReportUsage(servercode) == 0) {
432
+            ospReportTermSetupUsage();
433
+        }
434
+    }
435
+}
317 436
 
318
-		i++;
319
-	}
320
-	if (i==0) {
321
-		DBG("osp: dumpDebugInfo: There is no orig OSPDESTS AVP\n");
322
-	}
437
+/*
438
+ * Dump destination information
439
+ * param dest Destination
440
+ */
441
+void ospDumpDestination(osp_dest* dest)
442
+{
443
+    LOG(L_DBG, "osp: dest->host..........'%s'\n", dest->host);
444
+    LOG(L_DBG, "osp: dest->used..........'%d'\n", dest->used);
445
+    LOG(L_DBG, "osp: dest->lastcode......'%d'\n", dest->lastcode);
446
+    LOG(L_DBG, "osp: dest->time100.......'%d'\n", (unsigned int)dest->time100);
447
+    LOG(L_DBG, "osp: dest->time180.......'%d'\n", (unsigned int)dest->time180);
448
+    LOG(L_DBG, "osp: dest->time200.......'%d'\n", (unsigned int)dest->time200);
449
+}
323 450
 
324
-	dest_avp=search_first_avp(AVP_NAME_STR|AVP_VAL_STR,(int_str)TERM_OSPDESTS_LABEL,NULL,0);
451
+/*
452
+ * Dump all destination information
453
+ */
454
+void ospDumpAllDestination(void)
455
+{
456
+    struct usr_avp* destavp = NULL;
457
+    int_str destval;
458
+    osp_dest* dest = NULL;
459
+    int count = 0;
325 460
 
326
-	if (dest_avp) {
327
-		get_avp_val(dest_avp, &dest_val);
461
+    LOG(L_DBG, "osp: ospDumpAllDestination\n");
328 462
 
329
-		/* osp dest is wrapped in a string */
330
-		dest = (osp_dest *)dest_val.s.s;
463
+    for (destavp = search_first_avp(AVP_NAME_STR | AVP_VAL_STR, (int_str)OSP_ORIGDEST_LABEL, NULL, 0);
464
+        destavp != NULL;
465
+        destavp = search_next_avp(destavp,NULL))
466
+    {
467
+        get_avp_val(destavp, &destval);
331 468
 
332
-		DBG("osp: dumpDebugInfo: .....destination......\n");
469
+        /* OSP destination is wrapped in a string */
470
+        dest = (osp_dest*)destval.s.s;
333 471
 
334
-		dumbDestDebugInfo(dest);
335
-	} else {
336
-		DBG("osp: dumpDebugInfo: There is no dest OSPDESTS AVP\n");
337
-	}
472
+        LOG(L_DBG, "osp: ....originate '%d'....\n", count++);
338 473
 
474
+        ospDumpDestination(dest);
475
+    }
476
+    if (count == 0) {
477
+        LOG(L_DBG, "osp: there is no originate destination AVP\n");
478
+    }
339 479
 
340
-	DBG("osp: dumpDebugInfo: OUT\n");
341
-}
480
+    destavp = search_first_avp(AVP_NAME_STR | AVP_VAL_STR, (int_str)OSP_TERMDEST_LABEL, NULL, 0);
342 481
 
482
+    if (destavp) {
483
+        get_avp_val(destavp, &destval);
343 484
 
485
+        /* OSP destination is wrapped in a string */
486
+        dest = (osp_dest*)destval.s.s;
344 487
 
488
+        LOG(L_DBG, "osp: ....destination....\n");
345 489
 
346
-void dumbDestDebugInfo(osp_dest *dest) {
347
-	DBG("osp: dumpDebugInfo: dest->destination...'%s'\n", dest->destination);
348
-	DBG("osp: dumpDebugInfo: dest->used..........'%d'\n", dest->used);
349
-	DBG("osp: dumpDebugInfo: dest->last_code.....'%d'\n", dest->last_code);
350
-	DBG("osp: dumpDebugInfo: dest->time_100......'%d'\n", (unsigned int)dest->time_100);
351
-	DBG("osp: dumpDebugInfo: dest->time_180......'%d'\n", (unsigned int)dest->time_180);
352
-	DBG("osp: dumpDebugInfo: dest->time_200......'%d'\n", (unsigned int)dest->time_200);
490
+        ospDumpDestination(dest);
491
+    } else {
492
+        LOG(L_DBG, "osp: there is no terminate destination AVP\n");
493
+    }
353 494
 }
354 495
 
... ...
@@ -28,54 +28,52 @@
28 28
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
29 29
  */
30 30
 
31
+#ifndef _OSP_MOD_DESTINATION_H_
32
+#define _OSP_MOD_DESTINATION_H_
31 33
 
34
+#include <time.h>
35
+#include "osp_mod.h"
32 36
 
37
+typedef struct _osp_dest {
38
+    char validafter[OSP_STRBUF_SIZE];
39
+    char validuntil[OSP_STRBUF_SIZE];
40
+    char callid[OSP_STRBUF_SIZE];
41
+    char called[OSP_STRBUF_SIZE];
42
+    char calling[OSP_STRBUF_SIZE];
43
+    char source[OSP_STRBUF_SIZE];
44
+    char srcdev[OSP_STRBUF_SIZE];
45
+    char host[OSP_STRBUF_SIZE];
46
+    char destdev[OSP_STRBUF_SIZE];
47
+    char networkid[OSP_STRBUF_SIZE];
48
+    unsigned char token[OSP_TOKENBUF_SIZE];
49
+    unsigned int callidsize;
50
+    unsigned int tokensize;
51
+    unsigned int timelimit;
52
+    int lastcode;
53
+    time_t authtime;
54
+    time_t time100;
55
+    time_t time180;
56
+    time_t time200;
57
+    int type;
58
+    unsigned long long tid;
59
+    int supported;
60
+    int used;
61
+    int reported;
62
+} osp_dest;
33 63
 
64
+typedef struct _osp_fork {
65
+    char host[OSP_STRBUF_SIZE];
66
+} osp_fork;
34 67
 
35
-#ifndef OSP_MOD_DESTINATION_H
36
-#define OSP_MOD_DESTINATION_H
68
+osp_dest* ospInitDestination(osp_dest* dest);
69
+int ospSaveOrigDestination(osp_dest* dest);
70
+int ospSaveTermDestination(osp_dest* dest);
71
+int ospCheckOrigDestination(void);
72
+osp_dest* ospGetNextOrigDestination(void);
73
+osp_dest* ospGetTermDestination(void);
74
+osp_dest* ospGetForkedDestination(osp_fork* fork);
75
+void ospRecordEvent(int clientcode, int servercode);
76
+void ospDumpDestination(osp_dest* dest);
77
+void ospDumpAllDestination(void);
37 78
 
38
-#include "../../str.h"
39
-
40
-struct _osp_dest {
41
-	char validafter[100];
42
-	char validuntil[100];
43
-	char callid[100];
44
-	char callednumber[100];
45
-	char callingnumber[100];
46
-	char source[100];
47
-	char sourcedevice[100];
48
-	char destination[100];
49
-	char destinationdevice[100];
50
-	char network_id[100];
51
-	unsigned char osptoken[2000];
52
-	unsigned int sizeofcallid;
53
-	unsigned int timelimit;
54
-	unsigned int sizeoftoken;
55
-	int  used;
56
-	int  last_code;
57
-	time_t time_auth;
58
-	time_t time_100;
59
-	time_t time_180;
60
-	time_t time_200;
61
-	unsigned long long tid;
62
-	int type;
63
-	int reported;
64
-};
65
-
66
-typedef struct _osp_dest osp_dest;
67
-
68
-osp_dest* initDestination(osp_dest* dest);
69
-
70
-osp_dest* getNextOrigDestination();
71
-osp_dest* getTermDestination();
72
-
73
-
74
-int       saveOrigDestination(osp_dest* dest);
75
-int       saveTermDestination(osp_dest* dest);
76
-
77
-void	  recordEvent(int client_code, int server_code);
78
-
79
-void      dumpDebugInfo();
80
-void      dumbDestDebugInfo(osp_dest *dest);
81
-#endif
79
+#endif /* _OSP_MOD_DESTINATION_H_ */
... ...
@@ -330,9 +330,9 @@ route[4] {
330 330
 route[5] {
331 331
 	log(1,"Will try the 1st route and prepare to fail-over to the next one\n");
332 332
 
333
-	if (preparefirstosproute()) {
333
+	if (checkosproute()) {
334 334
 
335
-		append_hf("P-hint: 1st OSP route\r\n");
335
+		t_on_branch("1");
336 336
 
337 337
 		t_on_failure("1");
338 338
 
... ...
@@ -364,9 +364,11 @@ failure_route[1] {
364 364
 		}
365 365
 	}
366 366
 
367
-	if (preparenextosproute()) {
367
+	if (checkosproute()) {
368 368
 
369
-		append_hf("P-hint: OSP fail-over\r\n");
369
+		t_on_branch("1");
370
+
371
+		append_branch();
370 372
 
371 373
 		t_on_failure("1");
372 374
 
... ...
@@ -376,3 +378,10 @@ failure_route[1] {
376 378
 		t_reply("503", "Service not available - No more OSP routes");
377 379
 	}
378 380
 }
381
+
382
+
383
+branch_route[1] {
384
+	log(1,"Prepare route specific OSP information\n");
385
+
386
+    prepareosproute();
387
+}
... ...
@@ -28,31 +28,28 @@
28 28
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
29 29
  */
30 30
 
31
+#include <stdio.h>
32
+#include <osp/osp.h>
33
+#include "osp_mod.h"
31 34
 
35
+char* _osp_sp_uris[OSP_DEF_SPS];
36
+unsigned long _osp_sp_weights[OSP_DEF_SPS] = {OSP_DEF_WEIGHT, OSP_DEF_WEIGHT};
37
+unsigned char* _osp_private_key = NULL;
38
+unsigned char* _osp_local_certificate = NULL;
39
+unsigned char* _osp_ca_certificate = NULL;
40
+char* _osp_device_ip = NULL;
41
+char* _osp_device_port = NULL;
42
+int _osp_ssl_lifetime = OSP_DEF_SSLLIFE;
43
+int _osp_persistence = OSP_DEF_PERSISTENCE;
44
+int _osp_retry_delay = OSP_DEF_DELAY;
45
+int _osp_retry_limit = OSP_DEF_RETRY;
46
+int _osp_timeout = OSP_DEF_TIMEOUT;
47
+int _osp_max_dests = OSP_DEF_DESTS;
48
+int _osp_token_format = OSP_DEF_TOKEN;
49
+int _osp_crypto_hw = OSP_DEF_HW;
50
+int _osp_validate_callid = OSP_DEF_CALLID;
51
+char _osp_PRIVATE_KEY[OSP_KEYBUF_SIZE];
52
+char _osp_LOCAL_CERTIFICATE[OSP_KEYBUF_SIZE];
53
+char _osp_CA_CERTIFICATE[OSP_KEYBUF_SIZE];
32 54
 
33
-
34
-
35
-#include "osp/ospprovider.h"
36
-
37
-char* _spURIs[2];
38
-unsigned long _spWeights[2]       = {1000,1000};
39
-unsigned char* _private_key       = NULL;
40
-unsigned char* _local_certificate = NULL;
41
-unsigned char* _ca_certificate    = NULL;
42
-char* _device_ip         = NULL;
43
-char* _device_port       = NULL;
44
-int   _ssl_lifetime      = 300;
45
-int   _persistence       = 60 * 1000;
46
-int   _retry_delay       = 0;
47
-int   _retry_limit       = 2;
48
-int   _timeout           = 60 * 1000;
49
-int   _max_destinations  = 5;
50
-int   _token_format      = 2;
51
-int   _crypto_hw_support = 0;
52
-/* by default validate call ids, set to 0 to disable validation */
53
-int   _validate_call_id  = 1;
54
-char _PRIVATE_KEY[255];
55
-char _LOCAL_CERTIFICATE[255];
56
-char _CA_CERTIFICATE[255];
57
-
58
-OSPTPROVHANDLE _provider = -1;
55
+OSPTPROVHANDLE _osp_provider = -1;
... ...
@@ -28,329 +28,445 @@
28 28
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
29 29
  */
30 30
 
31
-
32
-
33
-
34
-
35
-#include "osp_mod.h"
36
-#include "osptoolkit.h"
31
+#include <string.h>
32
+#include <osp/osp.h>
33
+#include "../../dset.h"
34
+#include "../../usr_avp.h"
35
+#include "../../mem/mem.h"
37 36
 #include "orig_transaction.h"
38
-#include "sipheader.h"
39 37
 #include "destination.h"
38
+#include "osptoolkit.h"
39
+#include "sipheader.h"
40 40
 #include "usage.h"
41
-#include "osp/osp.h"
42
-#include "../../sr_module.h"
43
-#include "../../locking.h"
44
-#include "../../mem/mem.h"
45
-#include "../../dset.h"
46
-
47
-extern int   _max_destinations;
48
-extern char* _device_ip;
49
-extern char* _device_port;
50
-extern OSPTPROVHANDLE _provider;
51
-
52
-
53
-const int FIRST_ROUTE = 1;
54
-const int NEXT_ROUTE  = 0;
55
-
56
-
57
-static int loadosproutes(     struct sip_msg* msg, OSPTTRANHANDLE transaction, int expectedDestCount, char* source, char* source_dev, time_t time_ath);
58
-static int prepareDestination(struct sip_msg* msg, int isFirst);
59
-
60
-
61
-
62
-
63
-
64
-
65
-
66
-int requestosprouting(struct sip_msg* msg, char* ignore1, char* ignore2) {
67
-
68
-	int res;     /* used for function results */
69
-	int valid;   /* returncode for this function */
70
-
71
-	/* parameters for API call */
72
-	char osp_source_dev[200];
73
-	char e164_source[1000];
74
-	char e164_dest [1000];
75
-	unsigned int number_callids = 1;
76
-	OSPTCALLID* call_ids[number_callids];
77
-	unsigned int log_size = 0;
78
-	char* detail_log = NULL;
79
-	const char** preferred = NULL;
80
-	unsigned int dest_count;
81
-	OSPTTRANHANDLE transaction = -1;
82
-	time_t time_auth;
83
-
84
-	valid = MODULE_RETURNCODE_FALSE;
85
-
86
-	time_auth = time(NULL);
87
-
88
-	dest_count = _max_destinations;
89
-
90
-	if (0!= (res=OSPPTransactionNew(_provider, &transaction))) {
91
-		LOG(L_ERR, "ERROR: osp: Failed to create a new OSP transaction id %d\n",res);
92
-	} else if (0 != getFromUserpart(msg, e164_source,sizeof(e164_source))) {
93
-		LOG(L_ERR, "ERROR: osp: Failed to extract calling number\n");
94
-	} else if (0 != getToUserpart(msg, e164_dest,sizeof(e164_dest))) {
95
-		LOG(L_ERR, "ERROR: osp: Failed to extract called number\n");
96
-	} else if (0 != getCallId(msg, &(call_ids[0]))) {
97
-		LOG(L_ERR, "ERROR: osp: Failed to extract call id\n");
98
-	} else if (0 != getSourceAddress(msg,osp_source_dev,sizeof(osp_source_dev))) {
99
-		LOG(L_ERR, "ERROR: osp: Failed to extract source address\n");
100
-	} else {
101
-		LOG(L_INFO,"osp: Requesting OSP authorization and routing for: "
102
-			"transaction-handle '%i' \n"
103
-			"osp_source '%s' "
104
-			"osp_source_port '%s' "
105
-			"osp_source_dev '%s' "
106
-			"e164_source '%s' "
107
-			"e164_dest '%s' "
108
-			"call-id '%.*s' "
109
-			"dest_count '%i'",
110
-			transaction,
111
-			_device_ip,
112
-			_device_port,
113
-			osp_source_dev,
114
-			e164_source,
115
-			e164_dest,
116
-			call_ids[0]->ospmCallIdLen,
117
-			call_ids[0]->ospmCallIdVal,
118
-			dest_count
119
-		);	
120
-
121
-
122
-		if (strlen(_device_port) > 0) {
123
-			OSPPTransactionSetNetworkIds(transaction,_device_port,"");
124
-		}
125
-
126
-		/* try to request authorization */
127
-		res = OSPPTransactionRequestAuthorisation(
128
-		transaction,       /* transaction handle */
129
-		_device_ip,         /* from the configuration file */
130
-		osp_source_dev,    /* source of call, protocol specific */
131
-		e164_source,       /* calling number in nodotted e164 notation */
132
-		OSPC_E164,
133
-		e164_dest,         /* called number */
134
-		OSPC_E164,
135
-		"",                /* optional username string, used if no number */
136
-		number_callids,    /* number of call ids, here always 1 */
137
-		call_ids,          /* sized-1 array of call ids */
138
-		preferred,         /* preferred destinations, here always NULL */
139
-		&dest_count,       /* max destinations, after call dest_count */
140
-		&log_size,          /* size allocated for detaillog (next param) 0=no log */
141
-		detail_log);       /* memory location for detaillog to be stored */
142
-
143
-		if (res == 0 && dest_count > 0) {
144
-			LOG(L_INFO, "osp: there is %d osp routes, call-id '%.*s', transaction-id '%lld'\n",
145
-				dest_count,call_ids[0]->ospmCallIdLen, call_ids[0]->ospmCallIdVal,get_transaction_id(transaction));
146
-			record_orig_transaction(msg,transaction,osp_source_dev,e164_source,e164_dest,time_auth);
147
-			valid = loadosproutes(msg,transaction,dest_count,_device_ip,osp_source_dev,time_auth);
148
-		} else if (res == 0 && dest_count == 0) {
149
-			LOG(L_INFO, "osp: there is 0 osp routes, the route is blocked, call-id '%.*s', transaction-id '%lld'\n",
150
-				call_ids[0]->ospmCallIdLen,call_ids[0]->ospmCallIdVal,get_transaction_id(transaction));
151
-		} else {
152
-			LOG(L_ERR, "ERROR: osp: OSPPTransactionRequestAuthorisation returned %i, call-id '%.*s', transaction-id '%lld'\n",
153
-				res,call_ids[0]->ospmCallIdLen,call_ids[0]->ospmCallIdVal,get_transaction_id(transaction));
154
-		}
155
-	}
156
-
157
-	if (call_ids[0]!=NULL) {
158
-		OSPPCallIdDelete(&(call_ids[0]));
159
-	}
160
-
161
-	if (transaction!=-1) {
162
-		OSPPTransactionDelete(transaction);
163
-	}
164
-	
165
-	return valid;
166
-}
167 41
 
42
+extern char* _osp_device_ip;
43
+extern char* _osp_device_port;
44
+extern int _osp_max_dests;
45
+extern OSPTPROVHANDLE _osp_provider;
168 46
 
169
-static int loadosproutes(struct sip_msg* msg, OSPTTRANHANDLE transaction, int expectedDestCount, char* source, char* source_dev, time_t time_auth) {
170
-
171
-	int result = MODULE_RETURNCODE_TRUE;
172
-	int res;
173
-	int count;
174
-
175
-	osp_dest  dests[MAX_DESTS];
176
-	osp_dest* dest;
177
-	
178
-	for (count = 0; count < expectedDestCount; count++) {
179
-
180
-		dest = initDestination(&dests[count]);
181
-
182
-		if (dest == NULL) {
183
-			result = MODULE_RETURNCODE_FALSE;
184
-			break;
185
-		}
186
-
187
-		if (count==0) {
188
-			res = OSPPTransactionGetFirstDestination(
189
-				transaction,
190
-				sizeof(dest->validafter),
191
-				dest->validafter,
192
-				dest->validuntil,
193
-				&dest->timelimit,
194
-				&dest->sizeofcallid,
195
-				(void*)dest->callid,
196
-				sizeof(dest->callednumber),
197
-				dest->callednumber,
198
-				sizeof(dest->callingnumber),
199
-				dest->callingnumber,
200
-				sizeof(dest->destination),
201
-				dest->destination,
202
-				sizeof(dest->destinationdevice),
203
-				dest->destinationdevice,
204
-				&dest->sizeoftoken,
205
-				dest->osptoken);
206
-		} else {
207
-			res = OSPPTransactionGetNextDestination(
208
-				transaction,
209
-				0,
210
-				sizeof(dest->validafter),
211
-				dest->validafter,
212
-				dest->validuntil,
213
-				&dest->timelimit,
214
-				&dest->sizeofcallid,
215
-				(void*)dest->callid,
216
-				sizeof(dest->callednumber),
217
-				dest->callednumber,
218
-				sizeof(dest->callingnumber),
219
-				dest->callingnumber,
220
-				sizeof(dest->destination),
221
-				dest->destination,
222
-				sizeof(dest->destinationdevice),
223
-				dest->destinationdevice,
224
-				&dest->sizeoftoken,
225
-				dest->osptoken);
226
-		}
227
-
228
-		
229
-		if (res != 0) {
230
-			LOG(L_ERR,"ERROR: osp: getDestination %d failed, expected number %d, current count %d\n",res,expectedDestCount,count);
231
-			result = MODULE_RETURNCODE_FALSE;
232
-			break;
233
-		}
234
-
235
-		OSPPTransactionGetDestNetworkId(transaction,dest->network_id);
236
-		strcpy(dest->source,source);
237
-		strcpy(dest->sourcedevice,source_dev);
238
-		dest->type = OSPC_SOURCE;
239
-		dest->tid = get_transaction_id(transaction);
240
-		dest->time_auth = time_auth;
241
-
242
-		LOG(L_INFO,"osp: getDestination %d returned the following information: "
243
-		"valid after '%s' "
244
-		"valid until '%s' "
245
-		"time limit '%i' seconds "
246
-		"call-id '%.*s' "
247
-		"calling number '%s' "
248
-		"called number '%s' "
249
-		"destination '%s' "
250
-		"network id '%s' "
251
-		"bn token size '%i' ",
252
-		count, dest->validafter, dest->validuntil, dest->timelimit, dest->sizeofcallid, dest->callid, dest->callingnumber, dest->callednumber, 
253
-		dest->destination, dest->network_id, dest->sizeoftoken);
254
-	}
255
-
256
-	/* save destination in reverse order,
257
-	 * this way, when we start searching avps the destinations
258
-	 * will be in order 
259
-	 */
260
-	if (result == MODULE_RETURNCODE_TRUE) {
261
-		for(count = expectedDestCount -1; count >= 0; count--) {
262
-			saveOrigDestination(&dests[count]);
263
-		}
264
-	}
265
-
266
-	return result;
267
-}
268
-
269
-
270
-
271
-
272
-
273
-int preparefirstosproute(struct sip_msg* msg, char* ignore1, char* ignore2) {
274
-	int result = MODULE_RETURNCODE_TRUE;
275
-
276
-	DBG("osp: Preparing 1st route\n");
47
+const int OSP_FIRST_ROUTE = 1;
48
+const int OSP_NEXT_ROUTE = 0;
49
+const int OSP_MAIN_ROUTE = 1;
50
+const int OSP_BRANCH_ROUTE = 0;
277 51
 
278
-	result = prepareDestination(msg,FIRST_ROUTE);
52
+static int ospLoadRoutes(struct sip_msg* msg, OSPTTRANHANDLE transaction, int destcount, char* source, char* sourcedev, time_t authtime);
53
+static int ospPrepareDestination(struct sip_msg* msg, int isfirst, int type);
279 54
 
280
-	return result;
55
+/*
56
+ * Get routes from AuthRsp
57
+ * param msg SIP message
58
+ * param transaction Transaction handle
59
+ * param destcount Expected destination count
60
+ * param source Source IP
61
+ * param sourcedev Source device IP
62
+ * param authtime Request authorization time
63
+ * return MODULE_RETURNCODE_TRUE success, MODULE_RETURNCODE_FALSE failure
64
+ */
65
+static int ospLoadRoutes(
66
+    struct sip_msg* msg, 
67
+    OSPTTRANHANDLE transaction, 
68
+    int destcount, 
69
+    char* source, 
70
+    char* sourcedev, 
71
+    time_t authtime)
72
+{
73
+    int count;
74
+    int errorcode;
75
+    osp_dest* dest;
76
+    osp_dest dests[OSP_DEF_DESTS];
77
+	OSPE_DEST_PROT protocol;
78
+	OSPE_DEST_OSP_ENABLED enabled;
79
+    int result = MODULE_RETURNCODE_TRUE;
80
+    
81
+    LOG(L_DBG, "osp: ospLoadRoutes\n");
82
+
83
+    for (count = 0; count < destcount; count++) {
84
+        /* This is necessary becuase we will save destinations in reverse order */
85
+        dest = ospInitDestination(&dests[count]);
86
+
87
+        if (dest == NULL) {
88
+            result = MODULE_RETURNCODE_FALSE;
89
+            break;
90
+        }
91
+
92
+        if (count == 0) {
93
+            errorcode = OSPPTransactionGetFirstDestination(
94
+                transaction,
95
+                sizeof(dest->validafter),
96
+                dest->validafter,
97
+                dest->validuntil,
98
+                &dest->timelimit,
99
+                &dest->callidsize,
100
+                (void*)dest->callid,
101
+                sizeof(dest->called),
102
+                dest->called,
103
+                sizeof(dest->calling),
104
+                dest->calling,
105
+                sizeof(dest->host),
106
+                dest->host,
107
+                sizeof(dest->destdev),
108
+                dest->destdev,
109
+                &dest->tokensize,
110
+                dest->token);
111
+        } else {
112
+            errorcode = OSPPTransactionGetNextDestination(
113
+                transaction,
114
+                0,
115
+                sizeof(dest->validafter),
116
+                dest->validafter,
117
+                dest->validuntil,
118
+                &dest->timelimit,
119
+                &dest->callidsize,
120
+                (void*)dest->callid,
121
+                sizeof(dest->called),
122
+                dest->called,
123
+                sizeof(dest->calling),
124
+                dest->calling,
125
+                sizeof(dest->host),
126
+                dest->host,
127
+                sizeof(dest->destdev),
128
+                dest->destdev,
129
+                &dest->tokensize,
130
+                dest->token);
131
+        }
132
+        
133
+        if (errorcode != 0) {
134
+            LOG(L_ERR, 
135
+                "osp: ERROR: failed to load routes (%d) expected '%d' current '%d'\n", 
136
+                errorcode, 
137
+                destcount, 
138
+                count);
139
+            result = MODULE_RETURNCODE_FALSE;
140
+            break;
141
+        }
142
+
143
+        errorcode = OSPPTransactionGetDestProtocol(transaction, &protocol);
144
+        if (errorcode != 0) {
145
+            LOG(L_ERR, "osp: ERROR: failed to get dest protocol (%d)\n", errorcode);
146
+            result = MODULE_RETURNCODE_FALSE;
147
+            break;
148
+        } else {
149
+            switch (protocol) {
150
+                case OSPE_DEST_PROT_H323_LRQ:
151
+                case OSPE_DEST_PROT_H323_SETUP:
152
+                case OSPE_DEST_PROT_IAX:
153
+                    dest->supported = 0;
154
+                    break;
155
+                case OSPE_DEST_PROT_SIP:
156
+                case OSPE_DEST_PROT_UNDEFINED:
157
+                case OSPE_DEST_PROT_UNKNOWN:
158
+                default:
159
+                    dest->supported = 1;
160
+                    break;
161
+            }
162
+        }
163
+
164
+        errorcode = OSPPTransactionIsDestOSPEnabled(transaction, &enabled);
165
+        if (errorcode != 0) {
166
+            LOG(L_ERR, "osp: ERROR: failed to get dest OSP version (%d)\n", errorcode);
167
+            result = MODULE_RETURNCODE_FALSE;
168
+            break;
169
+        } else if (enabled == OSPE_OSP_FALSE) {
170
+            /* Destination device does not support OSP. Do not send token to it */
171
+            dest->token[0] = '\0';
172
+            dest->tokensize = 0;
173
+        }
174
+
175
+        OSPPTransactionGetDestNetworkId(transaction, dest->networkid);
176
+        strcpy(dest->source, source);
177
+        strcpy(dest->srcdev, sourcedev);
178
+        dest->type = OSPC_SOURCE;
179
+        dest->tid = ospGetTransactionId(transaction);
180
+        dest->authtime = authtime;
181
+
182
+        LOG(L_INFO,
183
+            "osp: get destination '%d': "
184
+            "valid after '%s' "
185
+            "valid until '%s' "
186
+            "time limit '%i' seconds "
187
+            "call-id '%.*s' "
188
+            "calling number '%s' "
189
+            "called number '%s' "
190
+            "host '%s' "
191
+            "supported '%d' "
192
+            "network id '%s' "
193
+            "token size '%i'\n",
194
+            count, 
195
+            dest->validafter, 
196
+            dest->validuntil, 
197
+            dest->timelimit, 
198
+            dest->callidsize, 
199
+            dest->callid, 
200
+            dest->calling, 
201
+            dest->called, 
202
+            dest->host, 
203
+            dest->supported,
204
+            dest->networkid, 
205
+            dest->tokensize);
206
+    }
207
+
208
+    /* 
209
+     * Save destination in reverse order,
210
+     * when we start searching avps the destinations
211
+     * will be in order 
212
+     */
213
+    if (result == MODULE_RETURNCODE_TRUE) {
214
+        for(count = destcount -1; count >= 0; count--) {
215
+            ospSaveOrigDestination(&dests[count]);
216
+        }
217
+    }
218
+
219
+    return result;
281 220
 }
282 221
 
283
-
284
-
285
-
286
-int preparenextosproute(struct sip_msg* msg, char* ignore1, char* ignore2) {
287
-	int result = MODULE_RETURNCODE_TRUE;
288
-
289
-	DBG("osp: Preparing next route\n");
290
-
291
-	result = prepareDestination(msg,NEXT_ROUTE);
292
-
293
-
294
-	return result;
222
+/*
223
+ * Request OSP authorization and routeing
224
+ * param msg SIP message
225
+ * param ignore1
226
+ * param ignore2
227
+ * return MODULE_RETURNCODE_TRUE success, MODULE_RETURNCODE_FALSE failure
228
+ */
229
+int requestosprouting(
230
+    struct sip_msg* msg, 
231
+    char* ignore1, 
232
+    char* ignore2)
233
+{
234
+    int errorcode;
235
+    time_t authtime;
236
+    char source[OSP_E164BUF_SIZE];
237
+    char sourcedev[OSP_STRBUF_SIZE];
238
+    char destination[OSP_E164BUF_SIZE];
239
+    unsigned int callidnumber = 1;
240
+    OSPTCALLID* callids[callidnumber];
241
+    unsigned int logsize = 0;
242
+    char* detaillog = NULL;
243
+    const char** preferred = NULL;
244
+    unsigned int destcount;