00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include "asterisk.h"
00038
00039 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 370655 $")
00040
00041 #include <osp/osp.h>
00042 #include <osp/osputils.h>
00043 #include <osp/ospb64.h>
00044
00045 #include "asterisk/paths.h"
00046 #include "asterisk/lock.h"
00047 #include "asterisk/config.h"
00048 #include "asterisk/utils.h"
00049 #include "asterisk/causes.h"
00050 #include "asterisk/channel.h"
00051 #include "asterisk/app.h"
00052 #include "asterisk/module.h"
00053 #include "asterisk/pbx.h"
00054 #include "asterisk/cli.h"
00055 #include "asterisk/astosp.h"
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442 #define OSP_SIZE_INTSTR ((unsigned int)16)
00443 #define OSP_SIZE_NORSTR ((unsigned int)256)
00444 #define OSP_SIZE_KEYSTR ((unsigned int)1024)
00445 #define OSP_SIZE_TOKSTR ((unsigned int)4096)
00446 #define OSP_SIZE_TECHSTR ((unsigned int)32)
00447 #define OSP_SIZE_UUID ((unsigned int)16)
00448 #define OSP_SIZE_UUIDSTR ((unsigned int)36)
00449 #define OSP_SIZE_QOSSTR ((unsigned int)1024)
00450
00451
00452 #define OSP_CALLID_UNDEF ((unsigned int)0)
00453 #define OSP_CALLID_SIP ((unsigned int)(1 << 0))
00454 #define OSP_CALLID_H323 ((unsigned int)(1 << 1))
00455 #define OSP_CALLID_IAX ((unsigned int)(1 << 2))
00456 #define OSP_CALLID_MAXNUM ((unsigned int)3)
00457
00458
00459 #define OSP_PROT_SIP ((const char*)"SIP")
00460 #define OSP_PROT_H323 ((const char*)"H323")
00461 #define OSP_PROT_IAX ((const char*)"IAX")
00462 #define OSP_PROT_SKYPE ((const char*)"SKYPE")
00463
00464
00465 #define OSP_TECH_SIP ((const char*)"SIP")
00466 #define OSP_TECH_H323 ((const char*)"H323")
00467 #define OSP_TECH_IAX ((const char*)"IAX2")
00468 #define OSP_TECH_SKYPE ((const char*)"SKYPE")
00469
00470
00471 #define OSP_SIP_HEADER ((const char*)"P-OSP-Auth-Token")
00472
00473
00474 enum osp_authpolicy {
00475 OSP_AUTH_NO = 0,
00476 OSP_AUTH_YES,
00477 OSP_AUTH_EXC
00478 };
00479
00480
00481 enum osp_workmode {
00482 OSP_MODE_DIRECT= 0,
00483 OSP_MODE_INDIRECT
00484 };
00485
00486
00487 enum osp_srvtype {
00488 OSP_SRV_VOICE = 0,
00489 OSP_SRV_NPQUERY
00490 };
00491
00492
00493 #define OSP_OK ((int)1)
00494 #define OSP_FAILED ((int)0)
00495 #define OSP_ERROR ((int)-1)
00496 #define OSP_AST_OK ((int)0)
00497 #define OSP_AST_ERROR ((int)-1)
00498 #define OSP_INVALID_HANDLE ((int)-1)
00499 #define OSP_CONFIG_FILE ((const char*)"osp.conf")
00500 #define OSP_GENERAL_CAT ((const char*)"general")
00501 #define OSP_DEF_PROVIDER ((const char*)"default")
00502 #define OSP_MAX_CERTS ((unsigned int)10)
00503 #define OSP_MAX_SPOINTS ((unsigned int)10)
00504 #define OSP_DEF_MAXCONNECT ((unsigned int)20)
00505 #define OSP_MIN_MAXCONNECT ((unsigned int)1)
00506 #define OSP_MAX_MAXCONNECT ((unsigned int)1000)
00507 #define OSP_DEF_RETRYDELAY ((unsigned int)0)
00508 #define OSP_MIN_RETRYDELAY ((unsigned int)0)
00509 #define OSP_MAX_RETRYDELAY ((unsigned int)10)
00510 #define OSP_DEF_RETRYLIMIT ((unsigned int)2)
00511 #define OSP_MIN_RETRYLIMIT ((unsigned int)0)
00512 #define OSP_MAX_RETRYLIMIT ((unsigned int)100)
00513 #define OSP_DEF_TIMEOUT ((unsigned int)500)
00514 #define OSP_MIN_TIMEOUT ((unsigned int)200)
00515 #define OSP_MAX_TIMEOUT ((unsigned int)10000)
00516 #define OSP_DEF_AUTHPOLICY OSP_AUTH_YES
00517 #define OSP_AUDIT_URL ((const char*)"localhost")
00518 #define OSP_LOCAL_VALIDATION ((int)1)
00519 #define OSP_SSL_LIFETIME ((unsigned int)300)
00520 #define OSP_HTTP_PERSISTENCE ((int)1)
00521 #define OSP_CUSTOMER_ID ((const char*)"")
00522 #define OSP_DEVICE_ID ((const char*)"")
00523 #define OSP_DEF_MAXDESTS ((unsigned int)12)
00524 #define OSP_DEF_TIMELIMIT ((unsigned int)0)
00525 #define OSP_DEF_PROTOCOL OSP_PROT_SIP
00526 #define OSP_DEF_WORKMODE OSP_MODE_DIRECT
00527 #define OSP_DEF_SRVTYPE OSP_SRV_VOICE
00528 #define OSP_MAX_CUSTOMINFO ((unsigned int)8)
00529 #define OSP_DEF_INTSTATS ((int)-1)
00530 #define OSP_DEF_FLOATSTATS ((float)-1)
00531
00532
00533 struct osp_provider {
00534 OSPTPROVHANDLE handle;
00535 char name[OSP_SIZE_NORSTR];
00536 char privatekey[OSP_SIZE_NORSTR];
00537 char localcert[OSP_SIZE_NORSTR];
00538 unsigned int canum;
00539 char cacerts[OSP_MAX_CERTS][OSP_SIZE_NORSTR];
00540 unsigned int spnum;
00541 char spoints[OSP_MAX_SPOINTS][OSP_SIZE_NORSTR];
00542 unsigned int maxconnect;
00543 unsigned int retrydelay;
00544 unsigned int retrylimit;
00545 unsigned int timeout;
00546 char source[OSP_SIZE_NORSTR];
00547 enum osp_authpolicy authpolicy;
00548 const char* defprotocol;
00549 enum osp_workmode workmode;
00550 enum osp_srvtype srvtype;
00551 struct osp_provider* next;
00552 };
00553
00554
00555 struct osp_callid {
00556 unsigned char buf[OSP_SIZE_NORSTR];
00557 unsigned int len;
00558 };
00559
00560
00561 struct osp_npdata {
00562 const char* rn;
00563 const char* cic;
00564 int npdi;
00565 const char* opname[OSPC_OPNAME_NUMBER];
00566 };
00567
00568
00569 struct osp_headers {
00570 const char* rpiduser;
00571 const char* paiuser;
00572 const char* divuser;
00573 const char* divhost;
00574 const char* pciuser;
00575 };
00576
00577
00578 struct osp_results {
00579 int inhandle;
00580 int outhandle;
00581 unsigned int intimelimit;
00582 unsigned int outtimelimit;
00583 char intech[OSP_SIZE_TECHSTR];
00584 char outtech[OSP_SIZE_TECHSTR];
00585 char dest[OSP_SIZE_NORSTR];
00586 char calling[OSP_SIZE_NORSTR];
00587 char called[OSP_SIZE_NORSTR];
00588 char token[OSP_SIZE_TOKSTR];
00589 char networkid[OSP_SIZE_NORSTR];
00590 char nprn[OSP_SIZE_NORSTR];
00591 char npcic[OSP_SIZE_NORSTR];
00592 int npdi;
00593 char opname[OSPC_OPNAME_NUMBER][OSP_SIZE_NORSTR];
00594 unsigned int numdests;
00595 struct osp_callid outcallid;
00596 };
00597
00598
00599 enum osp_callleg {
00600 OSP_CALL_INBOUND,
00601 OSP_CALL_OUTBOUND
00602 };
00603
00604
00605 enum osp_direction {
00606 OSP_DIR_RX = 0,
00607 OSP_DIR_TX,
00608 OSP_DIR_NUMBER
00609 };
00610
00611
00612 struct osp_metrics {
00613 int value;
00614 float min;
00615 float max;
00616 float avg;
00617 float sdev;
00618 };
00619
00620
00621 AST_MUTEX_DEFINE_STATIC(osp_lock);
00622 static int osp_initialized = 0;
00623 static int osp_hardware = 0;
00624 static int osp_security = 0;
00625 static struct osp_provider* osp_providers = NULL;
00626 static unsigned int osp_tokenformat = TOKEN_ALGO_SIGNED;
00627
00628
00629 const char* B64PKey = "MIIBOgIBAAJBAK8t5l+PUbTC4lvwlNxV5lpl+2dwSZGW46dowTe6y133XyVEwNiiRma2YNk3xKs/TJ3Wl9Wpns2SYEAJsFfSTukCAwEAAQJAPz13vCm2GmZ8Zyp74usTxLCqSJZNyMRLHQWBM0g44Iuy4wE3vpi7Wq+xYuSOH2mu4OddnxswCP4QhaXVQavTAQIhAOBVCKXtppEw9UaOBL4vW0Ed/6EA/1D8hDW6St0h7EXJAiEAx+iRmZKhJD6VT84dtX5ZYNVk3j3dAcIOovpzUj9a0CECIEduTCapmZQ5xqAEsLXuVlxRtQgLTUD4ZxDElPn8x0MhAiBE2HlcND0+qDbvtwJQQOUzDgqg5xk3w8capboVdzAlQQIhAMC+lDL7+gDYkNAft5Mu+NObJmQs4Cr+DkDFsKqoxqrm";
00630 const char* B64LCert = "MIIBeTCCASMCEHqkOHVRRWr+1COq3CR/xsowDQYJKoZIhvcNAQEEBQAwOzElMCMGA1UEAxMcb3NwdGVzdHNlcnZlci50cmFuc25leHVzLmNvbTESMBAGA1UEChMJT1NQU2VydmVyMB4XDTA1MDYyMzAwMjkxOFoXDTA2MDYyNDAwMjkxOFowRTELMAkGA1UEBhMCQVUxEzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNVBAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDBcMA0GCSqGSIb3DQEBAQUAA0sAMEgCQQCvLeZfj1G0wuJb8JTcVeZaZftncEmRluOnaME3ustd918lRMDYokZmtmDZN8SrP0yd1pfVqZ7NkmBACbBX0k7pAgMBAAEwDQYJKoZIhvcNAQEEBQADQQDnV8QNFVVJx/+7IselU0wsepqMurivXZzuxOmTEmTVDzCJx1xhA8jd3vGAj7XDIYiPub1PV23eY5a2ARJuw5w9";
00631 const char* B64CACert = "MIIBYDCCAQoCAQEwDQYJKoZIhvcNAQEEBQAwOzElMCMGA1UEAxMcb3NwdGVzdHNlcnZlci50cmFuc25leHVzLmNvbTESMBAGA1UEChMJT1NQU2VydmVyMB4XDTAyMDIwNDE4MjU1MloXDTEyMDIwMzE4MjU1MlowOzElMCMGA1UEAxMcb3NwdGVzdHNlcnZlci50cmFuc25leHVzLmNvbTESMBAGA1UEChMJT1NQU2VydmVyMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAPGeGwV41EIhX0jEDFLRXQhDEr50OUQPq+f55VwQd0TQNts06BP29+UiNdRW3c3IRHdZcJdC1Cg68ME9cgeq0h8CAwEAATANBgkqhkiG9w0BAQQFAANBAGkzBSj1EnnmUxbaiG1N4xjIuLAWydun7o3bFk2tV8dBIhnuh445obYyk1EnQ27kI7eACCILBZqi2MHDOIMnoN0=";
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641 static int osp_create_provider(
00642 struct ast_config* cfg,
00643 const char* name)
00644 {
00645 int res = OSP_FAILED;
00646 struct ast_variable* var;
00647 struct osp_provider* provider;
00648 OSPTPRIVATEKEY privatekey;
00649 OSPT_CERT localcert;
00650 OSPT_CERT cacerts[OSP_MAX_CERTS];
00651 const OSPT_CERT* pcacerts[OSP_MAX_CERTS];
00652 const char* pspoints[OSP_MAX_SPOINTS];
00653 unsigned char privatekeydata[OSP_SIZE_KEYSTR];
00654 unsigned char localcertdata[OSP_SIZE_KEYSTR];
00655 unsigned char cacertdata[OSP_SIZE_KEYSTR];
00656 int i, num, error = OSPC_ERR_NO_ERROR;
00657
00658 if (!(provider = ast_calloc(1, sizeof(*provider)))) {
00659 ast_log(LOG_ERROR, "Out of memory\n");
00660 return OSP_ERROR;
00661 }
00662
00663
00664 provider->handle = OSP_INVALID_HANDLE;
00665 ast_copy_string(provider->name, name, sizeof(provider->name));
00666 snprintf(provider->privatekey, sizeof(provider->privatekey), "%s/%s-privatekey.pem", ast_config_AST_KEY_DIR, name);
00667 snprintf(provider->localcert, sizeof(provider->localcert), "%s/%s-localcert.pem", ast_config_AST_KEY_DIR, name);
00668 snprintf(provider->cacerts[0], sizeof(provider->cacerts[0]), "%s/%s-cacert_0.pem", ast_config_AST_KEY_DIR, name);
00669 provider->maxconnect = OSP_DEF_MAXCONNECT;
00670 provider->retrydelay = OSP_DEF_RETRYDELAY;
00671 provider->retrylimit = OSP_DEF_RETRYLIMIT;
00672 provider->timeout = OSP_DEF_TIMEOUT;
00673 provider->authpolicy = OSP_DEF_AUTHPOLICY;
00674 provider->defprotocol = OSP_DEF_PROTOCOL;
00675 provider->workmode = OSP_DEF_WORKMODE;
00676 provider->srvtype = OSP_DEF_SRVTYPE;
00677
00678 for (var = ast_variable_browse(cfg, name); var != NULL; var = var->next) {
00679 if (!strcasecmp(var->name, "privatekey")) {
00680 if (osp_security) {
00681 if (var->value[0] == '/') {
00682 ast_copy_string(provider->privatekey, var->value, sizeof(provider->privatekey));
00683 } else {
00684 snprintf(provider->privatekey, sizeof(provider->privatekey), "%s/%s", ast_config_AST_KEY_DIR, var->value);
00685 }
00686 ast_debug(1, "OSP: privatekey '%s'\n", provider->privatekey);
00687 }
00688 } else if (!strcasecmp(var->name, "localcert")) {
00689 if (osp_security) {
00690 if (var->value[0] == '/') {
00691 ast_copy_string(provider->localcert, var->value, sizeof(provider->localcert));
00692 } else {
00693 snprintf(provider->localcert, sizeof(provider->localcert), "%s/%s", ast_config_AST_KEY_DIR, var->value);
00694 }
00695 ast_debug(1, "OSP: localcert '%s'\n", provider->localcert);
00696 }
00697 } else if (!strcasecmp(var->name, "cacert")) {
00698 if (osp_security) {
00699 if (provider->canum < OSP_MAX_CERTS) {
00700 if (var->value[0] == '/') {
00701 ast_copy_string(provider->cacerts[provider->canum], var->value, sizeof(provider->cacerts[provider->canum]));
00702 } else {
00703 snprintf(provider->cacerts[provider->canum], sizeof(provider->cacerts[provider->canum]), "%s/%s", ast_config_AST_KEY_DIR, var->value);
00704 }
00705 ast_debug(1, "OSP: cacerts[%d]: '%s'\n", provider->canum, provider->cacerts[provider->canum]);
00706 provider->canum++;
00707 } else {
00708 ast_log(LOG_WARNING, "OSP: Too many CA Certificates at line %d\n", var->lineno);
00709 }
00710 }
00711 } else if (!strcasecmp(var->name, "servicepoint")) {
00712 if (provider->spnum < OSP_MAX_SPOINTS) {
00713 ast_copy_string(provider->spoints[provider->spnum], var->value, sizeof(provider->spoints[provider->spnum]));
00714 ast_debug(1, "OSP: servicepoint[%d]: '%s'\n", provider->spnum, provider->spoints[provider->spnum]);
00715 provider->spnum++;
00716 } else {
00717 ast_log(LOG_WARNING, "OSP: Too many Service Points at line %d\n", var->lineno);
00718 }
00719 } else if (!strcasecmp(var->name, "maxconnect")) {
00720 if ((sscanf(var->value, "%30d", &num) == 1) && (num >= OSP_MIN_MAXCONNECT) && (num <= OSP_MAX_MAXCONNECT)) {
00721 provider->maxconnect = num;
00722 ast_debug(1, "OSP: maxconnect '%d'\n", num);
00723 } else {
00724 ast_log(LOG_WARNING, "OSP: maxconnect should be an integer from %d to %d, not '%s' at line %d\n",
00725 OSP_MIN_MAXCONNECT, OSP_MAX_MAXCONNECT, var->value, var->lineno);
00726 }
00727 } else if (!strcasecmp(var->name, "retrydelay")) {
00728 if ((sscanf(var->value, "%30d", &num) == 1) && (num >= OSP_MIN_RETRYDELAY) && (num <= OSP_MAX_RETRYDELAY)) {
00729 provider->retrydelay = num;
00730 ast_debug(1, "OSP: retrydelay '%d'\n", num);
00731 } else {
00732 ast_log(LOG_WARNING, "OSP: retrydelay should be an integer from %d to %d, not '%s' at line %d\n",
00733 OSP_MIN_RETRYDELAY, OSP_MAX_RETRYDELAY, var->value, var->lineno);
00734 }
00735 } else if (!strcasecmp(var->name, "retrylimit")) {
00736 if ((sscanf(var->value, "%30d", &num) == 1) && (num >= OSP_MIN_RETRYLIMIT) && (num <= OSP_MAX_RETRYLIMIT)) {
00737 provider->retrylimit = num;
00738 ast_debug(1, "OSP: retrylimit '%d'\n", num);
00739 } else {
00740 ast_log(LOG_WARNING, "OSP: retrylimit should be an integer from %d to %d, not '%s' at line %d\n",
00741 OSP_MIN_RETRYLIMIT, OSP_MAX_RETRYLIMIT, var->value, var->lineno);
00742 }
00743 } else if (!strcasecmp(var->name, "timeout")) {
00744 if ((sscanf(var->value, "%30d", &num) == 1) && (num >= OSP_MIN_TIMEOUT) && (num <= OSP_MAX_TIMEOUT)) {
00745 provider->timeout = num;
00746 ast_debug(1, "OSP: timeout '%d'\n", num);
00747 } else {
00748 ast_log(LOG_WARNING, "OSP: timeout should be an integer from %d to %d, not '%s' at line %d\n",
00749 OSP_MIN_TIMEOUT, OSP_MAX_TIMEOUT, var->value, var->lineno);
00750 }
00751 } else if (!strcasecmp(var->name, "source")) {
00752 ast_copy_string(provider->source, var->value, sizeof(provider->source));
00753 ast_debug(1, "OSP: source '%s'\n", provider->source);
00754 } else if (!strcasecmp(var->name, "authpolicy")) {
00755 if ((sscanf(var->value, "%30d", &num) == 1) && ((num == OSP_AUTH_NO) || (num == OSP_AUTH_YES) || (num == OSP_AUTH_EXC))) {
00756 provider->authpolicy = num;
00757 ast_debug(1, "OSP: authpolicy '%d'\n", num);
00758 } else {
00759 ast_log(LOG_WARNING, "OSP: authpolicy should be %d, %d or %d, not '%s' at line %d\n",
00760 OSP_AUTH_NO, OSP_AUTH_YES, OSP_AUTH_EXC, var->value, var->lineno);
00761 }
00762 } else if (!strcasecmp(var->name, "defprotocol")) {
00763 if (!strcasecmp(var->value, OSP_PROT_SIP)) {
00764 provider->defprotocol = OSP_PROT_SIP;
00765 ast_debug(1, "OSP: default protocol SIP\n");
00766 } else if (!strcasecmp(var->value, OSP_PROT_H323)) {
00767 provider->defprotocol = OSP_PROT_H323;
00768 ast_debug(1, "OSP: default protocol H.323\n");
00769 } else if (!strcasecmp(var->value, OSP_PROT_IAX)) {
00770 provider->defprotocol = OSP_PROT_IAX;
00771 ast_debug(1, "OSP: default protocol IAX\n");
00772 } else if (!strcasecmp(var->value, OSP_PROT_SKYPE)) {
00773 provider->defprotocol = OSP_PROT_SKYPE;
00774 ast_debug(1, "OSP: default protocol Skype\n");
00775 } else {
00776 ast_log(LOG_WARNING, "OSP: default protocol should be %s, %s, %s or %s not '%s' at line %d\n",
00777 OSP_PROT_SIP, OSP_PROT_H323, OSP_PROT_IAX, OSP_PROT_SKYPE, var->value, var->lineno);
00778 }
00779 } else if (!strcasecmp(var->name, "workmode")) {
00780 if ((sscanf(var->value, "%30d", &num) == 1) && ((num == OSP_MODE_DIRECT) || (num == OSP_MODE_INDIRECT))) {
00781 provider->workmode = num;
00782 ast_debug(1, "OSP: workmode '%d'\n", num);
00783 } else {
00784 ast_log(LOG_WARNING, "OSP: workmode should be %d or %d, not '%s' at line %d\n",
00785 OSP_MODE_DIRECT, OSP_MODE_INDIRECT, var->value, var->lineno);
00786 }
00787 } else if (!strcasecmp(var->name, "servicetype")) {
00788 if ((sscanf(var->value, "%30d", &num) == 1) && ((num == OSP_SRV_VOICE) || (num == OSP_SRV_NPQUERY))) {
00789 provider->srvtype = num;
00790 ast_debug(1, "OSP: servicetype '%d'\n", num);
00791 } else {
00792 ast_log(LOG_WARNING, "OSP: servicetype should be %d or %d, not '%s' at line %d\n",
00793 OSP_SRV_VOICE, OSP_SRV_NPQUERY, var->value, var->lineno);
00794 }
00795 }
00796 }
00797
00798 if (provider->canum == 0) {
00799 provider->canum = 1;
00800 }
00801
00802 for (i = 0; i < provider->spnum; i++) {
00803 pspoints[i] = provider->spoints[i];
00804 }
00805
00806 if (osp_security) {
00807 privatekey.PrivateKeyData = NULL;
00808 privatekey.PrivateKeyLength = 0;
00809
00810 localcert.CertData = NULL;
00811 localcert.CertDataLength = 0;
00812
00813 for (i = 0; i < provider->canum; i++) {
00814 cacerts[i].CertData = NULL;
00815 cacerts[i].CertDataLength = 0;
00816 }
00817
00818 if ((error = OSPPUtilLoadPEMPrivateKey((unsigned char*)provider->privatekey, &privatekey)) != OSPC_ERR_NO_ERROR) {
00819 ast_log(LOG_WARNING, "OSP: Unable to load privatekey '%s', error '%d'\n", provider->privatekey, error);
00820 } else if ((error = OSPPUtilLoadPEMCert((unsigned char*)provider->localcert, &localcert)) != OSPC_ERR_NO_ERROR) {
00821 ast_log(LOG_WARNING, "OSP: Unable to load localcert '%s', error '%d'\n", provider->localcert, error);
00822 } else {
00823 for (i = 0; i < provider->canum; i++) {
00824 if ((error = OSPPUtilLoadPEMCert((unsigned char*)provider->cacerts[i], &cacerts[i])) != OSPC_ERR_NO_ERROR) {
00825 ast_log(LOG_WARNING, "OSP: Unable to load cacert '%s', error '%d'\n", provider->cacerts[i], error);
00826 break;
00827 } else {
00828 pcacerts[i] = &cacerts[i];
00829 }
00830 }
00831 }
00832 } else {
00833 privatekey.PrivateKeyData = privatekeydata;
00834 privatekey.PrivateKeyLength = sizeof(privatekeydata);
00835
00836 localcert.CertData = localcertdata;
00837 localcert.CertDataLength = sizeof(localcertdata);
00838
00839 cacerts[0].CertData = cacertdata;
00840 cacerts[0].CertDataLength = sizeof(cacertdata);
00841 pcacerts[0] = &cacerts[0];
00842
00843 if ((error = OSPPBase64Decode(B64PKey, strlen(B64PKey), privatekey.PrivateKeyData, &privatekey.PrivateKeyLength)) != OSPC_ERR_NO_ERROR) {
00844 ast_log(LOG_WARNING, "OSP: Unable to decode private key, error '%d'\n", error);
00845 } else if ((error = OSPPBase64Decode(B64LCert, strlen(B64LCert), localcert.CertData, &localcert.CertDataLength)) != OSPC_ERR_NO_ERROR) {
00846 ast_log(LOG_WARNING, "OSP: Unable to decode local cert, error '%d'\n", error);
00847 } else if ((error = OSPPBase64Decode(B64CACert, strlen(B64CACert), cacerts[0].CertData, &cacerts[0].CertDataLength)) != OSPC_ERR_NO_ERROR) {
00848 ast_log(LOG_WARNING, "OSP: Unable to decode cacert, error '%d'\n", error);
00849 }
00850 }
00851
00852 if (error == OSPC_ERR_NO_ERROR) {
00853 error = OSPPProviderNew(provider->spnum,
00854 pspoints,
00855 NULL,
00856 OSP_AUDIT_URL,
00857 &privatekey,
00858 &localcert,
00859 provider->canum,
00860 pcacerts,
00861 OSP_LOCAL_VALIDATION,
00862 OSP_SSL_LIFETIME,
00863 provider->maxconnect,
00864 OSP_HTTP_PERSISTENCE,
00865 provider->retrydelay,
00866 provider->retrylimit,
00867 provider->timeout,
00868 OSP_CUSTOMER_ID,
00869 OSP_DEVICE_ID,
00870 &provider->handle);
00871 if (error != OSPC_ERR_NO_ERROR) {
00872 ast_log(LOG_WARNING, "OSP: Unable to create provider '%s', error '%d'\n", name, error);
00873 res = OSP_ERROR;
00874 } else {
00875 ast_debug(1, "OSP: provider '%s'\n", name);
00876 ast_mutex_lock(&osp_lock);
00877 provider->next = osp_providers;
00878 osp_providers = provider;
00879 ast_mutex_unlock(&osp_lock);
00880 res = OSP_OK;
00881 }
00882 }
00883
00884 if (osp_security) {
00885 for (i = 0; i < provider->canum; i++) {
00886 if (cacerts[i].CertData) {
00887 ast_free(cacerts[i].CertData);
00888 }
00889 }
00890 if (localcert.CertData) {
00891 ast_free(localcert.CertData);
00892 }
00893 if (privatekey.PrivateKeyData) {
00894 ast_free(privatekey.PrivateKeyData);
00895 }
00896 }
00897
00898 if (res != OSP_OK) {
00899 ast_free(provider);
00900 }
00901
00902 return res;
00903 }
00904
00905
00906
00907
00908
00909
00910
00911 static int osp_get_provider(
00912 const char* name,
00913 struct osp_provider** provider)
00914 {
00915 int res = OSP_FAILED;
00916 struct osp_provider* p;
00917
00918 *provider = NULL;
00919
00920 ast_mutex_lock(&osp_lock);
00921 for (p = osp_providers; p != NULL; p = p->next) {
00922 if (!strcasecmp(p->name, name)) {
00923 *provider = p;
00924 ast_debug(1, "OSP: find provider '%s'\n", name);
00925 res = OSP_OK;
00926 break;
00927 }
00928 }
00929 ast_mutex_unlock(&osp_lock);
00930
00931 return res;
00932 }
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942 static int osp_create_transaction(
00943 const char* name,
00944 int* trans,
00945 char* source,
00946 unsigned int srcsize)
00947 {
00948 int res = OSP_FAILED;
00949 struct osp_provider* provider;
00950 int error;
00951
00952 if ((trans == NULL) || (source == NULL) || (srcsize <= 0)) {
00953 ast_log(LOG_ERROR, "Invalid parameters\n");
00954 return OSP_ERROR;
00955 }
00956
00957 *trans = OSP_INVALID_HANDLE;
00958 *source = '\0';
00959
00960 ast_mutex_lock(&osp_lock);
00961 for (provider = osp_providers; provider; provider = provider->next) {
00962 if (!strcasecmp(provider->name, name)) {
00963 error = OSPPTransactionNew(provider->handle, trans);
00964 if (error == OSPC_ERR_NO_ERROR) {
00965 ast_debug(1, "OSP: transaction '%d'\n", *trans);
00966 ast_copy_string(source, provider->source, srcsize);
00967 ast_debug(1, "OSP: source '%s'\n", source);
00968 res = OSP_OK;
00969 } else {
00970 *trans = OSP_INVALID_HANDLE;
00971 ast_debug(1, "OSP: Unable to create transaction handle, error '%d'\n", error);
00972 *source = '\0';
00973 res = OSP_ERROR;
00974 }
00975 break;
00976 }
00977 }
00978 ast_mutex_unlock(&osp_lock);
00979
00980 return res;
00981 }
00982
00983
00984
00985
00986
00987
00988
00989 static void osp_convert_inout(
00990 const char* src,
00991 char* dest,
00992 unsigned int destsize)
00993 {
00994 struct in_addr inp;
00995 char buffer[OSP_SIZE_NORSTR];
00996 char* port;
00997
00998 if ((dest != NULL) && (destsize > 0)) {
00999 if (!ast_strlen_zero(src)) {
01000 ast_copy_string(buffer, src, sizeof(buffer));
01001
01002 if((port = strchr(buffer, ':')) != NULL) {
01003 *port = '\0';
01004 port++;
01005 }
01006
01007 if (inet_pton(AF_INET, buffer, &inp) == 1) {
01008 if (port != NULL) {
01009 snprintf(dest, destsize, "[%s]:%s", buffer, port);
01010 } else {
01011 snprintf(dest, destsize, "[%s]", buffer);
01012 }
01013 dest[destsize - 1] = '\0';
01014 } else {
01015 ast_copy_string(dest, src, destsize);
01016 }
01017 } else {
01018 *dest = '\0';
01019 }
01020 }
01021 }
01022
01023
01024
01025
01026
01027
01028
01029 static void osp_convert_outin(
01030 const char* src,
01031 char* dest,
01032 unsigned int destsize)
01033 {
01034 char buffer[OSP_SIZE_NORSTR];
01035 char* end;
01036 char* port;
01037
01038 if ((dest != NULL) && (destsize > 0)) {
01039 if (!ast_strlen_zero(src)) {
01040 ast_copy_string(buffer, src, sizeof(buffer));
01041
01042 if (buffer[0] == '[') {
01043 if((port = strchr(buffer + 1, ':')) != NULL) {
01044 *port = '\0';
01045 port++;
01046 }
01047
01048 if ((end = strchr(buffer + 1, ']')) != NULL) {
01049 *end = '\0';
01050 }
01051
01052 if (port != NULL) {
01053 snprintf(dest, destsize, "%s:%s", buffer + 1, port);
01054 dest[destsize - 1] = '\0';
01055 } else {
01056 ast_copy_string(dest, buffer + 1, destsize);
01057 }
01058 } else {
01059 ast_copy_string(dest, src, destsize);
01060 }
01061 } else {
01062 *dest = '\0';
01063 }
01064 }
01065 }
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078 static int osp_validate_token(
01079 int trans,
01080 const char* source,
01081 const char* destination,
01082 const char* calling,
01083 const char* called,
01084 const char* token,
01085 unsigned int* timelimit)
01086 {
01087 int res;
01088 int tokenlen;
01089 unsigned char tokenstr[OSP_SIZE_TOKSTR];
01090 char src[OSP_SIZE_NORSTR];
01091 char dest[OSP_SIZE_NORSTR];
01092 unsigned int authorised;
01093 unsigned int dummy = 0;
01094 int error;
01095
01096 if (timelimit == NULL) {
01097 ast_log(LOG_ERROR, "Invalid parameters\n");
01098 return OSP_ERROR;
01099 }
01100
01101 tokenlen = ast_base64decode(tokenstr, token, strlen(token));
01102 osp_convert_inout(source, src, sizeof(src));
01103 osp_convert_inout(destination, dest, sizeof(dest));
01104 error = OSPPTransactionValidateAuthorisation(trans,
01105 src,
01106 dest,
01107 NULL,
01108 NULL,
01109 calling ? calling : "",
01110 OSPC_NFORMAT_E164,
01111 called,
01112 OSPC_NFORMAT_E164,
01113 0,
01114 NULL,
01115 tokenlen,
01116 (char*)tokenstr,
01117 &authorised,
01118 timelimit,
01119 &dummy,
01120 NULL,
01121 osp_tokenformat);
01122 if (error != OSPC_ERR_NO_ERROR) {
01123 ast_log(LOG_WARNING, "OSP: Unable to validate inbound token, error '%d'\n", error);
01124 *timelimit = 0;
01125 res = OSP_ERROR;
01126 } else if (authorised) {
01127 ast_debug(1, "OSP: Authorised\n");
01128 res = OSP_OK;
01129 } else {
01130 ast_debug(1, "OSP: Unauthorised\n");
01131 res = OSP_FAILED;
01132 }
01133
01134 return res;
01135 }
01136
01137
01138
01139
01140
01141
01142
01143 static unsigned int osp_choose_timelimit(
01144 unsigned int in,
01145 unsigned int out)
01146 {
01147 if (in == OSP_DEF_TIMELIMIT) {
01148 return out;
01149 } else if (out == OSP_DEF_TIMELIMIT) {
01150 return in;
01151 } else {
01152 return in < out ? in : out;
01153 }
01154 }
01155
01156
01157
01158
01159
01160
01161
01162
01163
01164
01165
01166
01167
01168 static int osp_check_destination(
01169 struct osp_provider* provider,
01170 const char* calling,
01171 const char* called,
01172 const char* destination,
01173 unsigned int tokenlen,
01174 const char* token,
01175 OSPEFAILREASON* reason,
01176 struct osp_results* results)
01177 {
01178 int res;
01179 OSPE_DEST_OSPENABLED enabled;
01180 OSPE_PROTOCOL_NAME protocol;
01181 char dest[OSP_SIZE_NORSTR];
01182 OSPE_OPERATOR_NAME type;
01183 int error;
01184
01185 if ((provider == NULL) || (reason == NULL) || (results == NULL)) {
01186 ast_log(LOG_ERROR, "Invalid parameters\n");
01187 return OSP_ERROR;
01188 }
01189
01190 if ((error = OSPPTransactionIsDestOSPEnabled(results->outhandle, &enabled)) != OSPC_ERR_NO_ERROR) {
01191 ast_debug(1, "OSP: Unable to get destination OSP version, error '%d'\n", error);
01192 *reason = OSPC_FAIL_NORMAL_UNSPECIFIED;
01193 return OSP_ERROR;
01194 }
01195
01196 if (enabled == OSPC_DOSP_FALSE) {
01197 results->token[0] = '\0';
01198 } else {
01199 ast_base64encode(results->token, (const unsigned char*)token, tokenlen, sizeof(results->token) - 1);
01200 }
01201
01202 if ((error = OSPPTransactionGetDestinationNetworkId(results->outhandle, sizeof(results->networkid), results->networkid)) != OSPC_ERR_NO_ERROR) {
01203 ast_debug(1, "OSP: Unable to get destination network ID, error '%d'\n", error);
01204 results->networkid[0] = '\0';
01205 }
01206
01207 error = OSPPTransactionGetNumberPortabilityParameters(results->outhandle,
01208 sizeof(results->nprn),
01209 results->nprn,
01210 sizeof(results->npcic),
01211 results->npcic,
01212 &results->npdi);
01213 if (error != OSPC_ERR_NO_ERROR) {
01214 ast_debug(1, "OSP: Unable to get number portability parameters, error '%d'\n", error);
01215 results->nprn[0] = '\0';
01216 results->npcic[0] = '\0';
01217 results->npdi = 0;
01218 }
01219
01220 for (type = OSPC_OPNAME_START; type < OSPC_OPNAME_NUMBER; type++) {
01221 error = OSPPTransactionGetOperatorName(results->outhandle, type, sizeof(results->opname[type]), results->opname[type]);
01222 if (error != OSPC_ERR_NO_ERROR) {
01223 ast_debug(1, "OSP: Unable to get operator name of type '%d', error '%d'\n", type, error);
01224 results->opname[type][0] = '\0';
01225 }
01226 }
01227
01228 if ((error = OSPPTransactionGetDestProtocol(results->outhandle, &protocol)) != OSPC_ERR_NO_ERROR) {
01229 ast_debug(1, "OSP: Unable to get destination protocol, error '%d'\n", error);
01230 *reason = OSPC_FAIL_NORMAL_UNSPECIFIED;
01231 results->token[0] = '\0';
01232 results->networkid[0] = '\0';
01233 results->nprn[0] = '\0';
01234 results->npcic[0] = '\0';
01235 results->npdi = 0;
01236 for (type = OSPC_OPNAME_START; type < OSPC_OPNAME_NUMBER; type++) {
01237 results->opname[type][0] = '\0';
01238 }
01239 return OSP_ERROR;
01240 }
01241
01242 res = OSP_OK;
01243 osp_convert_outin(destination, dest, sizeof(dest));
01244 switch(protocol) {
01245 case OSPC_PROTNAME_SIP:
01246 ast_debug(1, "OSP: protocol SIP\n");
01247 ast_copy_string(results->outtech, OSP_TECH_SIP, sizeof(results->outtech));
01248 ast_copy_string(results->dest, dest, sizeof(results->dest));
01249 ast_copy_string(results->calling, calling, sizeof(results->calling));
01250 ast_copy_string(results->called, called, sizeof(results->called));
01251 break;
01252 case OSPC_PROTNAME_Q931:
01253 ast_debug(1, "OSP: protocol Q.931\n");
01254 ast_copy_string(results->outtech, OSP_TECH_H323, sizeof(results->outtech));
01255 ast_copy_string(results->dest, dest, sizeof(results->dest));
01256 ast_copy_string(results->calling, calling, sizeof(results->calling));
01257 ast_copy_string(results->called, called, sizeof(results->called));
01258 break;
01259 case OSPC_PROTNAME_IAX:
01260 ast_debug(1, "OSP: protocol IAX\n");
01261 ast_copy_string(results->outtech, OSP_TECH_IAX, sizeof(results->outtech));
01262 ast_copy_string(results->dest, dest, sizeof(results->dest));
01263 ast_copy_string(results->calling, calling, sizeof(results->calling));
01264 ast_copy_string(results->called, called, sizeof(results->called));
01265 break;
01266 case OSPC_PROTNAME_SKYPE:
01267 ast_debug(1, "OSP: protocol Skype\n");
01268 ast_copy_string(results->outtech, OSP_TECH_SKYPE, sizeof(results->outtech));
01269 ast_copy_string(results->dest, dest, sizeof(results->dest));
01270 ast_copy_string(results->calling, calling, sizeof(results->calling));
01271 ast_copy_string(results->called, called, sizeof(results->called));
01272 break;
01273 case OSPC_PROTNAME_UNDEFINED:
01274 case OSPC_PROTNAME_UNKNOWN:
01275 ast_debug(1, "OSP: unknown/undefined protocol '%d'\n", protocol);
01276 ast_debug(1, "OSP: use default protocol '%s'\n", provider->defprotocol);
01277 ast_copy_string(results->outtech, provider->defprotocol, sizeof(results->outtech));
01278 ast_copy_string(results->dest, dest, sizeof(results->dest));
01279 ast_copy_string(results->calling, calling, sizeof(results->calling));
01280 ast_copy_string(results->called, called, sizeof(results->called));
01281 break;
01282 case OSPC_PROTNAME_LRQ:
01283 case OSPC_PROTNAME_T37:
01284 case OSPC_PROTNAME_T38:
01285 case OSPC_PROTNAME_SMPP:
01286 case OSPC_PROTNAME_XMPP:
01287 default:
01288 ast_log(LOG_WARNING, "OSP: unsupported protocol '%d'\n", protocol);
01289 *reason = OSPC_FAIL_PROTOCOL_ERROR;
01290 results->token[0] = '\0';
01291 results->networkid[0] = '\0';
01292 results->nprn[0] = '\0';
01293 results->npcic[0] = '\0';
01294 results->npdi = 0;
01295 for (type = OSPC_OPNAME_START; type < OSPC_OPNAME_NUMBER; type++) {
01296 results->opname[type][0] = '\0';
01297 }
01298 res = OSP_FAILED;
01299 break;
01300 }
01301
01302 return res;
01303 }
01304
01305
01306
01307
01308
01309
01310 static OSPEFAILREASON asterisk2osp(
01311 int cause)
01312 {
01313 return (OSPEFAILREASON)cause;
01314 }
01315
01316
01317
01318
01319
01320
01321
01322
01323
01324
01325
01326
01327 static int osp_auth(
01328 const char* name,
01329 int* trans,
01330 const char* source,
01331 const char* calling,
01332 const char* called,
01333 const char* token,
01334 unsigned int* timelimit)
01335 {
01336 int res;
01337 struct osp_provider* provider = NULL;
01338 char dest[OSP_SIZE_NORSTR];
01339
01340 if ((trans == NULL) || (timelimit == NULL)) {
01341 ast_log(LOG_ERROR, "Invalid parameters\n");
01342 return OSP_ERROR;
01343 }
01344
01345 *trans = OSP_INVALID_HANDLE;
01346 *timelimit = OSP_DEF_TIMELIMIT;
01347
01348 if ((res = osp_get_provider(name, &provider)) <= 0) {
01349 ast_debug(1, "OSP: Unabe to find OSP provider '%s'\n", name);
01350 return res;
01351 }
01352
01353 switch (provider->authpolicy) {
01354 case OSP_AUTH_NO:
01355 res = OSP_OK;
01356 break;
01357 case OSP_AUTH_EXC:
01358 if (ast_strlen_zero(token)) {
01359 res = OSP_FAILED;
01360 } else if ((res = osp_create_transaction(name, trans, dest, sizeof(dest))) <= 0) {
01361 ast_debug(1, "OSP: Unable to generate transaction handle\n");
01362 *trans = OSP_INVALID_HANDLE;
01363 res = OSP_FAILED;
01364 } else if((res = osp_validate_token(*trans, source, dest, calling, called, token, timelimit)) <= 0) {
01365 OSPPTransactionRecordFailure(*trans, OSPC_FAIL_CALL_REJECTED);
01366 }
01367 break;
01368 case OSP_AUTH_YES:
01369 default:
01370 if (ast_strlen_zero(token)) {
01371 res = OSP_OK;
01372 } else if ((res = osp_create_transaction(name, trans, dest, sizeof(dest))) <= 0) {
01373 ast_debug(1, "OSP: Unable to generate transaction handle\n");
01374 *trans = OSP_INVALID_HANDLE;
01375 res = OSP_FAILED;
01376 } else if((res = osp_validate_token(*trans, source, dest, calling, called, token, timelimit)) <= 0) {
01377 OSPPTransactionRecordFailure(*trans, OSPC_FAIL_CALL_REJECTED);
01378 }
01379 break;
01380 }
01381
01382 return res;
01383 }
01384
01385
01386
01387
01388
01389
01390
01391 static int osp_create_uuid(
01392 unsigned char* uuid,
01393 unsigned int* bufsize)
01394 {
01395 int i, res;
01396 long int tmp[OSP_SIZE_UUID / sizeof(long int)];
01397
01398 if ((uuid != NULL) && (*bufsize >= OSP_SIZE_UUID)) {
01399 for (i = 0; i < OSP_SIZE_UUID / sizeof(long int); i++) {
01400 tmp[i] = ast_random();
01401 }
01402 memcpy(uuid, tmp, OSP_SIZE_UUID);
01403 *bufsize = OSP_SIZE_UUID;
01404 res = OSP_OK;
01405 } else {
01406 ast_log(LOG_ERROR, "Invalid parameters\n");
01407 res = OSP_ERROR;
01408 }
01409
01410 return res;
01411 }
01412
01413
01414
01415
01416
01417
01418
01419
01420 static int osp_uuid2str(
01421 unsigned char* uuid,
01422 char* buffer,
01423 unsigned int bufsize)
01424 {
01425 int res;
01426
01427 if ((uuid != NULL) && (bufsize > OSP_SIZE_UUIDSTR)) {
01428 snprintf(buffer, bufsize, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
01429 uuid[0], uuid[1], uuid[2], uuid[3], uuid[4], uuid[5], uuid[6], uuid[7],
01430 uuid[8], uuid[9], uuid[10], uuid[11], uuid[12], uuid[13], uuid[14], uuid[15]);
01431 res = OSP_OK;
01432 } else {
01433 ast_log(LOG_ERROR, "Invalid parameters\n");
01434 res = OSP_ERROR;
01435 }
01436
01437 return res;
01438 }
01439
01440
01441
01442
01443
01444
01445
01446 static int osp_create_callid(
01447 unsigned int type,
01448 struct osp_callid* callid)
01449 {
01450 int res;
01451
01452 if (callid == NULL) {
01453 ast_log(LOG_ERROR, "Invalid parameters\n");
01454 return OSP_ERROR;
01455 }
01456
01457 callid->len = sizeof(callid->buf);
01458 switch (type) {
01459 case OSP_CALLID_H323:
01460 res = osp_create_uuid(callid->buf, &callid->len);
01461 break;
01462 case OSP_CALLID_SIP:
01463 case OSP_CALLID_IAX:
01464 res = OSP_FAILED;
01465 break;
01466 default:
01467 res = OSP_ERROR;
01468 break;
01469 }
01470
01471 if ((res != OSP_OK) && (callid->len != 0)) {
01472 callid->buf[0] = '\0';
01473 callid->len = 0;
01474 }
01475
01476 return res;
01477 }
01478
01479
01480
01481
01482
01483
01484
01485
01486
01487
01488
01489
01490
01491
01492
01493
01494 static int osp_lookup(
01495 const char* name,
01496 unsigned int callidtypes,
01497 const char* actualsrc,
01498 const char* srcdev,
01499 const char* calling,
01500 const char* called,
01501 const char* snetid,
01502 struct osp_npdata* np,
01503 struct osp_headers* headers,
01504 const char* cinfo[],
01505 struct osp_results* results)
01506 {
01507 int res;
01508 struct osp_provider* provider = NULL;
01509 OSPE_PROTOCOL_NAME protocol;
01510 char source[OSP_SIZE_NORSTR];
01511 char callingnum[OSP_SIZE_NORSTR];
01512 char callednum[OSP_SIZE_NORSTR];
01513 char destination[OSP_SIZE_NORSTR];
01514 char* tmp;
01515 unsigned int tokenlen;
01516 char token[OSP_SIZE_TOKSTR];
01517 char src[OSP_SIZE_NORSTR];
01518 char dev[OSP_SIZE_NORSTR];
01519 char host[OSP_SIZE_NORSTR];
01520 unsigned int i, type;
01521 struct osp_callid callid;
01522 unsigned int callidnum;
01523 OSPT_CALL_ID* callids[OSP_CALLID_MAXNUM];
01524 char dest[OSP_SIZE_NORSTR];
01525 const char* preferred[2] = { NULL };
01526 unsigned int dummy = 0;
01527 OSPEFAILREASON reason;
01528 int error;
01529
01530 if (results == NULL) {
01531 ast_log(LOG_ERROR, "Invalid parameters\n");
01532 return OSP_ERROR;
01533 }
01534
01535 osp_convert_inout(results->dest, dest, sizeof(dest));
01536
01537 results->outhandle = OSP_INVALID_HANDLE;
01538 results->outtech[0] = '\0';
01539 results->calling[0] = '\0';
01540 results->called[0] = '\0';
01541 results->token[0] = '\0';
01542 results->networkid[0] = '\0';
01543 results->nprn[0] = '\0';
01544 results->npcic[0] = '\0';
01545 results->npdi = 0;
01546 for (type = OSPC_OPNAME_START; type < OSPC_OPNAME_NUMBER; type++) {
01547 results->opname[type][0] = '\0';
01548 }
01549 results->numdests = 0;
01550 results->outtimelimit = OSP_DEF_TIMELIMIT;
01551
01552 if ((res = osp_get_provider(name, &provider)) <= 0) {
01553 ast_debug(1, "OSP: Unabe to find OSP provider '%s'\n", name);
01554 return res;
01555 }
01556
01557 if ((res = osp_create_transaction(name, &results->outhandle, source, sizeof(source))) <= 0) {
01558 ast_debug(1, "OSP: Unable to generate transaction handle\n");
01559 results->outhandle = OSP_INVALID_HANDLE;
01560 if (results->inhandle != OSP_INVALID_HANDLE) {
01561 OSPPTransactionRecordFailure(results->inhandle, OSPC_FAIL_NORMAL_UNSPECIFIED);
01562 }
01563 return OSP_ERROR;
01564 }
01565
01566 if (!strcasecmp(results->intech, OSP_TECH_SIP)) {
01567 protocol = OSPC_PROTNAME_SIP;
01568 } else if (!strcasecmp(results->intech, OSP_TECH_H323)) {
01569 protocol = OSPC_PROTNAME_Q931;
01570 } else if (!strcasecmp(results->intech, OSP_TECH_IAX)) {
01571 protocol = OSPC_PROTNAME_IAX;
01572 } else if (!strcasecmp(results->intech, OSP_TECH_SKYPE)) {
01573 protocol = OSPC_PROTNAME_SKYPE;
01574 } else {
01575 protocol = OSPC_PROTNAME_SIP;
01576 }
01577 OSPPTransactionSetProtocol(results->outhandle, OSPC_PROTTYPE_SOURCE, protocol);
01578
01579 if (!ast_strlen_zero(snetid)) {
01580 OSPPTransactionSetNetworkIds(results->outhandle, snetid, "");
01581 }
01582
01583 OSPPTransactionSetNumberPortability(results->outhandle, np->rn, np->cic, np->npdi);
01584
01585 for (type = OSPC_OPNAME_START; type < OSPC_OPNAME_NUMBER; type++) {
01586 OSPPTransactionSetOperatorName(results->outhandle, type, np->opname[type]);
01587 }
01588
01589 OSPPTransactionSetRemotePartyId(results->outhandle, OSPC_NFORMAT_E164, headers->rpiduser);
01590 OSPPTransactionSetAssertedId(results->outhandle, OSPC_NFORMAT_E164, headers->paiuser);
01591 osp_convert_inout(headers->divhost, host, sizeof(host));
01592 OSPPTransactionSetDiversion(results->outhandle, headers->divuser, host);
01593 OSPPTransactionSetChargeInfo(results->outhandle, OSPC_NFORMAT_E164, headers->pciuser);
01594
01595 if (cinfo != NULL) {
01596 for (i = 0; i < OSP_MAX_CUSTOMINFO; i++) {
01597 if (!ast_strlen_zero(cinfo[i])) {
01598 OSPPTransactionSetCustomInfo(results->outhandle, i, cinfo[i]);
01599 }
01600 }
01601 }
01602
01603 ast_copy_string(callednum, called, sizeof(callednum));
01604 if((tmp = strchr(callednum, ';')) != NULL) {
01605 *tmp = '\0';
01606 }
01607
01608 callidnum = 0;
01609 callids[0] = NULL;
01610 for (i = 0; i < OSP_CALLID_MAXNUM; i++) {
01611 type = 1 << i;
01612 if (callidtypes & type) {
01613 error = osp_create_callid(type, &callid);
01614 if (error == 1) {
01615 callids[callidnum] = OSPPCallIdNew(callid.len, callid.buf);
01616 callidnum++;
01617 }
01618 }
01619 }
01620
01621 if (provider->workmode == OSP_MODE_INDIRECT) {
01622 osp_convert_inout(srcdev, src, sizeof(src));
01623 if (ast_strlen_zero(actualsrc)) {
01624 osp_convert_inout(srcdev, dev, sizeof(dev));
01625 } else {
01626 osp_convert_inout(actualsrc, dev, sizeof(dev));
01627 }
01628 } else {
01629 osp_convert_inout(source, src, sizeof(src));
01630 osp_convert_inout(srcdev, dev, sizeof(dev));
01631 }
01632
01633 if (provider->srvtype == OSP_SRV_NPQUERY) {
01634 OSPPTransactionSetServiceType(results->outhandle, OSPC_SERVICE_NPQUERY);
01635 if (!ast_strlen_zero(dest)) {
01636 preferred[0] = dest;
01637 }
01638 results->numdests = 1;
01639 } else {
01640 OSPPTransactionSetServiceType(results->outhandle, OSPC_SERVICE_VOICE);
01641 results->numdests = OSP_DEF_MAXDESTS;
01642 }
01643
01644 error = OSPPTransactionRequestAuthorisation(results->outhandle,
01645 src,
01646 dev,
01647 calling ? calling : "",
01648 OSPC_NFORMAT_E164,
01649 callednum,
01650 OSPC_NFORMAT_E164,
01651 NULL,
01652 callidnum,
01653 callids,
01654 preferred,
01655 &results->numdests,
01656 &dummy,
01657 NULL);
01658
01659 for (i = 0; i < callidnum; i++) {
01660 OSPPCallIdDelete(&callids[i]);
01661 }
01662
01663 if (error != OSPC_ERR_NO_ERROR) {
01664 ast_log(LOG_WARNING, "OSP: Unable to request authorization, error '%d'\n", error);
01665 results->numdests = 0;
01666 if (results->inhandle != OSP_INVALID_HANDLE) {
01667 OSPPTransactionRecordFailure(results->inhandle, OSPC_FAIL_NORMAL_UNSPECIFIED);
01668 }
01669 return OSP_ERROR;
01670 }
01671
01672 if (!results->numdests) {
01673 ast_debug(1, "OSP: No more destination\n");
01674 if (results->inhandle != OSP_INVALID_HANDLE) {
01675 OSPPTransactionRecordFailure(results->inhandle, OSPC_FAIL_NO_ROUTE_TO_DEST);
01676 }
01677 return OSP_FAILED;
01678 }
01679
01680 results->outcallid.len = sizeof(results->outcallid.buf);
01681 tokenlen = sizeof(token);
01682 error = OSPPTransactionGetFirstDestination(results->outhandle,
01683 0,
01684 NULL,
01685 NULL,
01686 &results->outtimelimit,
01687 &results->outcallid.len,
01688 results->outcallid.buf,
01689 sizeof(callednum),
01690 callednum,
01691 sizeof(callingnum),
01692 callingnum,
01693 sizeof(destination),
01694 destination,
01695 0,
01696 NULL,
01697 &tokenlen,
01698 token);
01699 if (error != OSPC_ERR_NO_ERROR) {
01700 ast_debug(1, "OSP: Unable to get first route, error '%d'\n", error);
01701 results->numdests = 0;
01702 results->outtimelimit = OSP_DEF_TIMELIMIT;
01703 if (results->inhandle != OSP_INVALID_HANDLE) {
01704 OSPPTransactionRecordFailure(results->inhandle, OSPC_FAIL_NO_ROUTE_TO_DEST);
01705 }
01706 return OSP_ERROR;
01707 }
01708
01709 results->numdests--;
01710 results->outtimelimit = osp_choose_timelimit(results->intimelimit, results->outtimelimit);
01711 ast_debug(1, "OSP: outtimelimit '%d'\n", results->outtimelimit);
01712 ast_debug(1, "OSP: calling '%s'\n", callingnum);
01713 ast_debug(1, "OSP: called '%s'\n", callednum);
01714 ast_debug(1, "OSP: destination '%s'\n", destination);
01715 ast_debug(1, "OSP: token size '%d'\n", tokenlen);
01716
01717 if ((res = osp_check_destination(provider, callingnum, callednum, destination, tokenlen, token, &reason, results)) > 0) {
01718 return OSP_OK;
01719 }
01720
01721 if (!results->numdests) {
01722 ast_debug(1, "OSP: No more destination\n");
01723 results->outtimelimit = OSP_DEF_TIMELIMIT;
01724 OSPPTransactionRecordFailure(results->outhandle, reason);
01725 if (results->inhandle != OSP_INVALID_HANDLE) {
01726 OSPPTransactionRecordFailure(results->inhandle, OSPC_FAIL_NO_ROUTE_TO_DEST);
01727 }
01728 return OSP_FAILED;
01729 }
01730
01731 while(results->numdests) {
01732 results->outcallid.len = sizeof(results->outcallid.buf);
01733 tokenlen = sizeof(token);
01734 error = OSPPTransactionGetNextDestination(results->outhandle,
01735 reason,
01736 0,
01737 NULL,
01738 NULL,
01739 &results->outtimelimit,
01740 &results->outcallid.len,
01741 results->outcallid.buf,
01742 sizeof(callednum),
01743 callednum,
01744 sizeof(callingnum),
01745 callingnum,
01746 sizeof(destination),
01747 destination,
01748 0,
01749 NULL,
01750 &tokenlen,
01751 token);
01752 if (error == OSPC_ERR_NO_ERROR) {
01753 results->numdests--;
01754 results->outtimelimit = osp_choose_timelimit(results->intimelimit, results->outtimelimit);
01755 ast_debug(1, "OSP: outtimelimit '%d'\n", results->outtimelimit);
01756 ast_debug(1, "OSP: calling '%s'\n", callingnum);
01757 ast_debug(1, "OSP: called '%s'\n", callednum);
01758 ast_debug(1, "OSP: destination '%s'\n", destination);
01759 ast_debug(1, "OSP: token size '%d'\n", tokenlen);
01760
01761 if ((res = osp_check_destination(provider, callingnum, callednum, destination, tokenlen, token, &reason, results)) > 0) {
01762 break;
01763 } else if (!results->numdests) {
01764 ast_debug(1, "OSP: No more destination\n");
01765 OSPPTransactionRecordFailure(results->outhandle, reason);
01766 if (results->inhandle != OSP_INVALID_HANDLE) {
01767 OSPPTransactionRecordFailure(results->inhandle, OSPC_FAIL_NO_ROUTE_TO_DEST);
01768 }
01769 res = OSP_FAILED;
01770 break;
01771 }
01772 } else {
01773 ast_debug(1, "OSP: Unable to get route, error '%d'\n", error);
01774 results->numdests = 0;
01775 results->outtimelimit = OSP_DEF_TIMELIMIT;
01776 if (results->inhandle != OSP_INVALID_HANDLE) {
01777 OSPPTransactionRecordFailure(results->inhandle, OSPC_FAIL_NORMAL_UNSPECIFIED);
01778 }
01779 res = OSP_ERROR;
01780 break;
01781 }
01782 }
01783
01784 return res;
01785 }
01786
01787
01788
01789
01790
01791
01792
01793
01794 static int osp_next(
01795 const char* name,
01796 int cause,
01797 struct osp_results* results)
01798 {
01799 int res;
01800 struct osp_provider* provider = NULL;
01801 char calling[OSP_SIZE_NORSTR];
01802 char called[OSP_SIZE_NORSTR];
01803 char dest[OSP_SIZE_NORSTR];
01804 unsigned int tokenlen;
01805 char token[OSP_SIZE_TOKSTR];
01806 OSPEFAILREASON reason;
01807 OSPE_OPERATOR_NAME type;
01808 int error;
01809
01810 if (results == NULL) {
01811 ast_log(LOG_ERROR, "Invalid parameters\n");
01812 return OSP_ERROR;
01813 }
01814
01815 results->outtech[0] = '\0';
01816 results->dest[0] = '\0';
01817 results->calling[0] = '\0';
01818 results->called[0] = '\0';
01819 results->token[0] = '\0';
01820 results->networkid[0] = '\0';
01821 results->nprn[0] = '\0';
01822 results->npcic[0] = '\0';
01823 results->npdi = 0;
01824 for (type = OSPC_OPNAME_START; type < OSPC_OPNAME_NUMBER; type++) {
01825 results->opname[type][0] = '\0';
01826 }
01827 results->outtimelimit = OSP_DEF_TIMELIMIT;
01828
01829 if ((res = osp_get_provider(name, &provider)) <= 0) {
01830 ast_debug(1, "OSP: Unabe to find OSP provider '%s'\n", name);
01831 return res;
01832 }
01833
01834 if (results->outhandle == OSP_INVALID_HANDLE) {
01835 ast_debug(1, "OSP: Transaction handle undefined\n");
01836 results->numdests = 0;
01837 if (results->inhandle != OSP_INVALID_HANDLE) {
01838 OSPPTransactionRecordFailure(results->inhandle, OSPC_FAIL_NORMAL_UNSPECIFIED);
01839 }
01840 return OSP_ERROR;
01841 }
01842
01843 reason = asterisk2osp(cause);
01844
01845 if (!results->numdests) {
01846 ast_debug(1, "OSP: No more destination\n");
01847 OSPPTransactionRecordFailure(results->outhandle, reason);
01848 if (results->inhandle != OSP_INVALID_HANDLE) {
01849 OSPPTransactionRecordFailure(results->inhandle, OSPC_FAIL_NO_ROUTE_TO_DEST);
01850 }
01851 return OSP_FAILED;
01852 }
01853
01854 while(results->numdests) {
01855 results->outcallid.len = sizeof(results->outcallid.buf);
01856 tokenlen = sizeof(token);
01857 error = OSPPTransactionGetNextDestination(
01858 results->outhandle,
01859 reason,
01860 0,
01861 NULL,
01862 NULL,
01863 &results->outtimelimit,
01864 &results->outcallid.len,
01865 results->outcallid.buf,
01866 sizeof(called),
01867 called,
01868 sizeof(calling),
01869 calling,
01870 sizeof(dest),
01871 dest,
01872 0,
01873 NULL,
01874 &tokenlen,
01875 token);
01876 if (error == OSPC_ERR_NO_ERROR) {
01877 results->numdests--;
01878 results->outtimelimit = osp_choose_timelimit(results->intimelimit, results->outtimelimit);
01879 ast_debug(1, "OSP: outtimelimit '%d'\n", results->outtimelimit);
01880 ast_debug(1, "OSP: calling '%s'\n", calling);
01881 ast_debug(1, "OSP: called '%s'\n", called);
01882 ast_debug(1, "OSP: destination '%s'\n", dest);
01883 ast_debug(1, "OSP: token size '%d'\n", tokenlen);
01884
01885 if ((res = osp_check_destination(provider, calling, called, dest, tokenlen, token, &reason, results)) > 0) {
01886 res = OSP_OK;
01887 break;
01888 } else if (!results->numdests) {
01889 ast_debug(1, "OSP: No more destination\n");
01890 OSPPTransactionRecordFailure(results->outhandle, reason);
01891 if (results->inhandle != OSP_INVALID_HANDLE) {
01892 OSPPTransactionRecordFailure(results->inhandle, OSPC_FAIL_NO_ROUTE_TO_DEST);
01893 }
01894 res = OSP_FAILED;
01895 break;
01896 }
01897 } else {
01898 ast_debug(1, "OSP: Unable to get route, error '%d'\n", error);
01899 results->token[0] = '\0';
01900 results->numdests = 0;
01901 results->outtimelimit = OSP_DEF_TIMELIMIT;
01902 if (results->inhandle != OSP_INVALID_HANDLE) {
01903 OSPPTransactionRecordFailure(results->inhandle, OSPC_FAIL_NORMAL_UNSPECIFIED);
01904 }
01905 res = OSP_ERROR;
01906 break;
01907 }
01908 }
01909
01910 return res;
01911 }
01912
01913
01914
01915
01916
01917
01918 static int osp_get_varint(
01919 const char* vstr)
01920 {
01921 char* tmp;
01922 int value = OSP_DEF_INTSTATS;
01923
01924 if (!ast_strlen_zero(vstr)) {
01925 if ((tmp = strchr(vstr, '=')) != NULL) {
01926 tmp++;
01927 if (sscanf(tmp, "%30d", &value) != 1) {
01928 value = OSP_DEF_INTSTATS;
01929 }
01930 }
01931 }
01932
01933 return value;
01934 }
01935
01936
01937
01938
01939
01940
01941 static float osp_get_varfloat(
01942 const char* vstr)
01943 {
01944 char* tmp;
01945 float value = OSP_DEF_FLOATSTATS;
01946
01947 if (!ast_strlen_zero(vstr)) {
01948 if ((tmp = strchr(vstr, '=')) != NULL) {
01949 tmp++;
01950 if (sscanf(tmp, "%30f", &value) != 1) {
01951 value = OSP_DEF_FLOATSTATS;
01952 }
01953 }
01954 }
01955
01956 return value;
01957 }
01958
01959
01960
01961
01962
01963
01964
01965
01966 static int osp_report_qos(
01967 int trans,
01968 enum osp_callleg leg,
01969 const char* qos)
01970 {
01971 int res = OSP_FAILED;
01972 enum osp_direction dir;
01973 char buffer[OSP_SIZE_NORSTR];
01974 char* tmp;
01975 char* item;
01976 int totalpackets[OSP_DIR_NUMBER];
01977 struct osp_metrics lost[OSP_DIR_NUMBER];
01978 struct osp_metrics jitter[OSP_DIR_NUMBER];
01979 struct osp_metrics rtt;
01980 int value;
01981
01982 if (!ast_strlen_zero(qos)) {
01983 for (dir = OSP_DIR_RX; dir < OSP_DIR_NUMBER; dir++) {
01984 totalpackets[dir] = OSP_DEF_INTSTATS;
01985 }
01986
01987 for (dir = OSP_DIR_RX; dir < OSP_DIR_NUMBER; dir++) {
01988 lost[dir].value = OSP_DEF_INTSTATS;
01989 lost[dir].min = OSP_DEF_FLOATSTATS;
01990 lost[dir].max = OSP_DEF_FLOATSTATS;
01991 lost[dir].avg = OSP_DEF_FLOATSTATS;
01992 lost[dir].sdev = OSP_DEF_FLOATSTATS;
01993 }
01994
01995 for (dir = OSP_DIR_RX; dir < OSP_DIR_NUMBER; dir++) {
01996 jitter[dir].value = OSP_DEF_INTSTATS;
01997 jitter[dir].min = OSP_DEF_FLOATSTATS;
01998 jitter[dir].max = OSP_DEF_FLOATSTATS;
01999 jitter[dir].avg = OSP_DEF_FLOATSTATS;
02000 jitter[dir].sdev = OSP_DEF_FLOATSTATS;
02001 }
02002
02003 rtt.value = OSP_DEF_INTSTATS;
02004 rtt.min = OSP_DEF_FLOATSTATS;
02005 rtt.max = OSP_DEF_FLOATSTATS;
02006 rtt.avg = OSP_DEF_FLOATSTATS;
02007 rtt.sdev = OSP_DEF_FLOATSTATS;
02008
02009 ast_copy_string(buffer, qos, sizeof(buffer));
02010 for (item = strtok_r(buffer, ";", &tmp); item; item = strtok_r(NULL, ";", &tmp)) {
02011 if (!strncasecmp(item, "rxcount", strlen("rxcount"))) {
02012 totalpackets[OSP_DIR_RX] = osp_get_varint(item);
02013 } else if (!strncasecmp(item, "txcount", strlen("txcount"))) {
02014 totalpackets[OSP_DIR_TX] = osp_get_varint(item);
02015 } else if (!strncasecmp(item, "lp", strlen("lp"))) {
02016 lost[OSP_DIR_RX].value = osp_get_varint(item);
02017 } else if (!strncasecmp(item, "minrxlost", strlen("minrxlost"))) {
02018 lost[OSP_DIR_RX].min = osp_get_varfloat(item);
02019 } else if (!strncasecmp(item, "maxrxlost", strlen("maxrxlost"))) {
02020 lost[OSP_DIR_RX].max = osp_get_varfloat(item);
02021 } else if (!strncasecmp(item, "avgrxlost", strlen("avgrxlost"))) {
02022 lost[OSP_DIR_RX].avg = osp_get_varfloat(item);
02023 } else if (!strncasecmp(item, "stdevrxlost", strlen("stdevrxlost"))) {
02024 lost[OSP_DIR_RX].sdev = osp_get_varfloat(item);
02025 } else if (!strncasecmp(item, "rlp", strlen("rlp"))) {
02026 lost[OSP_DIR_TX].value = osp_get_varint(item);
02027 } else if (!strncasecmp(item, "reported_minlost", strlen("reported_minlost"))) {
02028 lost[OSP_DIR_TX].min = osp_get_varfloat(item);
02029 } else if (!strncasecmp(item, "reported_maxlost", strlen("reported_maxlost"))) {
02030 lost[OSP_DIR_TX].max = osp_get_varfloat(item);
02031 } else if (!strncasecmp(item, "reported_avglost", strlen("reported_avglost"))) {
02032 lost[OSP_DIR_TX].avg = osp_get_varfloat(item);
02033 } else if (!strncasecmp(item, "reported_stdevlost", strlen("reported_stdevlost"))) {
02034 lost[OSP_DIR_TX].sdev = osp_get_varfloat(item);
02035 } else if (!strncasecmp(item, "rxjitter", strlen("rxjitter"))) {
02036 jitter[OSP_DIR_RX].value = osp_get_varint(item);
02037 } else if (!strncasecmp(item, "minrxjitter", strlen("minrxjitter"))) {
02038 jitter[OSP_DIR_RX].min = osp_get_varfloat(item);
02039 } else if (!strncasecmp(item, "maxrxjitter", strlen("maxrxjitter"))) {
02040 jitter[OSP_DIR_RX].max = osp_get_varfloat(item);
02041 } else if (!strncasecmp(item, "avgrxjitter", strlen("avgjitter"))) {
02042 jitter[OSP_DIR_RX].avg = osp_get_varfloat(item);
02043 } else if (!strncasecmp(item, "stdevrxjitter", strlen("stdevjitter"))) {
02044 jitter[OSP_DIR_RX].sdev = osp_get_varfloat(item);
02045 } else if (!strncasecmp(item, "txjitter", strlen("txjitter"))) {
02046 jitter[OSP_DIR_TX].value = osp_get_varint(item);
02047 } else if (!strncasecmp(item, "reported_minjitter", strlen("reported_minjitter"))) {
02048 jitter[OSP_DIR_TX].min = osp_get_varfloat(item);
02049 } else if (!strncasecmp(item, "reported_maxjitter", strlen("reported_maxjitter"))) {
02050 jitter[OSP_DIR_TX].max = osp_get_varfloat(item);
02051 } else if (!strncasecmp(item, "reported_avgjitter", strlen("reported_avgjitter"))) {
02052 jitter[OSP_DIR_TX].avg = osp_get_varfloat(item);
02053 } else if (!strncasecmp(item, "reported_stdevjitter", strlen("reported_stdevjitter"))) {
02054 jitter[OSP_DIR_TX].sdev = osp_get_varfloat(item);
02055 } else if (!strncasecmp(item, "rtt", strlen("rtt"))) {
02056 rtt.value = osp_get_varint(item);
02057 } else if (!strncasecmp(item, "minrtt", strlen("minrtt"))) {
02058 rtt.min = osp_get_varfloat(item);
02059 } else if (!strncasecmp(item, "maxrtt", strlen("maxrtt"))) {
02060 rtt.max = osp_get_varfloat(item);
02061 } else if (!strncasecmp(item, "avgrtt", strlen("avgrtt"))) {
02062 rtt.avg = osp_get_varfloat(item);
02063 } else if (!strncasecmp(item, "stdevrtt", strlen("stdevrtt"))) {
02064 rtt.sdev = osp_get_varfloat(item);
02065 }
02066 }
02067
02068 ast_debug(1, "OSP: call leg '%d'\n", leg);
02069 ast_debug(1, "OSP: rxcount '%d'\n", totalpackets[OSP_DIR_RX]);
02070 ast_debug(1, "OSP: txcount '%d'\n", totalpackets[OSP_DIR_TX]);
02071 ast_debug(1, "OSP: lp '%d'\n",lost[OSP_DIR_RX].value);
02072 ast_debug(1, "OSP: minrxlost '%f'\n", lost[OSP_DIR_RX].min);
02073 ast_debug(1, "OSP: maxrxlost '%f'\n", lost[OSP_DIR_RX].max);
02074 ast_debug(1, "OSP: avgrxlost '%f'\n", lost[OSP_DIR_RX].avg);
02075 ast_debug(1, "OSP: stdevrxlost '%f'\n", lost[OSP_DIR_RX].sdev);
02076 ast_debug(1, "OSP: rlp '%d'\n", lost[OSP_DIR_TX].value);
02077 ast_debug(1, "OSP: reported_minlost '%f'\n", lost[OSP_DIR_TX].min);
02078 ast_debug(1, "OSP: reported_maxlost '%f'\n", lost[OSP_DIR_TX].max);
02079 ast_debug(1, "OSP: reported_avglost '%f'\n", lost[OSP_DIR_TX].avg);
02080 ast_debug(1, "OSP: reported_stdevlost '%f'\n", lost[OSP_DIR_TX].sdev);
02081 ast_debug(1, "OSP: rxjitter '%d'\n", jitter[OSP_DIR_RX].value);
02082 ast_debug(1, "OSP: minrxjitter '%f'\n", jitter[OSP_DIR_RX].min);
02083 ast_debug(1, "OSP: maxrxjitter '%f'\n", jitter[OSP_DIR_RX].max);
02084 ast_debug(1, "OSP: avgrxjitter '%f'\n", jitter[OSP_DIR_RX].avg);
02085 ast_debug(1, "OSP: stdevrxjitter '%f'\n", jitter[OSP_DIR_RX].sdev);
02086 ast_debug(1, "OSP: txjitter '%d'\n", jitter[OSP_DIR_TX].value);
02087 ast_debug(1, "OSP: reported_minjitter '%f'\n", jitter[OSP_DIR_TX].min);
02088 ast_debug(1, "OSP: reported_maxjitter '%f'\n", jitter[OSP_DIR_TX].max);
02089 ast_debug(1, "OSP: reported_avgjitter '%f'\n", jitter[OSP_DIR_TX].avg);
02090 ast_debug(1, "OSP: reported_stdevjitter '%f'\n", jitter[OSP_DIR_TX].sdev);
02091 ast_debug(1, "OSP: rtt '%d'\n", rtt.value);
02092 ast_debug(1, "OSP: minrtt '%f'\n", rtt.min);
02093 ast_debug(1, "OSP: maxrtt '%f'\n", rtt.max);
02094 ast_debug(1, "OSP: avgrtt '%f'\n", rtt.avg);
02095 ast_debug(1, "OSP: stdevrtt '%f'\n", rtt.sdev);
02096
02097 if (leg == OSP_CALL_INBOUND) {
02098 OSPPTransactionSetPackets(trans, OSPC_SMETRIC_RTP, OSPC_SDIR_SRCREP, totalpackets[OSP_DIR_RX]);
02099 OSPPTransactionSetPackets(trans, OSPC_SMETRIC_RTCP, OSPC_SDIR_DESTREP, totalpackets[OSP_DIR_TX]);
02100 if (lost[OSP_DIR_RX].value >= 0) {
02101 value = lost[OSP_DIR_RX].value;
02102 } else {
02103 value = (int)lost[OSP_DIR_RX].avg;
02104 }
02105 OSPPTransactionSetLost(trans, OSPC_SMETRIC_RTP, OSPC_SDIR_SRCREP, value, OSP_DEF_INTSTATS);
02106 if (lost[OSP_DIR_TX].value >= 0) {
02107 value = lost[OSP_DIR_TX].value;
02108 } else {
02109 value = (int)lost[OSP_DIR_TX].avg;
02110 }
02111 OSPPTransactionSetLost(trans, OSPC_SMETRIC_RTCP, OSPC_SDIR_DESTREP, value, OSP_DEF_INTSTATS);
02112 if (jitter[OSP_DIR_RX].value >= 0) {
02113 value = jitter[OSP_DIR_RX].value;
02114 } else {
02115 value = (int)jitter[OSP_DIR_RX].avg;
02116 }
02117 OSPPTransactionSetJitter(trans,
02118 OSPC_SMETRIC_RTP,
02119 OSPC_SDIR_SRCREP,
02120 OSP_DEF_INTSTATS,
02121 (int)jitter[OSP_DIR_RX].min,
02122 (int)jitter[OSP_DIR_RX].max,
02123 value, jitter[OSP_DIR_RX].sdev);
02124 if (jitter[OSP_DIR_TX].value >= 0) {
02125 value = jitter[OSP_DIR_TX].value;
02126 } else {
02127 value = (int)jitter[OSP_DIR_TX].avg;
02128 }
02129 OSPPTransactionSetJitter(trans, OSPC_SMETRIC_RTCP, OSPC_SDIR_DESTREP,
02130 OSP_DEF_INTSTATS, (int)jitter[OSP_DIR_TX].min, (int)jitter[OSP_DIR_TX].max, value, jitter[OSP_DIR_TX].sdev);
02131 } else {
02132 OSPPTransactionSetPackets(trans, OSPC_SMETRIC_RTP, OSPC_SDIR_DESTREP, totalpackets[OSP_DIR_RX]);
02133 OSPPTransactionSetPackets(trans, OSPC_SMETRIC_RTCP, OSPC_SDIR_SRCREP, totalpackets[OSP_DIR_TX]);
02134 OSPPTransactionSetLost(trans, OSPC_SMETRIC_RTP, OSPC_SDIR_DESTREP, lost[OSP_DIR_RX].value, OSP_DEF_INTSTATS);
02135 OSPPTransactionSetLost(trans, OSPC_SMETRIC_RTCP, OSPC_SDIR_SRCREP, lost[OSP_DIR_TX].value, OSP_DEF_INTSTATS);
02136 if (jitter[OSP_DIR_RX].value >= 0) {
02137 value = jitter[OSP_DIR_RX].value;
02138 } else {
02139 value = (int)jitter[OSP_DIR_RX].avg;
02140 }
02141 OSPPTransactionSetJitter(trans,
02142 OSPC_SMETRIC_RTP,
02143 OSPC_SDIR_DESTREP,
02144 OSP_DEF_INTSTATS,
02145 (int)jitter[OSP_DIR_RX].min,
02146 (int)jitter[OSP_DIR_RX].max,
02147 value,
02148 jitter[OSP_DIR_RX].sdev);
02149 if (jitter[OSP_DIR_TX].value >= 0) {
02150 value = jitter[OSP_DIR_TX].value;
02151 } else {
02152 value = (int)jitter[OSP_DIR_TX].avg;
02153 }
02154 OSPPTransactionSetJitter(trans,
02155 OSPC_SMETRIC_RTCP,
02156 OSPC_SDIR_SRCREP,
02157 OSP_DEF_INTSTATS,
02158 (int)jitter[OSP_DIR_TX].min,
02159 (int)jitter[OSP_DIR_TX].max,
02160 value,
02161 jitter[OSP_DIR_TX].sdev);
02162 }
02163
02164 res = OSP_OK;
02165 }
02166
02167 return res;
02168 }
02169
02170
02171
02172
02173
02174
02175
02176
02177
02178
02179
02180
02181
02182
02183 static int osp_finish(
02184 int trans,
02185 int recorded,
02186 int cause,
02187 time_t start,
02188 time_t connect,
02189 time_t end,
02190 unsigned int release,
02191 const char* inqos,
02192 const char* outqos)
02193 {
02194 int res;
02195 OSPEFAILREASON reason;
02196 time_t alert = 0;
02197 unsigned isPddInfoPresent = 0;
02198 unsigned pdd = 0;
02199 unsigned int dummy = 0;
02200 int error;
02201
02202 if (trans == OSP_INVALID_HANDLE) {
02203 return OSP_FAILED;
02204 }
02205
02206 OSPPTransactionSetRoleInfo(trans, OSPC_RSTATE_STOP, OSPC_RFORMAT_OSP, OSPC_RVENDOR_ASTERISK);
02207
02208 if (!recorded) {
02209 reason = asterisk2osp(cause);
02210 OSPPTransactionRecordFailure(trans, reason);
02211 }
02212
02213 osp_report_qos(trans, OSP_CALL_INBOUND, inqos);
02214 osp_report_qos(trans, OSP_CALL_OUTBOUND, outqos);
02215
02216 error = OSPPTransactionReportUsage(trans,
02217 difftime(end, connect),
02218 start,
02219 end,
02220 alert,
02221 connect,
02222 isPddInfoPresent,
02223 pdd,
02224 release,
02225 NULL,
02226 OSP_DEF_INTSTATS,
02227 OSP_DEF_INTSTATS,
02228 OSP_DEF_INTSTATS,
02229 OSP_DEF_INTSTATS,
02230 &dummy,
02231 NULL);
02232 if (error == OSPC_ERR_NO_ERROR) {
02233 ast_debug(1, "OSP: Usage reported\n");
02234 res = OSP_OK;
02235 } else {
02236 ast_debug(1, "OSP: Unable to report usage, error '%d'\n", error);
02237 res = OSP_ERROR;
02238 }
02239 OSPPTransactionDelete(trans);
02240
02241 return res;
02242 }
02243
02244
02245
02246
02247
02248
02249
02250
02251
02252 static int ospauth_exec(
02253 struct ast_channel *chan,
02254 const char *data)
02255 {
02256 int res;
02257 const char* provider = OSP_DEF_PROVIDER;
02258 struct varshead* headp;
02259 struct ast_var_t* current;
02260 const char* source = "";
02261 const char* token = "";
02262 int handle;
02263 unsigned int timelimit;
02264 char buffer[OSP_SIZE_INTSTR];
02265 const char* status;
02266 char* tmp;
02267
02268 AST_DECLARE_APP_ARGS(args,
02269 AST_APP_ARG(provider);
02270 AST_APP_ARG(options);
02271 );
02272
02273 tmp = ast_strdupa(data);
02274
02275 AST_STANDARD_APP_ARGS(args, tmp);
02276
02277 if (!ast_strlen_zero(args.provider)) {
02278 provider = args.provider;
02279 }
02280 ast_debug(1, "OSPAuth: provider '%s'\n", provider);
02281
02282 headp = ast_channel_varshead(chan);
02283 AST_LIST_TRAVERSE(headp, current, entries) {
02284 if (!strcasecmp(ast_var_name(current), "OSPINPEERIP")) {
02285 source = ast_var_value(current);
02286 } else if (!strcasecmp(ast_var_name(current), "OSPINTOKEN")) {
02287 token = ast_var_value(current);
02288 }
02289 }
02290
02291 ast_debug(1, "OSPAuth: source '%s'\n", source);
02292 ast_debug(1, "OSPAuth: token size '%zd'\n", strlen(token));
02293
02294 res = osp_auth(provider, &handle, source,
02295 S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL),
02296 ast_channel_exten(chan), token, &timelimit);
02297 if (res > 0) {
02298 status = AST_OSP_SUCCESS;
02299 } else {
02300 timelimit = OSP_DEF_TIMELIMIT;
02301 if (!res) {
02302 status = AST_OSP_FAILED;
02303 } else {
02304 status = AST_OSP_ERROR;
02305 }
02306 }
02307
02308 snprintf(buffer, sizeof(buffer), "%d", handle);
02309 pbx_builtin_setvar_helper(chan, "OSPINHANDLE", buffer);
02310 ast_debug(1, "OSPAuth: OSPINHANDLE '%s'\n", buffer);
02311 snprintf(buffer, sizeof(buffer), "%d", timelimit);
02312 pbx_builtin_setvar_helper(chan, "OSPINTIMELIMIT", buffer);
02313 ast_debug(1, "OSPAuth: OSPINTIMELIMIT '%s'\n", buffer);
02314 pbx_builtin_setvar_helper(chan, "OSPAUTHSTATUS", status);
02315 ast_debug(1, "OSPAuth: %s\n", status);
02316
02317 if(res != OSP_OK) {
02318 res = OSP_AST_ERROR;
02319 } else {
02320 res = OSP_AST_OK;
02321 }
02322
02323 return res;
02324 }
02325
02326
02327
02328
02329
02330
02331
02332 static int osplookup_exec(
02333 struct ast_channel* chan,
02334 const char * data)
02335 {
02336 int res;
02337 const char* provider = OSP_DEF_PROVIDER;
02338 unsigned int callidtypes = OSP_CALLID_UNDEF;
02339 struct varshead* headp;
02340 struct ast_var_t* current;
02341 const char* actualsrc = "";
02342 const char* srcdev = "";
02343 const char* snetid = "";
02344 struct osp_npdata np;
02345 OSPE_OPERATOR_NAME type;
02346 struct osp_headers headers;
02347 unsigned int i;
02348 const char* cinfo[OSP_MAX_CUSTOMINFO] = { NULL };
02349 char buffer[OSP_SIZE_TOKSTR];
02350 struct osp_results results;
02351 const char* status;
02352 char* tmp;
02353
02354 AST_DECLARE_APP_ARGS(args,
02355 AST_APP_ARG(exten);
02356 AST_APP_ARG(provider);
02357 AST_APP_ARG(options);
02358 );
02359
02360 if (ast_strlen_zero(data)) {
02361 ast_log(LOG_WARNING, "OSPLookup: Arg required, OSPLookup(exten[,provider[,options]])\n");
02362 return OSP_AST_ERROR;
02363 }
02364
02365 tmp = ast_strdupa(data);
02366
02367 AST_STANDARD_APP_ARGS(args, tmp);
02368
02369 ast_debug(1, "OSPLookup: exten '%s'\n", args.exten);
02370
02371 if (!ast_strlen_zero(args.provider)) {
02372 provider = args.provider;
02373 }
02374 ast_debug(1, "OSPlookup: provider '%s'\n", provider);
02375
02376 if (args.options) {
02377 if (strchr(args.options, 'h')) {
02378 callidtypes |= OSP_CALLID_H323;
02379 }
02380 if (strchr(args.options, 's')) {
02381 callidtypes |= OSP_CALLID_SIP;
02382 }
02383 if (strchr(args.options, 'i')) {
02384 callidtypes |= OSP_CALLID_IAX;
02385 }
02386 }
02387 ast_debug(1, "OSPLookup: call id types '%d'\n", callidtypes);
02388
02389 results.inhandle = OSP_INVALID_HANDLE;
02390 results.intimelimit = OSP_DEF_TIMELIMIT;
02391 results.dest[0] = '\0';
02392
02393 np.rn = "";
02394 np.cic = "";
02395 np.npdi = 0;
02396 for (type = OSPC_OPNAME_START; type < OSPC_OPNAME_NUMBER; type++) {
02397 np.opname[type] = "";
02398 }
02399
02400 headers.rpiduser = "";
02401 headers.paiuser = "";
02402 headers.divuser = "";
02403 headers.divhost = "";
02404 headers.pciuser = "";
02405
02406 headp = ast_channel_varshead(chan);
02407 AST_LIST_TRAVERSE(headp, current, entries) {
02408 if (!strcasecmp(ast_var_name(current), "OSPINACTUALSRC")) {
02409 actualsrc = ast_var_value(current);
02410 } else if (!strcasecmp(ast_var_name(current), "OSPINPEERIP")) {
02411 srcdev = ast_var_value(current);
02412 } else if (!strcasecmp(ast_var_name(current), "OSPINTECH")) {
02413 ast_copy_string(results.intech, ast_var_value(current), sizeof(results.intech));
02414 } else if (!strcasecmp(ast_var_name(current), "OSPINHANDLE")) {
02415 if (sscanf(ast_var_value(current), "%30d", &results.inhandle) != 1) {
02416 results.inhandle = OSP_INVALID_HANDLE;
02417 }
02418 } else if (!strcasecmp(ast_var_name(current), "OSPINTIMELIMIT")) {
02419 if (sscanf(ast_var_value(current), "%30d", &results.intimelimit) != 1) {
02420 results.intimelimit = OSP_DEF_TIMELIMIT;
02421 }
02422 } else if (!strcasecmp(ast_var_name(current), "OSPINNETWORKID")) {
02423 snetid = ast_var_value(current);
02424 } else if (!strcasecmp(ast_var_name(current), "OSPINNPRN")) {
02425 np.rn = ast_var_value(current);
02426 } else if (!strcasecmp(ast_var_name(current), "OSPINNPCIC")) {
02427 np.cic = ast_var_value(current);
02428 } else if (!strcasecmp(ast_var_name(current), "OSPINNPDI")) {
02429 if (ast_true(ast_var_value(current))) {
02430 np.npdi = 1;
02431 }
02432 } else if (!strcasecmp(ast_var_name(current), "OSPINSPID")) {
02433 np.opname[OSPC_OPNAME_SPID] = ast_var_value(current);
02434 } else if (!strcasecmp(ast_var_name(current), "OSPINOCN")) {
02435 np.opname[OSPC_OPNAME_OCN] = ast_var_value(current);
02436 } else if (!strcasecmp(ast_var_name(current), "OSPINSPN")) {
02437 np.opname[OSPC_OPNAME_SPN] = ast_var_value(current);
02438 } else if (!strcasecmp(ast_var_name(current), "OSPINALTSPN")) {
02439 np.opname[OSPC_OPNAME_ALTSPN] = ast_var_value(current);
02440 } else if (!strcasecmp(ast_var_name(current), "OSPINMCC")) {
02441 np.opname[OSPC_OPNAME_MCC] = ast_var_value(current);
02442 } else if (!strcasecmp(ast_var_name(current), "OSPINMNC")) {
02443 np.opname[OSPC_OPNAME_MNC] = ast_var_value(current);
02444 } else if (!strcasecmp(ast_var_name(current), "OSPINTOHOST")) {
02445 ast_copy_string(results.dest, ast_var_value(current), sizeof(results.dest));
02446 } else if (!strcasecmp(ast_var_name(current), "OSPINRPIDUSER")) {
02447 headers.rpiduser = ast_var_value(current);
02448 } else if (!strcasecmp(ast_var_name(current), "OSPINPAIUSER")) {
02449 headers.paiuser = ast_var_value(current);
02450 } else if (!strcasecmp(ast_var_name(current), "OSPINDIVUSER")) {
02451 headers.divuser = ast_var_value(current);
02452 } else if (!strcasecmp(ast_var_name(current), "OSPINDIVHOST")) {
02453 headers.divhost = ast_var_value(current);
02454 } else if (!strcasecmp(ast_var_name(current), "OSPINPCIUSER")) {
02455 headers.pciuser = ast_var_value(current);
02456 } else if (!strcasecmp(ast_var_name(current), "OSPINCUSTOMINFO1")) {
02457 cinfo[0] = ast_var_value(current);
02458 } else if (!strcasecmp(ast_var_name(current), "OSPINCUSTOMINFO2")) {
02459 cinfo[1] = ast_var_value(current);
02460 } else if (!strcasecmp(ast_var_name(current), "OSPINCUSTOMINFO3")) {
02461 cinfo[2] = ast_var_value(current);
02462 } else if (!strcasecmp(ast_var_name(current), "OSPINCUSTOMINFO4")) {
02463 cinfo[3] = ast_var_value(current);
02464 } else if (!strcasecmp(ast_var_name(current), "OSPINCUSTOMINFO5")) {
02465 cinfo[4] = ast_var_value(current);
02466 } else if (!strcasecmp(ast_var_name(current), "OSPINCUSTOMINFO6")) {
02467 cinfo[5] = ast_var_value(current);
02468 } else if (!strcasecmp(ast_var_name(current), "OSPINCUSTOMINFO7")) {
02469 cinfo[6] = ast_var_value(current);
02470 } else if (!strcasecmp(ast_var_name(current), "OSPINCUSTOMINFO8")) {
02471 cinfo[7] = ast_var_value(current);
02472 }
02473 }
02474 ast_debug(1, "OSPLookup: actual source device '%s'\n", actualsrc);
02475 ast_debug(1, "OSPLookup: source device '%s'\n", srcdev);
02476 ast_debug(1, "OSPLookup: OSPINTECH '%s'\n", results.intech);
02477 ast_debug(1, "OSPLookup: OSPINHANDLE '%d'\n", results.inhandle);
02478 ast_debug(1, "OSPLookup: OSPINTIMELIMIT '%d'\n", results.intimelimit);
02479 ast_debug(1, "OSPLookup: OSPINNETWORKID '%s'\n", snetid);
02480 ast_debug(1, "OSPLookup: OSPINNPRN '%s'\n", np.rn);
02481 ast_debug(1, "OSPLookup: OSPINNPCIC '%s'\n", np.cic);
02482 ast_debug(1, "OSPLookup: OSPINNPDI '%d'\n", np.npdi);
02483 ast_debug(1, "OSPLookup: OSPINSPID '%s'\n", np.opname[OSPC_OPNAME_SPID]);
02484 ast_debug(1, "OSPLookup: OSPINOCN '%s'\n", np.opname[OSPC_OPNAME_OCN]);
02485 ast_debug(1, "OSPLookup: OSPINSPN '%s'\n", np.opname[OSPC_OPNAME_SPN]);
02486 ast_debug(1, "OSPLookup: OSPINALTSPN '%s'\n", np.opname[OSPC_OPNAME_ALTSPN]);
02487 ast_debug(1, "OSPLookup: OSPINMCC '%s'\n", np.opname[OSPC_OPNAME_MCC]);
02488 ast_debug(1, "OSPLookup: OSPINMNC '%s'\n", np.opname[OSPC_OPNAME_MNC]);
02489 ast_debug(1, "OSPLookup: OSPINTOHOST '%s'\n", results.dest);
02490 ast_debug(1, "OSPLookup: OSPINRPIDUSER '%s'\n", headers.rpiduser);
02491 ast_debug(1, "OSPLookup: OSPINPAIUSER '%s'\n", headers.paiuser);
02492 ast_debug(1, "OSPLookup: OSPINDIVUSER '%s'\n", headers.divuser);
02493 ast_debug(1, "OSPLookup: OSPINDIVHOST'%s'\n", headers.divhost);
02494 ast_debug(1, "OSPLookup: OSPINPCIUSER '%s'\n", headers.pciuser);
02495 for (i = 0; i < OSP_MAX_CUSTOMINFO; i++) {
02496 if (!ast_strlen_zero(cinfo[i])) {
02497 ast_debug(1, "OSPLookup: OSPINCUSTOMINFO%d '%s'\n", i, cinfo[i]);
02498 }
02499 }
02500
02501 if (ast_autoservice_start(chan) < 0) {
02502 return OSP_AST_ERROR;
02503 }
02504
02505 res = osp_lookup(provider, callidtypes, actualsrc, srcdev,
02506 S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL),
02507 args.exten, snetid, &np, &headers, cinfo, &results);
02508 if (res > 0) {
02509 status = AST_OSP_SUCCESS;
02510 } else {
02511 results.outtech[0] = '\0';
02512 results.dest[0] = '\0';
02513 results.calling[0] = '\0';
02514 results.called[0] = '\0';
02515 results.token[0] = '\0';
02516 results.networkid[0] = '\0';
02517 results.nprn[0] = '\0';
02518 results.npcic[0] = '\0';
02519 results.npdi = 0;
02520 for (type = OSPC_OPNAME_START; type < OSPC_OPNAME_NUMBER; type++) {
02521 results.opname[type][0] = '\0';
02522 }
02523 results.numdests = 0;
02524 results.outtimelimit = OSP_DEF_TIMELIMIT;
02525 results.outcallid.buf[0] = '\0';
02526 results.outcallid.len = 0;
02527 if (!res) {
02528 status = AST_OSP_FAILED;
02529 } else {
02530 status = AST_OSP_ERROR;
02531 }
02532 }
02533
02534 snprintf(buffer, sizeof(buffer), "%d", results.outhandle);
02535 pbx_builtin_setvar_helper(chan, "OSPOUTHANDLE", buffer);
02536 ast_debug(1, "OSPLookup: OSPOUTHANDLE '%s'\n", buffer);
02537 pbx_builtin_setvar_helper(chan, "OSPOUTTECH", results.outtech);
02538 ast_debug(1, "OSPLookup: OSPOUTTECH '%s'\n", results.outtech);
02539 pbx_builtin_setvar_helper(chan, "OSPDESTINATION", results.dest);
02540 ast_debug(1, "OSPLookup: OSPDESTINATION '%s'\n", results.dest);
02541 pbx_builtin_setvar_helper(chan, "OSPOUTCALLING", results.calling);
02542 ast_debug(1, "OSPLookup: OSPOUTCALLING '%s'\n", results.calling);
02543 pbx_builtin_setvar_helper(chan, "OSPOUTCALLED", results.called);
02544 ast_debug(1, "OSPLookup: OSPOUTCALLED '%s'\n", results.called);
02545 pbx_builtin_setvar_helper(chan, "OSPOUTNETWORKID", results.networkid);
02546 ast_debug(1, "OSPLookup: OSPOUTNETWORKID '%s'\n", results.networkid);
02547 pbx_builtin_setvar_helper(chan, "OSPOUTNPRN", results.nprn);
02548 ast_debug(1, "OSPLookup: OSPOUTNPRN '%s'\n", results.nprn);
02549 pbx_builtin_setvar_helper(chan, "OSPOUTNPCIC", results.npcic);
02550 ast_debug(1, "OSPLookup: OSPOUTNPCIC '%s'\n", results.npcic);
02551 snprintf(buffer, sizeof(buffer), "%d", results.npdi);
02552 pbx_builtin_setvar_helper(chan, "OSPOUTNPDI", buffer);
02553 ast_debug(1, "OSPLookup: OSPOUTNPDI'%s'\n", buffer);
02554 pbx_builtin_setvar_helper(chan, "OSPOUTSPID", results.opname[OSPC_OPNAME_SPID]);
02555 ast_debug(1, "OSPLookup: OSPOUTSPID '%s'\n", results.opname[OSPC_OPNAME_SPID]);
02556 pbx_builtin_setvar_helper(chan, "OSPOUTOCN", results.opname[OSPC_OPNAME_OCN]);
02557 ast_debug(1, "OSPLookup: OSPOUTOCN '%s'\n", results.opname[OSPC_OPNAME_OCN]);
02558 pbx_builtin_setvar_helper(chan, "OSPOUTSPN", results.opname[OSPC_OPNAME_SPN]);
02559 ast_debug(1, "OSPLookup: OSPOUTSPN '%s'\n", results.opname[OSPC_OPNAME_SPN]);
02560 pbx_builtin_setvar_helper(chan, "OSPOUTALTSPN", results.opname[OSPC_OPNAME_ALTSPN]);
02561 ast_debug(1, "OSPLookup: OSPOUTALTSPN '%s'\n", results.opname[OSPC_OPNAME_ALTSPN]);
02562 pbx_builtin_setvar_helper(chan, "OSPOUTMCC", results.opname[OSPC_OPNAME_MCC]);
02563 ast_debug(1, "OSPLookup: OSPOUTMCC '%s'\n", results.opname[OSPC_OPNAME_MCC]);
02564 pbx_builtin_setvar_helper(chan, "OSPOUTMNC", results.opname[OSPC_OPNAME_MNC]);
02565 ast_debug(1, "OSPLookup: OSPOUTMNC '%s'\n", results.opname[OSPC_OPNAME_MNC]);
02566 pbx_builtin_setvar_helper(chan, "OSPOUTTOKEN", results.token);
02567 ast_debug(1, "OSPLookup: OSPOUTTOKEN size '%zd'\n", strlen(results.token));
02568 snprintf(buffer, sizeof(buffer), "%d", results.numdests);
02569 pbx_builtin_setvar_helper(chan, "OSPDESTREMAILS", buffer);
02570 ast_debug(1, "OSPLookup: OSPDESTREMAILS '%s'\n", buffer);
02571 snprintf(buffer, sizeof(buffer), "%d", results.outtimelimit);
02572 pbx_builtin_setvar_helper(chan, "OSPOUTTIMELIMIT", buffer);
02573 ast_debug(1, "OSPLookup: OSPOUTTIMELIMIT '%s'\n", buffer);
02574 snprintf(buffer, sizeof(buffer), "%d", callidtypes);
02575 pbx_builtin_setvar_helper(chan, "OSPOUTCALLIDTYPES", buffer);
02576 ast_debug(1, "OSPLookup: OSPOUTCALLIDTYPES '%s'\n", buffer);
02577 pbx_builtin_setvar_helper(chan, "OSPLOOKUPSTATUS", status);
02578 ast_debug(1, "OSPLookup: %s\n", status);
02579
02580 if (!strcasecmp(results.outtech, OSP_TECH_SIP)) {
02581 snprintf(buffer, sizeof(buffer), "%s/%s@%s", results.outtech, results.called, results.dest);
02582 pbx_builtin_setvar_helper(chan, "OSPDIALSTR", buffer);
02583 if (!ast_strlen_zero(results.token)) {
02584 snprintf(buffer, sizeof(buffer), "%s: %s", OSP_SIP_HEADER, results.token);
02585 pbx_builtin_setvar_helper(chan, "_SIPADDHEADER", buffer);
02586 ast_debug(1, "OSPLookup: SIPADDHEADER size '%zd'\n", strlen(buffer));
02587 }
02588 } else if (!strcasecmp(results.outtech, OSP_TECH_H323)) {
02589 if ((callidtypes & OSP_CALLID_H323) && (results.outcallid.len != 0)) {
02590 osp_uuid2str(results.outcallid.buf, buffer, sizeof(buffer));
02591 } else {
02592 buffer[0] = '\0';
02593 }
02594 pbx_builtin_setvar_helper(chan, "OSPOUTCALLID", buffer);
02595 snprintf(buffer, sizeof(buffer), "%s/%s@%s", results.outtech, results.called, results.dest);
02596 pbx_builtin_setvar_helper(chan, "OSPDIALSTR", buffer);
02597 } else if (!strcasecmp(results.outtech, OSP_TECH_IAX)) {
02598 snprintf(buffer, sizeof(buffer), "%s/%s/%s", results.outtech, results.dest, results.called);
02599 pbx_builtin_setvar_helper(chan, "OSPDIALSTR", buffer);
02600 } else if (!strcasecmp(results.outtech, OSP_TECH_SKYPE)) {
02601 snprintf(buffer, sizeof(buffer), "%s/%s", results.outtech, results.called);
02602 pbx_builtin_setvar_helper(chan, "OSPDIALSTR", buffer);
02603 }
02604
02605 if (ast_autoservice_stop(chan) < 0) {
02606 return OSP_AST_ERROR;
02607 }
02608
02609 if(res != OSP_OK) {
02610 res = OSP_AST_ERROR;
02611 } else {
02612 res = OSP_AST_OK;
02613 }
02614
02615 return res;
02616 }
02617
02618
02619
02620
02621
02622
02623
02624 static int ospnext_exec(
02625 struct ast_channel* chan,
02626 const char * data)
02627 {
02628 int res;
02629 const char* provider = OSP_DEF_PROVIDER;
02630 int cause = 0;
02631 struct varshead* headp;
02632 struct ast_var_t* current;
02633 struct osp_results results;
02634 OSPE_OPERATOR_NAME type;
02635 char buffer[OSP_SIZE_TOKSTR];
02636 unsigned int callidtypes = OSP_CALLID_UNDEF;
02637 const char* status;
02638 char* tmp;
02639
02640 AST_DECLARE_APP_ARGS(args,
02641 AST_APP_ARG(cause);
02642 AST_APP_ARG(provider);
02643 AST_APP_ARG(options);
02644 );
02645
02646 if (ast_strlen_zero(data)) {
02647 ast_log(LOG_WARNING, "OSPNext: Arg required, OSPNext(cause[,provider[,options]])\n");
02648 return OSP_AST_ERROR;
02649 }
02650
02651 tmp = ast_strdupa(data);
02652
02653 AST_STANDARD_APP_ARGS(args, tmp);
02654
02655 if (!ast_strlen_zero(args.cause) && sscanf(args.cause, "%30d", &cause) != 1) {
02656 cause = 0;
02657 }
02658 ast_debug(1, "OSPNext: cause '%d'\n", cause);
02659
02660 if (!ast_strlen_zero(args.provider)) {
02661 provider = args.provider;
02662 }
02663 ast_debug(1, "OSPlookup: provider '%s'\n", provider);
02664
02665 results.inhandle = OSP_INVALID_HANDLE;
02666 results.outhandle = OSP_INVALID_HANDLE;
02667 results.intimelimit = OSP_DEF_TIMELIMIT;
02668 results.numdests = 0;
02669
02670 headp = ast_channel_varshead(chan);
02671 AST_LIST_TRAVERSE(headp, current, entries) {
02672 if (!strcasecmp(ast_var_name(current), "OSPINHANDLE")) {
02673 if (sscanf(ast_var_value(current), "%30d", &results.inhandle) != 1) {
02674 results.inhandle = OSP_INVALID_HANDLE;
02675 }
02676 } else if (!strcasecmp(ast_var_name(current), "OSPOUTHANDLE")) {
02677 if (sscanf(ast_var_value(current), "%30d", &results.outhandle) != 1) {
02678 results.outhandle = OSP_INVALID_HANDLE;
02679 }
02680 } else if (!strcasecmp(ast_var_name(current), "OSPINTIMELIMIT")) {
02681 if (sscanf(ast_var_value(current), "%30d", &results.intimelimit) != 1) {
02682 results.intimelimit = OSP_DEF_TIMELIMIT;
02683 }
02684 } else if (!strcasecmp(ast_var_name(current), "OSPOUTCALLIDTYPES")) {
02685 if (sscanf(ast_var_value(current), "%30d", &callidtypes) != 1) {
02686 callidtypes = OSP_CALLID_UNDEF;
02687 }
02688 } else if (!strcasecmp(ast_var_name(current), "OSPDESTREMAILS")) {
02689 if (sscanf(ast_var_value(current), "%30d", &results.numdests) != 1) {
02690 results.numdests = 0;
02691 }
02692 }
02693 }
02694 ast_debug(1, "OSPNext: OSPINHANDLE '%d'\n", results.inhandle);
02695 ast_debug(1, "OSPNext: OSPOUTHANDLE '%d'\n", results.outhandle);
02696 ast_debug(1, "OSPNext: OSPINTIMELIMIT '%d'\n", results.intimelimit);
02697 ast_debug(1, "OSPNext: OSPOUTCALLIDTYPES '%d'\n", callidtypes);
02698 ast_debug(1, "OSPNext: OSPDESTREMAILS '%d'\n", results.numdests);
02699
02700 if ((res = osp_next(provider, cause, &results)) > 0) {
02701 status = AST_OSP_SUCCESS;
02702 } else {
02703 results.outtech[0] = '\0';
02704 results.dest[0] = '\0';
02705 results.calling[0] = '\0';
02706 results.called[0] = '\0';
02707 results.token[0] = '\0';
02708 results.networkid[0] = '\0';
02709 results.nprn[0] = '\0';
02710 results.npcic[0] = '\0';
02711 results.npdi = 0;
02712 for (type = OSPC_OPNAME_START; type < OSPC_OPNAME_NUMBER; type++) {
02713 results.opname[type][0] = '\0';
02714 }
02715 results.numdests = 0;
02716 results.outtimelimit = OSP_DEF_TIMELIMIT;
02717 results.outcallid.buf[0] = '\0';
02718 results.outcallid.len = 0;
02719 if (!res) {
02720 status = AST_OSP_FAILED;
02721 } else {
02722 status = AST_OSP_ERROR;
02723 }
02724 }
02725
02726 pbx_builtin_setvar_helper(chan, "OSPOUTTECH", results.outtech);
02727 ast_debug(1, "OSPNext: OSPOUTTECH '%s'\n", results.outtech);
02728 pbx_builtin_setvar_helper(chan, "OSPDESTINATION", results.dest);
02729 ast_debug(1, "OSPNext: OSPDESTINATION '%s'\n", results.dest);
02730 pbx_builtin_setvar_helper(chan, "OSPOUTCALLING", results.calling);
02731 ast_debug(1, "OSPNext: OSPOUTCALLING '%s'\n", results.calling);
02732 pbx_builtin_setvar_helper(chan, "OSPOUTCALLED", results.called);
02733 ast_debug(1, "OSPNext: OSPOUTCALLED'%s'\n", results.called);
02734 pbx_builtin_setvar_helper(chan, "OSPOUTNETWORKID", results.networkid);
02735 ast_debug(1, "OSPLookup: OSPOUTNETWORKID '%s'\n", results.networkid);
02736 pbx_builtin_setvar_helper(chan, "OSPOUTNPRN", results.nprn);
02737 ast_debug(1, "OSPLookup: OSPOUTNPRN '%s'\n", results.nprn);
02738 pbx_builtin_setvar_helper(chan, "OSPOUTNPCIC", results.npcic);
02739 ast_debug(1, "OSPLookup: OSPOUTNPCIC '%s'\n", results.npcic);
02740 snprintf(buffer, sizeof(buffer), "%d", results.npdi);
02741 pbx_builtin_setvar_helper(chan, "OSPOUTNPDI", buffer);
02742 ast_debug(1, "OSPLookup: OSPOUTNPDI'%s'\n", buffer);
02743 pbx_builtin_setvar_helper(chan, "OSPOUTSPID", results.opname[OSPC_OPNAME_SPID]);
02744 ast_debug(1, "OSPLookup: OSPOUTSPID '%s'\n", results.opname[OSPC_OPNAME_SPID]);
02745 pbx_builtin_setvar_helper(chan, "OSPOUTOCN", results.opname[OSPC_OPNAME_OCN]);
02746 ast_debug(1, "OSPLookup: OSPOUTOCN '%s'\n", results.opname[OSPC_OPNAME_OCN]);
02747 pbx_builtin_setvar_helper(chan, "OSPOUTSPN", results.opname[OSPC_OPNAME_SPN]);
02748 ast_debug(1, "OSPLookup: OSPOUTSPN '%s'\n", results.opname[OSPC_OPNAME_SPN]);
02749 pbx_builtin_setvar_helper(chan, "OSPOUTALTSPN", results.opname[OSPC_OPNAME_ALTSPN]);
02750 ast_debug(1, "OSPLookup: OSPOUTALTSPN '%s'\n", results.opname[OSPC_OPNAME_ALTSPN]);
02751 pbx_builtin_setvar_helper(chan, "OSPOUTMCC", results.opname[OSPC_OPNAME_MCC]);
02752 ast_debug(1, "OSPLookup: OSPOUTMCC '%s'\n", results.opname[OSPC_OPNAME_MCC]);
02753 pbx_builtin_setvar_helper(chan, "OSPOUTMNC", results.opname[OSPC_OPNAME_MNC]);
02754 ast_debug(1, "OSPLookup: OSPOUTMNC '%s'\n", results.opname[OSPC_OPNAME_MNC]);
02755 pbx_builtin_setvar_helper(chan, "OSPOUTTOKEN", results.token);
02756 ast_debug(1, "OSPNext: OSPOUTTOKEN size '%zd'\n", strlen(results.token));
02757 snprintf(buffer, sizeof(buffer), "%d", results.numdests);
02758 pbx_builtin_setvar_helper(chan, "OSPDESTREMAILS", buffer);
02759 ast_debug(1, "OSPNext: OSPDESTREMAILS '%s'\n", buffer);
02760 snprintf(buffer, sizeof(buffer), "%d", results.outtimelimit);
02761 pbx_builtin_setvar_helper(chan, "OSPOUTTIMELIMIT", buffer);
02762 ast_debug(1, "OSPNext: OSPOUTTIMELIMIT '%s'\n", buffer);
02763 pbx_builtin_setvar_helper(chan, "OSPNEXTSTATUS", status);
02764 ast_debug(1, "OSPNext: %s\n", status);
02765
02766 if (!strcasecmp(results.outtech, OSP_TECH_SIP)) {
02767 snprintf(buffer, sizeof(buffer), "%s/%s@%s", results.outtech, results.called, results.dest);
02768 pbx_builtin_setvar_helper(chan, "OSPDIALSTR", buffer);
02769 if (!ast_strlen_zero(results.token)) {
02770 snprintf(buffer, sizeof(buffer), "%s: %s", OSP_SIP_HEADER, results.token);
02771 pbx_builtin_setvar_helper(chan, "_SIPADDHEADER", buffer);
02772 ast_debug(1, "OSPLookup: SIPADDHEADER size '%zd'\n", strlen(buffer));
02773 }
02774 } else if (!strcasecmp(results.outtech, OSP_TECH_H323)) {
02775 if ((callidtypes & OSP_CALLID_H323) && (results.outcallid.len != 0)) {
02776 osp_uuid2str(results.outcallid.buf, buffer, sizeof(buffer));
02777 } else {
02778 buffer[0] = '\0';
02779 }
02780 pbx_builtin_setvar_helper(chan, "OSPOUTCALLID", buffer);
02781 snprintf(buffer, sizeof(buffer), "%s/%s@%s", results.outtech, results.called, results.dest);
02782 pbx_builtin_setvar_helper(chan, "OSPDIALSTR", buffer);
02783 } else if (!strcasecmp(results.outtech, OSP_TECH_IAX)) {
02784 snprintf(buffer, sizeof(buffer), "%s/%s/%s", results.outtech, results.dest, results.called);
02785 pbx_builtin_setvar_helper(chan, "OSPDIALSTR", buffer);
02786 } else if (!strcasecmp(results.outtech, OSP_TECH_SKYPE)) {
02787 snprintf(buffer, sizeof(buffer), "%s/%s", results.outtech, results.called);
02788 pbx_builtin_setvar_helper(chan, "OSPDIALSTR", buffer);
02789 }
02790
02791 if(res != OSP_OK) {
02792 res = OSP_AST_ERROR;
02793 } else {
02794 res = OSP_AST_OK;
02795 }
02796
02797 return res;
02798 }
02799
02800
02801
02802
02803
02804
02805
02806 static int ospfinished_exec(
02807 struct ast_channel* chan,
02808 const char * data)
02809 {
02810 int res = OSP_OK;
02811 int cause = 0;
02812 struct varshead* headp;
02813 struct ast_var_t* current;
02814 int inhandle = OSP_INVALID_HANDLE;
02815 int outhandle = OSP_INVALID_HANDLE;
02816 int recorded = 0;
02817 time_t start, connect, end;
02818 unsigned int release;
02819 char buffer[OSP_SIZE_INTSTR];
02820 char inqos[OSP_SIZE_QOSSTR] = { 0 };
02821 char outqos[OSP_SIZE_QOSSTR] = { 0 };
02822 const char* status;
02823 char* tmp;
02824
02825 AST_DECLARE_APP_ARGS(args,
02826 AST_APP_ARG(cause);
02827 AST_APP_ARG(options);
02828 );
02829
02830 tmp = ast_strdupa(data);
02831
02832 AST_STANDARD_APP_ARGS(args, tmp);
02833
02834 headp = ast_channel_varshead(chan);
02835 AST_LIST_TRAVERSE(headp, current, entries) {
02836 if (!strcasecmp(ast_var_name(current), "OSPINHANDLE")) {
02837 if (sscanf(ast_var_value(current), "%30d", &inhandle) != 1) {
02838 inhandle = OSP_INVALID_HANDLE;
02839 }
02840 } else if (!strcasecmp(ast_var_name(current), "OSPOUTHANDLE")) {
02841 if (sscanf(ast_var_value(current), "%30d", &outhandle) != 1) {
02842 outhandle = OSP_INVALID_HANDLE;
02843 }
02844 } else if (!recorded &&
02845 (!strcasecmp(ast_var_name(current), "OSPAUTHSTATUS") ||
02846 !strcasecmp(ast_var_name(current), "OSPLOOKUPSTATUS") ||
02847 !strcasecmp(ast_var_name(current), "OSPNEXTSTATUS")))
02848 {
02849 if (strcasecmp(ast_var_value(current), AST_OSP_SUCCESS)) {
02850 recorded = 1;
02851 }
02852 } else if (!strcasecmp(ast_var_name(current), "OSPINAUDIOQOS")) {
02853 ast_copy_string(inqos, ast_var_value(current), sizeof(inqos));
02854 } else if (!strcasecmp(ast_var_name(current), "OSPOUTAUDIOQOS")) {
02855 ast_copy_string(outqos, ast_var_value(current), sizeof(outqos));
02856 }
02857 }
02858 ast_debug(1, "OSPFinish: OSPINHANDLE '%d'\n", inhandle);
02859 ast_debug(1, "OSPFinish: OSPOUTHANDLE '%d'\n", outhandle);
02860 ast_debug(1, "OSPFinish: recorded '%d'\n", recorded);
02861 ast_debug(1, "OSPFinish: OSPINAUDIOQOS '%s'\n", inqos);
02862 ast_debug(1, "OSPFinish: OSPOUTAUDIOQOS '%s'\n", outqos);
02863
02864 if (!ast_strlen_zero(args.cause) && sscanf(args.cause, "%30d", &cause) != 1) {
02865 cause = 0;
02866 }
02867 ast_debug(1, "OSPFinish: cause '%d'\n", cause);
02868
02869 if (ast_channel_cdr(chan)) {
02870 start = ast_channel_cdr(chan)->start.tv_sec;
02871 connect = ast_channel_cdr(chan)->answer.tv_sec;
02872 if (connect) {
02873 end = time(NULL);
02874 } else {
02875 end = connect;
02876 }
02877 } else {
02878 start = 0;
02879 connect = 0;
02880 end = 0;
02881 }
02882 ast_debug(1, "OSPFinish: start '%ld'\n", start);
02883 ast_debug(1, "OSPFinish: connect '%ld'\n", connect);
02884 ast_debug(1, "OSPFinish: end '%ld'\n", end);
02885
02886 release = ast_check_hangup(chan) ? 0 : 1;
02887
02888 if (osp_finish(outhandle, recorded, cause, start, connect, end, release, inqos, outqos) <= 0) {
02889 ast_debug(1, "OSPFinish: Unable to report usage for outbound call\n");
02890 }
02891 switch (cause) {
02892 case AST_CAUSE_NORMAL_CLEARING:
02893 break;
02894 default:
02895 cause = AST_CAUSE_NO_ROUTE_DESTINATION;
02896 break;
02897 }
02898 if (osp_finish(inhandle, recorded, cause, start, connect, end, release, inqos, outqos) <= 0) {
02899 ast_debug(1, "OSPFinish: Unable to report usage for inbound call\n");
02900 }
02901 snprintf(buffer, sizeof(buffer), "%d", OSP_INVALID_HANDLE);
02902 pbx_builtin_setvar_helper(chan, "OSPOUTHANDLE", buffer);
02903 pbx_builtin_setvar_helper(chan, "OSPINHANDLE", buffer);
02904
02905 if (res > 0) {
02906 status = AST_OSP_SUCCESS;
02907 } else if (!res) {
02908 status = AST_OSP_FAILED;
02909 } else {
02910 status = AST_OSP_ERROR;
02911 }
02912 pbx_builtin_setvar_helper(chan, "OSPFINISHSTATUS", status);
02913
02914 if(res != OSP_OK) {
02915 res = OSP_AST_ERROR;
02916 } else {
02917 res = OSP_AST_OK;
02918 }
02919
02920 return res;
02921 }
02922
02923
02924
02925 static int osp_unload(void)
02926 {
02927 struct osp_provider* provider;
02928 struct osp_provider* next;
02929
02930 if (osp_initialized) {
02931 ast_mutex_lock(&osp_lock);
02932 for (provider = osp_providers; provider; provider = next) {
02933 next = provider->next;
02934 OSPPProviderDelete(provider->handle, 0);
02935 ast_free(provider);
02936 }
02937 osp_providers = NULL;
02938 ast_mutex_unlock(&osp_lock);
02939
02940 OSPPCleanup();
02941
02942 osp_tokenformat = TOKEN_ALGO_SIGNED;
02943 osp_security = 0;
02944 osp_hardware = 0;
02945 osp_initialized = 0;
02946 }
02947
02948 return 0;
02949 }
02950
02951 static int osp_load(int reload)
02952 {
02953 const char* cvar;
02954 unsigned int ivar;
02955 struct ast_config* cfg;
02956 struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
02957 int error = OSPC_ERR_NO_ERROR;
02958
02959 if ((cfg = ast_config_load(OSP_CONFIG_FILE, config_flags)) == CONFIG_STATUS_FILEUNCHANGED) {
02960 return 0;
02961 } else if (cfg == CONFIG_STATUS_FILEINVALID) {
02962 ast_log(LOG_ERROR, "Config file %s is in an invalid format. Aborting.\n", OSP_CONFIG_FILE);
02963 return 0;
02964 }
02965
02966 if (cfg) {
02967 if (reload) {
02968 osp_unload();
02969 }
02970
02971 if ((cvar = ast_variable_retrieve(cfg, OSP_GENERAL_CAT, "accelerate")) && ast_true(cvar)) {
02972 if ((error = OSPPInit(1)) != OSPC_ERR_NO_ERROR) {
02973 ast_log(LOG_WARNING, "OSP: Unable to enable hardware acceleration, error='%d'\n", error);
02974 OSPPInit(0);
02975 } else {
02976 osp_hardware = 1;
02977 }
02978 } else {
02979 OSPPInit(0);
02980 }
02981 ast_debug(1, "OSP: osp_hardware '%d'\n", osp_hardware);
02982
02983 if ((cvar = ast_variable_retrieve(cfg, OSP_GENERAL_CAT, "securityfeatures")) && ast_true(cvar)) {
02984 osp_security = 1;
02985 }
02986 ast_debug(1, "OSP: osp_security '%d'\n", osp_security);
02987
02988 if ((cvar = ast_variable_retrieve(cfg, OSP_GENERAL_CAT, "tokenformat"))) {
02989 if ((sscanf(cvar, "%30d", &ivar) == 1) &&
02990 ((ivar == TOKEN_ALGO_SIGNED) || (ivar == TOKEN_ALGO_UNSIGNED) || (ivar == TOKEN_ALGO_BOTH)))
02991 {
02992 osp_tokenformat = ivar;
02993 } else {
02994 ast_log(LOG_WARNING, "tokenformat should be an integer from %d, %d or %d, not '%s'\n",
02995 TOKEN_ALGO_SIGNED, TOKEN_ALGO_UNSIGNED, TOKEN_ALGO_BOTH, cvar);
02996 }
02997 }
02998 ast_debug(1, "OSP: osp_tokenformat '%d'\n", osp_tokenformat);
02999
03000 for (cvar = ast_category_browse(cfg, NULL); cvar != NULL; cvar = ast_category_browse(cfg, cvar)) {
03001 if (strcasecmp(cvar, OSP_GENERAL_CAT)) {
03002 osp_create_provider(cfg, cvar);
03003 }
03004 }
03005
03006 osp_initialized = 1;
03007
03008 ast_config_destroy(cfg);
03009 } else {
03010 ast_log(LOG_WARNING, "OSP: Unable to find configuration. OSP support disabled\n");
03011 return 0;
03012 }
03013 ast_debug(1, "OSP: osp_initialized '%d'\n", osp_initialized);
03014
03015 return 1;
03016 }
03017
03018 static char *handle_cli_osp_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
03019 {
03020 int i;
03021 int found = 0;
03022 struct osp_provider* provider;
03023 const char* name = NULL;
03024 const char* tokenalgo;
03025
03026 switch (cmd) {
03027 case CLI_INIT:
03028 e->command = "osp show";
03029 e->usage =
03030 "Usage: osp show\n"
03031 " Displays information on Open Settlement Protocol support\n";
03032 return NULL;
03033 case CLI_GENERATE:
03034 return NULL;
03035 }
03036
03037 if ((a->argc < 2) || (a->argc > 3)) {
03038 return CLI_SHOWUSAGE;
03039 }
03040
03041 if (a->argc > 2) {
03042 name = a->argv[2];
03043 }
03044
03045 if (!name) {
03046 switch (osp_tokenformat) {
03047 case TOKEN_ALGO_BOTH:
03048 tokenalgo = "Both";
03049 break;
03050 case TOKEN_ALGO_UNSIGNED:
03051 tokenalgo = "Unsigned";
03052 break;
03053 case TOKEN_ALGO_SIGNED:
03054 default:
03055 tokenalgo = "Signed";
03056 break;
03057 }
03058 ast_cli(a->fd, "OSP: %s/%s/%s/%s\n",
03059 osp_initialized ? "Initialized" : "Uninitialized",
03060 osp_hardware ? "Accelerated" : "Normal",
03061 osp_security ? "Enabled" : "Disabled",
03062 tokenalgo);
03063 }
03064
03065 ast_mutex_lock(&osp_lock);
03066 for (provider = osp_providers; provider; provider = provider->next) {
03067 if (!name || !strcasecmp(provider->name, name)) {
03068 if (found) {
03069 ast_cli(a->fd, "\n");
03070 }
03071 ast_cli(a->fd, " == OSP Provider '%s' == \n", provider->name);
03072 if (osp_security) {
03073 ast_cli(a->fd, "Local Private Key: %s\n", provider->privatekey);
03074 ast_cli(a->fd, "Local Certificate: %s\n", provider->localcert);
03075 for (i = 0; i < provider->canum; i++) {
03076 ast_cli(a->fd, "CA Certificate %d: %s\n", i + 1, provider->cacerts[i]);
03077 }
03078 }
03079 for (i = 0; i < provider->spnum; i++) {
03080 ast_cli(a->fd, "Service Point %d: %s\n", i + 1, provider->spoints[i]);
03081 }
03082 ast_cli(a->fd, "Max Connections: %d\n", provider->maxconnect);
03083 ast_cli(a->fd, "Retry Delay: %d seconds\n", provider->retrydelay);
03084 ast_cli(a->fd, "Retry Limit: %d\n", provider->retrylimit);
03085 ast_cli(a->fd, "Timeout: %d milliseconds\n", provider->timeout);
03086 ast_cli(a->fd, "Source: %s\n", strlen(provider->source) ? provider->source : "<unspecified>");
03087 ast_cli(a->fd, "Auth Policy %d\n", provider->authpolicy);
03088 ast_cli(a->fd, "Default protocol %s\n", provider->defprotocol);
03089 ast_cli(a->fd, "Work mode %d\n", provider->workmode);
03090 ast_cli(a->fd, "Service type %d\n", provider->srvtype);
03091 ast_cli(a->fd, "OSP Handle: %d\n", provider->handle);
03092 found++;
03093 }
03094 }
03095 ast_mutex_unlock(&osp_lock);
03096
03097 if (!found) {
03098 if (name) {
03099 ast_cli(a->fd, "Unable to find OSP provider '%s'\n", name);
03100 } else {
03101 ast_cli(a->fd, "No OSP providers configured\n");
03102 }
03103 }
03104
03105 return CLI_SUCCESS;
03106 }
03107
03108
03109 static const char app1[] = "OSPAuth";
03110
03111
03112 static const char app2[] = "OSPLookup";
03113
03114
03115 static const char app3[] = "OSPNext";
03116
03117
03118 static const char app4[] = "OSPFinish";
03119
03120 static struct ast_cli_entry cli_osp[] = {
03121 AST_CLI_DEFINE(handle_cli_osp_show, "Displays OSF information")
03122 };
03123
03124 static int load_module(void)
03125 {
03126 int res;
03127
03128 if (!osp_load(0))
03129 return AST_MODULE_LOAD_DECLINE;
03130
03131 ast_cli_register_multiple(cli_osp, sizeof(cli_osp) / sizeof(struct ast_cli_entry));
03132 res = ast_register_application_xml(app1, ospauth_exec);
03133 res |= ast_register_application_xml(app2, osplookup_exec);
03134 res |= ast_register_application_xml(app3, ospnext_exec);
03135 res |= ast_register_application_xml(app4, ospfinished_exec);
03136
03137 return res;
03138 }
03139
03140 static int unload_module(void)
03141 {
03142 int res;
03143
03144 res = ast_unregister_application(app4);
03145 res |= ast_unregister_application(app3);
03146 res |= ast_unregister_application(app2);
03147 res |= ast_unregister_application(app1);
03148 ast_cli_unregister_multiple(cli_osp, sizeof(cli_osp) / sizeof(struct ast_cli_entry));
03149 osp_unload();
03150
03151 return res;
03152 }
03153
03154 static int reload(void)
03155 {
03156 osp_load(1);
03157
03158 return 0;
03159 }
03160
03161 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Open Settlement Protocol Applications",
03162 .load = load_module,
03163 .unload = unload_module,
03164 .reload = reload,
03165 );