~ubuntu-branches/ubuntu/oneiric/osptoolkit/oneiric

« back to all changes in this revision

Viewing changes to src/osptransapi.c

  • Committer: Bazaar Package Importer
  • Author(s): TransNexus, Inc.
  • Date: 2007-12-30 20:37:26 UTC
  • Revision ID: james.westby@ubuntu.com-20071230203726-dysah2e93yqd3vbp
Tags: upstream-3.4.2
ImportĀ upstreamĀ versionĀ 3.4.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**************************************************************************
 
2
*** COPYRIGHT (c) 2002 by TransNexus, Inc.                              ***
 
3
***                                                                     ***
 
4
*** This software is property of TransNexus, Inc.                       ***
 
5
*** This software is freely available under license from TransNexus.    ***
 
6
*** The license terms and conditions for free use of this software by   ***
 
7
*** third parties are defined in the OSP Toolkit Software License       ***
 
8
*** Agreement (LICENSE.txt).  Any use of this software by third         ***
 
9
*** parties, which does not comply with the terms and conditions of the ***
 
10
*** OSP Toolkit Software License Agreement is prohibited without        ***
 
11
*** the prior, express, written consent of TransNexus, Inc.             ***
 
12
***                                                                     ***
 
13
*** Thank you for using the OSP ToolKit(TM).  Please report any bugs,   ***
 
14
*** suggestions or feedback to support@transnexus.com                   ***
 
15
***                                                                     ***
 
16
**************************************************************************/
 
17
 
 
18
 
 
19
 
 
20
 
 
21
 
 
22
 
 
23
 
 
24
 
 
25
/*
 
26
 * osptransapi.cpp - API functions for transaction object.
 
27
 */
 
28
 
 
29
#include "osp/osp.h"
 
30
#include "osp/osptrans.h"
 
31
#include "osp/ospprovider.h"
 
32
#include "osp/ospxml.h"
 
33
#include "osp/ospmsginfo.h"
 
34
#include "osp/ospdest.h"
 
35
#include "osp/ospstatus.h"
 
36
#include "osp/ospusageind.h"
 
37
#include "osp/ospauthind.h"
 
38
#include "osp/osptokeninfo.h"
 
39
#include "osp/ospmsg.h"
 
40
#include "osp/ospfail.h"
 
41
#include "osp/osputils.h"
 
42
#include "osp/osptnprobe.h"
 
43
#include "osp/ospstatistics.h"
 
44
#include "osp/ospcapind.h"
 
45
 
 
46
#define OSPC_UNDEFINED_CALLID_NUM       ((unsigned)1)
 
47
#define OSPC_UNDEFINED_CALLID_STR       ((unsigned char*)"UNDEFINED")
 
48
#define OSPC_UNDEFINED_CALLID_SIZE      ((unsigned)9)                   /* size of OSPC_UNDEFINED_CALLID_STR */
 
49
 
 
50
/*
 
51
 * OSPPTransactionSetServiceAndPricingInfo
 
52
 * The API sets the Service Type and Pricing Information
 
53
 * in the transaction structure
 
54
 */
 
55
int 
 
56
OSPPTransactionSetServiceAndPricingInfo(
 
57
    OSPTTRANHANDLE  ospvTransaction,    /* In - Transaction handle             */
 
58
    OSPE_SERVICE_TYPE ospvServiceType, /* In- type of service, 0-voice, 1-data */
 
59
    OSPT_PRICING_INFO    *ospvPricingInfo[MAX_PRICING_INFO_ALLOWED]) /* In- Pricing Info */
 
60
{
 
61
    int errorcode = OSPC_ERR_NO_ERROR,i;
 
62
    OSPTTRANS *trans=NULL;
 
63
    OSPE_TRANS_STATE state;
 
64
 
 
65
    if (errorcode == OSPC_ERR_NO_ERROR)
 
66
    { 
 
67
        trans = OSPPTransactionGetContext(ospvTransaction, &errorcode);
 
68
    }
 
69
 
 
70
    if (errorcode == OSPC_ERR_NO_ERROR)
 
71
    {
 
72
        OSPPTransactionGetState(trans,&state);
 
73
        if (state != OSPC_TRANSNEW)
 
74
        {
 
75
            errorcode = OSPC_ERR_TRAN_REQ_OUT_OF_SEQ;
 
76
            OSPM_DBGERRORLOG(errorcode, "Called API Not In Sequence \n");
 
77
        }
 
78
    }
 
79
 
 
80
    if (errorcode == OSPC_ERR_NO_ERROR)
 
81
    {
 
82
       /*
 
83
        * Set the service type information
 
84
        */
 
85
       if ((ospvServiceType == OSPC_VOICE) || (ospvServiceType == OSPC_DATA))
 
86
       {
 
87
           trans->IsServiceInfoPresent = OSPC_TRUE;
 
88
           trans->ServiceType = ospvServiceType;
 
89
       }
 
90
       else
 
91
       {
 
92
           errorcode = OSPC_ERR_TRAN_INVALID_ENTRY;
 
93
           OSPM_DBGERRORLOG(errorcode, "Invalid input for OSPPTransactionSetServiceAndPricingInfo");
 
94
       }
 
95
 
 
96
       /*
 
97
        * Set the pricing info 
 
98
        */
 
99
       for (i=0;i<MAX_PRICING_INFO_ALLOWED;i++)
 
100
       {
 
101
           if ((errorcode == OSPC_ERR_NO_ERROR) && ospvPricingInfo[i] &&
 
102
               ospvPricingInfo[i]->unit && ospvPricingInfo[i]->currency && 
 
103
               (OSPM_STRLEN((const char *)ospvPricingInfo[i]->unit) < OSPC_UNITSIZE) && 
 
104
               (OSPM_STRLEN((const char *)ospvPricingInfo[i]->currency) < OSPC_CURRENCYSIZE))
 
105
           {
 
106
               trans->IsPricingInfoPresent = OSPC_TRUE;
 
107
               trans->PricingInfo[i].amount = ospvPricingInfo[i]->amount;
 
108
               trans->PricingInfo[i].increment = ospvPricingInfo[i]->increment;
 
109
               OSPM_STRCPY((char *)trans->PricingInfo[i].unit,(const char *)ospvPricingInfo[i]->unit);
 
110
               OSPM_STRCPY((char *)trans->PricingInfo[i].currency,(const char *)ospvPricingInfo[i]->currency);
 
111
           }
 
112
           else
 
113
           {
 
114
               trans->NumOfPricingInfoElements = i;
 
115
               break;
 
116
           }
 
117
       }
 
118
    }
 
119
 
 
120
    return errorcode;
 
121
}
 
122
 
 
123
/*
 
124
 * OSPPTransactionModifyDeviceIdentifiers
 
125
 * This API is called to overwrite the ospvSource/ospvSourceDevice/
 
126
 * ospvDestination/ospvDestination device that was passed in the 
 
127
 * Authorization Req/Validate API's.
 
128
 * This API provides the application with a mechanism of reporting Usage
 
129
 * with addresses different than those that were used while calling
 
130
 * RequestAuth/ValidateAuth/BuildUsageFromScratch/InitializeAtDevice etc APIs. 
 
131
 * Parameters 2 through 5 are optional. However, at least one of the four needs to be 
 
132
 * non-NULL.
 
133
 */ 
 
134
int
 
135
OSPPTransactionModifyDeviceIdentifiers(
 
136
    OSPTTRANHANDLE  ospvTransaction,    /* In - Transaction handle             */
 
137
    const char      *ospvSource,        /* In - optional */
 
138
    const char      *ospvSourceDevice,  /* In - optional */
 
139
    const char      *ospvDestination,   /* In - optional */
 
140
    const char      *ospvDestinationDevice)  /* In - optional */
 
141
{
 
142
    int errorcode = OSPC_ERR_NO_ERROR;
 
143
    OSPTTRANS *trans=NULL;
 
144
    OSPTDEST  *dest=NULL;
 
145
    OSPTBOOL modifyallowed=OSPC_FALSE;
 
146
    OSPTALTINFO *altinfo=NULL,*altinfoToKeep=NULL,*altinfoToKeep2=NULL;
 
147
 
 
148
    if ((ospvSource == NULL) && (ospvSourceDevice == NULL) && 
 
149
        (ospvDestination == NULL) && (ospvDestinationDevice == NULL))  
 
150
    {
 
151
        errorcode = OSPC_ERR_TRAN_INVALID_ENTRY;
 
152
        OSPM_DBGERRORLOG(errorcode, "Invalid input for OSPPTransactionModifyDeviceIdentifiers");
 
153
    }
 
154
 
 
155
    if (errorcode == OSPC_ERR_NO_ERROR)
 
156
    { 
 
157
        trans = OSPPTransactionGetContext(ospvTransaction, &errorcode);
 
158
    }
 
159
 
 
160
    if (errorcode == OSPC_ERR_NO_ERROR)
 
161
    {
 
162
        OSPPTransactionGetIsModifyDeviceIdAllowed(trans, &modifyallowed);
 
163
 
 
164
        if (modifyallowed == OSPC_TRUE)
 
165
        {
 
166
            if(trans->AuthRsp != (OSPTAUTHRSP *)OSPC_OSNULL)
 
167
            {
 
168
                /*
 
169
                 * We are the source. Change the non-NULL values passed in
 
170
                 * in the API within the CurrentDest obj.
 
171
                 */
 
172
                 dest = trans->CurrentDest;
 
173
 
 
174
                 if (ospvSource != NULL)
 
175
                 {
 
176
                     /*
 
177
                      * The check for duplicate calls has been removed.
 
178
                      * First delete the old ospmUpdatedSourceAddr list, if any
 
179
                      * Then add the new values.
 
180
                      */
 
181
                     while (!OSPPListEmpty((OSPTLIST *)&(dest->ospmUpdatedSourceAddr)))
 
182
                     {
 
183
                         altinfo = (OSPTALTINFO *)OSPPListRemove(
 
184
                                  (OSPTLIST *)&(dest->ospmUpdatedSourceAddr));
 
185
                         if (altinfo != (OSPTALTINFO *)OSPC_OSNULL)
 
186
                         {
 
187
                             OSPM_FREE(altinfo);
 
188
                             altinfo = OSPC_OSNULL;
 
189
                         }
 
190
                     }
 
191
                     /*
 
192
                      * Now add.
 
193
                      */
 
194
                     altinfo = OSPPAltInfoNew(strlen(ospvSource),
 
195
                                (const unsigned char *)ospvSource,
 
196
                                ospeTransport);
 
197
 
 
198
                     if(altinfo != OSPC_OSNULL)
 
199
                     {
 
200
                         OSPPListAppend(
 
201
                                    (OSPTLIST *)&(dest->ospmUpdatedSourceAddr),
 
202
                                    (void *)altinfo);
 
203
                     }
 
204
                }
 
205
 
 
206
                altinfo = NULL;
 
207
                if (ospvSourceDevice != NULL)
 
208
                {
 
209
                    /*
 
210
                     * The check for duplicate calls has been removed.
 
211
                     * First delete the old ospmUpdatedDeviceInfo list, if any
 
212
                     * Then add the new values.
 
213
                     */
 
214
                    while (!OSPPListEmpty((OSPTLIST *)&(dest->ospmUpdatedDeviceInfo)))
 
215
                    {
 
216
                        altinfo = (OSPTALTINFO *)OSPPListRemove(
 
217
                                  (OSPTLIST *)&(dest->ospmUpdatedDeviceInfo));
 
218
                        if (altinfo != (OSPTALTINFO *)OSPC_OSNULL)
 
219
                        {
 
220
                            OSPM_FREE(altinfo);
 
221
                            altinfo = OSPC_OSNULL;
 
222
                        }
 
223
                    }
 
224
                    /*
 
225
                     * Now add.
 
226
                     */
 
227
                     altinfo = OSPPAltInfoNew(strlen(ospvSourceDevice),
 
228
                                (const unsigned char *)ospvSourceDevice,
 
229
                                ospeTransport);
 
230
 
 
231
                     if(altinfo != OSPC_OSNULL)
 
232
                     {
 
233
                          OSPPListAppend(
 
234
                                (OSPTLIST *)&(dest->ospmUpdatedDeviceInfo),
 
235
                                (void *)altinfo);
 
236
                     }
 
237
                }
 
238
                altinfo = NULL;
 
239
                
 
240
                if (ospvDestination != NULL)
 
241
                {
 
242
                    /*
 
243
                     * Just overwrite on the old values, if any
 
244
                     */
 
245
                    OSPPDestSetAddr(dest,(const unsigned char *)ospvDestination);
 
246
                }
 
247
 
 
248
                if (ospvDestinationDevice != NULL)
 
249
                {
 
250
                    /*
 
251
                     * Just overwrite on the old values, if any
 
252
                     */
 
253
                    OSPPDestDevSetAddr(dest,(const unsigned char *)ospvDestinationDevice);
 
254
                }
 
255
            }
 
256
            else if(trans->AuthInd != (OSPTAUTHIND *)OSPC_OSNULL)
 
257
            {
 
258
                if ((ospvSource != NULL) && (errorcode == OSPC_ERR_NO_ERROR))
 
259
                {
 
260
                    /*
 
261
                     * Overwrite the SourceAlternate in the AuthInd
 
262
                     */
 
263
                    if (OSPPAuthIndHasSourceAlt(trans->AuthInd))
 
264
                    {
 
265
                        /*
 
266
                         * If srcAlt is present, delete the type- transport
 
267
                         * but keep the type-network.
 
268
                         */
 
269
                        altinfoToKeep = NULL;
 
270
                        while(!OSPPListEmpty(&(trans->AuthInd->ospmAuthIndSourceAlternate)))
 
271
                        {
 
272
                            altinfo = (OSPTALTINFO *)OSPPListRemove(&(trans->AuthInd->ospmAuthIndSourceAlternate));
 
273
                            if (altinfo->ospmAltInfoType == ospeNetwork)
 
274
                            {
 
275
                               /*
 
276
                                * This node in the list corresponds to
 
277
                                * Network Id. Do not delete it.
 
278
                                */
 
279
                               altinfoToKeep = altinfo;
 
280
                            }
 
281
                            else
 
282
                            {
 
283
                                OSPM_FREE(altinfo);
 
284
                                altinfo = OSPC_OSNULL;
 
285
                            }
 
286
                        }                 
 
287
                        /*
 
288
                         * Add back the AltInfo for networkId
 
289
                         */
 
290
                        if (altinfoToKeep)
 
291
                        {
 
292
                            OSPPListAppend(
 
293
                                 (OSPTLIST *)&(trans->AuthInd->ospmAuthIndSourceAlternate),
 
294
                                 (void *)altinfoToKeep);
 
295
                            altinfoToKeep = NULL;
 
296
                        }
 
297
                    }
 
298
                    altinfo = OSPPAltInfoNew(OSPM_STRLEN(ospvSource),
 
299
                                (const unsigned char *)ospvSource,
 
300
                                ospeTransport);
 
301
 
 
302
                    if(altinfo != OSPC_OSNULL)
 
303
                    {
 
304
 
 
305
                        OSPPListAppend(
 
306
                             (OSPTLIST *)&(trans->AuthInd->ospmAuthIndSourceAlternate),
 
307
                             (void *)altinfo);
 
308
                    }
 
309
                    altinfo = NULL;
 
310
                }
 
311
 
 
312
                if ((ospvSourceDevice != NULL) && (errorcode == OSPC_ERR_NO_ERROR))
 
313
                {
 
314
                    /*
 
315
                     * Overwrite the deviceInfo in the AuthInd
 
316
                     */
 
317
                    if (trans->AuthInd->ospmAuthIndDeviceInfo != NULL)
 
318
                    {
 
319
                        /*
 
320
                         * If srcAlt is present, delete the type- transport
 
321
                         * but keep the type-network.
 
322
                         */
 
323
                        altinfoToKeep = NULL;
 
324
                        while(!OSPPListEmpty(&(trans->AuthInd->ospmAuthIndDeviceInfo)))
 
325
                        {
 
326
                            altinfo = (OSPTALTINFO *)OSPPListRemove(&(trans->AuthInd->ospmAuthIndDeviceInfo));
 
327
                            if (altinfo->ospmAltInfoType == ospeNetwork)
 
328
                            {
 
329
                               /*
 
330
                                * This node in the list corresponds to
 
331
                                * Network Id. Do not delete it.
 
332
                                */
 
333
                               altinfoToKeep = altinfo;
 
334
                            }
 
335
                            else
 
336
                            {
 
337
                                OSPM_FREE(altinfo);
 
338
                                altinfo = OSPC_OSNULL;
 
339
                            }
 
340
                        }                 
 
341
                        /*
 
342
                         * Add back the AltInfo for networkId
 
343
                         */
 
344
                        if (altinfoToKeep)
 
345
                        {
 
346
                            OSPPListAppend(
 
347
                                 (OSPTLIST *)&(trans->AuthInd->ospmAuthIndDeviceInfo),
 
348
                                 (void *)altinfoToKeep);
 
349
                            altinfoToKeep = NULL;
 
350
                        }
 
351
                    }
 
352
                    altinfo = OSPPAltInfoNew(OSPM_STRLEN(ospvSourceDevice),
 
353
                                (const unsigned char *)ospvSourceDevice,
 
354
                                ospeTransport);
 
355
 
 
356
                    if(altinfo != OSPC_OSNULL)
 
357
                    {
 
358
 
 
359
                        OSPPListAppend(
 
360
                             (OSPTLIST *)&(trans->AuthInd->ospmAuthIndDeviceInfo),
 
361
                             (void *)altinfo);
 
362
                    }
 
363
                    altinfo = NULL;
 
364
                }
 
365
 
 
366
                if ((ospvDestination != NULL) && (errorcode == OSPC_ERR_NO_ERROR))
 
367
                {
 
368
                    /*
 
369
                     * This is a little messed up. 
 
370
                     * NetworkId, Destination and DestinationDevice go to the same list.
 
371
                     * Thus, when we are modifying the list, we need to replace only the node for destination.
 
372
                     * If there is a node for destinationDevice, it should still remain there.
 
373
                     */
 
374
                     while(!OSPPListEmpty(&(trans->AuthInd->ospmAuthIndDestinationAlternate)))
 
375
                     {
 
376
                         altinfo = (OSPTALTINFO *)OSPPListRemove(&(trans->AuthInd->ospmAuthIndDestinationAlternate));
 
377
                         if(altinfo != OSPC_OSNULL)
 
378
                         {
 
379
                             if (altinfo->ospmAltInfoType == ospeH323)
 
380
                             {
 
381
                                 /*
 
382
                                  * This node in the list corresponds to 
 
383
                                  * DestinationDevice. Do not delete it.
 
384
                                  */
 
385
                                 altinfoToKeep = altinfo;
 
386
                             }
 
387
                             else if (altinfo->ospmAltInfoType == ospeNetwork)
 
388
                             {
 
389
                                 /*
 
390
                                  * This node in the list corresponds to 
 
391
                                  * Network Id. Do not delete it.
 
392
                                  */
 
393
                                 altinfoToKeep2 = altinfo;
 
394
                             }
 
395
                             else
 
396
                             {
 
397
                                 OSPM_FREE(altinfo);
 
398
                             }
 
399
                             altinfo = OSPC_OSNULL;
 
400
                         }
 
401
                     }
 
402
 
 
403
                     /*
 
404
                      * We have emptied the list now. 
 
405
                      * Add back the altinfo that corresponded to destinationDevice and Network Id
 
406
                      */
 
407
                      if (altinfoToKeep)
 
408
                      {
 
409
                          OSPPListAppend(
 
410
                              (OSPTLIST *)&(trans->AuthInd->ospmAuthIndDestinationAlternate),
 
411
                              (void *)altinfoToKeep);
 
412
                          altinfoToKeep = NULL;    
 
413
                      }
 
414
 
 
415
                      if (altinfoToKeep2)
 
416
                      {
 
417
                          OSPPListAppend(
 
418
                              (OSPTLIST *)&(trans->AuthInd->ospmAuthIndDestinationAlternate),
 
419
                              (void *)altinfoToKeep2);
 
420
                          altinfoToKeep2 = NULL;    
 
421
                      }
 
422
                     /*
 
423
                      * Now add the new destination
 
424
                      */
 
425
 
 
426
                      altinfo =
 
427
                           OSPPAltInfoNew(OSPM_STRLEN(ospvDestination),
 
428
                           (const unsigned char *)ospvDestination,
 
429
                           ospeTransport);
 
430
 
 
431
                      if(altinfo != OSPC_OSNULL)
 
432
                      {
 
433
                           OSPPListAppend(
 
434
                                    (OSPTLIST *)&(trans->AuthInd->ospmAuthIndDestinationAlternate),
 
435
                                    (void *)altinfo);
 
436
                      }
 
437
                      altinfo = NULL;
 
438
                }
 
439
 
 
440
                if ((ospvDestinationDevice != NULL) && (errorcode == OSPC_ERR_NO_ERROR))
 
441
                {
 
442
                    /*
 
443
                     * This is a little messed up. 
 
444
                     * NetworkId, Destination and DestinationDevice go to the same list.
 
445
                     * Thus, when we are modifying the list, we need to replace only the node for destination device.
 
446
                     * If there is a node for destination, it should still remain there.
 
447
                     */
 
448
                     while(!OSPPListEmpty(&(trans->AuthInd->ospmAuthIndDestinationAlternate)))
 
449
                     {
 
450
                         altinfo = (OSPTALTINFO *)OSPPListRemove(&(trans->AuthInd->ospmAuthIndDestinationAlternate));
 
451
                         if(altinfo != OSPC_OSNULL)
 
452
                         {
 
453
                             if (altinfo->ospmAltInfoType == ospeTransport)
 
454
                             {
 
455
                                 /*
 
456
                                  * This node in the list corresponds to 
 
457
                                  * Destination. Do not delete it.
 
458
                                  */
 
459
                                 altinfoToKeep = altinfo;
 
460
                             }
 
461
                             else if (altinfo->ospmAltInfoType == ospeNetwork)
 
462
                             {
 
463
                                 /*
 
464
                                  * This node in the list corresponds to 
 
465
                                  * NetworkId. Do not delete it.
 
466
                                  */
 
467
                                 altinfoToKeep2 = altinfo;
 
468
                             }
 
469
                             else
 
470
                             {
 
471
                                 OSPM_FREE(altinfo);
 
472
                             }
 
473
                             altinfo = OSPC_OSNULL;
 
474
                         }
 
475
                     }
 
476
 
 
477
                     /*
 
478
                      * We have emptied the list now. 
 
479
                      * Add back the altinfo that corresponded to destination
 
480
                      */
 
481
 
 
482
                      if (altinfoToKeep)
 
483
                      {
 
484
                          OSPPListAppend(
 
485
                              (OSPTLIST *)&(trans->AuthInd->ospmAuthIndDestinationAlternate),
 
486
                              (void *)altinfoToKeep);
 
487
                          altinfoToKeep = NULL;    
 
488
                      }
 
489
 
 
490
                      if (altinfoToKeep2)
 
491
                      {
 
492
                          OSPPListAppend(
 
493
                              (OSPTLIST *)&(trans->AuthInd->ospmAuthIndDestinationAlternate),
 
494
                              (void *)altinfoToKeep2);
 
495
                          altinfoToKeep2 = NULL;    
 
496
                      }
 
497
 
 
498
                     /*
 
499
                      * Now add the new node for destinationDevice
 
500
                      */
 
501
 
 
502
                      altinfo =
 
503
                           OSPPAltInfoNew(OSPM_STRLEN(ospvDestinationDevice),
 
504
                           (const unsigned char *)ospvDestinationDevice,
 
505
                           ospeH323);
 
506
 
 
507
                      if(altinfo != OSPC_OSNULL)
 
508
                      {
 
509
                           OSPPListAppend(
 
510
                                    (OSPTLIST *)&(trans->AuthInd->ospmAuthIndDestinationAlternate),
 
511
                                    (void *)altinfo);
 
512
                      }
 
513
                      altinfo = NULL;
 
514
                }
 
515
            }
 
516
            else
 
517
            {
 
518
                errorcode = OSPC_ERR_TRAN_INVALID_ENTRY;
 
519
                OSPM_DBGERRORLOG(errorcode, "No information available to process this report.");
 
520
            }
 
521
        }
 
522
    }
 
523
 
 
524
    return errorcode;
 
525
 
 
526
}
 
527
 
 
528
/*
 
529
 * OSPPTransactionGetLookAheadInfoIfPresent():
 
530
 * This API should be called after calling ValidateAuthorization.
 
531
 * The API takes the transaction id as the input and returns the LookAhead 
 
532
 * information if present in the token. If the LookAhead information is present 
 
533
 * in the token, ospvIsLookAheadInfoPresent is set to TRUE and the 
 
534
 * corresponding values are also set. If the information is not present, 
 
535
 * ospvIsLookAheadInfoPresent is set to FALSE. 
 
536
 */
 
537
int 
 
538
OSPPTransactionGetLookAheadInfoIfPresent(
 
539
    OSPTTRANHANDLE  ospvTransaction,    /* In - Transaction handle             */
 
540
    OSPTBOOL    *ospvIsLookAheadInfoPresent, /* Out */
 
541
    char        *ospvLookAheadDestination, /* Out */
 
542
    OSPE_DEST_PROT      *ospvLookAheadDestProt, /* Out */
 
543
    OSPE_DEST_OSP_ENABLED       *ospvLookAheadDestOSPStatus) /* Out */
 
544
{
 
545
    int errorcode = OSPC_ERR_NO_ERROR;
 
546
    OSPTTRANS *trans=NULL;
 
547
    OSPTAUTHIND **ospvAuthInd;
 
548
    unsigned char *destinfo;
 
549
    OSPTALTINFO   *altinfo = OSPC_OSNULL;
 
550
    OSPTALTINFO   *altinfoToKeep = OSPC_OSNULL;
 
551
 
 
552
    trans = OSPPTransactionGetContext(ospvTransaction, &errorcode);
 
553
  
 
554
    if (errorcode == OSPC_ERR_NO_ERROR)
 
555
    {
 
556
        *ospvIsLookAheadInfoPresent = trans->TokenInfoIsLookAheadInfoPresent;
 
557
 
 
558
        if (trans->TokenInfoIsLookAheadInfoPresent == OSPC_TRUE)
 
559
        {
 
560
            trans->WasLookAheadInfoGivenToApp = OSPC_TRUE;
 
561
 
 
562
            /*
 
563
             * Copy the LookAhead info into the variables passed
 
564
             */
 
565
            destinfo = OSPPTokenInfoGetLookAheadDestAlt(&(trans->TokenLookAheadInfo));
 
566
            OSPM_MEMCPY(ospvLookAheadDestination,destinfo,strlen((const char *)destinfo)+1);
 
567
 
 
568
            *ospvLookAheadDestProt = OSPPTokenInfoGetLookAheadDestProtocol(&(trans->TokenLookAheadInfo));
 
569
 
 
570
            *ospvLookAheadDestOSPStatus = OSPPTokenInfoGetLookAheadOSPVersion(&(trans->TokenLookAheadInfo));
 
571
 
 
572
            /*
 
573
             * Now, we need to overwrite the destiantionAlt 
 
574
             * for usage reporting with the look ahead address
 
575
             * First, delete the old list.
 
576
             */
 
577
            ospvAuthInd = &(trans)->AuthInd;
 
578
            while(!OSPPListEmpty(&((*ospvAuthInd)->ospmAuthIndDestinationAlternate)))
 
579
            {
 
580
                altinfo = (OSPTALTINFO *)OSPPListRemove(&((*ospvAuthInd)->ospmAuthIndDestinationAlternate));
 
581
                if(altinfo != OSPC_OSNULL)
 
582
                {
 
583
                    if(altinfo->ospmAltInfoType == ospeNetwork)
 
584
                    {
 
585
                        /*
 
586
                        * This node in the list corresponds to
 
587
                        * Network Id. Do not delete it.
 
588
                        */
 
589
                        altinfoToKeep = altinfo;
 
590
                    }
 
591
                    else
 
592
                    {
 
593
                        OSPM_FREE(altinfo);
 
594
                        altinfo = OSPC_OSNULL;
 
595
                    }
 
596
                }
 
597
            }
 
598
 
 
599
            OSPPListDelete(&((*ospvAuthInd)->ospmAuthIndDestinationAlternate));
 
600
 
 
601
           /*
 
602
            * Create a new list of destiantion Alt
 
603
            */
 
604
           OSPPListNew((OSPTLIST *)&(trans->AuthInd->ospmAuthIndDestinationAlternate));
 
605
 
 
606
           /*
 
607
           * Add back the AltInfo for networkId
 
608
           */
 
609
           if (altinfoToKeep)
 
610
           {
 
611
               OSPPListAppend(
 
612
                   (OSPTLIST *)&(trans->AuthInd->ospmAuthIndDestinationAlternate),
 
613
                   (void *)altinfoToKeep);
 
614
                   altinfoToKeep = NULL;
 
615
           }
 
616
 
 
617
           altinfo =
 
618
                OSPPAltInfoNew(OSPM_STRLEN((const char *)destinfo),
 
619
                (const unsigned char *)destinfo,
 
620
                ospeTransport);
 
621
 
 
622
           if(altinfo != OSPC_OSNULL)
 
623
           {
 
624
               OSPPListAppend(
 
625
                   (OSPTLIST *)&(trans->AuthInd->ospmAuthIndDestinationAlternate),
 
626
                   (void *)altinfo);
 
627
           }
 
628
 
 
629
        }
 
630
    } 
 
631
  
 
632
   return errorcode;
 
633
}
 
634
 
 
635
/*
 
636
 * OSPPTransactionGetDestNetworkId() :
 
637
 * Reports the destination Network Id as returned in
 
638
 * either the (1) AuthRsp or the (2) Token
 
639
 * returns OSPC_ERR_NO_ERROR if successful, else a 'Request out of Sequence' errorcode.
 
640
 */
 
641
int
 
642
OSPPTransactionGetDestNetworkId(OSPTTRANHANDLE  ospvTransaction,/* In - Transaction handle             */
 
643
 char*    ospvNetworkId) /* In - network specific information     */
 
644
{
 
645
 
 
646
    int         errorcode   = OSPC_ERR_NO_ERROR;
 
647
    OSPTTRANS   *trans      = OSPC_OSNULL;
 
648
    OSPTDEST *dest = OSPC_OSNULL;
 
649
    OSPTALTINFO *destination    = OSPC_OSNULL;
 
650
    OSPTBOOL found;
 
651
    unsigned char *destval=NULL;
 
652
 
 
653
    trans = OSPPTransactionGetContext(ospvTransaction, &errorcode);
 
654
 
 
655
    if (trans != (OSPTTRANS*) NULL) 
 
656
    {
 
657
        if (trans->AuthReq != OSPC_OSNULL)
 
658
        {
 
659
            /*
 
660
             * We are the source. 
 
661
             * Get the information from the destination 
 
662
             * structure.
 
663
             */
 
664
            dest = trans->CurrentDest;
 
665
            if (trans->State == OSPC_GET_DEST_SUCCESS)
 
666
            {
 
667
                if (dest == (OSPTDEST *)NULL)
 
668
                {
 
669
                   errorcode = OSPC_ERR_TRAN_DEST_NOT_FOUND;
 
670
                   OSPM_DBGERRORLOG(errorcode, "Could not find Destination for this Transaction \n");
 
671
                }
 
672
                else
 
673
                {
 
674
                   if (OSPPDestHasNetworkAddr(dest) &&
 
675
                       OSPPDestGetNetworkAddr(dest))
 
676
                   {
 
677
                       sprintf(ospvNetworkId,(const char *)OSPPDestGetNetworkAddr(dest));
 
678
                   }
 
679
                   else
 
680
                   {
 
681
                       errorcode = OSPC_ERR_TRAN_NO_NETWORK_ID_IN_DEST;
 
682
                       OSPM_DBGERRORLOG(errorcode, "Destination does not contain network Id \n");
 
683
                   }
 
684
                }
 
685
            }
 
686
            else
 
687
            {
 
688
                errorcode = OSPC_ERR_TRAN_REQ_OUT_OF_SEQ;
 
689
                OSPM_DBGERRORLOG(errorcode, "Called API Not In Sequence \n");
 
690
            }
 
691
        }
 
692
        else if (trans->AuthInd != OSPC_OSNULL)
 
693
        {
 
694
           /*
 
695
            * We are the destination.
 
696
            * Get the information from the AuthInd structure.
 
697
            */
 
698
           found = OSPC_FALSE;
 
699
           destination = (OSPTALTINFO *)OSPPAuthIndFirstDestinationAlt(trans->AuthInd);
 
700
           while(destination != OSPC_OSNULL)
 
701
           {
 
702
               if (destination->ospmAltInfoType == ospeNetwork)
 
703
               {
 
704
                   found = OSPC_TRUE;
 
705
                   destval = OSPPAuthIndGetDestinationAltValue(destination);
 
706
                   if (destval != NULL)
 
707
                   {
 
708
                       sprintf(ospvNetworkId,(const char *)destval);
 
709
                   }
 
710
                   else
 
711
                   {
 
712
                       errorcode = OSPC_ERR_TRAN_NO_NETWORK_ID_IN_DEST;
 
713
                       OSPM_DBGERRORLOG(errorcode, "Destination does not contain network Id \n");
 
714
                   }
 
715
                   break;
 
716
               }
 
717
               else
 
718
               {
 
719
                   destination = (OSPTALTINFO *)OSPPAuthIndNextDestinationAlt(trans->AuthInd, destination);
 
720
               }
 
721
           }
 
722
 
 
723
           if (found == OSPC_FALSE)
 
724
           {
 
725
               errorcode = OSPC_ERR_TRAN_NO_NETWORK_ID_IN_DEST;
 
726
               OSPM_DBGERRORLOG(errorcode, "Destination does not contain network Id \n");
 
727
           }
 
728
        }
 
729
        else
 
730
        {
 
731
            errorcode = OSPC_ERR_TRAN_INVALID_ENTRY;
 
732
            OSPM_DBGERRORLOG(errorcode, "No information available to process this report.");
 
733
        }
 
734
    }
 
735
 
 
736
    return errorcode;
 
737
}
 
