[asterisk-commits] mmichelson: branch 1.8 r354545 - in /branches/1.8: CHANGES res/res_fax.c

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Thu Feb 9 10:56:40 CST 2012


Author: mmichelson
Date: Thu Feb  9 10:56:34 2012
New Revision: 354545

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=354545
Log:
Adding reload support to res_fax.so

(closes issue ASTERISK-16712)
reported by Frank DiGennaro

Review: https://reviewboard.asterisk.org/r/1713


Modified:
    branches/1.8/CHANGES
    branches/1.8/res/res_fax.c

Modified: branches/1.8/CHANGES
URL: http://svnview.digium.com/svn/asterisk/branches/1.8/CHANGES?view=diff&rev=354545&r1=354544&r2=354545
==============================================================================
--- branches/1.8/CHANGES (original)
+++ branches/1.8/CHANGES Thu Feb  9 10:56:34 2012
@@ -29,6 +29,10 @@
    Also, with strictrtp on, Asterisk will now drop all packets until learning
    mode has successfully exited. These changes are based on how pjmedia handles
    media sources and source changes.
+
+FAX changes
+------------
+ * res_fax now has module reload support.
 
 ------------------------------------------------------------------------------
 --- Functionality changes since Asterisk 1.8.7.1 -----------------------------

Modified: branches/1.8/res/res_fax.c
URL: http://svnview.digium.com/svn/asterisk/branches/1.8/res/res_fax.c?view=diff&rev=354545&r1=354544&r2=354545
==============================================================================
--- branches/1.8/res/res_fax.c (original)
+++ branches/1.8/res/res_fax.c Thu Feb  9 10:56:34 2012
@@ -249,13 +249,28 @@
 #define RES_FAX_STATUSEVENTS 0
 #define RES_FAX_MODEM (AST_FAX_MODEM_V17 | AST_FAX_MODEM_V27 | AST_FAX_MODEM_V29)
 
-static struct {
+struct fax_options {
 	enum ast_fax_modems modems;
 	uint32_t statusevents:1;
 	uint32_t ecm:1;
 	unsigned int minrate;	
 	unsigned int maxrate;
-} general_options;
+};
+
+static struct fax_options general_options;
+
+static const struct fax_options default_options = {
+	.minrate = RES_FAX_MINRATE,
+	.maxrate = RES_FAX_MAXRATE,
+	.statusevents = RES_FAX_STATUSEVENTS,
+	.modems = RES_FAX_MODEM,
+	.ecm = AST_FAX_OPTFLAG_TRUE,
+};
+
+AST_RWLOCK_DEFINE_STATIC(options_lock);
+
+static void get_general_options(struct fax_options* options);
+static void set_general_options(const struct fax_options* options);
 
 static const char *config = "res_fax.conf";
 
@@ -368,6 +383,7 @@
 static struct ast_fax_session_details *session_details_new(void)
 {
 	struct ast_fax_session_details *d;
+	struct fax_options options;
 
 	if (!(d = ao2_alloc(sizeof(*d), destroy_session_details))) {
 		return NULL;
@@ -377,6 +393,8 @@
 		ao2_ref(d, -1);
 		return NULL;
 	}
+
+	get_general_options(&options);
 
 	AST_LIST_HEAD_INIT_NOLOCK(&d->documents);
 
@@ -385,11 +403,11 @@
 	d->option.request_t38 = AST_FAX_OPTFLAG_FALSE;
 	d->option.send_cng = AST_FAX_OPTFLAG_FALSE;
 	d->option.send_ced = AST_FAX_OPTFLAG_FALSE;
-	d->option.ecm = general_options.ecm;
-	d->option.statusevents = general_options.statusevents;
-	d->modems = general_options.modems;
-	d->minrate = general_options.minrate;
-	d->maxrate = general_options.maxrate;
+	d->option.ecm = options.ecm;
+	d->option.statusevents = options.statusevents;
+	d->modems = options.modems;
+	d->minrate = options.minrate;
+	d->maxrate = options.maxrate;
 
 	return d;
 }
@@ -425,12 +443,18 @@
 
 unsigned int ast_fax_maxrate(void)
 {
-	return general_options.maxrate;
+	struct fax_options options;
+	get_general_options(&options);
+
+	return options.maxrate;
 }
 
 unsigned int ast_fax_minrate(void)
 {
-	return general_options.minrate;
+	struct fax_options options;
+	get_general_options(&options);
+
+	return options.minrate;
 }
 
 static int update_modem_bits(enum ast_fax_modems *bits, const char *value)
