提交 32dbb191 authored 作者: Di-Shi Sun's avatar Di-Shi Sun

Added work mode option and support for outbound proxy.

上级 4e820983
......@@ -19,7 +19,7 @@
</settings>
<profiles>
<!-- Default OSP provider profile -->
<!-- Default OSP profile -->
<profile name="default">
<!-- Service point URLs, up to 8 allowed -->
<!-- <param name="service-point-url" value="http://osptestserver.transnexus.com:1080/osp"/> -->
......@@ -42,6 +42,8 @@
<!-- HTTP timeout in milliseconds, 200~60000 -->
<param name="http-timeout" value="10000"/>
<!-- OSP work mode, direct or indirect -->
<param name="work-mode" value="direct"/>
<!-- OSP service type, voice or npquery -->
<param name="service-type" value="voice"/>
<!-- Max number of destinations -->
......
......@@ -96,14 +96,16 @@
#define OSP_MODULE_SKYPE "mod_skypopen" /* FreeSWITCH Skype module name */
/* OSP Variables Name */
#define OSP_VAR_PROFILE "osp_profile" /* Provider name, in OSP cookie */
#define OSP_VAR_PROFILE "osp_profile" /* Profile name, in OSP cookie */
#define OSP_VAR_TRANSID "osp_transaction_id" /* Transaction ID, in OSP cookie */
#define OSP_VAR_START "osp_start_time" /* Inbound Call start time, in OSP cookie */
#define OSP_VAR_DESTCOUNT "osp_destination_count" /* Destination count, in OSP cookie */
#define OSP_VAR_SRCDEV "osp_source_device" /* Source device IP, in OSP cookie or inbound (actual source device)*/
#define OSP_VAR_SRCNID "osp_source_nid" /* Source network ID, inbound and in OSP cookie */
#define OSP_VAR_DESTCOUNT "osp_destination_count" /* Destination count, in OSP cookie */
#define OSP_VAR_DESTIP "osp_destination_ip" /* Destination IP, in OSP cookie */
#define OSP_VAR_DESTNID "osp_destination_nid" /* Destination network ID, in OSP cookie */
#define OSP_VAR_CUSTOMINFO "osp_custom_info_" /* Custom info */
#define OSP_VAR_OUTPROXY "osp_outbound_proxy" /* Outbound proxy */
#define OSP_VAR_ROUTECOUNT "osp_route_count" /* Number of destinations */
#define OSP_VAR_ROUTEPRE "osp_route_" /* Destination prefix */
#define OSP_VAR_AUTOROUTE "osp_auto_route" /* Bridge route string */
......@@ -123,26 +125,32 @@
#define OSP_FS_RTPUPPKTS "rtp_audio_in_media_packet_count" /* Upstream packets */
typedef struct osp_settings {
switch_bool_t debug; /* OSP module debug info flag */
switch_log_level_t loglevel; /* Log level for debug info */
switch_bool_t hardware; /* Crypto hardware flag */
const char *module[OSPC_DPROT_NUMBER]; /* Endpoint names */
const char *profile[OSPC_DPROT_NUMBER]; /* Profile names */
OSPE_DEST_PROTOCOL protocol; /* Default destination protocol */
switch_bool_t shutdown; /* OSP module status */
switch_memory_pool_t *pool; /* OSP module memory pool */
switch_bool_t debug; /* OSP module debug info flag */
switch_log_level_t loglevel; /* Log level for debug info */
switch_bool_t hardware; /* Crypto hardware flag */
const char *modules[OSPC_DPROT_NUMBER]; /* Endpoint names */
const char *profiles[OSPC_DPROT_NUMBER]; /* Endpoint profile names */
OSPE_DEST_PROTOCOL protocol; /* Default destination protocol */
switch_bool_t shutdown; /* OSP module status */
switch_memory_pool_t *pool; /* OSP module memory pool */
} osp_settings_t;
/* OSP Work Modes */
typedef enum osp_workmode {
OSP_MODE_DIRECT = 0, /* Direct work mode */
OSP_MODE_INDIRECT /* Indirect work mode */
} osp_workmode_t;
/* OSP Service Types */
typedef enum osp_srvtype {
OSP_SRV_VOICE = 0, /* Normal voice service */
OSP_SRV_NPQUERY /* Number portability query service */
} osp_srvtype_t;
typedef struct osp_provider {
const char *name; /* OSP provider profile name */
typedef struct osp_profile {
const char *name; /* OSP profile name */
int spnum; /* Number of OSP service points */
const char *spurls[OSP_MAX_SP]; /* OSP provider service point URLs */
const char *spurls[OSP_MAX_SP]; /* OSP service point URLs */
const char *device; /* OSP source IP */
int lifetime; /* SSL life time */
int maxconnect; /* Max number of HTTP connections */
......@@ -150,14 +158,16 @@ typedef struct osp_provider {
int retrydelay; /* HTTP retry delay in seconds */
int retrylimit; /* HTTP retry times */
int timeout; /* HTTP timeout in ms */
osp_workmode_t workmode; /* OSP work mode */
osp_srvtype_t srvtype; /* OSP service type */
int maxdest; /* Max destinations */
switch_bool_t userphone; /* Add "user=phone" URI parameter */
OSPTPROVHANDLE handle; /* OSP provider handle */
struct osp_provider *next; /* Next OSP provider */
} osp_provider_t;
OSPTPROVHANDLE provider; /* OSP provider handle */
struct osp_profile *next; /* Next OSP profile */
} osp_profile_t;
typedef struct osp_inbound {
const char *actsrc; /* Actual source device IP address */
const char *srcdev; /* Source device IP address */
const char *calling; /* Inbound calling number */
char called[OSP_SIZE_NORSTR]; /* Inbound called number */
......@@ -171,6 +181,7 @@ typedef struct osp_inbound {
const char *srcnid; /* Inbound source network ID */
switch_time_t start; /* Call start time */
const char *cinfo[OSP_MAX_CINFO]; /* Custom info */
const char *outproxy; /* Outbound proxy IP address */
} osp_inbound_t;
typedef struct osp_destination {
......@@ -186,22 +197,25 @@ typedef struct osp_destination {
OSPE_DEST_PROTOCOL protocol; /* Destination protocol */
switch_bool_t supported; /* Supported by FreeRADIUS OSP module */
switch_bool_t userphone; /* Add "user=phone" parameter */
const char *outproxy; /* Outbound proxy IP */
} osp_destination_t;
typedef struct osp_results {
const char *profile; /* Provider name */
const char *profile; /* Profile name */
uint64_t transid; /* Transaction ID */
switch_time_t start; /* Call start time */
char called[OSP_SIZE_NORSTR]; /* Original called number */
const char *srcdev; /* Source device IP */
const char *srcnid; /* Source network ID */
int numdest; /* Number of destinations */
osp_destination_t dests[OSP_MAX_SP]; /* Destinations */
} osp_results_t;
typedef struct osp_cookie {
const char *profile; /* Provider name */
const char *profile; /* Profile name */
uint64_t transid; /* Transaction ID */
switch_time_t start; /* Call start time */
const char *srcdev; /* Source Device IP */
int destcount; /* Destination count */
const char *dest; /* Destination IP */
const char *srcnid; /* Source network ID */
......@@ -209,10 +223,10 @@ typedef struct osp_cookie {
} osp_cookie_t;
typedef struct osp_usage {
const char *srcdev; /* Source device IP */
const char *callid; /* Call-ID */
const char *calling; /* Calling number */
char called[OSP_SIZE_NORSTR]; /* Called number */
const char *srcdev; /* Source device IP */
OSPE_DEST_PROTOCOL protocol; /* Destination protocol */
int release; /* Release source */
switch_call_cause_t cause; /* Termination cause */
......@@ -230,7 +244,7 @@ typedef struct osp_usage {
} osp_usage_t;
typedef struct osp_threadarg {
OSPTTRANHANDLE handle; /* Transaction handle */
OSPTTRANHANDLE transaction; /* Transaction handle */
uint64_t transid; /* Transaction ID */
switch_call_cause_t cause; /* Release code */
time_t start; /* Call start time */
......@@ -245,8 +259,8 @@ typedef struct osp_threadarg {
/* OSP module global settings */
static osp_settings_t osp_globals;
/* OSP module providers */
static osp_provider_t *osp_providers = NULL;
/* OSP module profiles */
static osp_profile_t *osp_profiles = NULL;
/* switch_status_t mod_osp_load(switch_loadable_module_interface_t **module_interface, switch_memory_pool_t *pool) */
SWITCH_MODULE_LOAD_FUNCTION(mod_osp_load);
......@@ -260,27 +274,27 @@ SWITCH_MODULE_DEFINITION(mod_osp, mod_osp_load, mod_osp_shutdown, NULL);
#define osp_adjust_len(_head, _size, _len) { _len = strlen(_head); _head += _len; _size -= _len; }
/*
* Find OSP provider by name
* param name OSP provider name
* param provider OSP provider, NULL is allowed
* Find OSP profile by name
* param name OSP profile name
* param profile OSP profile, NULL is allowed
* return SWITCH_STATUS_SUCCESS Successful, SWITCH_STATUS_FALSE Failed
*/
static switch_status_t osp_find_provider(
static switch_status_t osp_find_profile(
const char *name,
osp_provider_t **provider)
osp_profile_t **profile)
{
osp_provider_t *p;
osp_profile_t *p;
switch_status_t status = SWITCH_STATUS_FALSE;
if (name) {
if (provider) {
*provider = NULL;
if (profile) {
*profile = NULL;
}
for (p = osp_providers; p; p = p->next) {
for (p = osp_profiles; p; p = p->next) {
if (!strcasecmp(p->name, name)) {
if (provider) {
*provider = p;
if (profile) {
*profile = p;
}
status = SWITCH_STATUS_SUCCESS;
break;
......@@ -300,12 +314,12 @@ static switch_status_t osp_load_settings(
switch_memory_pool_t *pool)
{
char *cf = "osp.conf";
switch_xml_t cfg, xml = NULL, param, settings, profile, profiles;
switch_xml_t cfg, xml = NULL, param, settings, xprofile, profiles;
const char *name;
const char *value;
const char *module;
const char *context;
osp_provider_t *provider;
osp_profile_t *profile;
int number;
switch_status_t status = SWITCH_STATUS_SUCCESS;
......@@ -373,14 +387,14 @@ static switch_status_t osp_load_settings(
}
} else if (!strcasecmp(name, "sip")) {
if (!switch_strlen_zero(module)) {
if (!(osp_globals.module[OSPC_DPROT_SIP] = switch_core_strdup(osp_globals.pool, module))) {
if (!(osp_globals.modules[OSPC_DPROT_SIP] = switch_core_strdup(osp_globals.pool, module))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to duplicate SIP module name\n");
status = SWITCH_STATUS_MEMERR;
break;
}
}
if (!switch_strlen_zero(context)) {
if (!(osp_globals.profile[OSPC_DPROT_SIP] = switch_core_strdup(osp_globals.pool, context))) {
if (!(osp_globals.profiles[OSPC_DPROT_SIP] = switch_core_strdup(osp_globals.pool, context))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to duplicate SIP profile name\n");
status = SWITCH_STATUS_MEMERR;
break;
......@@ -388,14 +402,14 @@ static switch_status_t osp_load_settings(
}
} else if (!strcasecmp(name, "h323")) {
if (!switch_strlen_zero(module)) {
if (!(osp_globals.module[OSPC_DPROT_Q931] = switch_core_strdup(osp_globals.pool, module))) {
if (!(osp_globals.modules[OSPC_DPROT_Q931] = switch_core_strdup(osp_globals.pool, module))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to duplicate H.323 module name\n");
status = SWITCH_STATUS_MEMERR;
break;
}
}
if (!switch_strlen_zero(context)) {
if (!(osp_globals.profile[OSPC_DPROT_Q931] = switch_core_strdup(osp_globals.pool, context))) {
if (!(osp_globals.profiles[OSPC_DPROT_Q931] = switch_core_strdup(osp_globals.pool, context))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to duplicate H.323 profile name\n");
status = SWITCH_STATUS_MEMERR;
break;
......@@ -403,14 +417,14 @@ static switch_status_t osp_load_settings(
}
} else if (!strcasecmp(name, "iax")) {
if (!switch_strlen_zero(module)) {
if (!(osp_globals.module[OSPC_DPROT_IAX] = switch_core_strdup(osp_globals.pool, module))) {
if (!(osp_globals.modules[OSPC_DPROT_IAX] = switch_core_strdup(osp_globals.pool, module))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to duplicate IAX module name\n");
status = SWITCH_STATUS_MEMERR;
break;
}
}
if (!switch_strlen_zero(context)) {
if (!(osp_globals.profile[OSPC_DPROT_IAX] = switch_core_strdup(osp_globals.pool, context))) {
if (!(osp_globals.profiles[OSPC_DPROT_IAX] = switch_core_strdup(osp_globals.pool, context))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to duplicate IAX profile name\n");
status = SWITCH_STATUS_MEMERR;
break;
......@@ -418,14 +432,14 @@ static switch_status_t osp_load_settings(
}
} else if (!strcasecmp(name, "skype")) {
if (!switch_strlen_zero(module)) {
if (!(osp_globals.module[OSPC_DPROT_SKYPE] = switch_core_strdup(osp_globals.pool, module))) {
if (!(osp_globals.modules[OSPC_DPROT_SKYPE] = switch_core_strdup(osp_globals.pool, module))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to duplicate Skype module name\n");
status = SWITCH_STATUS_MEMERR;
break;
}
}
if (!switch_strlen_zero(context)) {
if (!(osp_globals.profile[OSPC_DPROT_SKYPE] = switch_core_strdup(osp_globals.pool, context))) {
if (!(osp_globals.profiles[OSPC_DPROT_SKYPE] = switch_core_strdup(osp_globals.pool, context))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to duplicate Skype profile name\n");
status = SWITCH_STATUS_MEMERR;
break;
......@@ -443,122 +457,130 @@ static switch_status_t osp_load_settings(
}
if ((profiles = switch_xml_child(cfg, "profiles"))) {
for (profile = switch_xml_child(profiles, "profile"); profile; profile = profile->next) {
name = switch_xml_attr_soft(profile, "name");
for (xprofile = switch_xml_child(profiles, "profile"); xprofile; xprofile = xprofile->next) {
name = switch_xml_attr_soft(xprofile, "name");
if (switch_strlen_zero(name)) {
name = OSP_DEF_PROFILE;
}
if (osp_find_provider(name, NULL) == SWITCH_STATUS_SUCCESS) {
if (osp_find_profile(name, NULL) == SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Ignored duplicate profile '%s'\n", name);
continue;
}
if (!(provider = switch_core_alloc(osp_globals.pool, sizeof(*provider)))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to alloc provider\n");
if (!(profile = switch_core_alloc(osp_globals.pool, sizeof(*profile)))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to alloc profile\n");
status = SWITCH_STATUS_MEMERR;
break;
}
if (!(provider->name = switch_core_strdup(osp_globals.pool, name))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to duplicate provider name\n");
if (!(profile->name = switch_core_strdup(osp_globals.pool, name))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to duplicate profile name\n");
status = SWITCH_STATUS_MEMERR;
/* "provider" cannot free to pool in FreeSWITCH */
/* "profile" cannot free to pool in FreeSWITCH */
break;
}
/* Provider has been set to 0 by switch_core_alloc */
provider->lifetime = OSP_DEF_LIFETIME;
provider->maxconnect = OSP_DEF_MAXCONN;
provider->persistence = OSP_DEF_PERSIST;
provider->retrydelay = OSP_DEF_RETRYDELAY;
provider->retrylimit = OSP_DEF_RETRYLIMIT;
provider->timeout = OSP_DEF_TIMEOUT;
provider->maxdest = OSP_DEF_MAXDEST;
provider->handle = OSP_INVALID_HANDLE;
for (param = switch_xml_child(profile, "param"); param; param = param->next) {
/* "profile" has been set to 0 by switch_core_alloc */
profile->lifetime = OSP_DEF_LIFETIME;
profile->maxconnect = OSP_DEF_MAXCONN;
profile->persistence = OSP_DEF_PERSIST;
profile->retrydelay = OSP_DEF_RETRYDELAY;
profile->retrylimit = OSP_DEF_RETRYLIMIT;
profile->timeout = OSP_DEF_TIMEOUT;
profile->maxdest = OSP_DEF_MAXDEST;
profile->provider = OSP_INVALID_HANDLE;
for (param = switch_xml_child(xprofile, "param"); param; param = param->next) {
name = switch_xml_attr_soft(param, "name");
value = switch_xml_attr_soft(param, "value");
if (switch_strlen_zero(name) || switch_strlen_zero(value)) {
continue;
}
if (!strcasecmp(name, "service-point-url")) {
if (provider->spnum < OSP_MAX_SP) {
provider->spurls[provider->spnum] = switch_core_strdup(osp_globals.pool, value);
provider->spnum++;
if (profile->spnum < OSP_MAX_SP) {
profile->spurls[profile->spnum] = switch_core_strdup(osp_globals.pool, value);
profile->spnum++;
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Ignored excess service point '%s'\n", value);
}
} else if (!strcasecmp(name, "device-ip")) {
provider->device = switch_core_strdup(osp_globals.pool, value);
profile->device = switch_core_strdup(osp_globals.pool, value);
} else if (!strcasecmp(name, "ssl-lifetime")) {
if (sscanf(value, "%d", &number) == 1) {
provider->lifetime = number;
profile->lifetime = number;
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "ssl-lifetime must be a number\n");
}
} else if (!strcasecmp(name, "http-max-connections")) {
if ((sscanf(value, "%d", &number) == 1) && (number >= OSP_MIN_MAXCONN) && (number <= OSP_MAX_MAXCONN)) {
provider->maxconnect = number;
profile->maxconnect = number;
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
"http-max-connections must be between %d and %d\n", OSP_MIN_MAXCONN, OSP_MAX_MAXCONN);
}
} else if (!strcasecmp(name, "http-persistence")) {
if (sscanf(value, "%d", &number) == 1) {
provider->persistence = number;
profile->persistence = number;
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "http-persistence must be a number\n");
}
} else if (!strcasecmp(name, "http-retry-delay")) {
if ((sscanf(value, "%d", &number) == 1) && (number >= OSP_MIN_RETRYDELAY) && (number <= OSP_MAX_RETRYDELAY)) {
provider->retrydelay = number;
profile->retrydelay = number;
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
"http-retry-delay must be between %d and %d\n", OSP_MIN_RETRYDELAY, OSP_MAX_RETRYDELAY);
}
} else if (!strcasecmp(name, "http-retry-limit")) {
if ((sscanf(value, "%d", &number) == 1) && (number >= OSP_MIN_RETRYLIMIT) && (number <= OSP_MAX_RETRYLIMIT)) {
provider->retrylimit = number;
profile->retrylimit = number;
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
"http-retry-limit must be between %d and %d\n", OSP_MIN_RETRYLIMIT, OSP_MAX_RETRYLIMIT);
}
} else if (!strcasecmp(name, "http-timeout")) {
if ((sscanf(value, "%d", &number) == 1) && (number >= OSP_MIN_TIMEOUT) && (number <= OSP_MAX_TIMEOUT)) {
provider->timeout = number;
profile->timeout = number;
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
"http-timeout must be between %d and %d\n", OSP_MIN_TIMEOUT, OSP_MAX_TIMEOUT);
}
} else if (!strcasecmp(name, "work-mode")) {
if (!strcasecmp(value, "direct")) {
profile->workmode = OSP_MODE_DIRECT;
} else if (!strcasecmp(value, "indirect")) {
profile->workmode = OSP_MODE_INDIRECT;
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unknown work mode '%s'\n", value);
}
} else if (!strcasecmp(name, "service-type")) {
if (!strcasecmp(value, "voice")) {
provider->srvtype = OSP_SRV_VOICE;
profile->srvtype = OSP_SRV_VOICE;
} else if (!strcasecmp(value, "npquery")) {
provider->srvtype = OSP_SRV_NPQUERY;
profile->srvtype = OSP_SRV_NPQUERY;
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unknown service type '%s'\n", value);
}
} else if (!strcasecmp(name, "max-destinations")) {
if ((sscanf(value, "%d", &number) == 1) && (number >= OSP_MIN_MAXDEST) && (number <= OSP_MAX_MAXDEST)) {
provider->maxdest = number;
profile->maxdest = number;
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
"max-destinations must be between %d and %d\n", OSP_MIN_MAXDEST, OSP_MAX_MAXDEST);
}
} else if (!strcasecmp(name, "user-phone")) {
provider->userphone = switch_true(value);
profile->userphone = switch_true(value);
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unknown parameter '%s'\n", name);
}
}
if (!provider->spnum) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Without service point URI in profile '%s'\n", provider->name);
/* "provider" cannot free to pool in FreeSWITCH */
if (!profile->spnum) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Without service point URI in profile '%s'\n", profile->name);
/* "profile" cannot free to pool in FreeSWITCH */
continue;
}
provider->next = osp_providers;
osp_providers = provider;
profile->next = osp_profiles;
osp_profiles = profile;
}
}
......@@ -578,7 +600,7 @@ const char *B64CACert = "MIIBYDCCAQoCAQEwDQYJKoZIhvcNAQEEBQAwOzElMCMGA1UEAxMcb3N
*/
static void osp_init_osptk(void)
{
osp_provider_t *provider;
osp_profile_t *profile;
OSPTPRIVATEKEY privatekey;
unsigned char privatekeydata[OSP_SIZE_KEYSTR];
OSPT_CERT localcert;
......@@ -598,7 +620,7 @@ static void osp_init_osptk(void)
OSPPInit(OSPC_FALSE);
}
for (provider = osp_providers; provider; provider = provider->next) {
for (profile = osp_profiles; profile; profile = profile->next) {
privatekey.PrivateKeyData = privatekeydata;
privatekey.PrivateKeyLength = sizeof(privatekeydata);
......@@ -619,8 +641,8 @@ static void osp_init_osptk(void)
if (error == OSPC_ERR_NO_ERROR) {
error = OSPPProviderNew(
provider->spnum, /* Number of service points */
provider->spurls, /* Service point URLs */
profile->spnum, /* Number of service points */
profile->spurls, /* Service point URLs */
NULL, /* Weights */
OSP_AUDIT_URL, /* Audit URL */
&privatekey, /* Provate key */
......@@ -628,18 +650,18 @@ static void osp_init_osptk(void)
1, /* Number of cacerts */
&pcacert, /* cacerts */
OSP_LOCAL_VALID, /* Validating method */
provider->lifetime, /* SS lifetime */
provider->maxconnect, /* HTTP max connections */
provider->persistence, /* HTTP persistence */
provider->retrydelay, /* HTTP retry delay, in seconds */
provider->retrylimit, /* HTTP retry times */
provider->timeout, /* HTTP timeout */
profile->lifetime, /* SS lifetime */
profile->maxconnect, /* HTTP max connections */
profile->persistence, /* HTTP persistence */
profile->retrydelay, /* HTTP retry delay, in seconds */
profile->retrylimit, /* HTTP retry times */
profile->timeout, /* HTTP timeout */
OSP_CUSTOMER_ID, /* Customer ID */
OSP_DEVICE_ID, /* Device ID */
&provider->handle); /* Provider handle */
&profile->provider); /* Provider handle */
if (error != OSPC_ERR_NO_ERROR) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unable to create provider %s, error '%d'\n", provider->name, error);
provider->handle = OSP_INVALID_HANDLE;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Unable to create provider for profile %s, error '%d'\n", profile->name, error);
profile->provider = OSP_INVALID_HANDLE;
}
}
}
......@@ -698,7 +720,7 @@ SWITCH_STANDARD_API(osp_api_function)
char *argv[2] = { 0 };
char *params = NULL;
char *param = NULL;
osp_provider_t *provider;
osp_profile_t *profile;
char *loglevel;
if (session) {
......@@ -750,45 +772,54 @@ SWITCH_STANDARD_API(osp_api_function)
}
stream->write_function(stream, " log-level: %s\n", loglevel);
stream->write_function(stream, " crypto-hardware: %s\n", osp_globals.hardware ? "enabled" : "disabled");
if (switch_strlen_zero(osp_globals.module[OSPC_DPROT_SIP]) || switch_strlen_zero(osp_globals.profile[OSPC_DPROT_SIP])) {
if (switch_strlen_zero(osp_globals.modules[OSPC_DPROT_SIP]) || switch_strlen_zero(osp_globals.profiles[OSPC_DPROT_SIP])) {
stream->write_function(stream, " sip: unsupported\n");
} else {
stream->write_function(stream, " sip: %s/%s\n",
osp_globals.module[OSPC_DPROT_SIP], osp_globals.profile[OSPC_DPROT_SIP]);
osp_globals.modules[OSPC_DPROT_SIP], osp_globals.profiles[OSPC_DPROT_SIP]);
}
if (switch_strlen_zero(osp_globals.module[OSPC_DPROT_Q931]) || switch_strlen_zero(osp_globals.profile[OSPC_DPROT_Q931])) {
if (switch_strlen_zero(osp_globals.modules[OSPC_DPROT_Q931]) || switch_strlen_zero(osp_globals.profiles[OSPC_DPROT_Q931])) {
stream->write_function(stream, " h323: unsupported\n");
} else {
stream->write_function(stream, " h323: %s/%s\n",
osp_globals.module[OSPC_DPROT_Q931], osp_globals.profile[OSPC_DPROT_Q931]);
osp_globals.modules[OSPC_DPROT_Q931], osp_globals.profiles[OSPC_DPROT_Q931]);
}
if (switch_strlen_zero(osp_globals.module[OSPC_DPROT_IAX]) || switch_strlen_zero(osp_globals.profile[OSPC_DPROT_IAX])) {
if (switch_strlen_zero(osp_globals.modules[OSPC_DPROT_IAX]) || switch_strlen_zero(osp_globals.profiles[OSPC_DPROT_IAX])) {
stream->write_function(stream, " iax: unsupported\n");
} else {
stream->write_function(stream, " iax: %s/%s\n",
osp_globals.module[OSPC_DPROT_IAX], osp_globals.profile[OSPC_DPROT_IAX]);
osp_globals.modules[OSPC_DPROT_IAX], osp_globals.profiles[OSPC_DPROT_IAX]);
}
if (switch_strlen_zero(osp_globals.module[OSPC_DPROT_SKYPE]) || switch_strlen_zero(osp_globals.profile[OSPC_DPROT_SKYPE])) {
if (switch_strlen_zero(osp_globals.modules[OSPC_DPROT_SKYPE]) || switch_strlen_zero(osp_globals.profiles[OSPC_DPROT_SKYPE])) {
stream->write_function(stream, " skype: unsupported\n");
} else {
stream->write_function(stream, " skype: %s/%s\n",
osp_globals.module[OSPC_DPROT_SKYPE], osp_globals.profile[OSPC_DPROT_SKYPE]);
osp_globals.modules[OSPC_DPROT_SKYPE], osp_globals.profiles[OSPC_DPROT_SKYPE]);
}
stream->write_function(stream, " default-protocol: %s\n", osp_get_protocol(osp_globals.protocol));
stream->write_function(stream, "============== OSP Profiles Settings & Status ==============\n");
for (provider = osp_providers; provider; provider = provider->next) {
stream->write_function(stream, "Profile: %s\n", provider->name);
for (i = 0; i < provider->spnum; i++) {
stream->write_function(stream, " service-point-url: %s\n", provider->spurls[i]);
stream->write_function(stream, "============== OSP Profile Settings & Status ==============\n");
for (profile = osp_profiles; profile; profile = profile->next) {
stream->write_function(stream, "Profile: %s\n", profile->name);
for (i = 0; i < profile->spnum; i++) {
stream->write_function(stream, " service-point-url: %s\n", profile->spurls[i]);
}
stream->write_function(stream, " device-ip: %s\n", profile->device);
stream->write_function(stream, " ssl-lifetime: %d\n", profile->lifetime);
stream->write_function(stream, " http-max-connections: %d\n", profile->maxconnect);
stream->write_function(stream, " http-persistence: %d\n", profile->persistence);
stream->write_function(stream, " http-retry-dalay: %d\n", profile->retrydelay);
stream->write_function(stream, " http-retry-limit: %d\n", profile->retrylimit);
stream->write_function(stream, " http-timeout: %d\n", profile->timeout);
switch (profile->workmode) {
case OSP_MODE_DIRECT:
stream->write_function(stream, " work-mode: direct\n");
break;
case OSP_MODE_INDIRECT:
default:
stream->write_function(stream, " work-mode: indirect\n");
break;
}
stream->write_function(stream, " device-ip: %s\n", provider->device);
stream->write_function(stream, " ssl-lifetime: %d\n", provider->lifetime);
stream->write_function(stream, " http-max-connections: %d\n", provider->maxconnect);
stream->write_function(stream, " http-persistence: %d\n", provider->persistence);
stream->write_function(stream, " http-retry-dalay: %d\n", provider->retrydelay);
stream->write_function(stream, " http-retry-limit: %d\n", provider->retrylimit);
stream->write_function(stream, " http-timeout: %d\n", provider->timeout);
switch (provider->srvtype) {
switch (profile->srvtype) {
case OSP_SRV_NPQUERY:
stream->write_function(stream, " service-type: npquery\n");
break;
......@@ -797,9 +828,9 @@ SWITCH_STANDARD_API(osp_api_function)
stream->write_function(stream, " service-type: voice\n");
break;
}
stream->write_function(stream, " max-destinations: %d\n", provider->maxdest);
stream->write_function(stream, " user-phone: %s\n", provider->userphone ? "enabled" : "disabled");
stream->write_function(stream, " status: %s\n", provider->handle != OSP_INVALID_HANDLE ? "enabled" : "disabled");
stream->write_function(stream, " max-destinations: %d\n", profile->maxdest);
stream->write_function(stream, " user-phone: %s\n", profile->userphone ? "enabled" : "disabled");
stream->write_function(stream, " status: %s\n", profile->provider != OSP_INVALID_HANDLE ? "enabled" : "disabled");
}
} else {
stream->write_function(stream, "Invalid Syntax!\n");
......@@ -900,23 +931,37 @@ static void osp_parse_diversion(
/*
* Log AuthReq parameters
* param provider OSP provider
* param profile OSP profile
* param inbound Inbound info
* return
*/
static void osp_log_authreq(
osp_provider_t *provider,
osp_profile_t *profile,
osp_inbound_t *inbound)
{
char *srvtype;
const char *source;
const char *srcdev;
char term[OSP_SIZE_NORSTR];
int total;
if (osp_globals.debug) {
if (provider->srvtype == OSP_SRV_NPQUERY) {
if (profile->workmode == OSP_MODE_INDIRECT) {
source = inbound->srcdev;
if (switch_strlen_zero(inbound->actsrc)) {
srcdev = inbound->srcdev;
} else {
srcdev = inbound->actsrc;
}
} else {
source = profile->device;
srcdev = inbound->srcdev;
}
if (profile->srvtype == OSP_SRV_NPQUERY) {
srvtype = "npquery";
if (switch_strlen_zero(inbound->tohost)) {
switch_copy_string(term, provider->device, sizeof(term));
switch_copy_string(term, source, sizeof(term));
} else {
if (switch_strlen_zero(inbound->toport)) {
switch_copy_string(term, inbound->tohost, sizeof(term));
......@@ -928,10 +973,10 @@ static void osp_log_authreq(
} else {
srvtype = "voice";
term[0] = '\0';
total = provider->maxdest;
total = profile->maxdest;
}
switch_log_printf(SWITCH_CHANNEL_LOG, osp_globals.loglevel,
switch_log_printf(SWITCH_CHANNEL_LOG, osp_globals.loglevel,
"AuthReq: "
"srvtype = '%s' "
"source = '%s' "
......@@ -945,8 +990,8 @@ static void osp_log_authreq(
"cinfo = '%s/%s/%s/%s/%s/%s/%s/%s' "
"maxcount = '%d'\n",
srvtype,
provider->device,
inbound->srcdev,
source,
srcdev,
inbound->calling,
inbound->called,
inbound->nprn, inbound->npcic, inbound->npdi,
......@@ -980,6 +1025,7 @@ static void osp_get_inbound(
memset(inbound, 0, sizeof(*inbound));
caller = switch_channel_get_caller_profile(channel);
inbound->actsrc = switch_channel_get_variable(channel, OSP_VAR_SRCDEV);
inbound->srcdev = caller->network_addr;
inbound->calling = caller->caller_id_number;
osp_parse_userinfo(caller->destination_number, NULL, 0, inbound);
......@@ -1000,6 +1046,8 @@ static void osp_get_inbound(
switch_snprintf(name, sizeof(name), "%s%d", OSP_VAR_CUSTOMINFO, i + 1);
inbound->cinfo[i] = switch_channel_get_variable(channel, name);
}
inbound->outproxy = switch_channel_get_variable(channel, OSP_VAR_OUTPROXY);
}
/*
......@@ -1090,12 +1138,12 @@ static void osp_convert_outin(
/*
* Check destination
* param handle Transaction handle
* param transaction Transaction handle
* param dest Destination
* return SWITCH_STATUS_SUCCESS Successful, SWITCH_STATUS_FALSE Failed
*/
static switch_status_t osp_check_destination(
OSPTTRANHANDLE handle,
OSPTTRANHANDLE transaction,
osp_destination_t *dest)
{
OSPE_DEST_OSPENABLED enabled;
......@@ -1104,19 +1152,19 @@ static switch_status_t osp_check_destination(
int error;
switch_status_t status = SWITCH_STATUS_FALSE;
if ((handle == OSP_INVALID_HANDLE) || !dest) {
if ((transaction == OSP_INVALID_HANDLE) || !dest) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid parameters\n");
return status;
}
dest->supported = SWITCH_FALSE;
if ((error = OSPPTransactionIsDestOSPEnabled(handle, &enabled)) != OSPC_ERR_NO_ERROR) {
if ((error = OSPPTransactionIsDestOSPEnabled(transaction, &enabled)) != OSPC_ERR_NO_ERROR) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to get destination OSP version, error '%d'\n", error);
return status;
}
if ((error = OSPPTransactionGetDestProtocol(handle, &protocol)) != OSPC_ERR_NO_ERROR) {
if ((error = OSPPTransactionGetDestProtocol(transaction, &protocol)) != OSPC_ERR_NO_ERROR) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to get destination protocol, error '%d'\n", error);
return status;
}
......@@ -1130,7 +1178,7 @@ static switch_status_t osp_check_destination(
case OSPC_DPROT_IAX:
case OSPC_DPROT_SKYPE:
dest->protocol = protocol;
if (!switch_strlen_zero(osp_globals.module[protocol]) && !switch_strlen_zero(osp_globals.profile[protocol])) {
if (!switch_strlen_zero(osp_globals.modules[protocol]) && !switch_strlen_zero(osp_globals.profiles[protocol])) {
dest->supported = SWITCH_TRUE;
status = SWITCH_STATUS_SUCCESS;
}
......@@ -1146,11 +1194,12 @@ static switch_status_t osp_check_destination(
break;
}
if ((error = OSPPTransactionGetDestinationNetworkId(handle, sizeof(dest->destnid), dest->destnid)) != OSPC_ERR_NO_ERROR) {
if ((error = OSPPTransactionGetDestinationNetworkId(transaction, sizeof(dest->destnid), dest->destnid)) != OSPC_ERR_NO_ERROR) {
dest->destnid[0] = '\0';
}
error = OSPPTransactionGetNumberPortabilityParameters(handle,
error = OSPPTransactionGetNumberPortabilityParameters(
transaction,
sizeof(dest->nprn),
dest->nprn,
sizeof(dest->npcic),
......@@ -1163,7 +1212,7 @@ static switch_status_t osp_check_destination(
}
for (type = OSPC_OPNAME_START; type < OSPC_OPNAME_NUMBER; type++) {
if ((error = OSPPTransactionGetOperatorName(handle, type, sizeof(dest->opname[type]), dest->opname[type])) != OSPC_ERR_NO_ERROR) {
if ((error = OSPPTransactionGetOperatorName(transaction, type, sizeof(dest->opname[type]), dest->opname[type])) != OSPC_ERR_NO_ERROR) {
dest->opname[type][0] = '\0';
}
}
......@@ -1183,7 +1232,7 @@ static void osp_log_authrsp(
if (osp_globals.debug) {
for (i = 0; i < results->numdest; i++) {
switch_log_printf(SWITCH_CHANNEL_LOG, osp_globals.loglevel,
switch_log_printf(SWITCH_CHANNEL_LOG, osp_globals.loglevel,
"AuthRsp: "
"transid = '%"PRIu64"' "
"destcount = '%d' "
......@@ -1211,21 +1260,23 @@ static void osp_log_authrsp(
/*
* Do auth/routing request
* param provider OSP provider
* param handle Transaction handle
* param profile OSP profile
* param transaction Transaction handle
* param source Call originator info
* param results Routing info
* return SWITCH_STATUS_SUCCESS Successful, SWITCH_STATUS_FALSE Failed
*/
static switch_status_t osp_do_request(
osp_provider_t *provider,
OSPTTRANHANDLE handle,
osp_profile_t *profile,
OSPTTRANHANDLE transaction,
osp_inbound_t *inbound,
osp_results_t *results)
{
OSPTTRANS *context;
osp_destination_t *dest;
char tmp[OSP_SIZE_NORSTR];
const char *source;
const char *srcdev;
char src[OSP_SIZE_NORSTR];
char dev[OSP_SIZE_NORSTR];
char term[OSP_SIZE_NORSTR];
......@@ -1234,25 +1285,37 @@ static switch_status_t osp_do_request(
int count, error;
switch_status_t status = SWITCH_STATUS_FALSE;
osp_log_authreq(provider, inbound);
osp_log_authreq(profile, inbound);
OSPPTransactionSetNumberPortability(handle, inbound->nprn, inbound->npcic, inbound->npdi);
OSPPTransactionSetNumberPortability(transaction, inbound->nprn, inbound->npcic, inbound->npdi);
osp_convert_inout(inbound->divhost, tmp, sizeof(tmp));
OSPPTransactionSetDiversion(handle, inbound->divuser, tmp);
OSPPTransactionSetDiversion(transaction, inbound->divuser, tmp);
OSPPTransactionSetNetworkIds(handle, inbound->srcnid, NULL);
OSPPTransactionSetNetworkIds(transaction, inbound->srcnid, NULL);
for (count = 0; count < OSP_MAX_CINFO; count++) {
if (!switch_strlen_zero(inbound->cinfo[count])) {
OSPPTransactionSetCustomInfo(handle, count, inbound->cinfo[count]);
OSPPTransactionSetCustomInfo(transaction, count, inbound->cinfo[count]);
}
}
osp_convert_inout(provider->device, src, sizeof(src));
osp_convert_inout(inbound->srcdev, dev, sizeof(dev));
if (provider->srvtype == OSP_SRV_NPQUERY) {
OSPPTransactionSetServiceType(handle, OSPC_SERVICE_NPQUERY);
if (profile->workmode == OSP_MODE_INDIRECT) {
source = inbound->srcdev;
if (switch_strlen_zero(inbound->actsrc)) {
srcdev = inbound->srcdev;
} else {
srcdev = inbound->actsrc;
}
} else {
source = profile->device;
srcdev = inbound->srcdev;
}
osp_convert_inout(source, src, sizeof(src));
osp_convert_inout(srcdev, dev, sizeof(dev));
if (profile->srvtype == OSP_SRV_NPQUERY) {
OSPPTransactionSetServiceType(transaction, OSPC_SERVICE_NPQUERY);
if (switch_strlen_zero(inbound->tohost)) {
switch_copy_string(term, src, sizeof(term));
......@@ -1268,13 +1331,13 @@ static switch_status_t osp_do_request(
total = 1;
} else {
OSPPTransactionSetServiceType(handle, OSPC_SERVICE_VOICE);
OSPPTransactionSetServiceType(transaction, OSPC_SERVICE_VOICE);
total = provider->maxdest;
total = profile->maxdest;
}
error = OSPPTransactionRequestAuthorisation(
handle, /* Transaction handle */
transaction, /* Transaction handle */
src, /* Source */
dev, /* Source device */
inbound->calling, /* Calling */
......@@ -1298,7 +1361,7 @@ static switch_status_t osp_do_request(
return status;
}
context = OSPPTransactionGetContext(handle, &error);
context = OSPPTransactionGetContext(transaction, &error);
if (error == OSPC_ERR_NO_ERROR) {
results->transid = context->TransactionID;
} else {
......@@ -1306,13 +1369,14 @@ static switch_status_t osp_do_request(
}
switch_copy_string(results->called, inbound->called, sizeof(results->called));
results->srcdev = srcdev;
results->srcnid = inbound->srcnid;
results->start = inbound->start;
count = 0;
dest = &results->dests[count];
error = OSPPTransactionGetFirstDestination(
handle, /* Transaction handle */
transaction, /* Transaction handle */
0, /* Timestamp buffer size */
NULL, /* Valid after */
NULL, /* Valid until */
......@@ -1335,13 +1399,14 @@ static switch_status_t osp_do_request(
}
osp_convert_outin(term, dest->dest, sizeof(dest->dest));
osp_check_destination(handle, dest);
dest->userphone = provider->userphone;
osp_check_destination(transaction, dest);
dest->userphone = profile->userphone;
dest->outproxy = inbound->outproxy;
for (count = 1; count < total; count++) {
dest = &results->dests[count];
error = OSPPTransactionGetNextDestination(
handle, /* Transsaction handle */
transaction, /* Transsaction handle */
OSPC_FAIL_NONE, /* Failure reason */
0, /* Timestamp buffer size */
NULL, /* Valid after */
......@@ -1361,8 +1426,9 @@ static switch_status_t osp_do_request(
NULL); /* Token buffer */
if (error == OSPC_ERR_NO_ERROR) {
osp_convert_outin(term, dest->dest, sizeof(dest->dest));
osp_check_destination(handle, dest);
dest->userphone = provider->userphone;
osp_check_destination(transaction, dest);
dest->userphone = profile->userphone;
dest->outproxy = inbound->outproxy;
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to get destination, error '%d'\n", error);
break;
......@@ -1380,43 +1446,43 @@ static switch_status_t osp_do_request(
/*
* Request auth/routing info
* param channel Originator channel
* param profile Provider name
* param profile Profile name
* param results Routing info
* return SWITCH_STATUS_SUCCESS Successful, SWITCH_STATUS_FALSE Failed
*/
static switch_status_t osp_request_routing(
switch_channel_t *channel,
const char *profile,
const char *profilename,
osp_results_t *results)
{
osp_provider_t *provider;
OSPTTRANHANDLE handle;
osp_profile_t *profile;
OSPTTRANHANDLE transaction;
osp_inbound_t inbound;
int error;
switch_status_t status = SWITCH_STATUS_FALSE;
if (osp_find_provider(profile, &provider) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to find provider '%s'\n", profile);
if (osp_find_profile(profilename, &profile) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to find profile '%s'\n", profilename);
return status;
}
if (provider->handle == OSP_INVALID_HANDLE) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Disabled provider '%s'\n", profile);
if (profile->provider == OSP_INVALID_HANDLE) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Disabled profile '%s'\n", profilename);
return status;
}
results->profile = profile;
results->profile = profilename;
if ((error = OSPPTransactionNew(provider->handle, &handle)) != OSPC_ERR_NO_ERROR) {
if ((error = OSPPTransactionNew(profile->provider, &transaction)) != OSPC_ERR_NO_ERROR) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to create transaction handle, error '%d'\n", error);
return status;
}
osp_get_inbound(channel, &inbound);
status = osp_do_request(provider, handle, &inbound, results);
status = osp_do_request(profile, transaction, &inbound, results);
OSPPTransactionDelete(handle);
OSPPTransactionDelete(transaction);
return status;
}
......@@ -1438,10 +1504,11 @@ static void osp_build_allparam(
if (results && head && size) {
switch_snprintf(head, size,
"{%s=%s,%s=%"PRIu64",%s=%"PRId64"",
"{%s=%s,%s=%"PRIu64",%s=%"PRId64",%s=%s",
OSP_VAR_PROFILE, results->profile,
OSP_VAR_TRANSID, results->transid,
OSP_VAR_START, results->start);
OSP_VAR_START, results->start,
OSP_VAR_SRCDEV, results->srcdev);
osp_adjust_len(head, size, len);
if (!switch_strlen_zero(results->srcnid)) {
......@@ -1507,9 +1574,9 @@ static void osp_build_endpoint(
if (head && size) {
switch (dest->protocol) {
case OSPC_DPROT_SIP:
switch_snprintf(head, size, "%s/%s/%s", osp_globals.module[OSPC_DPROT_SIP], osp_globals.profile[OSPC_DPROT_SIP], dest->called);
switch_snprintf(head, size, "%s/%s/%s", osp_globals.modules[OSPC_DPROT_SIP], osp_globals.profiles[OSPC_DPROT_SIP], dest->called);
osp_adjust_len(head, size, len);
if (!switch_strlen_zero_buf(dest->nprn)) {
switch_snprintf(head, size, ";rn=%s", dest->nprn);
osp_adjust_len(head, size, len);
......@@ -1530,17 +1597,22 @@ static void osp_build_endpoint(
switch_snprintf(head, size, ";user=phone");
osp_adjust_len(head, size, len);
}
if (dest->outproxy) {
switch_snprintf(head, size, ";fs_path=sip:%s", dest->outproxy);
osp_adjust_len(head, size, len);
}
break;
case OSPC_DPROT_Q931:
switch_snprintf(head, size, "%s/%s/%s@%s", osp_globals.module[OSPC_DPROT_Q931], osp_globals.profile[OSPC_DPROT_Q931], dest->called, dest->dest);
switch_snprintf(head, size, "%s/%s/%s@%s", osp_globals.modules[OSPC_DPROT_Q931], osp_globals.profiles[OSPC_DPROT_Q931], dest->called, dest->dest);
osp_adjust_len(head, size, len);
break;
case OSPC_DPROT_IAX:
switch_snprintf(head, size, "%s/%s/%s/%s", osp_globals.module[OSPC_DPROT_Q931], osp_globals.profile[OSPC_DPROT_Q931], dest->dest, dest->called);
switch_snprintf(head, size, "%s/%s/%s/%s", osp_globals.modules[OSPC_DPROT_Q931], osp_globals.profiles[OSPC_DPROT_Q931], dest->dest, dest->called);
osp_adjust_len(head, size, len);
break;
case OSPC_DPROT_SKYPE:
switch_snprintf(head, size, "%s/%s/%s", osp_globals.module[OSPC_DPROT_Q931], osp_globals.profile[OSPC_DPROT_Q931], dest->called);
switch_snprintf(head, size, "%s/%s/%s", osp_globals.modules[OSPC_DPROT_Q931], osp_globals.profiles[OSPC_DPROT_Q931], dest->called);
osp_adjust_len(head, size, len);
break;
default:
......@@ -1680,6 +1752,8 @@ static void osp_add_application(
char name[OSP_SIZE_NORSTR];
char value[OSP_SIZE_ROUSTR];
int i, count;
switch_event_header_t *hi;
char *var;
if ((*extension = switch_caller_extension_new(session, results->called, results->called)) == 0) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to create extension\n");
......@@ -1688,6 +1762,17 @@ static void osp_add_application(
switch_channel_set_variable(channel, SWITCH_HANGUP_AFTER_BRIDGE_VARIABLE, "true");
/* Cleanup OSP varibales in originator */
if ((hi = switch_channel_variable_first(channel))) {
for (; hi; hi = hi->next) {
var = hi->name;
if (var && !strncmp(var, "osp_", 4)) {
switch_channel_set_variable(channel, var, NULL);
}
}
switch_channel_variable_last(channel);
}
osp_build_allparam(results, allparam, sizeof(allparam));
for (count = 0, i = 0; i < results->numdest; i++) {
......@@ -1766,13 +1851,16 @@ static switch_status_t osp_get_ospcookie(
cookie->start = 0;
}
cookie->srcdev = switch_channel_get_variable(channel, OSP_VAR_SRCDEV);
if (!(strvar = switch_channel_get_variable(channel, OSP_VAR_DESTCOUNT)) || (sscanf(strvar, "%d", &cookie->destcount) != 1)) {
cookie->destcount = 0;
}
cookie->dest = switch_channel_get_variable(channel, OSP_VAR_DESTIP);
cookie->srcnid = switch_channel_get_variable(channel, OSP_VAR_SRCNID);
cookie->destnid = switch_channel_get_variable(channel, OSP_VAR_DESTNID);
return SWITCH_STATUS_SUCCESS;
......@@ -1867,26 +1955,26 @@ static OSPTTHREADRETURN osp_report_thread(
info = (osp_threadarg_t *)threadarg;
OSPPTransactionRecordFailure(info->handle, info->cause);
OSPPTransactionRecordFailure(info->transaction, info->cause);
for (i = 0; i < 3; i++) {
error = OSPPTransactionReportUsage(
info->handle, /* Transaction handle */
info->duration, /* Call duration */
info->start, /* Call start time */
info->end, /* Call end time */
info->alert, /* Call alert time */
info->connect, /* Call connect time */
info->pdd != 0, /* Post dial delay present */
info->pdd, /* Post dial delay */
info->release, /* Release source */
NULL, /* Conference ID */
-1, /* Packets not received by peer */
-1, /* Fraction of packets not received by peer */
-1, /* Packets not received that were expected */
-1, /* Fraction of packets expected but not received */
NULL, /* Log buffer size */
NULL); /* Log buffer */
info->transaction, /* Transaction handle */
info->duration, /* Call duration */
info->start, /* Call start time */
info->end, /* Call end time */
info->alert, /* Call alert time */
info->connect, /* Call connect time */
info->pdd != 0, /* Post dial delay present */
info->pdd, /* Post dial delay */
info->release, /* Release source */
NULL, /* Conference ID */
-1, /* Packets not received by peer */
-1, /* Fraction of packets not received by peer */
-1, /* Packets not received that were expected */
-1, /* Fraction of packets expected but not received */
NULL, /* Log buffer size */
NULL); /* Log buffer */
if (error != OSPC_ERR_NO_ERROR) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,
"Failed to report usage for '%"PRIu64"' attempt '%d'\n",
......@@ -1897,7 +1985,7 @@ static OSPTTHREADRETURN osp_report_thread(
}
}
OSPPTransactionDelete(info->handle);
OSPPTransactionDelete(info->transaction);
switch_safe_free(info);
......@@ -1914,31 +2002,38 @@ static switch_status_t osp_report_usage(
osp_cookie_t *cookie,
osp_usage_t *usage)
{
osp_provider_t *provider;
OSPTTRANHANDLE handle;
osp_profile_t *profile;
const char *source;
OSPTTRANHANDLE transaction;
osp_threadarg_t *info;
OSPTTHREADID threadid;
OSPTTHRATTR threadattr;
int error;
switch_status_t status = SWITCH_STATUS_FALSE;
if (osp_find_provider(cookie->profile, &provider) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to find provider '%s'\n", cookie->profile);
if (osp_find_profile(cookie->profile, &profile) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to find profile '%s'\n", cookie->profile);
return status;
}
if ((error = OSPPTransactionNew(provider->handle, &handle)) != OSPC_ERR_NO_ERROR) {
if ((error = OSPPTransactionNew(profile->provider, &transaction)) != OSPC_ERR_NO_ERROR) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to create transaction handle, error '%d'\n", error);
return status;
}
if (profile->workmode == OSP_MODE_INDIRECT) {
source = usage->srcdev;
} else {
source = profile->device;
}
error = OSPPTransactionBuildUsageFromScratch(
handle, /* Transaction handle */
transaction, /* Transaction handle */
cookie->transid, /* Transaction ID */
OSPC_ROLE_SOURCE, /* CDR type, source */
provider->device, /* Source */
source, /* Source */
cookie->dest, /* Destination */
usage->srcdev, /* Source device */
cookie->srcdev, /* Source device */
OSP_DEF_STRING, /* Destination device */
usage->calling, /* Calling */
OSPC_NFORMAT_E164, /* Calling format */
......@@ -1950,44 +2045,44 @@ static switch_status_t osp_report_usage(
NULL, /* Log buffer size */
NULL); /* Log buffer */
if (error != OSPC_ERR_NO_ERROR) {
OSPPTransactionDelete(handle);
OSPPTransactionDelete(transaction);
return status;
}
status = SWITCH_STATUS_SUCCESS;
OSPPTransactionSetDestinationCount(handle, cookie->destcount);
OSPPTransactionSetDestinationCount(transaction, cookie->destcount);
if (!switch_strlen_zero(cookie->srcnid)) {
OSPPTransactionSetSrcNetworkId(handle, cookie->srcnid);
OSPPTransactionSetSrcNetworkId(transaction, cookie->srcnid);
}
if (!switch_strlen_zero(cookie->destnid)) {
OSPPTransactionSetDestNetworkId(handle, cookie->destnid);
OSPPTransactionSetDestNetworkId(transaction, cookie->destnid);
}
if (!switch_strlen_zero(usage->fcodec)) {
OSPPTransactionSetForwardCodec(handle, usage->fcodec);
OSPPTransactionSetForwardCodec(transaction, usage->fcodec);
}
if (!switch_strlen_zero(usage->rcodec)) {
OSPPTransactionSetReverseCodec(handle, usage->rcodec);
OSPPTransactionSetReverseCodec(transaction, usage->rcodec);
}
if (usage->rtpdownoctets != OSP_DEF_STATS) {
OSPPTransactionSetOctets(handle, OSPC_SMETRIC_RTP, OSPC_SFLOW_DOWNSTREAM, usage->rtpdownoctets);
OSPPTransactionSetOctets(transaction, OSPC_SMETRIC_RTP, OSPC_SFLOW_DOWNSTREAM, usage->rtpdownoctets);
}
if (usage->rtpupoctets != OSP_DEF_STATS) {
OSPPTransactionSetOctets(handle, OSPC_SMETRIC_RTP, OSPC_SFLOW_UPSTREAM, usage->rtpupoctets);
OSPPTransactionSetOctets(transaction, OSPC_SMETRIC_RTP, OSPC_SFLOW_UPSTREAM, usage->rtpupoctets);
}
if (usage->rtpdownpackets != OSP_DEF_STATS) {
OSPPTransactionSetPackets(handle, OSPC_SMETRIC_RTP, OSPC_SFLOW_DOWNSTREAM, usage->rtpdownpackets);
OSPPTransactionSetPackets(transaction, OSPC_SMETRIC_RTP, OSPC_SFLOW_DOWNSTREAM, usage->rtpdownpackets);
}
if (usage->rtpuppackets != OSP_DEF_STATS) {
OSPPTransactionSetPackets(handle, OSPC_SMETRIC_RTP, OSPC_SFLOW_UPSTREAM, usage->rtpuppackets);
OSPPTransactionSetPackets(transaction, OSPC_SMETRIC_RTP, OSPC_SFLOW_UPSTREAM, usage->rtpuppackets);
}
info = (osp_threadarg_t *)malloc(sizeof(osp_threadarg_t));
info->handle = handle;
info->transaction = transaction;
info->transid = cookie->transid;
info->cause = usage->cause;
info->start = cookie->start / 1000000;
......@@ -2003,7 +2098,7 @@ static switch_status_t osp_report_usage(
OSPM_CREATE_THREAD(threadid, &threadattr, osp_report_thread, info, error);
OSPM_THRATTR_DESTROY(threadattr);
/* handle and info will be released by osp_report_thread */
/* transaction and info will be released by osp_report_thread */
return status;
}
......@@ -2044,7 +2139,7 @@ static void osp_log_usageind(
usage->callid,
usage->calling,
usage->called,
usage->srcdev,
cookie->srcdev,
cookie->dest,
osp_filter_null(cookie->srcnid), osp_filter_null(cookie->destnid),
osp_get_protocol(usage->protocol),
......@@ -2159,11 +2254,11 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_osp_load)
*/
static void osp_cleanup_osptk(void)
{
osp_provider_t *provider;
osp_profile_t *profile;
for (provider = osp_providers; provider; provider = provider->next) {
OSPPProviderDelete(provider->handle, 0);
provider->handle = OSP_INVALID_HANDLE;
for (profile = osp_profiles; profile; profile = profile->next) {
OSPPProviderDelete(profile->provider, 0);
profile->provider = OSP_INVALID_HANDLE;
}
OSPPCleanup();
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论