738
 
 
739
/*
 
740
 * OSPPTransactionGetDestProtocol() :
 
741
 * Reports the Protocol Information at the Current destination. 
 
742
 * This API should be called right after Calling GetFirstDestination 
 
743
 * or should be called right after Calling GetNextDestination.
 
744
 * The parameters to the function are:
 
745
 *   ospvTransaction: handle of the transaction object.
 
746
 *   ospvDestinationProtocol: the memory location in which 
 
747
 *                            the Toolkit puts the Destination Protocol.
 
748
 *                            The returned value is one of the types 
 
749
 *                            defined in OSPE_DEST_PROT.
 
750
 * returns OSPC_ERR_NO_ERROR if successful, else a 'Request out of Sequence' errorcode.
 
751
 */
 
752
int
 
753
OSPPTransactionGetDestProtocol(
 
754
    OSPTTRANHANDLE  ospvTransaction,    /* In - Transaction handle             */
 
755
    OSPE_DEST_PROT *ospvDestinationProtocol)      /* Out - Destination Protocol Info     */
 
756
{
 
757
    int         errorcode   = OSPC_ERR_NO_ERROR;
 
758
    OSPTTRANS   *trans      = OSPC_OSNULL;
 
759
    OSPTDEST *dest = OSPC_OSNULL;
 
760
 
 
761
    trans = OSPPTransactionGetContext(ospvTransaction, &errorcode);
 
762
 
 
763
    if (trans != (OSPTTRANS*) NULL) 
 
764
    {
 
765
        dest = trans->CurrentDest;
 
766
        if (trans->State == OSPC_GET_DEST_SUCCESS)
 
767
        {
 
768
            if (dest == (OSPTDEST *)NULL)
 
769
            {
 
770
               errorcode = OSPC_ERR_TRAN_DEST_NOT_FOUND;
 
771
               OSPM_DBGERRORLOG(errorcode, "Could not find Destination for this Transaction \n");
 
772
            }
 
773
            else
 
774
            {
 
775
               *ospvDestinationProtocol = dest->ospmDestProtocol;
 
776
            }
 
777
        }
 
778
        else
 
779
        {
 
780
            errorcode = OSPC_ERR_TRAN_REQ_OUT_OF_SEQ;
 
781
            OSPM_DBGERRORLOG(errorcode, "Called API Not In Sequence \n");
 
782
        }
 
783
    }
 
784
    return errorcode;
 
785
}
 
786
 
 
787
 
 
788
/*
 
789
 * OSPPTransactionIsDestOSPEnabled() :
 
790
 * Reports whether the destination is OSP Enabled or Not. 
 
791
 * This API should be called right after Calling GetFirstDestination 
 
792
 * or should be called right after Calling GetNextDestination.
 
793
 * The parameters to the function are:
 
794
 *   ospvTransaction: handle of the transaction object.
 
795
 *   ospvDestinationOSPStatus: the memory location in which 
 
796
 *                            the Toolkit puts the destination OSP Status.
 
797
 *                            The returned value is one of the types 
 
798
 *                            defined in OSPE_DEST_OSP_ENABLED.
 
799
 * returns OSPC_ERR_NO_ERROR if successful, else a 'Request out of Sequence' errorcode.
 
800
 */
 
801
int
 
802
OSPPTransactionIsDestOSPEnabled(
 
803
    OSPTTRANHANDLE  ospvTransaction,    /* In - Transaction handle             */
 
804
    OSPE_DEST_OSP_ENABLED *ospvDestinationOSPStatus)      /* Out - Destination OSP Status     */
 
805
{
 
806
    int         errorcode   = OSPC_ERR_NO_ERROR;
 
807
    OSPTTRANS   *trans      = OSPC_OSNULL;
 
808
    OSPTDEST *dest = OSPC_OSNULL;
 
809
 
 
810
    trans = OSPPTransactionGetContext(ospvTransaction, &errorcode);
 
811
 
 
812
    if (trans != (OSPTTRANS*) NULL) 
 
813
    {
 
814
        dest = trans->CurrentDest;
 
815
        if (trans->State == OSPC_GET_DEST_SUCCESS)
 
816
        {
 
817
            if (dest == (OSPTDEST *)NULL)
 
818
            {
 
819
               errorcode = OSPC_ERR_TRAN_DEST_NOT_FOUND;
 
820
               OSPM_DBGERRORLOG(errorcode, "Could not find Destination for this Transaction \n");
 
821
            }
 
822
            else
 
823
            {
 
824
               *ospvDestinationOSPStatus = dest->ospmDestOSPVersion;
 
825
            }
 
826
        }
 
827
        else
 
828
        {
 
829
            errorcode = OSPC_ERR_TRAN_REQ_OUT_OF_SEQ;
 
830
            OSPM_DBGERRORLOG(errorcode, "Called API Not In Sequence \n");
 
831
        }
 
832
    }
 
833
    return errorcode;
 
834
}
 
835
 
 
836
 
 
837
/*
 
838
 * OSPPTransactionSetNetworkIds()
 
839
 *
 
840
 * Reports the network id for a particular transaction
 
841
 * This function can be used to report any network specific 
 
842
 * information to the server.
 
843
 * Reporting the termination group info is a good use of this interface
 
844
 * The parameters to the function are:
 
845
 *   ospvTransaction: handle of the transaction object.
 
846
 *   ospvNetworkId: the network specific information to be reported to the server.
 
847
 * returns OSPC_ERR_NO_ERROR if successful, else error code.
 
848
 */
 
849
int
 
850
OSPPTransactionSetNetworkIds(
 
851
    OSPTTRANHANDLE  ospvTransaction,    /* In - Transaction handle             */
 
852
    const char*    ospvSrcNetworkId,      /* In - Src network specific information     */
 
853
    const char*    ospvDstNetworkId)      /* In - Dst network specific information     */
 
854
{
 
855
    int         errorcode   = OSPC_ERR_NO_ERROR;
 
856
    OSPTTRANS   *trans      = OSPC_OSNULL;
 
857
    OSPTALTINFO  *altinfo = OSPC_OSNULL;
 
858
 
 
859
    if (((ospvSrcNetworkId == OSPC_OSNULL) && (ospvDstNetworkId == OSPC_OSNULL)) ||
 
860
        ((ospvSrcNetworkId && !(strcmp(ospvSrcNetworkId,""))) && 
 
861
        (ospvDstNetworkId && !(strcmp(ospvDstNetworkId,"")))))
 
862
    {
 
863
        errorcode = OSPC_ERR_TRAN_INVALID_ENTRY;
 
864
        OSPM_DBGERRORLOG(errorcode, "Invalid input for OSPPTransactionSetNetworkIds");
 
865
    }
 
866
 
 
867
    if (errorcode == OSPC_ERR_NO_ERROR)
 
868
    {
 
869
        trans = OSPPTransactionGetContext(ospvTransaction, &errorcode);
 
870
    }
 
871
 
 
872
    if ((trans != (OSPTTRANS*) NULL) && (errorcode == OSPC_ERR_NO_ERROR))
 
873
    {
 
874
        if (trans->State == OSPC_REPORT_USAGE_SUCCESS)
 
875
        {
 
876
            errorcode = OSPC_ERR_TRAN_REQ_OUT_OF_SEQ;
 
877
            OSPM_DBGERRORLOG(errorcode,"Calling OSPPTransactionSetNetworkId After Usage has been Reported");
 
878
        }
 
879
 
 
880
        if (errorcode == OSPC_ERR_NO_ERROR) 
 
881
        {
 
882
            if ((trans->SrcNetworkId != OSPC_OSNULL) || (trans->DstNetworkId != OSPC_OSNULL))
 
883
            {
 
884
                errorcode =OSPC_ERR_TRAN_DUPLICATE_REQUEST;
 
885
                OSPM_DBGERRORLOG(errorcode,"Duplicate Calls to OSPPTransactionSetNetworkIds");
 
886
            }
 
887
        }
 
888
 
 
889
        if (errorcode == OSPC_ERR_NO_ERROR) 
 
890
        {
 
891
            if ((trans->AuthReq == OSPC_OSNULL) && (trans->AuthInd == OSPC_OSNULL))
 
892
            {
 
893
                /* 
 
894
                 * Neither Authorization Request nor Validate Authorization has
 
895
                 * been called. We dont care if it is the source or destn in 
 
896
                 * this case. Just add the info to the transaction handler
 
897
                 */
 
898
                if (ospvSrcNetworkId != NULL)
 
899
                {
 
900
                    OSPM_MALLOC(trans->SrcNetworkId,char,strlen(ospvSrcNetworkId)+1);
 
901
                    if (trans->SrcNetworkId != OSPC_OSNULL)
 
902
                    {
 
903
                        OSPM_MEMCPY(trans->SrcNetworkId,ospvSrcNetworkId,strlen(ospvSrcNetworkId)+1);
 
904
                    }
 
905
                    else
 
906
                    {
 
907
                        errorcode = OSPC_ERR_TRAN_MALLOC_FAILED;
 
908
                    }
 
909
                }
 
910
 
 
911
                if (ospvDstNetworkId != NULL)
 
912
                {
 
913
                    OSPM_MALLOC(trans->DstNetworkId,char,strlen(ospvDstNetworkId)+1);
 
914
                    if (trans->DstNetworkId != OSPC_OSNULL)
 
915
                    {
 
916
                        OSPM_MEMCPY(trans->DstNetworkId,ospvDstNetworkId,strlen(ospvDstNetworkId)+1);
 
917
                    }
 
918
                    else
 
919
                    {
 
920
                        errorcode = OSPC_ERR_TRAN_MALLOC_FAILED;
 
921
                    }
 
922
                }
 
923
            }
 
924
            else
 
925
            if ((trans->AuthReq != OSPC_OSNULL) && (trans->AuthInd == OSPC_OSNULL))
 
926
            {
 
927
                /*
 
928
                 * End point is a source, however it is calling the 
 
929
                 * function out of sequence as it has already called 
 
930
                 * AuthReq, return an error
 
931
                 */
 
932
                errorcode = OSPC_ERR_TRAN_REQ_OUT_OF_SEQ;
 
933
                OSPM_DBGERRORLOG(errorcode,"Calling OSPPTransactionSetNetworkId After Authorization has been requested");
 
934
            }
 
935
            else
 
936
            {
 
937
                /* 
 
938
                 * For the other two cases in which AuthInd!= NULL
 
939
                 * End point is a destination, and Validate Authorization has already been called
 
940
                 * Since out of sequence calls are allowed on the destination, add this to the Authind req
 
941
                 * Check if there exists a list for destination alternates.If not then,
 
942
                 * Make a new list.
 
943
                 */
 
944
                if (trans->AuthInd->ospmAuthIndHasDestNetworkIdInToken == OSPC_FALSE)
 
945
                {
 
946
                    /*
 
947
                     * We will NOT overwrite the Network Id
 
948
                     * if specified in the token.
 
949
                     */
 
950
                    if (ospvDstNetworkId != NULL)
 
951
                    {
 
952
                        OSPM_MALLOC(trans->DstNetworkId,char,strlen(ospvDstNetworkId)+1);
 
953
                        if (trans->DstNetworkId != OSPC_OSNULL)
 
954
                        {
 
955
                            OSPM_MEMCPY(trans->DstNetworkId,ospvDstNetworkId,strlen(ospvDstNetworkId)+1);
 
956
                        }
 
957
                        else
 
958
                        {
 
959
                            errorcode = OSPC_ERR_TRAN_MALLOC_FAILED;
 
960
                        }
 
961
                    }
 
962
 
 
963
                    if ((errorcode == OSPC_ERR_NO_ERROR) && (ospvDstNetworkId != NULL))
 
964
                    {
 
965
                        if (trans->AuthInd->ospmAuthIndDestinationAlternate == OSPC_OSNULL) 
 
966
                        {
 
967
                            /*
 
968
                             * Make a new list
 
969
                             */
 
970
                            OSPPListNew((OSPTLIST *)&(trans->AuthInd->ospmAuthIndDestinationAlternate));
 
971
                        }
 
972
                        /*
 
973
                         * add to the list
 
974
                         */
 
975
                        altinfo = OSPPAltInfoNew(OSPM_STRLEN(ospvDstNetworkId),(const unsigned char *)ospvDstNetworkId,ospeNetwork);
 
976
                        if(altinfo != OSPC_OSNULL)
 
977
                        {
 
978
                            OSPPListAppend((OSPTLIST *)&(trans->AuthInd->ospmAuthIndDestinationAlternate),(void *)altinfo);
 
979
                            altinfo = OSPC_OSNULL;
 
980
                        }
 
981
                   } /* ospvDstNetworkId != NULL */
 
982
                }
 
983
 
 
984
                /* 
 
985
                 * End point is a destination, and Validate Authorization has already been called
 
986
                 * Since out of sequence calls are allowed on the destination, add this to the Authind req
 
987
                 * Check if there exists a list for source alternates.If not then,
 
988
                 * Make a new list.
 
989
                 */
 
990
                 if (ospvSrcNetworkId != NULL)
 
991
                 {
 
992
                     OSPM_MALLOC(trans->SrcNetworkId,char,strlen(ospvSrcNetworkId)+1);
 
993
                     if (trans->SrcNetworkId != OSPC_OSNULL)
 
994
                     {
 
995
                         OSPM_MEMCPY(trans->SrcNetworkId,ospvSrcNetworkId,strlen(ospvSrcNetworkId)+1);
 
996
                     }
 
997
                     else
 
998
                     {
 
999
                        errorcode = OSPC_ERR_TRAN_MALLOC_FAILED;
 
1000
                     }
 
1001
                }
 
1002
 
 
1003
                if ((errorcode == OSPC_ERR_NO_ERROR) && (ospvSrcNetworkId != NULL))
 
1004
                {
 
1005
                    if (trans->AuthInd->ospmAuthIndSourceAlternate == OSPC_OSNULL) 
 
1006
                    {
 
1007
                        /*
 
1008
                         * Make a new list
 
1009
                         */
 
1010
                        OSPPListNew((OSPTLIST *)&(trans->AuthInd->ospmAuthIndSourceAlternate));
 
1011
                    }
 
1012
                    /*
 
1013
                     * add to the list
 
1014
                     */
 
1015
                    altinfo = OSPPAltInfoNew(OSPM_STRLEN(ospvSrcNetworkId),(const unsigned char *)ospvSrcNetworkId,ospeNetwork);
 
1016
                    if(altinfo != OSPC_OSNULL)
 
1017
                    {
 
1018
                        OSPPListAppend((OSPTLIST *)&(trans->AuthInd->ospmAuthIndSourceAlternate),(void *)altinfo);
 
1019
                        altinfo = OSPC_OSNULL;
 
1020
                    }
 
1021
                } /* errorcode == OSPC_ERR_NO_ERROR */
 
1022
            }
 
1023
        } /* errorcode == OSPC_ERR_NO_ERROR */
 
1024
    } /* trans != (OSPTTRANS*) NULL */
 
1025
 
 
1026
    return errorcode;
 
1027
}
 
1028
 
 
1029
 
 
1030
 
 
1031
 
 
1032
 
 
1033
/*
 
1034
 * OSPPTransactionAccumulateOneWayDelay()
 
1035
 *
 
1036
 * Accumulates one way delay for transaction.
 
1037
 *
 
1038
 * The OSPPTransactionAccumulateOneWayDelay function accumulates one-way
 
1039
 * delay statistics for the call. It is used to report one way delay from
 
1040
 * the remote peer to the reporting system. This value may be calculated 
 
1041
 * by comparing the network time protocol (NTP) timestamp included in RTCP
 
1042
 * messages from the peer with the local NTP time in the  reporting system.
 
1043
 * Applications may call this function an unlimited number of times during
 
1044
 * a transaction, but only after the transaction has been authorised and 
 
1045
 * before its usage details are reported (i.e. after calling either the 
 
1046
 * function OSPPTransactionRequestAuthorisation or the function 
 
1047
 * OSPPTransactionValidateAuthorisation and before calling the function 
 
1048
 * OSPPTransactionReportUsage). Also, each call to this function must report
 
1049
 * statistics for a separate and distinct set of measurements. In other words,
 
1050
 * once OSPPTransactionAccumulateOneWayDelay is successfully called, the 
 
1051
 * application should discard (at least for subsequent calls to the function)
 
1052
 * the data and start calculating minimum, mean, variance measures anew.
 
1053
 * Applications may use this function to report a single sample, or they may
 
1054
 * report statistical measurements from a collection of samples. 
 
1055
 * The parameters to the function are:
 
1056
 *   ospvTransaction: handle of the transaction object.
 
1057
 *   ospvNumberOfSamples: the number of samples included in these statistics.
 
1058
 *   ospvMinimum: the minimum delay, in milliseconds, measured within the 
 
1059
 *      current set of samples. If the function call is used to report a single 
 
1060
 *      sample, this parameter should indicate that measurement, and it should 
 
1061
 *      be equal to the value of the ospvMean parameter.
 
1062
 *   ospvMean: the mean of the delay, in milliseconds, measured within the 
 
1063
 *      current set of samples. If the function call is used to report a single
 
1064
 *      sample, this parameter should indicate that measurement, and it should 
 
1065
 *      be equal to the value of the ospvMinimum parameter.
 
1066
 *   ospvVariance: the variance of the delay, in square milliseconds, measured
 
1067
 *      within the current set of samples. If the function call is used to 
 
1068
 *      report a single sample, this parameter should be zero.
 
1069
 * The SDK library is able to perform this function without network interaction,
 
1070
 * and, therefore, does not block for network input or output during its 
 
1071
 * execution.
 
1072
 *
 
1073
 * returns OSPC_ERR_NO_ERROR if successful, else error code.
 
1074
 */
 
1075
 
 
1076
int
 
1077
OSPPTransactionAccumulateOneWayDelay(
 
1078
    OSPTTRANHANDLE  ospvTransaction,    /* In - Transaction handle             */
 
1079
    unsigned        ospvNumberOfSamples,/* In - Number of samples included     */
 
1080
    unsigned        ospvMinimum,        /* In - Minimum delay in milliseconds  */
 
1081
    unsigned        ospvMean,           /* In - Mean of delay in milliseconds  */
 
1082
    float           ospvVariance)       /* In - Variance of delay in square ms */
 
1083
{
 
1084
    int         errorcode   = OSPC_ERR_NO_ERROR,
 
1085
                tnisnan     = OSPC_TRUE;
 
1086
    OSPTTRANS   *trans      = OSPC_OSNULL;
 
1087
    unsigned    currnumber  = 0;
 
1088
    double      topower     = 0,
 
1089
                mean        = 0,
 
1090
                intpart     = 0;
 
1091
    OSPTBOOL    accumallowed = OSPC_FALSE;
 
1092
    OSPTDELAY   tmpstats;
 
1093
 
 
1094
    OSPM_MEMSET(&tmpstats, 0, sizeof(OSPTDELAY));
 
1095
 
 
1096
    if((ospvNumberOfSamples == 0) ||
 
1097
        ((ospvNumberOfSamples == 1) &&
 
1098
        ((ospvMinimum != ospvMean) ||
 
1099
        (ospvVariance != 0))))
 
1100
    {
 
1101
        errorcode = OSPC_ERR_TRAN_INVALID_ENTRY;
 
1102
        OSPM_DBGERRORLOG(errorcode, "Invalid input for AccumulateOneWayDelay");
 
1103
    }
 
1104
 
 
1105
    if(errorcode == OSPC_ERR_NO_ERROR)
 
1106
    {
 
1107
        trans = OSPPTransactionGetContext(ospvTransaction, &errorcode);
 
1108
    }
 
1109
 
 
1110
    if(errorcode == OSPC_ERR_NO_ERROR)
 
1111
    {
 
1112
        OSPPTransactionGetAccumAllowed(trans, &accumallowed);
 
1113
        if(!accumallowed)
 
1114
        {
 
1115
            errorcode = OSPC_ERR_TRAN_ACCUMULATE_NOT_ALLOWED;
 
1116
            OSPM_DBGERRORLOG(errorcode, 
 
1117
                "AccumulateOneWay not allowed in this transaction state.");
 
1118
        }
 
1119
    }
 
1120
 
 
1121
    if(errorcode == OSPC_ERR_NO_ERROR)
 
1122
    {
 
1123
        /* if no statistics structure, make one */
 
1124
        if(trans->TNStatistics == OSPC_OSNULL)
 
1125
        {
 
1126
            trans->TNStatistics = OSPPStatisticsNew();
 
1127
 
 
1128
            if(trans->TNStatistics == OSPC_OSNULL)
 
1129
            {
 
1130
                errorcode = OSPC_ERR_TRAN_STATS_NEW_FAIL;
 
1131
                OSPM_DBGERRORLOG(errorcode, "New failed for stats struct.");
 
1132
            }
 
1133
        }
 
1134
 
 
1135
        if(errorcode == OSPC_ERR_NO_ERROR)
 
1136
        {
 
1137
            /* make temporary copy so we don't corrupt our accumulator */
 
1138
            OSPM_MEMCPY(&tmpstats, &(trans->TNStatistics->ospmOneWay), sizeof(OSPTDELAY));
 
1139
 
 
1140
            /* number of measurements */
 
1141
            currnumber = tmpstats.NumberOfSamples;
 
1142
 
 
1143
            tmpstats.NumberOfSamples += ospvNumberOfSamples;
 
1144
 
 
1145
            /* minimum measured value */
 
1146
            if(tmpstats.HasValue)
 
1147
            {
 
1148
                tmpstats.Minimum = tr_min(tmpstats.Minimum, ospvMinimum);
 
1149
            }
 
1150
            else
 
1151
            {
 
1152
                tmpstats.Minimum = ospvMinimum;
 
1153
            }
 
1154
 
 
1155
            /* sample mean - have to cast NumberOfSamples to a float to get some precision
 
1156
             * on the mean */
 
1157
 
 
1158
            mean = ((tmpstats.Mean * currnumber) + (ospvMean * ospvNumberOfSamples)) / 
 
1159
                (float)tmpstats.NumberOfSamples;
 
1160
 
 
1161
            /* make sure we don't have overflow */
 
1162
            OSPM_ISNAN(mean, tnisnan);
 
1163
 
 
1164
            if(tnisnan)
 
1165
            {
 
1166
                errorcode = OSPC_ERR_TRAN_INVALID_CALC;
 
1167
            }
 
1168
            else
 
1169
            {
 
1170
                /* if remainder is >= .5, round up, else round down */
 
1171
                if(OSPM_MODF(mean, &intpart) >= .5)
 
1172
                {
 
1173
                    tmpstats.Mean = (unsigned)OSPM_CEIL(mean);
 
1174
                }
 
1175
                else
 
1176
                {
 
1177
                    tmpstats.Mean = (unsigned)OSPM_FLOOR(mean);
 
1178
                }
 
1179
 
 
1180
                /* sum of squares of samples */
 
1181
                OSPM_POW((double)ospvMean, 2, topower);
 
1182
                if (topower != OSPC_ERR_POW)
 
1183
                {
 
1184
                    tmpstats.SumOfSampSquares = tmpstats.SumOfSampSquares + 
 
1185
                        ((ospvNumberOfSamples - 1) * (double)ospvVariance) + 
 
1186
                        (ospvNumberOfSamples * topower);
 
1187
                    topower = 0;
 
1188
                }
 
1189
                else
 
1190
                {
 
1191
                    errorcode = (int)topower;
 
1192
                }
 
1193
            }
 
1194
 
 
1195
            if(errorcode == OSPC_ERR_NO_ERROR)
 
1196
            {
 
1197
                /* variance */
 
1198
                OSPM_POW((double)tmpstats.Mean, 2, topower);
 
1199
                if(topower != OSPC_ERR_POW)
 
1200
                {
 
1201
                    tmpstats.Variance = (float)(tmpstats.SumOfSampSquares - 
 
1202
                        (tmpstats.NumberOfSamples * topower)) / 
 
1203
                        (tmpstats.NumberOfSamples - 1);
 
1204
                    topower = 0;
 
1205
                }
 
1206
                else
 
1207
                {
 
1208
                    errorcode = (int)topower;
 
1209
                }
 
1210
            }
 
1211
 
 
1212
            /* Only set state if we have actually done something, otherwise no
 
1213
             * change in state.
 
1214
             */
 
1215
            if(errorcode == OSPC_ERR_NO_ERROR)
 
1216
            {
 
1217
                tmpstats.HasValue = OSPC_TRUE;
 
1218
                trans->TNStatistics->ospmHasOneWay = OSPC_TRUE;
 
1219
                /* now copy values back to permanent accumulator */
 
1220
                OSPM_MEMCPY(&(trans->TNStatistics->ospmOneWay), 
 
1221
                    &(tmpstats), sizeof(OSPTDELAY));
 
1222
                OSPPTransactionSetState(trans, OSPC_ACCUMULATE_SUCCESS);
 
1223
            }
 
1224
            else
 
1225
            {
 
1226
                OSPPTransactionSetState(trans, OSPC_ACCUMULATE_FAIL);    
 
1227
            }
 
1228
        }
 
1229
    }
 
1230
 
 
1231
    return errorcode;
 
1232
}
 
1233
 
 
1234
 
 
1235
/*
 
1236
 * OSPPTransactionAccumulateRoundTripDelay()
 
1237
 *
 
1238
 * Accumulates round trip delay for transaction.
 
1239
 * 
 
1240
 * The OSPPTransactionAccumulateRoundTripDelay function accumulates round trip 
 
1241
 * delay statistics for the call. These measurements can be made using, for 
 
1242
 * example, H.245 round trip delay requests during the call. Applications may 
 
1243
 * call this function an unlimited number of times during a transaction, but 
 
1244
 * only after the transaction has been authorised and before its usage details 
 
1245
 * are reported (i.e. after calling either the function 
 
1246
 * OSPPTransactionRequestAuthorisation or the function 
 
1247
 * OSPPTransactionValidateAuthorisation and before calling the function 
 
1248
 * OSPPTransactionReportUsage). Also, each call to this function must report 
 
1249
 * statistics for a separate and distinct set of measurements. In other words, 
 
1250
 * once OSPPTransactionAccumulateRoundTripDelay is successfully called, 
 
1251
 * the application should discard (at least for subsequent calls to the function)
 
1252
 * the data and start calculating minimum, mean, variance measures anew.
 
1253
 * Applications may use this function to report a single sample, or they may 
 
1254
 * report statistical measurements from a collection of samples. 
 
1255
 * The parameters to the function are:
 
1256
 *   ospvTransaction: handle of the transaction object.
 
1257
 *   ospvNumberOfSamples: the number of samples included in these statistics.
 
1258
 *   ospvMinimum: the minimum delay, in milliseconds, measured within the current
 
1259
 *                set of samples. If the function call is used to report a single
 
1260
 *                sample, this parameter should indicate that measurement, and it
 
1261
 *                should be equal to the value of the ospvMean parameter.
 
1262
 *   ospvMean: the mean of the delay, in milliseconds, measured within the 
 
1263
 *             current set of samples. If the function call is used to report a 
 
1264
 *             single sample, this parameter should indicate that measurement, 
 
1265
 *             and it should be equal to the value of the ospvMinimum parameter.
 
1266
 *   ospvVariance: the variance of the delay, in square milliseconds, measured 
 
1267
 *                 within the current set of samples. If the function call is 
 
1268
 *                 used to report a single sample, this parameter should be zero.
 
1269
 * The SDK library is able to perform this function without network interaction,
 
1270
 * and, therefore, does not block for network input or output during its 
 
1271
 * execution.
 
1272
 *
 
1273
 * returns OSPC_ERR_NO_ERROR if successful, else error code.
 
1274
 */
 
1275
 
 
1276
int
 
1277
OSPPTransactionAccumulateRoundTripDelay(
 
1278
    OSPTTRANHANDLE ospvTransaction,    /* In - Transaction handle */
 
1279
    unsigned       ospvNumberOfSamples,/* In - Number of samples included */
 
1280
    unsigned       ospvMinimum,        /* In - Minimum delay in milliseconds */
 
1281
    unsigned       ospvMean,           /* In - Mean of delay in milliseconds */
 
1282
    float          ospvVariance)       /* In - Variance of delay in square 
 
1283
                           milliseconds */
 
1284
{
 
1285
    int         errorcode   = OSPC_ERR_NO_ERROR,
 
1286
                tnisnan       = OSPC_TRUE;
 
1287
    OSPTTRANS   *trans      = OSPC_OSNULL;
 
1288
    unsigned    currnumber  = 0;
 
1289
    double      topower     = 0,
 
1290
                mean        = 0,
 
1291
                intpart     = 0;
 
1292
    OSPTBOOL    accumallowed = OSPC_FALSE;
 
1293
    OSPTDELAY   tmpstats;
 
1294
 
 
1295
    OSPM_MEMSET(&tmpstats, 0, sizeof(OSPTDELAY));
 
1296
 
 
1297
    if((ospvNumberOfSamples == 0) ||
 
1298
        ((ospvNumberOfSamples == 1) &&
 
1299
        ((ospvMinimum != ospvMean) ||
 
1300
        (ospvVariance != 0))))
 
1301
    {
 
1302
        errorcode = OSPC_ERR_TRAN_INVALID_ENTRY;
 
1303
        OSPM_DBGERRORLOG(errorcode, "Invalid input for AccumulateOneWayDelay");
 
1304
    }
 
1305
 
 
1306
    if(errorcode == OSPC_ERR_NO_ERROR)
 
1307
    {
 
1308
        trans = OSPPTransactionGetContext(ospvTransaction, &errorcode);
 
1309
    }
 
1310
 
 
1311
    if(errorcode == OSPC_ERR_NO_ERROR)
 
1312
    {
 
1313
        OSPPTransactionGetAccumAllowed(trans, &accumallowed);
 
1314
        if(!accumallowed)
 
1315
        {
 
1316
            errorcode = OSPC_ERR_TRAN_ACCUMULATE_NOT_ALLOWED;
 
1317
            OSPM_DBGERRORLOG(errorcode, 
 
1318
                "AccumulateRoundTrip not allowed in this transaction state.");
 
1319
        }
 
1320
    }
 
1321
 
 
1322
    if(errorcode == OSPC_ERR_NO_ERROR)
 
1323
    {
 
1324
        /* if no statistics structure, make one */
 
1325
        if(trans->TNStatistics == OSPC_OSNULL)
 
1326
        {
 
1327
            trans->TNStatistics = OSPPStatisticsNew();
 
1328
 
 
1329
            if(trans->TNStatistics == OSPC_OSNULL)
 
1330
            {
 
1331
                errorcode = OSPC_ERR_TRAN_STATS_NEW_FAIL;
 
1332
                OSPM_DBGERRORLOG(errorcode, "New failed for stats struct.");
 
1333
            }
 
1334
        }
 
1335
 
 
1336
        if(errorcode == OSPC_ERR_NO_ERROR)
 
1337
        {
 
1338
            /* make temporary copy so we don't corrupt our accumulator */
 
1339
            OSPM_MEMCPY(&tmpstats, 
 
1340
                                &(trans->TNStatistics->ospmRoundTrip), 
 
1341
                                sizeof(OSPTDELAY));
 
1342
 
 
1343
            /* number of measurements */
 
1344
            currnumber = tmpstats.NumberOfSamples;
 
1345
 
 
1346
            tmpstats.NumberOfSamples += ospvNumberOfSamples;
 
1347
 
 
1348
            /* minimum measured value */
 
1349
            if(tmpstats.HasValue)
 
1350
            {
 
1351
                tmpstats.Minimum = tr_min(tmpstats.Minimum, ospvMinimum);
 
1352
            }
 
1353
            else
 
1354
            {
 
1355
                tmpstats.Minimum = ospvMinimum;
 
1356
            }
 
1357
 
 
1358
            /* sample mean - have to cast NumberOfSamples to a float to get some precision
 
1359
             * on the mean */
 
1360
            mean = ((tmpstats.Mean * currnumber) + (ospvMean * ospvNumberOfSamples)) / 
 
1361
                (float)tmpstats.NumberOfSamples;
 
1362
 
 
1363
            OSPM_ISNAN(tmpstats.Mean, tnisnan);
 
1364
 
 
1365
            if(tnisnan)
 
1366
            {
 
1367
                errorcode = OSPC_ERR_TRAN_INVALID_CALC;
 
1368
            }
 
1369
            else
 
1370
            {
 
1371
                /* if remainder is >= .5, round up, else round down */
 
1372
                if(OSPM_MODF(mean, &intpart) >= .5)
 
1373
                {
 
1374
                    tmpstats.Mean = (unsigned)OSPM_CEIL(mean);
 
1375
                }
 
1376
                else
 
1377
                {
 
1378
                    tmpstats.Mean = (unsigned)OSPM_FLOOR(mean);
 
1379
                }
 
1380
 
 
1381
                /* sum of squares of samples */
 
1382
                OSPM_POW((double)ospvMean, 2, topower);
 
1383
                if(topower != OSPC_ERR_POW)
 
1384
                {
 
1385
                    tmpstats.SumOfSampSquares = tmpstats.SumOfSampSquares + 
 
1386
                        ((ospvNumberOfSamples - 1) * (ospvVariance)) + 
 
1387
                        ((ospvNumberOfSamples) * (float)topower);
 
1388
                    topower = 0;
 
1389
                }
 
1390
                else
 
1391
                {
 
1392
                    errorcode = (int)topower;
 
1393
                }
 
1394
            }
 
1395
 
 
1396
            if(errorcode == OSPC_ERR_NO_ERROR)
 
1397
            {
 
1398
                /* variance */
 
1399
                OSPM_POW((double)  tmpstats.Mean, 2, topower);
 
1400
                if(topower != OSPC_ERR_POW)
 
1401
                { 
 
1402
                    tmpstats.Variance = (float)(tmpstats.SumOfSampSquares - 
 
1403
                        (tmpstats.NumberOfSamples * topower)) / 
 
1404
                        (tmpstats.NumberOfSamples - 1);
 
1405
                    topower = 0;
 
1406
                }
 
1407
                else
 
1408
                {
 
1409
                    errorcode = (int)topower;
 
1410
                }
 
1411
            }
 
1412
 
 
1413
            /* Only set state if we have actually done something, otherwise no
 
1414
             * change in state.
 
1415
             */
 
1416
            if(errorcode == OSPC_ERR_NO_ERROR)
 
1417
            {
 
1418
                tmpstats.HasValue = OSPC_TRUE;
 
1419
 
 
1420
                trans->TNStatistics->ospmHasRoundTrip = OSPC_TRUE;
 
1421
                /* now copy values back to permanent accumulator */
 
1422
                OSPM_MEMCPY(&(trans->TNStatistics->ospmRoundTrip), 
 
1423
                    &(tmpstats), sizeof(OSPTDELAY));
 
1424
                OSPPTransactionSetState(trans, OSPC_ACCUMULATE_SUCCESS);
 
1425
            }
 
1426
            else
 
1427
            {
 
1428
                OSPPTransactionSetState(trans, OSPC_ACCUMULATE_FAIL);
 
1429
            }
 
1430
        }
 
1431
    }
 
1432
 
 
1433
    return errorcode;
 
1434
}
 