@@ -2428,6 +2452,7 @@
 {
 	struct fax_module *fax;
 	char modems[128] = "";
+	struct fax_options options;
 
 	switch (cmd) {
 	case CLI_INIT:
@@ -2440,12 +2465,14 @@
 		return NULL;
 	}
 
+	get_general_options(&options);
+
 	ast_cli(a->fd, "FAX For Asterisk Settings:\n");
-	ast_cli(a->fd, "\tECM: %s\n", general_options.ecm ? "Enabled" : "Disabled");
-	ast_cli(a->fd, "\tStatus Events: %s\n",  general_options.statusevents ? "On" : "Off");
-	ast_cli(a->fd, "\tMinimum Bit Rate: %d\n", general_options.minrate);
-	ast_cli(a->fd, "\tMaximum Bit Rate: %d\n", general_options.maxrate);
-	ast_fax_modem_to_str(general_options.modems, modems, sizeof(modems));
+	ast_cli(a->fd, "\tECM: %s\n", options.ecm ? "Enabled" : "Disabled");
+	ast_cli(a->fd, "\tStatus Events: %s\n",  options.statusevents ? "On" : "Off");
+	ast_cli(a->fd, "\tMinimum Bit Rate: %d\n", options.minrate);
+	ast_cli(a->fd, "\tMaximum Bit Rate: %d\n", options.maxrate);
+	ast_fax_modem_to_str(options.modems, modems, sizeof(modems));
 	ast_cli(a->fd, "\tModem Modulations Allowed: %s\n", modems);
 	ast_cli(a->fd, "\n\nFAX Technology Modules:\n\n");
 	AST_RWLIST_RDLOCK(&faxmodules);
@@ -2588,35 +2615,60 @@
 	AST_CLI_DEFINE(cli_fax_show_stats, "Summarize FAX session history"),
 };
 
+static void set_general_options(const struct fax_options *options)
+{
+	ast_rwlock_wrlock(&options_lock);
+	general_options = *options;
+	ast_rwlock_unlock(&options_lock);
+}
+
+static void get_general_options(struct fax_options *options)
+{
+	ast_rwlock_rdlock(&options_lock);
+	*options = general_options;
+	ast_rwlock_unlock(&options_lock);
+}
+
 /*! \brief configure res_fax */
