static void *attempt_thread(void *data) { struct outgoing *o = data; int res, reason; if (!ast_strlen_zero(o->app)) { if (option_verbose > 2) ast_verbose(VERBOSE_PREFIX_3 "Attempting call on %s/%s for application %s(%s) (Retry %d)\n", o->tech, o->dest, o->app, o->data, o->retries); res = ast_pbx_outgoing_app(o->tech, AST_FORMAT_SLINEAR, o->dest, o->waittime * 1000, o->app, o->data, &reason, 2 /* wait to finish */, o->cid_num, o->cid_name, o->vars, o->account, NULL); } else { if (option_verbose > 2) ast_verbose(VERBOSE_PREFIX_3 "Attempting call on %s/%s for %s@%s:%d (Retry %d)\n", o->tech, o->dest, o->exten, o->context,o->priority, o->retries); res = ast_pbx_outgoing_exten(o->tech, AST_FORMAT_SLINEAR, o->dest, o->waittime * 1000, o->context, o->exten, o->priority, &reason, 2 /* wait to finish */, o->cid_num, o->cid_name, o->vars, o->account, NULL); } if (res) { ast_log(LOG_NOTICE, "Call failed to go through, reason %d\n", reason); if (o->retries >= o->maxretries + 1) { /* Max retries exceeded */ ast_log(LOG_EVENT, "Queued call to %s/%s expired without completion after %d attempt%s\n", o->tech, o->dest, o->retries - 1, ((o->retries - 1) != 1) ? "s" : ""); remove_from_queue(o, "Expired"); } else { /* Notate that the call is still active */ safe_append(o, time(NULL), "EndRetry"); } } else { ast_log(LOG_NOTICE, "Call completed to %s/%s\n", o->tech, o->dest); ast_log(LOG_EVENT, "Queued call to %s/%s completed\n", o->tech, o->dest); remove_from_queue(o, "Completed"); } free_outgoing(o); return NULL; }
/*! * \brief orginate a call from the CLI * \param fd file descriptor for cli * \param chan channel to create type/data * \param app application you want to run * \param appdata data for application * \retval CLI_SUCCESS on success. * \retval CLI_SHOWUSAGE on failure. */ static char *orig_app(int fd, const char *chan, const char *app, const char *appdata) { char *chantech; char *chandata; int reason = 0; struct ast_format_cap *cap; if (ast_strlen_zero(app)) return CLI_SHOWUSAGE; chandata = ast_strdupa(chan); chantech = strsep(&chandata, "/"); if (!chandata) { ast_cli(fd, "*** No data provided after channel type! ***\n"); return CLI_SHOWUSAGE; } if (!(cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) { return CLI_FAILURE; } ast_format_cap_append(cap, ast_format_slin, 0); ast_pbx_outgoing_app(chantech, cap, chandata, TIMEOUT * 1000, app, appdata, &reason, AST_OUTGOING_NO_WAIT, NULL, NULL, NULL, NULL, NULL, NULL); ao2_ref(cap, -1); return CLI_SUCCESS; }
/*! * \brief orginate a call from the CLI * \param fd file descriptor for cli * \param chan channel to create type/data * \param app application you want to run * \param appdata data for application * \retval CLI_SUCCESS on success. * \retval CLI_SHOWUSAGE on failure. */ static char *orig_app(int fd, const char *chan, const char *app, const char *appdata) { char *chantech; char *chandata; int reason = 0; if (ast_strlen_zero(app)) return CLI_SHOWUSAGE; chandata = ast_strdupa(chan); chantech = strsep(&chandata, "/"); if (!chandata) { ast_cli(fd, "*** No data provided after channel type! ***\n"); return CLI_SHOWUSAGE; } ast_pbx_outgoing_app(chantech, AST_FORMAT_SLINEAR, chandata, TIMEOUT * 1000, app, appdata, &reason, 0, NULL, NULL, NULL, NULL, NULL); return CLI_SUCCESS; }
void ast_ari_channels_originate(struct ast_variable *headers, struct ast_ari_channels_originate_args *args, struct ast_ari_response *response) { char *dialtech; char dialdevice[AST_CHANNEL_NAME]; char *caller_id = NULL; char *cid_num = NULL; char *cid_name = NULL; int timeout = 30000; char *stuff; struct ast_channel *chan; RAII_VAR(struct ast_channel_snapshot *, snapshot, NULL, ao2_cleanup); if (ast_strlen_zero(args->endpoint)) { ast_ari_response_error(response, 400, "Bad Request", "Endpoint must be specified"); return; } dialtech = ast_strdupa(args->endpoint); if ((stuff = strchr(dialtech, '/'))) { *stuff++ = '\0'; ast_copy_string(dialdevice, stuff, sizeof(dialdevice)); } if (ast_strlen_zero(dialtech) || ast_strlen_zero(dialdevice)) { ast_ari_response_error(response, 400, "Bad Request", "Invalid endpoint specified"); return; } if (args->timeout > 0) { timeout = args->timeout * 1000; } else if (args->timeout == -1) { timeout = -1; } if (!ast_strlen_zero(args->caller_id)) { caller_id = ast_strdupa(args->caller_id); ast_callerid_parse(caller_id, &cid_name, &cid_num); if (ast_is_shrinkable_phonenumber(cid_num)) { ast_shrink_phone_number(cid_num); } } if (!ast_strlen_zero(args->app)) { const char *app = "Stasis"; RAII_VAR(struct ast_str *, appdata, ast_str_create(64), ast_free); if (!appdata) { ast_ari_response_alloc_failed(response); return; } ast_str_set(&appdata, 0, "%s", args->app); if (!ast_strlen_zero(args->app_args)) { ast_str_append(&appdata, 0, ",%s", args->app_args); } /* originate a channel, putting it into an application */ if (ast_pbx_outgoing_app(dialtech, NULL, dialdevice, timeout, app, ast_str_buffer(appdata), NULL, 0, cid_num, cid_name, NULL, NULL, &chan)) { ast_ari_response_alloc_failed(response); return; } } else if (!ast_strlen_zero(args->extension)) {
static void ari_channels_handle_originate_with_id(const char *args_endpoint, const char *args_extension, const char *args_context, long args_priority, const char *args_app, const char *args_app_args, const char *args_caller_id, int args_timeout, struct ast_variable *variables, const char *args_channel_id, const char *args_other_channel_id, struct ast_ari_response *response) { char *dialtech; char dialdevice[AST_CHANNEL_NAME]; char *caller_id = NULL; char *cid_num = NULL; char *cid_name = NULL; int timeout = 30000; RAII_VAR(struct ast_format_cap *, cap, ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_NOLOCK), ast_format_cap_destroy); struct ast_format tmp_fmt; char *stuff; struct ast_channel *chan; RAII_VAR(struct ast_channel_snapshot *, snapshot, NULL, ao2_cleanup); struct ast_assigned_ids assignedids = { .uniqueid = args_channel_id, .uniqueid2 = args_other_channel_id, }; if (!cap) { ast_ari_response_alloc_failed(response); return; } ast_format_cap_add(cap, ast_format_set(&tmp_fmt, AST_FORMAT_SLINEAR, 0)); if ((assignedids.uniqueid && AST_MAX_PUBLIC_UNIQUEID < strlen(assignedids.uniqueid)) || (assignedids.uniqueid2 && AST_MAX_PUBLIC_UNIQUEID < strlen(assignedids.uniqueid2))) { ast_ari_response_error(response, 400, "Bad Request", "Uniqueid length exceeds maximum of %d\n", AST_MAX_PUBLIC_UNIQUEID); return; } if (ast_strlen_zero(args_endpoint)) { ast_ari_response_error(response, 400, "Bad Request", "Endpoint must be specified"); return; } dialtech = ast_strdupa(args_endpoint); if ((stuff = strchr(dialtech, '/'))) { *stuff++ = '\0'; ast_copy_string(dialdevice, stuff, sizeof(dialdevice)); } if (ast_strlen_zero(dialtech) || ast_strlen_zero(dialdevice)) { ast_ari_response_error(response, 400, "Bad Request", "Invalid endpoint specified"); return; } if (args_timeout > 0) { timeout = args_timeout * 1000; } else if (args_timeout == -1) { timeout = -1; } if (!ast_strlen_zero(args_caller_id)) { caller_id = ast_strdupa(args_caller_id); ast_callerid_parse(caller_id, &cid_name, &cid_num); if (ast_is_shrinkable_phonenumber(cid_num)) { ast_shrink_phone_number(cid_num); } } if (!ast_strlen_zero(args_app)) { const char *app = "Stasis"; RAII_VAR(struct ast_str *, appdata, ast_str_create(64), ast_free); if (!appdata) { ast_ari_response_alloc_failed(response); return; } ast_str_set(&appdata, 0, "%s", args_app); if (!ast_strlen_zero(args_app_args)) { ast_str_append(&appdata, 0, ",%s", args_app_args); } /* originate a channel, putting it into an application */ if (ast_pbx_outgoing_app(dialtech, cap, dialdevice, timeout, app, ast_str_buffer(appdata), NULL, 0, cid_num, cid_name, variables, NULL, &chan, &assignedids)) { ast_ari_response_alloc_failed(response); return; } } else if (!ast_strlen_zero(args_extension)) {