1435
 
 
1436
/*
 
1437
 * OSPPTransactionDelete()
 
1438
 *
 
1439
 * Delete the transaction in the transaction collections associated with this 
 
1440
 * transaction handle.
 
1441
 *
 
1442
 * The OSPPTransactionDelete function destroys the ospvTransaction object and 
 
1443
 * releases the resources it consumes. Once this function is called, the 
 
1444
 * application is prohibited from subsequent interaction with the object. 
 
1445
 * (Attempts to do so are refused with an appropriate error code.) The library 
 
1446
 * may continue to use the transaction's resources, however, until it has 
 
1447
 * concluded communication regarding this transaction with the settlement 
 
1448
 * server. An application can ensure the release of all resources 
 
1449
 * only by specifying a time limit in a call to OSPPProviderDelete.
 
1450
 *
 
1451
 * returns OSPC_ERR_NO_ERROR if successful, or error code.
 
1452
 */
 
1453
 
 
1454
int
 
1455
OSPPTransactionDelete(
 
1456
    OSPTTRANHANDLE  ospvTransaction)    /* In - Transaction handle. */
 
1457
{
 
1458
    int         errorcode       = OSPC_ERR_NO_ERROR;
 
1459
    OSPTTRANS   *trans          = OSPC_OSNULL;
 
1460
    OSPTBOOL    deleteallowed   = OSPC_FALSE;
 
1461
 
 
1462
    OSPTTRANCOLLECTION  *trancoll = NULL;
 
1463
    OSPTCOLLECTIONINDEX tranindex;
 
1464
 
 
1465
    trans = OSPPTransactionGetContext(ospvTransaction, &errorcode);
 
1466
 
 
1467
    if (errorcode == OSPC_ERR_NO_ERROR) 
 
1468
    {
 
1469
        OSPPTransactionGetDeleteAllowed(trans, &deleteallowed);
 
1470
 
 
1471
        if (deleteallowed == OSPC_TRUE) 
 
1472
        {
 
1473
            OSPPTransactionDeleteRequest(trans);
 
1474
 
 
1475
            OSPPTransactionDeleteResponse(trans);
 
1476
 
 
1477
            OSPPTransactionDeleteAuthInd(trans);
 
1478
 
 
1479
            OSPPTransactionDeleteAuthCnf(trans);
 
1480
 
 
1481
            OSPPTransactionDeleteUsageInd(trans);
 
1482
 
 
1483
            OSPPTransactionDeleteUsageCnf(trans);
 
1484
 
 
1485
            OSPPTransactionDeleteStatistics(trans);
 
1486
 
 
1487
            OSPPTransactionDeleteCapCnf(trans);
 
1488
 
 
1489
            errorcode = OSPPProviderGetTransactionCollection(trans->Provider, &trancoll);
 
1490
 
 
1491
            if (errorcode == OSPC_ERR_NO_ERROR) 
 
1492
            {
 
1493
                tranindex.Index = OSPM_GET_TRANSACTION_INDEX(ospvTransaction);
 
1494
                OSPPTransactionCollectionRemoveItem(trancoll, tranindex);
 
1495
            }
 
1496
 
 
1497
            if (trans->SrcNetworkId != (char *)OSPC_OSNULL)
 
1498
            {
 
1499
                OSPM_FREE(trans->SrcNetworkId);
 
1500
            }
 
1501
 
 
1502
            if (trans->DstNetworkId != (char *)OSPC_OSNULL)
 
1503
            {
 
1504
                OSPM_FREE(trans->DstNetworkId);
 
1505
            }
 
1506
 
 
1507
            if(trans != (OSPTTRANS *)NULL)
 
1508
            {
 
1509
                OSPM_FREE(trans);
 
1510
                trans = NULL;
 
1511
            }
 
1512
        }
 
1513
        else 
 
1514
        {
 
1515
            errorcode = OSPC_ERR_TRAN_DELETE_NOT_ALLOWED;
 
1516
            OSPM_DBGERRORLOG(errorcode, "delete not allowed in this trans state");
 
1517
        }
 
1518
    }
 
1519
 
 
1520
    return errorcode;
 
1521
}
 
1522
 
 
1523
/*
 
1524
 * OSPPTransactionGetFirstDestination()
 
1525
 *
 
1526
 * The OSPPTransactionGetFirstDestination function returns the identity of the
 
1527
 * first authorised destination for a call. The SDK library obtains this 
 
1528
 * information during the execution of the OSPPTransactionRequestAuthorisation 
 
1529
 * function. The parameters to this function consist of the following:
 
1530
 *  ospvTransaction: handle of the transaction object.
 
1531
 *  ospvSizeOfTimestamp: size of the character strings (including the 
 
1532
 *      terminating '\0') in which the function should store validity times 
 
1533
 *      for the destination. If this value is zero, then validity times are not
 
1534
 *      returned. If this size is non-zero but not large enough to store either
 
1535
 *      validity time, then an error is indicated and no destination is 
 
1536
 *      returned.
 
1537
 *  ospvValidAfter: character string in which to store the earliest time for 
 
1538
 *      which the call is authorised to the destination. The format for the 
 
1539
 *      string is the same as indicated in the OSP protocol specification. 
 
1540
 *      For example, 3:03 P.M. on May 2, 1997, Eastern Daylight Time in the 
 
1541
 *          United States is represented as "1997-05-02T19:03:00Z".
 
1542
 *  ospvValidUntil: character string in which to store the latest time for 
 
1543
 *      which the call is authorised to the destination. The format for the 
 
1544
 *      string is the same as for the ospvValidAfter parameter.
 
1545
 *  ospvTimeLimit: pointer to a variable in which to place the number of 
 
1546
 *      seconds for which the call is initially authorised. A value of zero 
 
1547
 *      indicates that no limit exists. Note that the initial time limit may be
 
1548
 *      extended during the call by either party.
 
1549
 *  ospvSizeOfCallId: pointer to a variable which, on input, contains the size 
 
1550
 *      of the memory buffer in which the function should place the H.323 call 
 
1551
 *      identifier for the destination. If the value is not large enough to 
 
1552
 *      accommodate the call identifier, then an error is indicated and no 
 
1553
 *      destination is returned. On output this variable is updated to indicate
 
1554
 *      the actual size of the call identifier.
 
1555
 *  ospvCallId: memory location in which to store the H.323 call identifier 
 
1556
 *      for the destination. The call identifier returned here is the same 
 
1557
 *      format as the call identifier passed to the 
 
1558
 *      OSPPTransactionRequestAuthorisation function.
 
1559
 *  ospvSizeOfCalledNumber: size of the character string (including the 
 
1560
 *      terminating '\0') in which the function should store the called number.
 
1561
 *      If the value is not large enough to accommodate the called number, then
 
1562
 *      an error is indicated and no destination is returned.
 
1563
 *  ospvCalledNumber: character string in which to store the called number. In
 
1564
 *      general, the called number returned here will be the same as the called
 
1565
 *      number that the application passed to the 
 
1566
 *      OSPPTransactionRequestAuthorisation function; however, the settlement 
 
1567
 *      service provider may perform a number translation on the called number,
 
1568
 *      resulting in a new called number that should be signaled to the peer 
 
1569
 *      gateway.
 
1570
 *  ospvSizeOfDestination: size of the character string (including the 
 
1571
 *      terminating '\0') in which the function should store the destination
 
1572
 *      information. If the value is not large enough to accommodate the 
 
1573
 *      destination, then an error is indicated and no destination is returned.
 
1574
 *  ospvDestination: character string in which to store the identity of the 
 
1575
 *      destination. The value is expressed as either a DNS name or an IP 
 
1576
 *      address enclosed in square brackets, followed by an optional colon and
 
1577
 *      TCP port number. Examples of valid destinations include 
 
1578
 *                      "gateway1.carrier.com" and "[172.16.1.2]:112".
 
1579
 *  ospvSizeOfDestinationDevice: size of the character string (including the 
 
1580
 *      terminating '\0') in which the function should store the destination 
 
1581
 *      device identity. If the value is not large enough to accommodate the 
 
1582
 *      destination device identity, then an error is indicated and no 
 
1583
 *      destination is returned.
 
1584
 *  ospvDestinationDevice: character string in which to store the identity of 
 
1585
 *      the destination device. The value is expressed as either a DNS name or an IP 
 
1586
 *      address enclosed in square brackets, followed by an optional colon and
 
1587
 *      TCP port number. Examples of valid destinations include 
 
1588
 *                      "gateway1.carrier.com" and "[172.16.1.2]:112".
 
1589
 *  ospvSizeOfToken: pointer to a variable which, on input, contains the size 
 
1590
 *      of the memory buffer in which the function should store the 
 
1591
 *      authorisation token for the destination. If the value is not large 
 
1592
 *      enough to accommodate the token, then an error is indicated and no 
 
1593
 *      destination is returned. On output this variable is updated to indicate
 
1594
 *      the actual size of the authorisation token.
 
1595
 *  ospvToken: memory location in which to store the authorisation token for 
 
1596
 *      this destination. In general, tokens are opaque, binary objects.
 
1597
 * The SDK library is able to perform this function without network 
 
1598
 * interaction, and, therefore, does not block for network input or output 
 
1599
 * during its execution.
 
1600
 * The function returns an error code or zero (if the operation was successful).
 
1601
 * Specific error codes and their meanings can be found in the osperrno.h file.
 
1602
 */
 
1603
 
 
1604
int
 
1605
OSPPTransactionGetFirstDestination(
 
1606
    OSPTTRANHANDLE  ospvTransaction,        /* In  - Transaction handle */
 
1607
    unsigned        ospvSizeOfTimestamp,    /* In  - Max size for timestamp string */
 
1608
    char            *ospvValidAfter,        /* Out - Valid After time in string format */
 
1609
    char            *ospvValidUntil,        /* Out - Valid Until time in string format */
 
1610
    unsigned        *ospvTimeLimit,         /* Out - Number of seconds call is authorised for */
 
1611
    unsigned        *ospvSizeOfCallId,      /* In/Out - Max size for CallId string Actual size of CallId string */
 
1612
    void            *ospvCallId,            /* Out - Call Id string */
 
1613
    unsigned        ospvSizeOfCalledNumber, /* In - Max size of called number */
 
1614
    char            *ospvCalledNumber,      /* Out - Called number string */
 
1615
    unsigned        ospvSizeOfCallingNumber, /* In - Max size of calling number */
 
1616
    char            *ospvCallingNumber,      /* Out - Calling number string */
 
1617
    unsigned        ospvSizeOfDestination,  /* In - Max size of destination string */
 
1618
    char            *ospvDestination,       /* Out - Destination string */
 
1619
    unsigned        ospvSizeOfDestinationDevice,    /* In - Max size of dest device string */
 
1620
    char            *ospvDestinationDevice,         /* Out - Dest device string */
 
1621
    unsigned        *ospvSizeOfToken,       /* In/Out - Max size of token string Actual size of token string */ 
 
1622
    void            *ospvToken)             /* Out - Token string */
 
1623
{
 
1624
    int           errorcode   = OSPC_ERR_NO_ERROR;
 
1625
    OSPTTRANS     *trans      = OSPC_OSNULL;
 
1626
 
 
1627
    trans = OSPPTransactionGetContext(ospvTransaction, &errorcode);
 
1628
 
 
1629
    if((trans != (OSPTTRANS *)NULL) &&
 
1630
        (errorcode == OSPC_ERR_NO_ERROR))
 
1631
    {
 
1632
        errorcode = OSPPTransactionGetDestAllowed(trans);
 
1633
    }
 
1634
 
 
1635
    if (errorcode == OSPC_ERR_NO_ERROR)
 
1636
    {
 
1637
        /* 
 
1638
         * Make sure we have a response
 
1639
         */
 
1640
        if (trans->AuthRsp == (OSPTAUTHRSP *)NULL)
 
1641
            errorcode = OSPC_ERR_TRAN_RESPONSE_NOT_FOUND;
 
1642
 
 
1643
        if(errorcode == OSPC_ERR_NO_ERROR)
 
1644
        { 
 
1645
            /*
 
1646
             * if no errors have occurred, get the destination information
 
1647
             */
 
1648
 
 
1649
            if ((errorcode == OSPC_ERR_NO_ERROR) && 
 
1650
                OSPPAuthRspHasDest(trans->AuthRsp) == OSPC_FALSE)
 
1651
            {
 
1652
                errorcode = OSPC_ERR_TRAN_DEST_INVALID;
 
1653
                OSPM_DBGERRORLOG(errorcode, "destination not found");
 
1654
            }
 
1655
            else
 
1656
            {
 
1657
                errorcode = OSPPTransactionGetDestination(trans,
 
1658
                    OSPC_FAIL_NONE,
 
1659
                    ospvSizeOfTimestamp,
 
1660
                    ospvValidAfter,
 
1661
                    ospvValidUntil,
 
1662
                    ospvTimeLimit,
 
1663
                    ospvSizeOfCallId,
 
1664
                    ospvCallId,
 
1665
                    ospvSizeOfCalledNumber,
 
1666
                    ospvCalledNumber,
 
1667
                    ospvSizeOfCallingNumber,
 
1668
                    ospvCallingNumber,
 
1669
                    ospvSizeOfDestination,
 
1670
                    ospvDestination,
 
1671
                    ospvSizeOfDestinationDevice,
 
1672
                    ospvDestinationDevice,
 
1673
                    ospvSizeOfToken,
 
1674
                    ospvToken);
 
1675
            }
 
1676
 
 
1677
            /* Set transaction state */
 
1678
            if (errorcode == OSPC_ERR_NO_ERROR)
 
1679
            {
 
1680
                OSPPTransactionSetState(trans, OSPC_GET_DEST_SUCCESS);
 
1681
                trans->HasGetDestSucceeded = OSPC_TRUE;
 
1682
            }
 
1683
            else
 
1684
            {
 
1685
                OSPPTransactionSetState(trans, OSPC_GET_DEST_FAIL);
 
1686
            }
 
1687
 
 
1688
        }
 
1689
    }
 
1690
 
 
1691
    return errorcode;
 
1692
}
 
1693
 
 
1694
/*
 
1695
 * OSPPTransactionGetNextDestination()
 
1696
 *
 
1697
 * The OSPPTransactionGetNextDestination function returns the identity of the 
 
1698
 * next authorised destination for a call. Applications may use this function 
 
1699
 * when attempts to use previously identified authorised destinations (starting
 
1700
 * with the first destination) fail. The SDK library obtains the necessary 
 
1701
 * information for this function during its execution of the 
 
1702
 * OSPPTransactionRequestAuthorisation. The parameters to this function consist
 
1703
 * of the following:
 
1704
 *  ospvTransaction: handle of the transaction object.
 
1705
 *  ospvFailureReason: the reason that attempts to use the previously 
 
1706
 *      identified destination failed; values for this parameter are listed in
 
1707
 *      the ospfail.h file.
 
1708
 *  ospvSizeOfTimestamp: size of the character strings (including the 
 
1709
 *      terminating '\0') in which the function should store validity times for
 
1710
 *      the destination. If this value is zero, then validity times are not 
 
1711
 *      returned. If this size is non-zero but not large enough to store either
 
1712
 *      validity time, then an error is indicated and no destination is 
 
1713
 *      returned.
 
1714
 *  ospvValidAfter: character string in which to store the earliest time for 
 
1715
 *      which the call is authorised to the destination. The format for the 
 
1716
 *      string is the same as indicated in the OSP protocol specification. 
 
1717
 *      For example, 3:03 P.M. on May 2, 1997, Eastern Daylight Time in the 
 
1718
 *          United States is represented as "1997-05-02T19:03:00Z".
 
1719
 *  ospvValidUntil: character string in which to store the latest time for 
 
1720
 *      which the call is authorised to the destination. The format for the 
 
1721
 *      string is the same as for the ospvValidAfter parameter.
 
1722
 *  ospvTimeLimit: pointer to a variable in which to place the number of 
 
1723
 *      seconds for which the call is initially authorised. A value of zero 
 
1724
 *      indicates that no limit exists. Note that the initial time limit may 
 
1725
 *      be extended during the call by either party.
 
1726
 *  ospvSizeOfCallId: pointer to a variable which, on input, contains the size 
 
1727
 *      of the memory buffer in which the function should place the H.323 call 
 
1728
 *      identifier for the destination. If the value is not large enough to 
 
1729
 *      accommodate the call identifier, then an error is indicated and no 
 
1730
 *      destination is returned. On output this variable is updated to indicate
 
1731
 *      the actual size of the call identifier.
 
1732
 *  ospvCallId: memory location in which to store the H.323 call identifier for
 
1733
 *      the destination. The call identifier returned here is the same format 
 
1734
 *      as the call identifier passed to the OSPPTransactionRequestAuthorisation
 
1735
 *      function.
 
1736
 *  ospvSizeOfCalledNumber: size of the character string (including the 
 
1737
 *      terminating '\0') in which the function should store the called number.
 
1738
 *      If the value is not large enough to accommodate the called number, then
 
1739
 *      an error is indicated and no destination is returned.
 
1740
 *  ospvCalledNumber: character string in which to store the called number. In 
 
1741
 *      general, the called number returned here will be the same as the called
 
1742
 *      number that the application passed to the 
 
1743
 *      OSPPTransactionRequestAuthorisation function; however, the settlement 
 
1744
 *      service provider may perform a number translation on the called number,
 
1745
 *      resulting in a new called number that should be signaled to the peer 
 
1746
 *      gateway.
 
1747
 *  ospvSizeOfDestination: size of the character string (including the 
 
1748
 *      terminating '\0') in which the function should store the destination 
 
1749
 *      information. If the value is not large enough to accommodate the destination, 
 
1750
 *      then an error is indicated and no destination is returned.
 
1751
 *  ospvDestination: character string in which to store the identity of the 
 
1752
 *      destination. The value is expressed as either a DNS name or an IP 
 
1753
 *      address enclosed in square brackets, followed by an optional colon 
 
1754
 *      and TCP port number. 
 
1755
 *          Examples of valid destinations include "gateway1.carrier.com" and 
 
1756
 *                                                          "[172.16.1.2]:112".
 
1757
 *  ospvSizeOfDestinationDevice: size of the character string (including the 
 
1758
 *      terminating '\0') in which the function should store the destination 
 
1759
 *      device identity. If the value is not large enough to accommodate the 
 
1760
 *      destination device identity, then an error is indicated and no 
 
1761
 *      destination is returned.
 
1762
 *  ospvDestinationDevice: character string in which to store the identity 
 
1763
 *      of the destination device. The value is expressed as either a DNS name or an IP 
 
1764
 *      address enclosed in square brackets, followed by an optional colon 
 
1765
 *      and TCP port number. 
 
1766
 *          Examples of valid destinations include "gateway1.carrier.com" and 
 
1767
 *                                                          "[172.16.1.2]:112".
 
1768
 *  ospvSizeOfToken: pointer to a variable which, on input, contains the size 
 
1769
 *      of the memory buffer in which the function should store the 
 
1770
 *      authorisation token for the destination. If the value is not large 
 
1771
 *      enough to accommodate the token, then an error is indicated and no 
 
1772
 *      destination is returned. On output this variable is updated to indicate
 
1773
 *      the actual size of the authorisation token.
 
1774
 *  ospvToken: memory location in which to store the authorisation token for 
 
1775
 *      this destination. In general, tokens are opaque, binary objects.
 
1776
 * The SDK library is able to perform this function without network 
 
1777
 * interaction, and, therefore, does not block for network input or output 
 
1778
 * during its execution.
 
1779
 * The function returns an error code or zero (if the operation was successful).
 
1780
 * Specific error codes and their meanings can be found in the osperrno.h file.
 
1781
 */
 
1782
 
 
1783
int
 
1784
OSPPTransactionGetNextDestination(
 
1785
    OSPTTRANHANDLE      ospvTransaction,        /* In - Transaction handle */
 
1786
    enum OSPEFAILREASON ospvFailureReason,      /* In - Failure code */
 
1787
    unsigned            ospvSizeOfTimestamp,    /* In - Max size of timestamp string */
 
1788
    char                *ospvValidAfter,        /* Out - Valid after time string */
 
1789
    char                *ospvValidUntil,        /* Out - Valid until time string */
 
1790
    unsigned            *ospvTimeLimit,         /* Out - Number of seconds call is authorised for */
 
1791
    unsigned            *ospvSizeOfCallId,      /* In - Max size of call id string */
 
1792
    void                *ospvCallId,            /* Out - Call Id string */
 
1793
    unsigned            ospvSizeOfCalledNumber, /* In - Max size of called number */
 
1794
    char                *ospvCalledNumber,      /* Out - Called number string */
 
1795
    unsigned            ospvSizeOfCallingNumber, /* In - Max size of calling number */
 
1796
    char                *ospvCallingNumber,      /* Out - Calling number string */
 
1797
    unsigned            ospvSizeOfDestination,  /* In - Max size of destination string */
 
1798
    char                *ospvDestination,       /* Out - Destination string */
 
1799
    unsigned            ospvSizeOfDestinationDevice,    /* In - Max size of dest device string */
 
1800
    char                *ospvDestinationDevice,         /* Out - Dest device string */
 
1801
    unsigned            *ospvSizeOfToken,       /* In/Out - Max size of token string Actual size of token string */
 
1802
    void                *ospvToken)             /* Out - Token string */
 
1803
{
 
1804
    int          errorcode = OSPC_ERR_NO_ERROR;
 
1805
    OSPTTRANS    *trans    = NULL;
 
1806
 
 
1807
    trans = OSPPTransactionGetContext(ospvTransaction, &errorcode);
 
1808
 
 
1809
    if(errorcode == OSPC_ERR_NO_ERROR)
 
1810
    {
 
1811
        errorcode = OSPPTransactionGetDestAllowed(trans);
 
1812
    }
 
1813
 
 
1814
    if(errorcode == OSPC_ERR_NO_ERROR)
 
1815
    {
 
1816
        /*
 
1817
         * In ver2.9.3, we have removed the check to not accept 0 as a TC Code. 
 
1818
         * The toolkit now accepts 0.
 
1819
         */
 
1820
        /* Now check for acceptable failure code */
 
1821
        if(errorcode == OSPC_ERR_NO_ERROR)
 
1822
        {
 
1823
            errorcode = OSPPFailReasonFind(ospvFailureReason);
 
1824
        }
 
1825
 
 
1826
        /*
 
1827
         * If the FailureReason = 0, change it to DEFAULT_GETNEXTDEST_NO_ERROR, which is a NONNULL value.
 
1828
         * This is being done because both the - GetFirst and GetNext function calls internally call
 
1829
         * GetDestination. This function expects ospvFailureReason to be 0 when the parent calling function 
 
1830
         * is GetFirst and NonZero when the parent calling function is GetNext.
 
1831
         * To avoid too many changes in the Toolkit, we are overwriting the value 0 with a unique 
 
1832
         * NonZero value here. When we have to actually set the Error Code in the destination structure,
 
1833
         * we will convert it back to 0. Probably not the best method, but continuing like this now.
 
1834
         */
 
1835
        if (ospvFailureReason == OSPC_FAIL_NONE)
 
1836
        {
 
1837
            ospvFailureReason = DEFAULT_GETNEXTDEST_NO_ERROR;
 
1838
        }
 
1839
 
 
1840
 
 
1841
        if(errorcode == OSPC_ERR_NO_ERROR)
 
1842
        {
 
1843
            if (trans->CurrentDest == (OSPTDEST *)OSPC_OSNULL)
 
1844
            {
 
1845
                errorcode = OSPC_ERR_TRAN_NO_MORE_RESPONSES;
 
1846
                OSPM_DBGERRORLOG(errorcode, "No more destinations.");
 
1847
            }
 
1848
 
 
1849
        }
 
1850
 
 
1851
        if ((errorcode == OSPC_ERR_NO_ERROR) && 
 
1852
            (trans != (OSPTTRANS *)NULL)) 
 
1853
        { 
 
1854
            errorcode = OSPPTransactionGetDestination(trans,
 
1855
                ospvFailureReason,
 
1856
                ospvSizeOfTimestamp,
 
1857
                ospvValidAfter,
 
1858
                ospvValidUntil,
 
1859
                ospvTimeLimit,
 
1860
                ospvSizeOfCallId,
 
1861
                ospvCallId,
 
1862
                ospvSizeOfCalledNumber,
 
1863
                ospvCalledNumber,
 
1864
                ospvSizeOfCallingNumber,
 
1865
                ospvCallingNumber,
 
1866
                ospvSizeOfDestination,
 
1867
                ospvDestination,
 
1868
                ospvSizeOfDestinationDevice,
 
1869
                ospvDestinationDevice,
 
1870
                ospvSizeOfToken,
 
1871
                ospvToken);
 
1872
        }
 
1873
 
 
1874
        /* Set transaction state */
 
1875
        if (errorcode == OSPC_ERR_NO_ERROR)
 
1876
        {
 
1877
            OSPPTransactionSetState(trans, OSPC_GET_DEST_SUCCESS);
 
1878
            trans->HasGetDestSucceeded = OSPC_TRUE;
 
1879
        }
 
1880
        else
 
1881
        {
 
1882
            OSPPTransactionSetState(trans, OSPC_GET_DEST_FAIL);
 
1883
        }
 
1884
 
 
1885
 
 
1886
        if (errorcode == OSPC_ERR_TRAN_DEST_INVALID)
 
1887
        {
 
1888
            errorcode = OSPC_ERR_TRAN_NO_MORE_RESPONSES;
 
1889
        }
 
1890
    }
 
1891
 
 
1892
    return errorcode;
 
1893
}
 
1894
 
 
1895
/*
 
1896
 * OSPPTransactionBuildUsageFromScratch()
 
1897
 *
 
1898
 * The OSPPTransactionBuildUsageFromScratch function builds a (newly created)
 
1899
 * transaction object. Applications can use this with a distributed 
 
1900
 * architecture in which the systems requesting and validating authorisation 
 
1901
 * (e.g. H.323 gatekeepers) are different than the systems that ultimately 
 
1902
 * report usage information (e.g. H.323 gateways). As such, this function is 
 
1903
 * (in a source device) an alternative to the combination of  the 
 
1904
 * OSPPTransactionRequestAuthorisation  function (to initiate a call) and the 
 
1905
 * OSPPTransactionGetFirstDestination function (to define the endpoints of the 
 
1906
 * call. In the destination device, this function serves as an alternative to 
 
1907
 * the function  OSPPTransactionValidateAuthorisation.
 
1908
 * The function is very similar to the OSPPTransactionInitializeAtDevice function
 
1909
 * except that it does not expect the user to include the token as a part of
 
1910
 * the API. 
 
1911
 * Parameters to the function are:
 
1912
 *  ospvTransaction: handle of the (previously created) transaction object.
 
1913
 *      For multiple calls to the API, this value should remain same. 
 
1914
 *  ospvServerTransactionId: The transaction id generated by the OSP Server.
 
1915
 *      This need not be initialized when the API is called for the 2nd time or thereafter.
 
1916
 *  ospvIsSource: indicates whether the system calling this function is acting 
 
1917
 *      as the source (if non-zero) or destination (if zero) for the call.
 
1918
 *      This is mandatory and should always be populated.
 
1919
 *  ospvSource: character string identifying the source of the call. The value 
 
1920
 *      is expressed as either a DNS name or an IP address enclosed in square 
 
1921
 *      brackets, followed by an optional colon and TCP port number. 
 
1922
 *      Examples of valid sources include "gateway1.carrier.com" and 
 
1923
 *                                                  "[172.16.1.2]:112".
 
1924
 *  ospvDestination: character string identifying the destination for the call. 
 
1925
 *      The value is expressed as either a DNS name or an IP address enclosed 
 
1926
 *      in square brackets, followed by an optional colon and TCP port number. 
 
1927
 *      Examples of valid destinations include "gateway1.carrier.com" and 
 
1928
 *                                                      "[172.16.1.2]:112".
 
1929
 *      Either ospvDestination or ospvDestinationDevice should be non-NULL.
 
1930
 *  ospvSourceDevice: character string identifying the source device. 
 
1931
 *      This could be the previous hop Gateway.
 
1932
 *      It is expressed as either a DNS name or an IP address enclosed in square 
 
1933
 *      brackets, followed by an optional colon and TCP port number. 
 
1934
 *      Examples of valid sources include "gateway1.carrier.com" and 
 
1935
 *                                                  "[172.16.1.2]:112".
 
1936
 *      This string is optional and may be empty.
 
1937
 *  ospvDestinationDevice: character string identifying the destination device. 
 
1938
 *      The value is expressed as either a DNS name or an IP address enclosed 
 
1939
 *      in square brackets, followed by an optional colon and TCP port number. 
 
1940
 *      Examples of valid destinations include "gateway1.carrier.com" and 
 
1941
 *                                                      "[172.16.1.2]:112".
 
1942
 *      This string is optional and may be empty.
 
1943
 *  ospvCallingNumber: character string containing the calling party's number 
 
1944
 *      expressed as a full international number conforming to the ITU E.164 
 
1945
 *      standard (with no punctuation).
 
1946
 *      When the API is called for the 2nd time or thereafter this value can 
 
1947
 *      be left NULL.
 
1948
 *  ospvCallingNumberFormat: Value that identifies the type of calling number.
 
1949
 *      It can be either {0-E.164, 1-SIP or 2-URL}
 
1950
 *  ospvCalledNumber: character string containing the called number, expressed 
 
1951
 *      as a full international number conforming to the ITU E.164 standard 
 
1952
 *      (with no punctuation).
 
1953
 *      When the API is called for the 2nd time or thereafter this value can 
 
1954
 *      be left NULL.
 
1955
 *  ospvCalledNumberFormat: Value that identifies the type of called number.
 
1956
 *      It can be either {0-E.164, 1-SIP or 2-URL}
 
1957
 *  ospvSizeOfCallId: size of the memory buffer containing the call identifier.
 
1958
 *      This should always be populated.
 
1959
 *  ospvCallId: memory location containing the H.323 call identifier for the 
 
1960
 *      call.
 
1961
 *      This should always be populated.
 
1962
 * The function returns an error code or zero (if the operation was successful)
 
1963
 * Specific error codes and their meanings can be found in the osperrno.h file.
 
1964
*/
 
1965
 
 
1966
int
 
1967
OSPPTransactionBuildUsageFromScratch(
 
1968
    OSPTTRANHANDLE  ospvTransaction,        /*In - Transaction handle */
 
1969
    OSPTUINT64  ospvServerTransactionId, /*In - OSP Server Transaction Id */
 
1970
    unsigned        ospvIsSource,           /*In - Is this the ogw or tgw */
 
1971
    const char     *ospvSource,             /*In - Source of call */
 
1972
    const char     *ospvDestination,        /*In - Destination for call */
 
1973
    const char     *ospvSourceDevice,       /*In - SourceDevice */
 
1974
    const char     *ospvDestinationDevice,  /*In - DestinationDevice */
 
1975
    const char     *ospvCallingNumber,      /*In - Calling number */
 
1976
    OSPE_NUMBERING_FORMAT ospvCallingNumberFormat,  /* In - Calling number format : sip/e.164/url */
 
1977
    const char     *ospvCalledNumber,       /*In - Called number */
 
1978
    OSPE_NUMBERING_FORMAT ospvCalledNumberFormat,  /* In - Called number format : sip/e.164/url */
 
1979
    unsigned        ospvSizeOfCallId,       /*In - Size of Callid */
 
1980
    const void     *ospvCallId,             /*In - Call identifier */
 
1981
    enum OSPEFAILREASON  ospvFailureReason, /* Reason that the previous destination failed */
 
1982
    unsigned   *ospvSizeOfDetailLog,   /* In/Out - Max size of detail log\ Actual size of detail log */
 
1983
    void           *ospvDetailLog         /* In - Pointer to storage for detail log */
 
1984
)
 
1985
{
 
1986
    int                 errorcode   = OSPC_ERR_NO_ERROR;
 
1987
    OSPTTRANS          *trans       = (OSPTTRANS *)OSPC_OSNULL;
 
1988
    unsigned            numcallids  = 1;
 
1989
    OSPTCALLID         *callid     = (OSPTCALLID *)OSPC_OSNULL;
 
1990
    OSPTAUTHIND        *authind    = OSPC_OSNULL;
 
1991
    OSPTDEST            *dest       = OSPC_OSNULL;
 
1992
    OSPTALTINFO        *altinfo    = OSPC_OSNULL;
 
1993
 
 
1994
    /* verify input */
 
1995
    if(((ospvDestination == (const char *)OSPC_OSNULL)&&
 
1996
        (ospvDestinationDevice == (const char *)OSPC_OSNULL)) ||
 
1997
        (ospvSizeOfCallId == 0)                          ||
 
1998
        ((ospvCallingNumberFormat != OSPC_E164) && (ospvCallingNumberFormat != OSPC_SIP) && (ospvCallingNumberFormat != OSPC_URL)) ||
 
1999
        ((ospvCalledNumberFormat != OSPC_E164) && (ospvCalledNumberFormat != OSPC_SIP) && (ospvCalledNumberFormat != OSPC_URL)) ||
 
2000
 
 
2001
        (ospvCallId == (const void *)OSPC_OSNULL))
 
2002
    {
 
2003
        errorcode = OSPC_ERR_TRAN_INVALID_ENTRY;
 
2004
        OSPM_DBGERRORLOG(errorcode, "invalid input for Initialize");
 
2005
    }
 
2006
 
 
2007
    /* Get transaction context */
 
2008
    if (errorcode == OSPC_ERR_NO_ERROR)
 
2009
    {
 
2010
        trans = OSPPTransactionGetContext(ospvTransaction, 
 
2011
            &errorcode);
 
2012
    }
 
2013
 
 
2014
    /* 
 
2015
     * move data into authreq & authrsp, (OGW) struct so 
 
2016
     * report usage will work. 
 
2017
     * We are adding a destination to authrsp->dest, setting current dest to
 
2018
     * point to it.
 
2019
     */
 
2020
 
 
2021
 
 
2022
    if(errorcode == OSPC_ERR_NO_ERROR)
 
2023
    {
 
2024
        if(ospvIsSource == OSPC_SOURCE)
 
2025
        {
 
2026
            if(trans->AuthReq != (OSPTAUTHREQ *)OSPC_OSNULL)
 
2027
            {
 
2028
                /*
 
2029
                 * This is the 2nd time that the API is being called.
 
2030
                 * Just add this destination to the list.
 
2031
                 */
 
2032
                errorcode = OSPPFailReasonFind(ospvFailureReason);
 
2033
                if(errorcode == OSPC_ERR_NO_ERROR)
 
2034
                {
 
2035
                    /* We are only adding a destination 
 
2036
                     * first set failure code in authrsp->currentdest 
 
2037
                     */
 
2038
                    OSPPDestSetTNFailReason(trans->CurrentDest, ospvFailureReason);
 
2039
 
 
2040
                    /* now build new dest */
 
2041
                    errorcode = OSPPTransactionResponseBuild(trans,
 
2042
                                                        ospvDestination, ospvCallingNumber, ospvSizeOfCallId,
 
2043
                                                        ospvCallId,
 
2044
                                                        5,/* Just giving a size because the Response function
 
2045
                                                           * does not like a size of 0 */
 
2046
                                                        "ABCDE");
 
2047
                }
 
2048
            }
 
2049
            else
 
2050
            {
 
2051
                 if ((ospvCallingNumber == (const char *)OSPC_OSNULL) ||
 
2052
                    (ospvCalledNumber == (const char *)OSPC_OSNULL)) 
 
2053
                 {
 
2054
                     errorcode = OSPC_ERR_TRAN_INVALID_ENTRY;
 
2055
                     OSPM_DBGERRORLOG(errorcode, "invalid input for Initialize");
 
2056
                 }
 
2057
 
 
2058
                /* create callid structure */
 
2059
                if (errorcode == OSPC_ERR_NO_ERROR)
 
2060
                {
 
2061
                    callid = OSPPCallIdNew(ospvSizeOfCallId, (const unsigned char *)ospvCallId);
 
2062
 
 
2063
                    if(callid == (OSPTCALLID *)OSPC_OSNULL)
 
2064
                    {
 
2065
                        errorcode = OSPC_ERR_DATA_NOCALLID;
 
2066
                    }
 
2067
                }
 
2068
 
 
2069
                if(errorcode == OSPC_ERR_NO_ERROR)
 
2070
                {
 
2071
                    /* we need to build authreq and authrsp */
 
2072
                    errorcode = OSPPTransactionRequestNew(trans, ospvSource,
 
2073
                        ospvSourceDevice,
 
2074
                        ospvCallingNumber,
 
2075
                        ospvCalledNumber, 
 
2076
                        (const char *)OSPC_OSNULL,
 
2077
                        numcallids,&callid,
 
2078
                        (const char **)OSPC_OSNULL,
 
2079
                        &numcallids, 
 
2080
                        ospvSizeOfDetailLog, 
 
2081
                        ospvDetailLog);
 
2082
 
 
2083
                    if (errorcode == OSPC_ERR_NO_ERROR)
 
2084
                    {
 
2085
                        trans->CallingNumberFormat = ospvCallingNumberFormat;
 
2086
                        trans->CalledNumberFormat = ospvCalledNumberFormat;
 
2087
                    }
 
2088
 
 
2089
                    /* delete callid - TransactionRequestNew created new one */
 
2090
                    OSPPCallIdDelete(&callid);
 
2091
                }
 
2092
 
 
2093
 
 
2094
                if(errorcode == OSPC_ERR_NO_ERROR)
 
2095
                {
 
2096
                    errorcode = OSPPTransactionResponseBuild(trans, 
 
2097
                    ospvDestination,ospvCallingNumber,
 
2098
                    ospvSizeOfCallId,
 
2099
                    ospvCallId, 
 
2100
                    5,/* Just giving a size because the Response function
 
2101
                         * does not like a size of 0 */ 
 
2102
                    "ABCDE");
 
2103
 
 
2104
                   /*
 
2105
                    * Populate Transaction Id
 
2106
                    */
 
2107
                   trans->TransactionID = ospvServerTransactionId;
 
2108
                   trans->HasTransactionID = OSPC_TRUE;
 
2109
 
 
2110
                   /* Set correct role */
 
2111
                   OSPPAuthIndSetRole(trans->AuthInd,OSPC_SOURCE);
 
2112
                }
 
2113
            }
 
2114
        }
 
2115
        else if(ospvIsSource == OSPC_DESTINATION)
 
2116
        {
 
2117
            if(trans->AuthInd != OSPC_OSNULL)
 
2118
            {
 
2119
                errorcode = OSPC_ERR_TRAN_INVALID_ENTRY;
 
2120
                OSPM_DBGERRORLOG(errorcode, "Transaction already initialized");
 
2121
            }
 
2122
            else
 
2123
            {
 
2124
                if ((ospvCallingNumber == (const char *)OSPC_OSNULL) ||
 
2125
                   (ospvCalledNumber == (const char *)OSPC_OSNULL)) 
 
2126
                {
 
2127
                    errorcode = OSPC_ERR_TRAN_INVALID_ENTRY;
 
2128
                    OSPM_DBGERRORLOG(errorcode, "invalid input for Initialize");
 
2129
                }
 
2130
 
 
2131
                /* Need to build the auth Ind element now */
 
2132
                if (errorcode == OSPC_ERR_NO_ERROR)
 
2133
                {
 
2134
                    authind = OSPPAuthIndNew();
 
2135
                }
 
2136
 
 
2137
                /* populate the new one */
 
2138
                if ((authind != (OSPTAUTHIND *)OSPC_OSNULL) && (errorcode == OSPC_ERR_NO_ERROR))
 
2139
                {
 
2140
 
 
2141
                    OSPPAuthIndSetTimestamp(authind, time(OSPC_OSNULL));
 
2142
                    callid = OSPPCallIdNew(ospvSizeOfCallId,
 
2143
                        (const unsigned char *)ospvCallId);
 
2144
 
 
2145
                    if (callid != (OSPTCALLID *)OSPC_OSNULL)
 
2146
                    {
 
2147
                        OSPPAuthIndSetRole(authind,OSPC_DESTINATION);
 
2148
                        OSPPAuthIndSetCallId(authind, callid);
 
2149
                        OSPPAuthIndSetSourceNumber(authind,
 
2150
                            (const unsigned char *)ospvCallingNumber);
 
2151
                        trans->CallingNumberFormat = ospvCallingNumberFormat;
 
2152
 
 
2153
                        OSPPAuthIndSetDestNumber(authind,
 
2154
                            (const unsigned char *)ospvCalledNumber);
 
2155
                        trans->CalledNumberFormat = ospvCalledNumberFormat;
 
2156
 
 
2157
                        OSPPListNew(&(authind->ospmAuthIndTokens));
 
2158
                        OSPPCallIdDelete(&callid);
 
2159
                    }
 
2160
                    else
 
2161
                    {
 
2162
                        errorcode = OSPC_ERR_TRAN_CALLID_NOT_FOUND;
 
2163
                        OSPM_DBGERRORLOG(errorcode, "callid is null");
 
2164
                    }
 
2165
 
 
2166
                    if (errorcode == OSPC_ERR_NO_ERROR)
 
2167
                    {
 
2168
                        /* create the destination object */
 
2169
                        dest = OSPPDestNew();
 
2170
 
 
2171
                        if (dest == OSPC_OSNULL)
 
2172
                        {
 
2173
                            errorcode = OSPC_ERR_DATA_NO_DEST;
 
2174
                        }
 
2175
                        else
 
2176
                        {
 
2177
                            OSPPDestSetCallId(dest,
 
2178
                                          (const unsigned char *)ospvCallId,
 
2179
                                          ospvSizeOfCallId);
 
2180
 
 
2181
                            OSPPDestSetNumber(dest, (const unsigned char *)ospvCalledNumber);
 
2182
 
 
2183
                            OSPPAuthIndSetDest(authind, dest);
 
2184
 
 
2185
                            trans->CurrentDest = dest;
 
2186
                            dest = OSPC_OSNULL;
 
2187
 
 
2188
                        }
 
2189
                    }
 
2190
                    trans->AuthInd = authind;
 
2191
 
 
2192
                    if ((errorcode == OSPC_ERR_NO_ERROR) && (ospvSourceDevice != OSPC_OSNULL))
 
2193
                    {
 
2194
                        /* device information - create a linked list */
 
2195
                        OSPPListNew((OSPTLIST *)&(trans->AuthInd->ospmAuthIndDeviceInfo));
 
2196
 
 
2197
                        altinfo = OSPPAltInfoNew(OSPM_STRLEN(ospvSourceDevice),
 
2198
                                (const unsigned char *)ospvSourceDevice,
 
2199
                                ospeTransport);
 
2200
 
 
2201
                        if(altinfo != OSPC_OSNULL)
 
2202
                        {
 
2203
 
 
2204
                            OSPPListAppend(
 
2205
                                    (OSPTLIST *)&(trans->AuthInd->ospmAuthIndDeviceInfo
 
2206
),
 
2207
                                    (void *)altinfo);
 
2208
                        }
 
2209
                        altinfo = OSPC_OSNULL;
 
2210
                    } /* end if ospvSourceDevice != OSPC_OSNULL */
 
2211
 
 
2212
 
 
2213
                    /* --------------------------------------
 
2214
                     * ospmAuthIndSourceAlternate (SourceAlternate)
 
2215
                     * --------------------------------------
 
2216
                     */
 
2217
 
 
2218
                    if(errorcode == OSPC_ERR_NO_ERROR)
 
2219
                    {
 
2220
 
 
2221
                        if ((ospvSource != OSPC_OSNULL)||(trans->SrcNetworkId!= OSPC_OSNULL))
 
2222
                        {
 
2223
 
 
2224
                            /* source alternates - create a linked list */
 
2225
                            OSPPListNew((OSPTLIST *)&(trans->AuthInd->ospmAuthIndSourceAlternate));
 
2226
 
 
2227
                            if(trans->SrcNetworkId != OSPC_OSNULL)
 
2228
                            {
 
2229
 
 
2230
                                altinfo = OSPPAltInfoNew(OSPM_STRLEN(trans->SrcNetworkId),
 
2231
                                    (const unsigned char *)trans->SrcNetworkId,
 
2232
                                    ospeNetwork);
 
2233
 
 
2234
                                if(altinfo != OSPC_OSNULL)
 
2235
                                {
 
2236
 
 
2237
                                    OSPPListAppend(
 
2238
                                        (OSPTLIST *)&(trans->AuthInd->ospmAuthIndSourceAlternate),
 
2239
                                        (void *)altinfo);
 
2240
                                }
 
2241
                            }
 
2242
                            altinfo = OSPC_OSNULL;
 
2243
 
 
2244
                            if(ospvSource != OSPC_OSNULL)
 
2245
                            {
 
2246
 
 
2247
                                altinfo = OSPPAltInfoNew(OSPM_STRLEN(ospvSource),
 
2248
                                    (const unsigned char *)ospvSource,
 
2249
                                    ospeTransport);
 
2250
 
 
2251
                                if(altinfo != OSPC_OSNULL)
 
2252
                                {
 
2253
 
 
2254
                                    OSPPListAppend(
 
2255
                                        (OSPTLIST *)&(trans->AuthInd->ospmAuthIndSourceAlternate),
 
2256
                                        (void *)altinfo);
 
2257
                                }
 
2258
                            }
 
2259
 
 
2260
                            altinfo = OSPC_OSNULL;
 
2261
                        }
 
2262
                        else
 
2263
                        {
 
2264
                            errorcode = OSPC_ERR_TRAN_SOURCE_INVALID;
 
2265
                        }
 
2266
                    } /* end  if(errorcode == OSPC_ERR_NO_ERROR) */
 
2267
 
 
2268
                    /* -----------------------------------------------------
 
2269
                     * ospmAuthIndDestinationAlternate (DestinationAlternate)
 
2270
                     * -----------------------------------------------------
 
2271
                     */
 
2272
 
 
2273
                    if(errorcode == OSPC_ERR_NO_ERROR)
 
2274
                    {
 
2275
 
 
2276
                        if((ospvDestination != OSPC_OSNULL) ||
 
2277
                            (ospvDestinationDevice != OSPC_OSNULL)|| (trans->DstNetworkId!= OSPC_OSNULL))
 
2278
                        {
 
2279
 
 
2280
                            /* destination alternates - create a linked list */
 
2281
                            OSPPListNew((OSPTLIST *)&(trans->AuthInd->ospmAuthIndDestinationAlternate));
 
2282
 
 
2283
 
 
2284
                            if(trans->DstNetworkId != OSPC_OSNULL)
 
2285
                            {
 
2286
 
 
2287
                                altinfo = OSPPAltInfoNew(OSPM_STRLEN(trans->DstNetworkId),
 
2288
                                    (const unsigned char *)trans->DstNetworkId,
 
2289
                                    ospeNetwork);
 
2290
 
 
2291
                                if(altinfo != OSPC_OSNULL)
 
2292
                                {
 
2293
 
 
2294
                                    OSPPListAppend(
 
2295
                                        (OSPTLIST *)&(trans->AuthInd->ospmAuthIndDestinationAlternate),
 
2296
                                        (void *)altinfo);
 
2297
                                }
 
2298
                            }
 
2299
 
 
2300
                            altinfo = OSPC_OSNULL;
 
2301
 
 
2302
                            if(ospvDestination != OSPC_OSNULL)
 
2303
                            {
 
2304
 
 
2305
                                altinfo =
 
2306
                                    OSPPAltInfoNew(OSPM_STRLEN(ospvDestination),
 
2307
                                    (const unsigned char *)ospvDestination,
 
2308
                                    ospeTransport);
 
2309
 
 
2310
                                if(altinfo != OSPC_OSNULL)
 
2311
                                {
 
2312
 
 
2313
                                    OSPPListAppend(
 
2314
                                        (OSPTLIST *)&(trans->AuthInd->ospmAuthIndDestinationAlternate),
 
2315
                                        (void *)altinfo);
 
2316
                                }
 
2317
                            }
 
2318
 
 
2319
                            altinfo = OSPC_OSNULL;
 
2320
 
 
2321
                            if(ospvDestinationDevice != OSPC_OSNULL)
 
2322
                            {
 
2323
 
 
2324
                                altinfo = OSPPAltInfoNew(OSPM_STRLEN(ospvDestinationDevice),
 
2325
                                    (const unsigned char *)ospvDestinationDevice,
 
2326
                                    ospeH323);
 
2327
 
 
2328
                                if(altinfo != OSPC_OSNULL)
 
2329
                                {
 
2330
 
 
2331
                                    OSPPListAppend(
 
2332
                                        (OSPTLIST *)&(trans->AuthInd->ospmAuthIndDestinationAlternate),
 
2333
                                        (void *)altinfo);
 
2334
                                }
 
2335
                            } /* end if ospvDestinationDevice != OSPC_OSNULL */
 
2336
                        }
 
2337
                        else
 
2338
                        {
 
2339
                            errorcode = OSPC_ERR_TRAN_DEST_INVALID;
 
2340
                        }
 
2341
                    } /* end  if(errorcode == OSPC_ERR_NO_ERROR) */
 
2342
 
 
2343
                    /*
 
2344
                     * Populate Transaction Id
 
2345
                     */
 
2346
                    trans->TransactionID = ospvServerTransactionId;
 
2347
                    trans->HasTransactionID = OSPC_TRUE;
 
2348
 
 
2349
                    /* Make sure role is correct */
 
2350
                    OSPPAuthIndSetRole(trans->AuthInd,OSPC_DESTINATION);
 
2351
                }
 
2352
 
 
2353
            }
 
2354
        }
 
2355
        else
 
2356
        {
 
2357
            errorcode = OSPC_ERR_TRAN_NOT_IMPLEMENTED;
 
2358
            OSPM_DBGERRORLOG(errorcode, "Invalid system type.");
 
2359
 
 
2360
        }
 
2361
    }
 
2362
 
 
2363
    /* Set transaction state */
 
2364
    if (errorcode == OSPC_ERR_NO_ERROR)
 
2365
    {
 
2366
        OSPPTransactionSetState(trans, OSPC_INITIALIZE_SUCCESS);
 
2367
    }
 
2368
    else
 
2369
    {
 
2370
        OSPPTransactionSetState(trans, OSPC_INITIALIZE_FAIL);
 
2371
    }
 
2372
 
 
2373
    return errorcode;
 
2374
}
 
2375
 
 
2376
 
 
2377
 
 
2378
/*
 
2379
 * OSPPTransactionSetDestinationCount()
 
2380
 *
 
2381
 * The OSPPTransactionSetDestinationCount function sets destination count.
 
2382
 * When a stateless proxy sends a stop source CDR, it may indicate which 
 
2383
 * destination number the usage indication is for.  For example, if the first
 
2384
 * two set-up attempts failed and the call was completed by the 3rd destination,
 
2385
 * the proxy should set the destination count to 3.  The proxy would call this
 
2386
 * API after building a usage indication (using OSPPTransactionBuildUsageFromScratch)
 
2387
 * and before reporting the message to a settlement server (using OSPPTransactionReportUsage())
 
2388
 *
 
2389
 * Parameters to the function are:
 
2390
 *  ospvTransaction: handle of the (previously created) transaction object.
 
2391
 *  ospvDestinationCount: The destination count
 
2392
 *
 
2393
 * Specific error codes and their meanings can be found in the osperrno.h file.
 
2394
 *
 
2395
*/
 
2396
int
 
2397
OSPPTransactionSetDestinationCount(
 
2398
    OSPTTRANHANDLE  ospvTransaction,        /*In - Transaction handle */
 
2399
    unsigned        ospvDestinationCount    /*In - Optional Destination Count, 0 if n/a */
 
2400
)
 
2401
{
 
2402
    int        errorcode   = OSPC_ERR_NO_ERROR;
 
2403
    OSPTTRANS *trans       = (OSPTTRANS *)OSPC_OSNULL;
 
2404
 
 
2405
    trans = OSPPTransactionGetContext(ospvTransaction,&errorcode);
 
2406
 
 
2407
    if(errorcode == OSPC_ERR_NO_ERROR)
 
2408
    {
 
2409
        if((trans->AuthReq != (OSPTAUTHREQ *)OSPC_OSNULL) && (trans->CurrentDest != (OSPTDEST *)OSPC_OSNULL))
 
2410
        {
 
2411
            OSPPDestSetDestinationCount(trans->CurrentDest,ospvDestinationCount);
 
2412
        }
 
2413
        else
 
2414
        {
 
2415
            errorcode = OSPC_ERR_TRAN_REQ_OUT_OF_SEQ;
 
2416
            OSPM_DBGERRORLOG(errorcode,"OSPPTransactionSetDestinationCount should be called after OSPPTransactionBuildUsageFromScratch for the source CDR");
 
2417
        }
 
2418
    }
 
2419
    else
 
2420
    {
 
2421
        errorcode = OSPC_ERR_TRAN_REQ_OUT_OF_SEQ;
 
2422
        OSPM_DBGERRORLOG(errorcode,"OSPPTransactionSetDestinationCount should be called after OSPPTransactionBuildUsageFromScratch for the source CDR");
 
2423
    }
 
2424
 
 
2425
    return errorcode;
 
2426
}
 
2427
 
 
2428
 
 
2429
/*
 
2430
 * OSPPTransactionInitializeAtDevice()
 
2431
 *
 
2432
 * The OSPPTransactionInitializeAtDevice function initializes a (newly created)
 
2433
 * transaction object. Applications can use this with a distributed 
 
2434
 * architecture in which the systems requesting and validating authorisation 
 
2435
 * (e.g. H.323 gatekeepers) are different than the systems that ultimately 
 
2436
 * report usage information (e.g. H.323 gateways). As such, this function is 
 
2437
 * (in a source device) an alternative to the combination of  the 
 
2438
 * OSPPTransactionRequestAuthorisation  function (to initiate a call) and the 
 
2439
 * OSPPTransactionGetFirstDestination function (to define the endpoints of the 
 
2440
 * call. In the destination device, this function serves as an alternative to 
 
2441
 * the function  OSPPTransactionValidateAuthorisation. 
 
2442
 * Parameters to the function are:
 
2443
 *  ospvTransaction: handle of the (previously created) transaction object.
 
2444
 *  ospvIsSource: indicates whether the system calling this function is acting 
 
2445
 *      as the source (if non-zero) or destination (if zero) for the call.
 
2446
 *  ospvSource: character string identifying the source of the call. The value 
 
2447
 *      is expressed as either a DNS name or an IP address enclosed in square 
 
2448
 *      brackets, followed by an optional colon and TCP port number. 
 
2449
 *      Examples of valid sources include "gateway1.carrier.com" and 
 
2450
 *                                                  "[172.16.1.2]:112".
 
2451
 *  ospvDestination: character string identifying the destination for the call. 
 
2452
 *      The value is expressed as either a DNS name or an IP address enclosed 
 
2453
 *      in square brackets, followed by an optional colon and TCP port number. 
 
2454
 *      Examples of valid destinations include "gateway1.carrier.com" and 
 
2455
 *                                                      "[172.16.1.2]:112".
 
2456
 *  ospvSourceDevice: character string identifying the source device. 
 
2457
 *      This could be the previous hop Gateway.
 
2458
 *      It is expressed as either a DNS name or an IP address enclosed in square 
 
2459
 *      brackets, followed by an optional colon and TCP port number. 
 
2460
 *      Examples of valid sources include "gateway1.carrier.com" and 
 
2461
 *                                                  "[172.16.1.2]:112".
 
2462
 *      This string is optional and may be empty.
 
2463
 *  ospvDestinationDevice: character string identifying the destination device. 
 
2464
 *      The value is expressed as either a DNS name or an IP address enclosed 
 
2465
 *      in square brackets, followed by an optional colon and TCP port number. 
 
2466
 *      Examples of valid destinations include "gateway1.carrier.com" and 
 
2467
 *                                                      "[172.16.1.2]:112".
 
2468
 *      This string is optional and may be empty.
 
2469
 *  ospvCallingNumber: character string containing the calling party's number 
 
2470
 *      expressed as a full international number conforming to the ITU E.164 
 
2471
 *      standard (with no punctuation).
 
2472
 *  ospvCallingNumberFormat: Value that identifies the type of calling number.
 
2473
 *      It can be either {0-E.164, 1-SIP or 2-URL}
 
2474
 *  ospvCalledNumber: character string containing the called number, expressed 
 
2475
 *      as a full international number conforming to the ITU E.164 standard 
 
2476
 *      (with no punctuation).
 
2477
 *  ospvCalledNumberFormat: Value that identifies the type of called number.
 
2478
 *      It can be either {0-E.164, 1-SIP or 2-URL}
 
2479
 *  ospvSizeOfCallId: size of the memory buffer containing the call identifier.
 
2480
 *  ospvCallId: memory location containing the H.323 call identifier for the 
 
2481
 *      call.
 
2482
 *  ospvSizeOfToken: size of the memory buffer containing an authorisation 
 
2483
 *      token for the call.
 
2484
 *  ospvToken: memory location containing an authorisation token.
 
2485
 *  ospvAuthorised: pointer to a variable in which the function will indicate 
 
2486
 *      whether or not the call is authorised. On return, a non-zero value 
 
2487
 *      indicates that the call is authorised by the provider, while a zero 
 
2488
 *      value indicates an authorisation failure.
 
2489
 *  ospvTimeLimit: pointer to a variable in which to place the number of 
 
2490
 *      seconds for which the call is initially authorised. A value of zero 
 
2491
 *      indicates that no limit exists. Note that the initial time limit may be
 
2492
 *      extended during the call by using the function 
 
2493
 *      OSPPTransactionRequestReauthorisation.
 
2494
 *  ospvSizeOfDetailLog: pointer to a variable which, on input, contains the 
 
2495
 *      maximum size of the detail log; on output, the variable will be updated
 
2496
 *      with the actual size of the detail log. By setting this value to zero, 
 
2497
 *      applications indicate that they do not wish a detail log for the 
 
2498
 *      authorisation validation.
 
2499
 *  ospvDetailLog: pointer to a location in which to store a detail log for the
 
2500
 *      validation. If this pointer is not NULL, and if the ospvSizeOfDetailLog
 
2501
 *      parameter is non-zero, then the library will store a copy of the 
 
2502
 *      authorisation confirmation obtained from the settlement provider, 
 
2503
 *      including the settlement provider's digital signature.
 
2504
 *  ospvTokenAlgo: This can take either of the 3 values - TOKEN_ALGO_SIGNED,
 
2505
 *      TOKEN_ALGO_UNSIGNED, and TOKEN_ALGO_BOTH. If the value is set to
 
2506
 *      TOKEN_ALGO_SIGNED the toolkit expects the token to be signed, and
 
2507
 *      validates the signature as a part of token validation. If the value
 
2508
 *      is set to TOKEN_ALGO_UNSIGNED, an unsigned token is expected. If the
 
2509
 *      value is set to TOKEN_ALGO_BOTH, then the toolkit accepts either a
 
2510
 *      signed token or an unsigned token.
 
2511
 * If the provider has been configured to perform local validation, the SDK 
 
2512
 * library is able to perform this function without network interaction, and, 
 
2513
 * therefore, does not block for network input or output during its execution. 
 
2514
 * If local validation is not used, this function blocks until authorisation 
 
2515
 * has been validated, refused, or an error has been detected. The Open 
 
2516
 * Settlement Protocol SDK Porting Guide includes information on modifying that
 
2517
 * behavior to prevent blocking.
 
2518
 * The function returns an error code or zero (if the operation was successful)
 
2519
 * Specific error codes and their meanings can be found in the osperrno.h file.
 
2520
*/
 
2521
 
 
2522
int
 
2523
OSPPTransactionInitializeAtDevice(
 
2524
    OSPTTRANHANDLE  ospvTransaction,        /*In - Transaction handle */
 
2525
    unsigned        ospvIsSource,           /*In - Is this the ogw or tgw */
 
2526
    const char     *ospvSource,             /*In - Source of call */
 
2527
    const char     *ospvDestination,        /*In - Destination for call */
 
2528
    const char     *ospvSourceDevice,       /*In - SourceDevice */
 
2529
    const char     *ospvDestinationDevice,  /*In - DestinationDevice */
 
2530
    const char     *ospvCallingNumber,      /*In - Calling number */
 
2531
    OSPE_NUMBERING_FORMAT  ospvCallingNumberFormat,  /* In - Calling number Format : sip/e.164/url*/
 
2532
    const char     *ospvCalledNumber,       /*In - Called number */
 
2533
    OSPE_NUMBERING_FORMAT  ospvCalledNumberFormat,  /* In - Called number Format : sip/e.164/url*/
 
2534
    unsigned        ospvSizeOfCallId,       /*In - Size of Callid */
 
2535
    const void     *ospvCallId,             /*In - Call identifier */
 
2536
    unsigned        ospvSizeOfToken,        /*In - Size of Token */
 
2537
    const void     *ospvToken,              /*In - token */
 
2538
    unsigned       *ospvAuthorised,         /*Out - indicates authorisation */
 
2539
    unsigned       *ospvTimeLimit,          /*Out - number of seconds allowed*/
 
2540
    unsigned       *ospvSizeOfDetailLog,    /* In/Out - Max size of detail log Actual size of detail log */
 
2541
    void           *ospvDetailLog,
 
2542
    unsigned       ospvTokenAlgo          /* In - Algorithm to be used for Validating Token */
 
2543
)
 