-static int set_config(const char *config_file)
+static int set_config(int reload)
 {
 	struct ast_config *cfg;
 	struct ast_variable *v;
-	struct ast_flags config_flags = { 0 };
+	struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
 	char modems[128] = "";
-
-	/* set defaults */	
-	general_options.minrate = RES_FAX_MINRATE;
-	general_options.maxrate = RES_FAX_MAXRATE;	
-	general_options.statusevents = RES_FAX_STATUSEVENTS;
-	general_options.modems = RES_FAX_MODEM;
-	general_options.ecm = AST_FAX_OPTFLAG_TRUE;
+	struct fax_options options;
+	int res = 0;
+
+	options = default_options;
+
+	/* When we're not reloading, we have to be certain to set the general options
+	 * to the defaults in case config loading goes wrong at some point. On a reload,
+	 * the general options need to stay the same as what they were prior to the
+	 * reload rather than being reset to the defaults.
+	 */
+	if (!reload) {
+		set_general_options(&options);
+	}
 
 	/* read configuration */
-	if (!(cfg = ast_config_load2(config_file, "res_fax", config_flags))) {
-		ast_log(LOG_NOTICE, "Configuration file '%s' not found, using default options.\n", config_file);
+	if (!(cfg = ast_config_load2(config, "res_fax", config_flags))) {
+		ast_log(LOG_NOTICE, "Configuration file '%s' not found, %s options.\n",
+				config, reload ? "not changing" : "using default");
 		return 0;
 	}
 
 	if (cfg == CONFIG_STATUS_FILEINVALID) {
-		ast_log(LOG_NOTICE, "Configuration file '%s' is invalid, using default options.\n", config_file);
+		ast_log(LOG_NOTICE, "Configuration file '%s' is invalid, %s options.\n",
+				config, reload ? "not changing" : "using default");
 		return 0;
 	}
 
 	if (cfg == CONFIG_STATUS_FILEUNCHANGED) {
-		ast_clear_flag(&config_flags, CONFIG_FLAG_FILEUNCHANGED);
-		cfg = ast_config_load2(config_file, "res_fax", config_flags);
+		return 0;
+	}
+
+	if (reload) {
+		options = default_options;
 	}
 
 	/* create configuration */
@@ -2626,49 +2678,54 @@
 		if (!strcasecmp(v->name, "minrate")) {
 			ast_debug(3, "reading minrate '%s' from configuration file\n", v->value);
 			if ((rate = fax_rate_str_to_int(v->value)) == 0) {
-				ast_config_destroy(cfg);
-				return -1;
+				res = -1;
+				goto end;
 			}
-			general_options.minrate = rate;
+			options.minrate = rate;
 		} else if (!strcasecmp(v->name, "maxrate")) {
 			ast_debug(3, "reading maxrate '%s' from configuration file\n", v->value);
 			if ((rate = fax_rate_str_to_int(v->value)) == 0) {
-				ast_config_destroy(cfg);
-				return -1;
+				res = -1;
+				goto end;
 			}
-			general_options.maxrate = rate;
+			options.maxrate = rate;
 		} else if (!strcasecmp(v->name, "statusevents")) {
 			ast_debug(3, "reading statusevents '%s' from configuration file\n", v->value);
-			general_options.statusevents = ast_true(v->value);
+			options.statusevents = ast_true(v->value);
 		} else if (!strcasecmp(v->name, "ecm")) {
 			ast_debug(3, "reading ecm '%s' from configuration file\n", v->value);
-			general_options.ecm = ast_true(v->value);
+			options.ecm = ast_true(v->value);
 		} else if ((!strcasecmp(v->name, "modem")) || (!strcasecmp(v->name, "modems"))) {
-			general_options.modems = 0;
-			update_modem_bits(&general_options.modems, v->value);
-		}
-	}
-
+			options.modems = 0;
+			update_modem_bits(&options.modems, v->value);
+		}
+	}
+
+	if (options.maxrate < options.minrate) {
+		ast_log(LOG_ERROR, "maxrate %d is less than minrate %d\n", options.maxrate, options.minrate);
+		res = -1;
+		goto end;
+	}
+
+	if (check_modem_rate(options.modems, options.minrate)) {
+		ast_fax_modem_to_str(options.modems, modems, sizeof(modems));
+		ast_log(LOG_ERROR, "'modems' setting '%s' is incompatible with 'minrate' setting %d\n", modems, options.minrate);
+		res = -1;
+		goto end;
+	}
+
+	if (check_modem_rate(options.modems, options.maxrate)) {
+		ast_fax_modem_to_str(options.modems, modems, sizeof(modems));
+		ast_log(LOG_ERROR, "'modems' setting '%s' is incompatible with 'maxrate' setting %d\n", modems, options.maxrate);
+		res = -1;
+		goto end;
+	}
+
+	set_general_options(&options);
+
+end:
 	ast_config_destroy(cfg);
-
-	if (general_options.maxrate < general_options.minrate) {
-		ast_log(LOG_ERROR, "maxrate %d is less than minrate %d\n", general_options.maxrate, general_options.minrate);
-		return -1;
-	}
-
-	if (check_modem_rate(general_options.modems, general_options.minrate)) {
-		ast_fax_modem_to_str(general_options.modems, modems, sizeof(modems));
-		ast_log(LOG_ERROR, "'modems' setting '%s' is incompatible with 'minrate' setting %d\n", modems, general_options.minrate);
-		return -1;
-	}
-
-	if (check_modem_rate(general_options.modems, general_options.maxrate)) {
-		ast_fax_modem_to_str(general_options.modems, modems, sizeof(modems));
-		ast_log(LOG_ERROR, "'modems' setting '%s' is incompatible with 'maxrate' setting %d\n", modems, general_options.maxrate);
-		return -1;
-	}
-
-	return 0;
+	return res;
 }
 
 /*! \brief FAXOPT read function returns the contents of a FAX option */
@@ -2829,7 +2886,7 @@
 		return AST_MODULE_LOAD_DECLINE;
 	}
 	
-	if (set_config(config) < 0) {
+	if (set_config(0) < 0) {
 		ast_log(LOG_ERROR, "failed to load configuration file '%s'\n", config);
 		ao2_ref(faxregistry.container, -1);
 		return AST_MODULE_LOAD_DECLINE;
@@ -2854,9 +2911,16 @@
 	return res;
 }
 
+static int reload_module(void)
+{
+	set_config(1);
+	return 0;
+}
+
 
 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER, "Generic FAX Applications",
 		.load = load_module,
 		.unload = unload_module,
+		.reload = reload_module,
 		.load_pri = AST_MODPRI_APP_DEPEND,
 	       );




More information about the asterisk-commits mailing list