Skip to content
Snippets Groups Projects
Commit 6d25b269 authored by Jenkins2's avatar Jenkins2 Committed by Gerrit Code Review
Browse files

Merge "CDR: Fix deadlock setting some CDR values."

parents dbb376f1 3078b7ad
No related branches found
No related tags found
No related merge requests found
...@@ -356,7 +356,7 @@ static void cdr_read_callback(void *data, struct stasis_subscription *sub, struc ...@@ -356,7 +356,7 @@ static void cdr_read_callback(void *data, struct stasis_subscription *sub, struc
static void cdr_write_callback(void *data, struct stasis_subscription *sub, struct stasis_message *message) static void cdr_write_callback(void *data, struct stasis_subscription *sub, struct stasis_message *message)
{ {
struct cdr_func_payload *payload = stasis_message_data(message); struct cdr_func_payload *payload;
struct ast_flags flags = { 0 }; struct ast_flags flags = { 0 };
AST_DECLARE_APP_ARGS(args, AST_DECLARE_APP_ARGS(args,
AST_APP_ARG(variable); AST_APP_ARG(variable);
...@@ -367,21 +367,17 @@ static void cdr_write_callback(void *data, struct stasis_subscription *sub, stru ...@@ -367,21 +367,17 @@ static void cdr_write_callback(void *data, struct stasis_subscription *sub, stru
if (cdr_write_message_type() != stasis_message_type(message)) { if (cdr_write_message_type() != stasis_message_type(message)) {
return; return;
} }
payload = stasis_message_data(message);
if (!payload) { if (!payload) {
return; return;
} }
if (ast_strlen_zero(payload->arguments)
if (ast_strlen_zero(payload->arguments)) { || !payload->value) {
ast_log(AST_LOG_WARNING, "%s requires a variable (%s(variable)=value)\n)", /* Sanity check. cdr_write() could never send these bad messages */
payload->cmd, payload->cmd); ast_assert(0);
return;
}
if (!payload->value) {
ast_log(AST_LOG_WARNING, "%s requires a value (%s(variable)=value)\n)",
payload->cmd, payload->cmd);
return; return;
} }
parse = ast_strdupa(payload->arguments); parse = ast_strdupa(payload->arguments);
AST_STANDARD_APP_ARGS(args, parse); AST_STANDARD_APP_ARGS(args, parse);
...@@ -389,32 +385,16 @@ static void cdr_write_callback(void *data, struct stasis_subscription *sub, stru ...@@ -389,32 +385,16 @@ static void cdr_write_callback(void *data, struct stasis_subscription *sub, stru
ast_app_parse_options(cdr_func_options, &flags, NULL, args.options); ast_app_parse_options(cdr_func_options, &flags, NULL, args.options);
} }
if (!strcasecmp(args.variable, "accountcode")) { /* These are already handled by cdr_write() */
ast_log(AST_LOG_WARNING, "Using the CDR function to set 'accountcode' is deprecated. Please use the CHANNEL function instead.\n"); ast_assert(strcasecmp(args.variable, "accountcode")
ast_channel_lock(payload->chan); && strcasecmp(args.variable, "peeraccount")
ast_channel_accountcode_set(payload->chan, payload->value); && strcasecmp(args.variable, "amaflags"));
ast_channel_unlock(payload->chan);
} else if (!strcasecmp(args.variable, "peeraccount")) { if (!strcasecmp(args.variable, "userfield")) {
ast_log(AST_LOG_WARNING, "The 'peeraccount' setting is not supported. Please set the 'accountcode' on the appropriate channel using the CHANNEL function.\n");
} else if (!strcasecmp(args.variable, "userfield")) {
ast_cdr_setuserfield(ast_channel_name(payload->chan), payload->value); ast_cdr_setuserfield(ast_channel_name(payload->chan), payload->value);
} else if (!strcasecmp(args.variable, "amaflags")) {
ast_log(AST_LOG_WARNING, "Using the CDR function to set 'amaflags' is deprecated. Please use the CHANNEL function instead.\n");
if (isdigit(*payload->value)) {
int amaflags;
sscanf(payload->value, "%30d", &amaflags);
ast_channel_lock(payload->chan);
ast_channel_amaflags_set(payload->chan, amaflags);
ast_channel_unlock(payload->chan);
} else {
ast_channel_lock(payload->chan);
ast_channel_amaflags_set(payload->chan, ast_channel_string2amaflag(payload->value));
ast_channel_unlock(payload->chan);
}
} else { } else {
ast_cdr_setvar(ast_channel_name(payload->chan), args.variable, payload->value); ast_cdr_setvar(ast_channel_name(payload->chan), args.variable, payload->value);
} }
return;
} }
static void cdr_prop_write_callback(void *data, struct stasis_subscription *sub, struct stasis_message *message) static void cdr_prop_write_callback(void *data, struct stasis_subscription *sub, struct stasis_message *message)
...@@ -523,27 +503,70 @@ static int cdr_read(struct ast_channel *chan, const char *cmd, char *parse, ...@@ -523,27 +503,70 @@ static int cdr_read(struct ast_channel *chan, const char *cmd, char *parse,
return 0; return 0;
} }
static int cdr_write(struct ast_channel *chan, const char *cmd, char *parse, static int cdr_write(struct ast_channel *chan, const char *cmd, char *arguments,
const char *value) const char *value)
{ {
RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup); struct stasis_message *message;
RAII_VAR(struct cdr_func_payload *, payload, NULL, ao2_cleanup); struct cdr_func_payload *payload;
RAII_VAR(struct stasis_message_router *, router, struct stasis_message_router *router;
ast_cdr_message_router(), ao2_cleanup); AST_DECLARE_APP_ARGS(args,
AST_APP_ARG(variable);
AST_APP_ARG(options);
);
char *parse;
if (!chan) { if (!chan) {
ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd); ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
return -1; return -1;
} }
if (ast_strlen_zero(arguments)) {
if (!router) { ast_log(LOG_WARNING, "%s requires a variable (%s(variable)=value)\n)",
ast_log(AST_LOG_WARNING, "Failed to manipulate CDR for channel %s: no message router\n", cmd, cmd);
ast_channel_name(chan)); return -1;
}
if (!value) {
ast_log(LOG_WARNING, "%s requires a value (%s(variable)=value)\n)",
cmd, cmd);
return -1; return -1;
} }
parse = ast_strdupa(arguments);
AST_STANDARD_APP_ARGS(args, parse);
/* These CDR variables are no longer supported or set directly on the channel */
if (!strcasecmp(args.variable, "accountcode")) {
ast_log(LOG_WARNING, "Using the %s function to set 'accountcode' is deprecated. Please use the CHANNEL function instead.\n",
cmd);
ast_channel_lock(chan);
ast_channel_accountcode_set(chan, value);
ast_channel_unlock(chan);
return 0;
}
if (!strcasecmp(args.variable, "amaflags")) {
int amaflags;
ast_log(LOG_WARNING, "Using the %s function to set 'amaflags' is deprecated. Please use the CHANNEL function instead.\n",
cmd);
if (isdigit(*value)) {
if (sscanf(value, "%30d", &amaflags) != 1) {
amaflags = AST_AMA_NONE;
}
} else {
amaflags = ast_channel_string2amaflag(value);
}
ast_channel_lock(chan);
ast_channel_amaflags_set(chan, amaflags);
ast_channel_unlock(chan);
return 0;
}
if (!strcasecmp(args.variable, "peeraccount")) {
ast_log(LOG_WARNING, "The 'peeraccount' setting is not supported. Please set the 'accountcode' on the appropriate channel using the CHANNEL function.\n");
return 0;
}
/* The remaining CDR variables are handled by CDR processing code */
if (!cdr_write_message_type()) { if (!cdr_write_message_type()) {
ast_log(AST_LOG_WARNING, "Failed to manipulate CDR for channel %s: message type not available\n", ast_log(LOG_WARNING, "Failed to manipulate CDR for channel %s: message type not available\n",
ast_channel_name(chan)); ast_channel_name(chan));
return -1; return -1;
} }
...@@ -554,16 +577,26 @@ static int cdr_write(struct ast_channel *chan, const char *cmd, char *parse, ...@@ -554,16 +577,26 @@ static int cdr_write(struct ast_channel *chan, const char *cmd, char *parse,
} }
payload->chan = chan; payload->chan = chan;
payload->cmd = cmd; payload->cmd = cmd;
payload->arguments = parse; payload->arguments = arguments;
payload->value = value; payload->value = value;
message = stasis_message_create(cdr_write_message_type(), payload); message = stasis_message_create(cdr_write_message_type(), payload);
ao2_ref(payload, -1);
if (!message) { if (!message) {
ast_log(AST_LOG_WARNING, "Failed to manipulate CDR for channel %s: unable to create message\n", ast_log(LOG_WARNING, "Failed to manipulate CDR for channel %s: unable to create message\n",
ast_channel_name(chan)); ast_channel_name(chan));
return -1; return -1;
} }
router = ast_cdr_message_router();
if (!router) {
ast_log(LOG_WARNING, "Failed to manipulate CDR for channel %s: no message router\n",
ast_channel_name(chan));
ao2_ref(message, -1);
return -1;
}
stasis_message_router_publish_sync(router, message); stasis_message_router_publish_sync(router, message);
ao2_ref(router, -1);
ao2_ref(message, -1);
return 0; return 0;
} }
...@@ -586,7 +619,7 @@ static int cdr_prop_write(struct ast_channel *chan, const char *cmd, char *parse ...@@ -586,7 +619,7 @@ static int cdr_prop_write(struct ast_channel *chan, const char *cmd, char *parse
return -1; return -1;
} }
if (!cdr_write_message_type()) { if (!cdr_prop_write_message_type()) {
ast_log(AST_LOG_WARNING, "Failed to manipulate CDR for channel %s: message type not available\n", ast_log(AST_LOG_WARNING, "Failed to manipulate CDR for channel %s: message type not available\n",
ast_channel_name(chan)); ast_channel_name(chan));
return -1; return -1;
......
...@@ -495,18 +495,17 @@ static int func_channel_write_real(struct ast_channel *chan, const char *functio ...@@ -495,18 +495,17 @@ static int func_channel_write_real(struct ast_channel *chan, const char *functio
ast_bridge_set_after_go_on(chan, ast_channel_context(chan), ast_channel_exten(chan), ast_channel_priority(chan), value); ast_bridge_set_after_go_on(chan, ast_channel_context(chan), ast_channel_exten(chan), ast_channel_priority(chan), value);
} }
} else if (!strcasecmp(data, "amaflags")) { } else if (!strcasecmp(data, "amaflags")) {
ast_channel_lock(chan); int amaflags;
if (isdigit(*value)) { if (isdigit(*value)) {
int amaflags; if (sscanf(value, "%30d", &amaflags) != 1) {
sscanf(value, "%30d", &amaflags); amaflags = AST_AMA_NONE;
ast_channel_amaflags_set(chan, amaflags); }
} else if (!strcasecmp(value,"OMIT")){ } else {
ast_channel_amaflags_set(chan, 1); amaflags = ast_channel_string2amaflag(value);
} else if (!strcasecmp(value,"BILLING")){
ast_channel_amaflags_set(chan, 2);
} else if (!strcasecmp(value,"DOCUMENTATION")){
ast_channel_amaflags_set(chan, 3);
} }
ast_channel_lock(chan);
ast_channel_amaflags_set(chan, amaflags);
ast_channel_unlock(chan); ast_channel_unlock(chan);
} else if (!strcasecmp(data, "peeraccount")) } else if (!strcasecmp(data, "peeraccount"))
locked_string_field_set(chan, peeraccount, value); locked_string_field_set(chan, peeraccount, value);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment