[asterisk-commits] res pjproject: Add module providing pjproject logging and u... (asterisk[master])

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Wed Jan 20 11:46:06 CST 2016


Joshua Colp has submitted this change and it was merged.

Change subject: res_pjproject:  Add module providing pjproject logging and utils
......................................................................


res_pjproject:  Add module providing pjproject logging and utils

res_pjsip_log_forwarder has been renamed to res_pjproject
and enhanced as follows:

As a follow-on to the recent 'Add CLI "pjsip show buildopts"' patch,
a new ast_pjproject_get_buildopt function has been added.  It
allows the caller to get the value of one of the buildopts.

The initial use case is retrieving the runtime value of
PJ_MAX_HOSTNAME to insure we don't send a hostname greater
than pjproject can handle.  Since it can differ between
the version of pjproject that Asterisk was compiled against
and the version of pjproject that Asterisk is running against,
we can't use the PJ_MAX_HOSTNAME macro directly in Asterisk
source code.

Change-Id: Iab6e82fec3d7cf00c1cf6185c42be3e7569dee1e
---
M CHANGES
A include/asterisk/res_pjproject.h
M res/res_pjproject.c
A res/res_pjproject.exports.in
4 files changed, 169 insertions(+), 63 deletions(-)

Approvals:
  Richard Mudgett: Looks good to me, but someone else must approve
  Anonymous Coward #1000019: Verified
  Joshua Colp: Looks good to me, approved



diff --git a/CHANGES b/CHANGES
index 93ecf94..173a411 100644
--- a/CHANGES
+++ b/CHANGES
@@ -205,6 +205,14 @@
 --- Functionality changes from Asterisk 13.7.0 to Asterisk 13.8.0 ------------
 ------------------------------------------------------------------------------
 
+res_pjproject
+------------------
+ * This module is the successor of res_pjsip_log_forwarder.  As well as
+   handling the log forwarding (which now displays as 'pjproject:0' instead
+   of 'pjsip:0'), it also adds a 'pjproject show buildopts' command to the CLI.
+   This displays the compiled-in options of the pjproject installation
+   Asterisk is currently running against.
+
 res_pjsip
 ------------------
 
diff --git a/include/asterisk/res_pjproject.h b/include/asterisk/res_pjproject.h
new file mode 100644
index 0000000..2095cae
--- /dev/null
+++ b/include/asterisk/res_pjproject.h
@@ -0,0 +1,62 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2016, Fairview 5 Engineering, LLC
+ *
+ * George Joseph <george.joseph at fairview5.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+#ifndef _RES_PJPROJECT_H
+#define _RES_PJPROJECT_H
+
+/*!
+ * \brief Retrieve a pjproject build option
+ *
+ * \param option The build option requested
+ * \param format_string A scanf-style format string to parse the option value into
+ * \param ... Pointers to variables to receive the values parsed
+ *
+ * \retval The number of values parsed
+ *
+ * \since 13.8.0
+ *
+ * \note The option requested must be from those returned by pj_dump_config()
+ * which can be displayed with the 'pjsip show buildopts' CLI command.
+ *
+ *   <b>Sample Usage:</b>
+ *   \code
+ *
+ *   int max_hostname;
+ *
+ *   ast_sip_get_pjproject_buildopt("PJ_MAX_HOSTNAME", "%d", &max_hostname);
+ *
+ *   \endcode
+ *
+ */
+int ast_pjproject_get_buildopt(char *option, char *format_string, ...) __attribute__((format(scanf, 2,3)));
+
+/*!
+ * \brief Increment the res_pjproject reference count.
+ *
+ * This ensures graceful shutdown happens in the proper order.
+ */
+void ast_pjproject_ref(void);
+
+/*!
+ * \brief Decrement the res_pjproject reference count.
+ *
+ * This ensures graceful shutdown happens in the proper order.
+ */
+void ast_pjproject_unref(void);
+
+#endif /* _RES_PJPROJECT_H */
diff --git a/res/res_pjproject.c b/res/res_pjproject.c
index c6b396a..de1cecb 100644
--- a/res/res_pjproject.c
+++ b/res/res_pjproject.c
@@ -18,18 +18,18 @@
 
 /*! \file
  *
- * \brief Bridge PJSIP logging to Asterisk logging.
+ * \brief Bridge PJPROJECT logging to Asterisk logging.
  * \author David M. Lee, II <dlee at digium.com>
  *
- * PJSIP logging doesn't exactly match Asterisk logging, but mapping the two is
- * not too bad. PJSIP log levels are identified by a single int. Limits are
- * not specified by PJSIP, but their implementation used 1 through 6.
+ * PJPROJECT logging doesn't exactly match Asterisk logging, but mapping the two is
+ * not too bad. PJPROJECT log levels are identified by a single int. Limits are
+ * not specified by PJPROJECT, but their implementation used 1 through 6.
  *
  * The mapping is as follows:
  *  - 0: LOG_ERROR
  *  - 1: LOG_ERROR
  *  - 2: LOG_WARNING
- *  - 3 and above: equivalent to ast_debug(level, ...) for res_pjsip.so
+ *  - 3 and above: equivalent to ast_debug(level, ...) for res_pjproject.so
  */
 
 /*** MODULEINFO
@@ -41,46 +41,30 @@
 
 ASTERISK_REGISTER_FILE()
 
+#include <stdarg.h>
+#include <pjlib.h>
 #include <pjsip.h>
 #include <pj/log.h>
 
 #include "asterisk/logger.h"
 #include "asterisk/module.h"
 #include "asterisk/cli.h"
+#include "asterisk/res_pjproject.h"
+#include "asterisk/vector.h"
 
 static pj_log_func *log_cb_orig;
 static unsigned decor_orig;
 
-/*! Protection from other CLI instances. */
-AST_MUTEX_DEFINE_STATIC(show_buildopts_lock);
+static AST_VECTOR(buildopts, char *) buildopts;
 
