/*! \brief Unpause monitoring of channel */ int AST_OPTIONAL_API_NAME(ast_monitor_unpause)(struct ast_channel *chan) { return ast_monitor_set_state(chan, AST_MONITOR_RUNNING); }
/*! \brief Start monitoring a channel * \param chan ast_channel struct to record * \param format_spec file format to use for recording * \param fname_base filename base to record to * \param need_lock whether to lock the channel mutex * \param stream_action whether to record the input and/or output streams. X_REC_IN | X_REC_OUT is most often used * Creates the file to record, if no format is specified it assumes WAV * It also sets channel variable __MONITORED=yes * \retval 0 on success * \retval -1 on failure */ int AST_OPTIONAL_API_NAME(ast_monitor_start)(struct ast_channel *chan, const char *format_spec, const char *fname_base, int need_lock, int stream_action) { int res = 0; LOCK_IF_NEEDED(chan, need_lock); if (!(ast_channel_monitor(chan))) { struct ast_channel_monitor *monitor; char *channel_name, *p; /* Create monitoring directory if needed */ ast_mkdir(ast_config_AST_MONITOR_DIR, 0777); if (!(monitor = ast_calloc(1, sizeof(*monitor)))) { UNLOCK_IF_NEEDED(chan, need_lock); return -1; } /* Determine file names */ if (!ast_strlen_zero(fname_base)) { int directory = strchr(fname_base, '/') ? 1 : 0; const char *absolute = *fname_base == '/' ? "" : ast_config_AST_MONITOR_DIR; const char *absolute_suffix = *fname_base == '/' ? "" : "/"; snprintf(monitor->read_filename, FILENAME_MAX, "%s%s%s-in", absolute, absolute_suffix, fname_base); snprintf(monitor->write_filename, FILENAME_MAX, "%s%s%s-out", absolute, absolute_suffix, fname_base); snprintf(monitor->filename_base, FILENAME_MAX, "%s%s%s", absolute, absolute_suffix, fname_base); /* try creating the directory just in case it doesn't exist */ if (directory) { char *name = ast_strdupa(monitor->filename_base); ast_mkdir(dirname(name), 0777); } } else { ast_mutex_lock(&monitorlock); snprintf(monitor->read_filename, FILENAME_MAX, "%s/audio-in-%lu", ast_config_AST_MONITOR_DIR, seq); snprintf(monitor->write_filename, FILENAME_MAX, "%s/audio-out-%lu", ast_config_AST_MONITOR_DIR, seq); seq++; ast_mutex_unlock(&monitorlock); /* Replace all '/' chars from the channel name with '-' chars. */ channel_name = ast_strdupa(ast_channel_name(chan)); for (p = channel_name; (p = strchr(p, '/')); ) { *p = '-'; } snprintf(monitor->filename_base, FILENAME_MAX, "%s/%d-%s", ast_config_AST_MONITOR_DIR, (int)time(NULL), channel_name); monitor->filename_changed = 1; } monitor->stop = ast_monitor_stop; /* Determine file format */ if (!ast_strlen_zero(format_spec)) { monitor->format = ast_strdup(format_spec); } else { monitor->format = ast_strdup("wav"); } /* open files */ if (stream_action & X_REC_IN) { if (ast_fileexists(monitor->read_filename, NULL, NULL) > 0) ast_filedelete(monitor->read_filename, NULL); if (!(monitor->read_stream = ast_writefile(monitor->read_filename, monitor->format, NULL, O_CREAT|O_TRUNC|O_WRONLY, 0, AST_FILE_MODE))) { ast_log(LOG_WARNING, "Could not create file %s\n", monitor->read_filename); ast_free(monitor); UNLOCK_IF_NEEDED(chan, need_lock); return -1; } } else monitor->read_stream = NULL; if (stream_action & X_REC_OUT) { if (ast_fileexists(monitor->write_filename, NULL, NULL) > 0) { ast_filedelete(monitor->write_filename, NULL); } if (!(monitor->write_stream = ast_writefile(monitor->write_filename, monitor->format, NULL, O_CREAT|O_TRUNC|O_WRONLY, 0, AST_FILE_MODE))) { ast_log(LOG_WARNING, "Could not create file %s\n", monitor->write_filename); if (monitor->read_stream) { ast_closestream(monitor->read_stream); } ast_free(monitor); UNLOCK_IF_NEEDED(chan, need_lock); return -1; } } else monitor->write_stream = NULL; ast_channel_monitor_set(chan, monitor); ast_monitor_set_state(chan, AST_MONITOR_RUNNING); /* so we know this call has been monitored in case we need to bill for it or something */ pbx_builtin_setvar_helper(chan, "__MONITORED","true"); ast_manager_event(chan, EVENT_FLAG_CALL, "MonitorStart", "Channel: %s\r\n" "Uniqueid: %s\r\n", ast_channel_name(chan), ast_channel_uniqueid(chan)); } else { ast_debug(1,"Cannot start monitoring %s, already monitored\n", ast_channel_name(chan)); res = -1; } UNLOCK_IF_NEEDED(chan, need_lock); return res; }
/* Pause monitoring of a channel */ int ast_monitor_pause(struct ast_channel *chan) { return ast_monitor_set_state(chan, AST_MONITOR_PAUSED); }
/* Unpause monitoring of a channel */ int ast_monitor_unpause(struct ast_channel *chan) { return ast_monitor_set_state(chan, AST_MONITOR_RUNNING); }
/* Start monitoring a channel */ int ast_monitor_start( struct ast_channel *chan, const char *format_spec, const char *fname_base, int need_lock) { int res = 0; char tmp[256]; LOCK_IF_NEEDED(chan, need_lock); if (!(chan->monitor)) { struct ast_channel_monitor *monitor; char *channel_name, *p; /* Create monitoring directory if needed */ if (mkdir(ast_config_AST_MONITOR_DIR, 0770) < 0) { if (errno != EEXIST) { ast_log(LOG_WARNING, "Unable to create audio monitor directory: %s\n", strerror(errno)); } } if (!(monitor = ast_calloc(1, sizeof(*monitor)))) { UNLOCK_IF_NEEDED(chan, need_lock); return -1; } /* Determine file names */ if (!ast_strlen_zero(fname_base)) { int directory = strchr(fname_base, '/') ? 1 : 0; /* try creating the directory just in case it doesn't exist */ if (directory) { char *name = strdup(fname_base); snprintf(tmp, sizeof(tmp), "mkdir -p \"%s\"",dirname(name)); free(name); ast_safe_system(tmp); } snprintf(monitor->read_filename, FILENAME_MAX, "%s/%s-in", directory ? "" : ast_config_AST_MONITOR_DIR, fname_base); snprintf(monitor->write_filename, FILENAME_MAX, "%s/%s-out", directory ? "" : ast_config_AST_MONITOR_DIR, fname_base); ast_copy_string(monitor->filename_base, fname_base, sizeof(monitor->filename_base)); } else { ast_mutex_lock(&monitorlock); snprintf(monitor->read_filename, FILENAME_MAX, "%s/audio-in-%ld", ast_config_AST_MONITOR_DIR, seq); snprintf(monitor->write_filename, FILENAME_MAX, "%s/audio-out-%ld", ast_config_AST_MONITOR_DIR, seq); seq++; ast_mutex_unlock(&monitorlock); channel_name = ast_strdupa(chan->name); while ((p = strchr(channel_name, '/'))) { *p = '-'; } snprintf(monitor->filename_base, FILENAME_MAX, "%s/%d-%s", ast_config_AST_MONITOR_DIR, (int)time(NULL), channel_name); monitor->filename_changed = 1; } monitor->stop = ast_monitor_stop; /* Determine file format */ if (!ast_strlen_zero(format_spec)) { monitor->format = strdup(format_spec); } else { monitor->format = strdup("wav"); } /* open files */ if (ast_fileexists(monitor->read_filename, NULL, NULL) > 0) { ast_filedelete(monitor->read_filename, NULL); } if (!(monitor->read_stream = ast_writefile(monitor->read_filename, monitor->format, NULL, O_CREAT|O_TRUNC|O_WRONLY, 0, 0644))) { ast_log(LOG_WARNING, "Could not create file %s\n", monitor->read_filename); free(monitor); ast_channel_unlock(chan); return -1; } if (ast_fileexists(monitor->write_filename, NULL, NULL) > 0) { ast_filedelete(monitor->write_filename, NULL); } if (!(monitor->write_stream = ast_writefile(monitor->write_filename, monitor->format, NULL, O_CREAT|O_TRUNC|O_WRONLY, 0, 0644))) { ast_log(LOG_WARNING, "Could not create file %s\n", monitor->write_filename); ast_closestream(monitor->read_stream); free(monitor); ast_channel_unlock(chan); return -1; } chan->monitor = monitor; ast_monitor_set_state(chan, AST_MONITOR_RUNNING); /* so we know this call has been monitored in case we need to bill for it or something */ pbx_builtin_setvar_helper(chan, "__MONITORED","true"); } else { ast_log(LOG_DEBUG,"Cannot start monitoring %s, already monitored\n", chan->name); res = -1; } UNLOCK_IF_NEEDED(chan, need_lock); return res; }