Skip to content
Snippets Groups Projects
core_local.c 30 KiB
Newer Older
  • Learn to ignore specific revisions
  • 	return CLI_SUCCESS;
    }
    
    static struct ast_cli_entry cli_local[] = {
    	AST_CLI_DEFINE(locals_show, "List status of local channels"),
    };
    
    static int manager_optimize_away(struct mansession *s, const struct message *m)
    {
    	const char *channel;
    	struct local_pvt *p;
    	struct local_pvt *found;
    	struct ast_channel *chan;
    
    	channel = astman_get_header(m, "Channel");
    	if (ast_strlen_zero(channel)) {
    		astman_send_error(s, m, "'Channel' not specified.");
    		return 0;
    	}
    
    	chan = ast_channel_get_by_name(channel);
    	if (!chan) {
    		astman_send_error(s, m, "Channel does not exist.");
    		return 0;
    	}
    
    	p = ast_channel_tech_pvt(chan);
    	ast_channel_unref(chan);
    
    	found = p ? ao2_find(locals, p, 0) : NULL;
    	if (found) {
    		ao2_lock(found);
    		ast_clear_flag(&found->base, AST_UNREAL_NO_OPTIMIZATION);
    		ao2_unlock(found);
    		ao2_ref(found, -1);
    		astman_send_ack(s, m, "Queued channel to be optimized away");
    	} else {
    		astman_send_error(s, m, "Unable to find channel");
    	}
    
    	return 0;
    }
    
    
    static int locals_cmp_cb(void *obj, void *arg, int flags)
    {
    	return (obj == arg) ? CMP_MATCH : 0;
    }
    
    /*!
     * \internal
     * \brief Shutdown the local proxy channel.
     * \since 12.0.0
     *
     * \return Nothing
     */
    static void local_shutdown(void)
    {
    	/* First, take us out of the channel loop */
    	ast_cli_unregister_multiple(cli_local, ARRAY_LEN(cli_local));
    	ast_manager_unregister("LocalOptimizeAway");
    	ast_channel_unregister(&local_tech);
    
    	ao2_ref(locals, -1);
    	locals = NULL;
    
    
    	ao2_cleanup(local_tech.capabilities);
    	local_tech.capabilities = NULL;
    
    
    	STASIS_MESSAGE_TYPE_CLEANUP(ast_local_optimization_begin_type);
    	STASIS_MESSAGE_TYPE_CLEANUP(ast_local_optimization_end_type);
    	STASIS_MESSAGE_TYPE_CLEANUP(ast_local_bridge_type);
    
    
    	if (STASIS_MESSAGE_TYPE_INIT(ast_local_optimization_begin_type)) {
    		return -1;
    	}
    
    	if (STASIS_MESSAGE_TYPE_INIT(ast_local_optimization_end_type)) {
    		return -1;
    	}
    
    	if (STASIS_MESSAGE_TYPE_INIT(ast_local_bridge_type)) {
    
    	if (!(local_tech.capabilities = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) {
    
    	ast_format_cap_append_by_type(local_tech.capabilities, AST_MEDIA_TYPE_UNKNOWN);
    
    
    	locals = ao2_container_alloc_list(AO2_ALLOC_OPT_LOCK_MUTEX, 0, NULL, locals_cmp_cb);
    	if (!locals) {
    
    		ao2_cleanup(local_tech.capabilities);
    		local_tech.capabilities = NULL;
    
    		return -1;
    	}
    
    	/* Make sure we can register our channel type */
    	if (ast_channel_register(&local_tech)) {
    		ast_log(LOG_ERROR, "Unable to register channel class 'Local'\n");
    		ao2_ref(locals, -1);
    
    		ao2_cleanup(local_tech.capabilities);
    		local_tech.capabilities = NULL;
    
    		return -1;
    	}
    	ast_cli_register_multiple(cli_local, ARRAY_LEN(cli_local));
    	ast_manager_register_xml_core("LocalOptimizeAway", EVENT_FLAG_SYSTEM|EVENT_FLAG_CALL, manager_optimize_away);
    
    
    	ast_register_cleanup(local_shutdown);