-struct pjsip_show_buildopts {
-	pthread_t thread;
-	int fd;
-};
-
-static struct pjsip_show_buildopts show_buildopts = {
-	.thread = AST_PTHREADT_NULL,
-	.fd = -1,
-};
-
-static void log_cb(int level, const char *data, int len)
+static void log_forwarder(int level, const char *data, int len)
 {
 	int ast_level;
-	/* PJSIP doesn't provide much in the way of source info */
-	const char * log_source = "pjsip";
+	/* PJPROJECT doesn't provide much in the way of source info */
+	const char * log_source = "pjproject";
 	int log_line = 0;
 	const char *log_func = "<?>";
 	int mod_level;
-
-	if (show_buildopts.fd != -1 && show_buildopts.thread == pthread_self()) {
-		/*
-		 * We are handling the CLI command dumping the
-		 * PJPROJECT compile time config option settings.
-		 */
-		ast_cli(show_buildopts.fd, "%s\n", data);
-		return;
-	}
 
 	/* Lower number indicates higher importance */
 	switch (level) {
@@ -94,29 +78,72 @@
 	default:
 		ast_level = __LOG_DEBUG;
 
-		/* For levels 3 and up, obey the debug level for res_pjsip */
+		/* For levels 3 and up, obey the debug level for res_pjproject */
 		mod_level = ast_opt_dbg_module ?
-			ast_debug_get_by_module("res_pjsip") : 0;
+			ast_debug_get_by_module("res_pjproject") : 0;
 		if (option_debug < level && mod_level < level) {
 			return;
 		}
 		break;
 	}
 
-	/* PJSIP uses indention to indicate function call depth. We'll prepend
+	/* PJPROJECT uses indention to indicate function call depth. We'll prepend
 	 * log statements with a tab so they'll have a better shot at lining
 	 * up */
 	ast_log(ast_level, log_source, log_line, log_func, "\t%s\n", data);
 }
 
