recording, STASIS_APP_RECORDING_STATE_FAILED, cause);
}
-static void recording_cleanup(struct stasis_app_recording *recording)
+static void recording_cleanup(void *data)
{
+ struct stasis_app_recording *recording = data;
+
ao2_unlink_flags(recordings, recording,
OBJ_POINTER | OBJ_UNLINK | OBJ_NODATA);
+ ao2_ref(recording, -1);
}
static int record_file(struct stasis_app_control *control,
struct ast_channel *chan, void *data)
{
- RAII_VAR(struct stasis_app_recording *, recording,
- NULL, recording_cleanup);
+ struct stasis_app_recording *recording = data;
char *acceptdtmf;
int res;
- recording = data;
ast_assert(recording != NULL);
if (stasis_app_get_bridge(control)) {
struct stasis_app_control *control,
struct stasis_app_recording_options *options)
{
- RAII_VAR(struct stasis_app_recording *, recording, NULL, ao2_cleanup);
+ struct stasis_app_recording *recording;
char *last_slash;
errno = 0;
if (recording->absolute_name == NULL) {
errno = ENOMEM;
+ ao2_ref(recording, -1);
return NULL;
}
if (ast_safe_mkdir(ast_config_AST_RECORDING_DIR,
recording->absolute_name, 0777) != 0) {
/* errno set by ast_mkdir */
+ ao2_ref(recording, -1);
return NULL;
}
*last_slash = '/';
ast_log(LOG_WARNING, "Recording file '%s' already exists and ifExists option is failure.\n",
recording->absolute_name);
errno = EEXIST;
+ ao2_ref(recording, -1);
return NULL;
}
"Recording %s already in progress\n",
recording->options->name);
errno = EEXIST;
+ ao2_ref(recording, -1);
return NULL;
}
ao2_link(recordings, recording);
stasis_app_control_register_add_rule(control, &rule_recording);
- /* A ref is kept in the recordings container; no need to bump */
- stasis_app_send_command_async(control, record_file, recording);
+ stasis_app_send_command_async(control, record_file, ao2_bump(recording), recording_cleanup);
- /* Although this should be bumped for the caller */
- ao2_ref(recording, +1);
return recording;
}
static struct stasis_app_command *exec_command_on_condition(
struct stasis_app_control *control, stasis_app_command_cb command_fn,
- void *data, app_command_can_exec_cb can_exec_fn)
+ void *data, command_data_destructor_fn data_destructor,
+ app_command_can_exec_cb can_exec_fn)
{
int retval;
struct stasis_app_command *command;
command_fn = command_fn ? : noop_cb;
- command = command_create(command_fn, data);
+ command = command_create(command_fn, data, data_destructor);
if (!command) {
return NULL;
}
static struct stasis_app_command *exec_command(
struct stasis_app_control *control, stasis_app_command_cb command_fn,
- void *data)
+ void *data, command_data_destructor_fn data_destructor)
{
- return exec_command_on_condition(control, command_fn, data, NULL);
+ return exec_command_on_condition(control, command_fn, data, data_destructor, NULL);
}
struct stasis_app_control_dial_data {
struct ast_channel *chan, void *data)
{
RAII_VAR(struct ast_dial *, dial, ast_dial_create(), ast_dial_destroy);
- RAII_VAR(struct stasis_app_control_dial_data *, dial_data, data, ast_free);
+ struct stasis_app_control_dial_data *dial_data = data;
enum ast_dial_result res;
char *tech, *resource;
struct ast_channel *new_chan;
dial_data->timeout = 30000;
}
- stasis_app_send_command_async(control, app_control_dial, dial_data);
+ stasis_app_send_command_async(control, app_control_dial, dial_data, ast_free_ptr);
return 0;
}
static int app_control_continue(struct stasis_app_control *control,
struct ast_channel *chan, void *data)
{
- RAII_VAR(struct stasis_app_control_continue_data *, continue_data, data, ast_free);
+ struct stasis_app_control_continue_data *continue_data = data;
ast_assert(control->channel != NULL);
continue_data->priority = -1;
}
- stasis_app_send_command_async(control, app_control_continue, continue_data);
+ stasis_app_send_command_async(control, app_control_continue, continue_data, ast_free_ptr);
return 0;
}
static int app_control_dtmf(struct stasis_app_control *control,
struct ast_channel *chan, void *data)
{
- RAII_VAR(struct stasis_app_control_dtmf_data *, dtmf_data, data, ast_free);
+ struct stasis_app_control_dtmf_data *dtmf_data = data;
if (ast_channel_state(chan) != AST_STATE_UP) {
ast_indicate(chan, AST_CONTROL_PROGRESS);
dtmf_data->after = after;
strcpy(dtmf_data->dtmf, dtmf);
- stasis_app_send_command_async(control, app_control_dtmf, dtmf_data);
+ stasis_app_send_command_async(control, app_control_dtmf, dtmf_data, ast_free_ptr);
return 0;
}
int stasis_app_control_ring(struct stasis_app_control *control)
{
- stasis_app_send_command_async(control, app_control_ring, NULL);
+ stasis_app_send_command_async(control, app_control_ring, NULL, NULL);
return 0;
}
int stasis_app_control_ring_stop(struct stasis_app_control *control)
{
- stasis_app_send_command_async(control, app_control_ring_stop, NULL);
+ stasis_app_send_command_async(control, app_control_ring_stop, NULL, NULL);
return 0;
}
static int app_control_mute(struct stasis_app_control *control,
struct ast_channel *chan, void *data)
{
- RAII_VAR(struct stasis_app_control_mute_data *, mute_data, data, ast_free);
+ struct stasis_app_control_mute_data *mute_data = data;
SCOPED_CHANNELLOCK(lockvar, chan);
ast_channel_suppress(control->channel, mute_data->direction, mute_data->frametype);
mute_data->direction = direction;
mute_data->frametype = frametype;
- stasis_app_send_command_async(control, app_control_mute, mute_data);
+ stasis_app_send_command_async(control, app_control_mute, mute_data, ast_free_ptr);
return 0;
}
static int app_control_unmute(struct stasis_app_control *control,
struct ast_channel *chan, void *data)
{
- RAII_VAR(struct stasis_app_control_mute_data *, mute_data, data, ast_free);
+ struct stasis_app_control_mute_data *mute_data = data;
SCOPED_CHANNELLOCK(lockvar, chan);
ast_channel_unsuppress(control->channel, mute_data->direction, mute_data->frametype);
mute_data->direction = direction;
mute_data->frametype = frametype;
- stasis_app_send_command_async(control, app_control_unmute, mute_data);
+ stasis_app_send_command_async(control, app_control_unmute, mute_data, ast_free_ptr);
return 0;
}
void stasis_app_control_hold(struct stasis_app_control *control)
{
- stasis_app_send_command_async(control, app_control_hold, NULL);
+ stasis_app_send_command_async(control, app_control_hold, NULL, NULL);
}
static int app_control_unhold(struct stasis_app_control *control,
void stasis_app_control_unhold(struct stasis_app_control *control)
{
- stasis_app_send_command_async(control, app_control_unhold, NULL);
+ stasis_app_send_command_async(control, app_control_unhold, NULL, NULL);
}
static int app_control_moh_start(struct stasis_app_control *control,
ast_moh_start(chan, moh_class, NULL);
- ast_free(moh_class);
return 0;
}
data = ast_strdup(moh_class);
}
- stasis_app_send_command_async(control, app_control_moh_start, data);
+ stasis_app_send_command_async(control, app_control_moh_start, data, ast_free_ptr);
}
static int app_control_moh_stop(struct stasis_app_control *control,
void stasis_app_control_moh_stop(struct stasis_app_control *control)
{
- stasis_app_send_command_async(control, app_control_moh_stop, NULL);
+ stasis_app_send_command_async(control, app_control_moh_stop, NULL, NULL);
}
static int app_control_silence_start(struct stasis_app_control *control,
void stasis_app_control_silence_start(struct stasis_app_control *control)
{
- stasis_app_send_command_async(control, app_control_silence_start, NULL);
+ stasis_app_send_command_async(control, app_control_silence_start, NULL, NULL);
}
static int app_control_silence_stop(struct stasis_app_control *control,
void stasis_app_control_silence_stop(struct stasis_app_control *control)
{
- stasis_app_send_command_async(control, app_control_silence_stop, NULL);
+ stasis_app_send_command_async(control, app_control_silence_stop, NULL, NULL);
}
struct ast_channel_snapshot *stasis_app_control_get_snapshot(
static int app_send_command_on_condition(struct stasis_app_control *control,
stasis_app_command_cb command_fn, void *data,
+ command_data_destructor_fn data_destructor,
app_command_can_exec_cb can_exec_fn)
{
RAII_VAR(struct stasis_app_command *, command, NULL, ao2_cleanup);
}
command = exec_command_on_condition(
- control, command_fn, data, can_exec_fn);
+ control, command_fn, data, data_destructor, can_exec_fn);
if (!command) {
return -1;
}
}
int stasis_app_send_command(struct stasis_app_control *control,
- stasis_app_command_cb command_fn, void *data)
+ stasis_app_command_cb command_fn, void *data, command_data_destructor_fn data_destructor)
{
- return app_send_command_on_condition(control, command_fn, data, NULL);
+ return app_send_command_on_condition(control, command_fn, data, data_destructor, NULL);
}
int stasis_app_send_command_async(struct stasis_app_control *control,
- stasis_app_command_cb command_fn, void *data)
+ stasis_app_command_cb command_fn, void *data,
+ command_data_destructor_fn data_destructor)
{
RAII_VAR(struct stasis_app_command *, command, NULL, ao2_cleanup);
return -1;
}
- command = exec_command(control, command_fn, data);
+ command = exec_command(control, command_fn, data, data_destructor);
if (!command) {
return -1;
}
static int bridge_channel_depart(struct stasis_app_control *control,
struct ast_channel *chan, void *data)
{
- RAII_VAR(struct ast_bridge_channel *, bridge_channel, data, ao2_cleanup);
+ struct ast_bridge_channel *bridge_channel = data;
{
SCOPED_CHANNELLOCK(lock, chan);
ast_channel_unlock(chan);
/* Depart this channel from the bridge using the command queue if possible */
- if (stasis_app_send_command_async(control, bridge_channel_depart, bridge_channel)) {
- ao2_cleanup(bridge_channel);
- }
+ stasis_app_send_command_async(control, bridge_channel_depart, bridge_channel, __ao2_cleanup);
if (stasis_app_channel_is_stasis_end_published(chan)) {
/* The channel has had a StasisEnd published on it, but until now had remained in
* the bridging system. This means that the channel moved from a Stasis bridge to a
stasis_app_control_get_channel_id(control));
return app_send_command_on_condition(
- control, control_add_channel_to_bridge, bridge,
+ control, control_add_channel_to_bridge, bridge, NULL,
app_control_can_add_channel_to_bridge);
}
ast_debug(3, "%s: Sending channel remove_from_bridge command\n",
stasis_app_control_get_channel_id(control));
return app_send_command_on_condition(
- control, app_control_remove_channel_from_bridge, bridge,
+ control, app_control_remove_channel_from_bridge, bridge, NULL,
app_control_can_remove_channel_from_bridge);
}