FreeSWITCH - mod_fifo fifo_member API

官网上http://wiki.freeswitch.org/wiki/Mod_fifo关于mod_fifo模块的说明中包含了一些有关此模块的API,及其使用说明。fifo_member是其中之一。这个API分两大类,一类是add,另一类是对应的del。下面是这两类的使用说明:

add   [] [] [] [expires] [taking-calls]
del  

但只有这些,没有各个参数的具体含义。如果只是这样,只能是在非常粗浅的层面来使用这个API。还好有代码,那就通过查看代码看看各个参数的含义都是什么。


fifo_member_api_function

之前有过分析其他API的经验,所以在源码中找到处理这个请求的函数不难。这个函数在mod_fifo.c文件内,名称是fifo_member_api_function。
	if (action && !strcasecmp(action, "add")) {
		if (argc > 3) {
			simo_count = atoi(argv[3]);
		}
		if (argc > 4) {
			timeout = atoi(argv[4]);
		}
		if (argc > 5) {
			lag = atoi(argv[5]);
		}
		if (argc > 6) {
			expires = switch_epoch_time_now(NULL) + atoi(argv[6]);
		}
		if (argc > 7) {
			taking_calls = atoi(argv[7]);
		}
		if (simo_count < 0) {
			simo_count = 1;
		}
		if (timeout < 0) {
			timeout = 60;
		}
		if (lag < 0) {
			lag = 5;
		}
		if (taking_calls < 1) {
			taking_calls = 1;
		}

		fifo_member_add(fifo_name, originate_string, simo_count, timeout, lag, expires, taking_calls);
		stream->write_function(stream, "%s", "+OK\n");
	} else if (action && !strcasecmp(action, "del")) {
		fifo_member_del(fifo_name, originate_string);
		stream->write_function(stream, "%s", "+OK\n");
	} else {
		stream->write_function(stream, "%s", "-ERR Invalid!\n");
		goto done;
	}



函数内这一部分的处理,也支持fifo_member只有add和del这两个子类。fifo_member_del和fifo_member_add分别是处理两个子类的函数。在此之前的处理,解析出了请求子类,存放在action变量内,解析出了fifo的名称,存放在fifo_name变量内,解析出了originate string,存放在了originate_string变量内。这三个参数是这两类子类都必须具有的参数。add子类特有的参数,在判断出是add子类后再做详细解析。

	argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0])));

	if (argc < 3) {
		stream->write_function(stream, "%s", "-ERR Invalid!\n");
		goto done;
	}

	action = argv[0];
	fifo_name = argv[1];
	originate_string = argv[2];

fifo_member_add

函数开头部分的处理。这一段的处理要将originate_string字串处理后得到另一个字符数组digest。从这里还看不出这么处理的原因是什么。

	if (switch_stristr("fifo_outbound_uuid=", originate_string)) {
		extract_fifo_outbound_uuid(originate_string, digest, sizeof(digest));
	} else {
		switch_md5_string(digest, (void *) originate_string, strlen(originate_string));
	}

继续看接下来的处理。利用fifo_name和digest数组组合一个sql语句。fifo_member API最简单的应用之一就是增加一个队列的成员:fifo_member add fifo1 user/1001。可以在fs_cli控制台下输入上述命令行执行增加队列成员的请求。

	sql = switch_mprintf("delete from fifo_outbound where fifo_name='%q' and uuid = '%q'", fifo_name, digest);
	switch_assert(sql);
	fifo_execute_sql(sql, globals.sql_mutex);
	free(sql);

将这条实际的命令行的参数代入正在分析的函数,fifo_name的值就应该是“fifo1”,originate_name的值是“user/1001”。如果这样的话,上述sql语句中digest值由“user/1001”通过计算得到,fifo_name的值是队列名称。这条sql语句的意思就是从fifo_outbound表内删除fifo_name字段是“fifo1”、uuid字段是字串“user/1001”处理后的值的记录。可以理解为,这是增加操作所以必须确保不会有同名的记录已经存在所以先删除一条这样的记录以防异常。不过,对于fifo_outbound这个表名,我觉得有某种误导的含义,为何后加一个outbound字串?继续看代码。接着是在globals.fifo_hash哈希表内查找名为fifo_name的fifo_node_t类型的变量。如果不存在,那么就创建一个。

	switch_mutex_lock(globals.mutex);
	if (!(node = switch_core_hash_find(globals.fifo_hash, fifo_name))) {
		node = create_node(fifo_name, 0, globals.sql_mutex);
		node->ready = 1;
	}
	switch_mutex_unlock(globals.mutex);

这与实验结果吻合,如果未在fifo.conf.xml配置文件中增加名为fifo1的队列,通过fifo_member add指令仍然可以动态增加一个名为fifo1的队列。现在不想深入到create_node函数内部实现的细节,因为这个函数与其他命令行参数貌似没有关联。得到一个fifo_node_t类型的变量后,再处理一次fifo_name。这次处理的目的是:得到一个fifo_name的副本。但这个副本经历过一些处理:如果原始fifo_name字串中包含“@”字符,那么就删除“@”及其之后的字符。

	name_dup = strdup(fifo_name);
	if ((p = strchr(name_dup, '@'))) {
		*p = '\0';
	}

接下来是执行一条插入语句。uuid字段是处理originate_name字串后得到的值。其他均取自命令行的参数。需要注意,此时并未用到之前处理得到的name_dup值。

	sql = switch_mprintf("insert into fifo_outbound "
						 "(uuid, fifo_name, originate_string, simo_count, use_count, timeout, "
						 "lag, next_avail, expires, static, outboun

你可能感兴趣的:(FreeSwitch,voip,FreeSWITCH,mod_fifo)