-static char *handle_pjsip_show_buildopts(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
+static void capture_buildopts_cb(int level, const char *data, int len)
 {
-	switch(cmd) {
+	if (strstr(data, "Teluu") || strstr(data, "Dumping")) {
+		return;
+	}
+
+	AST_VECTOR_ADD_SORTED(&buildopts, ast_strdup(ast_skip_blanks(data)), strcmp);
+}
+
+int ast_pjproject_get_buildopt(char *option, char *format_string, ...)
+{
+	int res = 0;
+	char *format_temp;
+	int i;
+
+	format_temp = ast_alloca(strlen(option) + strlen(" : ") + strlen(format_string) + 1);
+	sprintf(format_temp, "%s : %s", option, format_string);
+
+	for (i = 0; i < AST_VECTOR_SIZE(&buildopts); i++) {
+		va_list arg_ptr;
+		va_start(arg_ptr, format_string);
+		res = vsscanf(AST_VECTOR_GET(&buildopts, i), format_temp, arg_ptr);
+		va_end(arg_ptr);
+		if (res) {
+			break;
+		}
+	}
+
+	return res;
+}
+
+void ast_pjproject_ref(void)
+{
+	ast_module_ref(ast_module_info->self);
+}
+
+void ast_pjproject_unref(void)
+{
+	ast_module_unref(ast_module_info->self);
+}
+
+static char *handle_pjproject_show_buildopts(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
+{
+	int i;
+
+	switch (cmd) {
 	case CLI_INIT:
-		e->command = "pjsip show buildopts";
+		e->command = "pjproject show buildopts";
 		e->usage =
-			"Usage: pjsip show buildopts\n"
-			"       Show the compile time config of pjproject that res_pjsip is\n"
+			"Usage: pjproject show buildopts\n"
+			"       Show the compile time config of the pjproject that Asterisk is\n"
 			"       running against.\n";
 		return NULL;
 	case CLI_GENERATE:
@@ -125,60 +152,63 @@
 
 	ast_cli(a->fd, "PJPROJECT compile time config currently running against:\n");
 
-	/* Protect from other CLI instances trying to do this at the same time. */
-	ast_mutex_lock(&show_buildopts_lock);
-
-	show_buildopts.thread = pthread_self();
-	show_buildopts.fd = a->fd;
-	pj_dump_config();
-	show_buildopts.fd = -1;
-	show_buildopts.thread = AST_PTHREADT_NULL;
-
-	ast_mutex_unlock(&show_buildopts_lock);
+	for (i = 0; i < AST_VECTOR_SIZE(&buildopts); i++) {
+		ast_cli(a->fd, "%s\n", AST_VECTOR_GET(&buildopts, i));
+	}
 
 	return CLI_SUCCESS;
 }
 
-static struct ast_cli_entry pjsip_cli[] = {
-	AST_CLI_DEFINE(handle_pjsip_show_buildopts, "Show the compiled config of pjproject in use"),
+static struct ast_cli_entry pjproject_cli[] = {
+	AST_CLI_DEFINE(handle_pjproject_show_buildopts, "Show the compiled config of the pjproject in use"),
 };
 
 static int load_module(void)
 {
+	ast_debug(3, "Starting PJPROJECT logging to Asterisk logger\n");
+
 	pj_init();
 
 	decor_orig = pj_log_get_decor();
 	log_cb_orig = pj_log_get_log_func();
 
-	ast_debug(3, "Forwarding PJSIP logger to Asterisk logger\n");
-	/* SENDER prepends the source to the log message. This could be a
-	 * filename, object reference, or simply a string
-	 *
-	 * INDENT is assumed to be on by most log statements in PJSIP itself.
-	 */
-	pj_log_set_decor(PJ_LOG_HAS_SENDER | PJ_LOG_HAS_INDENT);
-	pj_log_set_log_func(log_cb);
+	if (AST_VECTOR_INIT(&buildopts, 64)) {
+		return AST_MODULE_LOAD_DECLINE;
+	}
 
-	ast_cli_register_multiple(pjsip_cli, ARRAY_LEN(pjsip_cli));
+	/*
+	 * On startup, we want to capture the dump once and store it.
+	 */
+	pj_log_set_log_func(capture_buildopts_cb);
+	pj_log_set_decor(0);
+	pj_dump_config();
+	pj_log_set_decor(PJ_LOG_HAS_SENDER | PJ_LOG_HAS_INDENT);
+	pj_log_set_log_func(log_forwarder);
+
+	ast_cli_register_multiple(pjproject_cli, ARRAY_LEN(pjproject_cli));
 
 	return AST_MODULE_LOAD_SUCCESS;
 }
 
+#define NOT_EQUALS(a, b) (a != b)
+
 static int unload_module(void)
 {
-	ast_cli_unregister_multiple(pjsip_cli, ARRAY_LEN(pjsip_cli));
-
+	ast_cli_unregister_multiple(pjproject_cli, ARRAY_LEN(pjproject_cli));
 	pj_log_set_log_func(log_cb_orig);
 	pj_log_set_decor(decor_orig);
+
+	AST_VECTOR_REMOVE_CMP_UNORDERED(&buildopts, NULL, NOT_EQUALS, ast_free);
+	AST_VECTOR_FREE(&buildopts);
+
+	ast_debug(3, "Stopped PJPROJECT logging to Asterisk logger\n");
 
 	pj_shutdown();
 
 	return 0;
 }
 
-/* While we don't really export global symbols, we want to load before other
- * modules that do */
-AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER, "PJSIP Log Forwarder",
+AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER, "PJPROJECT Log and Utility Support",
 	.support_level = AST_MODULE_SUPPORT_CORE,
 	.load = load_module,
 	.unload = unload_module,
diff --git a/res/res_pjproject.exports.in b/res/res_pjproject.exports.in
new file mode 100644
index 0000000..f1821a6
--- /dev/null
+++ b/res/res_pjproject.exports.in
@@ -0,0 +1,6 @@
+{
+	global:
+		LINKER_SYMBOL_PREFIXast_pjproject_*;
+	local:
+		*;
+};

-- 
To view, visit https://gerrit.asterisk.org/2042
To unsubscribe, visit https://gerrit.asterisk.org/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: Iab6e82fec3d7cf00c1cf6185c42be3e7569dee1e
Gerrit-PatchSet: 3
Gerrit-Project: asterisk
Gerrit-Branch: master
Gerrit-Owner: George Joseph <george.joseph at fairview5.com>
Gerrit-Reviewer: Anonymous Coward #1000019
Gerrit-Reviewer: Joshua Colp <jcolp at digium.com>
Gerrit-Reviewer: Richard Mudgett <rmudgett at digium.com>



More information about the asterisk-commits mailing list