2544
{
 
2545
    int                 errorcode   = OSPC_ERR_NO_ERROR;
 
2546
    OSPTTRANS          *trans       = (OSPTTRANS *)OSPC_OSNULL;
 
2547
    unsigned            numcallids  = 1;
 
2548
    OSPTCALLID          *callid     = (OSPTCALLID *)OSPC_OSNULL;
 
2549
 
 
2550
    /* verify input */
 
2551
    if(((ospvDestination == (const char *)OSPC_OSNULL)&&
 
2552
        (ospvDestinationDevice == (const char *)OSPC_OSNULL)) ||
 
2553
        (ospvCallingNumber == (const char *)OSPC_OSNULL) ||
 
2554
        (ospvCalledNumber == (const char *)OSPC_OSNULL)  ||
 
2555
        (ospvSizeOfCallId == 0)                          ||
 
2556
        (ospvCallId == (const void *)OSPC_OSNULL)   ||
 
2557
        (ospvSizeOfToken == 0)                      ||
 
2558
        ((ospvCallingNumberFormat != OSPC_E164) && (ospvCallingNumberFormat != OSPC_SIP) && (ospvCallingNumberFormat != OSPC_URL)) ||
 
2559
        ((ospvCalledNumberFormat != OSPC_E164) && (ospvCalledNumberFormat != OSPC_SIP) && (ospvCalledNumberFormat != OSPC_URL)) ||
 
2560
        (ospvToken == (const void *)OSPC_OSNULL))
 
2561
    {
 
2562
        errorcode = OSPC_ERR_TRAN_INVALID_ENTRY;
 
2563
        OSPM_DBGERRORLOG(errorcode, "invalid input for Initialize");
 
2564
    }
 
2565
 
 
2566
    /* Get transaction context */
 
2567
    if (errorcode == OSPC_ERR_NO_ERROR)
 
2568
    {
 
2569
        trans = OSPPTransactionGetContext(ospvTransaction, 
 
2570
            &errorcode);
 
2571
    }
 
2572
 
 
2573
    /* call validate */
 
2574
    if(errorcode == OSPC_ERR_NO_ERROR)
 
2575
    {
 
2576
        errorcode = OSPPTransactionValidateAuthorisation(ospvTransaction, 
 
2577
            ospvSource,
 
2578
            ospvDestination, 
 
2579
            ospvSourceDevice,
 
2580
            ospvDestinationDevice,
 
2581
            ospvCallingNumber, ospvCallingNumberFormat, ospvCalledNumber, ospvCalledNumberFormat, 
 
2582
            ospvSizeOfCallId, ospvCallId, 
 
2583
            ospvSizeOfToken, ospvToken, 
 
2584
            ospvAuthorised,
 
2585
            ospvTimeLimit, ospvSizeOfDetailLog,
 
2586
            ospvDetailLog,ospvTokenAlgo);
 
2587
    }
 
2588
     
 
2589
 
 
2590
    /* 
 
2591
     * move data into authreq & authrsp, (OGW) struct so 
 
2592
     * report usage will work. 
 
2593
     * We are adding a destination to authrsp->dest, setting current dest to
 
2594
     * point to it.
 
2595
     */
 
2596
 
 
2597
    *ospvAuthorised = OSPC_TRAN_AUTHORISED;
 
2598
 
 
2599
    if((errorcode == OSPC_ERR_NO_ERROR) &&
 
2600
        (*ospvAuthorised == OSPC_TRAN_AUTHORISED))
 
2601
    {
 
2602
        if(ospvIsSource == OSPC_SOURCE)
 
2603
        {
 
2604
            if(trans->AuthReq != (OSPTAUTHREQ *)OSPC_OSNULL)
 
2605
            {
 
2606
                errorcode = OSPC_ERR_TRAN_INVALID_ENTRY;
 
2607
                OSPM_DBGERRORLOG(errorcode, "Transaction already initialized");
 
2608
            }
 
2609
            else
 
2610
            {
 
2611
                /* create callid structure */
 
2612
                callid = OSPPCallIdNew(ospvSizeOfCallId, (const unsigned char *)ospvCallId);
 
2613
 
 
2614
                if(callid == (OSPTCALLID *)OSPC_OSNULL)
 
2615
                {
 
2616
                    errorcode = OSPC_ERR_DATA_NOCALLID;
 
2617
                }
 
2618
 
 
2619
                if(errorcode == OSPC_ERR_NO_ERROR)
 
2620
                {
 
2621
                    /* we need to build authreq and authrsp */
 
2622
                    errorcode = OSPPTransactionRequestNew(trans, ospvSource,
 
2623
                        ospvSourceDevice,
 
2624
                        ospvCallingNumber,
 
2625
                        ospvCalledNumber, 
 
2626
                        (const char *)OSPC_OSNULL,
 
2627
                        numcallids,&callid,
 
2628
                        (const char **)OSPC_OSNULL,
 
2629
                        &numcallids, 
 
2630
                        ospvSizeOfDetailLog, 
 
2631
                        ospvDetailLog);
 
2632
                }
 
2633
 
 
2634
                /* delete callid - TransactionRequestNew created new one */
 
2635
                OSPPCallIdDelete(&callid);
 
2636
            }
 
2637
 
 
2638
            if(errorcode == OSPC_ERR_NO_ERROR)
 
2639
            {
 
2640
                errorcode = OSPPTransactionResponseBuild(trans, 
 
2641
                    ospvDestination,ospvCallingNumber,
 
2642
                    ospvSizeOfCallId,
 
2643
                    ospvCallId, 
 
2644
                    ospvSizeOfToken, 
 
2645
                    ospvToken);
 
2646
            }
 
2647
 
 
2648
            /* Set correct role */
 
2649
            OSPPAuthIndSetRole(trans->AuthInd,OSPC_SOURCE);
 
2650
        }
 
2651
        else if(ospvIsSource == OSPC_DESTINATION)
 
2652
        {
 
2653
 
 
2654
            /* authind  already built by validate, just make sure role is correct */
 
2655
            OSPPAuthIndSetRole(trans->AuthInd,OSPC_DESTINATION);
 
2656
 
 
2657
        }
 
2658
        else
 
2659
        {
 
2660
            errorcode = OSPC_ERR_TRAN_NOT_IMPLEMENTED;
 
2661
            OSPM_DBGERRORLOG(errorcode, "Invalid system type.");
 
2662
 
 
2663
        }
 
2664
    }
 
2665
    else
 
2666
    {
 
2667
        if(errorcode == OSPC_ERR_NO_ERROR)
 
2668
        {
 
2669
            /* no error from validate, but token not authorised */
 
2670
            errorcode = OSPC_ERR_TRAN_TOKEN_INVALID;
 
2671
            OSPM_DBGERRORLOG(errorcode, "Token invalid");
 
2672
 
 
2673
        }
 
2674
    }
 
2675
 
 
2676
    /* Set transaction state */
 
2677
    if (errorcode == OSPC_ERR_NO_ERROR)
 
2678
    {
 
2679
        OSPPTransactionSetState(trans, OSPC_INITIALIZE_SUCCESS);
 
2680
    }
 
2681
    else
 
2682
    {
 
2683
        OSPPTransactionSetState(trans, OSPC_INITIALIZE_FAIL);
 
2684
    }
 
2685
 
 
2686
    return errorcode;
 
2687
}
 
2688
 
 
2689
/*
 
2690
 * The OSPPTransactionNew function creates a new transaction object for 
 
2691
 * ospvProvider. A handle to that object is returned to the location pointed 
 
2692
 * to by ospvTransaction.
 
2693
 * After calling this function to allocate storage for a transaction object, 
 
2694
 * applications should call one of the following three functions to initialize 
 
2695
 * the object:
 
2696
 *  OSPPTransactionRequestAuthorisation: used by the source of a call.
 
2697
 *  OSPPTransactionValidateAuthorisation: used by the destination for a call.
 
2698
 *  OSPPTransactionInitialize: used primarily in architectures that separate 
 
2699
 *      the call authorisation functions from call setup and usage reporting 
 
2700
 *      functions.
 
2701
 * The function returns an error code or zero (if the operation was successful)
 
2702
 * Specific error codes and their meanings can be found in the osperrno.h file.
 
2703
 */
 
2704
 
 
2705
int
 
2706
OSPPTransactionNew(
 
2707
    OSPTPROVHANDLE  ospvProvider,       /* In - Provider Handle */
 
2708
    OSPTTRANHANDLE  *ospvTransaction)   /* Out - Transaction Handle */
 
2709
{
 
2710
    int         errorcode = OSPC_ERR_NO_ERROR;
 
2711
    OSPTTRANS   *trans = NULL;
 
2712
 
 
2713
    errorcode = OSPPTransactionGetNewContext(ospvProvider, ospvTransaction);
 
2714
 
 
2715
    if (errorcode == OSPC_ERR_NO_ERROR)
 
2716
    {
 
2717
        trans = OSPPTransactionGetContext(*ospvTransaction, &errorcode);
 
2718
    }
 
2719
 
 
2720
    if (errorcode == OSPC_ERR_NO_ERROR)
 
2721
    {
 
2722
        trans->Provider = OSPPProviderGetContext(ospvProvider, &errorcode);
 
2723
    }
 
2724
 
 
2725
    if (errorcode == OSPC_ERR_NO_ERROR)
 
2726
    {
 
2727
        OSPPTransactionSetState(trans, OSPC_TRANSNEW);
 
2728
        trans->HasGetDestSucceeded = OSPC_FALSE;
 
2729
        trans->IsServiceInfoPresent = OSPC_FALSE;
 
2730
        trans->IsPricingInfoPresent = OSPC_FALSE;
 
2731
        trans->NumOfPricingInfoElements = 0;
 
2732
        trans->CurrentPricingInfoElement = 0;
 
2733
        trans->WasLookAheadInfoGivenToApp = OSPC_FALSE;
 
2734
        trans->TokenInfoIsLookAheadInfoPresent = OSPC_FALSE;
 
2735
        trans->SrcNetworkId = NULL;
 
2736
        trans->DstNetworkId = NULL;
 
2737
    }
 
2738
 
 
2739
    return errorcode;
 
2740
}
 
2741
 
 
2742
/*
 
2743
 * The OSPPTransactionRecordFailure function allows an application to record 
 
2744
 * the failure of a call attempt. Applications can use this function when they 
 
2745
 * wish to abandon a call attempt without exhausting the list of possible 
 
2746
 * destinations, and in a distributed architecture in which the system 
 
2747
 * retrieving successive destinations (e.g. an H.323 gatekeeper) is different 
 
2748
 * than the system that ultimately reports usage information (e.g. an H.323 
 
2749
 * gateway).
 
2750
 * The parameters to this function consist of the following:
 
2751
 *  ospvTransaction: handle of the transaction object.
 
2752
 *  ospvFailureReason: the reason that attempts to use the previously 
 
2753
 *      identified destination failed; values for this parameter are listed in 
 
2754
 *      the ospfail.h file.
 
2755
 * The SDK library is able to perform this function without network interaction
 
2756
 * and, therefore, does not block for network input or output during its 
 
2757
 * execution.
 
2758
 * The function returns an error code or zero (if the operation was successful)
 
2759
 * Specific error codes and their meanings can be found in the osperrno.h file.
 
2760
*/
 
2761
int
 
2762
OSPPTransactionRecordFailure(
 
2763
    OSPTTRANHANDLE       ospvTransaction,
 
2764
    enum OSPEFAILREASON  ospvFailureReason
 
2765
)
 
2766
{
 
2767
    int         errorcode = OSPC_ERR_NO_ERROR;
 
2768
    OSPTTRANS  *trans     = (OSPTTRANS *)OSPC_OSNULL;
 
2769
 
 
2770
    trans = OSPPTransactionGetContext(ospvTransaction, &errorcode);
 
2771
 
 
2772
    if((errorcode == OSPC_ERR_NO_ERROR) &&
 
2773
        (trans != (OSPTTRANS *)OSPC_OSNULL))
 
2774
    {
 
2775
        /*
 
2776
         * The failurereason should be either 0 or a positive value. This is the only 
 
2777
         * restriction we have now. 
 
2778
         */
 
2779
        if (ospvFailureReason < OSPC_FAIL_NONE)
 
2780
        {
 
2781
            errorcode = OSPC_ERR_FAILRSN_INVALID;
 
2782
            OSPM_DBGERRORLOG(errorcode, "Failure code invalid");
 
2783
        }
 
2784
 
 
2785
        if(errorcode == OSPC_ERR_NO_ERROR)
 
2786
        {
 
2787
 
 
2788
            /* Set failure reason for current destination */
 
2789
            OSPPDestSetTNFailReason(trans->CurrentDest, ospvFailureReason);
 
2790
 
 
2791
        }
 
2792
    }
 
2793
    else if(errorcode == OSPC_ERR_NO_ERROR)
 
2794
    {
 
2795
 
 
2796
        errorcode = OSPC_ERR_TRAN_TRANSACTION_NOT_FOUND;
 
2797
        OSPM_DBGERRORLOG(errorcode, "Transaction pointer is NULL.");
 
2798
 
 
2799
    }
 
2800
 
 
2801
    return errorcode;
 
2802
}
 
2803
 
 
2804
/*
 
2805
* OSPPTransactionReinitializeAtDevice
 
2806
* The OSPPTransactionReinitializeAtDevice function re-initializes a (previously
 
2807
* initialized) transaction object. Applications can use this with a distributed
 
2808
* architecture in which the systems requesting and validating authorisation 
 
2809
* (e.g. H.323 gatekeepers) are different than the systems that ultimately 
 
2810
* report usage information (e.g. H.323 gateways). The reporting device can call
 
2811
* this function after failing to reach a previous destination. As such, this
 
2812
* function is an alternative to the OSPPTransactionGetNextDestination function.
 
2813
* Parameters to the function are:
 
2814
*   ospvTransaction: handle of the (previously created) transaction object.
 
2815
*   ospvFailureReason: the reason that attempts to use the previously 
 
2816
*       identified destination failed; values for this parameter are listed in
 
2817
*       the ospfail.h file.
 
2818
* ospvIsSource: indicates whether the system calling this function is acting as
 
2819
*       the source (if non-zero) or destination (if zero) for the call.
 
2820
* ospvSource: character string identifying the source of the call. The value is
 
2821
*       expressed as either a DNS name or an IP address enclosed in square 
 
2822
*       brackets, followed by an optional colon and TCP port number. 
 
2823
*       Examples of valid sources include "gateway1.carrier.com" and 
 
2824
*           "[172.16.1.2]:112".
 
2825
* ospvDestination: character string identifying the destination for the call. 
 
2826
*       The value is expressed as either a DNS name or an IP address enclosed 
 
2827
*       in square brackets, followed by an optional colon and TCP port number. 
 
2828
*       Examples of valid destinations include "gateway1.carrier.com" and 
 
2829
*           "[172.16.1.2]:112".
 
2830
* ospvSourceDevice: character string identifying the source device. 
 
2831
*      This could be the previous hop Gateway.
 
2832
*      It is expressed as either a DNS name or an IP address enclosed in square 
 
2833
*      brackets, followed by an optional colon and TCP port number. 
 
2834
*      Examples of valid sources include "gateway1.carrier.com" and 
 
2835
*                                                  "[172.16.1.2]:112".
 
2836
*      This string is optional and may be empty.
 
2837
* ospvDestinationDevice: character string identifying the destination device. 
 
2838
*       The value is expressed as either a DNS name or an IP address enclosed 
 
2839
*       in square brackets, followed by an optional colon and TCP port number. 
 
2840
*       Examples of valid destinations include "gateway1.carrier.com" and 
 
2841
*           "[172.16.1.2]:112".
 
2842
*      This string is optional and may be empty.
 
2843
* ospvCallingNumber: character string containing the calling party's number 
 
2844
*       expressed as a full international number conforming to the ITU E.164 
 
2845
*       standard (with no punctuation).
 
2846
* ospvCalledNumber: character string containing the called number, expressed 
 
2847
*       as a full international number conforming to the ITU E.164 standard 
 
2848
*       (with no punctuation).
 
2849
* ospvSizeOfCallId: size of the memory buffer containing the call identifier.
 
2850
* ospvCallId: memory location containing the H.323 call identifier for the 
 
2851
*       call.
 
2852
* ospvSizeOfToken: size of the memory buffer containing an authorisation token
 
2853
*       for the call.
 
2854
* ospvToken: memory location containing an authorisation token.
 
2855
* ospvAuthorised: pointer to a variable in which the function will indicate 
 
2856
*       whether or not the call is authorised. On return, a non-zero value 
 
2857
*       indicates that the call is authorised by the provider, while a zero 
 
2858
*       value indicates an authorisation failure.
 
2859
* ospvTimeLimit: pointer to a variable in which to place the number of seconds
 
2860
*       for which the call is initially authorised. A value of zero indicates 
 
2861
*       that no limit exists. Note that the initial time limit may be extended 
 
2862
*       during the call by using the function 
 
2863
*       OSPPTransactionRequestReauthorisation.
 
2864
* ospvSizeOfDetailLog: pointer to a variable which, on input, contains the 
 
2865
*       maximum size of the detail log; on output, the variable will be updated
 
2866
*       with the actual size of the detail log. By setting this value to zero, 
 
2867
*       applications indicate that they do not wish a detail log for the 
 
2868
*       authorisation validation.
 
2869
* ospvDetailLog: pointer to a location in which to store a detail log for the 
 
2870
*       validation. If this pointer is not NULL, and if the ospvSizeOfDetailLog
 
2871
*       parameter is non-zero, then the library will store a copy of the 
 
2872
*       authorisation confirmation obtained from the settlement provider, 
 
2873
*       including the settlement provider's digital signature.
 
2874
*  ospvTokenAlgo: This can take either of the 3 values - TOKEN_ALGO_SIGNED,
 
2875
*      TOKEN_ALGO_UNSIGNED, and TOKEN_ALGO_BOTH. If the value is set to
 
2876
*      TOKEN_ALGO_SIGNED the toolkit expects the token to be signed, and
 
2877
*      validates the signature as a part of token validation. If the value
 
2878
*      is set to TOKEN_ALGO_UNSIGNED, an unsigned token is expected. If the
 
2879
*      value is set to TOKEN_ALGO_BOTH, then the toolkit accepts either a
 
2880
*      signed token or an unsigned token.
 
2881
* If the provider has been configured to perform local validation, the SDK 
 
2882
* library is able to perform this function without network interaction, and, 
 
2883
* therefore, does not block for network input or output during its execution. 
 
2884
* If local validation is not used, this function blocks until authorisation has
 
2885
* been validated, refused, or an error has been detected. The Open Settlement 
 
2886
* Protocol SDK Porting Guide includes information on modifying that behavior to
 
2887
* prevent blocking.
 
2888
* The function returns an error code or zero (if the operation was successful).
 
2889
* Specific error codes and their meanings can be found in the osperrno.h file.
 
2890
*/
 
2891
int
 
2892
OSPPTransactionReinitializeAtDevice(
 
2893
    OSPTTRANHANDLE       ospvTransaction,
 
2894
    enum OSPEFAILREASON  ospvFailureReason,
 
2895
    unsigned             ospvIsSource,
 
2896
    const char          *ospvSource,
 
2897
    const char          *ospvDestination,
 
2898
    const char          *ospvSourceDevice,
 
2899
    const char          *ospvDestinationDevice,
 
2900
    const char          *ospvCallingNumber,
 
2901
    const char          *ospvCalledNumber,
 
2902
    unsigned             ospvSizeOfCallId,
 
2903
    const void          *ospvCallId,
 
2904
    unsigned             ospvSizeOfToken,
 
2905
    const void          *ospvToken,
 
2906
    unsigned            *ospvAuthorised,
 
2907
    unsigned            *ospvTimeLimit,
 
2908
    unsigned            *ospvSizeOfDetailLog,
 
2909
    void                *ospvDetailLog,
 
2910
    unsigned            ospvTokenAlgo
 
2911
)
 
2912
{
 
2913
    int         errorcode = OSPC_ERR_NO_ERROR;
 
2914
    OSPTTRANS  *trans     = (OSPTTRANS *)OSPC_OSNULL;
 
2915
 
 
2916
    /* verify input */
 
2917
    if(((ospvSource == (const char *)OSPC_OSNULL) && 
 
2918
        (ospvSourceDevice == (const char *)OSPC_OSNULL)) ||
 
2919
        ((ospvDestination == (const char *)OSPC_OSNULL)&&
 
2920
        (ospvDestinationDevice == (const char *)OSPC_OSNULL)) ||
 
2921
        (ospvCallingNumber == (const char *)OSPC_OSNULL) ||
 
2922
        (ospvCalledNumber == (const char *)OSPC_OSNULL)  ||
 
2923
        (ospvSizeOfCallId == 0)                          ||
 
2924
        (ospvCallId == (const void *)OSPC_OSNULL)   ||
 
2925
        (ospvSizeOfToken == 0)                      ||
 
2926
        (ospvToken == (const void *)OSPC_OSNULL))
 
2927
    {
 
2928
 
 
2929
        errorcode = OSPC_ERR_TRAN_INVALID_ENTRY;
 
2930
        OSPM_DBGERRORLOG(errorcode, "Invalid input for ReInitialize");
 
2931
    }
 
2932
    else
 
2933
    {
 
2934
 
 
2935
        trans = OSPPTransactionGetContext(ospvTransaction, &errorcode);
 
2936
 
 
2937
        /*
 
2938
         * In ver2.9.3, we have removed the check to not accept 0 as a TC Code.
 
2939
         * The toolkit now accepts 0.
 
2940
         */
 
2941
 
 
2942
        /* Set failure reason for current destination, validate token and add new
 
2943
           destination. only on OGW
 
2944
           */
 
2945
 
 
2946
        /* Now check for acceptable failure code */
 
2947
        if(errorcode == OSPC_ERR_NO_ERROR)
 
2948
        {
 
2949
 
 
2950
            errorcode = OSPPFailReasonFind(ospvFailureReason);
 
2951
        }
 
2952
 
 
2953
        /* call validate */
 
2954
        if(errorcode == OSPC_ERR_NO_ERROR)
 
2955
        {
 
2956
 
 
2957
            /*
 
2958
             * The toolkit expects the calling and called numbers to be in
 
2959
             * the same format as the format that was used while callinf 
 
2960
             * InitializeAtDevice API
 
2961
             * The application should make sure of this !
 
2962
             */
 
2963
            errorcode = OSPPTransactionValidateAuthorisation(ospvTransaction, 
 
2964
                ospvSource,
 
2965
                ospvDestination, 
 
2966
                ospvSourceDevice,
 
2967
                ospvDestinationDevice,
 
2968
                ospvCallingNumber, trans->CallingNumberFormat, ospvCalledNumber,
 
2969
                trans->CalledNumberFormat,
 
2970
                ospvSizeOfCallId, ospvCallId, 
 
2971
                ospvSizeOfToken, ospvToken, 
 
2972
                ospvAuthorised,
 
2973
                ospvTimeLimit, ospvSizeOfDetailLog,
 
2974
                ospvDetailLog,
 
2975
                ospvTokenAlgo);
 
2976
        }
 
2977
 
 
2978
        if((errorcode == OSPC_ERR_NO_ERROR) &&
 
2979
            (*ospvAuthorised == OSPC_TRAN_AUTHORISED))
 
2980
        {
 
2981
            /* should only be called by OGW */
 
2982
            if(ospvIsSource == OSPC_SOURCE)
 
2983
            {
 
2984
                /* we are only adding a destination */
 
2985
                /* first set failure code in authrsp->currentdest */
 
2986
                OSPPDestSetTNFailReason(trans->CurrentDest, ospvFailureReason);
 
2987
                /* now build new dest */
 
2988
                errorcode = OSPPTransactionResponseBuild(trans, 
 
2989
                    ospvDestination, ospvCallingNumber,ospvSizeOfCallId,
 
2990
                    ospvCallId, ospvSizeOfToken, ospvToken);
 
2991
            }
 
2992
            else
 
2993
            {
 
2994
                errorcode = OSPC_ERR_TRAN_NOT_IMPLEMENTED;
 
2995
                OSPM_DBGERRORLOG(errorcode, "Invalid system type.");
 
2996
            }
 
2997
 
 
2998
        }
 
2999
        else
 
3000
        {
 
3001
            if(errorcode == OSPC_ERR_NO_ERROR)
 
3002
            {
 
3003
                /* no error from validate, but token not authorised */
 
3004
                errorcode = OSPC_ERR_TRAN_TOKEN_INVALID;
 
3005
                OSPM_DBGERRORLOG(errorcode, "Token invalid");
 
3006
 
 
3007
            }
 
3008
        }
 
3009
 
 
3010
    } /* end else (parameters are correct) */
 
3011
 
 
3012
    /* Set transaction state */
 
3013
    if (errorcode == OSPC_ERR_NO_ERROR)
 
3014
    {
 
3015
        OSPPTransactionSetState(trans, OSPC_REINITIALIZE_SUCCESS);
 
3016
    }
 
3017
    else
 
3018
    {
 
3019
        OSPPTransactionSetState(trans, OSPC_REINITIALIZE_FAIL);
 
3020
    }
 
3021
 
 
3022
    return errorcode;
 
3023
}
 
3024
 
 
3025
/*
 
3026
 * OSPPTransactionReportUsage()
 
3027
 *
 
3028
 * Reports usage information for a call.
 
3029
 *
 
3030
 * The OSPPTransactionReportUsage function reports usage information for a call
 
3031
 * Once this function returns successfully, it may not be called again for the 
 
3032
 * life of the transaction object. Parameters to the function are:
 
3033
 *   ospvTransaction: handle of the transaction object.
 
3034
 *   ospvDuration: the duration of the call, in seconds.
 
3035
 *   ospvStartTime: the call start time.
 
3036
 *   ospvLossPacketsSent: a count of the total number of packets sent by the 
 
3037
 *      reporting system that were not received by its peer, as reported in 
 
3038
 *      the peer's RTCP sender and receiver reports.
 
3039
 *   ospvLossFractionSent: the fraction of packets sent by the reporting system
 
3040
 *      that were not received by its peer, as reported in the peer's RTCP 
 
3041
 *      sender and receiver reports. The fraction is expressed as an integer 
 
3042
 *      number from 0 (no loss) to 255 (total loss).
 
3043
 *   ospvLossPacketsReceived: a count of the total number of packets that the 
 
3044
 *      reporting system expected to receive but did not, as reported in the 
 
3045
 *      system's RTCP sender and receiver reports.
 
3046
 *   ospvLossFractionReceived: the fraction of packets that the reporting 
 
3047
 *      system expected to receive but did not, as reported in it's RTCP sender
 
3048
 *      and receiver reports. The fraction is expressed as an integer number 
 
3049
 *      from 0 (no loss) to 255 (total loss).
 
3050
 *   ospvSizeOfDetailLog: pointer to a variable which, on input, contains the 
 
3051
 *      maximum size of the detail log; on output, the variable will be updated
 
3052
 *      with the actual size of the detail log. By setting this value to zero, 
 
3053
 *      applications indicate that they do not wish a detail log for the usage 
 
3054
 *      report.
 
3055
 *   ospvDetailLog: pointer to a location in which to store a detail log for 
 
3056
 *      the usage report. If this pointer is not NULL, and if the 
 
3057
 *      ospvSizeOfDetailLog parameter is non-zero, then the library will store 
 
3058
 *      a copy of the usage confirmation obtained from the settlement provider,
 
3059
 *      including the settlement provider's digital signature.
 
3060
 * As delivered in the SDK library, this function blocks until usage has been 
 
3061
 * reported or an error has been detected. The Open Settlement Protocol SDK 
 
3062
 * Porting Guide includes information on modifying that behavior to prevent 
 
3063
 * blocking.
 
3064
 *
 
3065
 * returns OSPC_ERR_NO_ERROR if successful, otherwise error code.
 
3066
 */
 
3067
 
 
3068
int
 
3069
OSPPTransactionReportUsage(
 
3070
    OSPTTRANHANDLE          ospvTransaction,            /* In - Transaction handle */
 
3071
    unsigned                ospvDuration,               /* In - Length of call */
 
3072
    OSPTTIME                ospvStartTime,              /* In - Call start time */
 
3073
    OSPTTIME                ospvEndTime,                /* In - Call end time */
 
3074
    OSPTTIME                ospvAlertTime,              /* In - Call alert time */
 
3075
    OSPTTIME                ospvConnectTime,            /* In - Call connect time */
 
3076
    unsigned                ospvIsPDDInfoPresent,       /* In - Is PDD Info present */
 
3077
    unsigned                ospvPostDialDelay,          /* In - Post Dial Delay */
 
3078
    unsigned                ospvReleaseSource,          /* In - EP that released the call */
 
3079
    unsigned char           *ospvConferenceId,          /* In - conference Id. Max 100 char long */
 
3080
    unsigned                ospvLossPacketsSent,        /* In - Packets not received by peer */ 
 
3081
    signed                  ospvLossFractionSent,       /* In - Fraction of packets not received by peer */
 
3082
    unsigned                ospvLossPacketsReceived,    /* In - Packets not received that were expected */
 
3083
    signed                  ospvLossFractionReceived,   /* In - Fraction of packets expected but not received */
 
3084
    unsigned                *ospvSizeOfDetailLog,    /* In/Out - Max size of detail log \ Actual size of detail log */
 
3085
    void                    *ospvDetailLog)             /* Out - Pointer to detail log storage */
 
