static struct ast_channel *media_request_helper(struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, struct ast_channel_tech *tech, const char *role) { struct ast_channel *chan; ast_callid callid; RAII_VAR(struct ast_unreal_pvt *, pvt, NULL, ao2_cleanup); if (!(pvt = ast_unreal_alloc(sizeof(*pvt), ast_unreal_destructor, cap))) { return NULL; } ast_copy_string(pvt->name, data, sizeof(pvt->name)); ast_set_flag(pvt, AST_UNREAL_NO_OPTIMIZATION); callid = ast_read_threadstorage_callid(); chan = ast_unreal_new_channels(pvt, tech, AST_STATE_UP, AST_STATE_UP, NULL, NULL, assignedids, requestor, callid); if (!chan) { return NULL; } ast_answer(pvt->owner); ast_answer(pvt->chan); if (ast_channel_add_bridge_role(pvt->chan, role)) { ast_hangup(chan); return NULL; } return chan; }
/*! \brief Part of PBX interface */ static struct ast_channel *local_request(const char *type, struct ast_format_cap *cap, const struct ast_assigned_ids *assignedids, const struct ast_channel *requestor, const char *data, int *cause) { struct local_pvt *p; struct ast_channel *chan; ast_callid callid; /* Allocate a new private structure and then Asterisk channels */ p = local_alloc(data, cap); if (!p) { return NULL; } callid = ast_read_threadstorage_callid(); chan = ast_unreal_new_channels(&p->base, &local_tech, AST_STATE_DOWN, AST_STATE_RING, p->exten, p->context, assignedids, requestor, callid); if (chan) { ao2_link(locals, p); } ao2_ref(p, -1); /* kill the ref from the alloc */ return chan; }
static void launch_monitor_thread(struct ast_channel *chan, const char *filename, unsigned int flags, int readvol, int writevol, const char *post_process, const char *filename_write, char *filename_read, const char *uid_channel_var) { pthread_t thread; struct mixmonitor *mixmonitor; char postprocess2[1024] = ""; char *datastore_id = NULL; postprocess2[0] = 0; /* If a post process system command is given attach it to the structure */ if (!ast_strlen_zero(post_process)) { char *p1, *p2; p1 = ast_strdupa(post_process); for (p2 = p1; *p2; p2++) { if (*p2 == '^' && *(p2+1) == '{') { *p2 = '$'; } } pbx_substitute_variables_helper(chan, p1, postprocess2, sizeof(postprocess2) - 1); } /* Pre-allocate mixmonitor structure and spy */ if (!(mixmonitor = ast_calloc(1, sizeof(*mixmonitor)))) { return; } /* Setup the actual spy before creating our thread */ if (ast_audiohook_init(&mixmonitor->audiohook, AST_AUDIOHOOK_TYPE_SPY, mixmonitor_spy_type, 0)) { mixmonitor_free(mixmonitor); return; } /* Copy over flags and channel name */ mixmonitor->flags = flags; if (!(mixmonitor->autochan = ast_autochan_setup(chan))) { mixmonitor_free(mixmonitor); return; } if (setup_mixmonitor_ds(mixmonitor, chan, &datastore_id)) { ast_autochan_destroy(mixmonitor->autochan); mixmonitor_free(mixmonitor); ast_free(datastore_id); return; } if (!ast_strlen_zero(uid_channel_var)) { if (datastore_id) { pbx_builtin_setvar_helper(chan, uid_channel_var, datastore_id); } } ast_free(datastore_id); mixmonitor->name = ast_strdup(ast_channel_name(chan)); if (!ast_strlen_zero(postprocess2)) { mixmonitor->post_process = ast_strdup(postprocess2); } if (!ast_strlen_zero(filename)) { mixmonitor->filename = ast_strdup(filename); } if (!ast_strlen_zero(filename_write)) { mixmonitor->filename_write = ast_strdup(filename_write); } if (!ast_strlen_zero(filename_read)) { mixmonitor->filename_read = ast_strdup(filename_read); } ast_set_flag(&mixmonitor->audiohook, AST_AUDIOHOOK_TRIGGER_SYNC); if (readvol) mixmonitor->audiohook.options.read_volume = readvol; if (writevol) mixmonitor->audiohook.options.write_volume = writevol; if (startmon(chan, &mixmonitor->audiohook)) { ast_log(LOG_WARNING, "Unable to add '%s' spy to channel '%s'\n", mixmonitor_spy_type, ast_channel_name(chan)); ast_audiohook_destroy(&mixmonitor->audiohook); mixmonitor_free(mixmonitor); return; } /* reference be released at mixmonitor destruction */ mixmonitor->callid = ast_read_threadstorage_callid(); ast_pthread_create_detached_background(&thread, NULL, mixmonitor_thread, mixmonitor); }