diff options
author | oej <oej@f38db490-d61c-443f-a65b-d21fe96a405b> | 2006-04-07 19:11:22 +0000 |
---|---|---|
committer | oej <oej@f38db490-d61c-443f-a65b-d21fe96a405b> | 2006-04-07 19:11:22 +0000 |
commit | 3c9910c57ea93ad5c743ee7d4384f74df5f462f1 (patch) | |
tree | 9fcb07813c761c6698388573346bd546999bfbe0 /apps/app_osplookup.c | |
parent | b104ac7d191ff501f7a5e095873a85ad0b36c290 (diff) |
Issue #6899 - remove OSP support code from chan_sip.c and app_dial.c
- implement all functions through internal APIs in res_osp.c and app_osplookup.c
(homesick)
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@18369 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'apps/app_osplookup.c')
-rw-r--r-- | apps/app_osplookup.c | 627 |
1 files changed, 453 insertions, 174 deletions
diff --git a/apps/app_osplookup.c b/apps/app_osplookup.c index 266c66dda..374564aa8 100644 --- a/apps/app_osplookup.c +++ b/apps/app_osplookup.c @@ -16,9 +16,9 @@ * at the top of the source tree. */ -/*! \file - * - * \brief Open Settlement Protocol Lookup +/*! + * \file + * \brief Open Settlement Protocol Applications * * \author Mark Spencer <markster@digium.com> * @@ -49,44 +49,55 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") #include "asterisk/app.h" #include "asterisk/options.h" -static char *tdesc = "OSP Lookup"; - -static char *app = "OSPLookup"; -static char *app2 = "OSPNext"; -static char *app3 = "OSPFinish"; - -static char *synopsis = "Lookup number in OSP"; -static char *synopsis2 = "Lookup next OSP entry"; -static char *synopsis3 = "Record OSP entry"; +static char *app1= "OSPAuth"; +static char *synopsis1 = "OSP authentication"; +static char *descrip1 = +" OSPAuth([provider[|options]]): Authenticate a SIP INVITE by OSP and sets\n" +"the variables:\n" +" ${OSPINHANDLE}: The in_bound call transaction handle\n" +" ${OSPINTIMELIMIT}: The in_bound call duration limit in seconds\n" +"\n" +"The option string may contain the following character:\n" +" 'j' -- jump to n+101 priority if the authentication was NOT successful\n" +"This application sets the following channel variable upon completion:\n" +" OSPAUTHSTATUS The status of the OSP Auth attempt as a text string, one of\n" +" SUCCESS | FAILED | ERROR\n"; -static char *descrip = +static char *app2= "OSPLookup"; +static char *synopsis2 = "Lookup destination by OSP"; +static char *descrip2 = " OSPLookup(exten[|provider[|options]]): Looks up an extension via OSP and sets\n" "the variables, where 'n' is the number of the result beginning with 1:\n" -" ${OSPTECH}: The technology to use for the call\n" -" ${OSPDEST}: The destination to use for the call\n" -" ${OSPTOKEN}: The actual OSP token as a string\n" -" ${OSPHANDLE}: The OSP Handle for anything remaining\n" -" ${OSPRESULTS}: The number of OSP results total remaining\n" +" ${OSPOUTHANDLE}: The OSP Handle for anything remaining\n" +" ${OSPTECH}: The technology to use for the call\n" +" ${OSPDEST}: The destination to use for the call\n" +" ${OSPCALLING}: The calling number to use for the call\n" +" ${OSPOUTTOKEN}: The actual OSP token as a string\n" +" ${OSPOUTTIMELIMIT}: The out_bound call duration limit in seconds\n" +" ${OSPRESULTS}: The number of OSP results total remaining\n" "\n" "The option string may contain the following character:\n" " 'j' -- jump to n+101 priority if the lookup was NOT successful\n" "This application sets the following channel variable upon completion:\n" " OSPLOOKUPSTATUS The status of the OSP Lookup attempt as a text string, one of\n" -" SUCCESS | FAILED \n"; - +" SUCCESS | FAILED | ERROR\n"; -static char *descrip2 = -" OSPNext(cause[|options]): Looks up the next OSP Destination for ${OSPHANDLE}\n" +static char *app3 = "OSPNext"; +static char *synopsis3 = "Lookup next destination by OSP"; +static char *descrip3 = +" OSPNext(cause[|options]): Looks up the next OSP Destination for ${OSPOUTHANDLE}\n" "See OSPLookup for more information\n" "\n" "The option string may contain the following character:\n" " 'j' -- jump to n+101 priority if the lookup was NOT successful\n" "This application sets the following channel variable upon completion:\n" " OSPNEXTSTATUS The status of the OSP Next attempt as a text string, one of\n" -" SUCCESS | FAILED \n"; +" SUCCESS | FAILED |ERROR\n"; -static char *descrip3 = -" OSPFinish(status[|options]): Records call state for ${OSPHANDLE}, according to\n" +static char *app4 = "OSPFinish"; +static char *synopsis4 = "Record OSP entry"; +static char *descrip4 = +" OSPFinish([status[|options]]): Records call state for ${OSPINHANDLE}, according to\n" "status, which should be one of BUSY, CONGESTION, ANSWER, NOANSWER, or CHANUNAVAIL\n" "or coincidentally, just what the Dial application stores in its ${DIALSTATUS}.\n" "\n" @@ -94,278 +105,546 @@ static char *descrip3 = " 'j' -- jump to n+101 priority if the finish attempt was NOT successful\n" "This application sets the following channel variable upon completion:\n" " OSPFINISHSTATUS The status of the OSP Finish attempt as a text string, one of\n" -" SUCCESS | FAILED \n"; +" SUCCESS | FAILED |ERROR \n"; LOCAL_USER_DECL; -static int str2cause(char *cause) +static int ospauth_exec(struct ast_channel *chan, void *data) { - if (!strcasecmp(cause, "BUSY")) - return AST_CAUSE_BUSY; - if (!strcasecmp(cause, "CONGESTION")) - return AST_CAUSE_CONGESTION; - if (!strcasecmp(cause, "ANSWER")) - return AST_CAUSE_NORMAL; - if (!strcasecmp(cause, "CANCEL")) - return AST_CAUSE_NORMAL; - if (!strcasecmp(cause, "NOANSWER")) - return AST_CAUSE_NOANSWER; - if (!strcasecmp(cause, "NOCHANAVAIL")) - return AST_CAUSE_CONGESTION; - ast_log(LOG_WARNING, "Unknown cause '%s', using NORMAL\n", cause); - return AST_CAUSE_NORMAL; + int res = 0; + struct localuser* u; + char* provider = OSP_DEF_PROVIDER; + int priority_jump = 0; + struct varshead* headp; + struct ast_var_t* current; + const char* source = ""; + const char* token = ""; + int handle; + unsigned int timelimit; + char* tmp; + char buffer[OSP_INTSTR_SIZE]; + char* status; + + AST_DECLARE_APP_ARGS(args, + AST_APP_ARG(provider); + AST_APP_ARG(options); + ); + + LOCAL_USER_ADD(u); + + if (!(tmp = ast_strdupa(data))) { + ast_log(LOG_ERROR, "Out of memory\n"); + LOCAL_USER_REMOVE(u); + return(-1); + } + + AST_STANDARD_APP_ARGS(args, tmp); + + if (!ast_strlen_zero(args.provider)) { + provider = args.provider; + } + ast_log(LOG_DEBUG, "OSPAuth: provider '%s'\n", provider); + + if (args.options) { + if (strchr(args.options, 'j')) { + priority_jump = 1; + } + } + ast_log(LOG_DEBUG, "OSPAuth: priority jump '%d'\n", priority_jump); + + headp = &chan->varshead; + AST_LIST_TRAVERSE(headp, current, entries) { + if (!strcasecmp(ast_var_name(current), "OSPPEERIP")) { + source = ast_var_value(current); + } else if (!strcasecmp(ast_var_name(current), "OSPINTOKEN")) { + token = ast_var_value(current); + } + } + ast_log(LOG_DEBUG, "OSPAuth: source '%s'\n", source); + ast_log(LOG_DEBUG, "OSPAuth: token size '%d'\n", strlen(token)); + + res = ast_osp_auth(provider, &handle, source, chan->cid.cid_num, chan->exten, token, &timelimit); + if (res > 0) { + status = OSP_APP_SUCCESS; + } else { + timelimit = OSP_DEF_TIMELIMIT; + if (!res) { + status = OSP_APP_FAILED; + } else { + handle = OSP_INVALID_HANDLE; + status = OSP_APP_ERROR; + } + } + + snprintf(buffer, sizeof(buffer), "%d", handle); + pbx_builtin_setvar_helper(chan, "OSPINHANDLE", buffer); + ast_log(LOG_DEBUG, "OSPAuth: OSPINHANDLE '%s'\n", buffer); + snprintf(buffer, sizeof(buffer), "%d", timelimit); + pbx_builtin_setvar_helper(chan, "OSPINTIMELIMIT", buffer); + ast_log(LOG_DEBUG, "OSPAuth: OSPINTIMELIMIT '%s'\n", buffer); + pbx_builtin_setvar_helper(chan, "OSPAUTHSTATUS", status); + ast_log(LOG_DEBUG, "OSPAuth: %s\n", status); + + if(!res) { + if (priority_jump || ast_opt_priority_jumping) { + ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101); + } else { + res = -1; + } + } else if (res > 0) { + res = 0; + } + + LOCAL_USER_REMOVE(u); + + return(res); } static int osplookup_exec(struct ast_channel *chan, void *data) { - int res=0; - struct localuser *u; - char *temp; - struct ast_osp_result result; + int res = 0; + struct localuser* u; + char* provider = OSP_DEF_PROVIDER; int priority_jump = 0; + struct varshead* headp; + struct ast_var_t* current; + const char* srcdev = ""; + char* tmp; + char buffer[OSP_TOKSTR_SIZE]; + struct ast_osp_result result; + char* status; + AST_DECLARE_APP_ARGS(args, - AST_APP_ARG(extension); + AST_APP_ARG(exten); AST_APP_ARG(provider); AST_APP_ARG(options); ); if (ast_strlen_zero(data)) { - ast_log(LOG_WARNING, "OSPLookup requires an argument OSPLookup(exten[|provider[|options]])\n"); - return -1; + ast_log(LOG_WARNING, "OSPLookup: Arg required, OSPLookup(exten[|provider[|options]])\n"); + return(-1); } LOCAL_USER_ADD(u); - if (!(temp = ast_strdupa(data))) { + if (!(tmp = ast_strdupa(data))) { + ast_log(LOG_ERROR, "Out of memory\n"); LOCAL_USER_REMOVE(u); - return -1; + return(-1); } - AST_STANDARD_APP_ARGS(args, temp); + AST_STANDARD_APP_ARGS(args, tmp); + + ast_log(LOG_DEBUG, "OSPLookup: exten '%s'\n", args.exten); + + if (!ast_strlen_zero(args.provider)) { + provider = args.provider; + } + ast_log(LOG_DEBUG, "OSPlookup: provider '%s'\n", provider); if (args.options) { - if (strchr(args.options, 'j')) + if (strchr(args.options, 'j')) { priority_jump = 1; + } } + ast_log(LOG_DEBUG, "OSPLookup: priority jump '%d'\n", priority_jump); + + result.inhandle = OSP_INVALID_HANDLE; + + headp = &chan->varshead; + AST_LIST_TRAVERSE(headp, current, entries) { + if (!strcasecmp(ast_var_name(current), "OSPINHANDLE")) { + if (sscanf(ast_var_value(current), "%d", &result.inhandle) != 1) { + result.inhandle = OSP_INVALID_HANDLE; + } + } else if (!strcasecmp(ast_var_name(current), "OSPINTIMELIMIT")) { + if (sscanf(ast_var_value(current), "%d", &result.intimelimit) != 1) { + result.intimelimit = OSP_DEF_TIMELIMIT; + } + } else if (!strcasecmp(ast_var_name(current), "OSPPEERIP")) { + srcdev = ast_var_value(current); + } + } + ast_log(LOG_DEBUG, "OSPLookup: OSPINHANDLE '%d'\n", result.inhandle); + ast_log(LOG_DEBUG, "OSPLookup: OSPINTIMELIMIT '%d'\n", result.intimelimit); + ast_log(LOG_DEBUG, "OSPLookup: source device '%s'\n", srcdev); - ast_log(LOG_DEBUG, "Whoo hoo, looking up OSP on '%s' via '%s'\n", args.extension, args.provider ? args.provider : "<default>"); - if ((res = ast_osp_lookup(chan, args.provider, args.extension, chan->cid.cid_num, &result)) > 0) { - char tmp[80]; - snprintf(tmp, sizeof(tmp), "%d", result.handle); - pbx_builtin_setvar_helper(chan, "_OSPHANDLE", tmp); - pbx_builtin_setvar_helper(chan, "_OSPTECH", result.tech); - pbx_builtin_setvar_helper(chan, "_OSPDEST", result.dest); - pbx_builtin_setvar_helper(chan, "_OSPTOKEN", result.token); - snprintf(tmp, sizeof(tmp), "%d", result.numresults); - pbx_builtin_setvar_helper(chan, "_OSPRESULTS", tmp); - pbx_builtin_setvar_helper(chan, "OSPLOOKUPSTATUS", "SUCCESS"); - + res = ast_osp_lookup(provider, srcdev, chan->cid.cid_num, args.exten, &result); + if (res > 0) { + status = OSP_APP_SUCCESS; } else { + result.tech[0] = '\0'; + result.dest[0] = '\0'; + result.calling[0] = '\0'; + result.token[0] = '\0'; + result.numresults = 0; + result.outtimelimit = OSP_DEF_TIMELIMIT; if (!res) { - ast_log(LOG_NOTICE, "OSP Lookup failed for '%s' (provider '%s')\n", args.extension, args.provider ? args.provider : "<default>"); - pbx_builtin_setvar_helper(chan, "OSPLOOKUPSTATUS", "FAILED"); - } else - ast_log(LOG_DEBUG, "Got hangup on '%s' while doing OSP Lookup for '%s' (provider '%s')!\n", chan->name, args.extension, args.provider ? args.provider : "<default>" ); + status = OSP_APP_FAILED; + } else { + result.outhandle = OSP_INVALID_HANDLE; + status = OSP_APP_ERROR; + } + } + + snprintf(buffer, sizeof(buffer), "%d", result.outhandle); + pbx_builtin_setvar_helper(chan, "OSPOUTHANDLE", buffer); + ast_log(LOG_DEBUG, "OSPLookup: OSPOUTHANDLE '%s'\n", buffer); + pbx_builtin_setvar_helper(chan, "OSPTECH", result.tech); + ast_log(LOG_DEBUG, "OSPLookup: OSPTECH '%s'\n", result.tech); + pbx_builtin_setvar_helper(chan, "OSPDEST", result.dest); + ast_log(LOG_DEBUG, "OSPLookup: OSPDEST '%s'\n", result.dest); + pbx_builtin_setvar_helper(chan, "OSPCALLING", result.calling); + ast_log(LOG_DEBUG, "OSPLookup: OSPCALLING '%s'\n", result.calling); + pbx_builtin_setvar_helper(chan, "OSPOUTTOKEN", result.token); + ast_log(LOG_DEBUG, "OSPLookup: OSPOUTTOKEN size '%d'\n", strlen(result.token)); + if (!ast_strlen_zero(result.token)) { + snprintf(buffer, sizeof(buffer), "P-OSP-Auth-Token: %s", result.token); + pbx_builtin_setvar_helper(chan, "_SIPADDHEADER", buffer); + ast_log(LOG_DEBUG, "OSPLookup: SIPADDHEADER size '%d'\n", strlen(buffer)); } - if (!res) { - /* Look for a "busy" place */ - if (priority_jump || ast_opt_priority_jumping) + snprintf(buffer, sizeof(buffer), "%d", result.numresults); + pbx_builtin_setvar_helper(chan, "OSPRESULTS", buffer); + ast_log(LOG_DEBUG, "OSPLookup: OSPRESULTS '%s'\n", buffer); + snprintf(buffer, sizeof(buffer), "%d", result.outtimelimit); + pbx_builtin_setvar_helper(chan, "OSPOUTTIMELIMIT", buffer); + ast_log(LOG_DEBUG, "OSPLookup: OSPOUTTIMELIMIT '%s'\n", buffer); + pbx_builtin_setvar_helper(chan, "OSPLOOKUPSTATUS", status); + ast_log(LOG_DEBUG, "OSPLookup: %s\n", status); + + if(!res) { + if (priority_jump || ast_opt_priority_jumping) { ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101); - } else if (res > 0) + } else { + res = -1; + } + } else if (res > 0) { res = 0; + } + LOCAL_USER_REMOVE(u); - return res; + + return(res); +} + +static int str2cause(char *str) +{ + int cause = AST_CAUSE_NORMAL; + + if (ast_strlen_zero(str)) { + cause = AST_CAUSE_NOTDEFINED; + } else if (!strcasecmp(str, "BUSY")) { + cause = AST_CAUSE_BUSY; + } else if (!strcasecmp(str, "CONGESTION")) { + cause = AST_CAUSE_CONGESTION; + } else if (!strcasecmp(str, "ANSWER")) { + cause = AST_CAUSE_NORMAL; + } else if (!strcasecmp(str, "CANCEL")) { + cause = AST_CAUSE_NORMAL; + } else if (!strcasecmp(str, "NOANSWER")) { + cause = AST_CAUSE_NOANSWER; + } else if (!strcasecmp(str, "NOCHANAVAIL")) { + cause = AST_CAUSE_CONGESTION; + } else { + ast_log(LOG_WARNING, "OSP: Unknown cause '%s', using NORMAL\n", str); + } + + return(cause); } static int ospnext_exec(struct ast_channel *chan, void *data) { int res=0; struct localuser *u; - char *temp; - const char *val; + int priority_jump = 0; int cause; + struct varshead* headp; + struct ast_var_t* current; struct ast_osp_result result; - int priority_jump = 0; + char *tmp; + char buffer[OSP_TOKSTR_SIZE]; + char* status; + AST_DECLARE_APP_ARGS(args, AST_APP_ARG(cause); AST_APP_ARG(options); ); if (ast_strlen_zero(data)) { - ast_log(LOG_WARNING, "OSPNext should have an argument (cause[|options])\n"); - return -1; + ast_log(LOG_WARNING, "OSPNext: Arg required, OSPNext(cause[|options])\n"); + return(-1); } LOCAL_USER_ADD(u); - if (!(temp = ast_strdupa(data))) { + if (!(tmp = ast_strdupa(data))) { + ast_log(LOG_ERROR, "Out of memory\n"); LOCAL_USER_REMOVE(u); - return -1; + return(-1); } - AST_STANDARD_APP_ARGS(args, temp); + AST_STANDARD_APP_ARGS(args, tmp); + + cause = str2cause(args.cause); + ast_log(LOG_DEBUG, "OSPNext: cause '%d'\n", cause); if (args.options) { if (strchr(args.options, 'j')) priority_jump = 1; } - - cause = str2cause(args.cause); - val = pbx_builtin_getvar_helper(chan, "OSPHANDLE"); - result.handle = -1; - if (!ast_strlen_zero(val) && (sscanf(val, "%d", &result.handle) == 1) && (result.handle > -1)) { - val = pbx_builtin_getvar_helper(chan, "OSPRESULTS"); - if (ast_strlen_zero(val) || (sscanf(val, "%d", &result.numresults) != 1)) { - result.numresults = 0; - } - if ((res = ast_osp_next(&result, cause)) > 0) { - char tmp[80]; - snprintf(tmp, sizeof(tmp), "%d", result.handle); - pbx_builtin_setvar_helper(chan, "_OSPHANDLE", tmp); - pbx_builtin_setvar_helper(chan, "_OSPTECH", result.tech); - pbx_builtin_setvar_helper(chan, "_OSPDEST", result.dest); - pbx_builtin_setvar_helper(chan, "_OSPTOKEN", result.token); - snprintf(tmp, sizeof(tmp), "%d", result.numresults); - pbx_builtin_setvar_helper(chan, "_OSPRESULTS", tmp); - pbx_builtin_setvar_helper(chan, "OSPNEXTSTATUS", "SUCCESS"); + ast_log(LOG_DEBUG, "OSPNext: priority jump '%d'\n", priority_jump); + + result.inhandle = OSP_INVALID_HANDLE; + result.outhandle = OSP_INVALID_HANDLE; + result.numresults = 0; + + headp = &chan->varshead; + AST_LIST_TRAVERSE(headp, current, entries) { + if (!strcasecmp(ast_var_name(current), "OSPINHANDLE")) { + if (sscanf(ast_var_value(current), "%d", &result.inhandle) != 1) { + result.inhandle = OSP_INVALID_HANDLE; + } + } else if (!strcasecmp(ast_var_name(current), "OSPOUTHANDLE")) { + if (sscanf(ast_var_value(current), "%d", &result.outhandle) != 1) { + result.outhandle = OSP_INVALID_HANDLE; + } + } else if (!strcasecmp(ast_var_name(current), "OSPINTIMEOUT")) { + if (sscanf(ast_var_value(current), "%d", &result.intimelimit) != 1) { + result.intimelimit = OSP_DEF_TIMELIMIT; + } + } else if (!strcasecmp(ast_var_name(current), "OSPRESULTS")) { + if (sscanf(ast_var_value(current), "%d", &result.numresults) != 1) { + result.numresults = 0; + } } + } + ast_log(LOG_DEBUG, "OSPNext: OSPINHANDLE '%d'\n", result.inhandle); + ast_log(LOG_DEBUG, "OSPNext: OSPOUTHANDLE '%d'\n", result.outhandle); + ast_log(LOG_DEBUG, "OSPNext: OSPINTIMELIMIT '%d'\n", result.intimelimit); + ast_log(LOG_DEBUG, "OSPNext: OSPRESULTS '%d'\n", result.numresults); + + if ((res = ast_osp_next(cause, &result)) > 0) { + status = OSP_APP_SUCCESS; } else { + result.tech[0] = '\0'; + result.dest[0] = '\0'; + result.calling[0] = '\0'; + result.token[0] = '\0'; + result.numresults = 0; + result.outtimelimit = OSP_DEF_TIMELIMIT; if (!res) { - if (result.handle < 0) - ast_log(LOG_NOTICE, "OSP Lookup Next failed for handle '%d'\n", result.handle); - else - ast_log(LOG_DEBUG, "No OSP handle specified\n"); - pbx_builtin_setvar_helper(chan, "OSPNEXTSTATUS", "FAILED"); - } else - ast_log(LOG_DEBUG, "Got hangup on '%s' while doing OSP Next!\n", chan->name); + status = OSP_APP_FAILED; + } else { + result.outhandle = OSP_INVALID_HANDLE; + status = OSP_APP_ERROR; + } + } + + pbx_builtin_setvar_helper(chan, "OSPTECH", result.tech); + ast_log(LOG_DEBUG, "OSPNext: OSPTECH '%s'\n", result.tech); + pbx_builtin_setvar_helper(chan, "OSPDEST", result.dest); + ast_log(LOG_DEBUG, "OSPNext: OSPDEST '%s'\n", result.dest); + pbx_builtin_setvar_helper(chan, "OSPCALLING", result.calling); + ast_log(LOG_DEBUG, "OSPNext: OSPCALLING '%s'\n", result.calling); + pbx_builtin_setvar_helper(chan, "OSPOUTTOKEN", result.token); + ast_log(LOG_DEBUG, "OSPNext: OSPOUTTOKEN size '%d'\n", strlen(result.token)); + if (!ast_strlen_zero(result.token)) { + snprintf(buffer, sizeof(buffer), "P-OSP-Auth-Token: %s", result.token); + pbx_builtin_setvar_helper(chan, "_SIPADDHEADER", buffer); + ast_log(LOG_DEBUG, "OSPNext: SIPADDHEADER size '%d'\n", strlen(buffer)); } - if (!res) { - /* Look for a "busy" place */ - if (priority_jump || ast_opt_priority_jumping) + snprintf(buffer, sizeof(buffer), "%d", result.numresults); + pbx_builtin_setvar_helper(chan, "OSPRESULTS", buffer); + ast_log(LOG_DEBUG, "OSPNext: OSPRESULTS '%s'\n", buffer); + snprintf(buffer, sizeof(buffer), "%d", result.outtimelimit); + pbx_builtin_setvar_helper(chan, "OSPOUTTIMELIMIT", buffer); + ast_log(LOG_DEBUG, "OSPNext: OSPOUTTIMELIMIT '%s'\n", buffer); + pbx_builtin_setvar_helper(chan, "OSPNEXTSTATUS", status); + ast_log(LOG_DEBUG, "OSPNext: %s\n", status); + + if(!res) { + if (priority_jump || ast_opt_priority_jumping) { ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101); - } else if (res > 0) + } else { + res = -1; + } + } else if (res > 0) { res = 0; + } + LOCAL_USER_REMOVE(u); - return res; + + return(res); } static int ospfinished_exec(struct ast_channel *chan, void *data) { - int res=0; - struct localuser *u; - char *temp; - const char *val; - int cause; - time_t start=0, duration=0; - struct ast_osp_result result; + int res = 1; + struct localuser* u; int priority_jump = 0; + int cause; + struct varshead* headp; + struct ast_var_t* current; + int inhandle = OSP_INVALID_HANDLE; + int outhandle = OSP_INVALID_HANDLE; + int recorded = 0; + time_t start, connect, end; + char* tmp; + char* str = ""; + char buffer[OSP_INTSTR_SIZE]; + char* status; + AST_DECLARE_APP_ARGS(args, AST_APP_ARG(status); AST_APP_ARG(options); ); - if (ast_strlen_zero(data)) { - ast_log(LOG_WARNING, "OSPFinish should have an argument (status[|options])\n"); - return -1; - } - LOCAL_USER_ADD(u); - if (!(temp = ast_strdupa(data))) { + if (!(tmp = ast_strdupa(data))) { + ast_log(LOG_ERROR, "Out of memory\n"); LOCAL_USER_REMOVE(u); - return -1; + return(-1); } - AST_STANDARD_APP_ARGS(args, temp); + AST_STANDARD_APP_ARGS(args, tmp); if (args.options) { if (strchr(args.options, 'j')) priority_jump = 1; } + ast_log(LOG_DEBUG, "OSPFinish: priority jump '%d'\n", priority_jump); + + headp = &chan->varshead; + AST_LIST_TRAVERSE(headp, current, entries) { + if (!strcasecmp(ast_var_name(current), "OSPINHANDLE")) { + if (sscanf(ast_var_value(current), "%d", &inhandle) != 1) { + inhandle = OSP_INVALID_HANDLE; + } + } else if (!strcasecmp(ast_var_name(current), "OSPOUTHANDLE")) { + if (sscanf(ast_var_value(current), "%d", &outhandle) != 1) { + outhandle = OSP_INVALID_HANDLE; + } + } else if (!recorded && + (!strcasecmp(ast_var_name(current), "OSPAUTHSTATUS") || + !strcasecmp(ast_var_name(current), "OSPLOOKUPSTATUS") || + !strcasecmp(ast_var_name(current), "OSPNEXTSTATUS"))) + { + if (strcasecmp(ast_var_value(current), OSP_APP_SUCCESS)) { + recorded = 1; + } + } + } + ast_log(LOG_DEBUG, "OSPFinish: OSPINHANDLE '%d'\n", inhandle); + ast_log(LOG_DEBUG, "OSPFinish: OSPOUTHANDLE '%d'\n", outhandle); + ast_log(LOG_DEBUG, "OSPFinish: recorded '%d'\n", recorded); + + if (!recorded) { + str = args.status; + } + cause = str2cause(str); + ast_log(LOG_DEBUG, "OSPFinish: cause '%d'\n", cause); if (chan->cdr) { - start = chan->cdr->answer.tv_sec; - if (start) - duration = time(NULL) - start; - else - duration = 0; - } else - ast_log(LOG_WARNING, "OSPFinish called on channel '%s' with no CDR!\n", chan->name); - - cause = str2cause(args.status); - val = pbx_builtin_getvar_helper(chan, "OSPHANDLE"); - result.handle = -1; - if (!ast_strlen_zero(val) && (sscanf(val, "%d", &result.handle) == 1) && (result.handle > -1)) { - if (!ast_osp_terminate(result.handle, cause, start, duration)) { - pbx_builtin_setvar_helper(chan, "_OSPHANDLE", ""); - pbx_builtin_setvar_helper(chan, "OSPFINISHSTATUS", "SUCCESS"); - res = 1; + start = chan->cdr->start.tv_sec; + connect = chan->cdr->answer.tv_sec; + if (connect) { + end = time(NULL); + } else { + end = connect; } } else { - if (!res) { - if (result.handle > -1) - ast_log(LOG_NOTICE, "OSP Finish failed for handle '%d'\n", result.handle); - else - ast_log(LOG_DEBUG, "No OSP handle specified\n"); - pbx_builtin_setvar_helper(chan, "OSPFINISHSTATUS", "FAILED"); - } else - ast_log(LOG_DEBUG, "Got hangup on '%s' while doing OSP Terminate!\n", chan->name); + start = 0; + connect = 0; + end = 0; + } + ast_log(LOG_DEBUG, "OSPFinish: start '%ld'\n", start); + ast_log(LOG_DEBUG, "OSPFinish: connect '%ld'\n", connect); + ast_log(LOG_DEBUG, "OSPFinish: end '%ld'\n", end); + + if (ast_osp_finish(outhandle, cause, start, connect, end) <= 0) { + ast_log(LOG_DEBUG, "OSPFinish: Unable to report usage for out_bound call\n"); + } + if (ast_osp_finish(inhandle, cause, start, connect, end) <= 0) { + ast_log(LOG_DEBUG, "OSPFinish: Unable to report usage for in_bound call\n"); + } + snprintf(buffer, sizeof(buffer), "%d", OSP_INVALID_HANDLE); + pbx_builtin_setvar_helper(chan, "OSPOUTHANDLE", buffer); + pbx_builtin_setvar_helper(chan, "OSPINHANDLE", buffer); + + if (res > 0) { + status = OSP_APP_SUCCESS; + } else if (!res) { + status = OSP_APP_FAILED; + } else { + status = OSP_APP_ERROR; } - if (!res) { - /* Look for a "busy" place */ - if (priority_jump || ast_opt_priority_jumping) + pbx_builtin_setvar_helper(chan, "OSPFINISHSTATUS", status); + + if(!res) { + if (priority_jump || ast_opt_priority_jumping) { ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101); - } else if (res > 0) + } else { + res = -1; + } + } else if (res > 0) { res = 0; + } + LOCAL_USER_REMOVE(u); - return res; -} + return(res); +} -int unload_module(void) +int load_module(void) { int res; - res = ast_unregister_application(app3); - res |= ast_unregister_application(app2); - res |= ast_unregister_application(app); + ast_osp_adduse(); - STANDARD_HANGUP_LOCALUSERS; + res = ast_register_application(app1, ospauth_exec, synopsis1, descrip1); + res |= ast_register_application(app2, osplookup_exec, synopsis2, descrip2); + res |= ast_register_application(app3, ospnext_exec, synopsis3, descrip3); + res |= ast_register_application(app4, ospfinished_exec, synopsis4, descrip4); - return res; + return(res); } -int load_module(void) +int unload_module(void) { int res; - res = ast_register_application(app, osplookup_exec, synopsis, descrip); - res |= ast_register_application(app2, ospnext_exec, synopsis2, descrip2); - res |= ast_register_application(app3, ospfinished_exec, synopsis3, descrip3); - - return res; + res = ast_unregister_application(app4); + res |= ast_unregister_application(app3); + res |= ast_unregister_application(app2); + res |= ast_unregister_application(app1); + + STANDARD_HANGUP_LOCALUSERS; + + ast_osp_deluse(); + + return(res); } int reload(void) { - return 0; + return(0); } - char *description(void) { - return tdesc; + return("Open Settlement Protocol Applications"); } int usecount(void) { int res; STANDARD_USECOUNT(res); - return res; + return(res); } char *key() { - return ASTERISK_GPL_KEY; + return(ASTERISK_GPL_KEY); } |