3086
{
 
3087
    int                     errorcode    = OSPC_ERR_NO_ERROR;
 
3088
    OSPTTRANS               *trans       = OSPC_OSNULL;
 
3089
    OSPTUSAGEIND            *usage       = OSPC_OSNULL;
 
3090
    OSPE_MSG_DATATYPES      datatype     = OSPC_MSG_LOWER_BOUND;
 
3091
    unsigned char           *xmldoc      = OSPC_OSNULL;
 
3092
    unsigned                sizeofxmldoc = 0;
 
3093
    OSPTMSGINFO             *msginfo     = OSPC_OSNULL;
 
3094
    OSPTDEST                *dest        = OSPC_OSNULL;
 
3095
    OSPTBOOL                usageallowed = OSPC_FALSE;
 
3096
    OSPTSTATISTICS          stats;
 
3097
    unsigned                destHasTNFailReason = OSPC_FALSE;
 
3098
 
 
3099
    OSPM_ARGUSED(ospvSizeOfDetailLog);
 
3100
    OSPM_ARGUSED(ospvDetailLog);
 
3101
 
 
3102
    OSPM_MEMSET(&stats, 0, sizeof(OSPTSTATISTICS));
 
3103
 
 
3104
    /* Verify Input */
 
3105
    if (ospvTransaction == OSPC_TRAN_HANDLE_INVALID)
 
3106
    {
 
3107
        errorcode = OSPC_ERR_TRAN_INVALID_ENTRY;
 
3108
        OSPM_DBGERRORLOG(errorcode, "transaction handle invalid");
 
3109
    }
 
3110
 
 
3111
    /* Get transaction context */
 
3112
    if(errorcode == OSPC_ERR_NO_ERROR)
 
3113
    {
 
3114
 
 
3115
        trans = OSPPTransactionGetContext(ospvTransaction, &errorcode);
 
3116
        if(trans == (OSPTTRANS *)OSPC_OSNULL)
 
3117
        {
 
3118
            errorcode = OSPC_ERR_TRAN_TRANSACTION_NOT_FOUND;
 
3119
            OSPM_DBGERRORLOG(errorcode, "transaction context not found");
 
3120
        }
 
3121
    }
 
3122
 
 
3123
    /* Have we already done this? */
 
3124
    if(errorcode == OSPC_ERR_NO_ERROR)
 
3125
    {
 
3126
        OSPPTransactionGetReportUsageAllowed(trans, &usageallowed);
 
3127
        if(!usageallowed)
 
3128
        {
 
3129
            errorcode = OSPC_ERR_TRAN_USAGE_ALREADY_REPORTED;
 
3130
            OSPM_DBGERRORLOG(errorcode, "Usage has already been reported.");
 
3131
        }
 
3132
    }
 
3133
 
 
3134
    /* Set up Statistics */
 
3135
    if(errorcode == OSPC_ERR_NO_ERROR)
 
3136
    {
 
3137
 
 
3138
        errorcode = OSPPStatisticsReportUsage(&(trans->TNStatistics),
 
3139
            ospvLossPacketsSent, 
 
3140
            ospvLossFractionSent,
 
3141
            ospvLossPacketsReceived, 
 
3142
            ospvLossFractionReceived);
 
3143
    }
 
3144
 
 
3145
    /* Set up Usage indication list using current dest list (originating) or
 
3146
     * authind (terminating) and current data */
 
3147
 
 
3148
    /* Are we originating or terminating */
 
3149
    if(errorcode == OSPC_ERR_NO_ERROR)
 
3150
    {
 
3151
 
 
3152
        /* Warning! Do not change the order of these checks without
 
3153
         * looking at OSPPTransactionInitializeAtDevice first
 
3154
         */
 
3155
        if(trans->AuthRsp != (OSPTAUTHRSP *)OSPC_OSNULL)
 
3156
        {
 
3157
            /* originating */
 
3158
            /* determines where most info will come from */
 
3159
            datatype = OSPC_MSG_ARESP;
 
3160
            if (OSPPAuthRspHasDest(trans->AuthRsp))
 
3161
            {
 
3162
                OSPPListNew(&(trans->UsageInd));
 
3163
 
 
3164
                /* Loop through all dests from first to current and create
 
3165
                 * usages for each
 
3166
                 */
 
3167
                for((dest = (OSPTDEST *)OSPPListFirst(&(trans->AuthRsp->ospmAuthRspDest)));
 
3168
                    (dest != trans->CurrentDest) && 
 
3169
                    (errorcode == OSPC_ERR_NO_ERROR) &&
 
3170
                    (dest != OSPC_OSNULL);
 
3171
                    (dest = (OSPTDEST *)OSPPListNext(&(trans->AuthRsp->ospmAuthRspDest), dest)))
 
3172
                {
 
3173
                    /*
 
3174
                     * All dests up to current (if any) must have failreasons.
 
3175
                     */
 
3176
                    if(!OSPPDestHasTNFailReason(dest))
 
3177
                    {
 
3178
                        errorcode = OSPC_ERR_TRAN_INVALID_ENTRY;
 
3179
                        OSPM_DBGERRORLOG(errorcode, "No failure code found.");
 
3180
                        break;
 
3181
                    }
 
3182
                    else
 
3183
                    {
 
3184
                        errorcode = OSPPTransactionBuildUsage(trans, &usage, dest, datatype);
 
3185
                    }
 
3186
                    
 
3187
                    /*
 
3188
                     * Add conference Id
 
3189
                     */
 
3190
                    if ((ospvConferenceId) && (ospvConferenceId[0] != '\0') && (OSPM_STRLEN((const char *)ospvConferenceId) < OSPC_CONFIDSIZE))
 
3191
                    {
 
3192
                        OSPPUsageIndSetConferenceId(usage,ospvConferenceId);
 
3193
                    }
 
3194
 
 
3195
                    if(errorcode == OSPC_ERR_NO_ERROR)
 
3196
                    {
 
3197
                        OSPPUsageIndSetDestinationCount(usage, OSPPDestGetDestinationCount(dest));
 
3198
 
 
3199
                        /* set FailureReason */
 
3200
                        OSPPUsageIndSetTNFailReason(usage, OSPPDestGetTNFailReason(dest));
 
3201
                        OSPPListAppend(&(trans->UsageInd), usage);
 
3202
                        usage = OSPC_OSNULL;
 
3203
                    }
 
3204
                }
 
3205
 
 
3206
                if(errorcode == OSPC_ERR_NO_ERROR)
 
3207
                {
 
3208
                    if(dest != OSPC_OSNULL)
 
3209
                    {
 
3210
                        /* We are at current, either set failure code or
 
3211
                         * build a usage detail
 
3212
                         */
 
3213
 
 
3214
                        errorcode = OSPPTransactionBuildUsage(trans, &usage, dest, datatype);
 
3215
 
 
3216
                        if(errorcode == OSPC_ERR_NO_ERROR)
 
3217
                        {
 
3218
                            destHasTNFailReason = OSPPDestHasTNFailReason(dest);
 
3219
                            if (destHasTNFailReason)
 
3220
                            {
 
3221
 
 
3222
                                /* Set failure reason */
 
3223
                                OSPPUsageIndSetTNFailReason(usage, OSPPDestGetTNFailReason(dest));
 
3224
                            }
 
3225
 
 
3226
                            OSPPUsageIndSetDestinationCount(usage, OSPPDestGetDestinationCount(dest));
 
3227
 
 
3228
                            /* Set Duration */
 
3229
                            OSPPUsageIndSetDuration(usage, (int)ospvDuration);
 
3230
                            OSPPUsageIndSetStartTime(usage, ospvStartTime);
 
3231
                            OSPPUsageIndSetEndTime(usage, ospvEndTime);
 
3232
                            OSPPUsageIndSetAlertTime(usage, ospvAlertTime);
 
3233
                            OSPPUsageIndSetConnectTime(usage, ospvConnectTime);
 
3234
                            OSPPUsageIndSetIsPDDInfoPresent(usage, ospvIsPDDInfoPresent);
 
3235
                            if (ospvIsPDDInfoPresent)
 
3236
                            {
 
3237
                                OSPPUsageIndSetPostDialDelay(usage, (int)ospvPostDialDelay);
 
3238
                            }
 
3239
                            OSPPUsageIndSetReleaseSource(usage,ospvReleaseSource);
 
3240
 
 
3241
                            /*
 
3242
                             * Add Conference Id
 
3243
                             */
 
3244
                            if ((ospvConferenceId) && (ospvConferenceId[0] != '\0') && (OSPM_STRLEN((const char *)ospvConferenceId) < OSPC_CONFIDSIZE))
 
3245
                            {
 
3246
                                OSPPUsageIndSetConferenceId(usage,ospvConferenceId);
 
3247
                            }
 
3248
                            /* Get Stats */
 
3249
                            if(OSPPTransactionHasStatistics(trans))
 
3250
                            {
 
3251
                                OSPPTransactionGetStatistics(trans, &stats);
 
3252
                                OSPPUsageIndSetTNStatistics(usage, &stats);
 
3253
                            }
 
3254
                        }
 
3255
 
 
3256
                        OSPPListAppend(&(trans->UsageInd), usage);
 
3257
                        usage = OSPC_OSNULL;
 
3258
                    }
 
3259
                    else
 
3260
                    {
 
3261
                        errorcode = OSPC_ERR_TRAN_DEST_NOT_FOUND;
 
3262
                        OSPM_DBGERRORLOG(errorcode, "No current destination found.");                
 
3263
                    }
 
3264
                }
 
3265
            }
 
3266
            else
 
3267
            {
 
3268
                /* Dest not found */
 
3269
                errorcode = OSPC_ERR_TRAN_DEST_NOT_FOUND;
 
3270
                OSPM_DBGERRORLOG(errorcode, "No destinations found.");
 
3271
            }
 
3272
        }
 
3273
        else if(trans->AuthInd != (OSPTAUTHIND *)OSPC_OSNULL)
 
3274
        {  /*terminating*/
 
3275
            datatype = OSPC_MSG_AIND;
 
3276
 
 
3277
            errorcode = OSPPTransactionBuildUsage(trans, &usage, dest, datatype);
 
3278
 
 
3279
            if(errorcode == OSPC_ERR_NO_ERROR)
 
3280
            {
 
3281
                destHasTNFailReason = OSPPDestHasTNFailReason(trans->CurrentDest);
 
3282
                if(destHasTNFailReason)
 
3283
                {
 
3284
                    /* Set failure reason */
 
3285
                    OSPPUsageIndSetTNFailReason(usage, OSPPDestGetTNFailReason(trans->CurrentDest));
 
3286
                }
 
3287
            }
 
3288
 
 
3289
            if(errorcode == OSPC_ERR_NO_ERROR)
 
3290
            {
 
3291
                OSPPListNew(&(trans->UsageInd));
 
3292
                OSPPUsageIndSetDuration(usage, (int)ospvDuration);
 
3293
                            OSPPUsageIndSetStartTime(usage, ospvStartTime);
 
3294
                OSPPUsageIndSetEndTime(usage, ospvEndTime);
 
3295
                OSPPUsageIndSetAlertTime(usage, ospvAlertTime);
 
3296
                OSPPUsageIndSetConnectTime(usage, ospvConnectTime);
 
3297
                OSPPUsageIndSetIsPDDInfoPresent(usage, ospvIsPDDInfoPresent);
 
3298
                if (ospvIsPDDInfoPresent)
 
3299
                {
 
3300
                    OSPPUsageIndSetPostDialDelay(usage, (int)ospvPostDialDelay);
 
3301
                }
 
3302
                OSPPUsageIndSetReleaseSource(usage,ospvReleaseSource);
 
3303
                if ((ospvConferenceId) && (ospvConferenceId[0] != '\0') && (OSPM_STRLEN((const char *)ospvConferenceId) < OSPC_CONFIDSIZE))
 
3304
                {
 
3305
                    OSPPUsageIndSetConferenceId(usage,ospvConferenceId);
 
3306
                }
 
3307
                OSPPListAppend(&(trans->UsageInd), usage);
 
3308
                usage = OSPC_OSNULL;
 
3309
            }
 
3310
        }
 
3311
        else
 
3312
        {
 
3313
            errorcode = OSPC_ERR_TRAN_INVALID_ENTRY;
 
3314
            OSPM_DBGERRORLOG(errorcode, "No information available to process this report.");
 
3315
        }
 
3316
    }
 
3317
 
 
3318
    /* Create appropriate xml message */
 
3319
    if (errorcode == OSPC_ERR_NO_ERROR) 
 
3320
    {
 
3321
        errorcode = OSPPXMLMessageCreate(OSPC_MSG_UIND, 
 
3322
            &xmldoc, &sizeofxmldoc, &(trans->UsageInd), trans);
 
3323
    }
 
3324
 
 
3325
    /* Check for audit. If it is turned on add xmldoc to audit
 
3326
     * storage.
 
3327
     */
 
3328
    if(errorcode == OSPC_ERR_NO_ERROR)
 
3329
    {
 
3330
        if(trans->Provider->Comm->Flags & OSPC_COMM_AUDIT_ON)
 
3331
        {
 
3332
            errorcode = OSPPAuditAddMessageToBuffer(trans->Provider->Audit, xmldoc,
 
3333
                                        sizeofxmldoc);
 
3334
            if(errorcode != OSPC_ERR_NO_ERROR)
 
3335
            {
 
3336
                OSPM_DBGERRORLOG(errorcode, "OSPPAuditAddMessageToBuffer failed.");
 
3337
                errorcode = OSPC_ERR_NO_ERROR;
 
3338
            }
 
3339
        }
 
3340
    }
 
3341
 
 
3342
    /* Create msginfo, put in queue and process return */
 
3343
    if (errorcode == OSPC_ERR_NO_ERROR)
 
3344
    {
 
3345
        errorcode = OSPPMsgInfoNew(&msginfo);
 
3346
 
 
3347
        if (errorcode == OSPC_ERR_NO_ERROR)
 
3348
        {
 
3349
            /* Set transaction state */
 
3350
            OSPPTransactionSetState(trans, OSPC_REPORT_USAGE_BLOCK);
 
3351
 
 
3352
            errorcode = OSPPTransactionPrepareAndQueMessage(
 
3353
                trans, xmldoc, sizeofxmldoc, &msginfo);
 
3354
 
 
3355
            if (errorcode == OSPC_ERR_NO_ERROR) 
 
3356
            {
 
3357
                errorcode = OSPPTransactionProcessReturn(
 
3358
                    trans, msginfo);
 
3359
            }
 
3360
 
 
3361
            OSPPMsgInfoDelete(&msginfo);
 
3362
        }
 
3363
    }
 
3364
 
 
3365
    if(errorcode == OSPC_ERR_NO_ERROR)
 
3366
    {
 
3367
        /* Set transaction state */
 
3368
        OSPPTransactionSetState(trans, OSPC_REPORT_USAGE_SUCCESS);
 
3369
    }
 
3370
    else
 
3371
    {
 
3372
        if(trans != OSPC_OSNULL)
 
3373
        {
 
3374
            /* Set transaction state */
 
3375
            OSPPTransactionSetState(trans, OSPC_REPORT_USAGE_FAIL);
 
3376
 
 
3377
            if(trans->UsageInd != OSPC_OSNULL)
 
3378
            {
 
3379
                OSPPTransactionDeleteUsageInd(trans);
 
3380
            }
 
3381
        }
 
3382
    }
 
3383
 
 
3384
    if(usage != OSPC_OSNULL)
 
3385
    {
 
3386
        OSPPUsageIndDelete(&usage);
 
3387
    }
 
3388
 
 
3389
    if (xmldoc != OSPC_OSNULL)
 
3390
    {
 
3391
        OSPM_FREE(xmldoc);
 
3392
        xmldoc = NULL;
 
3393
    }
 
3394
 
 
3395
    return errorcode;
 
3396
}
 
3397
 
 
3398
/*
 
3399
 * The OSPPTransactionRequestAuthorisation function allows an application to 
 
3400
 * request authorisation and, optionally, routing information for a transaction
 
3401
 * The parameters to the function are:
 
3402
 *  ospvTransaction: handle of the (previously created) transaction object.
 
3403
 *  ospvSource: character string identifying the source of the call. The value 
 
3404
 *      is expressed as either a DNS name or an IP address enclosed in square 
 
3405
 *      brackets, followed by an optional colon and TCP port number. 
 
3406
 *      Examples of valid sources include "gateway1.carrier.com" and 
 
3407
 *                                                      "[172.16.1.2]:112".
 
3408
 * ospvSourceDevice: character string identifying the source device. 
 
3409
 *      This could be the previous hop Gateway.
 
3410
 *      It is expressed as either a DNS name or an IP address enclosed in square 
 
3411
 *      brackets, followed by an optional colon and TCP port number. 
 
3412
 *      Examples of valid sources include "gateway1.carrier.com" and 
 
3413
 *                                                  "[172.16.1.2]:112".
 
3414
 *      This string is optional and may be empty.
 
3415
 *  ospvCallingNumber: character string containing the calling party's number 
 
3416
 *      expressed as a full international number conforming to the ITU E.164 
 
3417
 *      standard (with no punctuation); if the actual calling party number is 
 
3418
 *      unavailable (e.g. because the end user has blocked caller ID services),
 
3419
 *      then the application should supply a local phone number for the device 
 
3420
 *      originating the call.
 
3421
 *  ospvCallingNumberFormat: Value that identifies the type of calling number.
 
3422
 *      It can be either {0-E.164, 1-SIP or 2-URL}
 
3423
 *  ospvCalledNumber: character string containing the called number, expressed 
 
3424
 *      as a full international number conforming to the ITU E.164 standard 
 
3425
 *      (with no punctuation).
 
3426
 *  ospvCalledNumberFormat: Value that identifies the type of called number.
 
3427
 *      It can be either {0-E.164, 1-SIP or 2-URL}
 
3428
 *  ospvUser: character string identifying the end user (e.g. calling card and 
 
3429
 *      PIN number assigned to roaming users); this string may be empty.
 
3430
 *  ospvNumberOfCallIds: the number of call identifiers in the ospvCallIds list
 
3431
 *  ospvCallIds: an array of H.323 call identifiers for the call. The 
 
3432
 *      OSPTCALLID type consists of a length indicator and a pointer to the 
 
3433
 *      binary data. Applications may provide a list of call identifiers in 
 
3434
 *      anticipation of the authorisation request returning multiple potential 
 
3435
 *      destinations. In that case each potential destination is assigned a 
 
3436
 *      separate call identifier. An application may also provide only a single
 
3437
 *      call identifier yet still receive multiple potential destinations. In 
 
3438
 *      that case the same call identifier value must be used for each 
 
3439
 *      destination. If the ospvCallIds list contains more than one entry, the
 
3440
 *      number of entries in that list must be the same as the input value of 
 
3441
 *      the ospvNumberOfDestinations parameter. (Otherwise, an error is 
 
3442
 *      returned.) The value of a call identifier is opaque to the SDK and is 
 
3443
 *      treated as an arbitrary array of bytes.
 
3444
 *  ospvPreferredDestinations: a list of character strings containing preferred
 
3445
 *      destinations for the call, expressed as either DNS names or IP 
 
3446
 *      addresses enclosed in square brackets, followed by an optional colon 
 
3447
 *      and TCP port number. The list is terminated by an empty string or a 
 
3448
 *      NULL pointer, and, if the application has no preferred destinations, 
 
3449
 *      the list may be empty. If multiple preferred destinations are included,
 
3450
 *      they are listed in order of decreasing preference.
 
3451
 *      Examples of valid destinations include "gateway1.carrier.com" and 
 
3452
 *                                                          "[172.16.1.2]:112".
 
3453
 *  ospvNumberOfDestinations: pointer to a variable which, on input, contains 
 
3454
 *      the maximum number of destinations the application wishes to consider; 
 
3455
 *      on output the variable will be updated with the actual number of 
 
3456
 *      destinations authorised.
 
3457
 *  ospvSizeOfDetailLog: pointer to a variable which, on input, contains the 
 
3458
 *      maximum size of the detail log; on output, the variable will be updated
 
3459
 *      with the actual size of the detail log. By setting this value to zero, 
 
3460
 *      applications indicate that they do not wish a detail log for the 
 
3461
 *      authorisation request.
 
3462
 *  ospvDetailLog: pointer to a location in which to store a detail log for the
 
3463
 *      authorisation request. If this pointer is not NULL, and if the 
 
3464
 *      ospvSizeOfDetailLog parameter is non-zero, then the library will store 
 
3465
 *      a copy of the authorisation response obtained from the settlement 
 
3466
 *      provider, including the settlement provider's digital signature.
 
3467
 * As delivered in the SDK library, this function blocks until authorisation 
 
3468
 * has been received or an error has been detected. The Open Settlement 
 
3469
 * Protocol SDK Porting Guide includes information on modifying that behavior 
 
3470
 * to prevent blocking.
 
3471
 * The function returns an error code or zero (if the operation was successful)
 
3472
 * Specific error codes and their meanings can be found in the osperrno.h file.
 
3473
 */
 
3474
 
 
3475
int
 
3476
OSPPTransactionRequestAuthorisation(
 
3477
    OSPTTRANHANDLE  ospvTransaction,            /* In - Transaction handle */
 
3478
    const char      *ospvSource,                /* In - Source of call */
 
3479
    const char      *ospvSourceDevice,                /* In - SourceDevice of call */
 
3480
    const char      *ospvCallingNumber,         /* In - Calling number */
 
3481
    OSPE_NUMBERING_FORMAT ospvCallingNumberFormat,  /* In - Calling number format : sip/e.164/url */
 
3482
    const char      *ospvCalledNumber,          /* In - Called number */
 
3483
    OSPE_NUMBERING_FORMAT ospvCalledNumberFormat,  /* In - Called number format : sip/e.164/url */
 
3484
    const char      *ospvUser,                  /* In - End user (optional) */
 
3485
    unsigned        ospvNumberOfCallIds,        /* In - Number of call identifiers */
 
3486
    OSPTCALLID      *ospvCallIds[],             /* In - List of call identifiers */
 
3487
    const char      *ospvPreferredDestinations[], /* In - List of preferred destinations for call */
 
3488
    unsigned        *ospvNumberOfDestinations,  /* In/Out - Max number of destinations Actual number of dests authorised */
 
3489
    unsigned        *ospvSizeOfDetailLog,       /* In/Out - Max size of detail log Actual size of detail log */
 
3490
    void            *ospvDetailLog)             /* In/Out - Location of detail log storage */
 
3491
{
 
3492
    int           errorcode    = OSPC_ERR_NO_ERROR;
 
3493
    OSPTTRANS     *trans       = OSPC_OSNULL;
 
3494
    OSPTMSGINFO   *msginfo     = OSPC_OSNULL;
 
3495
    unsigned char *xmldoc      = OSPC_OSNULL;
 
3496
    unsigned      sizeofxmldoc = 0,
 
3497
                  delay        = OSPC_TNPROBE_MAXWAIT;
 
3498
    OSPTALTINFO   *altinfo     = OSPC_OSNULL;
 
3499
    OSPT_TN_PROBE *probelist   = OSPC_OSNULL,
 
3500
                  *tmpprobe    = OSPC_OSNULL;
 
3501
    OSPTDEST      *dest        = OSPC_OSNULL;
 
3502
    register unsigned probecnt = 0;
 
3503
    OSPTSVCPT     *svcpt       = OSPC_OSNULL;
 
3504
    unsigned      tmpNumberOfCallIds = 0;
 
3505
    OSPTCALLID    **tmpCallIds = OSPC_OSNULL;
 
3506
    static OSPTCALLID undefinedCallId = { { OSPC_OSNULL }, OSPC_UNDEFINED_CALLID_SIZE, OSPC_UNDEFINED_CALLID_STR };
 
3507
    static OSPTCALLID *undefinedCallIds[OSPC_UNDEFINED_CALLID_NUM] = { &undefinedCallId };
 
3508
 
 
3509
    if( (ospvCallingNumber == (const char *)OSPC_OSNULL)    ||
 
3510
        (ospvCalledNumber == (const char *)OSPC_OSNULL)     ||
 
3511
        ((ospvNumberOfCallIds != 0) && ((ospvCallIds == (OSPTCALLID **)OSPC_OSNULL) || (ospvCallIds[0] == (OSPTCALLID *)OSPC_OSNULL))) ||
 
3512
        ((ospvCallingNumberFormat != OSPC_E164) && (ospvCallingNumberFormat != OSPC_SIP) && (ospvCallingNumberFormat != OSPC_URL)) ||
 
3513
        ((ospvCalledNumberFormat != OSPC_E164) && (ospvCalledNumberFormat != OSPC_SIP) && (ospvCalledNumberFormat != OSPC_URL)) ||
 
3514
        (ospvNumberOfDestinations == 0))
 
3515
    {
 
3516
        errorcode = OSPC_ERR_TRAN_INVALID_ENTRY;
 
3517
        OSPM_DBGERRORLOG(errorcode, "Invalid input for RequestAuthorisation");
 
3518
    }
 
3519
 
 
3520
    if(errorcode == OSPC_ERR_NO_ERROR)
 
3521
    {
 
3522
        if (ospvNumberOfCallIds == 0)
 
3523
        {
 
3524
            tmpNumberOfCallIds = OSPC_UNDEFINED_CALLID_NUM;
 
3525
            tmpCallIds = undefinedCallIds;
 
3526
        }
 
3527
        else {
 
3528
            tmpNumberOfCallIds = ospvNumberOfCallIds;
 
3529
            tmpCallIds = ospvCallIds;
 
3530
 
 
3531
/* Relax the number of call ids check for Emergent's two call ids solution */
 
3532
/*
 
3533
            if ((ospvNumberOfCallIds > 1) &&
 
3534
                (ospvNumberOfCallIds != *ospvNumberOfDestinations))
 
3535
            {
 
3536
                errorcode = OSPC_ERR_TRAN_CALLID_DEST_MISMATCH;
 
3537
                OSPM_DBGERRORLOG(errorcode, 
 
3538
                    "number of callids != number of dests sent in.");
 
3539
            }
 
3540
*/
 
3541
        }
 
3542
    }
 
3543
 
 
3544
    if(errorcode == OSPC_ERR_NO_ERROR)
 
3545
    {
 
3546
        trans = OSPPTransactionGetContext(ospvTransaction, &errorcode);
 
3547
 
 
3548
        /* Check Callids */
 
3549
        if (errorcode == OSPC_ERR_NO_ERROR) 
 
3550
        {
 
3551
 
 
3552
            /* if there is an authreq here already, we have an error */
 
3553
            if(trans->AuthReq == OSPC_OSNULL)
 
3554
            {
 
3555
 
 
3556
                /* Build Auth request */
 
3557
                if (errorcode == OSPC_ERR_NO_ERROR)
 
3558
                {
 
3559
 
 
3560
                    errorcode =  OSPPTransactionRequestNew (trans, 
 
3561
                        ospvSource, ospvSourceDevice, ospvCallingNumber,           
 
3562
                        ospvCalledNumber, ospvUser, tmpNumberOfCallIds,
 
3563
                        tmpCallIds, ospvPreferredDestinations, 
 
3564
                        ospvNumberOfDestinations, 
 
3565
                        ospvSizeOfDetailLog, ospvDetailLog);
 
3566
                   
 
3567
                    if (errorcode == OSPC_ERR_NO_ERROR)
 
3568
                    {
 
3569
                        trans->CallingNumberFormat = ospvCallingNumberFormat;
 
3570
                        trans->CalledNumberFormat = ospvCalledNumberFormat;
 
3571
                    }
 
3572
 
 
3573
                    if (errorcode == OSPC_ERR_NO_ERROR) 
 
3574
                    {
 
3575
 
 
3576
                        errorcode = OSPPXMLMessageCreate(OSPC_MSG_AREQ, 
 
3577
                            &xmldoc, &sizeofxmldoc, trans->AuthReq, trans);
 
3578
 
 
3579
                        if (errorcode == OSPC_ERR_NO_ERROR)
 
3580
                        {
 
3581
 
 
3582
                            errorcode = OSPPMsgInfoNew(&msginfo);
 
3583
 
 
3584
                            if (errorcode == OSPC_ERR_NO_ERROR)
 
3585
                            {
 
3586
                            /* Set transaction state */
 
3587
                                OSPPTransactionSetState(trans, OSPC_AUTH_REQUEST_BLOCK);
 
3588
 
 
3589
                                errorcode = OSPPTransactionPrepareAndQueMessage(
 
3590
                                    trans, xmldoc, sizeofxmldoc, &msginfo);
 
3591
 
 
3592
                                if (errorcode == OSPC_ERR_NO_ERROR) 
 
3593
                                {   
 
3594
                                    errorcode = OSPPTransactionProcessReturn(
 
3595
                                        trans, msginfo);
 
3596
 
 
3597
                                    if((errorcode == OSPC_ERR_NO_ERROR) &&
 
3598
                                        (trans->AuthRsp != OSPC_OSNULL))
 
3599
                                    {
 
3600
                                        /* Set num destinations */
 
3601
                                        *ospvNumberOfDestinations = OSPPAuthRspGetNumDests(trans->AuthRsp);
 
3602
 
 
3603
                                        /* Check status code */
 
3604
                                        if(trans->AuthRsp->ospmAuthRspStatus->ospmStatusCode > 299)
 
3605
                                        {
 
3606
                                            errorcode = OSPPUtilGetErrorFromStatus(
 
3607
                                                trans->AuthRsp->ospmAuthRspStatus->ospmStatusCode);
 
3608
                                        }
 
3609
 
 
3610
                                        if((*ospvNumberOfDestinations > 0) && (errorcode == OSPC_ERR_NO_ERROR))
 
3611
                                        {
 
3612
                                            /* Do we need to run probe? */
 
3613
                                            if((*ospvNumberOfDestinations > 1) &&
 
3614
                                                (OSPPAuthRspHasTNDelayLimit(trans->AuthRsp) || 
 
3615
                                                OSPPAuthRspHasTNDelayPref(trans->AuthRsp)))
 
3616
                                            {
 
3617
 
 
3618
                                                /* build probe list */
 
3619
                                                OSPM_MALLOC(probelist, OSPT_TN_PROBE, 
 
3620
                                                    sizeof(OSPT_TN_PROBE) * *ospvNumberOfDestinations);
 
3621
                                                if(probelist == OSPC_OSNULL)
 
3622
                                                {
 
3623
                                                    errorcode = OSPC_ERR_TRAN_MALLOC_FAILED;
 
3624
                                                }
 
3625
 
 
3626
                                                if(errorcode == OSPC_ERR_NO_ERROR)
 
3627
                                                {
 
3628
                                                    OSPM_MEMSET(probelist, 0, 
 
3629
                                                        sizeof(OSPT_TN_PROBE) * *ospvNumberOfDestinations);
 
3630
 
 
3631
                                                    tmpprobe = probelist;
 
3632
                                                    for(probecnt = 0, dest = (OSPTDEST *)OSPPAuthRspFirstDest(trans->AuthRsp); 
 
3633
                                                        probecnt < *ospvNumberOfDestinations; 
 
3634
                                                        dest = (OSPTDEST *)OSPPAuthRspNextDest(trans->AuthRsp, dest))
 
3635
                                                    {
 
3636
 
 
3637
                                                        if(dest != OSPC_OSNULL)
 
3638
                                                        {
 
3639
                                                            errorcode = OSPPCommParseSvcPt((const char *)OSPPDestGetAddr(dest), 
 
3640
                                                                                            &svcpt, 
 
3641
                                                                                            0);
 
3642
                                                        }
 
3643
 
 
3644
                                                        if(errorcode == OSPC_ERR_NO_ERROR)
 
3645
                                                        {
 
3646
                                                            if (svcpt != (OSPTSVCPT *)OSPC_OSNULL)
 
3647
                                                            {
 
3648
                                                                tmpprobe[probecnt].ospmipaddr = svcpt->IpAddr;
 
3649
 
 
3650
                                                                if (svcpt->HostName)
 
3651
                                                                    OSPM_FREE(svcpt->HostName);
 
3652
 
 
3653
                                                                if (svcpt->URI)
 
3654
                                                                    OSPM_FREE(svcpt->URI);
 
3655
 
 
3656
                                                                OSPM_FREE(svcpt);
 
3657
                                                                
 
3658
                                                                probecnt++;
 
3659
                                                            }
 
3660
                                                        }
 
3661
                                                    }
 
3662
                                                }
 
3663
 
 
3664
                                                /* Check for delay, if present, change from default.
 
3665
                                                 * Call probe */
 
3666
                                                if(OSPPAuthRspHasTNDelayLimit(trans->AuthRsp))
 
3667
                                                {
 
3668
                                                    delay = OSPPAuthRspGetTNDelayLimit(trans->AuthRsp);
 
3669
                                                }
 
3670
 
 
3671
                                                errorcode = OSPPTNProbe(probelist, probecnt, delay);
 
3672
 
 
3673
                                                if(errorcode == OSPC_ERR_NO_ERROR)
 
3674
                                                { 
 
3675
                                                    if(OSPPAuthRspHasTNDelayLimit(trans->AuthRsp))
 
3676
                                                    {
 
3677
                                                        OSPPTNProbePruneList(&(trans->AuthRsp->ospmAuthRspDest),
 
3678
                                                            probelist,
 
3679
                                                            OSPPAuthRspGetTNDelayLimit(trans->AuthRsp),
 
3680
                                                            ospvNumberOfDestinations);
 
3681
                                                    }
 
3682
 
 
3683
                                                    if((OSPPAuthRspHasTNDelayPref(trans->AuthRsp)) &&
 
3684
                                                        (*ospvNumberOfDestinations > 1))
 
3685
                                                    {
 
3686
 
 
3687
                                                        OSPPTNProbeArrangeList(&(trans->AuthRsp->ospmAuthRspDest),
 
3688
                                                            probelist,
 
3689
                                                            *ospvNumberOfDestinations);
 
3690
                                                    }
 
3691
                                                }
 
3692
 
 
3693
                                                if(probelist != OSPC_OSNULL)
 
3694
                                                {
 
3695
                                                    OSPM_FREE(probelist);
 
3696
                                                }
 
3697
                                            }
 
3698
                                        }
 
3699
                                    }
 
3700
 
 
3701
                                }
 
3702
                                else
 
3703
                                {
 
3704
                                    OSPPTransactionDeleteRequest(trans);
 
3705
                                }
 
3706
 
 
3707
                                OSPPMsgInfoDelete(&msginfo);
 
3708
 
 
3709
                                if (trans->AuthReq != OSPC_OSNULL && 
 
3710
                                    trans->AuthReq->ospmAuthReqDestinationAlternate != OSPC_OSNULL)
 
3711
                                {
 
3712
                                    /* We don't keep these around */
 
3713
                                    while (!OSPPListEmpty(&((trans->AuthReq)->ospmAuthReqDestinationAlternate)))
 
3714
                                    {
 
3715
                                        altinfo = (OSPTALTINFO *)OSPPListRemove(&((trans->AuthReq)->ospmAuthReqDestinationAlternate));
 
3716
                                        if (altinfo != OSPC_OSNULL)
 
3717
                                        {
 
3718
                                            OSPM_FREE(altinfo);
 
3719
                                            altinfo = OSPC_OSNULL;
 
3720
                                        }
 
3721
                                    }  
 
3722
                                    OSPPListDelete(&((trans->AuthReq)->ospmAuthReqDestinationAlternate));
 
3723
                                }
 
3724
                            }
 
3725
                        }
 
3726
                    }
 
3727
                }
 
3728
            }
 
3729
            else
 
3730
            {
 
3731
                errorcode = OSPC_ERR_TRAN_NO_NEW_AUTHREQ;
 
3732
                OSPM_DBGERRORLOG(errorcode, "Unfinished AuthReq found.");
 
3733
            }
 
3734
 
 
3735
            if (xmldoc != NULL)
 
3736
            {
 
3737
                OSPM_FREE(xmldoc);
 
3738
                xmldoc = NULL;
 
3739
            }
 
3740
        }
 
3741
 
 
3742
    } /* end else (valid data) */
 
3743
 
 
3744
    /* Set transaction state */
 
3745
    if ((errorcode == OSPC_ERR_NO_ERROR) ||
 
3746
        (errorcode == OSPC_ERR_TRAN_NO_NEW_AUTHREQ))
 
3747
    {
 
3748
        OSPPTransactionSetState(trans, OSPC_AUTH_REQUEST_SUCCESS);
 
3749
    }
 
3750
    else
 
3751
    {
 
3752
        OSPPTransactionSetState(trans, OSPC_AUTH_REQUEST_FAIL);
 
3753
    }
 
3754
 
 
3755
    return errorcode;
 
3756
}
 
3757
 
 
3758
/*
 
3759
 * OSPPTransactionRequestReauthorisation()
 
3760
 *
 
3761
 * Request reauthorisation for a previously authorised call.
 
3762
 *
 
3763
 * The OSPPTransactionRequestReauthorisation function asks the SDK library to 
 
3764
 * refresh a previously granted authorisation, perhaps, for example, because 
 
3765
 * the time limit for that authorisation is nearing its expiration. Parameters 
 
3766
 * to the function are:
 
3767
 *   ospvTransaction: handle of the (previously created) transaction object.
 
3768
 *   ospvSizeOfToken: pointer to a variable which, on input, contains the size 
 
3769
 *      of the memory buffer in which the function should store the 
 
3770
 *      authorisation token for the destination. If the value is not large 
 
3771
 *      enough to accommodate the token, then an error is indicated and no 
 
3772
 *      destination is returned. On output this variable is updated to indicate
 
3773
 *      the actual size of the authorisation token.
 
3774
 *   ospvToken: memory location in which to store the authorisation token for 
 
3775
 *      this destination. In general, tokens are opaque, binary objects.
 
3776
 *   ospvAuthorised: pointer to a variable in which the function will indicate 
 
3777
 *      whether or not the call is reauthorised. On return, a non-zero value 
 
3778
 *      indicates that the call is reauthorised by the provider, while a zero 
 
3779
 *      value indicates an authorisation failure.
 
3780
 *   ospvTimeLimit: pointer to a variable in which to place the total number of
 
3781
 *      seconds for which the call is now authorised. A value of zero indicates
 
3782
 *      that no limit exists.
 
3783
 *   ospvSizeOfDetailLog: pointer to a variable which, on input, contains the 
 
3784
 *      maximum size of the detail log; on output, the variable will be updated
 
3785
 *      with the actual size of the detail log. By setting this value to zero, 
 
3786
 *      applications indicate that they do not wish a detail log for the 
 
3787
 *      authorisation reauthorisation.
 
3788
 *   ospvDetailLog: pointer to a location in which to store a detail log for 
 
3789
 *      the reauthorisation. If this pointer is not NULL, and if the 
 
3790
 *      ospvSizeOfDetailLog parameter is non-zero, then the library will store 
 
3791
 *      a copy of the reauthorisation response obtained from the settlement 
 
3792
 *      provider, including the settlement provider's digital signature.
 
3793
 * This function blocks on network input/output until authorisation has been 
 
3794
 * refreshed, refused, or an error has been detected. The Open Settlement 
 
3795
 * Protocol SDK Porting Guide includes information on modifying that behavior 
 
3796
 * to prevent blocking.
 
3797
 *
 
3798
 * returns OSPC_ERR_NO_ERROR if successful, otherwise error code.
 
3799
 */
 
3800
 
 
3801
int
 
3802
OSPPTransactionRequestReauthorisation(
 
3803
    OSPTTRANHANDLE  ospvTransaction,  /* In - Transaction handle */
 
3804
    unsigned        ospvDuration,     /* In - duration of in-progress call */
 
3805
    unsigned        *ospvSizeOfToken, /* In/Out - max size of authorization token space actual size of authorization token */
 
3806
    void            *ospvToken,       /* Out - Reauthorisation token storage */
 
3807
    unsigned        *ospvAuthorised,  /* Out - Indicator of status of reauthorisation (non-zero = OK) */
 
3808
    unsigned        *ospvTimeLimit,   /* Out - Total number of seconds for reauthorisation ( zero = unlimited )*/
 
3809
    unsigned        *ospvSizeOfDetailLog, /* In/Out - Max size of detail log\ Actual size of detail log */
 
3810
    void            *ospvDetailLog)       /* In/Out - Location of detail log storage */
 
3811
{
 
3812
    int             errorcode       = OSPC_ERR_NO_ERROR;
 
3813
    OSPTTRANS       *trans          = OSPC_OSNULL;
 
3814
    unsigned char   *xmldoc         = OSPC_OSNULL;
 
3815
    unsigned        sizeofxmldoc    = 0;
 
3816
    OSPTMSGINFO     *msginfo        = OSPC_OSNULL;
 
3817
    OSPTSTATUS      *status         = OSPC_OSNULL;
 
3818
    OSPTTOKEN       *token          = OSPC_OSNULL;
 
3819
 
 
3820
    *ospvAuthorised = OSPC_FALSE;
 
3821
    OSPM_ARGUSED(ospvSizeOfDetailLog);
 
3822
    OSPM_ARGUSED(ospvDetailLog);
 
3823
 
 
3824
    /* Get transaction context */
 
3825
    if(errorcode == OSPC_ERR_NO_ERROR)
 
3826
    {
 
3827
 
 
3828
        trans = OSPPTransactionGetContext(ospvTransaction, &errorcode);
 
3829
        if(trans == (OSPTTRANS *)OSPC_OSNULL)
 
3830
        {
 
3831
            errorcode = OSPC_ERR_TRAN_TRANSACTION_NOT_FOUND;
 
3832
            OSPM_DBGERRORLOG(errorcode, "transaction context not found");
 
3833
        }
 
3834
    }
 
3835
 
 
3836
    /* Has to be OGW */
 
3837
    if(errorcode == OSPC_ERR_NO_ERROR)
 
3838
    {
 
3839
        if(trans->AuthRsp != (OSPTAUTHRSP *)OSPC_OSNULL)
 
3840
        {
 
3841
            /* OGW */
 
3842
            /* Build ReauthReq */
 
3843
            errorcode = OSPPTransactionBuildReauthRequest(trans, ospvDuration);
 
3844
 
 
3845
        }
 
3846
        else if(trans->AuthInd != (OSPTAUTHIND *)OSPC_OSNULL)
 
3847
        {  /* TGW */
 
3848
            errorcode = OSPC_ERR_TRAN_TRANSACTION_NOT_ALLOWED;
 
3849
            OSPM_DBGERRORLOG(errorcode, "This transaction not allowed on TGW.");
 
3850
        }
 
3851
        else
 
3852
        {
 
3853
            errorcode = OSPC_ERR_TRAN_INVALID_ENTRY;
 
3854
            OSPM_DBGERRORLOG(errorcode, "No information available to process this request.");
 
3855
        }
 
3856
 
 
3857
    }
 
3858
 
 
3859
    /* Create appropriate xml message */
 
3860
    if (errorcode == OSPC_ERR_NO_ERROR) 
 
3861
    {
 
3862
        errorcode = OSPPXMLMessageCreate(OSPC_MSG_REAREQ, 
 
3863
            &xmldoc, &sizeofxmldoc, trans->ReauthReq, trans);
 
3864
    }
 
3865
 
 
3866
    /* Create msginfo, put in queue and process return */
 
3867
    if (errorcode == OSPC_ERR_NO_ERROR)
 
3868
    {
 
3869
        errorcode = OSPPMsgInfoNew(&msginfo);
 
3870
 
 
3871
        if (errorcode == OSPC_ERR_NO_ERROR)
 
3872
        {
 
3873
            errorcode = OSPPTransactionPrepareAndQueMessage(
 
3874
                trans, xmldoc, sizeofxmldoc, &msginfo);
 
3875
 
 
3876
            if (errorcode == OSPC_ERR_NO_ERROR) 
 
3877
            {
 
3878
 
 
3879
                errorcode = OSPPTransactionProcessReturn(
 
3880
                    trans, msginfo);
 
3881
            }
 
3882
 
 
3883
            OSPPMsgInfoDelete(&msginfo);
 
3884
        }
 
3885
    }
 
3886
 
 
3887
    if((trans->ReauthRsp != OSPC_OSNULL) &&
 
3888
        (errorcode == OSPC_ERR_NO_ERROR))
 
3889
    {
 
3890
 
 
3891
        /* verify REARESP TXID == trans->txid*/
 
3892
        if(trans->ReauthRsp->ospmReauthRspTrxId != trans->TransactionID)
 
3893
        {
 
3894
            errorcode = OSPC_ERR_TRAN_TXID_INVALID;
 
3895
        }
 
3896
 
 
3897
        /* check status code - set authorised */
 
3898
        if (OSPPReauthRspHasStatus(trans->ReauthRsp) == OSPC_FALSE)
 
3899
        {
 
3900
            errorcode = OSPC_ERR_TRAN_STATUS_INVALID;
 
3901
            OSPM_DBGERRORLOG(errorcode, "status not found");
 
3902
        }
 
3903
        else
 
3904
        {
 
3905
            status = OSPPReauthRspGetStatus(trans->ReauthRsp);
 
3906
            if(status != (OSPTSTATUS *)OSPC_OSNULL)
 
3907
            {
 
3908
                if (!OSPM_STATUSCODE_SUCCESSFUL(status->ospmStatusCode))
 
3909
                { 
 
3910
 
 
3911
                    errorcode = status->ospmStatusCode;
 
3912
                    OSPM_DBGERRORLOG(errorcode, "server returned a status error");
 
3913
                }
 
3914
                else
 
3915
                {
 
3916
                    *ospvAuthorised = OSPC_TRUE;
 
3917
                }
 
3918
            }
 
3919
            else
 
3920
            {
 
3921
                errorcode = OSPC_ERR_TRAN_STATUS_NOT_FOUND;
 
3922
                OSPM_DBGERRORLOG(errorcode, "status not found");
 
3923
            }
 
3924
        }
 
3925
 
 
3926
        if(errorcode == OSPC_ERR_NO_ERROR)
 
3927
        {
 
3928
            if(!OSPPReauthRspHasDest(trans->ReauthRsp))
 
3929
            {
 
3930
                errorcode = OSPC_ERR_TRAN_DEST_NOT_FOUND;
 
3931
            }
 
3932
            else
 
3933
            {
 
3934
                /* set token from REARESP token*/
 
3935
 
 
3936
                if (!OSPPDestHasToken(trans->ReauthRsp->ospmReauthRspDest))
 
3937
                {
 
3938
 
 
3939
                    errorcode = OSPC_ERR_TRAN_TOKEN_INVALID;
 
3940
                    OSPM_DBGERRORLOG(errorcode, 
 
3941
                        "null pointer for token.");
 
3942
                }
 
3943
                else
 
3944
                {
 
3945
                    token =(OSPTTOKEN *)OSPPDestFirstToken(trans->ReauthRsp->ospmReauthRspDest);
 
3946
                    if (token == (OSPTTOKEN *)OSPC_OSNULL)
 
3947
                    {
 
3948
 
 
3949
                        errorcode = OSPC_ERR_TRAN_TOKEN_INVALID;
 
3950
                        OSPM_DBGERRORLOG(errorcode, 
 
3951
                            "null pointer for token.");
 
3952
                    }
 
3953
                    else
 
3954
                    {
 
3955
                        if (*ospvSizeOfToken < (unsigned)OSPPTokenGetSize(token))
 
3956
                        {
 
3957
 
 
3958
                            errorcode = OSPC_ERR_TRAN_NOT_ENOUGH_SPACE_FOR_COPY;
 
3959
                            OSPM_DBGERRORLOG(errorcode, 
 
3960
                                "not enough space for token");
 
3961
                        }
 
3962
                        else
 
3963
                        {
 
3964
                            /*
 
3965
                             * Get the token
 
3966
                             */
 
3967
                            OSPM_MEMCPY(ospvToken, 
 
3968
                                OSPPTokenGetValue(token),
 
3969
                                OSPPTokenGetSize(token));
 
3970
                        }
 
3971
                        *ospvSizeOfToken = OSPPTokenGetSize(token);
 
3972
                    }
 
3973
                }
 
3974
 
 
3975
                if(errorcode == OSPC_ERR_NO_ERROR)
 
3976
                {
 
3977
                    /* set timelimit from REARESP duration */
 
3978
                    if(!OSPPDestHasLimit(trans->ReauthRsp->ospmReauthRspDest))
 
3979
                    {
 
3980
                        errorcode = OSPC_ERR_TRAN_DATA_NOT_FOUND;
 
3981
                    }
 
3982
                    else
 
3983
                    {
 
3984
                        *ospvTimeLimit = OSPPDestGetLimit(trans->ReauthRsp->ospmReauthRspDest);
 
3985
                    }
 
3986
                }
 
3987
            }
 
3988
        }
 
3989
    }
 
3990
 
 
3991
    if (xmldoc != OSPC_OSNULL)
 
3992
    {
 
3993
        OSPM_FREE(xmldoc);
 
3994
        xmldoc = NULL;
 
3995
    }
 
3996
 
 
3997
    /* Now delete the reauth request and reauth response */
 
3998
    OSPPTransactionDeleteReauthReq(trans);
 
3999
    OSPPTransactionDeleteReauthRsp(trans);
 
4000
 
 
4001
    return errorcode;
 
4002
}
 
4003
 
 
4004
/*
 
4005
 * The OSPPTransactionValidateAuthorisation function asks the SDK library to 
 
4006
 * validate a requested incoming call, based on the call's parameters and 
 
4007
 * authorisation tokens included in the call. This function may be called 
 
4008
 * multiple times for a single call, so that, for example, call requests with 
 
4009
 * multiple authorisation tokens may result in multiple calls to this function,
 
4010
 * one for each authorisation token in the request. Parameters to the function 
 
4011
 * are
 
4012
 *  ospvTransaction: handle of the (previously created) transaction object.
 
4013
 *  ospvSource: character string identifying the source of the call. The value 
 
4014
 *      is expressed as either a DNS name or an IP address enclosed in square 
 
4015
 *      brackets, followed by an optional colon and TCP port number. 
 
4016
 *      Examples of valid sources include "gateway1.carrier.com" and 
 
4017
 *                                                          "[172.16.1.2]:112".
 
4018
 *  ospvDestination: character string identifying the destination for the call.
 
4019
 *      The value is expressed as either a DNS name or an IP address enclosed 
 
4020
 *      in square brackets, followed by an optional colon and TCP port number. 
 
4021
 *      Examples of valid destinations include "gateway1.carrier.com" and 
 
4022
 *                                                          "[172.16.1.2]:112".
 
4023
 * ospvSourceDevice: character string identifying the source device. 
 
4024
 *      This could be the previous hop Gateway.
 
4025
 *      It is expressed as either a DNS name or an IP address enclosed in square 
 
4026
 *      brackets, followed by an optional colon and TCP port number. 
 
4027
 *      Examples of valid sources include "gateway1.carrier.com" and 
 
4028
 *                                                  "[172.16.1.2]:112".
 
4029
 *      This string is optional and may be empty.
 
4030
 *  ospvDestinationDevice: character string identifying the destination device. 
 
4031
 *      The value is expressed as either a DNS name or an IP address enclosed 
 
4032
 *      in square brackets, followed by an optional colon and TCP port number. 
 
4033
 *      Examples of valid destinations include "gateway1.carrier.com" and 
 
4034
 *                                                          "[172.16.1.2]:112".
 
4035
 *      This string is optional and may be empty.
 
4036
 *  ospvCallingNumber: character string containing the calling party's number 
 
4037
 *      expressed as a full international number conforming to the ITU E.164 
 
4038
 *      standard (with no punctuation).
 
4039
 *  ospvCallingNumberFormat: Value that identifies the type of calling number.
 
4040
 *      It can be either {0-E.164, 1-SIP or 2-URL}
 
4041
 *  ospvCalledNumber: character string containing the called number, expressed 
 
4042
 *      as a full international number conforming to the ITU E.164 standard 
 
4043
 *      (with no punctuation).
 
4044
 *  ospvCalledNumberFormat: Value that identifies the type of called number.
 
4045
 *      It can be either {0-E.164, 1-SIP or 2-URL}
 
4046
 *  ospvSizeOfCallId: size of the memory buffer containing the call identifier.
 
4047
 *  ospvCallId: memory location containing the H.323 call identifier for the 
 
4048
 *      call.
 
4049
 *  ospvSizeOfToken: size of the memory buffer containing an authorisation 
 
4050
 *      token for the call.
 
4051
 *  ospvToken: memory location containing an authorisation token.
 
4052
 *  ospvAuthorised: pointer to a variable in which the function will indicate 
 
4053
 *      whether or not the call is authorised. On return, a non-zero value 
 
4054
 *      indicates that the call is authorised by the provider, while a zero 
 
4055
 *      value indicates an authorisation failure.
 
4056
 *  ospvTimeLimit: pointer to a variable in which to place the number of 
 
4057
 *      seconds for which the call is initially authorised. A value of zero 
 
4058
 *      indicates that no limit exists. Note that the initial time limit may be
 
4059
 *      extended during the call by using the function 
 
4060
 *      OSPPTransactionRequestReauthorisation.
 
4061
 *  ospvSizeOfDetailLog: pointer to a variable which, on input, contains the 
 
4062
 *      maximum size of the detail log; on output, the variable will be updated
 
4063
 *      with the actual size of the detail log. By setting this value to zero, 
 
4064
 *      applications indicate that they do not wish a detail log for the 
 
4065
 *      authorisation validation.
 
4066
 *  ospvDetailLog: pointer to a location in which to store a detail log for the
 
4067
 *      validation. If this pointer is not NULL, and if the ospvSizeOfDetailLog
 
4068
 *      parameter is non-zero, then the library will store a copy of the 
 
4069
 *      authorisation confirmation obtained from the settlement provider, 
 
4070
 *      including the settlement provider's digital signature.
 
4071
 *  ospvTokenAlgo: This can take either of the 3 values - TOKEN_ALGO_SIGNED,
 
4072
 *      TOKEN_ALGO_UNSIGNED, and TOKEN_ALGO_BOTH. If the value is set to 
 
4073
 *      TOKEN_ALGO_SIGNED the toolkit expects the token to be signed, and 
 
4074
 *      validates the signature as a part of token validation. If the value
 
4075
 *      is set to TOKEN_ALGO_UNSIGNED, an unsigned token is expected. If the 
 
4076
 *      value is set to TOKEN_ALGO_BOTH, then the toolkit accepts either a 
 
4077
 *      signed token or an unsigned token.
 
4078
 * If the provider has been configured to perform local validation, the SDK 
 
4079
 * library is able to perform this function without network interaction, and, 
 
4080
 * therefore, does not block for network input or output during its execution. 
 
4081
 * If local validation is not used, this function blocks until authorisation 
 
4082
 * has been validated, refused, or an error has been detected. The Open 
 
4083
 * Settlement Protocol SDK Porting Guide includes information on modifying that
 
4084
 * behavior to prevent blocking.
 
4085
 * The function returns an error code or zero (if the operation was successful)
 
4086
 * Specific error codes and their meanings can be found in the osperrno.h file.
 
4087
 */
 
4088
int
 
4089
OSPPTransactionValidateAuthorisation(
 
4090
    OSPTTRANHANDLE      ospvTransaction,        /* In - Transaction handle */
 
4091
    const char          *ospvSource,            /* In - Source of call */
 
4092
    const char          *ospvDestination,       /* In - Destination for call */
 
4093
    const char          *ospvSourceDevice,      /* In - SourceDevice of call */
 
4094
    const char          *ospvDestinationDevice, /* In - DestinationDevice for call */
 
4095
    const char          *ospvCallingNumber,     /* In - Calling number string*/
 
4096
    OSPE_NUMBERING_FORMAT  ospvCallingNumberFormat,  /* In - Calling number Format : sip/e.164/url*/
 
4097
    const char          *ospvCalledNumber,      /* In - Called number string */
 
4098
    OSPE_NUMBERING_FORMAT  ospvCalledNumberFormat,  /* In - Called number Format : sip/e.164/url*/
 
4099
    unsigned            ospvSizeOfCallId,       /* In - Size of call id value */
 
4100
    const void          *ospvCallId,            /* In - Call Id for this call */
 
4101
    unsigned            ospvSizeOfToken,        /* In - Size of authorization token */
 
4102
    const void          *ospvToken,             /* In - Authorisation token */
 
4103
    unsigned            *ospvAuthorised,        /* Out - Call authorisation indicator */
 
4104
    unsigned            *ospvTimeLimit,         /* Out - Number of seconds call is authorised for */
 
4105
    unsigned            *ospvSizeOfDetailLog,   /* In/Out - Max size of detail log\ Actual size of detail log */
 
4106
    void                *ospvDetailLog,         /* In - Pointer to storage for detail log */
 
4107
    unsigned            ospvTokenAlgo)          /* In - Algorithm to be used for Validating Token */
 
4108
{
 
4109
    int                 errorcode  = OSPC_ERR_NO_ERROR;
 
4110
    OSPTTRANS          *trans      = OSPC_OSNULL;
 
4111
    OSPTAUTHIND        *authind    = OSPC_OSNULL;
 
4112
    OSPTCALLID         *callid     = OSPC_OSNULL;
 
4113
    OSPTTOKEN          *token      = OSPC_OSNULL;
 
4114
    int                 retcode    = 0;
 
4115
    OSPTTOKENINFO      *tokeninfo  = OSPC_OSNULL;
 
4116
    OSPE_MSG_DATATYPES  dtype      = OSPC_MSG_LOWER_BOUND;
 
4117
    OSPTALTINFO        *altinfo    = OSPC_OSNULL;
 
4118
    OSPTPROVIDER        *provider  = OSPC_OSNULL;
 
4119
    OSPTSEC             *security  = OSPC_OSNULL;
 
4120
    unsigned char       *tokenmsg  = OSPC_OSNULL;
 
4121
    unsigned            sizeoftokenmsg = 0;
 
4122
    OSPTDEST            *dest       = OSPC_OSNULL;
 
4123
    int                 BAllowDupTransId = OSPC_TRUE;
 
4124
    token_algo_t        tokenAlgo = (token_algo_t)ospvTokenAlgo;
 
4125
    OSPTBOOL            IsTokenSigned=OSPC_FALSE;
 
4126
    OSPE_DEST_OSP_ENABLED dstOSPStatus;
 
4127
    OSPE_DEST_PROT dstProt;
 
4128
    unsigned char *CallIdValue = OSPC_OSNULL;
 
4129
    unsigned CallIdSize = 0;
 
4130
    OSPTBOOL callidundefined = OSPC_FALSE;
 
4131
    unsigned char *AuthIndCallId = OSPC_OSNULL;
 
4132
    unsigned char AsciiTokenMsg[1000]; /* The assumption is that the ASCII
 
4133
                                        * token will be less than 1000 bytes 
 
4134
                                        * long.
 
4135
                                        */
 
4136
 
 
4137
    OSPM_ARGUSED(ospvSizeOfDetailLog);
 
4138
    OSPM_ARGUSED(ospvDetailLog);
 
4139
 
 
4140
    /* Verify input */
 
4141
    if (((ospvDestination == (const char *)OSPC_OSNULL)&&
 
4142
        (ospvDestinationDevice == (const char *)OSPC_OSNULL)) ||
 
4143
        (ospvCallingNumber == (const char *)OSPC_OSNULL) ||
 
4144
        (ospvCalledNumber == (const char *)OSPC_OSNULL)  ||
 
4145
        (ospvSizeOfToken == 0)                           ||
 
4146
        (ospvToken == (const void *)OSPC_OSNULL)         ||
 
4147
        ((ospvCallingNumberFormat != OSPC_E164) && (ospvCallingNumberFormat != OSPC_SIP) && (ospvCallingNumberFormat != OSPC_URL)) ||
 
4148
        ((ospvCalledNumberFormat != OSPC_E164) && (ospvCalledNumberFormat != OSPC_SIP) && (ospvCalledNumberFormat != OSPC_URL)) ||
 
4149
        ((tokenAlgo < TOKEN_ALGO_SIGNED) || (tokenAlgo >TOKEN_ALGO_BOTH)))
 
4150
    {
 
4151
 
 
4152
        errorcode = OSPC_ERR_TRAN_INVALID_ENTRY;
 
4153
        OSPM_DBGERRORLOG(errorcode, "Invalid input for ValidateAuth");
 
4154
    }
 
4155
 
 
4156
    /* Check to see what tokenAlgo value is passed, 
 
4157
     * and whether it is consistent with the kind of token passed in the API.
 
4158
     */
 
4159
    if ((OSPM_STRNCMP("<?xml",ospvToken,5) == 0) ||
 
4160
        (OSPM_STRNCMP("V=1\n",ospvToken,4) == 0))
 
4161
    {
 
4162
        /*
 
4163
         * The token is unsigned.
 
4164
         * if tokenAlgo = TOKEN_ALGO_SIGNED, then send an error back
 
4165
         */
 
4166
        if (tokenAlgo == TOKEN_ALGO_SIGNED)
 
4167
        {
 
4168
            errorcode = OSPC_ERR_TRAN_UNSIGNED_TOKEN_NOT_ALLOWED;
 
4169
            OSPM_DBGERRORLOG(errorcode, "Not configured to do unsigned token in ValidateAuth");
 
4170
        }
 
4171
        else
 
4172
        {
 
4173
            IsTokenSigned = OSPC_FALSE;
 
4174
        }
 
4175
    }
 
4176
    else
 
4177
    {
 
4178
        /*
 
4179
         * The token is signed.
 
4180
         * if tokenAlgo = TOKEN_ALGO_UNSIGNED, then send an error back
 
4181
         */
 
4182
        if (tokenAlgo == TOKEN_ALGO_UNSIGNED)
 
4183
        {
 
4184
            errorcode = OSPC_ERR_TRAN_SIGNED_TOKEN_NOT_ALLOWED;
 
4185
            OSPM_DBGERRORLOG(errorcode, "Not configured to do signed token in ValidateAuth");
 
4186
        }
 
4187
        else
 
4188
        {
 
4189
            IsTokenSigned = OSPC_TRUE;
 
4190
        }
 
4191
    }
 
4192
 
 
4193
    /* Get transaction context */
 
4194
    if (errorcode == OSPC_ERR_NO_ERROR)
 
4195
    {
 
4196
        trans = OSPPTransactionGetContext(ospvTransaction, 
 
4197
            &errorcode);
 
4198
    }
 
4199
 
 
4200
    /*
 
4201
     * Validate the signature and get the call id from the token
 
4202
     */
 
4203
    if (errorcode == OSPC_ERR_NO_ERROR)
 
4204
    {
 
4205
        errorcode = OSPPTransactionGetProvider(trans, &provider);
 
4206
    }
 
4207
 
 
4208
        if (errorcode == OSPC_ERR_NO_ERROR)
 
4209
        {
 
4210
            errorcode = OSPPProviderGetSecurity(provider, &security);
 
4211
        }
 
4212
 
 
4213
        if ((errorcode == OSPC_ERR_NO_ERROR) &&(IsTokenSigned == OSPC_TRUE))
 
4214
        {
 
4215
            errorcode = OSPPSecSignatureVerify(security,
 
4216
                &tokenmsg, &sizeoftokenmsg,
 
4217
                (unsigned char *)ospvToken, ospvSizeOfToken,
 
4218
                OSPC_SEC_SIGNATURE_AND_CONTENT);
 
4219
 
 
4220
            #ifdef OSPC_VALIDATE_TOKEN_CERT_SUBJECT_NAME
 
4221
            if(errorcode == OSPC_ERR_NO_ERROR)
 
4222
            {
 
4223
                errorcode = OSPPTransactionValidateTokenCert(trans, (unsigned char *)ospvToken, ospvSizeOfToken);
 
4224
            }
 
4225
            #endif
 
4226
 
 
4227
        }
 
4228
 
 
4229
        if ((errorcode == OSPC_ERR_NO_ERROR) && (IsTokenSigned == OSPC_FALSE))
 
4230
        {
 
4231
            /* just copy the token content into the token msg. No sig present */
 
4232
            OSPM_MALLOC(tokenmsg, unsigned char, ospvSizeOfToken);
 
4233
            if (tokenmsg != OSPC_OSNULL)
 
4234
            {
 
4235
                OSPM_MEMCPY(tokenmsg, ospvToken, ospvSizeOfToken);
 
4236
                sizeoftokenmsg = ospvSizeOfToken;
 
4237
                errorcode = OSPC_ERR_NO_ERROR;
 
4238
            }
 
4239
            else
 
4240
            {
 
4241
                errorcode = OSPC_ERR_TRAN_MALLOC_FAILED;
 
4242
            }
 
4243
        }
 
4244
 
 
4245
        /*
 
4246
         * Parse the Token into a TokenInfo structure
 
4247
         */
 
4248
        if (errorcode == OSPC_ERR_NO_ERROR)
 
4249
        {
 
4250
            if (OSPM_STRNCMP("<?xml",(const char *)tokenmsg,5) == 0)
 
4251
            {
 
4252
                errorcode = OSPPXMLMessageParse( (unsigned char *)tokenmsg,
 
4253
                    sizeoftokenmsg, 
 
4254
                    (void **)&tokeninfo, &dtype);
 
4255
            }
 
4256
            else
 
4257
            {
 
4258
               /*
 
4259
                * This is an IAX or SIP token
 
4260
                * we need to copy the info to another string 
 
4261
                * because the tokeninfo array is not null terminated,
 
4262
                * and there is not enough memory to add a '\0' at the end.
 
4263
                * Explicitly NULL terminate the string
 
4264
                */
 
4265
               OSPM_MEMCPY(AsciiTokenMsg,tokenmsg,sizeoftokenmsg);
 
4266
               AsciiTokenMsg[sizeoftokenmsg] = '\0';
 
4267
               dtype = OSPC_MSG_TOKINFO;
 
4268
               errorcode = OSPPParseTokenInfoFromASCIIToken(
 
4269
                                 (unsigned char *)AsciiTokenMsg,
 
4270
                                  sizeoftokenmsg, &tokeninfo);
 
4271
            }
 
4272
        }
 
4273
 
 
4274
 
 
4275
    /*
 
4276
     * Get the call id from the token, if it is "UNDEFINED", set callidundefined
 
4277
     */
 
4278
    if (errorcode == OSPC_ERR_NO_ERROR)
 
4279
    {
 
4280
        CallIdSize = OSPPTokenInfoGetCallIdSize(tokeninfo); 
 
4281
        CallIdValue = OSPPTokenInfoGetCallIdValue(tokeninfo);
 
4282
        if ((CallIdSize == OSPC_UNDEFINED_CALLID_SIZE) && 
 
4283
            (OSPM_MEMCMP(CallIdValue, OSPC_UNDEFINED_CALLID_STR, OSPC_UNDEFINED_CALLID_SIZE) == 0))
 
4284
        {
 
4285
            callidundefined = OSPC_TRUE;
 
4286
        }
 
4287
        else {
 
4288
            callidundefined = OSPC_FALSE;
 
4289
        }
 
4290
    }
 
4291
 
 
4292
    /* Is there an AuthInd here already?
 
4293
     * If so, we are only adding the token
 
4294
     */
 
4295
    if (errorcode == OSPC_ERR_NO_ERROR)
 
4296
    {
 
4297
        /* not here... make a new one */
 
4298
        if (trans->AuthInd == OSPC_OSNULL)
 
4299
        {
 
4300
            authind = OSPPAuthIndNew();
 
4301
 
 
4302
            /* populate the new one */
 
4303
            if (authind != (OSPTAUTHIND *)OSPC_OSNULL)
 
4304
            {
 
4305
 
 
4306
                OSPPAuthIndSetTimestamp(authind, time(OSPC_OSNULL));
 
4307
 
 
4308
                if ((ospvSizeOfCallId > 0) && (ospvCallId != NULL))
 
4309
                {
 
4310
                    callid = OSPPCallIdNew(ospvSizeOfCallId, 
 
4311
                       (const unsigned char *)ospvCallId);
 
4312
                }
 
4313
                else
 
4314
                {
 
4315
                    /*
 
4316
                     * Copy the callId from the token.
 
4317
                     */
 
4318
                    callid = OSPPCallIdNew(CallIdSize,
 
4319
                        (const unsigned char *)CallIdValue);
 
4320
                }
 
4321
 
 
4322
                if (callid != (OSPTCALLID *)OSPC_OSNULL)
 
4323
                {
 
4324
                   OSPPAuthIndSetCallId(authind, callid);
 
4325
                   OSPPCallIdDelete(&callid);
 
4326
                }
 
4327
                else
 
4328
                {
 
4329
                   errorcode = OSPC_ERR_TRAN_CALLID_NOT_FOUND;
 
4330
                   OSPM_DBGERRORLOG(errorcode, "callid is null");
 
4331
                }
 
4332
 
 
4333
 
 
4334
                if (errorcode == OSPC_ERR_NO_ERROR)
 
4335
                {
 
4336
                    OSPPAuthIndSetRole(authind,OSPC_DESTINATION);
 
4337
                    OSPPAuthIndSetSourceNumber(authind, 
 
4338
                        (const unsigned char *)ospvCallingNumber);
 
4339
                    trans->CallingNumberFormat = ospvCallingNumberFormat;
 
4340
 
 
4341
                    OSPPAuthIndSetDestNumber(authind, 
 
4342
                        (const unsigned char *)ospvCalledNumber);
 
4343
                    trans->CalledNumberFormat = ospvCalledNumberFormat;
 
4344
 
 
4345
                    OSPPListNew(&(authind->ospmAuthIndTokens));
 
4346
 
 
4347
                 /* create the destination object */
 
4348
                    dest = OSPPDestNew(); 
 
4349
 
 
4350
                    if (dest == OSPC_OSNULL)
 
4351
                    {
 
4352
                        errorcode = OSPC_ERR_DATA_NO_DEST;
 
4353
                    }
 
4354
                    else
 
4355
                    {
 
4356
                        if ((ospvCallId != NULL) && (ospvSizeOfCallId > 0))
 
4357
                        {
 
4358
                            OSPPDestSetCallId(dest, 
 
4359
                                          (const unsigned char *)ospvCallId,
 
4360
                                          ospvSizeOfCallId);
 
4361
                        }
 
4362
 
 
4363
                        OSPPDestSetNumber(dest, (const unsigned char *)ospvCalledNumber);
 
4364
 
 
4365
                        OSPPAuthIndSetDest(authind, dest);
 
4366
 
 
4367
                        trans->CurrentDest = dest;
 
4368
                        dest = OSPC_OSNULL;
 
4369
 
 
4370
                    }
 
4371
                }
 
4372
                
 
4373
 
 
4374
 
 
4375
                if (errorcode == OSPC_ERR_NO_ERROR)
 
4376
                {
 
4377
                    token = OSPPTokenNew(ospvSizeOfToken, 
 
4378
                        (const unsigned char *)ospvToken);
 
4379
 
 
4380
                    if(token != (OSPTTOKEN *)OSPC_OSNULL)
 
4381
                    {
 
4382
                        OSPPListAppend (&(authind->ospmAuthIndTokens), 
 
4383
                            (void *)token);
 
4384
 
 
4385
                        trans->AuthInd = authind;
 
4386
                    }
 
4387
                    else
 
4388
                    {
 
4389
                        errorcode = OSPC_ERR_TRAN_TOKEN_NOT_FOUND;
 
4390
                        OSPM_DBGERRORLOG(errorcode, "token is null");
 
4391
                    }
 
4392
                }
 
4393
 
 
4394
                if ((errorcode == OSPC_ERR_NO_ERROR) && (ospvSourceDevice != OSPC_OSNULL))
 
4395
                {
 
4396
                    /* device information - create a linked list */
 
4397
                    OSPPListNew((OSPTLIST *)&(trans->AuthInd->ospmAuthIndDeviceInfo));
 
4398
 
 
4399
                    altinfo = OSPPAltInfoNew(OSPM_STRLEN(ospvSourceDevice),
 
4400
                                (const unsigned char *)ospvSourceDevice,
 
4401
                                ospeTransport);
 
4402
 
 
4403
                    if(altinfo != OSPC_OSNULL)
 
4404
                    {
 
4405
 
 
4406
                        OSPPListAppend(
 
4407
                                    (OSPTLIST *)&(trans->AuthInd->ospmAuthIndDeviceInfo),
 
4408
                                    (void *)altinfo);
 
4409
                    }
 
4410
                    altinfo = OSPC_OSNULL;
 
4411
                } /* end if ospvSourceDevice != OSPC_OSNULL */
 
4412
 
 
4413
                /* --------------------------------------
 
4414
                 * ospmAuthIndSourceAlternate (SourceAlternate)
 
4415
                 * --------------------------------------
 
4416
                 */
 
4417
 
 
4418
                if(errorcode == OSPC_ERR_NO_ERROR)
 
4419
                {
 
4420
 
 
4421
                    if ((ospvSource != OSPC_OSNULL)|| (trans->SrcNetworkId!= OSPC_OSNULL)) 
 
4422
                    {
 
4423
 
 
4424
                        /* source alternates - create a linked list */
 
4425
                        OSPPListNew((OSPTLIST *)&(trans->AuthInd->ospmAuthIndSourceAlternate));
 
4426
 
 
4427
                        if(trans->SrcNetworkId != OSPC_OSNULL)
 
4428
                        {
 
4429
 
 
4430
                            altinfo = OSPPAltInfoNew(OSPM_STRLEN(trans->SrcNetworkId),
 
4431
                                (const unsigned char *)trans->SrcNetworkId,
 
4432
                                ospeNetwork);
 
4433
 
 
4434
                            if(altinfo != OSPC_OSNULL)
 
4435
                            {
 
4436
 
 
4437
                                OSPPListAppend(
 
4438
                                    (OSPTLIST *)&(trans->AuthInd->ospmAuthIndSourceAlternate),
 
4439
                                    (void *)altinfo);
 
4440
                            }
 
4441
                        }
 
4442
                        altinfo = OSPC_OSNULL;
 
4443
 
 
4444
                        if(ospvSource != OSPC_OSNULL)
 
4445
                        {
 
4446
 
 
4447
                            altinfo = OSPPAltInfoNew(OSPM_STRLEN(ospvSource), 
 
4448
                                (const unsigned char *)ospvSource,
 
4449
                                ospeTransport);
 
4450
 
 
4451
                            if(altinfo != OSPC_OSNULL)
 
4452
                            {
 
4453
 
 
4454
                                OSPPListAppend(
 
4455
                                    (OSPTLIST *)&(trans->AuthInd->ospmAuthIndSourceAlternate),
 
4456
                                    (void *)altinfo);
 
4457
                            }
 
4458
                        }
 
4459
 
 
4460
                        altinfo = OSPC_OSNULL;
 
4461
 
 
4462
                    }
 
4463
                    else
 
4464
                    {
 
4465
                        errorcode = OSPC_ERR_TRAN_SOURCE_INVALID;
 
4466
                    }
 
4467
                } /* end  if(errorcode == OSPC_ERR_NO_ERROR) */
 
4468
 
 
4469
                /* -----------------------------------------------------
 
4470
                 * ospmAuthIndDestinationAlternate (DestinationAlternate)
 
4471
                 * -----------------------------------------------------
 
4472
                 */
 
4473
 
 
4474
                if(errorcode == OSPC_ERR_NO_ERROR)
 
4475
                {
 
4476
 
 
4477
                    if((ospvDestination != OSPC_OSNULL) ||
 
4478
                        (ospvDestinationDevice != OSPC_OSNULL)|| (trans->DstNetworkId!= OSPC_OSNULL))
 
4479
                    {
 
4480
 
 
4481
                        /* destination alternates - create a linked list */
 
4482
                        OSPPListNew((OSPTLIST *)&(trans->AuthInd->ospmAuthIndDestinationAlternate));
 
4483
 
 
4484
 
 
4485
                        /*
 
4486
                         * We want to copy the Dst Trnk Group from the 
 
4487
                         * Transaction Structure only when the tokenInfo
 
4488
                         * does not contain the Network Id.
 
4489
                         * Thus, we are overwriting what had been Set using
 
4490
                         * the SetNetworkIds API
 
4491
                         */
 
4492
                        if ((trans->DstNetworkId != OSPC_OSNULL) && tokeninfo && 
 
4493
                            (tokeninfo->ospmTokenInfoIsDstNetworkIdPresent == OSPC_FALSE))
 
4494
                        {
 
4495
 
 
4496
                            altinfo = OSPPAltInfoNew(OSPM_STRLEN(trans->DstNetworkId), 
 
4497
                                (const unsigned char *)trans->DstNetworkId,
 
4498
                                ospeNetwork);
 
4499
 
 
4500
                            if(altinfo != OSPC_OSNULL)
 
4501
                            {
 
4502
 
 
4503
                                OSPPListAppend(
 
4504
                                    (OSPTLIST *)&(trans->AuthInd->ospmAuthIndDestinationAlternate),
 
4505
                                    (void *)altinfo);
 
4506
                            }
 
4507
                        }
 
4508
 
 
4509
                        altinfo = OSPC_OSNULL;
 
4510
 
 
4511
                        if(ospvDestination != OSPC_OSNULL)
 
4512
                        {
 
4513
 
 
4514
                            altinfo = 
 
4515
                                OSPPAltInfoNew(OSPM_STRLEN(ospvDestination), 
 
4516
                                (const unsigned char *)ospvDestination,
 
4517
                                ospeTransport);
 
4518
 
 
4519
                            if(altinfo != OSPC_OSNULL)
 
4520
                            {
 
4521
 
 
4522
                                OSPPListAppend(
 
4523
                                    (OSPTLIST *)&(trans->AuthInd->ospmAuthIndDestinationAlternate),
 
4524
                                    (void *)altinfo);
 
4525
                            }
 
4526
                        }
 
4527
 
 
4528
                        altinfo = OSPC_OSNULL;
 
4529
 
 
4530
                        if(ospvDestinationDevice != OSPC_OSNULL)
 
4531
                        {
 
4532
 
 
4533
                            altinfo = OSPPAltInfoNew(OSPM_STRLEN(ospvDestinationDevice),
 
4534
                                (const unsigned char *)ospvDestinationDevice,
 
4535
                                ospeH323);
 
4536
 
 
4537
                            if(altinfo != OSPC_OSNULL)
 
4538
                            {
 
4539
 
 
4540
                                OSPPListAppend(
 
4541
                                    (OSPTLIST *)&(trans->AuthInd->ospmAuthIndDestinationAlternate),
 
4542
                                    (void *)altinfo);
 
4543
                            }
 
4544
                        } /* end if ospvDestinationDevice != OSPC_OSNULL */
 
4545
                    }
 
4546
                    else
 
4547
                    {
 
4548
                        errorcode = OSPC_ERR_TRAN_DEST_INVALID;
 
4549
                    }
 
4550
                } /* end  if(errorcode == OSPC_ERR_NO_ERROR) */
 
4551
            }
 
4552
        }
 
4553
        else
 
4554
        {
 
4555
            /* authind already here, make sure it is the right one */
 
4556
            retcode = OSPM_STRCMP((const char *)OSPPAuthIndGetDestNumber(trans->AuthInd),
 
4557
                                    ospvCalledNumber);
 
4558
 
 
4559
            if(retcode != 0)
 
4560
            {
 
4561
                errorcode = OSPC_ERR_TRAN_TOKEN_INVALID;
 
4562
                OSPM_DBGERRORLOG(errorcode, "Called number does not match");
 
4563
            }
 
4564
            else
 
4565
            {
 
4566
               retcode = OSPM_STRCMP((const char *)OSPPAuthIndGetSourceNumber(trans->AuthInd),
 
4567
                                    ospvCallingNumber);
 
4568
 
 
4569
                if(retcode != 0)
 
4570
                {
 
4571
                    errorcode = OSPC_ERR_TRAN_TOKEN_INVALID;
 
4572
                    OSPM_DBGERRORLOG(errorcode, "Calling number does not match");
 
4573
                }
 
4574
            }
 
4575
 
 
4576
            if(errorcode == OSPC_ERR_NO_ERROR)
 
4577
            {
 
4578
 
 
4579
                if(trans->AuthInd->ospmAuthIndTokens != (OSPTLIST)OSPC_OSNULL)
 
4580
                {
 
4581
 
 
4582
                    token = OSPPTokenNew(ospvSizeOfToken, 
 
4583
                        (const unsigned char *)ospvToken);
 
4584
 
 
4585
                    if(token != (OSPTTOKEN *)OSPC_OSNULL)
 
4586
                    {
 
4587
                        OSPPListAppend (&(trans->AuthInd->ospmAuthIndTokens), 
 
4588
                            (void *)token);
 
4589
                    }
 
4590
                    else
 
4591
                    {
 
4592
                        errorcode = OSPC_ERR_TRAN_TOKEN_NOT_FOUND;
 
4593
                        OSPM_DBGERRORLOG(errorcode, "token is null");
 
4594
                    }
 
4595
                }
 
4596
                else
 
4597
                {
 
4598
                    errorcode = OSPC_ERR_TRAN_LIST_NOT_FOUND;
 
4599
                    OSPM_DBGERRORLOG(errorcode, "list is null");
 
4600
                }
 
4601
            }
 
4602
        }
 
4603
    }
 
4604
 
 
4605
    /*
 
4606
     * Now that we have a complete AuthInd, let's verify it against
 
4607
     * the token received
 
4608
     */
 
4609
    if (errorcode == OSPC_ERR_NO_ERROR) 
 
4610
    {
 
4611
        /* 
 
4612
         * The token validation part has been moved from here to the
 
4613
         * the top. This is so that we may extract the call Id from
 
4614
         * the token early enough.
 
4615
         */
 
4616
 
 
4617
        /*
 
4618
         * If Forward Route information is present, 
 
4619
         * Store it in the transaction object
 
4620
         */
 
4621
        if (tokeninfo != NULL)
 
4622
        {
 
4623
            trans->TokenInfoIsLookAheadInfoPresent = tokeninfo->ospmTokenInfoIsLookAheadInfoPresent; 
 
4624
        }
 
4625
 
 
4626
        if (trans->TokenInfoIsLookAheadInfoPresent)
 
4627
        {
 
4628
            /*
 
4629
             * Set the destination
 
4630
             */
 
4631
           OSPPTokenInfoSetLookAheadDestAlt(&(trans->TokenLookAheadInfo),
 
4632
                                            OSPPTokenInfoGetLookAheadDestAlt(&(tokeninfo->ospmTokenLookAheadInfo))); 
 
4633
 
 
4634
           /*
 
4635
            * Set the destination Protocol
 
4636
            */
 
4637
           dstProt = OSPPTokenInfoGetLookAheadDestProtocol(&(tokeninfo->ospmTokenLookAheadInfo));
 
4638
           trans->TokenLookAheadInfo.lookAheadDestProt = dstProt;
 
4639
            
 
4640
          /* 
 
4641
           * Set the OSP Version
 
4642
           */
 
4643
          dstOSPStatus = OSPPTokenInfoGetLookAheadOSPVersion(&(tokeninfo->ospmTokenLookAheadInfo));
 
4644
          trans->TokenLookAheadInfo.lookAheadDestOSPStatus =  dstOSPStatus;
 
4645
        }
 
4646
 
 
4647
        /*
 
4648
         * If the token contains the Network Id 
 
4649
         * then add that to the list of destination Alternates
 
4650
         */
 
4651
         if (tokeninfo && (tokeninfo->ospmTokenInfoIsDstNetworkIdPresent == OSPC_TRUE))
 
4652
         {
 
4653
             altinfo = NULL;
 
4654
             altinfo = OSPPAltInfoNew(OSPM_STRLEN((char *)OSPPTokenInfoGetDstNetworkId(tokeninfo)), 
 
4655
                                (const unsigned char *)OSPPTokenInfoGetDstNetworkId(tokeninfo),
 
4656
                                ospeNetwork);
 
4657
 
 
4658
             if(altinfo != OSPC_OSNULL)
 
4659
             {
 
4660
 
 
4661
                 OSPPListAppend(
 
4662
                     (OSPTLIST *)&(trans->AuthInd->ospmAuthIndDestinationAlternate),
 
4663
                     (void *)altinfo);
 
4664
             }
 
4665
             altinfo = NULL;
 
4666
             trans->AuthInd->ospmAuthIndHasDestNetworkIdInToken = OSPC_TRUE;
 
4667
         }
 
4668
 
 
4669
 
 
4670
        if (errorcode == OSPC_ERR_NO_ERROR && dtype == OSPC_MSG_TOKINFO)
 
4671
        {
 
4672
 
 
4673
            /*
 
4674
             * Verify Source Number
 
4675
             */
 
4676
            retcode = OSPM_STRCMP((const char *)OSPPAuthIndGetSourceNumber(trans->AuthInd),
 
4677
                                    (const char *)OSPPTokenInfoGetSourceNumber(tokeninfo));
 
4678
 
 
4679
            if (retcode != 0)
 
4680
            {
 
4681
                errorcode = OSPC_ERR_TRAN_TOKEN_INVALID;
 
4682
                OSPM_DBGERRORLOG(errorcode, "information does not match");
 
4683
            }
 
4684
            else
 
4685
            {
 
4686
                /*
 
4687
                 * Verify Destination Number
 
4688
                 */
 
4689
                retcode = OSPM_STRCMP((const char *)OSPPAuthIndGetDestNumber(trans->AuthInd),
 
4690
                                    (const char *)OSPPTokenInfoGetDestNumber(tokeninfo));
 
4691
 
 
4692
                if (retcode != 0)
 
4693
                {
 
4694
                    errorcode = OSPC_ERR_TRAN_TOKEN_INVALID;
 
4695
                    OSPM_DBGERRORLOG(errorcode, "information does not match");
 
4696
                }
 
4697
                else
 
4698
                {
 
4699
                    /*
 
4700
                     * Verify CallId
 
4701
                     */
 
4702
                    if ((CallIdValue != OSPC_OSNULL) && 
 
4703
                        ((AuthIndCallId=OSPPAuthIndGetCallIdValue(trans->AuthInd)) != OSPC_OSNULL) && 
 
4704
                        (ospvSizeOfCallId > 0) &&
 
4705
                        (callidundefined == OSPC_FALSE))
 
4706
                    {
 
4707
                        retcode = OSPM_MEMCMP(AuthIndCallId,
 
4708
                                  CallIdValue, ospvSizeOfCallId); 
 
4709
                    }
 
4710
 
 
4711
                    if (retcode != 0)
 
4712
                    {
 
4713
                        errorcode = OSPC_ERR_TRAN_TOKEN_INVALID;
 
4714
                        OSPM_DBGERRORLOG(errorcode, "information does not match");
 
4715
                    }
 
4716
                    else
 
4717
                    {
 
4718
                        /*
 
4719
                         * Verify Valid After
 
4720
                         */
 
4721
                        if (time((time_t *)0) <  OSPPTokenInfoGetValidAfter(tokeninfo))
 
4722
                        {
 
4723
                            errorcode = OSPC_ERR_TRAN_TOO_SOON_TO_USE_TOKEN;
 
4724
                            OSPM_DBGERRORLOG(errorcode, "too soon to use token");
 
4725
                        }
 
4726
                        else
 
4727
                        {
 
4728
                            /*
 
4729
                             * Verify Valid Until
 
4730
                             */
 
4731
                            if (time((time_t *)0) >  OSPPTokenInfoGetValidUntil(tokeninfo))
 
4732
                            {
 
4733
                                errorcode = OSPC_ERR_TRAN_TOO_LATE_TO_USE_TOKEN;
 
4734
                                OSPM_DBGERRORLOG(errorcode, "too late to use token");
 
4735
                            }
 
4736
                        }
 
4737
                    }
 
4738
                }
 
4739
            }
 
4740
            if (errorcode == OSPC_ERR_NO_ERROR)
 
4741
            {
 
4742
                /*
 
4743
                 * Add transaction id to transactionid tree and check for reuse.
 
4744
                 */
 
4745
#ifdef OSP_ALLOW_DUP_TXN
 
4746
                BAllowDupTransId = OSPC_TRUE;
 
4747
#else
 
4748
                BAllowDupTransId = OSPC_FALSE;
 
4749
#endif
 
4750
                if (BAllowDupTransId ||
 
4751
                    (OSPPTransIdCheckAndAdd(OSPPTokenInfoGetTrxId(tokeninfo), 
 
4752
                                         (unsigned long)OSPPTokenInfoGetValidUntil(tokeninfo), 
 
4753
                                          trans->Provider)))
 
4754
                {
 
4755
 
 
4756
                    /*
 
4757
                     * Populate Transaction Id
 
4758
                     */
 
4759
                    trans->TransactionID = OSPPTokenInfoGetTrxId(tokeninfo);
 
4760
                    trans->HasTransactionID = OSPC_TRUE;
 
4761
 
 
4762
                    *ospvAuthorised = OSPC_TRAN_AUTHORISED;
 
4763
                    *ospvTimeLimit = (unsigned)OSPPTokenInfoGetDuration(tokeninfo);
 
4764
                    OSPPAuthIndSetTimeLimit(trans->AuthInd, *ospvTimeLimit);
 
4765
                }
 
4766
                else
 
4767
                {
 
4768
                    errorcode = OSPC_ERR_TRAN_TOKEN_REUSE;
 
4769
                    OSPM_DBGERRORLOG(errorcode, "attemp to reuse token");
 
4770
                }
 
4771
            }
 
4772
        }
 
4773
    }
 
4774
 
 
4775
    if(tokeninfo != OSPC_OSNULL)
 
4776
    {
 
4777
        OSPPTokenInfoDelete(&tokeninfo);
 
4778
        tokeninfo = OSPC_OSNULL;
 
4779
    }
 
4780
 
 
4781
    if (tokenmsg != OSPC_OSNULL)
 
4782
    {
 
4783
        OSPM_FREE(tokenmsg);
 
4784
        tokenmsg = OSPC_OSNULL;
 
4785
    }
 
4786
 
 
4787
    /* Set transaction state */
 
4788
    if (errorcode == OSPC_ERR_NO_ERROR)
 
4789
        OSPPTransactionSetState(trans, OSPC_VALIDATE_AUTH_SUCCESS);
 
4790
    else
 
4791
    {
 
4792
        OSPPTransactionSetState(trans, OSPC_VALIDATE_AUTH_FAIL);
 
4793
    }
 
4794
    return errorcode;
 
4795
}
 
4796
 
 
4797
int
 
4798
OSPPTransactionValidateReAuthorisation(
 
4799
    OSPTTRANHANDLE      ospvTransaction,      /* In - Transaction handle */
 
4800
    unsigned            ospvSizeOfToken,      /* In - Size of authorization token */
 
4801
    const void          *ospvToken,           /* In - Authorisation token */
 
4802
    unsigned            *ospvAuthorised,      /* Out - Call authorisation indicator */
 
4803
    unsigned            *ospvTimeLimit,       /* Out - Number of seconds call is authorised for */
 
4804
    unsigned            *ospvSizeOfDetailLog, /* In/Out - Max size of detail log\ Actual size of detail log */
 
4805
    void                *ospvDetailLog,       /* In - Pointer to storage for detail log */
 
4806
    unsigned            ospvTokenAlgo)          /* In - Algorithm to be used for Validating Token */
 
4807
{
 
4808
    int         errorcode       = OSPC_ERR_NO_ERROR;
 
4809
    OSPTTRANS   *trans          = OSPC_OSNULL;
 
4810
    OSPTALTINFO *source         = OSPC_OSNULL,
 
4811
        *sourcealt      = OSPC_OSNULL,
 
4812
        *destination    = OSPC_OSNULL,
 
4813
        *destalt        = OSPC_OSNULL;
 
4814
    const char  *sourceval      = OSPC_OSNULL,
 
4815
                *sourcealtval   = OSPC_OSNULL,
 
4816
                *destval        = OSPC_OSNULL,
 
4817
                *destaltval     = OSPC_OSNULL;
 
4818
 
 
4819
    /* Validate will verify input */
 
4820
 
 
4821
    /* Get transaction context */
 
4822
    if (errorcode == OSPC_ERR_NO_ERROR)
 
4823
    {
 
4824
        trans = OSPPTransactionGetContext(ospvTransaction, 
 
4825
            &errorcode);
 
4826
    }
 
4827
 
 
4828
    /* Make sure this is a terminating gateway */
 
4829
    if(errorcode == OSPC_ERR_NO_ERROR)
 
4830
    {
 
4831
        if(trans->AuthRsp != OSPC_OSNULL)
 
4832
        {
 
4833
            errorcode = OSPC_ERR_TRAN_TRANSACTION_NOT_ALLOWED;
 
4834
        }
 
4835
    }
 
4836
 
 
4837
    /* Make sure we have an AuthInd */
 
4838
    if(trans->AuthInd != OSPC_OSNULL)
 
4839
    {
 
4840
        source = (OSPTALTINFO *)OSPPAuthIndFirstSourceAlt(trans->AuthInd);
 
4841
        if(source != OSPC_OSNULL)
 
4842
        {
 
4843
            sourceval = (const char *)OSPPAuthIndGetSourceAltValue(source);
 
4844
 
 
4845
            sourcealt = (OSPTALTINFO *)OSPPAuthIndNextSourceAlt(trans->AuthInd, source);
 
4846
            if(sourcealt != OSPC_OSNULL)
 
4847
            {
 
4848
                sourcealtval = (const char *)OSPPAuthIndGetSourceAltValue(sourcealt);
 
4849
            }
 
4850
        }
 
4851
 
 
4852
        destination = (OSPTALTINFO *)OSPPAuthIndFirstDestinationAlt(trans->AuthInd);
 
4853
        if(destination != OSPC_OSNULL)
 
4854
        {
 
4855
            destval = (const char *)OSPPAuthIndGetDestinationAltValue(destination);
 
4856
 
 
4857
            destalt = (OSPTALTINFO *)OSPPAuthIndNextDestinationAlt(trans->AuthInd, destination);
 
4858
            if(destalt != OSPC_OSNULL)
 
4859
            {
 
4860
                destaltval = (const char *)OSPPAuthIndGetDestinationAltValue(destalt);
 
4861
            }
 
4862
        }
 
4863
 
 
4864
        /* call ValidateAuthorisation */
 
4865
        if(errorcode == OSPC_ERR_NO_ERROR)
 
4866
        {
 
4867
            errorcode = OSPPTransactionValidateAuthorisation(ospvTransaction, 
 
4868
                sourceval,                
 
4869
                destval,  
 
4870
                sourcealtval,                
 
4871
                destaltval, 
 
4872
                (const char *)OSPPAuthIndGetSourceNumber(trans->AuthInd),         
 
4873
                trans->CallingNumberFormat,
 
4874
                (const char *)OSPPAuthIndGetDestNumber(trans->AuthInd), 
 
4875
                trans->CalledNumberFormat,
 
4876
                OSPPAuthIndGetCallIdSize(trans->AuthInd),           
 
4877
                (const void *)OSPPAuthIndGetCallIdValue(trans->AuthInd), 
 
4878
                ospvSizeOfToken,            
 
4879
                ospvToken,  ospvAuthorised,            
 
4880
                ospvTimeLimit, ospvSizeOfDetailLog,       
 
4881
                ospvDetailLog,ospvTokenAlgo);
 
4882
        }
 
4883
    }
 
4884
 
 
4885
    return errorcode;
 
4886
}
 
4887
 
 
4888
 
 
4889
 
 
4890
 
 
4891
 
 
4892
 
 
4893
 
 
4894
 
 
4895
 
 
4896
 
 
4897
 
 
4898
 
 
4899
 
 
4900
/*
 
4901
 * The OSPPTransactionIndicateCapability function allows an application to 
 
4902
 * indicate its availability.
 
4903
 * The parameters to the function are:
 
4904
 *  ospvTransaction: handle of the (previously created) transaction object.
 
4905
 *  ospvSource: character string identifying the source of the call. The value 
 
4906
 *      is expressed as either a DNS name or an IP address enclosed in square 
 
4907
 *      brackets, followed by an optional colon and TCP port number. 
 
4908
 *      Examples of valid sources include "gateway1.carrier.com" and 
 
4909
 *                                                      "[172.16.1.2]:112".
 
4910
 *  ospvSourceDevice: character string identifying the source device. 
 
4911
 *      This could be the previous hop Gateway.
 
4912
 *      It is expressed as either a DNS name or an IP address enclosed in square 
 
4913
 *      brackets, followed by an optional colon and TCP port number. 
 
4914
 *      Examples of valid sources include "gateway1.carrier.com" and 
 
4915
 *                                                  "[172.16.1.2]:112".
 
4916
 *      This string is optional and may be empty.
 
4917
 * ospvAlmostOutOfResources: a Boolean value to indicate whether or not the  
 
4918
 *      is about to run out of resources.  The value can also be used to 
 
4919
 *      indicate that a device is about to go off-line or come on-line.
 
4920
 *  ospvSizeOfDetailLog: pointer to a variable which, on input, contains the 
 
4921
 *      maximum size of the detail log; on output, the variable will be updated
 
4922
 *      with the actual size of the detail log. By setting this value to zero, 
 
4923
 *      applications indicate that they do not wish a detail log for the 
 
4924
 *      authorisation request.
 
4925
 *  ospvDetailLog: pointer to a location in which to store a detail log for the
 
4926
 *      authorisation request. If this pointer is not NULL, and if the 
 
4927
 *      ospvSizeOfDetailLog parameter is non-zero, then the library will store 
 
4928
 *      a copy of the authorisation response obtained from the settlement 
 
4929
 *      provider, including the settlement provider's digital signature.
 
4930
 * As delivered in the SDK library, this function blocks until confirmation 
 
4931
 * has been received or an error has been detected. The Open Settlement 
 
4932
 * Protocol SDK Porting Guide includes information on modifying that behavior 
 
4933
 * to prevent blocking.
 
4934
 * The function returns an error code or zero (if the operation was successful)
 
4935
 * Specific error codes and their meanings can be found in the osperrno.h file.
 
4936
 */
 
4937
 
 
4938
int
 
4939
OSPPTransactionIndicateCapabilities(
 
4940
    OSPTTRANHANDLE  ospvTransaction,            /* In - Transaction handle */
 
4941
    const char      *ospvSource,                /* In - Source of call */
 
4942
    const char      *ospvSourceDevice,          /* In - SourceDevice of call */
 
4943
    const char      *ospvSourceNetworkId,       /* In - NetworkId of call. Could be trunk grp */
 
4944
    unsigned         ospvAlmostOutOfResources,  /* In - Boolean almost out of resources indicator */
 
4945
    unsigned        *ospvSizeOfDetailLog,       /* In/Out - Max size of detail log Actual size of detail log */
 
4946
    void            *ospvDetailLog)             /* In/Out - Location of detail log storage */
 
4947
{
 
4948
    int            errorcode   = OSPC_ERR_NO_ERROR;
 
4949
    OSPTTRANS     *trans       = OSPC_OSNULL;
 
4950
    OSPTMSGINFO   *msginfo     = OSPC_OSNULL;
 
4951
    unsigned char *xmldoc      = OSPC_OSNULL;
 
4952
    unsigned       sizeofxmldoc= 0;
 
4953
    OSPTCAPIND    *capind      = OSPC_OSNULL;
 
4954
 
 
4955
    OSPM_ARGUSED(ospvSizeOfDetailLog);
 
4956
    OSPM_ARGUSED(ospvDetailLog);
 
4957
 
 
4958
 
 
4959
    /*
 
4960
     * Validate input parameters - Source and SourceDevice must not be NULLs
 
4961
     */
 
4962
    if (OSPC_OSNULL == ospvSource ||
 
4963
        OSPC_OSNULL == ospvSourceDevice)
 
4964
    {
 
4965
        errorcode = OSPC_ERR_TRAN_INVALID_ENTRY;
 
4966
        OSPM_DBGERRORLOG(errorcode, "Invalid input for OSPPTransactionIndicateCapabilities");
 
4967
        OSPM_DBGERRORLOG(errorcode, "ospvSource and ospvSourceDevice must not be NULLs");
 
4968
    }
 
4969
 
 
4970
 
 
4971
    /*
 
4972
     * Get transaction context, the call can fail if the transaction
 
4973
     * handle passed to the function is not valid.
 
4974
     */
 
4975
    if (OSPC_ERR_NO_ERROR == errorcode)
 
4976
    {
 
4977
        trans = OSPPTransactionGetContext(ospvTransaction, &errorcode);
 
4978
    }
 
4979
 
 
4980
 
 
4981
    /*
 
4982
     * Insure that the transaction does not already have a capability
 
4983
     * response, auth response, or token structures assigned to it.
 
4984
     */
 
4985
    if (OSPC_ERR_NO_ERROR == errorcode)
 
4986
    {
 
4987
        if (OSPC_OSNULL != trans->CapCnf)
 
4988
        {
 
4989
            errorcode =OSPC_ERR_TRAN_DUPLICATE_REQUEST;
 
4990
            OSPM_DBGERRORLOG(errorcode,"Duplicate Call To OSPPTransactionIndicateCapabilities");
 
4991
        }
 
4992
        else if (OSPC_OSNULL != trans->AuthRsp || OSPC_OSNULL != trans->AuthInd)
 
4993
        {
 
4994
            errorcode = OSPC_ERR_TRAN_REQ_OUT_OF_SEQ;
 
4995
            OSPM_DBGERRORLOG(errorcode, "Called API Not In Sequence \n");
 
4996
        }
 
4997
    }
 
4998
 
 
4999
    /*
 
5000
     * 
 
5001
     * Input parameters and state validation are over, we are off to the business logic
 
5002
     *
 
5003
     */
 
5004
    if (OSPC_ERR_NO_ERROR == errorcode)
 
5005
    {
 
5006
        /*
 
5007
         * Create and initialize new Capability Indication structure
 
5008
         */
 
5009
        errorcode = OSPPCapIndNew(&capind,trans,ospvSource,ospvSourceDevice,ospvSourceNetworkId,ospvAlmostOutOfResources);
 
5010
    
 
5011
    
 
5012
 
 
5013
        /*
 
5014
         * XML-encode the structure
 
5015
         */
 
5016
        if (OSPC_ERR_NO_ERROR == errorcode)
 
5017
        {
 
5018
            errorcode = OSPPXMLMessageCreate(OSPC_MSG_CAPIND,&xmldoc,&sizeofxmldoc,capind,trans);
 
5019
        }
 
5020
 
 
5021
 
 
5022
        /*
 
5023
         * Prepare a structure for sending the message over the network
 
5024
         */
 
5025
        if (OSPC_ERR_NO_ERROR == errorcode)
 
5026
        {
 
5027
            errorcode = OSPPMsgInfoNew(&msginfo);
 
5028
        }
 
5029
        
 
5030
 
 
5031
        /*
 
5032
         * Hand off the request to a communication manager and block waiting for a response.
 
5033
         * The function will decide which comm manager should handle the call.
 
5034
         * The function call will not return untill a valid response is received or all 
 
5035
         * service points and retries have been exausted.
 
5036
         */
 
5037
        if (OSPC_ERR_NO_ERROR == errorcode)
 
5038
        {    
 
5039
            OSPPTransactionSetState(trans, OSPC_CAP_IND_BLOCK);
 
5040
 
 
5041
            errorcode = OSPPTransactionPrepareAndQueMessage(trans, xmldoc, sizeofxmldoc, &msginfo);
 
5042
        }
 
5043
 
 
5044
 
 
5045
        /*
 
5046
         * Parse the XML message, build a response structure and assign it to the
 
5047
         * transaction object.  The structure will be released when the transaction
 
5048
         * is deleted
 
5049
         */
 
5050
        if (OSPC_ERR_NO_ERROR == errorcode)
 
5051
        {
 
5052
            errorcode = OSPPTransactionProcessReturn(trans, msginfo);
 
5053
        }
 
5054
 
 
5055
        /*
 
5056
         * If the response code is above 299, translate it to an error code
 
5057
         */
 
5058
        if (OSPC_ERR_NO_ERROR == errorcode)
 
5059
        {
 
5060
            if (trans->CapCnf->ospmStatus->ospmStatusCode > 299)
 
5061
            {
 
5062
                errorcode = OSPPUtilGetErrorFromStatus(trans->CapCnf->ospmStatus->ospmStatusCode);
 
5063
            }
 
5064
        }
 
5065
 
 
5066
        /*
 
5067
         * Update the transaction status based on the error code
 
5068
         */
 
5069
        if (OSPC_ERR_NO_ERROR == errorcode)
 
5070
        {
 
5071
            OSPPTransactionSetState(trans, OSPC_CAP_IND_SUCCESS);
 
5072
        }
 
5073
        else
 
5074
        {
 
5075
            OSPPTransactionSetState(trans, OSPC_CAP_IND_FAIL);
 
5076
        }
 
5077
    }
 
5078
    else
 
5079
    {
 
5080
        /* Data or state validation must have failed */
 
5081
    }
 
5082
 
 
5083
 
 
5084
    /*
 
5085
     *
 
5086
     * Clean-up temporary objects
 
5087
     *
 
5088
     */
 
5089
    if (OSPC_OSNULL != xmldoc)
 
5090
    {
 
5091
        OSPM_FREE(xmldoc);
 
5092
        xmldoc = NULL;
 
5093
    }
 
5094
 
 
5095
    if (OSPC_OSNULL != capind)
 
5096
    {
 
5097
        OSPPCapIndDelete(&capind);
 
5098
    }
 
5099
 
 
5100
    if (OSPC_OSNULL != msginfo)
 
5101
    {
 
5102
        OSPPMsgInfoDelete(&msginfo);
 
5103
    }
 
5104
 
 
5105
    return errorcode;
 
5106
}